/* Cleaned 2026-08-10.
   Rules whose selectors name a class or id that Harko.html and its modules
   never apply have been removed. Everything taken out is in style.removed.css,
   in original order, so nothing is lost and any of it can be pasted back.
   NOT checked against s_harko_help.html - that file was not available. */

/* Web-font import removed: sHarko runs entirely from local files.
   The stacks below resolve to fonts already present on every desktop OS. */

/* ==========================================================================
   Powder 5 — Studio Monitor theme
   Original CSS replaced. Selector names preserved to keep JS happy.
   Aesthetic: high-end Japanese audio receiver. Brushed metal, hairline
   rules, monospace technical readouts, restrained amber LED accent,
   muted cool blue for primary actions. Light + dark.
   ========================================================================== */

:root {
    color-scheme: light;

    /* Type */
    --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
                 Helvetica, Arial, sans-serif;
    --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono",
                 "Roboto Mono", Menlo, Consolas, "Liberation Mono", monospace;

    /* Surfaces — neutral grays (slight cool cast, like brushed aluminum) */
    --bg-app:        #e8eaed;   /* outer chassis */
    --bg-panel:      #f3f4f5;   /* control panel face */
    --bg-stage:      #ffffff;   /* chart / results stage */
    --bg-inset:      #eceef1;   /* recessed input wells */
    --bg-inset-2:    #e0e3e7;
    --bg-elevated:   #ffffff;   /* modals, popovers */
    --bg-hover:      rgba(20,32,48,0.055);

    /* Brushed-metal gradient (very subtle) for chrome surfaces */
    --metal:         #fbfcfd;
    --metal-deep:    #eceef1;

    /* Text */
    --fg:            #14171b;
    --fg-2:          #41474f;     /* secondary */
    --fg-3:          #656b74;     /* tertiary / labels */
    --fg-4:          #a0a4ab;     /* disabled */

    /* Hairlines — the workhorse separator */
    --rule:          #cbced3;
    --rule-soft:     #d8dadd;
    --rule-strong:   #a3a8af;

    /* Accents */
    --accent:        #4a7fb5;     /* muted cool blue — primary action */
    --accent-hover:  #3d6fa3;
    --accent-tint:   rgba(74,127,181,0.14);
    --accent-ring:   rgba(74,127,181,0.30);

    --led:           #d68a2a;     /* amber indicator LED */
    --led-glow:      rgba(214,138,42,0.5);

    --danger:        #b03a3a;
    --success:       #3a7a4a;
    --warning:       #b88318;

    /* Shadows — minimal. Hardware UIs don't float. */
    --shadow-1:      0 1px 0 rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.04);
    --shadow-2:      0 8px 24px rgba(0,0,0,0.12);

    /* Corner radii — keep tight (rx ≈ 2) per chosen language */
    --r-1: 2px;
    --r-2: 3px;
    --r-3: 4px;

    /* Legacy token aliases (so existing inline styles + JS keep working) */
    --system-blue:                var(--accent);
    --system-gray-1:              var(--fg-3);
    --system-gray-2:              var(--fg-4);
    --system-gray-3:              #b8bcc1;
    --system-gray-4:              var(--rule);
    --system-gray-5:              var(--rule-soft);
    --system-gray-6:              var(--bg-inset);
    --system-background:          var(--bg-stage);
    --system-grouped-background:  var(--bg-app);
    --system-material-thin:       rgba(255,255,255,0.7);
    --system-material-regular:    rgba(255,255,255,0.85);
    --system-label:               var(--fg);
    --system-secondary-label:     var(--fg-2);
    --system-tertiary-label:      var(--fg-3);
    --system-separator:           var(--rule);
    --system-fill:                rgba(60,70,80,0.08);
    --system-secondary-fill:      rgba(60,70,80,0.05);
    --system-shadow:              rgba(0,0,0,0.10);
}

[data-theme="dark"] {
    color-scheme: dark;

    --bg-app:        #1a1c1e;
    --bg-panel:      #232629;
    --bg-stage:      #15171a;
    --bg-inset:      #14161a;
    --bg-inset-2:    #0f1114;
    --bg-elevated:   #2a2d31;
    --bg-hover:      rgba(255,255,255,0.05);

    --metal:         #2b2f34;
    --metal-deep:    #202327;

    --fg:            #e8eaed;
    --fg-2:          #c0c4c9;
    --fg-3:          #969ba2;
    --fg-4:          #50545a;

    --rule:          #44474c;
    --rule-soft:     #3a3d42;
    --rule-strong:   #4a4e54;

    --accent:        #5b91c7;
    --accent-hover:  #6ea3d8;
    --accent-tint:   rgba(91,145,199,0.18);
    --accent-ring:   rgba(91,145,199,0.40);

    --led:           #e09a3a;
    --led-glow:      rgba(224,154,58,0.55);

    --danger:        #e06868;
    --success:       #6abf7e;
    --warning:       #e0b04a;

    --shadow-1:      0 1px 0 rgba(0,0,0,0.40), 0 1px 2px rgba(0,0,0,0.30);
    --shadow-2:      0 8px 24px rgba(0,0,0,0.55);

    --system-gray-3: #4a4e54;
    --system-gray-4: var(--rule);
    --system-gray-5: var(--rule-soft);
    --system-gray-6: var(--bg-inset);
    --system-fill:               rgba(255,255,255,0.06);
    --system-secondary-fill:     rgba(255,255,255,0.04);
}

/* ---------- Base ---------- */

* { box-sizing: border-box; }

/* numeric inputs & readouts get monospace */
input[type="number"],
.control-input[type="number"],
input[type="text"].sg-search-row input,
.slider-value-display,
.result-card-value,
#app-version-footer,
.sg-list-item .num,
.sg-explain-grid dd {
    font-family: var(--font-mono);
    font-feature-settings: "tnum" 1, "zero" 1;
    letter-spacing: 0;
}

/* ---------- App shell ---------- */

/* The only element inside #controls-panel that scrolls. Everything that
   isn't the action-button-bar footer lives in here, so the footer itself
   never has to "catch up" via position:sticky — it simply isn't part of
   the scrolling flow, and is always visible regardless of tab content
   height or scroll position. */

