/* ═══════════════════════════════════════════════════════════════════════
   NUCLEORA DESIGN SYSTEM — Phase 8, W0 (shared shell). SINGLE SOURCE OF TRUTH.
   ───────────────────────────────────────────────────────────────────────
   OWNERSHIP: W0 owns this file. W1–W10 CONSUME tokens and must never add,
   rename or re-point one. A workspace that needs a value no token expresses
   files a request to W0 rather than writing a local literal.

   NAMING: the `--n-*` names below are the primitives. Every pre-Phase-8 name
   (`--acc`, `--panel2`, `--line`, `--ink`, `--muted`, `--bg2`, `--on-acc`,
   `--warn`, `--err`, `--good`, `--sp-*`, `--radius-*`, `--ease*`, …) is kept
   as an ALIAS pointing into the new palette — never deleted. 270 uses of
   `--acc` across 51 files depend on that.

   HAIRLINE SPLIT (WCAG 1.4.11): `--n-line-1` is DECORATIVE (~1.3:1 — correct
   for a card edge) and `--n-line-3` is the CONTROL BOUNDARY (>=3:1). Borders
   on inputs/buttons/other interactive controls must use `--n-line-3`;
   `--line` stays aliased to the decorative one for backward compatibility.

   ───────────────────────────────────────────────────────────────────────
   PHASE 8b RETUNE (de-AI-aesthetic pass). The Phase-8 palette above was a
   dark-first surface set with saturated cyan/teal accents, diffuse glow
   shadows and a header gradient. That reads as generated-startup chrome
   rather than instrument software, so the VALUES below were re-pointed.
   Every one of the 116 token NAMES is unchanged, so the retune propagates
   through all 56 adopting module files without editing any of them.

   The four rules the new values follow:
     1. LIGHT IS THE DEFAULT. `:root` is now the light surface set; dark is
        an explicit opt-in via [data-theme="dark"]. (This is the inverse of
        Phase 8 — index.html's pre-paint script was flipped to match.)
     2. SATURATED COLOUR IS DATA SEMANTICS ONLY. Accents are desaturated
        navy/green so that a green "pass" or a red "risk" in a result table
        is the most saturated thing on screen, not the chrome.
     3. NO GLOW, NO GRADIENT, NO GLASS. --glow-acc/--glow-acc2 are zeroed
        (names kept: they resolve, they just paint nothing);
        --header-from/--header-to are the SAME value so the header gradient
        computes flat; --glass is a solid surface, not a translucent one.
        Shadows are tight 1-4px offsets for real floating layers (popovers,
        modals) instead of 12-32px cinematic diffusion.
     4. SMALL RADII. The scale is re-pointed 4/6/10/16 -> 2/3/4/6px.

   ⚠ --radius-pill IS NO LONGER A PILL. It is re-pointed 999px -> 3px. The
   NAME is kept because 30 module files consume it for status chips and
   badges, and re-pointing the value is the only way to de-pill them all
   without editing files this track does not own. If you are adding new
   markup, do not read "pill" as a promise of a 999px radius.

   Contrast was computed, not eyeballed: every text-role token clears WCAG
   AA 4.5:1 against ALL FIVE surfaces --n-bg-0..--n-bg-4 in BOTH themes,
   and --n-line-3/--n-ink-3/--n-focus-ring clear the 3:1 non-text floor.
   Worst measured cases: light --n-base-c 4.73:1, dark --n-base-a 4.50:1,
   dark --n-line-3 3.22:1, light --n-line-3 3.30:1.
   ═══════════════════════════════════════════════════════════════════════ */
:root, :root[data-theme="light"]{
  /* ---- surfaces: 5 elevation steps. Light mode inverts the Phase-8
         ordering: bg-0 is the recessed app background (light grey), and
         bg-1/bg-2 are the white working surfaces that sit ON it. ---- */
  --n-bg-0:#f2f4f6;   /* app background, behind everything */
  --n-bg-1:#ffffff;   /* rail, header, tab strip */
  --n-bg-2:#ffffff;   /* card / panel surface */
  --n-bg-3:#f1f3f5;   /* raised: inputs, hover fills, popovers */
  --n-bg-4:#e4e8ec;   /* highest: active/pressed fills, tooltips */

  /* ---- hairlines ---- */
  --n-line-1:#dce0e5; /* decorative divider, card border */
  --n-line-2:#c2c8cf; /* stronger structural divider */
  --n-line-3:#767f89; /* CONTROL boundary: input/button borders (3.30:1) */

  /* ---- ink ---- */
  --n-ink-1:#13181d;  /* primary text (14.5:1 worst surface) */
  --n-ink-2:#4a535d;  /* secondary text (6.35:1 worst surface) */
  --n-ink-3:#6b747e;  /* tertiary/disabled; large text + UI glyphs only */

  /* ---- semantics. Desaturated navy/green: chrome must never out-saturate
         a data verdict. Green = pass, red = risk, amber = caution. ---- */
  --n-accent:#17457c;      /* deep navy — primary action, selection */
  --n-accent-2:#0b6b45;    /* forest green — pass / validated */
  --n-warn:#7a5206;        /* amber-brown — caution */
  --n-err:#a91f16;         /* oxide red — risk / failure */
  --n-info:#17457c;
  --n-on-accent:#ffffff;   /* text on an accent fill (9.64:1) */

  /* ---- tinted states (pre-resolved flat fills, never alpha over glass) ---- */
  --n-accent-tint:#e9eef4;      /* selected row background */
  --n-accent-tint-2:#dae3ee;    /* selected + hover */
  --n-focus-ring:#17457c;       /* >=3:1 against every surface above */

  /* ---- nucleotide hues (functional, never decorative) ---- */
  --n-base-a:#1f5fa9; --n-base-t:#7a5206; --n-base-g:#0b6b45;
  --n-base-c:#0f6f80; --n-base-u:#2f6f4f;

  /* ---- elevation: tight offsets for genuinely-floating layers only.
         A card does NOT get a shadow in this design; it gets a 1px line. ---- */
  --n-shadow-1:0 1px 1px rgba(19,24,29,.06);
  --n-shadow-2:0 2px 4px rgba(19,24,29,.10);
  --n-shadow-3:0 4px 10px rgba(19,24,29,.14);

  /* ---- legacy aliases — DO NOT REMOVE (270 uses of --acc alone) ---- */
  --bg:var(--n-bg-0); --bg2:var(--n-bg-1);
  --panel:var(--n-bg-2); --panel2:var(--n-bg-3);
  --ink:var(--n-ink-1); --muted:var(--n-ink-2);
  --line:var(--n-line-1);
  --acc:var(--n-accent); --acc2:var(--n-accent-2); --acc3:var(--n-info);
  --warn:var(--n-warn); --err:var(--n-err); --on-acc:var(--n-on-accent);
  --good:var(--n-accent-2); --ok:var(--n-warn); --low:var(--n-err);
  --a:var(--n-base-a); --t:var(--n-base-t); --g:var(--n-base-g);
  --c:var(--n-base-c); --u:var(--n-base-u); --hue-blue:var(--n-base-a);
  --shadow:rgba(19,24,29,.10); --shadow-strong:rgba(19,24,29,.16);
  /* Header is FLAT: both stops are the same colour, so every existing
     `linear-gradient(180deg,var(--header-from),var(--header-to))` call site
     computes a solid fill without being edited. */
  --header-from:var(--n-bg-1); --header-to:var(--n-bg-1);
  /* Glows are OFF. The names still resolve (116-token contract) but paint
     nothing, which removes the accent glow everywhere at once. */
  --glow-acc:0 0 0 rgba(0,0,0,0); --glow-acc2:0 0 0 rgba(0,0,0,0);

  /* ---- previously UNDEFINED but referenced in 6+ files — define them ----
     Measured before Phase 8: 10 custom properties were consumed by
     static/*.js/css and defined nowhere (--border x6 files, --mono x4,
     --accent x2, --fg x2, --panel-bg, --bd, --pnl, --chip, --card-bg,
     --card), plus --glass consumed by lab.html. Each resolved to the empty
     string, so those declarations silently did nothing. All 11 are defined
     here so nothing in the codebase references an undefined variable.
     --glass is deliberately a SOLID surface: lab.html used it for frosted
     translucent panels, and pointing it at an opaque colour removes the
     glassmorphism there without editing that file. */
  --border:var(--n-line-1); --bd:var(--n-line-1);
  --fg:var(--n-ink-1); --card:var(--n-bg-2); --card-bg:var(--n-bg-2);
  --panel-bg:var(--n-bg-2); --pnl:var(--n-bg-2);
  --chip:var(--n-bg-3); --glass:var(--n-bg-2);
  --accent:var(--n-accent);
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;

  /* ---- Phase 8b: two tokens a module asked W0 for and never got ----
     ws_home_project_management.js consumes --n-bg-5 (a surface one step above
     --n-bg-4, for a modal panel) and --n-scrim (the modal backdrop). Both
     were undefined, so `background:var(--n-bg-5)` painted NOTHING and the
     modal backdrop was fully transparent. The W0 contract says a workspace
     needing a value no token expresses files a request to W0 rather than
     writing a local literal -- this is that request, honoured. The scrim is
     deliberately a flat 55% neutral, NOT a backdrop-filter blur. */
  --n-bg-5:#d6dbe1;
  --n-scrim:rgba(19,24,29,.55);
}
/* ── Dark mode: now an explicit opt-in, not the default. A high-contrast
      neutral charcoal — not a blue-black "night mode" glow surface. Every
      text-role token here was lifted until it cleared 4.5:1 against all
      five surfaces (worst case --n-base-a at 4.50:1). ── */
:root[data-theme="dark"]{
  --n-bg-0:#16191d; --n-bg-1:#1c2025; --n-bg-2:#21262c;
  --n-bg-3:#2a3037; --n-bg-4:#353c45;
  --n-line-1:#2f353c; --n-line-2:#414952; --n-line-3:#818b95;
  --n-ink-1:#e7eaee; --n-ink-2:#a9b1bb; --n-ink-3:#818b95;
  --n-accent:#7baad5; --n-accent-2:#44b989;
  --n-warn:#d29b40; --n-err:#e58d85; --n-info:#7baad5;
  --n-on-accent:#101418;
  --n-accent-tint:#1e2b3a; --n-accent-tint-2:#26364a;
  --n-focus-ring:#7baad5;
  --n-base-a:#72a9e1; --n-base-t:#d29b40; --n-base-g:#44b989;
  --n-base-c:#5fb1bf; --n-base-u:#86bd9a;
  --n-shadow-1:0 1px 1px rgba(0,0,0,.18);
  --n-shadow-2:0 2px 4px rgba(0,0,0,.24);
  --n-shadow-3:0 4px 10px rgba(0,0,0,.30);
  --n-bg-5:#3c444c;
  --n-scrim:rgba(0,0,0,.60);
  /* dark-mode overrides of the non-var() legacy aliases */
  --shadow:rgba(0,0,0,.24); --shadow-strong:rgba(0,0,0,.34);
}
/* ── Spacing (4px grid), type scale, radius, border-width, motion.
      `--sp-*` and `--ease*` already existed and keep their values;
      --sp-0/--sp-8/--sp-px are added, and the radius scale is re-pointed
      to the Phase-8 values (§1.7). ── */
:root{
  --sp-0:0; --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px;
  --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px;
  --sp-px:1px;

  --font-ui:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
  --font-mono:ui-monospace,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;

  /* Phase 8b: line-heights tightened one notch across the scale (denser
     readout, less marketing airiness) and the two display steps pulled down
     — a 28px headline is a landing page, not a tool window. */
  --fs-1:11px;   --lh-1:1.35;   /* micro: badges, counts, table sub-labels   */
  --fs-2:12px;   --lh-2:1.38;   /* dense UI: rail items, table cells, chips  */
  --fs-3:13px;   --lh-3:1.45;   /* BODY DEFAULT — forms, prose, buttons      */
  --fs-4:14px;   --lh-4:1.30;   /* card title (h2/h3)                        */
  --fs-5:16px;   --lh-5:1.25;   /* view title (h1 inside a view)             */
  --fs-6:19px;   --lh-6:1.18;   /* page/app title                            */
  --fs-7:24px;   --lh-7:1.12;   /* numeric readout, dashboard KPI            */

  /* Weights pulled back: 750 headings read as advertising. Scientific
     software tops out around semibold. */
  --fw-normal:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;
  /* --ls-tight is now ZERO. Negative tracking on large headings is one of
     the most reliable generated-marketing tells; the name is kept because
     module files consume it. */
  --ls-tight:0; --ls-normal:0; --ls-caps:.04em;
  --fs-mono-1:12px; --fs-mono-2:12.5px;  /* sequence text */

  /* Phase 8b: the whole radius scale re-pointed DOWN. Sharp practical
     panels, not rounded-2xl marketing cards. See the --radius-pill warning
     in the header comment — it is 3px now, not 999px. */
  --radius-xs:2px;   /* chips, badges, tags         */
  --radius-sm:3px;   /* buttons, inputs, rail items */
  --radius-md:4px;   /* cards, panels, popovers     */
  --radius-lg:6px;   /* modals, sheets              */
  --radius-pill:3px;

  --bw-1:1px; --bw-2:2px;

  /* Phase 8b: MOTION IS OFF. All three durations are 0ms, so every
     every `transition` duration and token-driven animation across the 56
     adopting module files becomes an instant state change without editing
     any of them. The --ease* curves are retained (names are consumed) but
     are inert at zero duration. Updates should feel like a native control
     repainting, not like a page animating in. */
  --ease:cubic-bezier(.22,.75,.32,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur-1:0ms;  /* hover, colour change      */
  --dur-2:0ms;  /* disclosure open/close     */
  --dur-3:0ms;  /* view transition, modal    */
}
/* ── Density (§1.10). ONE global control, persisted, on <html>. W1–W10 must
      express row heights as var(--row-h) so the switch works everywhere at
      once. `comfortable` is the default and is also declared on bare :root
      so --row-h/--density-pad always resolve even before the attribute is
      written (ws_subapp_settings.js also writes data-density; same two
      values, so the two controls agree rather than fight).

      Phase 8b: both steps tightened (34/28 -> 28/24) and comfortable's
      vertical padding cut a step. 34px rows are a touch-target height; this
      is a desktop workbench where 428 destinations have to fit a rail. ── */
:root,
:root[data-density="comfortable"]{ --row-h:28px; --density-pad:var(--sp-1) var(--sp-3); }
:root[data-density="compact"]    { --row-h:24px; --density-pad:var(--sp-px) var(--sp-2); }

/* ── Tier filter (§3.1). Pure CSS: no JS re-render, so switching tiers
      cannot trigger the §6.2 page-wipe failure mode. Absence of
      [data-ui-tier] == "full" (everything visible), so an un-tagged item is
      never hidden — items without data-tier are ALWAYS visible. ── */
:root[data-ui-tier="guided"]   [data-tier="standard"],
:root[data-ui-tier="guided"]   [data-tier="full"],
:root[data-ui-tier="standard"] [data-tier="full"]{display:none}

/* ── Motion: honour prefers-reduced-motion globally (§1.7). ── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{font-family:var(--font-ui);
  background:var(--bg);color:var(--ink);font-size:var(--fs-3);line-height:var(--lh-3);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
header{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;
  padding:7px 14px;border-bottom:var(--bw-1) solid var(--n-line-2);background:var(--n-bg-1)}
.brand{display:flex;gap:12px;align-items:center;min-width:0}
.logo{display:block;flex-shrink:0}
header h1{margin:0;font-size:var(--fs-6);line-height:var(--lh-6);
  font-weight:var(--fw-semibold);letter-spacing:0}
.tagline{color:var(--muted);font-size:12px;letter-spacing:.01em}
.header-right{display:flex;gap:8px;align-items:center;flex-wrap:wrap;min-width:0}
.badges{display:flex;gap:5px;margin-right:8px;flex-wrap:wrap}
.badge{font-size:var(--fs-1);padding:1px 5px;border-radius:var(--radius-xs);
  font-weight:var(--fw-medium);font-family:var(--font-mono)}
.badge.on{background:rgba(75,191,151,.16);color:var(--acc2)}
.badge.off{background:rgba(224,104,95,.14);color:var(--err)}
.tabs{display:flex;gap:2px;padding:0 20px;background:var(--panel);border-bottom:1px solid var(--line);flex-wrap:wrap}
.tab{padding:11px 17px;cursor:pointer;color:var(--muted);border-bottom:2px solid transparent;font-weight:600;
  user-select:none;transition:color .15s var(--ease),border-color .15s var(--ease)}
.tab:hover{color:var(--ink)}
.tab.active{color:var(--acc);border-bottom-color:var(--acc)}
main{padding:22px 22px 56px;max-width:1400px;margin:0 auto}
.view{display:none}
/* Phase 8b: no entrance animation. A view appears when you click its rail
   item; fading + sliding it in is a marketing-site affordance that costs
   220ms of every navigation. `view-in` is retained as an EMPTY keyframe
   because .empty-coach and .cal-row still reference it by name. */
.view.active{display:block}
@keyframes view-in{from{opacity:1}to{opacity:1}}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);margin-bottom:var(--sp-4)}
@media(max-width:1000px){.grid-2{grid-template-columns:1fr}}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-md);padding:var(--sp-3) var(--sp-4)}
.card-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--sp-3)}
.card h2{margin:0 0 2px;font-size:var(--fs-4);line-height:var(--lh-4);font-weight:var(--fw-semibold);letter-spacing:0}
.card-actions{display:flex;gap:6px;align-items:center}
.sub{color:var(--muted);font-size:12.5px;margin-bottom:var(--sp-3);line-height:1.55}
label{display:block;font-size:11.5px;color:var(--muted);margin:var(--sp-2) 0 4px;font-weight:650;
  text-transform:uppercase;letter-spacing:.03em}
label.chk{display:inline-flex;gap:5px;align-items:center;color:var(--ink);margin:0;cursor:pointer;
  font-weight:500;text-transform:none;letter-spacing:normal;font-size:13px}
/* Controls carry the AA control boundary (--n-line-3), not the decorative
   hairline, and focus is a crisp 2px ring rather than a 3px accent bloom. */
input[type=text],input[type=number],textarea,select{width:100%;background:var(--n-bg-1);
  border:var(--bw-1) solid var(--n-line-3);
  color:var(--ink);border-radius:var(--radius-sm);padding:5px 8px;font-size:var(--fs-3);font-family:inherit}
input[type=text]:focus,input[type=number]:focus,textarea:focus,select:focus{outline:var(--bw-2) solid var(--n-focus-ring);
  outline-offset:-1px;border-color:var(--n-line-3)}
/* Numeric entry is monospaced with tabular figures so digits align in a
   column and a changing value does not reflow the field. */
input[type=number]{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
input.mini{width:130px;padding:5px 8px;font-size:12px}
textarea.seq-edit{font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:12.5px;letter-spacing:.4px;
  resize:vertical;line-height:1.7}
.seq-edit{min-height:64px}
#editorSeq{min-height:150px}
.row{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:flex-start}
.row>div{flex:1;min-width:120px}
button{background:var(--acc);color:var(--on-acc);border:var(--bw-1) solid transparent;
  border-radius:var(--radius-sm);padding:5px 12px;font-size:var(--fs-3);
  font-weight:var(--fw-medium);cursor:pointer}
button:hover{filter:brightness(1.08)}
button:active{transform:translateY(1px)}
button:focus-visible{outline:var(--bw-2) solid var(--n-focus-ring);outline-offset:1px}
button.ghost{background:var(--n-bg-1);color:var(--ink);border:var(--bw-1) solid var(--n-line-3);
  font-weight:var(--fw-medium)}
button.ghost:hover{background:var(--n-bg-3)}
button.sm{padding:3px 9px;font-size:var(--fs-2)}
button:disabled{opacity:.5;cursor:not-allowed;filter:none;transform:none}
.btn-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.opts-row{display:flex;gap:16px;flex-wrap:wrap;margin:12px 0}
.opts-group-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted);margin:14px 0 2px;border-top:var(--bw-1) solid var(--border);padding-top:var(--sp-3)}
.opts-group-label:first-child{border-top:none;padding-top:0;margin-top:2px}
.gc-target-row{align-items:center}
/* Phase 8b: index.html no longer contains a type=range (all 5 became numeric
   inputs with explicit units). This rule is retained for any range input a
   module injects, with the dead hex fallback removed -- --accent is defined. */
.gc-target-row input[type=range]{flex:1;min-width:140px;max-width:280px;accent-color:var(--accent)}
/* the numeric GC field + its unit sit inline on the same row */
.gc-target-row input[type=number]{flex:0 0 auto;width:76px}
.gc-target-row input[type=range]:disabled{opacity:.4}
.wide-input{width:100%;box-sizing:border-box}
.editor-stats{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.stat{background:var(--panel2);border:1px solid var(--line);border-radius:7px;padding:5px 10px;font-size:12px}
.stat b{color:var(--acc)}
/* Sequence/plasmid map holder. Phase 8b: the radial vignette and inset
   highlight are gone -- a flat plotting surface with a 1px frame, like any
   other instrument canvas. The ring itself is drawn by Nucleora's own SVG map
   renderer (static/nvp_map.js); seqviz was removed. */
.map-holder{height:420px;background:var(--n-bg-1);
  border:var(--bw-1) solid var(--n-line-2);border-radius:var(--radius-md);overflow:hidden}
/* C1: map legend + zoom */
.map-zoom{display:inline-flex;gap:3px;align-items:center}
.map-zoom .xs,.map-sel .xs,.fd-body .xs{padding:2px 7px;font-size:11px}
button.xs{padding:2px 7px;font-size:11px;background:var(--panel2);color:var(--ink);border:1px solid var(--line);font-weight:600}
.map-legend{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin:0 2px 8px;font-size:11px;color:var(--muted)}
.map-legend .lg{display:inline-flex;align-items:center;gap:5px}
.lg-sw{width:12px;height:12px;border-radius:3px;display:inline-block}
.lg-sw.lg-line{width:2px;height:13px;border-radius:0;background:var(--muted)}
.lg-hint{margin-left:auto;font-style:italic;opacity:.8}
/* C2: clicked-feature detail */
.map-feat-detail{display:none;margin-top:8px;padding:9px 12px;background:var(--bg2);
  border-left:3px solid var(--acc);border-radius:8px}
.fd-head{font-size:13px;margin-bottom:3px}
.fd-type{font-size:10px;background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:1px 7px;color:var(--muted);margin-left:6px}
.fd-body{font-size:12px;color:var(--muted);font-family:ui-monospace,monospace}
.fd-aa{margin-top:5px;color:var(--acc2);word-break:break-all}
.scroll-out{max-height:360px;overflow:auto}
.muted{color:var(--muted)}
.seqbox{font-family:ui-monospace,monospace;font-size:12.5px;word-break:break-all;background:var(--bg2);
  border:1px solid var(--line);border-radius:8px;padding:11px;line-height:1.85;max-height:200px;overflow:auto}
.nt-A{color:var(--a)}.nt-T{color:var(--t)}.nt-G{color:var(--g)}.nt-C{color:var(--c)}.nt-U{color:var(--u)}
.protein-seq{font-family:ui-monospace,monospace;font-size:12.5px;word-break:break-all;line-height:1.8;color:var(--muted)}
table{border-collapse:collapse;width:100%;font-size:var(--fs-2);margin-top:var(--sp-2)}
/* Phase 8b: table padding cut 7px/9px -> 3px/7px. A results table is meant
   to show many rows at once. Numerals are tabular so columns align. */
th,td{border:var(--bw-1) solid var(--line);padding:3px 7px;text-align:left;
  font-variant-numeric:tabular-nums}
tbody tr{transition:background .12s var(--ease)}
tbody tr:hover{background:var(--panel2)}
th{background:var(--panel2);color:var(--muted);position:sticky;top:0}
tr.hit{cursor:pointer}tr.hit:hover td{background:var(--panel2)}
.pill{display:inline-block;padding:1px 6px;border-radius:var(--radius-xs);font-size:var(--fs-1);
  font-weight:var(--fw-medium);margin:1px 4px 1px 0;border:var(--bw-1) solid transparent}
.pill.good{background:rgba(75,191,151,.16);color:var(--good)}
.pill.ok{background:rgba(224,164,74,.16);color:var(--ok)}
.pill.low,.pill.high{background:rgba(224,104,95,.16);color:var(--low)}
.pill.info{background:rgba(149,169,160,.16);color:var(--muted)}
.src-tabs{display:flex;gap:4px;margin-bottom:14px}
.src{padding:4px 11px;border-radius:var(--radius-sm);background:var(--n-bg-1);
  border:var(--bw-1) solid var(--n-line-3);
  cursor:pointer;font-size:var(--fs-2);font-weight:var(--fw-medium);color:var(--muted)}
.src.active{background:var(--acc);color:var(--on-acc)}
.err-msg{color:var(--err);font-size:12.5px;margin-top:8px;
  background:rgba(224,104,95,.10);border:1px solid var(--err);border-radius:8px;
  padding:9px 12px;display:flex;align-items:center;gap:8px}
.err-msg::before{content:"[WARN]";flex:0 0 auto}
.ok-msg{color:var(--acc2);font-size:12.5px}
.spinner{display:inline-block;width:13px;height:13px;border:2px solid var(--line);border-top-color:var(--acc);
  border-radius:50%;animation:spin .7s linear infinite;vertical-align:middle;margin-left:6px}
@keyframes spin{to{transform:rotate(360deg)}}
.qc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin:10px 0}
.qc-item{background:var(--panel2);border:1px solid var(--line);border-radius:8px;padding:9px}
.qc-item .m{font-size:11px;color:var(--muted)}
.qc-item .v{font-size:17px;font-weight:700;margin-top:2px}
.seg-map{font-family:ui-monospace,monospace;font-size:11.5px;word-break:break-all;line-height:1.9;
  background:var(--bg2);border:1px solid var(--line);border-radius:8px;padding:11px;max-height:150px;overflow:auto}
.seg{padding:1px 2px;border-radius:3px}
.legend{display:flex;gap:14px;flex-wrap:wrap;margin:10px 0;font-size:11.5px}
.legend span{display:inline-flex;gap:5px;align-items:center}
.swatch{width:13px;height:13px;border-radius:3px;display:inline-block}
/* Parts & provenance panel */
.prov-mapwrap{background:var(--bg2);border:1px solid var(--line);border-radius:8px;padding:6px 4px;margin:6px 0 14px}
.prov-svg{width:100%;height:64px;display:block}
.prov-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px}
.prov-card{background:var(--panel2);border:1px solid var(--line);border-radius:9px;padding:10px 11px;border-left:3px solid var(--acc)}
.prov-head{display:flex;align-items:center;gap:7px;margin-bottom:4px}
.prov-origin{font-weight:600;font-size:12.5px;color:var(--ink);margin-bottom:5px}
.prov-tags{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:5px}
.prov-tag{font-size:10px;background:var(--bg2);border:1px solid var(--line);border-radius:10px;padding:1px 7px;color:var(--muted)}
.prov-tag.mono{font-family:ui-monospace,monospace}
.prov-why{font-size:11px;color:var(--muted);line-height:1.5}
.prov-ref{font-size:10px;color:var(--muted);opacity:.8;margin-top:4px;font-style:italic}
/* Cloning method gallery */
.clone-gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px;margin-bottom:12px}
.clone-tile{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:12px 10px;
  text-align:center;cursor:pointer;transition:transform .1s,border-color .1s,background .1s;user-select:none}
/* Phase 8b: no hover lift (see the .designer-fab note). Surface + border
   only, so the tile does not move under the cursor. */
.clone-tile:hover{background:var(--n-bg-3);border-color:var(--acc)}
.clone-tile.active{border-color:var(--acc);background:var(--n-accent-tint);box-shadow:none}
.clone-tile .ct-ico{display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;margin:0 auto 7px;border-radius:7px;background:var(--panel2);
  border:1px solid var(--line);color:var(--acc);font-size:12px;font-weight:700;letter-spacing:.5px}
.clone-tile.active .ct-ico,.clone-tile:hover .ct-ico{background:var(--acc);color:var(--on-acc);border-color:var(--acc)}
.clone-tile b{display:block;font-size:13px;color:var(--ink)}
.clone-tile span{display:block;font-size:10.5px;color:var(--muted);margin-top:2px;line-height:1.3}
.clone-desc{background:var(--bg2);border-left:3px solid var(--acc);border-radius:7px;padding:9px 12px;
  margin-bottom:12px;font-size:12.5px;color:var(--muted);line-height:1.55}
.c-panel{margin-bottom:6px}
.prebuilt-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 10px;margin-bottom:10px;
  background:var(--panel2);border:1px solid var(--line);border-radius:8px}
.prebuilt-bar select{max-width:260px}
.prebuilt-bar #prebuiltNote{flex-basis:100%;margin-top:2px}
/* History tree (DAG) viewer */
.hist-toolbar{display:flex;align-items:center;gap:12px;margin-bottom:10px}
.dag-canvas{overflow:auto;background:var(--bg2);border:1px solid var(--line);border-radius:8px;padding:8px;min-height:120px;max-height:460px}
.dag-svg{display:block}
.dag-edge{fill:none;stroke:var(--line);stroke-width:1.5}
.dag-node rect{fill:var(--panel2);stroke:var(--line);stroke-width:1}
.dag-node:hover rect{stroke:var(--acc)}
.dag-node.cur rect{fill:color-mix(in srgb,var(--acc) 22%,var(--panel2));stroke:var(--acc);stroke-width:2}
.dag-node.sel rect{stroke:var(--acc2);stroke-width:2}
.dag-node .dag-op{fill:var(--ink);font-size:11px;font-weight:600}
.dag-node .dag-sub{fill:var(--muted);font-size:9.5px}
.dag-detail{margin-top:12px;padding:10px 12px;background:var(--bg2);border-radius:8px;border-left:3px solid var(--acc)}
.dag-diff{margin-top:12px;padding:10px 12px;background:var(--bg2);border-radius:8px;border-left:3px solid var(--acc2)}
.dag-diff h4{margin:0 0 6px;font-size:13px;color:var(--ink)}
/* Parts bin */
.parts-bin summary{cursor:pointer;font-weight:600;color:var(--acc);padding:6px 0}
.parts-bin-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px;margin:8px 0}
.pb-card{background:var(--bg2);border:1px solid var(--line);border-radius:8px;padding:10px}
.pb-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pb-head b{font-size:12.5px;color:var(--ink)}
.pb-dg{font-size:10.5px;font-weight:600;color:var(--acc2);background:color-mix(in srgb,var(--acc2) 15%,transparent);padding:1px 6px;border-radius:8px}
.pb-meta{font-size:10.5px;color:var(--muted)}
.pb-src{font-size:10.5px;color:var(--muted);margin:4px 0}
.pb-note{font-size:11px;color:var(--ink);opacity:.85;line-height:1.4;margin-bottom:6px}
/* Severity-badge validation system (green / sandstone / terracotta) */
/* Phase 8b: the severity trio was a private hardcoded palette on the old eco
   greens/sands, so a "pass" here did not match a "pass" anywhere else. Now
   aliased onto the semantic tokens: one definition, both themes, and severity
   colour is the same colour the rest of the app uses for the same meaning. */
:root{--sev-green:var(--n-accent-2);--sev-sand:var(--n-warn);--sev-terra:var(--n-err)}
.sev-summary{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:8px 0}
.sev-chip{font-size:var(--fs-1);font-weight:var(--fw-medium);padding:1px 6px;border-radius:var(--radius-xs)}
.sev-chip.green{background:color-mix(in srgb,var(--sev-green) 18%,transparent);color:var(--sev-green)}
.sev-chip.sandstone{background:color-mix(in srgb,var(--sev-sand) 20%,transparent);color:var(--sev-sand)}
.sev-chip.terracotta{background:color-mix(in srgb,var(--sev-terra) 20%,transparent);color:var(--sev-terra)}
.sev-grade{margin-left:auto;font-size:11.5px;font-weight:600;color:var(--muted)}
.sev-verdict{padding:8px 12px;border-radius:8px;font-weight:600;font-size:13px;margin:6px 0 12px}
.sev-verdict.green{background:color-mix(in srgb,var(--sev-green) 12%,transparent);color:var(--sev-green)}
.sev-verdict.sandstone{background:color-mix(in srgb,var(--sev-sand) 14%,transparent);color:var(--sev-sand)}
.sev-verdict.terracotta{background:color-mix(in srgb,var(--sev-terra) 14%,transparent);color:var(--sev-terra)}
.sev-row{display:flex;gap:10px;padding:9px 0;border-bottom:1px solid var(--line)}
.sev-badge{font-size:16px;flex:0 0 auto;width:22px;text-align:center}
.sev-body{flex:1}
.sev-title{font-weight:600;font-size:12.5px;color:var(--ink);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.sev-cat{font-size:10px;font-weight:500;color:var(--muted);background:var(--panel2);padding:1px 7px;border-radius:8px}
.sev-pos{font-family:ui-monospace,monospace;font-size:11px;color:var(--acc);cursor:pointer;text-decoration:underline}
.sev-msg{font-size:12px;color:var(--ink);opacity:.85;margin-top:2px;line-height:1.4}
.sev-fix{font-size:11.5px;color:var(--acc2);margin-top:3px}
.sev-clean{color:var(--sev-green);font-weight:600;padding:8px 0}
.sev-row.sandstone .sev-badge{filter:none}
.sev-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:5px}
.sev-reopt-out{margin-top:6px}
.sev-reopt-out:empty{margin-top:0}
/* Multi-objective (Pareto) explorer */
.pareto-panel summary{cursor:pointer;font-weight:600;color:var(--acc);padding:6px 0}
.pareto-sliders{display:flex;flex-direction:column;gap:6px;margin:8px 0}
.pareto-sliders label{display:flex;align-items:center;gap:10px;font-size:12px}
.pareto-sliders input[type=range]{flex:1;max-width:220px}
.pareto-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:10px}
@media(max-width:760px){.pareto-grid{grid-template-columns:1fr}}
.pareto-svg{width:100%;background:var(--bg2);border:1px solid var(--line);border-radius:8px}
.pareto-svg .ax{stroke:var(--line);stroke-width:1}
.pareto-svg .axl{fill:var(--muted);font-size:9px}
.pareto-svg .pt{fill:color-mix(in srgb,var(--acc) 55%,transparent);stroke:var(--acc);stroke-width:1}
.pareto-svg .pt.best{fill:var(--acc2);stroke:var(--ink);stroke-width:1.5}
.pareto-table{width:100%;border-collapse:collapse;font-size:12px}
.pareto-table th{text-align:left;color:var(--muted);font-weight:600;padding:3px 6px;border-bottom:1px solid var(--line)}
.pareto-table td{padding:3px 6px;border-bottom:1px solid var(--line)}
.pareto-table tr.best{background:color-mix(in srgb,var(--acc2) 12%,transparent)}
.pareto-table .mono{font-family:ui-monospace,monospace}
/* Sequence-tuning card (GC / motifs / Kozak / poly(A)) */
#tuneCard h4{margin:0 0 6px;font-size:12.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.03em}
.gc-svg{width:100%;height:90px;background:var(--bg2);border:1px solid var(--line);border-radius:8px}
.gc-svg .gc-ok{fill:color-mix(in srgb,var(--acc2) 9%,transparent)}
.gc-svg .gc-mid{stroke:var(--line);stroke-dasharray:3 3}
.gc-svg .gc-line{fill:none;stroke:var(--acc);stroke-width:1.5}
.gc-svg .gc-cliff{fill:var(--warn)}
.kz-box{display:flex;gap:14px;align-items:flex-start;background:var(--bg2);border-radius:8px;padding:10px 12px}
.kz-score{font-size:26px;font-weight:800;line-height:1}
.kz-score span{font-size:12px;font-weight:500;color:var(--muted)}
.kz-score.green{color:var(--sev-green)} .kz-score.sandstone{color:var(--sev-sand)} .kz-score.terracotta{color:var(--sev-terra)}
.kz-notes{margin:4px 0 0;padding-left:16px;font-size:11.5px;color:var(--ink);opacity:.85}
.mo-list{display:flex;flex-direction:column;gap:2px;margin-top:6px}
.mo-row{padding:7px 0;border-bottom:1px solid var(--line);font-size:12.5px}
.mo-row .mo-pos{color:var(--acc);cursor:pointer;margin-right:8px}
.mo-row.warn{border-left:3px solid var(--sev-sand);padding-left:8px}
.mo-why{font-size:11px;color:var(--muted);margin-top:2px}
/* Translation ribbon */
.rb-modes{display:flex;gap:6px}
.rb-strip{display:flex;flex-wrap:wrap;font-family:ui-monospace,monospace;font-size:12px;line-height:1;margin:4px 0;gap:1px}
.rb-aa{width:15px;height:19px;display:flex;align-items:center;justify-content:center;color:var(--on-acc);
  background:var(--c);border-radius:2px;cursor:default;font-weight:600}
.rb-aa.rare{outline:2px solid var(--sev-terra);outline-offset:-2px}
/* Phase 8b: no hover scale. Magnifying a residue on hover moves the
   neighbours the user is trying to read; the outline marks it instead. */
.rb-aa:hover{outline:var(--bw-2) solid var(--n-ink-1);outline-offset:-1px;z-index:2;position:relative}
.rb-track{position:relative;height:18px;margin-bottom:3px}
.rb-sub{position:absolute;top:0;height:16px;background:color-mix(in srgb,var(--acc) 25%,transparent);
  border:1px solid var(--acc);border-radius:3px;font-size:9.5px;color:var(--ink);white-space:nowrap;
  overflow:hidden;padding:0 3px;box-sizing:border-box}