/* A true fixed footer (flex-shrink:0, outside #controls-scroll) rather than
   a sticky element inside the scroll flow — sticky only keeps an element
   from scrolling OUT of view once you've already scrolled to it; it does
   nothing for the very first render, so on tall panels (e.g. Profile with
   many parameters) the buttons stayed below the fold until manually
   scrolled down. As a direct, non-scrolling flex child of #controls-panel,
   this bar is visible immediately on every tab, with no scrolling needed. */

#drag-handle::after {
    content: "";
    position: absolute;
    inset: 0 -3px;
}
#drag-handle:hover, #drag-handle:active {
    background: var(--accent);
    box-shadow: 0 0 0 1px var(--accent-ring);
}

/* App version footer (model-number tag) */

/* ---------- Labels ---------- */

/* ---------- Inputs ---------- */

.control-input,
.control-select {
    width: 100%;
    background: var(--bg-inset);
    border: 1px solid var(--rule);
    color: var(--fg);
    border-radius: var(--r-1);
    padding: 6px 10px;
    transition: border-color 0.12s, box-shadow 0.12s, background 0.12s;
    box-sizing: border-box;
    font-size: 13px;
    height: 30px;
    font-family: inherit;
    box-shadow: inset 0 1px 0 rgba(0,0,0,0.03);
}
[data-theme="dark"] .control-input,
[data-theme="dark"] .control-select {
    box-shadow: inset 0 1px 0 rgba(0,0,0,0.5);
}
.control-input:hover:not(:disabled),
.control-select:hover:not(:disabled) {
    border-color: var(--rule-strong);
}
.control-input:focus,
.control-select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-ring);
    background: var(--bg-stage);
}
.control-input:disabled {
    background: var(--bg-inset);
    color: var(--fg-4);
    opacity: 0.7;
}

/* native dropdown chevron */
.control-select {
    appearance: none;
    -webkit-appearance: none;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--fg-2) 50%),
        linear-gradient(135deg, var(--fg-2) 50%, transparent 50%);
    background-position:
        calc(100% - 14px) 12px,
        calc(100% - 9px) 12px;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    padding-right: 26px;
}

/* number-input spinners — keep them but tone down */
/* ---------- Buttons ---------- */

[data-theme="dark"] .btn:hover:not(:disabled) {
    background: var(--bg-elevated);
}
.btn-primary:active:not(:disabled) {
    background: var(--accent-hover);
    box-shadow: 0 1px 2px rgba(0,0,0,0.20) inset;
}

/* ---------- Tabs ---------- */

#lattice-parameters-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* ---------- Placeholder (empty stage) ---------- */

[data-theme="dark"] #results-area {
    background-image: none;
}

/* ---------- Animations & focus ---------- */

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.btn:focus-visible,
.control-input:focus-visible,
.control-select:focus-visible,
.fit-checkbox:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* ---------- Space Group modal ---------- */

/* ---------- Misc safety: tighten anything inline-styled in old CSS ----- */

/* Make the "Select Group »" button match other inputs visually */
#space-group-open-modal {
    background: var(--bg-inset) !important;
    border: 1px solid var(--rule) !important;
    color: var(--fg) !important;
    text-align: left !important;
    padding-left: 10px !important;
}
#space-group-open-modal:hover {
    border-color: var(--accent) !important;
    color: var(--accent) !important;
}

/* --- 3D isosurface: per-site legend -------------------------------------
   One row per unique site: rank, the colour density3d.js draws it in, the
   peak height and a show/hide toggle. It sits in the controls column where
   the old "Atom positions" checkbox was; "hide all" does what that checkbox
   used to do, one row at a time or all at once.

   The list shows ten rows and scrolls beyond that, so a solution with forty
   sites cannot push the rest of the panel off the screen. The cap is written
   in rows rather than pixels, and the row height is fixed, so the two cannot
   disagree about what ten rows measures. */

/* Fix to force the left panel to clip bleeding text and hide the horizontal scrollbar */
#controls-panel, #panel-scroll {
    overflow-x: hidden !important;
}

/* ==========================================================================
   sHarko — application layer
   Appended to the shared Studio Monitor theme. Everything below is
   sHarko-specific structure; it uses only the tokens defined at the top of
   this file, so it follows the light/dark switch with no extra work.

   This section replaces the Tailwind utility classes the page used to carry
   in its markup. Those hard-coded a single palette (dark-left / light-right)
   into every class attribute, so no theme could override them, and they made
   the markup unreadable. There is no Tailwind anywhere now.
   ========================================================================== */

/* ---- shell ------------------------------------------------------------ */

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
}
body {
    font-family: var(--font-sans);
    font-size: 13px;
    line-height: 1.5; /* base reading rhythm */
    color: var(--fg);
    background: var(--bg-app);
    display: flex;
    flex-direction: column;
    height: 100vh;
    overflow: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    letter-spacing: 0.005em;
    margin: 0;
}

#app-container {
    display: flex;
    width: 100%;
    flex-grow: 1;
    min-height: 0;
    background: var(--bg-app);
    flex: 1 1 auto;
}

#controls-panel {
    width: 420px;
    min-width: 340px;
    max-width: 720px;
    flex-shrink: 0;
    background: var(--bg-panel);
    border-right: 1px solid var(--rule);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
    z-index: 20;
    box-shadow: none;
    border-radius: 0;
    padding: 16px 18px 0;
}

#panel-scroll {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; overflow-x: hidden; 
    padding-right: 6px;
}

#panel-scroll::-webkit-scrollbar { width: 8px; }
#panel-scroll::-webkit-scrollbar-track { background: transparent; }
#panel-scroll::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 4px; }
#panel-scroll::-webkit-scrollbar-thumb:hover { background: var(--rule-strong); }

#drag-handle {
    width: 6px;
    cursor: col-resize;
    background: var(--rule);
    flex-shrink: 0;
    transition: background-color .15s;
    position: relative;
}
#drag-handle:hover, body.resizing #drag-handle { background: var(--accent); }

#results-area {
    flex-grow: 1;
    position: relative;
    background: var(--bg-stage);
    min-width: 0;
    display: flex;
    flex-direction: column;
    padding: 12px 16px 8px;
    z-index: 10;
    border-radius: 0;
    margin: 0;
    box-shadow: none;
    border-left: 1px solid var(--rule);
    background-image: none;
    background-color: var(--bg-stage);
    flex: 1 1 auto;
    color: var(--fg);
    min-height: 0;
}

/* ---- generic controls ------------------------------------------------- */

/* No longer a flex child fighting for height; it just takes what it needs. */

.control-label {
    display: block;
    font-weight: 600;
    color: var(--fg-3);
    font-size: .66rem;
    letter-spacing: .09em;
    margin-bottom: 7px;
    font-family: var(--font-mono);
    text-transform: uppercase;
}
.field-label {
    display: block; margin-bottom: 4px;
    font-size: .78rem; font-weight: 500; color: var(--fg-2);
}
.hint { font-size: .74rem; color: var(--fg-3); line-height: 1.5; }
.mono { font-family: var(--font-mono); }
.readout { font-family: var(--font-mono); font-size: .7rem; color: var(--fg-3); }
.readout strong { color: var(--fg); font-weight: 600; }
.hidden {
    display: none !important;
}

.row      { display: flex; align-items: center; gap: 8px; }

.row-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.spacer { flex: 1 1 auto; }

.btn {
    padding: .5rem .9rem;
    border-radius: var(--r-2);
    font-weight: 600;
    transition: background .15s, border-color .15s, color .15s;
    cursor: pointer;
    border: 1px solid var(--rule);
    text-align: center;
    font-size: .8rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--metal);
    color: var(--fg);
    box-shadow: var(--shadow-1);
    font-family: var(--font-sans);
    gap: 6px;
    white-space: nowrap;
}
.btn:hover:not(:disabled) {
    border-color: var(--rule-strong);
    background: var(--bg-hover);
}
.btn:active:not(:disabled) {
    transform: translateY(.5px);
}
.btn:disabled {
    background: var(--bg-inset);
    color: var(--fg-4);
    border-color: var(--rule-soft);
    cursor: default;
    opacity: .42;
    box-shadow: none;
}
.btn-primary {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    box-shadow: 0 1px 0 rgba(255,255,255,0.15) inset, var(--shadow-1);
}
.btn-primary:hover:not(:disabled) {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
    color: #fff;
}
/* Danger had a hover rule and no resting one, so an active Stop button was
   indistinguishable from a plain secondary until the pointer was on it. It is
   now filled like .btn-primary, so every enabled button reads the same way and
   only the colour says what kind of action it is. */
.btn-danger {
    background: var(--danger); border-color: var(--danger); color: #fff;
    box-shadow: 0 1px 0 rgba(255,255,255,0.15) inset, var(--shadow-1);
}
.btn-danger:hover:not(:disabled) { background: var(--danger); border-color: var(--danger); color: #fff; filter: brightness(1.08); }
.btn-full { width: 100%; }

.control-input, .control-select,
input[type="text"], input[type="number"] {
    background: var(--bg-inset); color: var(--fg);
    border: 1px solid var(--rule); border-radius: var(--r-2);
    padding: 5px 8px; font-family: var(--font-mono); font-size: .78rem;
    width: 100%; box-sizing: border-box;
}
.control-input:focus, .control-select:focus,
input[type="text"]:focus, input[type="number"]:focus {
    outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-ring);
}
.control-input:disabled, .control-select:disabled { opacity: .45; cursor: default; }

input[type="number"] {
    appearance: textfield;
    -moz-appearance: textfield;
}

input[type="range"] {
    width: 100%; height: 4px; appearance: none; -webkit-appearance: none;
    background: var(--bg-inset-2); border-radius: 2px; cursor: pointer; margin: 6px 0;
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%;
    background: var(--accent); border: 2px solid var(--bg-panel); cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
    width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--bg-panel);
    background: var(--accent); cursor: pointer;
}
input[type="range"]:disabled { opacity: .45; }
input[type="range"]:disabled::-webkit-slider-thumb { cursor: default; }

/* Checkboxes: a real input, styled — so the box itself is the hit target. */
input[type="checkbox"].check {
    appearance: none; -webkit-appearance: none;
    width: 15px; height: 15px; flex-shrink: 0; margin: 0;
    border: 1px solid var(--rule-strong); border-radius: var(--r-1);
    background: var(--bg-inset); cursor: pointer; position: relative;
}
input[type="checkbox"].check:checked { background: var(--accent); border-color: var(--accent); }
input[type="checkbox"].check:checked::after {
    content: ""; position: absolute; left: 4px; top: 1px;
    width: 4px; height: 8px; border: solid #fff;
    border-width: 0 2px 2px 0; transform: rotate(42deg);
}
input[type="checkbox"].check:focus-visible { outline: 2px solid var(--accent-ring); outline-offset: 1px; }
input[type="checkbox"].check:disabled { opacity: .45; cursor: default; }
.check-row { display: flex; align-items: center; gap: 7px; cursor: pointer; font-size: .78rem; }
.check-row.disabled { opacity: .5; cursor: default; }
/* Grey the whole boolean row (and its explanation note) uniformly when its
   checkbox is disabled, so every disabled toggle reads the same. */
.check-row:has(> input.check:disabled) { opacity: .5; }

/* Switch. The whole thing is a <label>, so the track and knob are clickable —
   previously only the caption text was, because the visual was a bare <span>
   next to a visually-hidden input. */

/* ---- tabs ------------------------------------------------------------- */

.left-tabs, .right-tabs {
    display: flex; flex-wrap: wrap; gap: 2px; flex-shrink: 0;
    border-bottom: 1px solid var(--rule); margin-bottom: .9rem;
}
.left-tab-button, .right-tab-button {
    padding: .42rem .85rem; background: none; border: none;
    border-bottom: 2px solid transparent; cursor: pointer; white-space: nowrap;
    font-family: var(--font-mono); font-size: .7rem; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase; color: var(--fg-3);
    transition: color .15s, border-color .15s;
}
.left-tab-button:hover:not(:disabled), .right-tab-button:hover:not(:disabled) { color: var(--fg); }
.left-tab-button.left-tab-active, .right-tab-button.right-tab-active {
    color: var(--accent); border-color: var(--accent);
}
.left-tab-button:disabled, .right-tab-button:disabled { color: var(--fg-4); cursor: default; }
.left-tab-content { display: none !important; }
.left-tab-content.active { display: block !important; }
.right-tab-panes { flex: 1 1 auto; min-height: 0; }
.right-tab-content { display: none !important; flex-direction: column; height: 100%; min-height: 0; }
.right-tab-content.active { display: flex !important; }