.rb-leg{display:inline-flex;gap:10px;font-size:11px;color:var(--muted);align-items:center;margin-top:4px}
.rb-leg i{width:11px;height:11px;border-radius:2px;display:inline-block;margin-right:3px;vertical-align:-1px}
.rb-readout{margin-top:8px;padding:7px 10px;background:var(--bg2);border-radius:6px;font-size:12px;min-height:18px}
.rb-readout .mono{font-family:ui-monospace,monospace}
/* Advanced IVT chemistry QC */
.ivt-adv-bar{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin:12px 0 6px;padding:10px;background:var(--bg2);border-radius:8px}
.ivt-adv-bar label{font-size:11.5px;color:var(--muted);display:flex;flex-direction:column;gap:3px}
.ivt-adv-bar select,.ivt-adv-bar input{background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:5px;padding:3px 6px;font-size:12px}
.dsrna-svg{width:100%;height:54px;background:var(--bg2);border-radius:6px;margin:4px 0}
/* Module 4: structure arc diagram + LNP */
.arc-svg{width:100%;height:180px;background:var(--bg2);border:1px solid var(--line);border-radius:8px}
.arc-svg .arc{fill:none;stroke:var(--acc);stroke-width:1.2}
.arc-svg .arc-base{stroke:var(--ink);stroke-width:1.5;opacity:.5}
.uw-box{display:flex;gap:12px;align-items:flex-start;background:var(--bg2);border-radius:8px;padding:10px 12px}
.lnp-controls{display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin:8px 0;padding:10px;background:var(--bg2);border-radius:8px}
.lnp-controls label{font-size:11.5px;color:var(--muted);display:flex;align-items:center;gap:8px}
.lnp-controls input[type=range]{max-width:160px}
.lnp-controls select{background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:5px;padding:3px 6px}
.lnp-cards{display:flex;gap:12px;flex-wrap:wrap;margin:6px 0}
.lnp-metric{background:var(--bg2);border-radius:8px;padding:10px 16px;text-align:center;min-width:96px}
.lnp-metric .n{font-size:22px;font-weight:800;color:var(--acc)}
.lnp-metric .n span{font-size:12px;font-weight:500;color:var(--muted);margin-left:2px}
.lnp-metric .l{font-size:11px;color:var(--muted);margin-top:2px}
/* Module 1: sourcing tools */
.mini-link{font-size:11px;color:var(--acc);cursor:pointer;margin-left:8px;font-weight:500}
.mini-link:hover{text-decoration:underline}
.fetch-card,.swap-card,.anc-card{background:var(--bg2);border-radius:8px;padding:12px;margin-top:8px}
.fetch-feats,.batch-table,.swap-table{width:100%;border-collapse:collapse;margin:8px 0;font-size:12px}
.fetch-feats th,.batch-table th,.swap-table th{text-align:left;color:var(--muted);font-weight:600;border-bottom:1px solid var(--line);padding:3px 6px}
.fetch-feats td,.batch-table td,.swap-table td{padding:3px 6px;border-bottom:1px solid var(--line)}
.batch-table tr.bi-dup td{opacity:.6}
.batch-table tr.bi-warn td{color:var(--sev-terra)}
.btn-row{display:flex;gap:8px;align-items:center;margin-top:8px}
.anc-cov{width:100%;height:40px;background:var(--panel);border-radius:6px;margin:6px 0}
.anc-seq{font-size:11px;word-break:break-all;background:var(--panel);padding:6px;border-radius:6px;margin-top:6px}
.sp-bar{display:inline-block;width:70px;height:8px;background:var(--panel);border-radius:4px;overflow:hidden;vertical-align:middle;margin-right:6px}
.sp-bar>span{display:block;height:100%;background:var(--acc2)}
/* Module 5: sequencing QC + RNA gel */
.rgel-wrap{display:flex;gap:16px;align-items:flex-start;margin-top:8px}
.rgel-lane{position:relative;width:64px;background:var(--n-bg-4);
  border:var(--bw-1) solid var(--n-line-2);border-radius:var(--radius-xs)}
.rgel-well{position:absolute;top:0;left:8px;right:8px;height:5px;background:var(--ink);opacity:.4;border-radius:2px}
/* Phase 8b: bands are solid, not glowing. Band INTENSITY carries meaning on
   a gel; a decorative bloom around every band corrupts that reading. */
.rgel-band{position:absolute;left:6px;right:6px;height:4px;background:var(--acc2);border-radius:0}
/* The smear IS the degradation readout, so the fade is meaningful data and
   is kept -- only the corner radius is squared off. */
.rgel-smear{position:absolute;left:10px;right:10px;background:linear-gradient(var(--acc2),transparent);border-radius:0}
.rgel-trace{width:100%;height:90px;background:var(--bg2);border-radius:6px}
.rgel-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--acc2);margin-right:5px}
.chrom-svg{width:100%;height:70px;background:var(--bg2);border-radius:6px;margin:6px 0}
.ngs-cov{width:100%;height:44px;background:var(--bg2);border-radius:6px;margin:4px 0}
.ivtp-card{background:var(--bg2);border-radius:8px;padding:12px;margin-top:8px}
.ivtp-row{margin:3px 0}
.ivtp-row .mono{background:var(--panel);padding:2px 6px;border-radius:4px}
/* Map layer toolbar */
.map-toolbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:8px 12px;margin-bottom:var(--sp-2);
  background:var(--bg2);border:1px solid var(--line);border-radius:var(--radius-sm);font-size:12px}
.map-toolbar .mt-label{color:var(--muted);font-weight:600;font-size:11px}
.map-toolbar .chk.sm{font-size:12px;color:var(--ink);display:inline-flex;align-items:center;gap:4px}
.map-toolbar .mini{padding:2px 6px;font-size:11.5px}
.map-sel{margin-left:auto;font-size:11.5px;color:var(--muted);font-family:ui-monospace,monospace}
.map-sel b{color:var(--acc)}
.map-topology{font-size:11px;font-weight:600;padding:2px 8px;border-radius:10px;background:var(--panel2);color:var(--muted)}
.map-topology.topo-circular{color:var(--acc2)}
.map-topology.topo-linear{color:var(--muted)}
.map-tooltip{display:none;position:absolute;z-index:400;background:var(--panel2);color:var(--ink);
  border:1px solid var(--line);border-radius:6px;padding:6px 10px;font-size:11.5px;line-height:1.4;
  box-shadow:var(--n-shadow-2);pointer-events:none;max-width:220px}
.ed-ctx-menu{display:none;position:absolute;z-index:500;background:var(--panel2);border:1px solid var(--line);
  border-radius:var(--radius-sm);padding:3px;font-size:var(--fs-2);box-shadow:var(--n-shadow-3);min-width:180px}
.ed-ctx-item{padding:6px 12px;border-radius:5px;cursor:pointer;color:var(--ink)}
.ed-ctx-item:hover{background:var(--acc);color:var(--on-acc)}
.feat-bulk-recolor{display:inline-flex;align-items:center;gap:6px;margin-left:10px}
.feat-bulk-recolor input[type=color]{width:22px;height:22px;padding:0;border:1px solid var(--line);border-radius:4px;background:none}
#featEditorTable th:first-child,#featEditorBody td:first-child{width:22px;text-align:center}
.toast{position:fixed;bottom:22px;left:50%;transform:translateX(-50%) translateY(100px);
  background:var(--panel2);border:1px solid var(--line);color:var(--ink);padding:10px 18px;border-radius:8px;
  font-size:var(--fs-3);z-index:100;box-shadow:var(--n-shadow-3)}
.toast.show{transform:translateX(-50%) translateY(0)}
details{margin-top:8px}summary{cursor:pointer;color:var(--acc);font-size:12.5px}
.small{font-size:11.5px}
a{color:var(--acc);text-decoration:none;transition:opacity .12s var(--ease)}
a:hover{opacity:.82;text-decoration:underline}
h3{font-size:13px;margin:14px 0 6px}
.frame-row{font-family:ui-monospace,monospace;font-size:11.5px;white-space:pre-wrap;word-break:break-all}

/* ===== Multiple sequence alignment ===== */
.msa-summary{font-size:12.5px;margin:8px 0}
.msa-block{overflow-x:auto;font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:12px;
  border:1px solid var(--line);border-radius:8px;padding:8px;background:var(--bg2);white-space:nowrap}
.msa-row{display:flex;gap:10px;line-height:1.5}
.msa-name{flex:0 0 120px;color:var(--muted);text-align:right;user-select:none;overflow:hidden;text-overflow:ellipsis}
.msa-seq{letter-spacing:1px}
.msa-ch{display:inline-block;width:1ch}
.msa-match{color:var(--acc2)}
.msa-mis{color:var(--sev-terra);font-weight:700}
.msa-gap{color:var(--line)}
.msa-consensus{border-top:1px solid var(--line);margin-top:4px;padding-top:4px;font-weight:700}

/* ===== Application-aware auto-configure ===== */
.autoconfig-bar{display:flex;flex-wrap:wrap;align-items:end;gap:12px;margin:10px 0;padding:10px;
  border:1px dashed var(--acc);border-radius:9px;background:color-mix(in srgb,var(--acc) 6%,transparent)}
.autoconfig-bar label{font-size:11.5px;color:var(--muted);display:flex;flex-direction:column;gap:3px}
.ac-picks{margin-top:6px;display:flex;flex-direction:column;gap:3px}
.ac-pick{font-size:11.5px}

/* ===== Multi-antigen (polyvalent) design panel ===== */
.multi-panel{margin:10px 0;border:1px solid var(--line);border-radius:9px;padding:4px 10px;background:var(--panel2)}
.multi-list{display:flex;flex-direction:column;gap:8px;margin-bottom:8px}
.multi-row{display:flex;gap:8px;align-items:flex-start}
.multi-row .mini{flex:0 0 130px}
.multi-seq{flex:1;min-height:44px;font-size:11.5px;letter-spacing:.3px;resize:vertical;
  border:1px solid var(--line);border-radius:7px;padding:6px 8px;background:var(--bg2);color:var(--ink);word-break:break-all}
.ok-msg{color:var(--acc2);font-size:12.5px;padding:6px 0}

/* ===== Cap-fix action row (advanced chemistry QC) ===== */
.ivt-fix-row{display:flex;align-items:center;gap:9px;margin-top:7px}
.ivt-fix-row button.sm{white-space:nowrap}

/* ===== Protein / peptide view in the editor ===== */
.pep-view{padding:14px}
.pep-head{margin-bottom:10px}
.pep-cards{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:10px}
.pep-metric{flex:1 1 120px;min-width:110px;padding:9px 11px;border:1px solid var(--line);border-radius:9px;background:var(--panel2)}
.pep-metric .n{font-size:19px;font-weight:800}
.pep-metric .n span{font-size:11px;color:var(--muted);font-weight:600}
.pep-metric .n.pos{color:var(--acc2)} .pep-metric .n.neg{color:var(--sev-terra)}
.pep-metric .l{font-size:10.5px;color:var(--muted);margin-top:2px}
.aa-legend{display:flex;flex-wrap:wrap;gap:12px;font-size:11px;color:var(--muted);margin:6px 0 8px}
.aa-legend i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:4px;vertical-align:-1px}
.aa-legend .aa-pos{background:var(--acc2)} .aa-legend .aa-neg{background:var(--err)}
.aa-legend .aa-hydro{background:var(--warn)} .aa-legend .aa-polar{background:var(--hue-blue)}
.aa-legend .aa-special{background:var(--acc3)}
.pep-ribbon{line-height:2;word-break:break-all;background:var(--bg2);border-radius:8px;padding:10px}
.pep-ribbon .aa{padding:1px 0;border-radius:2px}
.pep-ribbon .aa-pos{color:var(--acc2);font-weight:700} .pep-ribbon .aa-neg{color:var(--err);font-weight:700}
.pep-ribbon .aa-hydro{color:var(--warn)} .pep-ribbon .aa-polar{color:var(--hue-blue)}
.pep-ribbon .aa-special{color:var(--acc3);font-weight:700} .pep-ribbon .aa-other{color:var(--muted)}

/* ===== ProteinEnzymePredictionSuite ===== */
.pep-suite-launch{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}
.ps-loading{padding:14px;color:var(--muted)}
.ps-summary{padding:10px 0 14px;font-size:14px}
.ps-cats{display:flex;flex-direction:column;gap:8px}
.ps-cat{border:1px solid var(--line);border-radius:9px;background:var(--panel2);overflow:hidden}
.ps-cat summary{cursor:pointer;padding:10px 12px;font-weight:700;font-size:13px;list-style:none}
.ps-cat summary::-webkit-details-marker{display:none}
.ps-cat summary::before{content:"▸ ";color:var(--muted)}
.ps-cat[open] summary::before{content:"▾ "}
.ps-cat-body{padding:4px 12px 12px}
.ps-field{margin:8px 0;padding-left:8px;border-left:2px solid var(--line)}
.ps-field-name{font-size:11.5px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.02em;margin-bottom:3px}
.ps-leaf{margin:2px 0 8px}
.ps-leaf-val{font-size:13px}
.ps-cite{font-size:10.5px;color:var(--muted);margin-top:2px;font-style:italic}
.ps-kv{border-collapse:collapse;font-size:12.5px}
.ps-kv td{padding:2px 8px 2px 0;vertical-align:top}
.ps-kv td:first-child{color:var(--muted);white-space:nowrap}
.ps-hitlist{margin:2px 0;padding-left:16px;font-size:12px}
.ps-hitlist li{margin:1px 0}

/* ===== Calibration & verification — same conic-ring treatment as the
      Construct Health Score, plus a subtle row-reveal stagger so a long
      pass/fail list doesn't dump onto screen all at once ===== */
.cal-summary{display:flex;align-items:center;gap:18px;padding:15px 17px;border-radius:var(--radius-md);
  margin-bottom:var(--sp-4);border:1px solid var(--line);background:var(--panel2)}
.cal-summary.cal-good{border-color:var(--sev-green)}
.cal-summary.cal-bad{border-color:var(--sev-terra)}
.cal-score{position:relative;width:64px;height:64px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:20px;font-weight:800;line-height:1;flex:0 0 auto;
  background:conic-gradient(var(--gauge-c,var(--muted)) calc(var(--pct,0)*1%),var(--line) 0)}
.cal-score::before{content:"";position:absolute;inset:4px;border-radius:50%;background:var(--panel2)}
.cal-score>*{position:relative}
.cal-good .cal-score{--gauge-c:var(--sev-green);color:var(--sev-green)}
.cal-bad .cal-score{--gauge-c:var(--sev-terra);color:var(--sev-terra)}
.cal-score span{display:block;font-size:10px;color:var(--muted);font-weight:600}
.cal-list{display:flex;flex-direction:column;gap:2px}
.cal-row{display:flex;align-items:center;gap:10px;padding:6px 10px;border-radius:7px;font-size:12.5px;
  /* Phase 8b: staggered row entrance removed (see @keyframes below). */}
.cal-row:nth-child(odd){background:var(--panel2)}
.cal-row:hover{background:var(--bg2)}
@keyframes cal-row-in{from{opacity:1}to{opacity:1}}
.cal-mark{flex:0 0 auto;width:18px;text-align:center;font-weight:800}
.cal-row.ok .cal-mark{color:var(--sev-green)} .cal-row.bad .cal-mark{color:var(--sev-terra)}
.cal-row.skip .cal-mark{color:var(--muted)} .cal-row.skip{opacity:.7}
.cal-row.skip .cal-detail{color:var(--muted)}
.cal-label{flex:1;min-width:0}
.cal-detail{color:var(--sev-terra);font-size:11px;overflow-wrap:anywhere}

/* ===== Multi-construct tabs ===== */
.tab-bar{display:flex;align-items:flex-end;gap:3px;padding:6px 14px 0;background:var(--panel);
  border-bottom:1px solid var(--line);overflow-x:auto;flex-wrap:nowrap}
.tab-bar .tab{display:inline-flex;align-items:center;gap:7px;padding:7px 12px;border-radius:8px 8px 0 0;
  border:1px solid var(--line);border-bottom:none;background:var(--panel2);color:var(--muted);
  cursor:pointer;font-size:12.5px;font-weight:600;max-width:220px;white-space:nowrap;flex:0 0 auto}
.tab-bar .tab.active{background:var(--bg);color:var(--ink);border-color:var(--acc);position:relative;top:1px}
.tab-bar .tab-dot{width:7px;height:7px;border-radius:50%;background:var(--muted);flex:0 0 auto}
.tab-bar .tab.active .tab-dot{background:var(--acc)}
.tab-bar .tab-title{overflow:hidden;text-overflow:ellipsis;max-width:160px}
.tab-bar .tab-x{font-size:15px;line-height:1;opacity:.6;border-radius:4px;padding:0 3px}
.tab-bar .tab-x:hover{opacity:1;background:var(--panel);color:var(--sev-terra)}
.tab-bar .tab-new{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;
  border:1px solid var(--line);border-radius:8px;background:var(--panel2);color:var(--muted);cursor:pointer;flex:0 0 auto;margin-left:2px}
.tab-bar .tab-new:hover{color:var(--acc);border-color:var(--acc)}
.tab-bar .tab-new .icn{width:15px;height:15px}

/* ===== Recent antigens ===== */
.recent-antigens{margin-bottom:14px;padding:9px 12px;border:var(--bw-1) solid var(--line);
  border-radius:var(--radius-sm);background:var(--n-bg-3)}
.ra-head{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.ra-list{display:flex;flex-wrap:wrap;gap:8px}
.ra-item{display:flex;flex-direction:column;align-items:flex-start;gap:2px;padding:8px 12px;
  border:1px solid var(--line);border-radius:9px;background:var(--panel);cursor:pointer;text-align:left;min-width:150px}
.ra-item:hover{border-color:var(--acc)}
.ra-name{font-weight:650;font-size:12.5px;color:var(--ink);max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ra-meta{font-size:10.5px;color:var(--muted)}

/* ===== Construct Health Score — the flat ring became a conic-gradient
      progress dial (--pct set inline by JS from the numeric score) so the
      score reads at a glance rather than needing the number underneath. ===== */
.health-card{display:flex;gap:18px;align-items:center;margin:4px 0 var(--sp-4);padding:15px 17px;
  border:1px solid var(--line);border-radius:var(--radius-md);background:var(--panel2);
}
/* Phase 8b: no hover shadow lift on a status card (it is not clickable). */
.hs-gauge{--pct:0;flex:0 0 auto;width:76px;height:76px;border-radius:50%;display:flex;flex-direction:column;
  align-items:center;justify-content:center;position:relative;
  background:conic-gradient(var(--gauge-c,var(--muted)) calc(var(--pct)*1%),var(--line) 0);
  transition:background 1s var(--ease-out)}
.hs-gauge::before{content:"";position:absolute;inset:5px;border-radius:50%;background:var(--panel2)}
.hs-gauge.hs-good{--gauge-c:var(--sev-green)}
.hs-gauge.hs-ok{--gauge-c:var(--sev-sand)}
.hs-gauge.hs-bad{--gauge-c:var(--sev-terra)}
.hs-num{position:relative;font-size:24px;font-weight:800;line-height:1}
.hs-good .hs-num{color:var(--sev-green)} .hs-ok .hs-num{color:var(--sev-sand)} .hs-bad .hs-num{color:var(--sev-terra)}
.hs-of{position:relative;font-size:10px;color:var(--muted);margin-top:1px}
.hs-grade{position:absolute;top:-8px;right:-8px;width:22px;height:22px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:800;color:var(--on-acc);
  box-shadow:var(--n-shadow-1)}
.hs-good .hs-grade{background:var(--sev-green)} .hs-ok .hs-grade{background:var(--sev-sand)} .hs-bad .hs-grade{background:var(--sev-terra)}
.hs-body{min-width:0;flex:1}
.hs-title{font-weight:700;font-size:14.5px;margin-bottom:5px;letter-spacing:-.005em}
.hs-ded{font-size:12px;line-height:1.6;margin-bottom:5px;overflow-wrap:anywhere}
.hs-pts{color:var(--sev-terra);font-weight:700;font-size:11px}
.hs-clean{font-size:12.5px;color:var(--sev-green);font-weight:600;margin-bottom:5px}

/* ===== A3: guided-workflow step progress ===== */
.step-progress{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:14px}
.sp-step{display:inline-flex;align-items:center;gap:7px;background:var(--panel2);color:var(--muted);
  border:var(--bw-1) solid var(--n-line-3);border-radius:var(--radius-sm);padding:3px 10px;
  font-size:var(--fs-2);font-weight:var(--fw-medium);cursor:pointer}
.sp-step .sp-n{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;
  border-radius:50%;background:var(--bg2);font-size:11px}
.sp-step.current{border-color:var(--acc);color:var(--ink)}
.sp-step.current .sp-n{background:var(--acc);color:var(--on-acc)}
.sp-step.done{color:var(--acc2);border-color:var(--acc2)}
.sp-step.done .sp-n{background:var(--acc2);color:var(--on-acc)}
.sp-step:disabled{opacity:.45;cursor:not-allowed}
.sp-arrow{color:var(--muted)}

/* ===== D1: guided tour ===== */
.tour-overlay{display:none;position:fixed;inset:0;z-index:250;background:rgba(0,0,0,.55)}
.tour-overlay.show{display:block}
.tour-spot{position:absolute;border-radius:var(--radius-sm);box-shadow:0 0 0 9999px rgba(0,0,0,.55);
  border:2px solid var(--acc);transition:all .25s ease;pointer-events:none}
.tour-card{position:absolute;width:300px;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-md);padding:12px 14px;box-shadow:var(--n-shadow-3);z-index:251}
.tour-title{font-weight:700;font-size:14px;margin-bottom:6px;color:var(--acc)}
.tour-body{font-size:12.5px;color:var(--ink);line-height:1.55}
.tour-foot{display:flex;align-items:center;justify-content:space-between;margin-top:12px}
.tour-count{font-size:11px;color:var(--muted)}
.tour-foot button{margin-left:6px}

/* ===== expanded Sequence Editor: find/replace, jump-to-position, feature editor ===== */
.ed-toolbar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:7px 10px;margin-bottom:8px;
  background:var(--bg2);border:1px solid var(--line);border-radius:8px}
.ed-tb-group{display:inline-flex;align-items:center;gap:5px}
.ed-tb-group .mini{width:140px}
.ed-find-count{color:var(--muted);font-size:11px;min-width:44px}
.ed-inline-label{display:inline;margin:0;color:var(--muted);font-size:11px;font-weight:600}
.ed-tb-jump{margin-left:auto}
.seq-edit.ed-has-match{outline:2px solid var(--acc)}
/* highlight overlay: an inert, identically-metriced div sits directly behind the
   transparent-background textarea so find-hits / the current match / selection
   ranges can be painted as <mark>-style spans without touching the real value. */
.ed-edit-wrap{position:relative}
.ed-highlight-overlay{position:absolute;inset:0;margin:0;color:transparent;background:transparent;
  overflow:auto;white-space:pre-wrap;word-break:break-all;pointer-events:none;border-color:transparent}
.ed-edit-wrap textarea.seq-edit{position:relative;background:transparent;z-index:1}
.ed-edit-wrap{background:var(--panel2);border-radius:8px}
.eh-hit{background:rgba(90,169,255,.28);border-radius:2px}
.eh-hit-current{background:var(--acc);color:var(--on-acc);border-radius:2px}
.ed-caret-readout{color:var(--muted);font-size:11px;margin-top:4px}
.feat-editor{margin-top:14px;border-top:1px solid var(--line);padding-top:12px}
.feat-editor-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}
.feat-editor-head h3{margin:0;font-size:13px}
.feat-editor-table{width:100%;border-collapse:collapse;font-size:12px}
.feat-editor-table th{background:var(--panel2);color:var(--muted);text-align:left;padding:5px 6px}
.feat-editor-table td{padding:3px 6px;border-bottom:1px solid var(--line)}
.feat-editor-table input[type=text]{padding:4px 6px;font-size:11.5px;width:100%;min-width:60px}
.feat-editor-table input[type=number]{padding:4px 6px;font-size:11.5px;width:72px}
.feat-editor-table select{padding:4px 6px;font-size:11.5px}
.feat-editor-table input[type=color]{width:30px;height:24px;padding:0;border:1px solid var(--line);border-radius:4px;cursor:pointer}
.feat-row-invalid td{background:rgba(224,104,95,.08)}
.feat-row-err{color:var(--err);font-size:10.5px}

/* ===== persistent "back to guided Design workflow" control ===== */
.designer-fab{position:fixed;right:20px;bottom:20px;z-index:230;display:inline-flex;align-items:center;gap:7px;
  background:var(--acc);color:var(--on-acc);border:var(--bw-1) solid var(--n-line-3);
  border-radius:var(--radius-sm);padding:6px 12px;
  font-size:var(--fs-2);font-weight:var(--fw-medium);cursor:pointer;box-shadow:var(--n-shadow-2);
  text-decoration:none}
/* Phase 8b: no lift-on-hover. Surface change only -- hover must never move
   a control the user is aiming at. */
.designer-fab:hover{background:var(--n-accent-tint-2);color:var(--n-accent)}
.designer-fab .icn{width:16px;height:16px;flex:0 0 auto}
body.rail-collapsed .designer-fab{right:20px}
@media(max-width:640px){.designer-fab span:not(.icn){display:none}.designer-fab{padding:7px}}

/* ===== B3: top progress bar (shown while any request is in flight) ===== */
.topbar{position:fixed;top:0;left:0;height:3px;width:100%;z-index:300;
  background:transparent;overflow:hidden;pointer-events:none;opacity:0;transition:opacity .2s}
.topbar.show{opacity:1}
/* Phase 8b: the 3px progress bar no longer sweeps. An indeterminate
   animation implies progress information the app does not have; a static
   accent rule is an honest "busy" signal. The keyframe name is retained
   because the reduced-motion block below still references it. */
.topbar::before{content:"";position:absolute;height:100%;width:100%;left:0;
  background:var(--acc)}
@keyframes tb-slide{from{left:0}to{left:0}}
body.busy{cursor:progress}

/* ===== B1: inline error panel with retry ===== */
.err-panel{display:flex;align-items:center;gap:10px;background:rgba(224,104,95,.10);
  border:1px solid var(--err);border-radius:8px;padding:10px 12px;margin:8px 0}
.err-ic{color:var(--err);font-size:16px;flex:0 0 auto}
.err-txt{flex:1;color:var(--ink);font-size:12.5px}

/* ===== D3: empty-state coach. Phase 8b: the dotted "illustration"
      backdrop and the entrance animation are gone -- it is a bordered
      notice, which is what it actually is. ===== */
.empty-coach{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  background:var(--n-bg-3);
  border:var(--bw-1) solid var(--n-line-2);border-left:3px solid var(--n-line-3);
  border-radius:var(--radius-sm);padding:var(--sp-3) var(--sp-4);margin:0 0 var(--sp-4)}
.ec-txt{color:var(--muted);font-size:13px;line-height:1.5}
.ec-btns{display:flex;gap:6px}

/* ===== A1: persistent active-construct bar ===== */
.construct-bar{background:var(--panel2);border-bottom:1px solid var(--line);
  padding:7px 22px;font-size:12.5px;cursor:pointer;position:sticky;top:0;z-index:40}
.construct-bar:hover{filter:brightness(1.05)}
.cb-empty{color:var(--muted)}
.cb-empty a{color:var(--acc);cursor:pointer}
/* E281. The backend-unreachable banner. Fixed to the top of the VIEWPORT (not
   the page flow) because the condition applies to the whole app and must stay
   visible wherever the user has scrolled to. High z-index for the same reason:
   a modal that cannot talk to the server must not cover the explanation of
   why. */
.gl-srvdown{position:fixed;top:0;left:0;right:0;z-index:9999;
  background:var(--n-err,#a91f16);color:#fff;padding:10px 16px;
  font-size:13px;line-height:1.5;box-shadow:0 2px 8px rgba(0,0,0,.3)}
.gl-srvdown code{background:rgba(255,255,255,.18);padding:1px 5px;border-radius:3px;
  font-family:var(--mono,ui-monospace,monospace)}
.gl-srvdown .cb-act{color:#fff;font-weight:600}
/* E283. The boot indicator, shown by index.html before the first API call
   returns and removed by app.js once the backend answers. Centred rather than
   a top bar: at that moment there is nothing else on screen to displace. */
.gl-booting{position:fixed;inset:0;z-index:9998;display:flex;align-items:center;
  justify-content:center;background:var(--bg,#0f1216);color:var(--muted,#8b95a1);
  font-size:14px;gap:10px;flex-direction:column}
.gl-booting small{opacity:.75;max-width:44ch;text-align:center;line-height:1.5}

/* E123. The banner's actions are <button>s now, not styled anchors: focusable,
   announced as controls, and reachable from the keyboard. They keep the link
   appearance so the banner does not turn into three heavy buttons in a status
   strip -- appearance unchanged, semantics fixed. */
.cb-act{background:none;border:0;padding:0 2px;font:inherit;color:var(--acc);
  cursor:pointer;text-decoration:underline}
.cb-act:hover{text-decoration:none}
.cb-act:focus-visible{outline:2px solid var(--n-focus-ring,var(--acc));outline-offset:2px}
.cb-act:disabled{opacity:.6;cursor:default;text-decoration:none}
.cb-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.cb-name{font-weight:700;color:var(--ink)}
.cb-chip{background:var(--n-bg-3);border:var(--bw-1) solid var(--line);border-radius:var(--radius-xs);
  padding:0 6px;font-size:var(--fs-1);color:var(--muted);font-family:var(--font-mono)}
.cb-chip.cb-good{color:var(--acc2);border-color:var(--acc2)}
.cb-chip.cb-warn{color:var(--warn);border-color:var(--warn)}
.cb-goto{margin-left:auto;color:var(--acc);font-size:11px;font-weight:600}

/* ===== A2: command palette (⌘K) ===== */
.palette-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);
  z-index:200;align-items:flex-start;justify-content:center;padding-top:12vh}
.palette-overlay.show{display:flex}
.palette-box{width:min(560px,90vw);background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-md);box-shadow:var(--n-shadow-3);overflow:hidden}
.palette-input{width:100%;border:0;border-bottom:1px solid var(--line);background:transparent;
  color:var(--ink);font-size:15px;padding:14px 16px;outline:none;font-family:inherit}
.palette-list{max-height:50vh;overflow:auto}
.palette-row{display:flex;align-items:center;gap:10px;padding:9px 16px;cursor:pointer}
.palette-row:hover{background:var(--bg2)}
.palette-icon{width:22px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--muted)}
.palette-icon .icn{width:16px;height:16px}
.pal-n{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;border-radius:5px;background:var(--panel);border:1px solid var(--line);font-size:10px;font-weight:700;color:var(--muted)}
.palette-label{flex:1;font-weight:600}
.palette-hint{color:var(--muted);font-size:11px}
.palette-empty{padding:14px 16px;color:var(--muted)}

/* ===== Layout: left rail + workspace ===== */
.active-name{color:var(--acc2);font-size:12.5px;font-weight:650;margin-right:6px;
  max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;vertical-align:middle}
.layout{display:flex;min-height:calc(100vh - 58px)}
.rail{width:222px;flex:0 0 222px;background:var(--n-bg-1);border-right:var(--bw-1) solid var(--n-line-2);
  padding:10px 7px;display:flex;flex-direction:column;gap:12px}
.rail-brand{display:flex;align-items:center;justify-content:center;margin-bottom:-8px}
.rail-brand img{display:block;border-radius:6px}
body.rail-collapsed .rail-brand{margin-bottom:0}
.rail-toggle{align-self:flex-end;margin-bottom:-8px}
/* monochrome line-icons */
.icn{width:16px;height:16px;flex:0 0 auto;vertical-align:-3px}
.ri-ico{display:inline-flex;align-items:center;justify-content:center;color:var(--muted)}
.rail-item.active .ri-ico{color:var(--acc)}
.icon-btn{display:inline-flex;align-items:center;justify-content:center;padding:6px 8px}
.icon-btn .icn{width:15px;height:15px;vertical-align:0}
.header-right button:not(.icon-btn){display:inline-flex;align-items:center;gap:6px}
/* ═══ E1 / Phase-8 §5.5: on-demand collapsed rail (ICONS ONLY) ═══
   The pre-Phase-8 defect was NOT label hiding — that worked (measured: 0 of
   436 labels visible when collapsed). The defect was that 410 of 428 items
   had no icon to fall back on, so collapsing left a 60px column of blank
   34px click targets. Icons are now supplied by NucleoraUI.resolveRailIcons()
   (app.js), which guarantees every .rail-item carries a .ri-ico. These rules
   hide every text-bearing part and centre the icon box.

   Legacy glyph holders (.rail-icon/.rail-ico/.hd-rail-icon/.pal-n) are hidden
   here too: modules put emoji and bullets in them, emoji do not inherit
   currentColor and render inconsistently across platforms (§5.4). The icon
   resolver replaces them with a real SVG or a monogram. `.step-n` is the one
   sanctioned exception — a numbered badge is meaningful when collapsed. */
body.rail-collapsed .rail{width:60px;flex-basis:60px}
body.rail-collapsed .rail-item{justify-content:center;padding:var(--sp-2) 0}
body.rail-collapsed .rail-item .ri-lbl,
body.rail-collapsed .rail-label,
body.rail-collapsed .rail-group-label,
body.rail-collapsed .rail-foot,
body.rail-collapsed .rail-item .rail-icon,
body.rail-collapsed .rail-item .rail-ico,
body.rail-collapsed .rail-item .hd-rail-icon,
body.rail-collapsed .rail-item .rail-text,
body.rail-collapsed .rail-item .pal-n,
body.rail-collapsed .rail-item .ri-sub,
body.rail-collapsed .rail-item .ri-badge,
body.rail-collapsed .wsnav-label,
body.rail-collapsed .wsnav-count,
body.rail-collapsed .wsnav-caret,
body.rail-collapsed .wsnav-bench-label,
body.rail-collapsed .n-layer-label,
body.rail-collapsed .n-layer-count,
body.rail-collapsed .n-layer-caret,
body.rail-collapsed .n-layer-item-label,
body.rail-collapsed .n-layer-item-hint{display:none}

/* icons keep their box and centre */
body.rail-collapsed .ri-ico,
body.rail-collapsed .n-layer-icon,
body.rail-collapsed .n-layer-item-icon,
body.rail-collapsed .wsnav-icon{width:24px;height:24px;margin:0}

/* workspace buttons need an icon of their own (all 10 were blank) */
body.rail-collapsed .wsnav-btn{justify-content:center;padding:var(--sp-2) 0}
body.rail-collapsed .wsnav-icon{display:inline-flex}

/* inline panels can't indent inside a 60px rail */
body.rail-collapsed .wsnav-panel,
body.rail-collapsed .n-layer--inline > .n-layer-panel{
  margin-left:0;padding-left:0;border-left:none}

/* An inline style="padding:6px 10px" on a rail item beats
   `body.rail-collapsed .rail-item{padding:…}` on specificity — 65 items carry
   one. Until W1–W10 strip them from their own files, this override keeps the
   collapsed rail correctly sized. Scoped to the collapsed state ONLY, so it
   changes nothing about the expanded rail. */
body.rail-collapsed .rail-item[style]{
  padding-left:0!important;padding-right:0!important;justify-content:center!important}
/* F1: visible keyboard focus */
.rail-item:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,
.palette-row:focus-visible,a:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.rail-group{display:flex;flex-direction:column;gap:1px}
.rail-label{font-size:var(--fs-1);text-transform:uppercase;letter-spacing:var(--ls-caps);
  color:var(--n-ink-2);font-weight:var(--fw-semibold);padding:0 8px 2px}
.rail-item{display:flex;align-items:center;gap:7px;padding:var(--density-pad);
  min-height:var(--row-h);border-radius:var(--radius-sm);cursor:pointer;
  color:var(--ink);font-size:var(--fs-2);font-weight:var(--fw-normal);text-decoration:none}
.rail-item:hover{background:var(--panel2)}
.rail-item.active{background:var(--acc);color:var(--on-acc);font-weight:var(--fw-medium)}
.step-n{display:inline-flex;width:17px;height:17px;border-radius:var(--radius-xs);
  background:var(--n-bg-4);border:var(--bw-1) solid var(--n-line-2);
  color:var(--acc);font-size:var(--fs-1);font-weight:var(--fw-semibold);
  font-family:var(--font-mono);align-items:center;justify-content:center;flex:0 0 auto}
.rail-item.active .step-n{background:var(--on-acc);color:var(--acc)}
.rail-foot{margin-top:auto;padding:10px;border-top:1px solid var(--line);line-height:1.4}
main{padding:22px 26px;max-width:1080px;margin:0;flex:1}
.step-head{margin-bottom:var(--sp-3);padding-bottom:var(--sp-2);
  border-bottom:var(--bw-1) solid var(--n-line-1)}
/* Phase 8b: view titles drop from 22px/750/-.01em to the --fs-5 step at
   semibold with no negative tracking. A 22px tight-tracked heading is a
   landing-page H1; this is a window title. */
.step-head h2{margin:0 0 4px;font-size:var(--fs-5);line-height:var(--lh-5);
  font-weight:var(--fw-semibold);letter-spacing:0}
.lead{color:var(--muted);font-size:var(--fs-3);line-height:var(--lh-3);margin:0;max-width:76ch}
.lead a,.banner a,.rail-foot a{color:var(--acc);cursor:pointer;text-decoration:underline}
.lead em{color:var(--ink);font-style:normal;background:var(--panel2);padding:1px 5px;border-radius:4px}

/* search bar */
.search-bar{display:flex;gap:8px;margin-bottom:8px}
.search-bar input{flex:1}
.search-bar .species-in{flex:0 0 220px}
.search-bar .strain-in{flex:0 0 190px}
.quick-ex{margin-bottom:12px}
.quick-ex a{color:var(--acc);cursor:pointer;text-decoration:underline;margin:0 2px}
.card.alt{background:var(--panel2);margin-top:14px}
.card.alt summary{font-weight:650;color:var(--ink)}

/* ===== 3D structure viewer (AlphaFold, via 3Dmol.js).
      Phase 8b: the ambient glow, the 24px drop shadow and the hardcoded
      dark-green radial gradient are gone. A structure viewport is a flat
      neutral stage -- any colour in it must be the pLDDT coding, not the
      backdrop competing with it. The confidence legend below stays: it is
      what makes the colour-coding readable. ===== */