/* ---- map workspace ----------------------------------------------------
   The maps used to be capped to min(width, height) of a small flex cell, so
   on a wide screen they occupied a fraction of the available area. Each
   section is now a grid: canvas takes all remaining space, controls sit in a
   fixed rail beside it, and the canvas is sized from its measured box rather
   than forced square.                                                      */

#maps-workspace {
    flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 4px;
    display: flex; flex-direction: column; gap: 14px;
}
#maps-workspace::-webkit-scrollbar { width: 8px; }
#maps-workspace::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 4px; }

.map-section { display: flex; flex-direction: column; min-height: 0; }
.map-section-title {
    font-family: var(--font-mono); font-size: .66rem; font-weight: 600;
    letter-spacing: .09em; text-transform: uppercase; color: var(--fg-3);
    margin: 0 0 6px;
}

/* ---- single row of three equal, square map panes ---- */
.map-grid {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
    align-items: start;
    width: 100%;
}
.map-pane { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.map-pane-title {
    font-family: var(--font-mono); font-size: .62rem; font-weight: 600;
    letter-spacing: .04em; text-transform: uppercase; color: var(--fg-3);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.map-pane-wrapper { width: 100%; }
.map-pane-wrapper canvas { display: block; }

/* per-pane colour bar + min/max, one set under each map */
.pane-colour-bar {
    height: 10px; border-radius: 2px; margin-top: 6px;
    border: 1px solid var(--rule-soft);
    background: linear-gradient(to right, #0000ff, #00ffff, #00ff00, #ffff00, #ff0000);
}
.pane-colour-bar.diverging {
    background: linear-gradient(to right, #2166ac, #67a9cf, #f7f7f7, #ef8a62, #b2182b);
}
.pane-scale-ends { display: flex; justify-content: space-between; margin-top: 2px; }

/* Busy overlay now covers the whole grid rather than one canvas */
.map-grid > #canvas-busy-overlay { position: absolute; inset: 0; }

/* ---- controls row beneath the grid ---- */
.map-controls-row {
    display: flex; align-items: flex-end; gap: 16px;
    margin-top: 12px; flex-wrap: wrap;
}
.map-ctrl { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.map-ctrl-grow { flex: 1 1 220px; }
.map-controls-row .field-label { margin-bottom: 2px; }
.map-controls-row #export-grd-btn { white-space: nowrap; }

canvas { display: block; }

/* Help affordance parked inside the canvas, top-right */

#canvas-busy-overlay {
    position: absolute; inset: 0; display: none;
    align-items: center; justify-content: center; z-index: 5;
    background: color-mix(in srgb, var(--bg-inset-2) 70%, transparent);
}
#canvas-busy-overlay.visible { display: flex; }
.spinner {
    width: 32px; height: 32px; border-radius: 50%;
    border: 3px solid var(--rule); border-top-color: var(--accent);
    animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* colour bar + scale caption */

.scale-end {
    font-family: var(--font-mono); font-size: .68rem; color: var(--fg-3);
}
.scale-end.right { text-align: right; }
.scale-caption {
    font-family: var(--font-mono); font-size: .66rem; line-height: 1.5;
    color: var(--fg-3); margin-top: 6px;
}
.scale-caption em { color: var(--fg-2); font-style: normal; font-weight: 600; }
#coords-display {
    font-family: var(--font-mono); font-size: .68rem; color: var(--fg-3);
    min-height: 1.1em; margin-top: 4px;
}

/* marker list beside the 3D view */

/* ---- tables ----------------------------------------------------------- */

.table-container {
    overflow-y: auto; background: var(--bg-inset);
    border: 1px solid var(--rule-soft); border-radius: var(--r-3);
    min-height: 0;
}
/* Inside a flex column (the Peaks pane) it should fill; in block flow (the
   left panel) it must not, or it collapses. */
.peaks-column > .table-container { flex: 1 1 auto; }
.table-container::-webkit-scrollbar { width: 8px; }
.table-container::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 4px; }
.styled-table { width: 100%; border-collapse: collapse; font-size: .74rem; }
.styled-table th, .styled-table td {
    text-align: left; padding: 5px 9px; font-family: var(--font-mono); color: var(--fg-2);
}
.styled-table thead th {
    position: sticky; top: 0; z-index: 1; background: var(--bg-inset);
    color: var(--fg-3); border-bottom: 1px solid var(--rule);
    font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
}
.styled-table tbody tr { border-bottom: 1px solid var(--rule-soft); }
.styled-table tbody tr:hover { background: var(--bg-hover); }
.styled-table td.num { text-align: right; }
.table-empty { text-align: center; padding: 18px 0; color: var(--fg-4); }

/* Peaks tab: Patterson and Consolidated side by side */
#peaks-columns {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
    flex: 1 1 auto; min-height: 0;
}
.peaks-column { display: flex; flex-direction: column; min-height: 0; }
.peaks-column-head {
    display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; flex-shrink: 0;
}
.peaks-column-head h3 {
    margin: 0; font-family: var(--font-mono); font-size: .68rem; font-weight: 600;
    letter-spacing: .07em; text-transform: uppercase; color: var(--fg-3);
}
.peaks-column-head .count { font-family: var(--font-mono); font-size: .66rem; color: var(--fg-4); }
@media (max-width: 1100px) { #peaks-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 720px)  { #peaks-columns { grid-template-columns: 1fr; } }
.col-sub {
    font-family: var(--font-mono); font-size: .62rem; color: var(--fg-4);
    margin: -2px 0 5px; letter-spacing: .04em;
}

/* ---- misc ------------------------------------------------------------- */

.info-box {
    background: var(--bg-inset); border: 1px solid var(--rule-soft);
    padding: 9px 10px; border-radius: var(--r-2);
    font-family: var(--font-mono); font-size: .75rem; line-height: 1.55; color: var(--fg-2);
}
.info-box.scroll {
    max-height: 130px; min-height: 56px; overflow-y: auto;
    display: block;
}

#status-message {
    padding: 5px 9px; border-radius: var(--r-2); min-height: 24px;
    display: flex; align-items: center; margin: 8px 0 10px; flex-shrink: 0;
    font-family: var(--font-mono); font-size: .72rem; color: var(--fg-2);
}
/* display:none came from an inline <style> block in the markup; the zeroed
   box metrics were here. Merged: display:none makes the rest redundant for
   layout, but they are kept so the rule still behaves if display is overridden. */
#status-message:empty { display: none; padding: 0; min-height: 0; margin-bottom: 0; }
#status-message.is-error   { color: var(--danger);  background: color-mix(in srgb, var(--danger) 13%, transparent); }
#status-message.is-success { color: var(--success); background: color-mix(in srgb, var(--success) 13%, transparent); }
#status-message.is-warn    { color: var(--warning); background: color-mix(in srgb, var(--warning) 15%, transparent); }

.progress-track {
    width: 100%; height: 5px; border-radius: 3px; overflow: hidden;
    background: var(--bg-inset-2); border: 1px solid var(--rule-soft);
}
.progress-fill { height: 100%; width: 0%; background: var(--accent); transition: width .2s; }

.stat-block {
    background: var(--bg-inset); border: 1px solid var(--rule-soft);
    border-radius: var(--r-2); padding: 8px 10px;
}
.stat-row { display: flex; justify-content: space-between; gap: 10px; font-size: .74rem; }
.stat-row + .stat-row { margin-top: 5px; }
.stat-row .k { color: var(--fg-3); }
.stat-row .v { font-family: var(--font-mono); font-weight: 600; color: var(--fg); }
.stat-row .v.good { color: var(--success); }
/* Acceptance outside its healthy band: the chains are stuck, or wandering. */
.stat-row .v.warn { color: var(--warning); }

.tooltip { position: relative; display: inline-block; }
.tooltip .tooltiptext {
    visibility: hidden; opacity: 0; transition: opacity .2s;
    position: absolute; z-index: 100; top: 140%; left: 0; width: 320px;
    background: var(--bg-elevated); color: var(--fg);
    border: 1px solid var(--rule); box-shadow: var(--shadow-2);
    border-radius: var(--r-3); padding: 11px 13px;
    text-align: left; font-size: .76rem; line-height: 1.5; font-weight: 400;
    text-transform: none; letter-spacing: normal;
}
.tooltip .tooltiptext.right { left: auto; right: 0; }
.tooltip .tooltiptext.visible { visibility: visible; opacity: 1; }
.tooltip .tooltiptext a { color: var(--accent); }
.help-dot {
    display: inline-flex; align-items: center; justify-content: center;
    width: 14px; height: 14px; border-radius: 50%; cursor: pointer;
    border: 1px solid var(--rule-strong); color: var(--fg-3);
    font-size: .6rem; font-weight: 700; font-family: var(--font-mono);
    vertical-align: middle;
}
.help-dot:hover { color: var(--fg); border-color: var(--accent); }

#theme-toggle {
    position: fixed; top: 8px; right: 10px; z-index: 60;
    width: 28px; height: 28px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--rule); border-radius: var(--r-2);
    background: var(--metal); color: var(--fg-2); cursor: pointer;
}
#theme-toggle:hover { color: var(--fg); border-color: var(--rule-strong); }
#theme-toggle svg { width: 14px; height: 14px; }
[data-theme="dark"] #theme-icon-sun { display: none; }
:root:not([data-theme="dark"]) #theme-icon-moon { display: none; }