.st3d-card{border:var(--bw-1) solid var(--line)}
.st3d-viewer{width:100%;height:420px;border:var(--bw-1) solid var(--n-line-2);
  border-radius:var(--radius-md);
  position:relative;background:var(--n-bg-4);overflow:hidden}
.st3d-legend{display:flex;align-items:center;gap:8px;margin-top:8px;font-size:10.5px;color:var(--muted)}
/* This gradient is DATA, not decoration: it is the pLDDT confidence scale
   3Dmol paints the model with, so it is kept -- but re-pointed off the four
   hardcoded hexes onto the base-hue tokens so it tracks the theme. */
.st3d-legend-bar{flex:1;max-width:180px;height:6px;border-radius:var(--radius-xs);
  background:linear-gradient(90deg,var(--n-base-a),var(--n-base-g),var(--n-warn),var(--n-err))}
.card .pad{padding-top:12px}
.mini-tabs{display:flex;gap:4px;margin-bottom:10px}
.mini-tab{padding:3px 10px;border-radius:var(--radius-sm);background:var(--n-bg-1);
  border:var(--bw-1) solid var(--n-line-3);
  cursor:pointer;font-size:var(--fs-2);font-weight:var(--fw-medium);color:var(--muted)}
.mini-tab.active{background:var(--acc);color:var(--on-acc)}
.banner{padding:10px 12px;border-radius:8px;background:var(--panel2);border:1px solid var(--line);margin-bottom:14px;font-size:13px}
.banner.set{background:rgba(75,191,151,.1);border-color:rgba(75,191,151,.3);color:var(--ink)}
.help-dot{display:inline-flex;width:15px;height:15px;border-radius:50%;background:var(--panel2);
  color:var(--muted);font-size:10px;font-weight:800;align-items:center;justify-content:center;cursor:help;border:1px solid var(--line)}
.view-toggle{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden}
.vt{padding:6px 15px;cursor:pointer;font-size:12.5px;font-weight:600;color:var(--muted);background:var(--panel2)}
.vt.active{background:var(--acc);color:var(--on-acc)}
.big-edit{min-height:300px}
button.big{font-size:14.5px;padding:12px 26px}
.hit-card{background:var(--panel2);border:1px solid var(--line);border-radius:9px;padding:11px 13px;margin-bottom:8px;
  display:flex;justify-content:space-between;align-items:center;gap:12px}
.hit-card .h-title{font-size:13px;font-weight:600}
.src-badge{font-size:9.5px;padding:1px 6px;border-radius:10px;font-weight:700;margin-right:5px;vertical-align:middle;letter-spacing:.02em}
.src-badge.uni{background:rgba(90,169,255,.18);color:var(--hue-blue)}
.src-badge.ncbi{background:rgba(95,182,201,.18);color:var(--acc3)}
.src-badge.rev{background:rgba(75,191,151,.18);color:var(--acc2)}
.hit-card .h-meta{font-size:11.5px;color:var(--muted);margin-top:2px}

/* ===== codon tester registry ===== */
.ct-list{margin-top:10px;display:flex;flex-direction:column;gap:9px}
.ct-card{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:12px 14px}
.ct-card.certified{border-color:var(--acc2);box-shadow:inset 3px 0 0 var(--acc2)}
.ct-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.ct-name{font-size:13.5px;font-weight:700;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.ct-tier{font-size:9.5px;padding:1.5px 7px;border-radius:10px;font-weight:800;letter-spacing:.03em;text-transform:uppercase}
.ct-tier.certified{background:rgba(75,191,151,.18);color:var(--acc2)}
.ct-tier.recognized{background:rgba(90,169,255,.16);color:var(--hue-blue)}
.ct-tier.utility{background:rgba(149,169,160,.16);color:var(--muted)}
.ct-installed{font-size:9.5px;padding:1.5px 7px;border-radius:10px;font-weight:700;background:rgba(75,191,151,.16);color:var(--acc2)}
.ct-metrics{margin-top:5px}
.ct-metric-chip{display:inline-block;font-size:10px;font-weight:700;padding:1px 6px;margin:2px 4px 0 0;border-radius:6px;background:var(--bg2);color:var(--muted);border:1px solid var(--line)}
.ct-desc{font-size:12px;color:var(--ink);margin-top:6px;line-height:1.45}
.ct-cite{font-size:10.5px;color:var(--muted);margin-top:5px;font-style:italic}
.ct-actions{display:flex;flex-direction:column;gap:6px;flex:0 0 auto;min-width:118px;align-items:stretch}
.ct-actions button{white-space:nowrap}
.ct-log{font-family:var(--mono,monospace);font-size:10.5px;color:var(--muted);background:var(--bg2);border:1px solid var(--line);border-radius:6px;padding:6px 8px;margin-top:7px;white-space:pre-wrap;max-height:120px;overflow:auto}
/* concordance table */
.ct-verdict{border-radius:9px;padding:11px 13px;margin-bottom:12px;font-size:13px;font-weight:600}
.ct-verdict.agree{background:rgba(75,191,151,.14);border:1px solid var(--acc2);color:var(--ink)}
.ct-verdict.mixed{background:rgba(224,164,74,.14);border:1px solid var(--warn);color:var(--ink)}
.ct-table{width:100%;border-collapse:collapse;font-size:12.5px;margin-top:8px}
.ct-table th,.ct-table td{border:1px solid var(--line);padding:7px 9px;text-align:left}
.ct-table th{background:var(--bg2);font-weight:700}
.ct-table td.num{text-align:right;font-variant-numeric:tabular-nums}
.ct-agree-badge{font-size:10px;font-weight:800;padding:1px 7px;border-radius:9px}
.ct-agree-badge.yes{background:rgba(75,191,151,.18);color:var(--acc2)}
.ct-agree-badge.no{background:rgba(149,169,160,.16);color:var(--muted)}
.ct-metric-block{margin-top:14px}
.ct-metric-block h4{margin:0 0 4px;font-size:12.5px}
/* multi-antigen inline search */
.ma-search{margin:8px 0 12px;padding:10px;border:1px dashed var(--line);border-radius:9px;background:var(--bg2)}
.ma-search .hit-card{padding:8px 11px}
.ma-entry{margin-top:10px;padding-top:9px;border-top:1px solid var(--line)}
.ma-entry a{cursor:pointer}
/* Below 800px the rail force-collapses. §5.6: this query must carry the SAME
   selector set as body.rail-collapsed, or narrow viewports keep the blank-row
   bug even after the desktop fix. */
@media(max-width:800px){
  .rail{width:60px;flex-basis:60px}
  .rail-item{justify-content:center;padding:var(--sp-2) 0}
  .rail-item .ri-lbl,.rail-label,.rail-group-label,.rail-foot,
  .rail-item .rail-icon,.rail-item .rail-ico,.rail-item .hd-rail-icon,
  .rail-item .rail-text,.rail-item .pal-n,.rail-item .ri-sub,.rail-item .ri-badge,
  .wsnav-label,.wsnav-count,.wsnav-caret,.wsnav-bench-label,
  .n-layer-label,.n-layer-count,.n-layer-caret,
  .n-layer-item-label,.n-layer-item-hint{display:none}
  .ri-ico,.n-layer-icon,.n-layer-item-icon,.wsnav-icon{width:24px;height:24px;margin:0}
  .wsnav-btn{justify-content:center;padding:var(--sp-2) 0}
  .wsnav-icon{display:inline-flex}
  .wsnav-panel,.n-layer--inline > .n-layer-panel{margin-left:0;padding-left:0;border-left:none}
  .rail-item[style]{padding-left:0!important;padding-right:0!important;justify-content:center!important}
  .search-bar{flex-wrap:wrap}
  .search-bar .species-in,.search-bar .strain-in{flex-basis:100%}
}

/* ===== rich hover tooltips ===== */
.info{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:15px;height:15px;border-radius:50%;background:var(--panel2);color:var(--acc);
  font-size:10px;font-weight:800;cursor:help;border:1px solid var(--line);margin-left:5px;flex:0 0 auto}
.info:hover{background:var(--acc);color:var(--on-acc)}
.info .tip{visibility:hidden;opacity:0;position:absolute;z-index:50;left:50%;bottom:130%;
  transform:translateX(-50%);width:290px;background:var(--panel2);border:1px solid var(--acc);
  border-radius:9px;padding:11px 13px;font-size:12px;font-weight:400;line-height:1.55;
  color:var(--ink);text-align:left;box-shadow:var(--n-shadow-3);
  white-space:normal;pointer-events:none}
.info .tip b{color:var(--acc2)}
.info .tip .eg{display:block;margin-top:6px;padding-top:6px;border-top:1px solid var(--line);color:var(--muted);font-size:11px}
.info:hover .tip{visibility:visible;opacity:1}
.info .tip::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);
  border:6px solid transparent;border-top-color:var(--acc)}
label .info{vertical-align:middle}
.chk .info{margin-left:3px}

/* ===== catalog organism picker ===== */
.org-picker{border:1px solid var(--line);border-radius:9px;background:var(--panel2);overflow:hidden}
.org-search{width:100%;border:none;border-bottom:1px solid var(--line);background:var(--panel);
  padding:9px 12px;color:var(--ink);font-size:13px;border-radius:0}
.org-list{max-height:230px;overflow-y:auto}
.org-cat{font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);
  font-weight:700;padding:8px 12px 3px;background:var(--panel2);position:sticky;top:0}
.org-opt{display:flex;align-items:center;gap:8px;padding:7px 12px;cursor:pointer;font-size:13px}
.org-opt:hover{background:var(--panel)}
.org-opt.sel{background:var(--acc);color:var(--on-acc);font-weight:650}
.org-opt .oemoji{font-size:15px}
/* E108. The scientific name, inline rather than hover-only. Italic and muted:
   it is a secondary identifier, so it must not compete with the common name it
   disambiguates. */
.org-opt .olatin{font-style:italic;color:var(--muted);font-size:11px}
.org-opt .oprov{margin-left:auto;font-size:10px;font-weight:700;padding:1px 7px;border-radius:10px}
.oprov.empirical{background:rgba(75,191,151,.18);color:var(--acc2)}
.oprov.proxy{background:rgba(224,164,74,.18);color:var(--warn)}
.oprov.reference{background:rgba(90,169,255,.18);color:var(--hue-blue)}
.oprov.buildable{background:rgba(95,182,201,.18);color:var(--acc3)}
.org-opt.sel .oprov{background:rgba(0,0,0,.18);color:var(--on-acc)}
.org-chosen{padding:9px 12px;font-size:13px;display:flex;align-items:center;gap:8px;border-top:1px solid var(--line)}
.build-note{font-size:var(--fs-1);color:var(--acc3);margin-top:var(--sp-1)}


/* ---- clade-anchored recommendation panel (Step 2) ---- */
.rec-note{margin-top:10px;padding:10px 12px;border:1px solid var(--line);
  border-left:3px solid var(--acc2);border-radius:8px;background:rgba(75,191,151,.06)}
.rec-note:empty{display:none}
.rec-head{font-size:12.5px;color:var(--ink)}
.rec-head b{color:var(--acc2)}
.rec-basis{margin-left:8px;font-size:10.5px;color:var(--muted);font-weight:400}
.rec-vals{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:8px 0 6px}
.rec-chip{background:var(--n-bg-3);border:var(--bw-1) solid var(--line);border-radius:var(--radius-xs);
  padding:2px 10px;font-size:11.5px;color:var(--muted)}
.rec-chip b{color:var(--ink)}
.rec-why{margin-top:4px;line-height:1.5}
button.xs{font-size:var(--fs-1);padding:1px 7px;border-radius:var(--radius-xs);line-height:1.4}

/* ---- detailed help page ---- */
.help-toc{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 18px;padding:12px;
  background:var(--panel2);border:1px solid var(--line);border-radius:10px}
.help-toc a{font-size:var(--fs-2);padding:2px 8px;border-radius:var(--radius-xs);background:var(--n-bg-3);
  border:1px solid var(--line);color:var(--acc);cursor:pointer;text-decoration:none}
.help-toc a:hover{background:var(--acc);color:var(--on-acc)}
#view-help h3{scroll-margin-top:16px;margin-top:26px;padding-top:14px;border-top:1px solid var(--line)}
#view-help h3:first-of-type{border-top:none}
.gloss{width:100%;border-collapse:collapse;margin:8px 0}
.gloss th,.gloss td{text-align:left;vertical-align:top;padding:7px 9px;border-bottom:1px solid var(--line);font-size:12.5px}
.gloss th{color:var(--muted);font-weight:600}
.gloss td:first-child{white-space:nowrap;color:var(--acc);font-weight:600}
.gloss .rec-cell{color:var(--acc2);font-weight:600;white-space:nowrap}
.help-tip{padding:9px 12px;border-left:3px solid var(--acc);background:rgba(90,169,255,.07);
  border-radius:6px;margin:10px 0;font-size:12.5px}
.help-warn{padding:9px 12px;border-left:3px solid var(--warn);background:rgba(224,164,74,.08);
  border-radius:6px;margin:10px 0;font-size:12.5px}
.help-brand{display:flex;align-items:center;gap:10px;margin-bottom:4px}
.help-brand img{display:block;border-radius:8px}
.help-brand h2{margin:0}
.help-note{padding:9px 12px;border-left:3px solid var(--acc);background:color-mix(in srgb,var(--acc) 8%,transparent);
  border-radius:6px;margin:10px 0;font-size:12.5px;line-height:1.6}
.back-top{font-size:11px;color:var(--muted);cursor:pointer;float:right;font-weight:400}
.back-top:hover{color:var(--acc)}

/* ---- IVT simulate & check ---- */
.ivt-h{margin:16px 0 8px;font-size:13px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.ivt-grade{display:flex;align-items:center;gap:14px;margin:6px 0 4px}
.grade-badge{width:52px;height:52px;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;
  font-size:26px;font-weight:800;color:var(--on-acc);flex:0 0 auto}
.grade-badge.good{background:var(--good)} .grade-badge.ok{background:var(--ok)} .grade-badge.low{background:var(--low)}
.ivt-stages{display:flex;flex-direction:column;gap:2px}
.ivt-stage{display:flex;gap:10px;padding:8px 10px;border-radius:8px;align-items:flex-start}
.ivt-stage .ivt-dot{width:9px;height:9px;border-radius:50%;margin-top:5px;flex:0 0 auto}
.ivt-stage.ok .ivt-dot{background:var(--good)} .ivt-stage.warn .ivt-dot{background:var(--warn)} .ivt-stage.error .ivt-dot{background:var(--err)}
.ivt-checks{display:flex;flex-direction:column;gap:4px}
.ivt-check{display:flex;gap:10px;padding:9px 11px;border-radius:8px;border:1px solid var(--line);background:var(--panel2)}
.ivt-check>div:last-child{min-width:0;flex:1;overflow-wrap:anywhere}
.ivt-check .mono{overflow-wrap:anywhere}
.ivt-check .ivt-ci{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex:0 0 auto;color:var(--on-acc)}
.ivt-check.pass{border-left:3px solid var(--good)} .ivt-check.pass .ivt-ci{background:var(--good)}
.ivt-check.accent{border-left:3px solid var(--acc)} .ivt-check.accent .ivt-ci{background:var(--acc)}
.ivt-check.warn{border-left:3px solid var(--warn)} .ivt-check.warn .ivt-ci{background:var(--warn)}
.ivt-check.error{border-left:3px solid var(--err)} .ivt-check.error .ivt-ci{background:var(--err)}
.ivt-fix{margin-top:4px;font-size:12px;color:var(--acc2)}

/* ---- virtual gel ---- */
.gel-wrap{display:flex;gap:10px;align-items:flex-start;padding:16px;margin:8px 0;
  background:var(--n-bg-1);border:var(--bw-1) solid var(--line);
  border-radius:var(--radius-md);overflow-x:auto}
.gel-lane{display:flex;flex-direction:column;align-items:center;min-width:70px}
.gel-well{position:relative;width:100%;background:var(--n-bg-4);border:var(--bw-1) solid var(--line);
  border-radius:var(--radius-xs)}
/* Phase 8b: solid bands, no bloom -- see the .rgel-band note above. */
.gel-band{position:absolute;left:50%;transform:translateX(-50%);height:4px;border-radius:0;
  background:var(--g)}
.gel-lane.ladder .gel-band{background:var(--a)}
.gel-mw{position:absolute;right:-2px;font-size:9px;color:var(--muted);transform:translateX(100%)}
.gel-lname{margin-top:6px;font-size:11px;color:var(--muted);text-align:center;max-width:80px;word-break:break-word}

/* ---- peptide + alignment ---- */
.mono-in{font-family:ui-monospace,Menlo,monospace;font-size:12px}
.aln-view{font-family:ui-monospace,Menlo,monospace;font-size:12px;background:var(--panel2);
  border:1px solid var(--line);border-radius:8px;padding:12px;overflow-x:auto;white-space:pre;line-height:1.35;margin-top:8px}
.aln-row{display:flex;gap:8px} .aln-lab{color:var(--muted);width:12px;flex:0 0 auto}
.aln-mid{color:var(--acc2)} .aln-gap{height:8px}
/* Align-to-reference QC */
.qc-verdict{padding:9px 12px;border-radius:8px;font-weight:600;font-size:13px;margin-bottom:10px}
.qc-verdict.ok{background:color-mix(in srgb,var(--acc2) 18%,transparent);color:var(--acc2);border:1px solid var(--acc2)}
.qc-verdict.warn{background:color-mix(in srgb,var(--warn) 16%,transparent);color:var(--warn);border:1px solid var(--warn)}
.qc-table{width:100%;border-collapse:collapse;margin:10px 0;font-size:12.5px}
.qc-table th{text-align:left;color:var(--muted);font-weight:600;border-bottom:1px solid var(--line);padding:5px 8px}
.qc-table td{padding:5px 8px;border-bottom:1px solid var(--line)}
.qc-table .mono{font-family:ui-monospace,monospace}
.qc-type{font-size:11px;padding:1px 7px;border-radius:10px;font-weight:600}
.qc-type.t-substitution{background:color-mix(in srgb,var(--acc) 20%,transparent);color:var(--acc)}
.qc-type.t-insertion{background:color-mix(in srgb,var(--acc2) 20%,transparent);color:var(--acc2)}
.qc-type.t-deletion{background:color-mix(in srgb,var(--warn) 20%,transparent);color:var(--warn)}
.qc-eff{font-weight:600} .qc-eff.eff-sil{color:var(--muted)} .qc-eff.eff-mis{color:var(--acc)} .qc-eff.eff-non{color:var(--err)}
.qc-legend{display:flex;gap:14px;font-size:11px;margin:8px 0 2px}
.qc-legend .d-sub,.qc-legend .d-del,.qc-legend .d-ins{padding:1px 6px;border-radius:4px}
.aln-view .d-mat{color:var(--muted)}
.aln-view .d-sub{background:color-mix(in srgb,var(--acc) 35%,transparent);color:var(--ink);border-radius:2px}
.aln-view .d-del{background:color-mix(in srgb,var(--warn) 35%,transparent);color:var(--ink);border-radius:2px}
.aln-view .d-ins{background:color-mix(in srgb,var(--acc2) 35%,transparent);color:var(--ink);border-radius:2px}
.aln-view .d-gap{color:var(--warn)}

/* ---- manufacture & order ---- */
.mfg-form{margin:10px 0}
.mfg-head{display:flex;align-items:center;gap:20px;margin:6px 0;flex-wrap:wrap}
.mfg-big .n{font-size:30px;font-weight:800;color:var(--acc2);line-height:1}
.mfg-big .l{font-size:12px;color:var(--muted);margin-top:3px}
.mfg-meta{display:flex;flex-direction:column;gap:2px;font-size:12px;color:var(--muted)}
.mfg-meta b{color:var(--ink)}
.mfg-why{font-size:12px;color:var(--warn);margin:4px 0}
.mfg-ceil{margin:2px 0 6px}
svg.spark{background:var(--panel2);border:1px solid var(--line);border-radius:8px;margin:6px 0;height:90px;width:100%;max-width:520px;display:block}
svg.spark .sl{fill:var(--muted);font-size:9px}
table tr.tot td{border-top:2px solid var(--line);font-weight:700}
table tr.sel-row td{background:rgba(90,169,255,.10);font-weight:600}

/* ===== F3: respect reduced-motion preference ===== */
@media (prefers-reduced-motion: reduce){
  *{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;scroll-behavior:auto !important}
  .topbar::before{animation:none;left:0;width:100%}
}

/* ===== Vaccination Studio ===== */
.vseg{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden}
.vseg-btn{background:var(--panel2);color:var(--muted);border:0;border-radius:0;padding:8px 14px;font-weight:650;font-size:12.5px;border-right:1px solid var(--line)}
.vseg-btn:last-child{border-right:0}
.vseg-btn.active{background:var(--acc);color:var(--on-acc)}
.vax-verdict{display:flex;align-items:center;gap:14px;padding:10px 12px;border-radius:var(--radius-sm);margin:2px 0 14px;
  background:color-mix(in srgb,var(--acc) 9%,transparent);border:1px solid var(--line)}
.vax-verdict .vax-vtxt{font-size:15px;font-weight:700}
.vax-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));gap:14px}
.vax-panel{background:var(--panel);border:var(--bw-1) solid var(--line);
  border-radius:var(--radius-md);padding:var(--sp-3)}