.warn-line {
    font-family: var(--font-mono); font-size: .68rem; line-height: 1.45;
    color: var(--warning); margin-top: 4px;
}

.muted { color: var(--fg-3); font-size: .9em; }

/* ---- square map canvases ------------------------------------------------
   Both canvases are square and the drawing fills them edge to edge.
   The 2D slice is drawn in FRACTIONAL coordinates, so each in-plane axis runs
   0 to 1 across the full width regardless of the cell's metric shape. That is
   the conventional way to present a Patterson section, and it is what makes
   the two panes match; the true cell geometry is shown in the 3D view, which
   applies the orthogonalisation matrix.                                     */

/* The canvas wrapper is a normal block whose size JS sets directly.
   It used to be an absolutely positioned child of a .canvas-square box whose
   height was also set by JS - so before the first resize ran (or whenever the
   pane was hidden and clientWidth measured zero) the box had no height and the
   wrapper drew straight over the content below it. */
.canvas-wrapper {
    position: relative;
    overflow: hidden;
    background: var(--bg-inset-2);
    border: 1px solid var(--rule-soft);
    border-radius: var(--r-3);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
}

/* ---- editable structure list ---- */
.edit-row {
    display: grid;
    /* El | Wyck | x | y | z | eye. The coordinates are read-only and six
       characters wide, so they are capped rather than given 1fr each - that
       left three sprawling boxes and no room for anything else. The eye
       column takes the slack so the row still spans the list. */
    grid-template-columns: 2.4rem 3.4rem repeat(3, minmax(0, 5.5rem)) minmax(2rem, 1fr);
    gap: 4px; align-items: center; padding: 4px 6px;
    border-bottom: 1px solid var(--rule-soft); transition: opacity 0.2s;
}

.edit-row:last-child { border-bottom: none; }
.edit-row .el {
    font-family: var(--font-mono); font-size: .72rem; font-weight: 600; color: var(--fg);
}
.edit-row input[type="number"] {
    padding: 2px 4px; font-size: .68rem; width: 100%;
    text-align: right; -moz-appearance: textfield;
}

.edit-row .wyck {
    font-family: var(--font-mono); font-size: .68rem; color: var(--fg-2);
    text-align: center;
}
.visibility-btn { background: none; border: none; padding: 0; cursor: pointer; color: var(--fg-3); font-size: 14px; justify-self: end; }
.visibility-btn:hover { color: var(--fg); }