.vax-panel h3{margin:0 0 4px;font-size:14px;display:flex;align-items:center;gap:8px}
.vax-panel h3 .icn{width:16px;height:16px;color:var(--acc)}
.vax-panel .vax-sub{color:var(--muted);font-size:11.5px;margin-bottom:9px}
.conf{display:inline-block;font-size:10px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;
  padding:0 6px;border-radius:var(--radius-xs);margin-left:6px;vertical-align:middle}
.conf.high{background:color-mix(in srgb,var(--good) 20%,transparent);color:var(--good)}
.conf.medium{background:color-mix(in srgb,var(--warn) 22%,transparent);color:var(--warn)}
.conf.low{background:color-mix(in srgb,var(--err) 16%,transparent);color:var(--err)}
.conf.none{background:var(--panel2);color:var(--muted);border:1px dashed var(--line)}
.conf.accent{background:color-mix(in srgb,var(--acc) 18%,transparent);color:var(--acc)}
.route-grade{display:inline-block;font-weight:800;font-size:11px;text-transform:uppercase;letter-spacing:.4px;
  padding:1px 6px;border-radius:var(--radius-xs)}
.route-grade.suitable{background:color-mix(in srgb,var(--good) 20%,transparent);color:var(--good)}
.route-grade.needs_reformulation{background:color-mix(in srgb,var(--warn) 22%,transparent);color:var(--warn)}
.route-grade.not_recommended{background:color-mix(in srgb,var(--err) 18%,transparent);color:var(--err)}
.vax-kv{display:flex;justify-content:space-between;gap:10px;padding:4px 0;border-bottom:1px dashed var(--line);font-size:12.5px}
.vax-kv:last-child{border-bottom:0}
.vax-kv b{color:var(--ink);font-variant-numeric:tabular-nums}
.vax-flag{display:flex;gap:9px;padding:8px 0;border-bottom:1px dashed var(--line);font-size:12px}
.vax-flag:last-child{border-bottom:0}
.vax-flag .fsev{flex:0 0 auto;font-size:9.5px;font-weight:800;text-transform:uppercase;letter-spacing:.4px;
  padding:2px 7px;border-radius:6px;height:fit-content}
.fsev.blocking{background:color-mix(in srgb,var(--err) 20%,transparent);color:var(--err)}
.fsev.review{background:color-mix(in srgb,var(--warn) 22%,transparent);color:var(--warn)}
.fsev.reassuring{background:color-mix(in srgb,var(--good) 20%,transparent);color:var(--good)}
.fsev.informational{background:var(--panel2);color:var(--muted)}
.vax-rec{padding:9px 12px;border-left:3px solid var(--acc2);background:color-mix(in srgb,var(--acc2) 9%,transparent);
  border-radius:0 8px 8px 0;font-size:12.5px;margin-top:8px}
.vax-cite{font-size:11px;color:var(--muted);word-break:break-word}
.vax-cite code{background:var(--panel2);padding:1px 5px;border-radius:4px;font-size:10.5px}
.vax-boiler{font-family:ui-monospace,monospace;font-size:11px;white-space:pre-wrap;background:var(--bg2);
  border:1px solid var(--line);border-radius:8px;padding:12px;max-height:340px;overflow:auto;line-height:1.55}

/* ---- segmented toggle (shared by Vaccination route + Virtual Lab mode) ---- */
#vaxRouteSeg.seg, #vlModeSeg.seg{display:inline-flex;padding:0;border:1px solid var(--line);
  border-radius:8px;overflow:hidden;background:var(--panel2)}
#vaxRouteSeg .seg-btn, #vlModeSeg .seg-btn{background:var(--panel2);color:var(--muted);border:0;
  border-radius:0;padding:8px 14px;font-weight:650;font-size:12.5px;border-right:1px solid var(--line);cursor:pointer}
#vaxRouteSeg .seg-btn:last-child, #vlModeSeg .seg-btn:last-child{border-right:0}
#vaxRouteSeg .seg-btn.active, #vlModeSeg .seg-btn.active{background:var(--acc);color:var(--on-acc)}

/* ---- Virtual Lab Bench result cards ---- */
#vlOut{display:flex;flex-direction:column;gap:14px;margin-top:14px}
.vl-card{background:var(--panel);border:var(--bw-1) solid var(--line);
  border-radius:var(--radius-md);padding:var(--sp-3)}
.vl-card h3{font-size:14px;display:flex;align-items:center;gap:8px}
.vl-card h3 .icn{width:16px;height:16px;color:var(--acc)}
.vl-readout{font-size:13px;color:var(--ink);margin:8px 0 10px;line-height:1.5}
.vl-kv{font-size:12.5px;color:var(--ink);margin:6px 0}
.vl-kv span{color:var(--muted)}
.vl-list{margin:8px 0;padding-left:18px;font-size:12px;color:var(--ink);line-height:1.65}
.vl-src{margin-top:10px;word-break:break-word}
.vl-disc{margin-top:8px;padding-top:8px;border-top:1px dashed var(--line);line-height:1.5;font-style:italic}
.vl-spark{display:block;background:var(--bg2);border:1px solid var(--line);border-radius:8px;margin:6px 0}
.vl-band{display:inline-block;font-weight:800;font-size:15px;letter-spacing:.4px;padding:6px 14px;
  border-radius:8px;margin:6px 0}
.vl-band .small{font-weight:600;letter-spacing:0}
.vl-band-high{background:color-mix(in srgb,var(--err) 16%,transparent);color:var(--err)}
.vl-band-moderate{background:color-mix(in srgb,var(--warn) 20%,transparent);color:var(--warn)}
.vl-band-low{background:color-mix(in srgb,var(--good) 18%,transparent);color:var(--good)}

/* ---- Virtual Lab Bench: species physiology profile ---- */
.pill{display:inline-block;font-size:10.5px;font-weight:700;border-radius:10px;padding:1px 8px;border:1px solid var(--line);vertical-align:middle}
.pill-meas{background:var(--good);color:var(--on-acc);border-color:transparent}
.pill-pred{background:var(--panel2);color:var(--acc);border-color:var(--acc)}
.pill-supp{background:transparent;color:var(--low);border-color:var(--low)}
.vl-physgrid{margin:6px 0}
.vl-physgrid .vl-kv{padding:3px 0;border-bottom:1px dashed var(--line)}
.vl-backtest{color:var(--muted)}
#vlSpecies optgroup{font-weight:700;color:var(--muted)}

/* ===== Engagement Lab ===== */
.lab-cols{display:grid;grid-template-columns:1fr 380px;gap:16px;align-items:start}
@media(max-width:1000px){.lab-cols{grid-template-columns:1fr}}
.lab-h{font-size:13px;font-weight:700;color:var(--ink);margin:4px 0 8px}
.lab-count{display:inline-block;font-size:var(--fs-2);font-weight:var(--fw-medium);
  padding:2px 8px;border-radius:var(--radius-xs);font-family:var(--font-mono);
  background:var(--panel2);color:var(--muted);border:1px solid var(--line)}
.lab-count.ok{background:color-mix(in srgb,var(--good) 18%,transparent);color:var(--good);border-color:transparent}
.lab-count.under{background:color-mix(in srgb,var(--warn) 18%,transparent);color:var(--warn);border-color:transparent}
.lab-count.over{background:color-mix(in srgb,var(--err) 16%,transparent);color:var(--err);border-color:transparent}
.lab-point{display:flex;gap:10px;padding:10px 12px;border:1px solid var(--line);border-radius:10px;
  background:var(--panel);margin-bottom:8px;cursor:pointer;transition:border-color .12s,background .12s}
.lab-point:hover{border-color:var(--acc)}
.lab-point.on{border-color:var(--acc);background:color-mix(in srgb,var(--acc) 7%,transparent)}
.lab-point input{margin-top:3px;flex:0 0 auto;accent-color:var(--acc)}
.lab-point-body{display:flex;flex-direction:column;gap:3px}
.lab-point-head{font-size:12.5px;font-weight:650;color:var(--ink);display:flex;align-items:center;gap:8px;flex-wrap:wrap;line-height:1.4}
.lab-point-d{line-height:1.5}
.lab-draft-card,.lab-hold-card{position:sticky;top:8px}
.lab-hold-card{margin-top:12px}
.lab-draft{width:100%;font-family:ui-monospace,monospace;font-size:12px;line-height:1.55;resize:vertical}
.lab-hold-row{padding:8px 0;border-top:1px dashed var(--line)}
.lab-hold-row:first-child{border-top:0}

/* ===== Compliance Planner (vp-*) ===== */
.vp-disclaimer{border-left:3px solid var(--warn)}
.vp-check{display:inline-flex;gap:6px;align-items:center;color:var(--ink);font-weight:500;margin:0;cursor:pointer;font-size:12.5px}
.vp-check input{width:auto}
.vp-badge{display:inline-block;padding:1px 6px;border-radius:var(--radius-xs);
  font-size:var(--fs-1);font-weight:var(--fw-medium);letter-spacing:.02em;vertical-align:middle}
.vp-stop{background:rgba(224,104,95,.16);color:var(--err);border:1px solid var(--err)}
.vp-review{background:rgba(224,164,74,.16);color:var(--warn);border:1px solid var(--warn)}
.vp-inform{background:rgba(75,191,151,.14);color:var(--acc2);border:1px solid var(--acc2)}
.vp-flux{background:rgba(95,182,201,.14);color:var(--acc3);border:1px solid var(--acc3)}
.vp-verify{background:rgba(70,166,221,.14);color:var(--acc);border:1px solid var(--acc)}
.vp-summary{margin-top:14px}
.vp-tally{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.vp-stopbox{margin-top:12px;padding:10px 14px;border:1px solid var(--err);border-radius:10px;background:rgba(224,104,95,.08)}
.vp-stopbox ul{margin:6px 0 0;padding-left:20px}
.vp-stopbox li{margin:3px 0}
.vp-lock{font-size:10px;color:var(--err);border:1px solid var(--err);border-radius:6px;padding:0 5px;margin-left:4px}
.vp-note{margin-top:10px;color:var(--muted)}
.vp-section{margin-top:14px}
.vp-section h3{margin:0 0 10px}
.vp-rule{border:1px solid var(--line);border-radius:10px;padding:11px 13px;margin:9px 0;background:var(--panel2)}
.vp-rule.vp-stop{border-left:3px solid var(--err)}
.vp-rule.vp-review{border-left:3px solid var(--warn)}
.vp-rule.vp-inform{border-left:3px solid var(--acc2)}
.vp-rule-head{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.vp-rule-meta{margin:3px 0}
.vp-rule-sum{margin:6px 0;line-height:1.5}
.vp-flags{margin:6px 0;display:flex;gap:6px;flex-wrap:wrap}
.vp-raised{margin:5px 0;color:var(--muted)}
.vp-raised code{background:var(--bg2);padding:1px 6px;border-radius:5px;font-size:11px;color:var(--acc)}
.vp-actions{margin:6px 0 4px;padding-left:20px}
.vp-actions li{margin:3px 0;line-height:1.45}
.vp-cites{margin-top:6px;line-height:1.7}
.vp-cites a{color:var(--acc2);word-break:break-word}
.vp-notes{margin-top:6px;line-height:1.45;font-style:italic}
.vp-crosslink{display:inline-block;margin-top:6px;color:var(--acc);font-size:12px;font-weight:600;cursor:pointer;text-decoration:none}
.vp-crosslink:hover{text-decoration:underline}
.vp-live{margin-top:14px;border-left:3px solid var(--acc2)}
.vp-live-head h3{margin:0 0 2px}
.vp-live-dom{margin:12px 0;padding-top:10px;border-top:1px solid var(--line)}
.vp-live-domhead{margin-bottom:4px}
.vp-live-doc{margin:8px 0;padding:8px 11px;border:1px solid var(--line);border-radius:8px;background:var(--panel2)}
.vp-live-doc-head{margin-bottom:2px}
.vp-live-doc-head a{color:var(--ink);text-decoration:none}
.vp-live-doc-head a:hover{color:var(--acc2);text-decoration:underline}
.vp-live-abs{margin-top:5px;line-height:1.45;color:var(--muted)}

/* ══════════════════════════════════════════════════════════════════
   Eco theme enhancement layer.
   Purely additive & visual: a soft header rule and a calm card-hover
   tint. Uses only the existing --acc/--acc2/--panel/--line/--shadow
   tokens above, so it re-colors automatically with the light/dark
   toggle and adds no new selectors that any JS depends on. Prior neon
   glows, gradient header text, and a scanline overlay have been
   removed as not fitting the calmer eco aesthetic.
   ══════════════════════════════════════════════════════════════════ */
:root{--font-mono-accent:ui-monospace,"SF Mono",Menlo,"Cascadia Code",monospace}

/* Phase 8b: the accent GRADIENT rule under the header bar is replaced by a
   single structural hairline. A two-colour gradient stripe is decoration;
   the header needs a boundary. */
header{position:relative}
header::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--n-line-2)}

/* Phase 8b: NO card hover effect at all. A card is not a button -- glowing
   its rim on mouse-over implies an affordance that is not there, and 428
   destinations worth of rims lighting up as the cursor crosses them is the
   single most "generated landing page" behaviour in the app. */

/* Table headers: UI font, uppercase micro-caps -- a real column header.
   Phase 8b moved MONOSPACE off the header and onto the data cells (see the
   th,td rule above), which is where column alignment actually matters. */
th{font-family:var(--font-ui);font-size:var(--fs-1);letter-spacing:var(--ls-caps);
  text-transform:uppercase;font-weight:var(--fw-semibold);color:var(--n-ink-2)}

@media (prefers-reduced-motion: reduce){
  *{scroll-behavior:auto}
}

/* ── Human-readable / Code output toggle (ws_shared_outputmode.js) ──────
   One global preference, shown as a header pill (#outputModeToggle), that
   flips visibility of the two views baked into every GLOutput.wrap(...)
   result block across all workspace groups. */
.gl-outmode-btn{min-width:58px;font-weight:600}
.gl-outmode-btn.gl-outmode-code{color:var(--acc);border-color:var(--acc)}
.gl-output-wrap{margin-top:8px}
.gl-out-label{font-size:11px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;
  color:var(--muted);margin-bottom:4px}
.gl-out-kv{display:flex;flex-direction:column;gap:2px;font-size:13px}
.gl-out-row{display:flex;justify-content:space-between;gap:12px;padding:3px 0;
  border-bottom:1px solid var(--line)}
.gl-out-row:last-child{border-bottom:none}
.gl-out-k{color:var(--muted)}
.gl-out-v{font-weight:600;text-align:right}
.gl-out-empty{color:var(--muted);font-style:italic;font-size:12px;padding:4px 0}
.gl-out-raw{background:var(--panel2,var(--panel));border:1px solid var(--line);border-radius:6px;
  padding:8px 10px;font-family:var(--font-mono-accent,ui-monospace,monospace);font-size:11.5px;
  line-height:1.45;overflow:auto;max-height:340px;white-space:pre-wrap;word-break:break-word}