.edit-head {
    display: grid;
    grid-template-columns: 2.4rem 3.4rem repeat(3, minmax(0, 5.5rem)) minmax(2rem, 1fr);
    gap: 4px; padding: 3px 6px;
    font-family: var(--font-mono); font-size: .6rem; letter-spacing: .06em;
    text-transform: uppercase; color: var(--fg-4);
    border-bottom: 1px solid var(--rule);
}
.edit-head span:not(:first-child):not(:last-child) { text-align: right; }
.edit-head span:nth-child(2) { text-align: center; }

details > summary { list-style: revert; }
details > summary::-webkit-details-marker { display: revert; }

/* ---- swarm results layout ---------------------------------------------
   Two columns: the structure on the left, the numbers and actions on the
   right. Both are normal flow, so nothing can overlap anything else.       */

/* Top row of the results page: 3D viewer left, fitness plot right, each
   half the width. The asymmetric unit sits below, spanning both.          */
#swarm-layout {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px; align-items: start;
}
@media (max-width: 900px) { #swarm-layout { grid-template-columns: 1fr; } }

#swarm-structure-col, #swarm-plot-col, #swarm-stats-col, #swarm-data-col { min-width: 0; }
#swarm-data-col { margin-top: 16px; }

.pane-head {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin-bottom: 6px;
}
.pane-head .map-section-title { margin: 0; }

.pane-actions {
    display: flex; gap: 8px; margin-top: 8px;
}
.pane-actions .btn { flex: 1 1 0; }

.tag-warn {
    font-family: var(--font-mono); font-size: .6rem; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--warning); border: 1px solid var(--warning);
    border-radius: var(--r-1); padding: 1px 5px;
}

/* Editable asymmetric unit */
.edit-list {
    border: 1px solid var(--rule-soft); border-radius: var(--r-2);
    background: var(--bg-inset); max-height: 260px; overflow-y: auto;
}
.edit-list::-webkit-scrollbar { width: 7px; }
.edit-list::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 4px; }

/* The Map panel's sliders. Peak width and B replaced a number box plus an
   "auto"/"fit" checkbox, so they share the group with the tolerance slider
   and need to line up with it. */
#sigma-input, #temp-factor-input, #tolerance-slider, #min-contact-input {
    width: 100%; display: block;
}

#cost-wrapper { margin: 0; }

/* The results page used to scroll inside #swarm-layout. Now that the layout
   is only the top row, the pane itself has to take that job or the content
   below the fold would be unreachable. */
#swarm-results-tab { overflow-y: auto; padding-right: 4px; }
#swarm-results-tab::-webkit-scrollbar { width: 8px; }
#swarm-results-tab::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 4px; }

/* ==========================================================================
   Migrated from inline <style> blocks in Harko.html
   ==========================================================================
   These rules previously lived in two <style> elements in the markup: one
   before <head> (invalid placement - the parser hoisted it into an implicit
   head ahead of this file) and one inside <body>. Both are collected here so
   every definition lives in one place.

   Order matters: this section is appended last, exactly where the in-body
   block used to sit in the cascade, so computed styles are unchanged.
   ========================================================================== */

/* ---------- Detached tooltips ----------------------------------------- */
/* The tooltip section above styles `.tooltip .tooltiptext` (a tooltip nested
   inside its trigger). Tooltips that JS reparents to document.body are direct
   children of body, so that descendant selector no longer matches them and
   they need their own rule. The two selectors are disjoint by construction -
   a detached tooltip is never inside .tooltip - so neither overrides the
   other; the duplicated declarations are the price of that split. */
body > .tooltiptext {
    visibility: hidden; opacity: 0; transition: opacity .2s;
    position: fixed; z-index: 10000; width: 320px;
    background: var(--bg-elevated); color: var(--fg);
    border: 1px solid var(--rule); box-shadow: var(--shadow-2);
    border-radius: var(--r-3); padding: 11px 13px;
    text-align: left; font-size: .76rem; line-height: 1.5; font-weight: 400;
    text-transform: none; letter-spacing: normal;
}
body > .tooltiptext.right   { left: auto; right: 0; }
body > .tooltiptext.visible { visibility: visible; opacity: 1; }
body > .tooltiptext a       { color: var(--accent); }

/* ---------- Settings cards -------------------------------------------- */
/* Used by the swarm/analysis option panels; no earlier rule defines these. */
.settings-card {
    background: var(--bg-elevated);
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 14px;
    margin-bottom: 16px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.card-header {
    margin-top: 0;
    margin-bottom: 14px;
    font-size: 13px;
    font-weight: 700;
    color: var(--accent);
    border-bottom: 1px solid var(--rule);
    padding-bottom: 6px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* ---------- Stale-map affordance ---------------------------------------- */
/* Set on the Calculate Map button by markMapStale() when a synthesis or
   peak-search setting has been changed but not yet applied. A quiet ring
   rather than a colour change, so it reads as "pending" without competing
   with the primary-button fill or the warning status message. */
.btn.needs-run {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--warning) 55%, transparent);
}
.btn.needs-run:disabled { box-shadow: none; }

/* ---------- Collapsible panel sections ---------------------------------- */
/* The four left-panel cards are <details>/<summary> rather than div/h3 with a
   JS toggle: the element already provides click and keyboard activation, the
   expanded/collapsed state is exposed to assistive tech without any aria
   bookkeeping, and find-in-page can open a closed section on its own. The
   cards keep their .settings-card / .card-header classes, so everything the
   old markup styled still applies. */

.settings-card > .card-header {
    cursor: pointer;
    list-style: none;                 /* Firefox default triangle */
    display: flex;
    align-items: center;
    gap: 8px;
    user-select: none;
    /* The rule under the header belongs to the open state; when collapsed it
       reads as a stray line under a title, so it is moved to [open] below. */
    border-bottom: none;
    padding-bottom: 0;
    margin-bottom: 0;
    transition: color .12s;
}
.settings-card[open] > .card-header {
    border-bottom: 1px solid var(--rule);
    padding-bottom: 6px;
    margin-bottom: 14px;
}
.settings-card > .card-header::-webkit-details-marker { display: none; }
.settings-card > .card-header:hover { color: var(--accent-hover, var(--accent)); }

/* Disclosure caret, drawn from a border so it needs no font or image. */
.settings-card > .card-header::before {
    content: '';
    flex: 0 0 auto;
    width: 0; height: 0;
    border-left: 7px solid currentColor;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    transform: rotate(0deg);
    transform-origin: 35% 50%;
    transition: transform .15s ease;
}
.settings-card[open] > .card-header::before { transform: rotate(90deg); }

/* Keyboard focus has to stay visible: the summary is the control now. */
.settings-card > .card-header:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--r-1);
}

/* A collapsed card is just its title bar, so the padding that framed a full
   card of controls is too generous. */
.settings-card:not([open]) { padding-bottom: 14px; }

@media (prefers-reduced-motion: reduce) {
    .settings-card > .card-header,
    .settings-card > .card-header::before { transition: none; }
}


/* ==========================================================================
   Token-based layer moved out of Harko.html
   --------------------------------------------------------------------------
   Everything the markup used to declare inline now lives here, referencing the
   tokens at the top of this file. Harko.html carries no raw colours, sizes or
   spacing of its own; only the handful of inline styles the JavaScript writes
   at runtime (canvas sizing, modal open/close, progress width, tooltip
   position) remain in the markup, because they are behaviour, not design.
   ========================================================================== */

/* ---- Spacing utilities (map to the app's vertical rhythm) ------------- */
.mt-1 { margin-top: 4px; }    .mb-1 { margin-bottom: 4px; }
.mt-2 { margin-top: 8px; }    .mb-2 { margin-bottom: 8px; }
.mt-3 { margin-top: 12px; }   .mb-3 { margin-bottom: 12px; }
.mt-4 { margin-top: 16px; }   .mb-4 { margin-bottom: 16px; }
.mb-0 { margin-bottom: 0; }

/* ---- Small layout helpers --------------------------------------------- */
.grid-2      { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.grid-2.gap-sm { gap: 8px; }
.col-span-2  { grid-column: 1 / -1; }
.grow        { flex: 1 1 auto; }
.flex-2      { flex: 2 1 auto; }
.flex-z      { flex: 1 1 70px; }
.section-head-row {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 6px;
}

/* ---- Multi-line technical text field (distance constraints) ----------- */
.control-input.code-area {
    font-family: var(--font-mono); font-size: 12px; line-height: 1.45;
    min-height: 5.5em; resize: vertical; margin-bottom: 4px;
}

/* ---- Top-right control cluster (info / theme / help) ------------------ */
#top-right-controls {
    position: fixed; top: 10px; right: 12px; z-index: 9999;
    display: flex; align-items: center; overflow: hidden;
    background: var(--bg-elevated);
    border: 1px solid var(--rule); border-radius: var(--r-3);
    box-shadow: var(--shadow-1);
}
#top-right-controls > button,
#top-right-controls > a {
    width: 30px; height: 30px; margin: 0; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: transparent; border: none;
    border-right: 1px solid var(--rule);
    color: var(--fg-2); cursor: pointer;
    text-decoration: none; font-size: 1rem;
    transition: background .12s, color .12s;
}
#top-right-controls > :last-child { border-right: none; }
#top-right-controls > button:hover,
#top-right-controls > a:hover { background: var(--bg-hover); color: var(--fg); }
#top-right-controls svg { width: 18px; height: 18px; }
/* This cluster hosts the theme toggle, so neutralise the standalone fixed rule */
#top-right-controls #theme-toggle {
    position: static; width: 30px; height: 30px;
    border: none; border-right: 1px solid var(--rule);
    border-radius: 0; background: transparent;
}

/* ---- Paired button rows (Clear / Save, Run Swarm / Stop) --------------
   These were 92px islands in rows that every other card fills edge to edge,
   which is what made them read as a different kind of button. They now share
   the row equally, so every button in the panel has the same geometry. */
.btn-fixed { flex: 1 1 0; width: auto; min-width: 0; text-align: center; }

/* ---- Slider vertical rhythm, one rule for every card ------------------
   No slider carries a note underneath any more - a control's state is read at
   the foot of its own help box - so every slider gets the same caption gap and
   the same gap to what follows. */
.settings-card input[type="range"]              { margin: 12px 0 18px; }

/* ---- Selected-row appearance (lists + candidate table) ---------------- */
/* A tint and a hairline outline are enough to say which row is selected; the
   inset accent bar pulled the eye to the left edge of the table instead. */
.row-selected {
    background: color-mix(in srgb, var(--accent) 18%, transparent) !important;
    outline: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
    font-weight: 600;
}

/* ---- Lattice-parameter rows (built in JS) ----------------------------- */
.lattice-param-row {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 6px;
}
.lattice-param-row .control-label { align-self: center; margin: 0; }