/* ═══════════════════════════════════════════════════════════════════════════
   PHASE 8 — W0 SHARED COMPONENT LAYER
   ───────────────────────────────────────────────────────────────────────────
   Everything below is the contract W1–W10 build against: the four .btn
   variants, the .n-layer disclosure widget, the shared .n-inspector, and the
   collapsed-rail icon primitives. Appended at the END of app.css so it wins
   over the pre-Phase-8 rules above at equal specificity without editing them
   (the existing `button{...}` base rule keeps working untouched for every
   un-migrated call site).

   NON-NEGOTIABLE, from §1.8:
     1. Focus is NEVER removed. No `outline:none` without an equivalent
        :focus-visible replacement, and the ring is the SAME token everywhere
        so keyboard users see one affordance across all 428 targets.
     2. Selection is a tint + left bar, not a saturated fill — except the
        single active rail item, which keeps its solid --n-accent fill.
     3. Hover NEVER changes layout. Surface and colour only; a border-WIDTH
        change on hover reflows 428 rows.
     4. Disabled is never the only signal — pair it with a title/hint.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ---------- 1. Buttons: exactly four variants (§1.9). No fifth. ----------
   `.btn` is additive: it does NOT restyle the bare `button` element, so the
   hundreds of existing `<button>` / `<button class="ghost sm">` call sites are
   untouched. New work opts in with .btn + one variant class.
   At most ONE .btn-primary visible per view at a time. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  min-height:var(--row-h);padding:var(--sp-2) var(--sp-4);
  font-family:var(--font-ui);font-size:var(--fs-3);line-height:var(--lh-3);
  font-weight:var(--fw-medium);border-radius:var(--radius-sm);
  border:var(--bw-1) solid transparent;background:transparent;color:var(--n-ink-1);
  cursor:pointer;text-decoration:none;white-space:nowrap;
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease),
             border-color var(--dur-1) var(--ease)}
.btn:focus-visible{outline:var(--bw-2) solid var(--n-focus-ring);outline-offset:2px}
.btn:active:not(:disabled){transform:translateY(1px)}
.btn:disabled,.btn[aria-disabled="true"]{opacity:.55;cursor:not-allowed;transform:none}
.btn[aria-busy="true"]{color:var(--n-ink-2)}

.btn.btn-primary{background:var(--n-accent);color:var(--n-on-accent);border-color:transparent;
  font-weight:var(--fw-semibold)}
.btn.btn-primary:hover:not(:disabled){background:var(--n-accent);filter:brightness(1.08)}
.btn.btn-primary:active:not(:disabled){filter:brightness(.94)}

.btn.btn-secondary{background:var(--n-bg-3);color:var(--n-ink-1);border-color:var(--n-line-3)}
.btn.btn-secondary:hover:not(:disabled){background:var(--n-bg-4)}
.btn.btn-secondary:active:not(:disabled){background:var(--n-bg-4);filter:brightness(.96)}

.btn.btn-ghost{background:transparent;color:var(--n-ink-2);border-color:transparent}
.btn.btn-ghost:hover:not(:disabled){background:var(--n-bg-3);color:var(--n-ink-1);
  border-color:var(--n-line-3)}

.btn.btn-danger{background:transparent;color:var(--n-err);border-color:var(--n-err)}
.btn.btn-danger:hover:not(:disabled){background:color-mix(in srgb,var(--n-err) 14%,transparent);
  color:var(--n-err)}

/* disabled must not keep a hover-coloured surface */
.btn.btn-primary:disabled,.btn.btn-secondary:disabled,
.btn.btn-ghost:disabled,.btn.btn-danger:disabled{background:var(--n-bg-2);color:var(--n-ink-3);
  border-color:var(--n-line-1);filter:none}

.btn.btn-sm{font-size:var(--fs-2);padding:var(--sp-1) var(--sp-3);gap:var(--sp-1);min-height:auto}
.btn.btn-lg{font-size:var(--fs-4);padding:var(--sp-3) var(--sp-5)}
.btn.btn-icon{padding:var(--sp-2);min-width:var(--row-h)}
.btn.btn-block{width:100%}
.btn .icn{width:16px;height:16px;flex:0 0 auto;vertical-align:0}

/* ---------- 2. The layered-button pattern (§2.5) ----------
   A .n-layer may contain leaf actions and AT MOST ONE nested .n-layer.
   Never a third level — anything wanting depth 3 is a view, route to it.
   Closed state is expressed ONLY by the `hidden` attribute on the panel,
   never by style.display, so the panel's contents leave the tab order
   automatically and no manual tabindex bookkeeping is needed (§2.4). */
.n-layer{position:relative}
.n-layer-trigger{display:flex;align-items:center;gap:var(--sp-2);width:100%;
  min-height:var(--row-h);padding:var(--density-pad);
  background:transparent;border:var(--bw-1) solid transparent;color:var(--n-ink-1);
  cursor:pointer;text-align:left;font-family:var(--font-ui);
  border-radius:var(--radius-sm);font-size:var(--fs-3);font-weight:var(--fw-medium);
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}
.n-layer-trigger:hover{background:var(--n-bg-3)}
.n-layer-icon{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;flex:0 0 auto;color:var(--n-ink-2)}
.n-layer-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.n-layer-count{font-size:var(--fs-1);color:var(--n-ink-2);background:var(--n-bg-3);
  border-radius:var(--radius-pill);padding:0 var(--sp-2)}
.n-layer-caret{flex:0 0 auto;display:inline-flex;align-items:center;color:var(--n-ink-2);
  transition:transform var(--dur-2) var(--ease)}
.n-layer-trigger[aria-expanded="true"] .n-layer-caret{transform:rotate(180deg)}
.n-layer-trigger[aria-expanded="true"]{background:var(--n-bg-3)}
.n-layer-trigger:focus-visible{outline:var(--bw-2) solid var(--n-focus-ring);outline-offset:2px}

.n-layer-panel[hidden]{display:none}
.n-layer-panel{display:flex;flex-direction:column;gap:var(--sp-1);padding:var(--sp-2)}
/* inline (rail) variant — expands in flow, pushes siblings down */
.n-layer--inline > .n-layer-panel{margin-left:var(--sp-3);
  border-left:var(--bw-1) solid var(--n-line-1);padding-left:var(--sp-2)}
/* overlay (toolbar) variant — floats, closes on outside click */
.n-layer--overlay > .n-layer-panel{position:absolute;z-index:40;top:calc(100% + var(--sp-1));
  left:0;min-width:240px;background:var(--n-bg-3);border:var(--bw-1) solid var(--n-line-2);
  border-radius:var(--radius-md);box-shadow:var(--n-shadow-2)}

.n-layer-item{display:flex;align-items:center;gap:var(--sp-2);width:100%;
  min-height:var(--row-h);padding:var(--density-pad);border-radius:var(--radius-sm);
  font-family:var(--font-ui);font-size:var(--fs-2);color:var(--n-ink-1);
  background:transparent;border:0;text-align:left;cursor:pointer}
.n-layer-item:hover{background:var(--n-bg-4)}
.n-layer-item:focus-visible{outline:var(--bw-2) solid var(--n-focus-ring);outline-offset:2px}
.n-layer-item[aria-current="page"]{background:var(--n-accent-tint);color:var(--n-accent);
  box-shadow:inset 3px 0 0 var(--n-accent)}
.n-layer-item[disabled],.n-layer-item[aria-disabled="true"]{color:var(--n-ink-3);
  opacity:.55;cursor:not-allowed}
.n-layer-item-icon{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;flex:0 0 auto;color:var(--n-ink-2)}
.n-layer-item-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.n-layer-item-hint{margin-left:auto;font-size:var(--fs-1);color:var(--n-ink-3);flex:0 0 auto}
.n-layer-sep{height:var(--bw-1);background:var(--n-line-1);margin:var(--sp-1) 0}

/* ---------- 3. Shared right-side inspector (§3.5) ----------
   A workspace gets AT MOST ONE right-side inspector and it is
   selection-driven: clicking a feature/primer/fragment swaps the inspector to
   that entity's properties, common fields first, ONE "Advanced" affordance,
   never more than one level deep. This replaces the per-module permanent side
   rails (15 vlm-panel, 10 vax-panel, 6 lnpf-panel, …). */
.n-inspector{display:flex;flex-direction:column;gap:var(--sp-3);
  width:300px;flex:0 0 300px;min-width:0;
  background:var(--n-bg-2);border-left:var(--bw-1) solid var(--n-line-1);
  padding:var(--sp-4);overflow-y:auto}
.n-inspector[hidden]{display:none}
.n-inspector-head{display:flex;align-items:center;gap:var(--sp-2);
  padding-bottom:var(--sp-2);border-bottom:var(--bw-1) solid var(--n-line-1)}
.n-inspector-title{flex:1;min-width:0;font-size:var(--fs-4);line-height:var(--lh-4);
  font-weight:var(--fw-semibold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.n-inspector-kind{font-size:var(--fs-1);color:var(--n-ink-2);background:var(--n-bg-3);
  border-radius:var(--radius-pill);padding:0 var(--sp-2)}
.n-inspector-body{display:flex;flex-direction:column;gap:var(--sp-2)}
.n-inspector-row{display:flex;justify-content:space-between;gap:var(--sp-3);
  font-size:var(--fs-2);line-height:var(--lh-2);padding:var(--sp-1) 0}
.n-inspector-k{color:var(--n-ink-2);flex:0 0 auto}
.n-inspector-v{font-weight:var(--fw-medium);text-align:right;min-width:0;word-break:break-word}
.n-inspector-empty{color:var(--n-ink-3);font-size:var(--fs-2);font-style:italic;
  padding:var(--sp-3) 0}
@media(max-width:1100px){.n-inspector{width:260px;flex-basis:260px}}
@media(max-width:800px){.n-inspector{display:none}}

/* ---------- 4. Collapsed-rail icon primitives (§5.3) ----------
   `.ri-ico` already existed; `.ri-mono` is the step-3 monogram fallback that
   guarantees NO rail item can ever render blank when collapsed. A monogram is
   a SAFETY NET, not a licence: an agent shipping monograms has not completed
   its checklist item 4, and the verification counts them. */
.ri-ico{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;flex:0 0 auto;color:var(--n-ink-2)}
.ri-ico .icn{width:16px;height:16px;vertical-align:0}
.rail-item.active .ri-ico{color:var(--n-on-accent)}
.ri-mono{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;font-family:var(--font-ui);font-size:var(--fs-1);
  line-height:1;font-weight:var(--fw-semibold);letter-spacing:0;
  color:var(--n-ink-3);text-transform:uppercase;user-select:none}
.rail-item.active .ri-mono{color:var(--n-on-accent)}
/* a bench-inherited icon reads one step quieter than a registered one */
.rail-item[data-icon-src="bench"] .ri-ico{color:var(--n-ink-3)}
.rail-item.active[data-icon-src="bench"] .ri-ico{color:var(--n-on-accent)}

/* workspace-button icons (all 10 .wsnav-btn were blank when collapsed) */
.wsnav-icon{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;flex:0 0 auto;color:var(--n-ink-2)}
.wsnav-icon .icn{width:16px;height:16px;vertical-align:0}
.wsnav-block.open > .wsnav-btn .wsnav-icon{color:var(--n-accent)}

/* ---------- 5. Density control in the header ---------- */
.n-density{display:inline-flex;align-items:center;border:var(--bw-1) solid var(--n-line-3);
  border-radius:var(--radius-sm);overflow:hidden}
.n-density-btn{padding:var(--sp-1) var(--sp-3);background:var(--n-bg-3);color:var(--n-ink-2);
  border:0;cursor:pointer;font-family:var(--font-ui);font-size:var(--fs-2);
  font-weight:var(--fw-medium)}
.n-density-btn[aria-pressed="true"]{background:var(--n-accent);color:var(--n-on-accent)}
.n-density-btn:focus-visible{outline:var(--bw-2) solid var(--n-focus-ring);outline-offset:-2px}
.n-tier{display:inline-flex;align-items:center;border:var(--bw-1) solid var(--n-line-3);
  border-radius:var(--radius-sm);overflow:hidden}
.n-tier-btn{padding:var(--sp-1) var(--sp-3);background:var(--n-bg-3);color:var(--n-ink-2);
  border:0;cursor:pointer;font-family:var(--font-ui);font-size:var(--fs-2);
  font-weight:var(--fw-medium)}
.n-tier-btn[aria-pressed="true"]{background:var(--n-accent);color:var(--n-on-accent)}
.n-tier-btn:focus-visible{outline:var(--bw-2) solid var(--n-focus-ring);outline-offset:-2px}

/* ═══════════════════════════════════════════════════════════════════════════
   PHASE 8b — DE-AI-AESTHETIC ADDITIONS
   ───────────────────────────────────────────────────────────────────────────
   Two small primitives the de-AI pass needs, appended last so they win at
   equal specificity without editing the rules above.
   ═══════════════════════════════════════════════════════════════════════════ */

/* `.unit` — the explicit unit next to a numeric input (°C, mM, kcal/mol, %, µg).
   A number without its unit is not a measurement, and a decorative slider hides
   the unit entirely. Rendered quiet and monospaced so it reads as annotation on
   the field rather than as part of the label sentence. */
.unit{font-family:var(--font-mono);font-size:var(--fs-1);color:var(--n-ink-2);
  font-weight:var(--fw-normal);text-transform:none;letter-spacing:0;white-space:nowrap}

/* `.hidden-echo` — a value echo that used to sit beside a slider ("50%"). The
   numeric input now shows its own value, so the echo is redundant ON SCREEN but
   is NOT deleted: three oninput handlers and GL.pareto() write to these ids, and
   removing the nodes would throw. Kept in the DOM, hidden from sight, and
   aria-hidden at the call site so it is not read out twice. */
.hidden-echo{display:none}

/* Raw-output blocks: monospace, selectable, scrollable. "Expose raw outputs
   (JSON/FASTA) and the actual parameters used rather than hiding the
   computation" -- so the raw view is a first-class surface, not a debug panel. */
.n-raw{font-family:var(--font-mono);font-size:var(--fs-mono-1);line-height:var(--lh-2);
  background:var(--n-bg-3);border:var(--bw-1) solid var(--n-line-1);
  border-radius:var(--radius-sm);padding:var(--sp-2) var(--sp-3);margin:var(--sp-2) 0;
  max-height:360px;overflow:auto;white-space:pre-wrap;word-break:break-word;
  -webkit-user-select:text;user-select:text}
.n-raw-head{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-3);
  font-size:var(--fs-1);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--n-ink-2);font-weight:var(--fw-semibold)}

/* A method citation under an analytical module. This is the "citations as a
   design element" primitive: small, always-on, monospace source line -- not a
   tooltip the user has to discover. */
.n-cite{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--n-ink-2);
  margin-top:var(--sp-2);padding-top:var(--sp-1);
  border-top:var(--bw-1) solid var(--n-line-1)}
.n-cite-label{font-family:var(--font-mono);color:var(--n-ink-1)}

/* ═══════════════════════════════════════════════════════════════════════════
   ONBOARDING SYSTEM
   Multi-step introduction for new users.
   ═══════════════════════════════════════════════════════════════════════════ */
.onboarding-overlay{
  display:none;position:fixed;inset:0;z-index:500;
  background:var(--n-scrim);backdrop-filter:blur(4px);
  align-items:center;justify-content:center}
.onboarding-overlay.show{display:flex}

.onboarding-container{
  width:100%;max-width:640px;max-height:90vh;overflow-y:auto;
  margin:var(--sp-4)}

.onboarding-step{
  background:var(--n-bg-2);border:1px solid var(--n-line-1);
  border-radius:var(--radius-lg);padding:var(--sp-6);
  box-shadow:var(--n-shadow-3);text-align:center}

/* Welcome screen */
.onboarding-welcome .onboarding-logo{margin-bottom:var(--sp-4)}
.onboarding-welcome .onboarding-logo img{width:64px;height:64px}
.onboarding-title{font-size:var(--fs-6);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0 0 var(--sp-2)}
.onboarding-tagline{font-size:var(--fs-4);color:var(--n-accent);
  margin:0 0 var(--sp-3)}
.onboarding-subtitle{font-size:var(--fs-3);color:var(--n-ink-2);
  margin:0 0 var(--sp-5);line-height:var(--lh-3)}

.onboarding-actions{display:flex;gap:var(--sp-3);justify-content:center;
  margin-top:var(--sp-4)}

.onboarding-btn{
  padding:var(--sp-2) var(--sp-4);border-radius:var(--radius-sm);
  font-size:var(--fs-3);font-weight:var(--fw-medium);cursor:pointer;
  border:1px solid transparent;transition:all .15s ease}
.onboarding-btn.primary{
  background:var(--n-accent);color:var(--n-on-accent);border-color:var(--n-accent)}
.onboarding-btn.primary:hover{filter:brightness(1.1)}
.onboarding-btn.secondary{
  background:var(--n-bg-3);color:var(--n-ink-1);border-color:var(--n-line-2)}
.onboarding-btn.secondary:hover{background:var(--n-bg-4)}

.onboarding-skip{
  display:block;margin:var(--sp-4) auto 0;padding:var(--sp-1);
  background:none;border:none;color:var(--n-ink-2);font-size:var(--fs-2);
  cursor:pointer;text-decoration:underline}
.onboarding-skip:hover{color:var(--n-ink-1)}

/* Workspace selector */
.onboarding-step-title{font-size:var(--fs-5);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0 0 var(--sp-2)}
.onboarding-step-desc{font-size:var(--fs-3);color:var(--n-ink-2);
  margin:0 0 var(--sp-4)}

.onboarding-workspace-grid{
  display:grid;grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));
  gap:var(--sp-3);margin:var(--sp-4) 0}

.onboarding-workspace-card{
  background:var(--n-bg-3);border:2px solid var(--n-line-1);
  border-radius:var(--radius-md);padding:var(--sp-4);cursor:pointer;
  text-align:left;transition:all .15s ease}
.onboarding-workspace-card:hover{border-color:var(--n-line-2);background:var(--n-bg-4)}
.onboarding-workspace-card.selected{
  border-color:var(--n-accent);background:var(--n-accent-tint)}

.owc-icon{width:36px;height:36px;color:var(--n-accent);margin-bottom:var(--sp-2)}
.owc-icon svg{width:100%;height:100%}
.owc-name{font-size:var(--fs-4);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0 0 var(--sp-1)}
.owc-desc{font-size:var(--fs-2);color:var(--n-ink-2);margin:0 0 var(--sp-2)}
.owc-features{font-size:var(--fs-1);color:var(--n-ink-2);margin:0;
  padding-left:var(--sp-3);list-style:disc}
.owc-features li{margin:2px 0}

/* Tour intro */
.onboarding-tour-intro .onboarding-tour-icon{
  width:48px;height:48px;color:var(--n-accent);margin:0 auto var(--sp-3)}
.onboarding-tour-intro .onboarding-tour-icon svg{width:100%;height:100%}

.onboarding-tour-preview{
  display:flex;flex-direction:column;gap:var(--sp-2);
  margin:var(--sp-4) auto;max-width:280px;text-align:left}
.otp-item{display:flex;align-items:center;gap:var(--sp-2);
  font-size:var(--fs-3);color:var(--n-ink-2)}
.otp-num{width:24px;height:24px;border-radius:50%;
  background:var(--n-accent-tint);color:var(--n-accent);
  font-size:var(--fs-2);font-weight:var(--fw-semibold);
  display:flex;align-items:center;justify-content:center;flex-shrink:0}

/* Sample project */
.onboarding-sample-card{
  background:var(--n-bg-3);border:1px solid var(--n-line-1);
  border-radius:var(--radius-md);padding:var(--sp-4);margin:var(--sp-4) 0;
  text-align:left}
.osc-name{font-size:var(--fs-4);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0 0 var(--sp-1)}
.osc-desc{font-size:var(--fs-3);color:var(--n-ink-2);margin:0 0 var(--sp-2)}
.osc-meta{display:flex;gap:var(--sp-2);font-size:var(--fs-2)}
.osc-tag{background:var(--n-accent);color:var(--n-on-accent);
  padding:2px 6px;border-radius:var(--radius-xs)}
.osc-org{color:var(--n-ink-2)}

/* ═══════════════════════════════════════════════════════════════════════════
   TUTORIAL SYSTEM
   Reusable step-by-step guides with spotlight highlighting.
   ═══════════════════════════════════════════════════════════════════════════ */
.tutorial-overlay{
  display:none;position:fixed;inset:0;z-index:300;
  pointer-events:none}
.tutorial-overlay.show{display:block;pointer-events:auto}

.tutorial-spotlight{
  position:absolute;border-radius:var(--radius-sm);
  box-shadow:0 0 0 9999px rgba(0,0,0,.55);
  pointer-events:none;opacity:0;transition:all .25s ease}