/* ---- Space-group modal ------------------------------------------------ */
.modal-overlay {
    display: none; position: fixed; inset: 0; z-index: 10000;
    background: color-mix(in srgb, #000 42%, transparent);
    align-items: center; justify-content: center;
}
.modal-content {
    background: var(--bg-elevated); color: var(--fg);
    border: 1px solid var(--rule); border-radius: var(--r-3);
    box-shadow: var(--shadow-2);
    padding: 20px; width: 800px; max-width: 90vw; max-height: 90vh;
    display: flex; flex-direction: column;
}
.modal-content > h2 { margin-top: 0; }
.sg-search-row { display: flex; gap: 10px; margin-bottom: 10px; }
.sg-search-row .sg-num { flex: 0 0 130px; }
.sg-search-row .sg-sym { flex: 1 1 auto; }
.sg-chip-group { margin-bottom: 10px; }
.sg-chip-row   { display: flex; gap: 4px; flex-wrap: wrap; }
.sg-chip-row + .sg-chip-row { margin-top: 4px; }
.sg-axes-label { font-size: .72rem; color: var(--fg-3); margin-top: 4px; }
.sg-panes      { display: flex; gap: 10px; flex: 1 1 auto; min-height: 0; }
.sg-panes > .info-box { flex: 1; overflow-y: auto; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 15px; }

/* ---- One-off placements that were inline ------------------------------ */
.tag-warn.inline-flag    { margin-left: 10px; }
.readout.note-inline     { margin-left: 10px; }
.readout.note-quiet      { margin-left: 10px; opacity: .7; }
.candidates-box          { padding: 0; max-height: 220px; overflow-x: hidden; }
.edit-list-empty         { font-size: .68rem; padding: 14px 0; }
.info-box.contacts-list  { margin-top: 8px; max-height: 170px; font-size: 11px; }
.info-box.quality-note   { margin-top: 8px; font-size: 11px; }
.pane-actions.align-end  { justify-content: flex-end; }
.scale-caption.align-end { text-align: right; }
.log-box { max-height: 260px; }


/* ==========================================================================
   Control-panel rhythm & type roles (authoritative)
   --------------------------------------------------------------------------
   One deterministic system for every left-panel card. All flow margins are
   reset, then rebuilt with adjacent-sibling rules (no margin-collapse guesswork):
       group -> group        = 16px
       within a group        = 6px   (caption -> control -> hint)
   Type roles, each uniform across the whole panel:
       .caption  = a control's title line (.field-label and boolean .check-row)
       .hint     = an explanatory sub-line (.readout)
       .control-label = a small uppercase section divider (a 3rd, distinct role)
   #controls-panel scoping outranks the markup's mb-*/mt-* utilities, so those
   become no-ops and this is what renders.
   ========================================================================== */

/* ---- Type roles -------------------------------------------------------- */
#controls-panel .field-label,
#controls-panel .check-row {
    font-family: var(--font-sans);
    font-size: .78rem; font-weight: 600; color: var(--fg);
    letter-spacing: normal; text-transform: none; line-height: 1.35;
}
#controls-panel .check-row { display: flex; align-items: center; gap: 8px; }
#controls-panel .readout {
    font-family: var(--font-mono);
    font-size: .7rem; font-weight: 400; color: var(--fg-3); line-height: 1.5;
}
#controls-panel .control-label {
    font-family: var(--font-mono);
    font-size: .66rem; font-weight: 600; color: var(--fg-3);
    letter-spacing: .09em; text-transform: uppercase;
}

/* ---- Rhythm: reset, then 16px between groups --------------------------- */
#controls-panel .settings-card > * { margin: 0; }
#controls-panel .settings-card > * + * { margin-top: 16px; }

/* ---- Tighten to 6px within a group (caption -> control -> hint) -------- */
#controls-panel .settings-card > .field-label + input,
#controls-panel .settings-card > .field-label + select,
#controls-panel .settings-card > .field-label + textarea,
#controls-panel .settings-card > .control-label + input,
#controls-panel .settings-card > .control-label + select { margin-top: 6px; }

/* ---- Sliders sit clear of their caption -------------------------------- */
#controls-panel .settings-card > input[type="range"] { margin-top: 12px; }

/* ---- Captions/controls that live inside a wrapper div (cards 1-2) ------ */
#controls-panel .settings-card > div .field-label,
#controls-panel .settings-card > div .control-label { margin: 0 0 6px; }
#controls-panel .settings-card > div .control-input,
#controls-panel .settings-card > div .control-select { margin: 0; }


/* ---- Fix + disabled-state parity (patch) ------------------------------ */
/* Every panel slider is a block, so none carries an inline-baseline gap
   beneath it -> caption-to-slider distance is identical everywhere. */
#controls-panel .settings-card input[type="range"] { display: block; }

/* A disabled control greys its caption and its hint, exactly like a disabled
   boolean row -> disabled state reads the same for every control type. */
#controls-panel .field-label:has(+ input:disabled),
#controls-panel .field-label:has(+ select:disabled),
#controls-panel .field-label:has(+ textarea:disabled) { opacity: .5; }
#controls-panel input:disabled + .readout,
#controls-panel select:disabled + .readout { opacity: .5; }


/* ==========================================================================
   Live readouts inside a help box
   --------------------------------------------------------------------------
   Every per-control explanation used to be a line of text under its control,
   which left some controls two lines taller than others. They then briefly
   opened on hover, which put boxes under the pointer while it was only
   crossing the panel. Both are gone: a control's state now lives at the foot
   of its own help box, so the ONE way to ask a control anything is to click
   its question mark. Nothing in the panel reacts to the pointer merely
   passing over it.
   ========================================================================== */
.tooltiptext .tt-live {
    display: block; margin-top: 11px; padding-top: 9px;
    border-top: 1px solid var(--rule-soft);
    font-family: var(--font-mono); font-size: .7rem; line-height: 1.5;
    color: var(--fg-3);
}
.tooltiptext .tt-live:empty { display: none; }
.tooltiptext .tt-live strong,
.tooltiptext .tt-live b { color: var(--fg); }

/* Sub-line inside a tooltip (e.g. the live GPU limits under Configurations) */
.tooltiptext .tt-sub {
    display: block; font-family: var(--font-mono);
    font-size: .7rem; color: var(--fg-3);
}

/* ==========================================================================
   Slider groups  (card 4: one block of sliders, no section captions)
   ========================================================================== */
#controls-panel .settings-card > .slider-group { margin-top: 16px; }
#controls-panel .settings-card > .slider-group .field-label { margin: 0; }
#controls-panel .settings-card > .slider-group input[type="range"] {
    display: block; width: 100%; margin: 12px 0 18px;
}
#controls-panel .settings-card > .slider-group > input[type="range"]:last-child {
    margin-bottom: 4px;
}

/* ==========================================================================
   Section spacing inside a card
   --------------------------------------------------------------------------
   A .control-label is a section divider, and a button row ends a section, so
   both get more air than the 16px that separates two controls of one group.
   ========================================================================== */
#controls-panel .settings-card > * + .control-label { margin-top: 28px; }
#controls-panel .settings-card > .slider-group + .row,
#controls-panel .settings-card > .grid-2 + .btn,
#controls-panel .settings-card > .grid-2 + .btn-primary { margin-top: 26px; }