.tutorial-spotlight.show{opacity:1}

.tutorial-tooltip{
  position:absolute;width:320px;
  background:var(--n-bg-2);border:1px solid var(--n-line-1);
  border-radius:var(--radius-md);box-shadow:var(--n-shadow-3);
  padding:var(--sp-3);z-index:301;opacity:0;
  transform:translateY(8px);transition:all .2s ease}
.tutorial-overlay.show .tutorial-tooltip{opacity:1;transform:translateY(0)}

/* Tooltip arrow */
.tutorial-tooltip::before{
  content:'';position:absolute;width:0;height:0;
  border:8px solid transparent}
.tutorial-tooltip-bottom::before{
  bottom:100%;left:50%;transform:translateX(-50%);
  border-bottom-color:var(--n-bg-2)}
.tutorial-tooltip-top::before{
  top:100%;left:50%;transform:translateX(-50%);
  border-top-color:var(--n-bg-2)}
.tutorial-tooltip-left::before{
  left:100%;top:50%;transform:translateY(-50%);
  border-left-color:var(--n-bg-2)}
.tutorial-tooltip-right::before{
  right:100%;top:50%;transform:translateY(-50%);
  border-right-color:var(--n-bg-2)}

.tutorial-tooltip-header{display:flex;justify-content:space-between;
  align-items:center;margin-bottom:var(--sp-2)}
.tutorial-progress{font-size:var(--fs-1);color:var(--n-ink-2)}
.tutorial-close{background:none;border:none;color:var(--n-ink-2);
  font-size:18px;cursor:pointer;padding:0;line-height:1}
.tutorial-close:hover{color:var(--n-ink-1)}

.tutorial-tooltip-title{font-size:var(--fs-4);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0 0 var(--sp-2)}
.tutorial-tooltip-body{font-size:var(--fs-3);color:var(--n-ink-2);
  line-height:var(--lh-3);margin:0 0 var(--sp-2)}
.tutorial-tooltip-tip{font-size:var(--fs-2);color:var(--n-accent);
  margin:var(--sp-2) 0;padding:var(--sp-2);
  background:var(--n-accent-tint);border-radius:var(--radius-xs)}

.tutorial-tooltip-footer{display:flex;justify-content:flex-end;
  gap:var(--sp-2);margin-top:var(--sp-3)}

.tutorial-btn{
  padding:var(--sp-1) var(--sp-3);border-radius:var(--radius-xs);
  font-size:var(--fs-2);font-weight:var(--fw-medium);cursor:pointer;
  border:1px solid transparent;transition:all .15s ease}
.tutorial-btn.primary{
  background:var(--n-accent);color:var(--n-on-accent);border-color:var(--n-accent)}
.tutorial-btn.primary:hover{filter:brightness(1.1)}
.tutorial-btn.secondary{
  background:transparent;color:var(--n-ink-2);border-color:var(--n-line-2)}
.tutorial-btn.secondary:hover{background:var(--n-bg-3);color:var(--n-ink-1)}

.tutorial-progress-bar{
  height:3px;background:var(--n-bg-4);border-radius:2px;
  margin-top:var(--sp-3);overflow:hidden}
.tutorial-progress-fill{height:100%;background:var(--n-accent);
  transition:width .3s ease}

/* Tutorial prompt (first-time hint) */
.tutorial-prompt{
  position:fixed;bottom:var(--sp-4);right:var(--sp-4);z-index:200;
  animation:tutorial-prompt-in .3s ease}
@keyframes tutorial-prompt-in{from{opacity:0;transform:translateY(10px)}}
.tutorial-prompt.fade-out{opacity:0;transform:translateY(10px);
  transition:all .3s ease}

.tutorial-prompt-content{
  display:flex;align-items:center;gap:var(--sp-2);
  background:var(--n-bg-2);border:1px solid var(--n-line-1);
  border-radius:var(--radius-md);padding:var(--sp-2) var(--sp-3);
  box-shadow:var(--n-shadow-2);font-size:var(--fs-3)}
.tutorial-prompt-icon{font-size:16px}
.tutorial-prompt-text{color:var(--n-ink-2)}
.tutorial-prompt-text a{color:var(--n-accent);text-decoration:underline}
.tutorial-prompt-close{background:none;border:none;color:var(--n-ink-2);
  font-size:16px;cursor:pointer;padding:0;margin-left:var(--sp-1)}
.tutorial-prompt-close:hover{color:var(--n-ink-1)}

/* ═══════════════════════════════════════════════════════════════════════════
   HELP SYSTEM
   Contextual help icons and slide-out panel.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Help icon */
.help-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;border-radius:50%;
  background:var(--n-bg-3);border:1px solid var(--n-line-2);
  color:var(--n-ink-2);font-size:11px;cursor:pointer;
  transition:all .15s ease;vertical-align:middle;margin-left:4px}
.help-icon:hover{background:var(--n-accent-tint);border-color:var(--n-accent);
  color:var(--n-accent)}
.help-icon-sm{width:14px;height:14px;font-size:9px}
.help-icon-glyph{font-weight:var(--fw-semibold)}

/* Help tooltip */
.help-tooltip{
  position:absolute;width:280px;
  background:var(--n-bg-2);border:1px solid var(--n-line-1);
  border-radius:var(--radius-md);box-shadow:var(--n-shadow-3);
  padding:var(--sp-3);z-index:400;
  opacity:0;visibility:hidden;transform:translateY(4px);
  transition:all .15s ease}
.help-tooltip.show{opacity:1;visibility:visible;transform:translateY(0)}
.help-tooltip.help-tooltip-above{transform:translateY(-4px)}
.help-tooltip.help-tooltip-above.show{transform:translateY(0)}

.help-tooltip-header{display:flex;justify-content:space-between;
  align-items:flex-start;margin-bottom:var(--sp-2)}
.help-tooltip-title{font-size:var(--fs-3);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0}
.help-tooltip-close{background:none;border:none;color:var(--n-ink-2);
  font-size:16px;cursor:pointer;padding:0;line-height:1}
.help-tooltip-close:hover{color:var(--n-ink-1)}

.help-tooltip-body{font-size:var(--fs-2);color:var(--n-ink-2);
  line-height:var(--lh-2);margin:0}
.help-tooltip-tip{font-size:var(--fs-2);color:var(--n-accent);
  margin-top:var(--sp-2)}
.help-tooltip-link{display:block;margin-top:var(--sp-2);
  font-size:var(--fs-2);color:var(--n-accent);text-decoration:none}
.help-tooltip-link:hover{text-decoration:underline}

/* Help panel (slide-out) */
.help-panel{
  position:fixed;top:0;right:0;bottom:0;width:380px;max-width:100vw;
  background:var(--n-bg-1);border-left:1px solid var(--n-line-1);
  box-shadow:var(--n-shadow-3);z-index:450;
  transform:translateX(100%);transition:transform .25s ease;
  display:flex;flex-direction:column}
.help-panel.show{transform:translateX(0)}

.help-panel-header{
  display:flex;justify-content:space-between;align-items:center;
  padding:var(--sp-4);border-bottom:1px solid var(--n-line-1)}
.help-panel-title{font-size:var(--fs-5);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0}
.help-panel-close{background:none;border:none;color:var(--n-ink-2);
  font-size:24px;cursor:pointer;padding:0;line-height:1}
.help-panel-close:hover{color:var(--n-ink-1)}

.help-panel-search{padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--n-line-1)}
.help-search-input{width:100%;padding:var(--sp-2);
  background:var(--n-bg-3);border:1px solid var(--n-line-2);
  border-radius:var(--radius-sm);font-size:var(--fs-3);color:var(--n-ink-1)}
.help-search-input:focus{outline:none;border-color:var(--n-accent)}
.help-search-input::placeholder{color:var(--n-ink-3)}

.help-panel-content{flex:1;overflow-y:auto;padding:var(--sp-4)}

.help-section{margin-bottom:var(--sp-5)}
.help-section-title{font-size:var(--fs-3);font-weight:var(--fw-semibold);
  color:var(--n-ink-1);margin:0 0 var(--sp-3);
  text-transform:uppercase;letter-spacing:var(--ls-caps)}

/* Quick start guides */
.help-guides{display:flex;flex-direction:column;gap:var(--sp-2)}
.help-guide-item{
  background:var(--n-bg-3);border:1px solid var(--n-line-1);
  border-radius:var(--radius-sm);padding:var(--sp-3)}
.help-guide-title{font-size:var(--fs-3);font-weight:var(--fw-medium);
  color:var(--n-ink-1);margin:0 0 var(--sp-1)}
.help-guide-desc{font-size:var(--fs-2);color:var(--n-ink-2);
  margin:0 0 var(--sp-2)}
.help-guide-actions{display:flex;gap:var(--sp-2)}
.help-guide-tutorial{
  padding:var(--sp-1) var(--sp-2);border-radius:var(--radius-xs);
  background:var(--n-accent);color:var(--n-on-accent);border:none;
  font-size:var(--fs-2);cursor:pointer}
.help-guide-tutorial:hover{filter:brightness(1.1)}
.help-guide-link{font-size:var(--fs-2);color:var(--n-accent);
  text-decoration:none}
.help-guide-link:hover{text-decoration:underline}

/* FAQ */
.help-faq{display:flex;flex-direction:column;gap:var(--sp-1)}
.help-faq-item{border:1px solid var(--n-line-1);border-radius:var(--radius-sm)}
.help-faq-item[open]{background:var(--n-bg-3)}
.help-faq-q{
  padding:var(--sp-2) var(--sp-3);font-size:var(--fs-3);
  font-weight:var(--fw-medium);color:var(--n-ink-1);cursor:pointer;
  list-style:none}
.help-faq-q::-webkit-details-marker{display:none}
.help-faq-q::before{content:'▸';margin-right:var(--sp-2);color:var(--n-ink-2);
  transition:transform .15s ease;display:inline-block}
.help-faq-item[open] .help-faq-q::before{transform:rotate(90deg)}
.help-faq-a{padding:0 var(--sp-3) var(--sp-3);font-size:var(--fs-2);
  color:var(--n-ink-2);line-height:var(--lh-2)}

.help-no-results{font-size:var(--fs-3);color:var(--n-ink-2);
  text-align:center;padding:var(--sp-4)}

/* Videos */
.help-videos{display:flex;flex-direction:column;gap:var(--sp-2)}
.help-video-item{
  display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-2);border:1px solid var(--n-line-1);
  border-radius:var(--radius-sm);text-decoration:none;
  transition:background .15s ease}
.help-video-item:hover{background:var(--n-bg-3)}
.help-video-thumb{
  width:48px;height:36px;background:var(--n-bg-4);
  border-radius:var(--radius-xs);
  display:flex;align-items:center;justify-content:center;
  color:var(--n-ink-2);font-size:16px;flex-shrink:0}
.help-video-info{display:flex;flex-direction:column}
.help-video-title{font-size:var(--fs-3);color:var(--n-ink-1)}
.help-video-duration{font-size:var(--fs-1);color:var(--n-ink-2)}

/* Contact section */
.help-contact{border-top:1px solid var(--n-line-1);padding-top:var(--sp-4)}
.help-contact p{font-size:var(--fs-3);color:var(--n-ink-2);margin:0 0 var(--sp-3)}
.help-contact-links{display:flex;flex-direction:column;gap:var(--sp-2)}
.help-contact-link{
  display:flex;align-items:center;gap:var(--sp-2);
  padding:var(--sp-2);border:1px solid var(--n-line-1);
  border-radius:var(--radius-sm);text-decoration:none;
  font-size:var(--fs-3);color:var(--n-ink-1);
  transition:background .15s ease}
.help-contact-link:hover{background:var(--n-bg-3)}
.help-contact-icon{font-size:16px}


/* ═══════════════════════════════════════════════════════════════════════════
   MICRO-INTERACTIONS (Phase 6 Visual Polish)
   ═══════════════════════════════════════════════════════════════════════════
   Subtle animations for a polished, professional feel.
   Uses transform/opacity for GPU acceleration and 60fps performance.
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- Button hover/active states with smooth transitions --- */
button,
.btn,
[role="button"] {
  transition: 
    background-color 150ms ease-out,
    border-color 150ms ease-out,
    color 150ms ease-out,
    transform 100ms ease-out,
    box-shadow 150ms ease-out;
}

button:hover:not(:disabled),
.btn:hover:not(:disabled) {
  transform: translateY(-1px);
}

button:active:not(:disabled),
.btn:active:not(:disabled) {
  transform: translateY(0);
}

/* Primary button glow on hover */
button.btn--primary:hover:not(:disabled),
.btn--primary:hover:not(:disabled) {
  box-shadow: 0 4px 12px rgba(23, 69, 124, 0.25);
}

/* Ghost button subtle background */
button.btn--ghost:hover:not(:disabled),
.btn--ghost:hover:not(:disabled) {
  background-color: var(--n-bg-3);
}

/* --- Card hover lift effect --- */
.card--interactive,
.clone-tile,
.pb-card,
.prov-card,
.help-guide-item,
.help-video-item {
  transition: 
    transform 200ms ease-out,
    box-shadow 200ms ease-out,
    border-color 150ms ease-out;
}

.card--interactive:hover,
.clone-tile:hover,
.pb-card:hover,
.prov-card:hover,
.help-guide-item:hover,
.help-video-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(19, 24, 29, 0.08);
}

/* --- Modal fade-in/slide-in animations --- */
.modal,
.palette-overlay,
.tour-overlay,
#toast {
  transition: 
    opacity 200ms ease-out,
    visibility 200ms ease-out;
}

.modal__content,
.palette-box,
.tour-card {
  transition: 
    transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1),
    opacity 200ms ease-out;
}

/* Modal entrance */
@keyframes modal-enter {
  from {
    opacity: 0;
    transform: scale(0.95) translateY(8px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

/* Modal slide up */
@keyframes modal-slide-up {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Apply to modals when they become visible */
.modal--open .modal__content,
.palette-overlay:not([style*="display: none"]) .palette-box {
  animation: modal-enter 250ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

/* --- Loading skeleton shimmer --- */
.skeleton,
.loading-skeleton {
  background: linear-gradient(
    90deg,
    var(--n-bg-3) 25%,
    var(--n-bg-4) 50%,
    var(--n-bg-3) 75%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
  border-radius: var(--radius-sm);
}

@keyframes skeleton-shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

/* Skeleton text placeholder */
.skeleton--text {
  height: 1em;
  width: 100%;
}

.skeleton--text-short {
  height: 1em;
  width: 60%;
}

.skeleton--circle {
  border-radius: 50%;
}

/* --- Success checkmark animation --- */
@keyframes checkmark-draw {
  0% {
    stroke-dashoffset: 24;
  }
  100% {
    stroke-dashoffset: 0;
  }
}

@keyframes checkmark-scale {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
}

.success-checkmark {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: var(--n-accent-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  animation: checkmark-scale 400ms ease-out;
}

.success-checkmark svg {
  width: 14px;
  height: 14px;
  stroke: white;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  stroke-dasharray: 24;
  animation: checkmark-draw 400ms ease-out forwards;
}

/* Success message animation */
@keyframes success-fade-in {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.ok-msg,
.success-msg,
.alert--success {
  animation: success-fade-in 300ms ease-out;
}

/* --- Error shake animation --- */
@keyframes error-shake {
  0%, 100% {
    transform: translateX(0);
  }
  10%, 30%, 50%, 70%, 90% {
    transform: translateX(-4px);
  }
  20%, 40%, 60%, 80% {
    transform: translateX(4px);
  }
}

.error-shake,
.err-msg.shake,
input.error,
input:invalid:not(:placeholder-shown) {
  animation: error-shake 500ms ease-out;
}

/* Error field highlight */
input.error,
textarea.error,
select.error,
input:invalid:not(:placeholder-shown) {
  border-color: var(--n-err);
  background-color: rgba(169, 31, 22, 0.04);
}

/* --- Focus ring styles for accessibility --- */
*:focus-visible {
  outline: 2px solid var(--n-focus-ring);
  outline-offset: 2px;
}

/* Remove default outline for mouse users */
*:focus:not(:focus-visible) {
  outline: none;
}

/* Custom focus ring for inputs */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: none;
  border-color: var(--n-focus-ring);
  box-shadow: 0 0 0 3px rgba(23, 69, 124, 0.15);
}

/* Focus ring for buttons */
button:focus-visible,
.btn:focus-visible {
  outline: none;
  box-shadow: 
    0 0 0 2px var(--n-bg-1),
    0 0 0 4px var(--n-focus-ring);
}

/* --- Toast notifications --- */
@keyframes toast-slide-in {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes toast-slide-out {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-8px);
  }
}

.toast.show {
  animation: toast-slide-in 300ms ease-out forwards;
}

.toast.hide {
  animation: toast-slide-out 200ms ease-in forwards;
}

/* --- Spinner animation enhancement --- */
.spinner {
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Pulse animation for loading states */
@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

.loading-pulse,
.spinner-pulse {
  animation: pulse 1.5s ease-in-out infinite;
}

/* --- Accordion/Details smooth expand --- */
details {
  transition: height 200ms ease-out;
}

details summary {
  cursor: pointer;
  user-select: none;
  transition: color 150ms ease-out;
}

details summary:hover {
  color: var(--n-accent);
}

details[open] summary {
  margin-bottom: var(--sp-2);
}

/* --- Tab/navigation transitions --- */
.rail-item,
.tab,
.mini-tab,
.seg-btn {
  transition: 
    background-color 150ms ease-out,
    color 150ms ease-out,
    border-color 150ms ease-out;
}

/* --- Input transitions --- */
input,
textarea,
select {
  transition: 
    border-color 150ms ease-out,
    box-shadow 150ms ease-out,
    background-color 150ms ease-out;
}

/* --- Link hover underline animation --- */
a:not(.btn):not(.rail-item):not(.tab) {
  position: relative;
  text-decoration: none;
}

a:not(.btn):not(.rail-item):not(.tab)::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 0;
  height: 1px;
  background-color: currentColor;
  transition: width 200ms ease-out;
}

a:not(.btn):not(.rail-item):not(.tab):hover::after {
  width: 100%;
}

/* --- Badge/pill pop-in --- */
@keyframes badge-pop {
  0% {
    transform: scale(0.8);
    opacity: 0;
  }
  50% {
    transform: scale(1.05);
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

.badge.new,
.pill.new {
  animation: badge-pop 300ms ease-out;
}

/* --- Progress bar animation --- */
@keyframes progress-indeterminate {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(200%);
  }
}

.progress-bar--indeterminate::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 50%;
  background: linear-gradient(
    90deg,
    transparent,
    var(--n-accent),
    transparent
  );
  animation: progress-indeterminate 1.5s ease-in-out infinite;
}

/* --- Collapse/expand icon rotation --- */
.collapse-icon,
details summary::before,
.rail-toggle svg {
  transition: transform 200ms ease-out;
}

details[open] summary::before,
.expanded .collapse-icon {
  transform: rotate(90deg);
}

/* --- Reduced motion: respect user preference --- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  
  .skeleton,
  .loading-skeleton {
    animation: none;
    background: var(--n-bg-3);
  }
}
