/* ── IBM Plex self-hosted fonts (OFL licensed; subset Latin, woff2) ──
   Subsetting: Latin U+0000-00FF + extras, kern+liga+tnum, --flavor=woff2.
   IBM Plex figures are tabular by default (engineering/console heritage) so
   font-variant-numeric: tabular-nums works without a separate tnum feature.
   UI symbols (☰ ↶ ↷ ◇ ▸ ▾ ✕ • ↳ ◆) fall back to the system stack intentionally. */
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/plex-sans-400.woff2) format('woff2');
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/plex-sans-600.woff2) format('woff2');
}
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/plex-sans-condensed-600.woff2) format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/plex-mono-400.woff2) format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/plex-mono-500.woff2) format('woff2');
}
/* ── Space Grotesk (HOUSE display face — OFL; subset Latin, woff2) ──
   The brand/display voice: wordmark, screen/section titles, the inspector task
   title, large timecode/numeral readouts. Weights 500–700 per the spec scale.
   Data/instrument texture stays IBM Plex Mono (kept above). */
@font-face {
  font-family: 'Space Grotesk';
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/space-grotesk-500.woff2) format('woff2');
}
@font-face {
  font-family: 'Space Grotesk';
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/space-grotesk-600.woff2) format('woff2');
}
@font-face {
  font-family: 'Space Grotesk';
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  src: url(/fonts/space-grotesk-700.woff2) format('woff2');
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
  /* ── HOUSE direction (design/design-spec.md) ───────────────────────────────
     COOL Penn-Blue-tinted navy-black neutrals + TANGELO signal. Supersedes the
     warm #141312 family. "Most of the UI is monochrome navy-black +
     white; Tangelo appears only on now/active/primary/selection/LEDs." --bg is
     mirrored by COLORS.bg in theme.ts (the WebGL canvas) — change in tandem. */
  /* Brand spine */
  --tangelo:      #F15722;   /* THE signal: now / active / primary CTA / selection / playhead / LED */
  --tangelo-rgb:  241,87,34;
  --tangelo-tint: #ff9376;   /* Tangelo text on dark (e.g. "Due soon") */
  --penn-blue:    #000039;   /* brand elevation tone — mixed into panels/borders, never a flat fill */
  /* Navy neutral scale (Penn-Blue-tinted — cool, not pure gray). HOUSE final
     (README "Design Tokens"): a medium navy #16192b base, NOT the spec's earlier
     near-black #060609 — the README + screenshots are the shipping ground truth. */
  --bg:        #16192b;   /* app background / panel / settings container (--bg-canvas); mirrored by COLORS.bg */
  --bg-timeline: #13182a; /* timeline well + inset inputs (recessed) */
  /*  functional-grid timeline surface (LOCKED: design/timeline-surface.md).
     Single-sourced in theme.ts TL + bridged by pushThemeVars (these are STATIC FALLBACKS).
     The WebGL canvas paints the well base + day-rules in its shader; these vars let the DOM
     well chrome match it. Geometry tokens (--tl-day/--tl-ruler/--tl-lane/--tl-gutter) are
     DYNAMIC (render loop / layout) — not declared here. */
  --tl-well:        radial-gradient(135% 120% at 50% -12%, #101a2e, #070a14);
  --tl-well-border: #050a14;
  --tl-well-inset:  inset 0 0 46px rgba(30,50,90,.16), inset 0 2px 14px rgba(0,0,0,.7);
  --tl-rule:        rgba(150,168,214,.05);   /* vertical day-rule */
  --tl-band:        rgba(160,178,224,.016);  /* lane-band tint (alternating lanes) */
  --surface:   #16192b;   /* cards, list/dock-front containers (--surface-1) — reads vs --bg via border + inset highlight */
  --surface2:  #1c2138;   /* secondary buttons, chips, inputs-on-panel (--surface-2) */
  --keyline:        #0e1119; /* hairline dividers, ruler/timeline grid */
  --keyline-strong: #05070f; /* panel borders (near-black — the keyline IS the structure) */
  --border:         #05070f; /* panel border (alias of --keyline-strong; legacy name) */
  --border-control: #2a2e3e; /* button / chip borders */
  --text-hi:  #f4f5f8;   /* primary text / highlights */
  --text:     #d9dde7;   /* body / values */
  --text-mut: #b9bfd2;   /* section/field labels, metadata (engraved light gray) */
  --text-dim: #888fa3;   /* placeholders, disabled, faint secondary */
  /* Semantic accents — bridged from theme.ts (pushThemeVars overwrites at boot);
     these are STATIC FALLBACKS. Kind hues stay quiet/navy-compatible per HOUSE. */
  --amber:    #E6B13F;   /* decision / workday-chip amber */
  --red:      #E8634C;   /* work-debt red / rake (harmonized coral) */
  --task:     #445170;   /* muted slate-blue (quiet idle identity) */
  --bet:      #E0B341;   /* bet gold */
  --seq:      #6E5A8A;   /* muted plum (pushThemeVars overwrites at boot) */
  --accent:     #F15722;   /* interactive accent = TANGELO (signal; focus rings, primary) */
  --accent-rgb: 241,87,34; /* triplet of --accent for rgba() tints */
  --accent-dim: #7a2c12;   /* deep-Tangelo border (primary-key edge) */
  /* Single-source styling (see theme.ts SEMANTIC + main.ts pushThemeVars):
     the chrome semantic inks + the channel-triplet (--x-rgb) forms used by
     rgba(var(--x-rgb), α) tints. These are STATIC FALLBACKS — pushThemeVars()
     overwrites the bridged hues (task/bet/seq/red/amber/conflict) at boot and
     on per-project palette override; the semantic inks below stay fixed. */
  --danger: #e08064;  --danger-rgb: 224,128,100;  /* destructive / error (HOUSE) */
  --link:   #8aa6d4;  --link-rgb: 138,166,212;    /* body links / ref-chips (cool) */
  --ok:     #6fe0a0;  --ok-rgb: 111,224,160;      /* success / done (HOUSE) */
  --warn:   #e6b13f;  --warn-rgb: 230,177,63;     /* soft warning (amber) */
  --info:   #8fb0ec;  --info-rgb: 143,176,236;    /* due-soon / info blue */
  --focus:  #ff9376;  --focus-rgb: 255,147,118;   /* focus-chip / verb-active (Tangelo-tint) */
  --conflict: #E0884E;                            /* dep-conflict orange (kept distinct from signal) */
  /*  part-3 — fixed chrome inks, now single-sourced in
     theme.ts CHROME_INK and bridged by pushThemeVars (like SEMANTIC). NOT
     per-project overridable (decision). These are STATIC FALLBACKS only;
     edit the values in theme.ts CHROME_INK, not here. */
  --focus-border: #F15722;  /* search/filter focus + active-filter border (Tangelo, HOUSE) */
  --seq-ink: #b0a0c8;       /* lightened seq plum for legible chrome text */
  --bet-ink: #dfc489;       /* lightened bet gold for legible chrome text (ref-well chip) */
  --hover-bg: rgba(255,255,255,.06);              /* generic row/item hover */
  /* Triplet forms of the bridged kind/rake hues (for alpha tints). */
  --task-rgb: 68,81,112;  --bet-rgb: 224,179,65;  --seq-rgb: 110,90,138; /* muted plum */
  --red-rgb: 232,99,76;
  /* — amber/conflict triplets: referenced by .summary-detail.cat-decision/cat-blocked for
     the .readout glow (--readout-ink-rgb). Were referenced but never defined → glow-less; the
     decision readout (now a magnitude pill) is the first real consumer. amber #E6B13F / conflict #E0884E. */
  --amber-rgb: 230,177,63;  --conflict-rgb: 224,136,78;
  /* — modern DOM font stack + tabular numerals. The stack prefers the host
     platform UI faces (San Francisco / Segoe / Roboto) then falls back cleanly.
     --num applies tabular (monospaced-figure) numerals so dates/days/counts align
     in columns; opt surfaces in via font-variant-numeric, NOT a global default. */
  /* HOUSE typography: TWO families. Display = brand voice (Space Grotesk); Mono =
     the data/instrument layer (IBM Plex Mono) and the DOMINANT texture of the UI —
     the app base font is --font-mono ("monospace-forward"), set on html/body below.
     --font is the rare body-prose fallback only. Swap in licensed PK Display later
     by editing --font-display. */
  --font-display: 'PK Display', 'Space Grotesk', 'Unbounded', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --font: 'Satoshi', 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;

  /* ──  type scale — ONE ramp, shared by every surface ────────────
     The single source for font-size. Values track the sizes already in use
     so adopting a token is a rename, not a resize. Density does NOT fork the
     scale (the specification: "ONE type scale, TWO spacing densities") — work vs
     config differ by SPACING + line-height below, never by a second ramp. */
  /* — "tad bigger" type: the ramp is bumped one modest notch so copy reads
     easier without breaking the density rhythm (≈+1px through the body range). */
  --fs-2xs:  10.5px; /* uppercase section heads, tags, badges */
  --fs-xs:   11.5px; /* dim meta, ruler numerals, lane labels (work) */
  --fs-sm:   12.5px; /* compact body + controls (work) */
  --fs-base: 13.5px; /* default body */
  --fs-md:   14.5px; /* config/authoring body + entity names */
  --fs-lg:   16px;   /* modal / section titles */
  --fs-xl:   19px;   /* display headings */
  --fs-2xl:  23px;   /* hero stat numerals */
  /* Two line-heights = the readable half of the density split. */
  --lh-tight: 1.3;   /* work surfaces — instrument-tight rows */
  --lh-loose: 1.55;  /* config/authoring — calm, readable prose */

  /* ──  spacing — base scale + TWO density aliases ────────────────
     --space-tight drives padding/gap on WORK surfaces (timeline, ruler,
     gutter, wells dock); --space-loose drives CONFIG/authoring (inspector,
     modals, #manage, comments). Reach for the alias, not a raw px. */
  --sp-1: 2px;  --sp-2: 4px;  --sp-3: 6px;  --sp-4: 8px;
  --sp-5: 10px; --sp-6: 12px; --sp-7: 16px; --sp-8: 24px;
  --space-tight: var(--sp-3);   /* 6px — compact work-surface rhythm */
  --space-loose: var(--sp-6);   /* 12px — roomy authoring rhythm */
  --gap-tight:  var(--sp-3);    /* 6px */
  --gap-loose:  var(--sp-5);    /* 10px */

  /* ── HOUSE material & depth (design/design-spec.md) ───────────────
     "Elevation = material, not float." Nothing drops a generic floating
     shadow — surfaces are RECESSED (wells/inputs/timeline), RAISED (buttons/
     chips/clips), or LIFTED (inspector/modals only). All control borders go to
     #000 so the highlight/shadow does the shaping. Reach for these by ROLE. */
  /* Recessed — inputs, wells, the timeline surface (sink in). */
  --recess:    inset 0 2px 7px rgba(0,0,0,.75);
  --recess-bg: var(--bg-timeline);                 /* near-black fill */
  /* Raised key — secondary/neutral buttons & chips & idle clips (sit proud). */
  --raised:    inset 0 1px 0 rgba(150,160,210,.13), 0 1px 2px rgba(0,0,0,.5);
  --raised-bg: linear-gradient(180deg,#1a1e32,#0e1120);
  /* Lifted panel — inspector / modals ONLY (Penn-Blue lift + real drop). */
  --lifted:    inset 0 1px 0 rgba(150,160,210,.16), 0 8px 24px rgba(0,0,0,.55);
  /* — the shared RECESSED-MONO READOUT-WINDOW (the `.readout` pill). The
     canonical idiom is the "07d" duration pill / wells `well-bin-readout` (inset dark
     well, near-black border, inset top-highlight bevel, rounded). One source so the
     Summary + Lanes docks (+ future docks) read as one instrument. The window is
     NEUTRAL-dark for every hue; the meaning rides in the numeral ink (--readout-ink).
     Default ink = the phosphor cyan (neutral magnitudes); a debt readout overrides
     --readout-ink to its semantic hue. --cyan/--cyan-rgb come from theme.ts CHROME_INK
     via pushThemeVars (static fallback below). */
  --readout-bg:     #0b0f1a;                                                    /* inset dark well (matches well-bin-readout) */
  --readout-shadow: inset 0 2px 6px rgba(0,0,0,.8), inset 0 1px 0 rgba(150,160,210,.07); /* recess + top-highlight bevel */
  --cyan:           #7fd8e0;   /* static fallback; pushThemeVars overwrites at boot (CHROME_INK) */
  --cyan-rgb:       127,216,224;
  /* Primary key — the one Tangelo CTA per context. */
  --primary-ink:    #2a0f06;
  --primary-bg:     linear-gradient(180deg,#ff8e5f,#dc4d1d);
  --primary-border: #7a2c12;
  --primary-shadow: inset 0 1px 0 rgba(255,255,255,.42), 0 2px 4px rgba(0,0,0,.45), 0 0 14px rgba(241,87,34,.4);
  /* Tangelo signal glow — active clip / live LED / armed control (use sparingly). */
  --glow-tangelo:   0 0 12px rgba(241,87,34,.35), inset 0 0 14px rgba(241,87,34,.12);
  /* Legacy --elev-* tiers, remapped onto the material language (raised → lifted)
     so existing references (floating windows, popovers) inherit HOUSE depth. */
  --elev-1: var(--raised);                                                    /* resting cards/pills */
  --elev-2: inset 0 1px 0 rgba(150,160,210,.12), 0 4px 12px rgba(0,0,0,.5);   /* hovered cards, dock, popovers */
  --elev-3: var(--lifted);                                                    /* floating windows (resting) */
  --elev-4: inset 0 1px 0 rgba(150,160,210,.18), 0 16px 40px rgba(0,0,0,.62); /* focused window / modals (top) */
  /* Tangelo focus ring for the raised/armed/selected/focused states (HOUSE). */
  --ring-accent: 0 0 0 1px var(--accent-dim);
  --ring-accent-strong: 0 0 0 2px rgba(var(--accent-rgb),.5);
  /* Motion — fast for press/hover, med for raise/open. Never applied to
     left/top/width/height/transform on floating windows (would lag drag). */
  --t-fast: .10s ease;
  --t-med:  .18s ease;
  /* Curve radii — minimal, consistent.  locks "just a smidge": --r-sm 4px
     matches the renderer's BAR_R 3.5, and the top of the scale is trimmed so the
     chrome never reads heavier-rounded than the bars (depth+tactile, not glassy). */
  --r-sm: 4px;
  --r-md: 6px;
  --r-lg: 8px;
  --r-pill: 14px;
  /* Group separators — a recessed rule (dark groove + light catch-light) that
     reads as a real boundary on the dark base, not a faint 1px line ("contrast too low, especially around grouping/separators"). */
  /* Machined separators — a recessed rule (dark groove + cool catch-light) that
     reads as a real boundary on the navy base, not a faint 1px line. */
  --sep:        #0b0f1a;
  --sep-groove: 0 1px 0 rgba(150,160,210,.08);
  /* Penn-Blue top-light gradients for elevated surfaces (HOUSE --panel-elevated
     / --header / raised-key). Mixed Penn-Blue lift, never a flat fill. */
  --grad-surface:  linear-gradient(180deg, #1e2244, #13162a);   /* panel-elevated (inspector/modals/window titlebars) */
  --grad-surface2: linear-gradient(180deg, #1a1e32, #0e1120);   /* raised key */
  --grad-header:   linear-gradient(180deg, #1d2148, #10142a);   /* top bar (incl. folded-in transport instruments) */
  --grad-gutter:   linear-gradient(180deg, #1e2246, #141a36);   /* lane-label gutter column */
  --grad-wellbin:  linear-gradient(180deg, #232847, #141930);   /* well capture bins (raised keys) */
}
/* HOUSE: monospace-forward — the base font is IBM Plex Mono (the dominant texture);
   prose/display surfaces opt into --font / --font-display where needed. */
html, body { height: 100%; overflow: hidden; background: var(--bg); color: var(--text); font: var(--fs-base)/1.4 var(--font-mono); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
#app { display: flex; flex-direction: column; height: 100vh; position: relative; }
/* Floating-window layer: covers the whole app below the 50px topbar (#toast-stack is
   position:fixed so the topbar takes exactly its 50px flex-basis). pointer-events:none so
   it never blocks the chrome beneath; windows re-enable events. No overflow:hidden — windows
   may sit anywhere in the view. Windows clamp to this layer (their offsetParent). */
#window-layer { position: absolute; inset: 50px 0 0 0; pointer-events: none; }
#window-layer > * { pointer-events: auto; }
#chrome { display: flex; flex: 1; min-height: 0; }

/* Top chrome bar — project name + the merged record-dot menu button (HOUSE) */
#topbar { flex: 0 0 50px; display: flex; align-items: center; gap: 10px; padding: 0 14px; background: var(--grad-header); border-bottom: 1px solid #000; box-shadow: inset 0 1px 0 rgba(150,160,210,.14), 0 1px 0 rgba(0,0,0,.6); z-index: 50; }
/* HOUSE — the logo chip IS the menu trigger AND the app's identity mark: the
   favicon (the same well+playhead glyph as the browser tab) rendered as the button face,
   superseding the earlier CSS record-dot. 24×24 button; the SVG already carries its own
   navy well + rounded corners, so we keep only the machined frame (border + inset shadow)
   for a tactile edge — recess on :active; keyboard-focusable with the 1px Tangelo ring. */
#logo-chip { width: 32px; height: 32px; flex: 0 0 auto; padding: 0; border: 1px solid #000; border-radius: var(--r-sm); cursor: pointer;
    background: url(/favicon/favicon.svg) center / 30px 30px no-repeat, linear-gradient(180deg, #3a3f50, #20232f);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -1px 2px rgba(0,0,0,.55), 0 1px 2px rgba(0,0,0,.5); }
#logo-chip:hover { filter: brightness(1.25); }
#logo-chip:active { box-shadow: inset 0 1px 3px rgba(0,0,0,.6); filter: brightness(.92); }
#logo-chip:focus-visible { outline: 1px solid var(--tangelo); outline-offset: 2px; }
#brand { font-family: var(--font-display); font-size: 15px; letter-spacing: .16em; font-weight: 600; color: var(--text-hi); }
#project-name { font-family: var(--font-display); font-size: 15px; font-weight: 500; color: var(--text-mut); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#focus-chip { font-size: 12px; color: var(--focus); background: rgba(var(--focus-rgb),.1); border: 1px solid var(--accent-dim); border-radius: 12px; padding: 2px 10px; cursor: pointer; white-space: nowrap; max-width: 280px; overflow: hidden; text-overflow: ellipsis; }
#focus-chip:hover { filter: brightness(1.3); }
/* — machined seam between the identity (logo/brand/project) and the instrument
   cluster folded up from the old transport strip. A 1px engraved rule: a faint cool
   highlight fading at the ends + a black shadow edge, with breathing room each side so
   it reads as a deliberate divider, not just another gap. */
.topbar-divider { flex: 0 0 auto; width: 1px; height: 24px; margin: 0 6px; align-self: center;
    background: linear-gradient(180deg, transparent, rgba(150,160,210,.24) 22%, rgba(150,160,210,.24) 78%, transparent);
    box-shadow: 1px 0 0 rgba(0,0,0,.45); }
#topbar-spacer { flex: 1; }
/* — the account readout joins the topbar instrument. It is a READOUT, not a button
   (account actions live in the logo-chip menu), so it wears a quiet RECESSED engraved
   plate — consistent material with the activity bell + transport keys beside it, but it
   reads as a display, not a pressable key. Mono + tabular for the engraved-data look. */
#user-chip { display: inline-flex; align-items: center; height: 30px; padding: 0 11px; font-family: var(--font-mono); font-size: 12px; letter-spacing: .02em; color: var(--text-dim); background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); box-shadow: var(--recess); white-space: nowrap; }
#user-chip b { color: var(--text-hi); font-weight: 600; }
/* Filter + search chrome. The cluster groups the global fuzzy search
   box, the one-click "My work" toggle, an active-filter chip with a clear ×, the
   member picker, and the rescope/dim mode toggle. .active highlights an engaged
   filter; .filter-on lights the cluster when any filter is live. */
#filter-bar { position: relative; display: flex; align-items: center; gap: 7px; }
/* — recessed engraved-input recipe (matches .insp-name / .fuzzy-input); --r-sm so it
   shares the corner radius of the raised filter keys beside it (the cluster reads as one). */
#search-box { width: 150px; height: 26px; box-sizing: border-box; font-size: 12px; padding: 0 10px; background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text); outline: none; box-shadow: var(--recess); }
#search-box:focus { border-color: var(--focus-border); width: 200px; }
#search-box::placeholder { color: var(--text-dim); }
/* — the filter cluster reads as ONE instrument with the transport strip below it:
   the segmented filter buttons now wear the transport's RAISED MONO-KEY idiom (.tp-btn:
   --raised-bg + --raised + --font-mono), not the old transparent ghost pill. SELECTED
   stays a clear pressed signal — a WHITE cap with black ink (the "My work" treatment) +
   an inset-pressed shadow — so an engaged filter reads as a physically depressed key.
   These replace the earlier ghost-pill treatment so the filter row matches the
   transport controls. */
.seg { display: inline-flex; align-items: center; gap: 0; }
.seg .seg-btn { border-radius: 0; }
.seg .seg-btn:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.seg .seg-btn:last-child { border-radius: 0 var(--r-sm) var(--r-sm) 0; margin-left: -1px; }
.filter-btn { font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; padding: 0 11px; height: 26px; line-height: 1; display: inline-flex; align-items: center; background: var(--raised-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text); cursor: pointer; white-space: nowrap; box-shadow: var(--raised); }
.filter-btn:hover { filter: brightness(1.2); }
.filter-btn:active { transform: translateY(1px); }
/*  item 14 — the top-right cluster is SECONDARY (not a main interactable), so the engaged
   state is a quiet PRESSED key (recessed surface + bright text + the inset-settle below), NOT a
   glaring white cap. Reads as depressed/engaged without competing with the timeline. */
.filter-btn.active { background: var(--surface2); border-color: var(--border-control); color: var(--text-hi); font-weight: 600; }
.filter-btn.active:hover { filter: brightness(1.15); }
/* `:not([hidden])` so the HTML `hidden` attribute (low-specificity UA display:none) still
   wins over this ID rule's `display:inline-flex` — these controls are shown only when a
   filter is live. Scoped here, not via a global `[hidden]!important` (that would reach the
   other lanes' hidden elements). */
#filter-chip:not([hidden]) { font-family: var(--font-mono); font-size: 11px; color: var(--tangelo-tint); background: rgba(var(--accent-rgb),.12); border: 1px solid var(--accent-dim); border-radius: var(--r-sm); padding: 0 10px; height: 26px; display: inline-flex; align-items: center; cursor: pointer; white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis; box-shadow: var(--glow-tangelo); }
#filter-chip:hover { filter: brightness(1.3); }
#filter-mode:not([hidden]) { font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; padding: 0 11px; height: 26px; line-height: 1; display: inline-flex; align-items: center; background: var(--raised-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text-dim); cursor: pointer; white-space: nowrap; box-shadow: var(--raised); }
#filter-mode:hover { filter: brightness(1.2); }
#filter-mode:active { transform: translateY(1px); }
#filter-mode.on { color: var(--text-hi); background: var(--surface2); border-color: var(--border-control); font-weight: 600; }

/* ── HOUSE — Transport instruments (folded into the top bar) ─────────
   The signature "instrument" surface: the few controls you physically PLAY,
   rendered with machined tactility (knurled knob, physical toggle). Once a 46px
   strip of its own; the layout now reclaims that row by folding the cluster inline into the
   top bar after the project name. Now a transparent inline flex group (the keys
   carry their own surfaces); Tangelo only on the live pointer/armed cap. */
#transport { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; }
.tp-group { display: flex; align-items: center; gap: 7px; }
.tp-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em; font-weight: 500; color: var(--text-mut); text-shadow: 0 1px 0 rgba(0,0,0,.7); user-select: none; }
/* Knurled zoom knob (30×30) — a conic-gradient knurl ring + an inset radial cap + a
   Tangelo pointer tick. Drag-to-turn / scroll-to-fine (wired in main.ts). */
.tp-knob { position: relative; width: 30px; height: 30px; border-radius: 50%; border: 1px solid #000; padding: 0; cursor: ns-resize;
  touch-action: none;
  background:
    radial-gradient(circle at 50% 32%, #2c303b 0 40%, #13151c 44%, transparent 46%),
    repeating-conic-gradient(#23262f 0 8deg, #171a22 8deg 16deg);
  box-shadow: inset 0 1px 0 rgba(150,160,210,.18), inset 0 0 6px rgba(0,0,0,.7), 0 1px 2px rgba(0,0,0,.5); }
.tp-knob:hover { box-shadow: inset 0 1px 0 rgba(150,160,210,.25), inset 0 0 6px rgba(0,0,0,.7), 0 1px 2px rgba(0,0,0,.5), var(--ring-accent); }
.tp-knob:active { transform: translateY(1px); }
/* The pointer tick — a Tangelo notch from cap edge toward the rim, rotated by JS. */
.tp-knob-tick { position: absolute; left: 50%; top: 3px; width: 2px; height: 8px; margin-left: -1px; border-radius: 1px; background: var(--tangelo); box-shadow: 0 0 7px rgba(var(--accent-rgb),.8); transform-origin: 50% 12px; }
/* Physical toggle (40×22) — a pill track + a sliding cap. ON = Tangelo track + white cap
   + glow; OFF = recessed navy track + gray cap. Snaps with a short ease. */
.tp-toggle { position: relative; width: 40px; height: 22px; border-radius: var(--r-pill); border: 1px solid #000; padding: 0; cursor: pointer; background: linear-gradient(180deg,#0c0f1a,#181b30); box-shadow: var(--recess); transition: background var(--t-med), box-shadow var(--t-med); }
.tp-toggle-cap { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: linear-gradient(180deg,#9398a8,#5a5f72); box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 1px 2px rgba(0,0,0,.5); transition: left .12s cubic-bezier(.2,.8,.2,1), background var(--t-med); }
.tp-toggle[aria-checked="true"] { background: var(--tangelo); box-shadow: var(--recess), var(--glow-tangelo); }
.tp-toggle[aria-checked="true"] .tp-toggle-cap { left: 20px; background: #fff; box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 1px 3px rgba(0,0,0,.5); }
/* Jog + undo/redo: raised neutral keys on the strip. */
.tp-btn { height: 24px; min-width: 24px; padding: 0 9px; background: var(--raised-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text); cursor: pointer; font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; box-shadow: var(--raised); line-height: 1; }
.tp-btn:hover:not(:disabled) { filter: brightness(1.4); }
.tp-btn:active:not(:disabled) { transform: translateY(1px); }
.tp-btn:disabled { opacity: .35; cursor: default; }
.tp-icon, .tp-jog-arrow { padding: 0 7px; font-size: 13px; }
.tp-jog { gap: 4px; }
.tp-view { position: relative; }
.tp-view .view-pop { top: calc(100% + 7px); left: 0; right: auto; min-width: 220px; padding: 8px; }
.view-pop-head { padding: 0 4px 6px; border-bottom: 1px solid var(--border); color: var(--text-hi); font-family: var(--font-display); font-size: 12px; font-weight: 600; }
.view-pop-row { display: flex; align-items: center; gap: 8px; min-height: 26px; padding: 2px 4px; }
.view-pop-row input[type="checkbox"] { flex: 0 0 auto; margin: 0; accent-color: var(--tangelo); }
.view-pop-row input[type="checkbox"]:disabled { opacity: .45; }
.view-pop-row input[type="checkbox"]:disabled + label { color: var(--text-dim); cursor: default; }
.view-pop-row label { color: var(--text); font-size: 12px; cursor: pointer; }
.view-pop-mode { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 5px; padding: 7px 4px 0; border-top: 1px solid var(--border); }
.view-pop-mode-cap { color: var(--text-dim); font-size: 11px; }
.view-pop-reset { width: 100%; justify-content: center; margin-top: 7px; }
.tp-btn.has-view-filters { position: relative; }
.tp-btn.has-view-filters::after { content: ""; position: absolute; top: 3px; right: 3px; width: 7px; height: 7px; border-radius: 50%; background: var(--tangelo); box-shadow: 0 0 0 1px rgba(0,0,0,.45), 0 0 4px rgba(255,255,255,.18); pointer-events: none; }

/* ──  forecast legend tooltip ───────────────────────────────────────────────
   A HOUSE panel anchored under the FORECAST toggle, shown on hover (dwell) + focus.
   It decodes the predictive overlay; each row pairs a tiny inline mini-repro of the
   on-canvas mark with a terse caption. Recessed-raised panel idiom (matches the
   inspector/menu), Space Grotesk captions, no decorative color beyond the swatches
   (pinned to the exact canvas inks). The .tp-group holding the toggle is the anchor. */
.tp-forecast { position: relative; }
.fc-legend {
  position: absolute; top: calc(100% + 7px); left: -4px; z-index: 1200;
  min-width: 232px; padding: 9px 11px 10px;
  background: var(--surface2); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--lifted);
  display: flex; flex-direction: column; gap: 7px;
}
.fc-legend[hidden] { display: none; }
.fc-legend-head { font-family: var(--font-display); font-size: 12px; font-weight: 600; letter-spacing: .01em; color: var(--text-hi); margin-bottom: 1px; }
.fc-legend-row { display: flex; align-items: center; gap: 9px; }
.fc-legend-cap { font-family: var(--font-display); font-size: 11.5px; letter-spacing: .005em; color: var(--text); line-height: 1.25; }
.fc-legend-cap b { font-weight: 600; color: var(--text-hi); }
/* Swatch column — fixed box so the three rows align; inline mini-repros of the marks. */
.fc-sw { flex: 0 0 34px; width: 34px; height: 18px; position: relative; display: inline-block; }
/* Overrun: a short neutral planned-bar stub + a slim blue-grey overrun segment butted
   to its right edge + an UP caret (apex above the segment end), Tangelo — mirroring
   drawProjection's segment (#9FB4D8) + caretUp (#F15722, apex up). */
.fc-sw-overrun .fc-sw-bar { position: absolute; left: 0; top: 4px; width: 15px; height: 10px; border-radius: 2px; background: linear-gradient(180deg,#2b3a5e,#1a2238); border: 1px solid #0a0e18; }
.fc-sw-overrun .fc-sw-seg { position: absolute; left: 16px; top: 4px; width: 13px; height: 10px; border-radius: 0 2px 2px 0; background: #9FB4D8; opacity: .8; }
/* UP caret (apex up, sitting just above the segment end) — mirrors scene.ts caretUp. */
.fc-sw-overrun .fc-sw-caret { position: absolute; left: 25px; top: 0; width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-bottom: 5px solid #F15722; }
/* Rings: a transparent rounded-rect with a colored border — the SDF outlines. */
.fc-sw-ring { box-sizing: border-box; height: 14px; margin: 2px 0; border-radius: var(--r-sm); background: transparent; }
.fc-sw-crit { border: 2px solid #A78BFA; }
.fc-sw-alloc { border: 2px solid #F472B6; }

/* Hamburger dropdown menu */
.menu-pop { position: fixed; z-index: 1200; min-width: 200px; background: var(--surface2); border: 1px solid var(--border); border-radius: 8px; padding: 5px; box-shadow: 0 12px 36px rgba(0,0,0,.5); display: flex; flex-direction: column; }
.menu-item { text-align: left; background: none; border: none; color: var(--text); padding: 8px 11px; border-radius: 5px; cursor: pointer; font-size: 13px; display: flex; align-items: center; gap: 8px; }
.menu-item:hover:not(:disabled) { background: var(--hover-bg); }
.menu-item:disabled { color: var(--text-dim); cursor: default; }
.menu-item.menu-danger { color: var(--danger); }
.menu-empty { padding: 8px 11px; color: var(--text-dim); font-size: 12px; }
.project-link-item { text-decoration: none; }
.menu-sep { height: 1px; background: var(--border); margin: 4px 2px; }
.menu-head { padding: 6px 11px 3px; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-dim); }
/* Project-picker search widget (used when project count > 3) */
.menu-proj-picker { display: flex; flex-direction: column; padding: 2px 4px 4px; }
.menu-proj-search { background: var(--recess-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 5px 8px; font-size: 12px; box-shadow: var(--recess); outline: none; margin-bottom: 4px; }
.menu-proj-search:focus { border-color: var(--accent-dim); }
.menu-proj-search::placeholder { color: var(--text-dim); }
.menu-proj-list { display: flex; flex-direction: column; max-height: 180px; overflow-y: auto; }
.menu-proj-list .menu-item { width: 100%; }
.menu-proj-list .menu-item.active { background: rgba(255,255,255,.12); }
.menu-proj-match { color: var(--text-hi); font-weight: 600; }
.menu-item.menu-proj-current { color: var(--text-dim); cursor: default; pointer-events: none; }
.menu-proj-icon { width: 1.1em; height: 1.1em; object-fit: contain; vertical-align: -0.2em; margin-right: 0.35em; border-radius: 2px; flex: none; }

/* Generic modal (admin, project mgmt) */
.modal-overlay { position: fixed; inset: 0; z-index: 1400; background: rgba(8,8,8,.6); display: flex; align-items: flex-start; justify-content: center; padding-top: 8vh; }
.modal-card { width: 460px; max-width: 92vw; max-height: 80vh; overflow-y: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: 0 24px 70px rgba(0,0,0,.55); }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--surface); }
.modal-title { font-family: var(--font-display); font-size: 15px; font-weight: 600; }
.modal-close { background: none; border: none; color: var(--text-dim); font-size: 20px; line-height: 1; cursor: pointer; }
.modal-close:hover { color: var(--text); }
.modal-body { padding: 16px 18px; line-height: var(--lh-loose); }
.modal-sub { font-size: 12px; color: var(--text-dim); margin-bottom: 14px; }
.modal-row { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--border); }
.modal-row:last-child { border-bottom: none; }
.modal-row-main { flex: 1; min-width: 0; }
.modal-row-name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modal-row-sub { font-size: 11px; color: var(--text-dim); }
.modal-tag { font-size: 9px; padding: 1px 6px; border-radius: 8px; background: var(--surface2); border: 1px solid var(--border-control); color: var(--text); letter-spacing: .04em; }
.modal-input { background: var(--surface2); border: 1px solid var(--border); color: var(--text); padding: 7px 9px; border-radius: 6px; font-size: 13px; }
.modal-input:focus { outline: none; border-color: var(--accent); }
.modal-form { display: flex; gap: 8px; margin-top: 14px; align-items: center; flex-wrap: wrap; }
/* item 13 — dialog buttons on the tactile raised-key idiom (was flat surface2). */
.modal-btn { padding: 7px 12px; border: 1px solid #000; border-radius: var(--r-sm); background: var(--raised-bg); color: var(--text); cursor: pointer; font-size: 12px; box-shadow: var(--raised); }
.modal-btn:hover:not(:disabled) { filter: brightness(1.35); }
.modal-btn:disabled { opacity: .4; cursor: default; }
.modal-btn.primary { background: var(--primary-bg); border-color: var(--primary-border); color: var(--primary-ink); font-weight: 600; box-shadow: var(--primary-shadow); }
.modal-btn.danger { border-color: rgba(var(--danger-rgb),.45); color: var(--danger); }
.modal-status { min-height: 16px; margin-top: 10px; font-size: 12px; color: var(--danger); }
.modal-status.ok { color: var(--ok); }
.modal-textarea { display: block; width: 100%; box-sizing: border-box; margin-top: 6px; background: var(--recess-bg); border: 1px solid #000; color: var(--text); padding: 8px 9px; border-radius: var(--r-sm); font: 12px/1.5 var(--font-mono); resize: vertical; box-shadow: var(--recess); }
.modal-textarea:focus { outline: none; border-color: var(--accent); }
.well-item-name { display: block; width: 100%; box-sizing: border-box; margin-bottom: 10px; }
/* passkey panel scoped spacing — adds bottom gap after "Add a passkey" row so
   the "Add another device" help text doesn't sit flush against the button above it. */
.passkey-add-row { margin-bottom: 14px; }
/* Management page: a wider card hosting stacked titled sections + a stat grid. */
.modal-card.wide { width: 620px; }
.manage-section-head { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-dim); margin: 18px 0 6px; padding-top: 14px; border-top: 1px solid var(--border); }
.manage-section-head:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.manage-link { color: var(--text); text-decoration: none; }
.manage-link:hover { color: var(--task); text-decoration: underline; }
.manage-stats { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.manage-stat { flex: 1; min-width: 84px; background: var(--surface2); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; text-align: center; }
.manage-stat-num { font-size: 20px; font-weight: 600; }
.manage-stat-lbl { font-size: 10px; color: var(--text-dim); letter-spacing: .04em; text-transform: uppercase; margin-top: 2px; }
.manage-setting-row { margin-top: 12px; display: flex; flex-direction: column; gap: 4px; }
.manage-setting-lbl { font-size: 12px; font-weight: 600; }

/* ── Management page — full-page routed surface (#manage hash) ──────────
   A fixed overlay over the whole app: a left sidebar of tabs + a scrolling
   content area. NOT a floating window. Driven by the URL hash so back/forward
   and deep-links work; writeViewState preserves the fragment. */
.manage-page { position: fixed; inset: 0; z-index: 200; display: flex; background: var(--bg); }
.manage-sidebar { flex: 0 0 200px; display: flex; flex-direction: column; gap: 4px; padding: 16px 12px; background: var(--grad-surface); border-right: 1px solid var(--sep); }
.manage-brand { font-size: 11px; letter-spacing: .22em; font-weight: 700; color: var(--text-dim); padding: 4px 10px 12px; }
.manage-nav { display: flex; flex-direction: column; gap: 2px; }
.manage-tab { text-align: left; background: transparent; border: 1px solid transparent; color: var(--text); border-radius: var(--r-md); padding: 8px 12px; font-size: 13px; cursor: pointer; }
.manage-tab:hover { background: var(--surface2); }
.manage-tab.active { background: var(--surface2); border-color: var(--sep); font-weight: 600; box-shadow: var(--elev-1); }
/* — scope group headers in the sidebar nav (ORG / PROJECT / ACCOUNT). Rendered only
   when ≥1 child is visible (gating-safe), so a non-admin never sees an empty group. */
.manage-nav-group { font-size: 9px; letter-spacing: .18em; font-weight: 700; text-transform: uppercase; color: var(--text-dim); opacity: .65; padding: 12px 12px 3px; }
.manage-nav-spacer { flex: 1; }
/* — per-tab scope bar (relocated active-managed-project selector). The first content
   element of each PROJECT-scoped tab; reads as SCOPE, distinct from the All-projects [Open]. */
.manage-scope-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 22px; padding: 10px 14px; background: var(--surface2); border: 1px solid var(--sep); border-radius: var(--r-md); box-shadow: var(--elev-1); }
.manage-scope-lbl { font-size: 10px; letter-spacing: .14em; font-weight: 700; text-transform: uppercase; color: var(--text-dim); }
.manage-scope-sel { flex: 1; min-width: 180px; max-width: 360px; }
.manage-scope-live { flex: 0 0 100%; font-size: 11px; color: var(--text-dim); min-height: 0; }
.manage-scope-live:empty { display: none; }
/*  item 9 — "← Back to Tracks": a branded tactile chip (raised key) leading with the
   favicon logo plate (the same logo-chip recipe as .review-back-brand / #logo-chip). */
.manage-back { display: inline-flex; align-items: center; gap: 8px; background: none; border: none; padding: 4px; cursor: pointer; }
.manage-back-logo { width: 22px; height: 22px; flex: none; border-radius: 3px; background: url(/favicon/favicon.svg) center / 20px 20px no-repeat, linear-gradient(180deg, #3a3f50, #20232f); box-shadow: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -1px 2px rgba(0,0,0,.55); }
.manage-back-label { font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--seq-ink); background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); padding: 3px 9px; box-shadow: var(--recess); }
.manage-back:hover { filter: brightness(1.25); }
.manage-back:hover .manage-back-label { color: var(--text-hi); }
.manage-back:active { transform: translateY(1px); }
.manage-content { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.manage-body { flex: 1; overflow-y: auto; padding: 28px 36px; max-width: 880px; line-height: var(--lh-loose); }
.manage-status { flex: 0 0 auto; padding: 8px 36px; font-size: 12px; color: var(--text-dim); border-top: 1px solid var(--sep); min-height: 16px; }
.manage-status.ok { color: var(--ok); }
.manage-section-sub { font-size: 12px; color: var(--text-dim); margin: 0 0 8px; line-height: 1.5; max-width: 640px; }
.manage-section-body { display: flex; flex-direction: column; }
.manage-list { display: flex; flex-direction: column; }
.manage-row { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 0; border-bottom: 1px solid var(--sep); }
.manage-row:last-child { border-bottom: none; }
.manage-row-main { flex: 1; min-width: 0; }
.manage-row-name { font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.manage-row-sub { font-size: 11px; color: var(--text-dim); margin-top: 1px; }
.manage-empty { font-size: 12px; color: var(--text-dim); padding: 8px 0; }
.manage-form { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.manage-icon-preview { display: flex; align-items: center; justify-content: center; width: 48px; height: 48px; border: 1px solid #000; border-radius: var(--r-sm); background: var(--recess-bg); box-shadow: var(--recess); flex: none; }
.manage-icon-img { width: 100%; height: 100%; object-fit: contain; border-radius: var(--r-sm); image-rendering: pixelated; }
.manage-icon-remove { padding: 3px 8px; font-size: 13px; line-height: 1; }
/* HOUSE — settings/lists button taxonomy: neutral = raised key (border-control);
   destructive = danger ghost; primary = the one solid Tangelo per form. Inline form
   inputs are recessed (sink in) with the primary key trailing. */
.manage-input { background: var(--recess-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 7px 9px; font-size: 12px; outline: none; box-shadow: var(--recess); }
.manage-input:focus { border-color: var(--accent-dim); }
.manage-btn { background: var(--raised-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 7px 12px; font-size: 12px; cursor: pointer; white-space: nowrap; box-shadow: var(--raised); text-align: center; box-sizing: border-box; }
.manage-btn:hover { filter: brightness(1.3); }
.manage-btn:disabled { opacity: .45; cursor: default; filter: none; }
.manage-btn.primary { background: var(--primary-bg); border-color: var(--primary-border); color: var(--primary-ink); font-weight: 600; box-shadow: var(--primary-shadow); }
.manage-btn.danger { background: transparent; color: var(--danger); border-color: rgba(var(--danger-rgb),.4); box-shadow: none; }
.manage-btn.danger:hover { background: rgba(var(--danger-rgb),.14); filter: none; }
.manage-btn.sm { padding: 4px 9px; font-size: 11px; }
/* HOUSE — trailing action cluster: a fixed, right-aligned column group so the
   per-row controls line up column-to-column across rows (was a ragged free flex). */
.manage-row-actions { display: flex; align-items: center; gap: 8px; flex: none; justify-content: flex-end; }
/* HOUSE — collapsed project-sharing: one fixed-width "Share ▾" trigger expands a
   team checklist under the row (replaces variable-count "Unshare <team>" buttons). */
.manage-share-list { display: flex; flex-direction: column; gap: 2px; margin: -2px 0 10px 12px; padding-left: 10px; border-left: 2px solid var(--border); }
.manage-share-opt { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text); padding: 4px 0; cursor: pointer; }
/*  item 8 — HOUSE custom checkbox: a recessed dark box that fills with the Tangelo
   signal + a check glyph when on (replaces the OS accent-color box, which never matched the
   tactile chrome). Shared by the #manage share list, the project-settings toggles
   (.house-check,  item 10), and the markdown body checkbox so every checkbox is one part. */
.manage-share-opt input[type="checkbox"],
input.house-check[type="checkbox"],
.body-line .body-checkbox {
  appearance: none; -webkit-appearance: none; margin: 0; flex: none;
  width: 15px; height: 15px; border: 1px solid #000; border-radius: 3px;
  background: var(--recess-bg); box-shadow: var(--recess); cursor: pointer; position: relative;
}
.manage-share-opt input[type="checkbox"]:hover,
input.house-check[type="checkbox"]:hover,
.body-line .body-checkbox:hover { border-color: var(--border-control); }
.manage-share-opt input[type="checkbox"]:checked,
input.house-check[type="checkbox"]:checked,
.body-line .body-checkbox:checked { background: var(--primary-bg); border-color: var(--primary-border); box-shadow: var(--primary-shadow); }
.manage-share-opt input[type="checkbox"]:checked::after,
input.house-check[type="checkbox"]:checked::after,
.body-line .body-checkbox:checked::after {
  content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
  border: solid var(--primary-ink); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.manage-enroll { margin-top: 12px; }
.manage-enroll-head { font-size: 11px; color: var(--text-dim); margin-bottom: 4px; }

/* ── Review ledger — full-page routed surface (#review hash) ────────────
   A fixed overlay over the whole app (z ≥ 200, like .manage-page): a header, a
   filter bar, a sortable column header, and a virtualized scrolling table body.
   Rows = tracks ∪ well items; cells edit in place via existing store methods. */
.review-page { position: fixed; inset: 0; z-index: 210; display: flex; flex-direction: column; background: var(--bg); }
/* a row-detail / comments window opened from the #review overlay must float ABOVE it.
   The shared floating window-manager clamps inline z-index to 49 (below the topbar) on every
   raise, so we override with !important here — above the overlay (210), below modal/confirm
   dialogs (1400) so a delete-confirm still covers the window. */
.wellitem-window.review-floating, #comments-window.review-floating { z-index: 1350 !important; }
.review-detail-verbs { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; }
.review-head { flex: 0 0 auto; display: flex; align-items: center; gap: 12px; padding: 14px 24px; background: var(--grad-surface); border-bottom: 1px solid var(--sep); box-shadow: var(--sep-groove); }
.review-title { font-family: var(--font-display); font-size: 15px; font-weight: 700; letter-spacing: .04em; }
.review-head-spacer { flex: 1; }
/*  item 11 — Back to timeline: the brand mark (left, the favicon plate reused from
   #logo-chip) + a mono uppercase "Back to timeline" tech-chip label (right), as a tactile
   raised key. */
.review-back { display: inline-flex; align-items: center; gap: 8px; padding: 4px 11px 4px 5px; background: var(--raised-bg); border: 1px solid #000; border-radius: var(--r-sm); cursor: pointer; box-shadow: var(--raised); }
.review-back:hover { filter: brightness(1.25); }
.review-back:active { transform: translateY(1px); }
.review-back-brand { width: 22px; height: 22px; flex: none; border-radius: 3px; background: url(/favicon/favicon.svg) center / 20px 20px no-repeat, linear-gradient(180deg, #3a3f50, #20232f); box-shadow: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -1px 2px rgba(0,0,0,.55); }
.review-back-label { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-mut); }
.review-back:hover .review-back-label { color: var(--text-hi); }
/* Filter bar — search + selects + owner/tag pickers + done-range, wrapping. */
.review-filters { flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 24px; border-bottom: 1px solid var(--sep); background: var(--surface); }
.review-input { background: var(--surface2); border: 1px solid var(--border); color: var(--text); border-radius: var(--r-sm); padding: 5px 8px; font-size: 12px; outline: none; }
.review-input:focus { border-color: var(--accent); }
.review-date { color-scheme: dark; }
.review-flabel { font-size: 11px; color: var(--text-dim); }
.review-fbtn { background: var(--raised-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 5px 10px; font-size: 12px; cursor: pointer; box-shadow: var(--raised); }
.review-fbtn:hover { filter: brightness(1.3); }
.review-fbtn:active { transform: translateY(1px); }
.review-owner-pick { min-width: 150px; }
.review-owner-pick .fuzzy-input { font-size: 12px; }
.review-tagfilter { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.review-tagfilter .tag-chip-field { display: inline-flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.review-count { font-size: 11px; color: var(--text-dim); margin-left: auto; white-space: nowrap; }
/* Table — a CSS grid shared by header + data rows so columns line up exactly. */
.review-row { display: grid; grid-template-columns: var(--review-kind-col, 84px) minmax(180px, 2fr) 130px 130px 110px minmax(150px, 1.4fr) minmax(140px, 1fr) minmax(140px, 1.2fr); align-items: center; gap: 0; }
/* Cross-project: a leading Project column; the Lane column is dropped (lane paths
   aren't loaded for other projects). Header + data rows share this variant so they align. */
.review-row.review-scoped { grid-template-columns: minmax(120px, 1fr) var(--review-kind-col, 84px) minmax(180px, 2fr) 130px 130px 110px minmax(150px, 1.4fr) minmax(140px, 1.2fr); }
.review-project-link { cursor: pointer; color: var(--accent); }
.review-project-link:hover { text-decoration: underline; }
.review-scope-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: var(--r-sm); overflow: hidden; }
.review-scope-toggle button { background: var(--surface2); border: none; color: var(--text-dim); padding: 5px 10px; font-size: 12px; cursor: pointer; }
.review-scope-toggle button.on { background: var(--accent); color: #fff; }
.review-loadmore { display: flex; justify-content: center; padding: 14px; }
.review-remote-note { font-size: 11px; color: var(--text-dim); padding: 0 6px; }
.review-header { flex: 0 0 auto; padding: 0 24px; background: var(--surface); border-bottom: 1px solid var(--sep); box-shadow: var(--sep-groove); height: 32px; }
.review-col-head { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); cursor: pointer; user-select: none; padding: 0 6px; height: 100%; display: flex; align-items: center; }
.review-col-head:hover { color: var(--text); }
.review-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 24px; }
.review-spacer { position: relative; }
.review-viewport { position: absolute; left: 0; right: 0; top: 0; }
.review-data-row { border-bottom: 1px solid var(--sep); }
.review-data-row:hover { background: var(--surface2); }
.review-well-row { background: rgba(var(--bet-rgb),.035); }
.review-well-row:hover { background: var(--surface2); }
.review-cell { padding: 0 6px; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.review-dim { color: var(--text-dim); }
.review-kind { font-size: 9px; letter-spacing: .04em; text-transform: uppercase; padding: 2px 6px; border-radius: 8px; background: var(--surface2); border: 1px solid var(--border); color: var(--text-dim); }
.review-kind-task { color: var(--link); border-color: rgba(var(--task-rgb),.4); }
.review-kind-bet { color: var(--bet); border-color: rgba(var(--bet-rgb),.4); }
.review-kind-seq { color: var(--seq-ink); border-color: rgba(var(--seq-rgb),.4); }
.review-kind-bugs { color: var(--danger); border-color: rgba(var(--red-rgb),.4); }
.review-kind-cut { color: #9aa7b8; }
.review-kind-killed { color: var(--bet); }
.review-kind-someday { color: #9a7fc0; }
.review-name-text { cursor: pointer; }
.review-name-text:hover { text-decoration: underline; }
.review-edit-input { width: 100%; background: var(--surface2); border: 1px solid var(--accent); color: var(--text); border-radius: var(--r-sm); padding: 3px 6px; font-size: 12px; outline: none; }
.review-lane-sel { border-color: var(--border); cursor: pointer; }
.review-edit-pick { width: 100%; }
.review-edit-pick .fuzzy-input { width: 100%; }
.review-status-btn { background: var(--raised-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-pill); padding: 2px 10px; font-size: 11px; cursor: pointer; box-shadow: var(--raised); }
.review-status-btn:hover { filter: brightness(1.3); }
.review-status-btn:active { transform: translateY(1px); }
.review-status-done { color: var(--ok); }
.review-status-wip { color: var(--accent); border-color: var(--accent-dim); }
/* per-row action affordances (⋯ detail, cut/kill, delete-forever) live inline in the
   Name + Status cells so the fixed grid layout stays intact. The Name cell becomes a flex
   row: the name text truncates, the actions sit on the right and reveal on row hover. */
.review-col-name { display: flex; align-items: center; gap: 6px; }
.review-col-name .review-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; min-width: 0; }
.review-row-actions { margin-left: auto; display: inline-flex; gap: 3px; flex: none; opacity: 0; transition: opacity .1s; }
.review-data-row:hover .review-row-actions { opacity: 1; }
.review-act { background: var(--raised-bg); border: 1px solid #000; color: var(--text-dim, var(--text)); border-radius: var(--r-sm); padding: 1px 7px; font-size: 11px; line-height: 1.4; cursor: pointer; box-shadow: var(--raised); }
.review-act:hover { filter: brightness(1.3); }
.review-act-del:hover { color: var(--bet); border-color: var(--bet); }
.review-act-cut { margin-left: 6px; }
.review-act-cut:hover { color: var(--bet); }
.review-tags-view { display: flex; flex-wrap: nowrap; gap: 4px; align-items: center; cursor: pointer; overflow: hidden; }
.review-tag-chip { font-size: 10px; padding: 1px 7px; }
.review-edit-tags { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.deleted-row { grid-template-columns: 110px minmax(220px, 2fr) 160px 170px 120px; }
.deleted-body { padding-top: 0; }
.deleted-body .review-data-row { min-height: 34px; cursor: pointer; }
.deleted-restore { padding: 3px 9px; }
.deleted-detail { position: fixed; right: 28px; top: 82px; z-index: 1350; width: min(680px, calc(100vw - 56px)); max-height: calc(100vh - 112px); display: flex; flex-direction: column; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--r-sm); box-shadow: var(--elev-2); overflow: hidden; }
.deleted-json { margin: 0; padding: 12px; overflow: auto; color: var(--text); background: var(--recess-bg); font-family: var(--font-mono); font-size: 11px; line-height: 1.45; white-space: pre-wrap; }

/* ── Tag chip widget (tagChipPicker) — shared by the inspector tag editor, the
   timeline tag filter, the well filters  and the review ledger. ────── */
.tag-chip-field { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
/*  item 9 — INSET CHIP: a recessed dark window with a faint per-tag colored wash + the
   per-tag dot, very small radius. The dark base + inset shadow are here; the LOW-alpha hue
   tint is layered inline by paintTagChip() (fuzzy.ts) over #0b0f1a, so color rides on the
   tag DATA, never a token. Neutral light ink keeps the label legible on any hue. */
.tag-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; padding: 2px 7px; background: var(--readout-bg); border: 1px solid #000; border-radius: 3px; color: var(--text); white-space: nowrap; box-shadow: inset 0 1px 3px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.04); }
/* deterministic per-name tag color, carried by a small dot (background set inline from
   theme.tagColor — per-tag data, never a token). A hair of white halo = the "shine". */
.tag-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; box-shadow: 0 0 0 1px rgba(0,0,0,.45), 0 0 4px rgba(255,255,255,.18); }
.tag-chip-x { background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 13px; line-height: 1; padding: 0 1px; border-radius: 50%; }
.tag-chip-x:hover { color: var(--text-hi); background: rgba(255,255,255,.12); }
.tag-chip-add { min-width: 96px; }
.tag-chip-add .fuzzy-input { font-size: 11px; padding: 2px 6px; }
/* #15.2 — in the inspector, the tag-add field standardizes to the shared small-input recipe
   (the .insp-attach-name baseline: font 12px, padding 6px 8px) so every inspector text input
   sits at one size. The recessed-field chrome (bg/border/shadow/r-sm) is already on .fuzzy-input;
   only the off-recipe size needs aligning. (Scoped to .insp-tags — review/well surfaces keep
   their own compact tag size.) */
.insp-tags .tag-chip-add .fuzzy-input { font-size: 12px; padding: 6px 8px; }

/* Gutter — lane headers, aligned to canvas rows. position:relative anchors the
   horizontal-resize grip on the dock's right edge (outside the rows). */
#gutter { position: relative; width: 180px; min-width: 150px; max-width: 360px; background: var(--grad-gutter); border-right: 1px solid #000; box-shadow: inset 0 1px 0 rgba(150,160,210,.12); display: flex; flex-direction: column; flex-shrink: 0; line-height: var(--lh-tight); }
/* — the dock TITLE engraved to match the Summary dock + WELLS · CAPTURE BINS family
   (uppercase Space-Grotesk, letterspaced). "LANES" comes from index.html; the treatment
   is here so no HTML/JS text change is needed (the docks read as one instrument). */
#gutter-ruler { height: 32px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 8px 0 12px; font-family: var(--font-display); font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); text-shadow: 0 1px 0 rgba(0,0,0,.6); }
/* Minimal transient lane-name filter riding in the ruler between LANES and the density
   stepper. Ghost until focus (borderless, dim placeholder) so the header stays quiet. */
#lane-filter { flex: 1; min-width: 0; margin: 0 6px; padding: 1px 4px; background: transparent; border: none; border-bottom: 1px solid transparent; border-radius: 0; color: var(--text); font-family: var(--font-mono); font-size: 10px; font-weight: 400; letter-spacing: 0; text-transform: none; }
#lane-filter::placeholder { color: var(--text-dim); opacity: .5; }
#lane-filter:focus { outline: none; border-bottom-color: var(--border-control); }
/* (Today/undo/redo relocated to the HOUSE transport strip — styled as .tp-btn.) */
#gutter-lanes { flex: 1; overflow: hidden; position: relative; }
/* — HOUSE row idiom, matching .summary-row: near-black keyline + inset top-highlight
   separator (now that bg ≈ surface). Name in --text-hi. (lane-color tint is applied
   inline by gutter.ts at GUTTER_TINT_A and composes over this gradientless row.) */
.lane-header { display: flex; align-items: center; justify-content: space-between; padding-right: 6px; border-top: 1px solid var(--keyline); box-shadow: inset 0 1px 0 rgba(150,160,210,.05); font-size: var(--fs-sm); color: var(--text); }
.lane-header.lane-nested { color: var(--text-mut); background: rgba(var(--seq-rgb),.05); }
/*  item-3: the lane NAME gets layout priority — flex-grow + a generous min-width so it
   stays readable at normal dock widths (only ellipsizes at genuine narrowness). The tools
   cluster no longer steals the name's horizontal budget at rest (see .lane-tools below: it is
   lifted out of flow when hidden, so the name spans the full row until you hover). */
.lane-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 64px; color: var(--text-hi); letter-spacing: .01em; }
.lane-header.lane-nested .lane-name { color: var(--text-mut); }
/*  item-2: a member lane of a domain group — a leading accent bar in the group's color
   (set inline as --group-accent) marks the contiguous run; the faint run tint is set inline.
   The bar + the small inline indent make the lane read as NESTED under its header band. The
   LAST member of the run carries a closing keyline so the group's extent is unambiguous. */
.lane-header.lane-in-group { box-shadow: inset 3px 0 0 var(--group-accent, var(--keyline-strong)); }
.lane-header.lane-group-last { border-bottom: 1px solid var(--keyline-strong); }
/* HOUSE — lane status LED: a steady 7px dot. No animation (idle = calm instrument).
   Active glows faintly (Tangelo signal); bet is amber; idle is a quiet recessed dot. */
.lane-led { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; margin-left: 8px; background: #2a4a3b; box-shadow: inset 0 0 0 1px rgba(0,0,0,.5); } /* LED at the RIGHT of the row (README); idle = dim phosphor green — the LED reports SCREEN state, so its idle dot is green-dark */
.lane-led-active { background: var(--tangelo); box-shadow: var(--glow-tangelo); }
.lane-led-bet { background: var(--bet); box-shadow: 0 0 6px rgba(var(--bet-rgb),.5); }
/* clean gutter at rest (matches the target mock — name + LED only). Tools
   HOVER-REVEAL per-child (not via cluster opacity, which would also hide an active
   solo/mute since CSS opacity multiplies down the tree). A soloed/muted toggle keeps
   its `.active` override so the lane's scoping state stays visible at rest. */
/*  item-3: at REST the tools are lifted OUT of layout flow (absolutely positioned at the
   row's right edge) so they reserve ZERO horizontal space — the lane name then spans the full
   row width instead of being squeezed by always-present-but-invisible buttons. On hover the
   cluster fades in over the row's right side (a subtle scrim keeps it legible over the name).
   An ACTIVE solo/mute toggle stays visible at rest, but absolute-positioned it no longer steals
   the name's width. The row's right padding leaves room for the always-on LED. */
.lane-tools {
  display: flex; gap: 3px; align-items: center;
  position: absolute; right: 22px; top: 50%; transform: translateY(-50%);
  z-index: 1; pointer-events: none;
}
.lane-tools > * { opacity: 0; transition: opacity .12s; pointer-events: auto; }
.lane-header:hover .lane-tools { background: linear-gradient(90deg, transparent, var(--surface) 18%); padding-left: 16px; }
.lane-header:hover .lane-tools > * { opacity: 1; }
/* Grouped ⊕ is exempt from at-rest .active visibility: solo/mute are operational scoping
   state worth showing at rest, but group membership is structural and already carried by the
   accent bar + row tint + closing keyline — an amber ⊕ on (most) every lane read as noise. */
.lane-tools .active:not(.lane-group-pick-btn) { opacity: 1; }
.lane-toggle { width: 18px; height: 18px; font-size: 10px; font-weight: 700; line-height: 1; border: 1px solid #000; border-radius: 3px; background: var(--raised-bg); color: var(--text-dim); cursor: pointer; padding: 0; box-shadow: var(--raised); }
.lane-toggle.t-solo.active { background: var(--amber); color: #1a1a1a; border-color: var(--amber); }
.lane-toggle.t-mute.active { background: #6a3a3a; color: #ffb0a8; border-color: #7a4a4a; }
.lane-toggle.t-rm:hover { background: #6a3a3a; color: #ffb0a8; border-color: #7a4a4a; }
/* — domain (lane) group header band. An ENGRAVED HOUSE band (reuses the recessed
   gutter material): a recessed near-black fill + a top keyline, structurally
   distinct from a lane row. The group's color rides as a faint tint (set inline by
   gutter.ts) + the name ink. The whole-group S/M toggles reuse the .lane-toggle look. */
/* the group header is ASYMMETRIC.
   EXPANDED = a ~6px group-colored RULE, all but invisible (DIMS.GROUP_HEADER_H = 6). The name
   rides the CANVAS faintly (drawExpandedGroupLabel), so the gutter shows only the rule + a faint
   caret at rest; HOVER grows the band and reveals the name + S/M + swatch (it floats over the
   first member row via z-index — the row model is untouched, only the at-rest paint shrinks).
   COLLAPSED = a taller engraved band carrying name + chip + S/M (+ the sub-lane composite on
   the canvas). Both heights ride Row.height (drag/drop is r.height-relative). */
.lane-header.lane-group {
  display: flex; align-items: center; gap: 3px;
  padding-left: 4px; padding-right: 6px;
}
/* EXPANDED at rest — a near-invisible rule: faint group tint (inline bg) + a hairline edge.
   overflow:visible lets the hover-grown content float past the 6px band. */
.lane-header.lane-group:not(.collapsed) {
  overflow: visible;
  border-bottom: 1px solid rgba(150,160,210,.06);
}
.lane-header.lane-group:not(.collapsed) .group-name { display: none; }   /* name lives on the canvas at rest */
.lane-header.lane-group:not(.collapsed) .lane-tools { display: none; }   /* controls reveal on hover */
.lane-header.lane-group:not(.collapsed) .group-caret { opacity: .4; }
/* EXPANDED on hover — grow (beats the inline 6px height) + reveal name/controls. Tall enough
   (28px) to seat the 24px S/M toggles with breathing room; the whole band is click-to-collapse. */
.lane-header.lane-group:not(.collapsed):hover {
  height: 28px !important; z-index: 30;
  background: var(--recess-bg) !important;
  box-shadow: var(--recess);
}
.lane-header.lane-group:not(.collapsed):hover .group-name { display: block; }
.lane-header.lane-group:not(.collapsed):hover .lane-tools { display: flex; }
.lane-header.lane-group:not(.collapsed):hover .group-caret { opacity: 1; }
/* COLLAPSED — the engraved stand-in band: recessed material + bracketing keylines. The band is
   tall enough to back the canvas sub-lane stack, so its controls (caret/name/chip/S/M) pin to the
   TOP rather than centering in the dead space. */
.lane-header.lane-group.collapsed {
  align-items: flex-start; padding-top: 3px;
  border-bottom: 1px solid var(--keyline-strong);
  background: var(--recess-bg);
  box-shadow: var(--recess), inset 0 -1px 0 rgba(0,0,0,.5);
  border-top: 1px solid var(--keyline-strong);
}
.lane-header.lane-group .group-name {
  flex: 0 1 auto; min-width: 0; max-width: 52%;   /* shrinkable: ellipsize, never shove the right cluster off-screen */
  font-family: var(--font-display); font-weight: 700;
  font-size: 10px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-hi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* COLLAPSED member roster — the contained lane names, muted, truncating with an ellipsis in the
   narrow dock (min-width:0 lets a flex child shrink below content so the ellipsis engages). The
   debt chip lives in the right cluster, so a long roster never pushes the number off-screen. */
.lane-header.lane-group .group-roster {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .01em;
  color: var(--text-mut); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding-left: 2px;
}
/* Controls ride a RIGHT-anchored static cluster (margin-left:auto). Expanded → they hover/
   focus-reveal; collapsed → always visible. Smaller keys to fit the short band. */
/* Right cluster never shrinks — name + roster ellipsize first, so the chip/S/M stay on-screen
   in the narrow dock (the static shot caught these clipping past the gutter's overflow edge). */
.lane-header.lane-group .lane-tools { position: static; transform: none; gap: 4px; margin-left: auto; flex: 0 0 auto; }
/* Whole-group S/M ~1.5× the per-lane toggle (was 16px, too small to hit reliably — user report). */
.lane-header.lane-group .lane-toggle { width: 24px; height: 24px; font-size: 13px; }
/* The controls' opacity lives on the CHILDREN (global `.lane-tools > *` sets them to 0; the
   `.lane-header:hover .lane-tools > *` rule already reveals the EXPANDED band on hover). So we
   only need: collapsed → always visible (group solo/mute matters most while folded), and
   expanded → also reveal on keyboard focus. */
.lane-header.lane-group.collapsed .lane-tools > * { opacity: 1; }
.lane-header.lane-group:not(.collapsed):focus-within .lane-tools > * { opacity: 1; }
/* Collapse caret — a quiet flat glyph (no raised key); turns Tangelo on hover. */
.group-caret {
  flex: 0 0 auto; width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  line-height: 1; padding: 0 3px;
  font-size: 12px; border: none; background: none; color: var(--text-mut);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.group-caret:hover { color: var(--tangelo); }
/* Aggregate debt chip on a COLLAPSED group header — a recessed mono readout window,
   debt ink in the work-debt coral so a folded group's debt still reads as debt (law 9). */
.group-debt-chip {
  flex: 0 0 auto; font-family: var(--font-mono); font-size: 9px; font-weight: 700;
  letter-spacing: .02em; line-height: 1; padding: 2px 6px; margin-right: 2px;
  border: 1px solid #000; border-radius: var(--r-sm); cursor: pointer;
  background: var(--recess-bg); box-shadow: var(--recess);
  color: var(--danger);
}
.group-debt-chip:hover { filter: brightness(1.25); }
/* — per-lane group-assign affordance: a compact ⊕ key in the gutter tools (reuses the
   .lane-toggle material). Clicking opens a body-portaled popover (openMenu) hosting the fuzzy
   group combobox — portaled so it ESCAPES #gutter-lanes' overflow:hidden (a native <select> or
   an inline popover clipped in the ~180px dock). `.active` = this lane is in a group. */
.lane-group-pick-btn { font-size: 12px; }
.lane-group-pick-btn.active { background: var(--amber); color: #1a1a1a; border-color: var(--amber); }
/* The fuzzy group combobox lives inside a .menu-pop (body-level). It must be a BLOCK column
   (not the base .fuzzy-field inline-flex ROW) so its STATIC .fuzzy-pop stacks BELOW the input —
   in-flow inside the menu-pop, which keeps the whole combobox ONE box that openMenu can viewport-
   clamp. (.fuzzy-field at (0,1,0) ties our earlier .lane-group-pick-fuzzy and won by source order,
   leaving the field a row and the static pop a 45px sliver beside the input — the "cut off" bug.
   The (0,2,0) compound selector below wins regardless of order.) */
.fuzzy-field.lane-group-pick-fuzzy { display: block; position: relative; width: 270px; }
.lane-group-pick-fuzzy .fuzzy-input { width: 100%; font-size: 12px; }
.lane-group-pick-fuzzy .fuzzy-pop { position: static; box-shadow: none; border: none; padding: 2px 0 0; min-width: 0; max-height: 220px; }
/* The clear-× (shown when the lane already has a group) sits over the input's right edge so the
   block layout doesn't stack it on its own line. */
.lane-group-pick-fuzzy .fuzzy-clear { position: absolute; right: 6px; top: 7px; }
/* Group + "+ Create…" rows render on ONE line (the tight 200px popover wrapped "Audio"→"Aud io").
   Override the global .ref-pop-item word-break for this picker; the wider field has the room. */
.lane-group-pick-fuzzy .ref-pop-item { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: normal; }
/*  item-1: the group-header band is a drag handle for moving the whole group. A grab
   cursor on the band body signals it; the caret/tools keep their own pointer cursors. */
.lane-header.lane-group-draggable { cursor: grab; }
.lane-header.lane-group-draggable:active { cursor: grabbing; }
.lane-header.lane-group-draggable .group-caret,
.lane-header.lane-group-draggable .lane-tools > *,
.lane-header.lane-group-draggable .group-debt-chip { cursor: pointer; }
/* The group drop-indicator reuses .lane-drop-indicator but tints to the active signal so a
   group move reads distinctly from a single-lane reorder. */
.group-drop-indicator { background: var(--tangelo); box-shadow: var(--glow-tangelo); }
.lane-name-input { width: calc(100% - 12px); background: var(--surface2); border: 1px solid var(--task); color: var(--text); border-radius: 3px; padding: 2px 5px; font-size: 12px; }
.lane-name-input:focus { outline: none; }
/* item 14 — +lane is a real tactile raised key (was a dashed ghost), matching +well. */
.lane-add { position: absolute; left: 0; right: 0; height: 24px; margin-top: 4px; background: var(--raised-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text-mut); font-size: 11px; cursor: pointer; box-shadow: var(--raised); margin-left: 8px; margin-right: 8px; width: calc(100% - 16px); }
.lane-add:hover { color: var(--text-hi); filter: brightness(1.3); }
/* HOUSE — per-lane height grip: a thin handle on each lane's BOTTOM edge. Invisible
   at rest, a faint phosphor catch-light on hover; row-resize cursor signals the gesture.
   .lane-header is position:absolute (set inline by gutter.ts), so this anchors to it. */
.lane-resize { position: absolute; left: 0; right: 0; bottom: 0; height: 6px; cursor: ns-resize; z-index: 2; touch-action: none; }
.lane-resize:hover { background: linear-gradient(180deg, transparent, rgba(125,224,190,.18)); box-shadow: inset 0 -1px 0 rgba(125,224,190,.35); }
body.lane-resizing, body.lane-resizing * { cursor: ns-resize !important; user-select: none; }
/* HOUSE — density stepper: sits to the RIGHT of the "LANES" label in #gutter-ruler.
   A small raised key matching the gutter tool language; cycles compact/normal/comfortable. */
/* item 14 — S/M/L density stepper as a tactile raised key (was flat surface2). */
.density-step { font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .04em; line-height: 1; padding: 3px 7px; border: 1px solid #000; border-radius: 3px; background: var(--raised-bg); color: var(--text-mut); cursor: pointer; box-shadow: var(--raised); }
.density-step:hover { color: var(--text-hi); filter: brightness(1.3); }
.density-step:active { transform: translateY(1px); }
/* — Lanes-dock horizontal resize grip on the gutter's RIGHT edge (mirror of
   .summary-resize, opposite border). Drag to set the dock width (URL view-state &gw);
   #canvas-wrap shrinks → the existing ResizeObserver repaints the canvas for free. The
   catch-light points RIGHT (toward the screen) so the grip reads as the dock's edge. It
   sits on #gutter (full height), outside #gutter-lanes, so it never collides with the
   per-lane .lane-resize (height) grip or the lane-reorder drag. Reuses body.col-resizing. */
.gutter-resize { position: absolute; right: -3px; top: 0; bottom: 0; width: 6px; cursor: col-resize; z-index: 5; touch-action: none; }
.gutter-resize:hover { background: linear-gradient(90deg, transparent, rgba(125,224,190,.18)); box-shadow: inset -1px 0 0 rgba(125,224,190,.35); }
/* Hidden-lanes affordance — persistent strip listing out-of-scope lanes */
.hidden-strip { position: absolute; left: 0; right: 0; bottom: 0; background: var(--surface2); border-top: 1px solid var(--border); padding: 6px 8px; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; box-shadow: 0 -4px 12px rgba(0,0,0,.25); }
.hidden-label { font-size: 10px; color: var(--text-dim); letter-spacing: .04em; width: 100%; }
.hidden-chip { font-size: 11px; padding: 2px 7px; border: 1px dashed var(--border); border-radius: 10px; background: var(--surface); color: var(--text-mut); cursor: pointer; }
.hidden-chip:hover { color: var(--text); border-color: var(--border-control); }

/* Canvas wrap — WebGL canvas + DOM text overlay */
#canvas-wrap { flex: 1; position: relative; overflow: hidden; touch-action: none; }
#timeline { display: block; width: 100%; height: 100%; touch-action: none; }
#text-overlay { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
/* Ruler day/date numerals + bar labels share the modern stack; tabular-nums keeps
   date columns from jittering as digits change. font-variant is static glyph
   selection — safe on this per-frame-repositioned overlay (no transition). On-bar/on-chip
   labels DO carry a faint text-shadow (the LABEL_HALO contrast halo, set inline by
   text-overlay.addLabel) so flipped ink stays legible on any
   user/lane bar fill. This is intentional, NOT an oversight: only the ~10-20 bar/chip
   labels opt in (a cheap composited paint op on already-painted, static-position text)
 — the high-churn ruler/grid numerals that repaint on every horizontal scroll stay
   haloless (passed no shadow), so the hot path keeps its no-shadow cost. */
#text-overlay span { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Summary panel */
#summary { width: 250px; min-width: 180px; background: var(--surface); border-left: 1px solid var(--border); display: flex; flex-direction: column; flex-shrink: 0; position: relative; }
/* HOUSE — Summary-width grip: a thin vertical handle on the panel's LEFT border.
   Dragging it left widens the panel (the canvas-wrap flexes to fill). Invisible at rest,
   a faint phosphor catch-light on hover; col-resize cursor signals the gesture. */
.summary-resize { position: absolute; left: -3px; top: 0; bottom: 0; width: 6px; cursor: col-resize; z-index: 5; touch-action: none; }
.summary-resize:hover { background: linear-gradient(90deg, rgba(125,224,190,.18), transparent); box-shadow: inset 1px 0 0 rgba(125,224,190,.35); }
body.col-resizing, body.col-resizing * { cursor: col-resize !important; user-select: none; }
/* — engraved uppercase dock title in the WELLS · CAPTURE BINS / LANES family
   (uppercase + .14em tracking + the engrave text-shadow) so the Summary, Lanes, and
   Wells docks read as one instrument. "Summary" comes from index.html; uppercased here. */
#summary-header { height: 32px; border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 12px; font-family: var(--font-display); font-size: 11px; color: var(--text-dim); letter-spacing: .14em; text-transform: uppercase; font-weight: 600; text-shadow: 0 1px 0 rgba(0,0,0,.6); }
#summary-body { flex: 1; overflow-y: auto; padding-bottom: 12px; min-height: 80px; }
/* Wells dock — typed LIFO bins in a collapsible bottom drawer; items are
   draggable pills you drop onto a lane to pull (retask/rebet). */
#wells-dock { flex: 0 0 auto; height: 214px; background: var(--surface); border-top: 1px solid #000; box-shadow: inset 0 1px 0 rgba(150,160,210,.1), 0 -3px 12px rgba(0,0,0,.3); display: flex; flex-direction: column; z-index: 10; }
#wells-dock.collapsed { height: auto !important; }
/* HOUSE wells header (prototype "Wells · capture bins" + "CAPTURED N" readout). */
.wells-dock-bar { height: 34px; display: flex; align-items: center; gap: 10px; padding: 0 16px; cursor: pointer; user-select: none; }
.wells-dock-bar:hover { background: rgba(255,255,255,.025); }
.wells-dock-caret { color: var(--text-mut); font-size: 10px; width: 10px; }
.wells-dock-title { font-family: var(--font-mono); font-size: 11px; color: var(--text-mut); letter-spacing: .24em; text-transform: uppercase; font-weight: 500; text-shadow: 0 1px 0 rgba(0,0,0,.7); }
.wells-dock-counts { font-size: 11px; color: var(--text-dim); display: flex; gap: 8px; }
.wells-dock-spacer { flex: 1; }
/* "CAPTURED" engraved label + a cyan readout numeral on an inset window (a passive
   data readout — the one place --cyan #7fd8e0 appears, per the spec's "phosphor readout"). */
.wells-captured-label { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.wells-captured-total { font-family: var(--font-display); font-size: 13px; font-weight: 600; letter-spacing: .14em; color: #7fd8e0; background: #0a0e18; border: 1px solid #000; border-radius: 3px; padding: 3px 9px; box-shadow: inset 0 2px 5px rgba(0,0,0,.8); text-shadow: 0 0 9px rgba(127,216,224,.5); }
.wells-dock-new { background: var(--raised-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 4px 11px; font-size: 11px; cursor: pointer; box-shadow: var(--raised); }
.wells-dock-new:hover { filter: brightness(1.4); }
/* item 3 — dock filter searchbox: a recessed engraved input matching #search-box. */
.wells-dock-filter { width: 130px; height: 24px; box-sizing: border-box; font-family: var(--font-mono); font-size: 11px; padding: 0 9px; background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text); outline: none; box-shadow: var(--recess); }
.wells-dock-filter:focus { border-color: var(--focus-border); }
.wells-dock-filter::placeholder { color: var(--text-dim); }
/* HOUSE recessed capture-bin TRAY (prototype #0e1220 well): bins sit raised inside it. */
.wells-dock-body { display: flex; flex-direction: column; gap: 12px; overflow: auto; flex: 1; min-height: 0; margin: 0 16px 8px; padding: 12px; line-height: var(--lh-tight); background: #0e1220; border: 1px solid var(--keyline-strong); border-radius: var(--r-sm); box-shadow: inset 0 2px 9px rgba(0,0,0,.55), inset 0 1px 0 rgba(150,160,210,.05); }
.wells-bin-row { display: flex; flex-wrap: wrap; gap: 10px; align-content: flex-start; }
#wells-dock.collapsed .wells-dock-body { display: none; }
/* HOUSE capture bin — a raised key in the recessed tray: label + state LED on top,
   a big Space-Grotesk count numeral + unit word in an inset readout window below. */
/*  item 2 — at most 8 bins per row: flex-basis = one-eighth of the row (minus the 7
   inter-card gaps). flex-grow keeps few wells filling the row; >8 wrap to the next row. */
.well-card { position: relative; flex: 1 1 calc((100% - 150px) / 16); min-width: 104px; display: flex; flex-direction: column; gap: 9px; padding: 11px 11px 12px; background: var(--grad-wellbin); border: 1px solid #000; border-radius: var(--r-sm); box-shadow: var(--raised); cursor: pointer; user-select: none; transition: border-color .12s, box-shadow .12s; }
.well-card:hover { border-color: #2e3654; box-shadow: inset 0 1px 0 rgba(150,160,210,.2), 0 3px 9px rgba(0,0,0,.5); }
.well-card.open { border-color: var(--accent); box-shadow: var(--raised), 0 0 0 1px var(--accent-dim); }
.well-card.park-armed { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(var(--accent-rgb),.4); }
.well-card.reordering { opacity: .5; }
.well-card.drop-target { border-color: var(--accent); box-shadow: -2px 0 0 0 var(--accent); }
/* ghost of a dragged task/bet — uses the refreshed bar hues (theme task/bet). */
.park-ghost { position: fixed; z-index: 1300; width: 132px; height: 26px; border-radius: var(--r-sm); pointer-events: none; background: rgba(var(--task-rgb),.28); border: 1px solid rgba(var(--task-rgb),.95); }
.park-ghost.bet { background: rgba(var(--bet-rgb),.28); border-color: rgba(var(--bet-rgb),.95); }
/* Bin top row: engraved label + steady state LED dot. */
.well-bin-top { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.well-card-name { font-size: 10px; letter-spacing: .15em; text-transform: uppercase; color: #c8cde0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.well-bin-led { flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%; background: #3a3f50; }
/* the dock card LED + the well-window item-row leading state-bar reuse the SAME
   per-kind hues — the grouped selectors below cover both `.well-bin-led` (card) and
   `.well-row-bar` (item row) so the kind hues stay single-sourced. */
.well-card.well-bugs   .well-bin-led,
.well-row.well-bugs   .well-row-bar { background: var(--tangelo); box-shadow: 0 0 6px rgba(var(--accent-rgb),.85); }
.well-card.well-killed .well-bin-led,
.well-row.well-killed .well-row-bar { background: var(--bet); box-shadow: 0 0 6px rgba(var(--bet-rgb),.7); }
.well-card.well-cut    .well-bin-led,
.well-row.well-cut    .well-row-bar { background: #5fb389; box-shadow: 0 0 6px rgba(95,179,137,.6); }
.well-card.well-someday .well-bin-led,
.well-row.well-someday .well-row-bar,
.well-card.well-custom .well-bin-led,
.well-row.well-custom .well-row-bar { background: #3a3f50; }
/* Bin readout window: inset dark window with the count numeral + unit word. */
.well-bin-readout { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; padding: 5px 9px; background: #0b0f1a; border: 1px solid #000; border-radius: 3px; box-shadow: inset 0 2px 6px rgba(0,0,0,.8); }
.well-card-count { font-family: var(--font-display); font-size: 22px; font-weight: 600; line-height: 1; letter-spacing: .02em; color: #e3e6ee; text-shadow: 0 0 10px rgba(150,170,220,.22); }
.well-bin-unit { font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--text-dim); white-space: nowrap; }
/* Reorder/delete controls — hover-revealed top-right so the bin stays clean. */
.well-bin-ctl { position: absolute; top: 5px; right: 5px; display: inline-flex; gap: 1px; opacity: 0; transition: opacity .12s; }
.well-card:hover .well-bin-ctl { opacity: 1; }
/* the dock quick-capture row (.wells-capture-*) was removed — capture now lives in
   the well window's add-item row. With nothing below the bins, the dock body is just the
   bin tray, so the dock resize grows the tray cleanly. */
.well-card-arrow { flex-shrink: 0; background: rgba(10,14,26,.7); border: none; color: var(--text-mut); cursor: pointer; font-size: 9px; line-height: 1; padding: 2px 3px; border-radius: 2px; }
.well-card-arrow:hover:not(:disabled) { color: var(--text-hi); background: var(--hover-bg); }
.well-card-arrow:disabled { opacity: .25; cursor: default; }
.well-card-del { flex-shrink: 0; background: rgba(10,14,26,.7); border: none; color: var(--text-mut); cursor: pointer; font-size: 12px; line-height: 1; padding: 1px 4px; border-radius: 2px; }
.well-card-del:hover { color: var(--danger); background: rgba(var(--red-rgb),.12); }
/* resize drag handle at the top of the dock */
.wells-dock-resize { height: 5px; cursor: ns-resize; background: transparent; flex-shrink: 0; border-top: 1px solid transparent; transition: border-color .15s; touch-action: none; }
.wells-dock-resize:hover { border-top-color: var(--accent); }
/* per-well floating window (one independent window per open well — no tab
   shell). Geometry only — the lifted surface / border / elevation come from the shared
   floating-window group below. Default open is TOP-anchored (keeps a fresh window inside
   #canvas-wrap); wells-dock.ts cascades the left/top per open count. max-height pins growth
   to the parent content height so it can never spill past the dock below (the resize
   with the dock capture row gone there's nothing for the window to overflow onto). */
.well-window { position: absolute; left: 12px; top: 16px; width: 320px; height: 340px; max-height: calc(100% - 16px); border-radius: var(--r-md); overflow: hidden; z-index: 39; display: flex; flex-direction: column; }
/* drag-to-park arm cue when a dragged task/bet hovers an open well window. */
.well-window.park-armed { border-color: var(--accent); box-shadow: var(--elev-4), 0 0 0 2px rgba(var(--accent-rgb),.5); }
/* kind-tinted header BADGE (instead of forking panel-head.ts to add an LED dot) —
   the kind hue rides the badge plate so the header carries the well-kind signal. */
.panel-badge.wellbadge.well-bugs   { background: var(--tangelo); color: #1a0a04; box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 0 8px rgba(var(--accent-rgb),.6); }
.panel-badge.wellbadge.well-killed { background: var(--bet); color: #1c1604; box-shadow: inset 0 1px 0 rgba(255,255,255,.35); }
.panel-badge.wellbadge.well-cut    { background: #5fb389; color: #04140c; box-shadow: inset 0 1px 0 rgba(255,255,255,.35); }
.panel-badge.wellbadge.well-someday,
.panel-badge.wellbadge.well-custom { background: var(--text-hi); color: #060609; }
.wellwin-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 10px; display: flex; flex-direction: column; gap: 4px; }
.wellwin-empty { padding: 6px 4px; font-size: 12px; color: var(--text-dim); font-style: italic; }
/* item 11 — corner se handle: shares the simplified .insp-resize glyph (see line ~924). */
.wellwin-resize { position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 3; touch-action: none; }
.wellwin-resize::after { content: ""; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px; border-right: 2px solid var(--text-dim); border-bottom: 2px solid var(--text-dim); opacity: .5; }
.wellwin-resize:hover::after { opacity: .8; }
/* HOUSE — well-window filter + add blocks: classes on recessed inputs to match
   the inspector's engraved recessed-field language; non-scrolling bands under the head. */
.wellwin-filter { display: flex; flex-direction: column; gap: 5px; padding: 8px 12px; border-bottom: 1px solid var(--sep); flex-shrink: 0; }
.wellwin-filter-row { display: flex; align-items: center; gap: 8px; }
.wellwin-filter-label { font-size: 9px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .14em; white-space: nowrap; text-shadow: 0 1px 0 rgba(0,0,0,.7); }
/* Item #13: stacked add rows — name + optional note each on their OWN full-width row so
   they have room to breathe (user ask). The standalone ENTER keycap is gone; a quiet
   right-aligned "↵ to add" hint carries the discoverability that Enter commits. */
.wellwin-add { display: flex; flex-direction: column; gap: 6px; padding: 8px 12px; border-bottom: 1px solid var(--sep); flex-shrink: 0; }
.wellwin-add-name, .wellwin-add-body { width: 100%; }
.wellwin-add-hint { align-self: flex-end; margin-top: -2px; font-size: 10.5px; color: var(--text-dim); letter-spacing: .02em; }
/* Shared recessed input for the well-window filter/add fields (engraved-field language). */
.wellwin-input { min-width: 0; background: var(--recess-bg); border: 1px solid #000; color: var(--text); padding: 5px 8px; font-size: 11px; border-radius: var(--r-sm); box-shadow: var(--recess); outline: none; }
.wellwin-input:focus { border-color: var(--accent-dim); }
.wellwin-filter-name { flex: 1; }
/* the tag-filter inline-add field (tagChipPicker / fuzzy.ts) recessed to match the
   filter inputs — the "+ tag filter…" affordance is an inline-add field, not a verb button,
   so it adopts the engraved recessed-field language rather than the .verb raised-key look. */
.wellwin-filter-tags .tag-chip-field { gap: 4px; }
.wellwin-filter-tags .tag-chip-add .fuzzy-input { background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); box-shadow: var(--recess); font-size: 11px; padding: 4px 7px; color: var(--text); }
.wellwin-filter-tags .tag-chip-add .fuzzy-input:focus { border-color: var(--accent-dim); }
/* well-item editor as a floating window (HOUSE — surface/elevation now shared). */
.wellitem-window { position: absolute; left: 360px; bottom: 220px; width: 340px; height: 380px; border-radius: var(--r-lg); overflow: hidden; z-index: 41; display: flex; flex-direction: column; }
.wellitem-head { display: flex; align-items: center; justify-content: space-between; padding: 9px 12px 8px; cursor: move; background: var(--surface); border-bottom: 1px solid var(--border); flex-shrink: 0; }
.wellitem-title { font-size: 13px; font-weight: 600; }
.wellitem-close { background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 17px; line-height: 1; padding: 0 4px; }
.wellitem-close:hover { color: var(--text); }
.wellitem-content { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-loose); display: flex; flex-direction: column; gap: var(--gap-loose); line-height: var(--lh-loose); }
/* HOUSE: the name field adopts the inspector's recessed engraved-input look (.insp-name). */
.wellitem-name { flex: 0 0 auto; width: 100%; box-sizing: border-box; background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text-hi); padding: 7px 9px; font-family: var(--font-display); font-size: 15px; font-weight: 500; box-shadow: var(--recess); outline: none; resize: none; overflow-y: auto; line-height: 1.35; max-height: 5.5rem; }
.wellitem-name:focus { border-color: var(--accent-dim); }
.wellitem-meta { font-size: 11.5px; color: var(--text-dim); }
.wellitem-meta-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* Inset tactile chip badge for well-item status (e.g. resolved). Matches the
   .insp-status-badge recipe: mono, uppercase, small, box-shadow: --recess, tinted. */
.well-status-chip { font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 2px 7px; border-radius: var(--r-sm); box-shadow: var(--recess); }
.well-status-resolved { color: var(--ok); border: 1px solid rgba(var(--ok-rgb),.4); background: rgba(var(--ok-rgb),.10); }
/* tombstone status — PULLED (re-committed, in flight) = amber; DONE (successor shipped) = ok green. */
.well-status-pulled { color: var(--amber); border: 1px solid rgba(var(--amber-rgb),.4); background: rgba(var(--amber-rgb),.10); }
.well-status-done { color: var(--ok); border: 1px solid rgba(var(--ok-rgb),.4); background: rgba(var(--ok-rgb),.10); }
.well-status-chip.clickable { cursor: pointer; }
.well-status-chip.clickable:hover { filter: brightness(1.3); }

/* hidden-bucket reveal toggles ("Pulled N" / "Done N") — same inset tactile chip
   recipe as .well-status-chip; dim/neutral when off, tinted in the bucket's color when on. */
.wellwin-hidden-chips { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.wellwin-hidden-chips:empty { display: none; }
.wellwin-toggle-chip { font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 2px 7px; border-radius: var(--r-sm); box-shadow: var(--recess); background: transparent; border: 1px solid var(--border); color: var(--text-dim); cursor: pointer; transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast); }
.wellwin-toggle-chip:hover { color: var(--text); border-color: var(--text-dim); }
.wellwin-toggle-chip.on.tg-pulled { color: var(--amber); border-color: rgba(var(--amber-rgb),.4); background: rgba(var(--amber-rgb),.10); }
.wellwin-toggle-chip.on.tg-done { color: var(--ok); border-color: rgba(var(--ok-rgb),.4); background: rgba(var(--ok-rgb),.10); }
.wellwin-toggle-chip:focus-visible { outline: 1px solid var(--accent); }
.wellitem-sub { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.wellitem-textarea { flex: 1; min-height: 80px; resize: none; background: var(--surface2); border: 1px solid var(--border); border-radius: 6px; color: var(--text); padding: 8px 9px; font: inherit; font-size: 13px; line-height: 1.5; }
/* HOUSE: actions now ride the shared `.insp-verbs` row (Save = verb-active, Cancel = verb);
   the row class supplies the flex layout, so this only pins it as a non-shrinking footer. */
.wellitem-actions { flex-shrink: 0; }
/* item 11 — corner se handle: shares the simplified .insp-resize glyph. */
.wellitem-resize { position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 3; touch-action: none; }
.wellitem-resize::after { content: ""; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px; border-right: 2px solid var(--text-dim); border-bottom: 2px solid var(--text-dim); opacity: .5; }
.wellitem-resize:hover::after { opacity: .8; }
.well-pills { overflow-y: auto; padding: 0 8px; display: flex; flex-direction: column; gap: 4px; }
/* well-window item rows in the INSPECTOR list-row idiom — a flat raised row with a
   leading kind state-bar, the item name, an action key, and a hover-revealed × (like the
   dock bins). `.well-pill` is kept for the drag / .flash / .dragging hooks; `.well-row`
   carries the new list-row look (overrides the legacy pill geometry). */
.well-pill { display: flex; align-items: center; gap: 6px; padding: 4px 6px 4px 9px; font-size: 12px; background: var(--surface2); border: 1px solid var(--border); border-radius: 13px; cursor: grab; }
/* flex-shrink:0 — the well-window list (.wellwin-list) is a column flexbox with
   overflow-y:auto; without this the rows would compress to fit (becoming too thin)
   instead of overflowing into a scroll when a well holds many items. */
.well-row { flex: 0 0 auto; gap: 8px; padding: 6px 7px 6px 0; border-radius: var(--r-sm); background: var(--grad-surface2); border: 1px solid #000; box-shadow: var(--raised); overflow: hidden; }
.well-row-bar { flex: 0 0 auto; align-self: stretch; width: 3px; border-radius: 1px; background: #3a3f50; }
.well-pill:hover { border-color: var(--border-control); }
.well-row:hover { filter: brightness(1.12); border-color: #000; }
.well-pill:active { cursor: grabbing; }
.well-pill.dragging { opacity: .4; }
.well-pill.flash { animation: well-flash 1.3s ease-out; }
/* a box-shadow + transform PULSE only (no background/border-color keys) so the row's
   own gradient shows throughout and the ring fades smoothly back to the resting raised
   shadow — a fill-flash on a gradient row can't interpolate and snaps at the end. */
@keyframes well-flash {
  0%   { box-shadow: 0 0 0 2px rgba(var(--focus-rgb),.6), var(--raised); transform: translateY(-3px) scale(1.015); }
  18%  { transform: translateY(1px) scale(.997); }
  30%  { box-shadow: 0 0 0 2px rgba(var(--focus-rgb),.6), var(--raised); transform: translateY(0) scale(1); }
  100% { box-shadow: 0 0 0 0 rgba(var(--focus-rgb),0), var(--raised); transform: none; }
}
/*  hero 4 — "items land with weight": a well card pulses + settles when its
   item count INCREASES (a fresh capture just dropped in). Overshoot easing gives
   the drop a sense of mass. Created by wells-dock.ts only on a real count bump. */
.well-card.landed { animation: well-land .52s cubic-bezier(.2,.85,.25,1.25); }
@keyframes well-land {
  0%   { transform: translateY(-4px) scale(1.05); box-shadow: var(--elev-2), var(--ring-accent-strong); }
  55%  { transform: translateY(1px) scale(.995); }
  100% { transform: translateY(0) scale(1); box-shadow: var(--elev-1); }
}
.well-pill.resolved .well-pill-name { text-decoration: line-through; color: var(--text-dim); }
.well-pill-name { flex: 1; overflow-wrap: break-word; min-width: 0; }
/* Item #4 — reverse "fixed by <track>" link on a bug well-item row: a quiet dim label +
   the existing .ref-chip.ref-track link chip(s). flex:0 so the name keeps the slack; the
   chip itself can shrink (the ref-chip already ellipsis-free, kept compact). */
.well-row-fixedby { flex: 0 1 auto; display: inline-flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; max-width: 45%; }
.well-row-fixedby-label { font-size: 10px; color: var(--text-dim); letter-spacing: .03em; white-space: nowrap; flex: 0 0 auto; }
.well-row-fixedby .ref-chip { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Well item names get a min-width so they stay readable; max 2 lines with ellipsis. */
.well-row .well-pill-name { color: var(--text-hi); min-width: 80px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
/* action key: quiet raised key (Fix / Pull / Retask / Rebet), HOUSE button language. */
.well-act { flex-shrink: 0; background: var(--raised-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 3px 9px; font-size: 10px; letter-spacing: .04em; cursor: pointer; box-shadow: var(--raised); }
.well-act:hover { filter: brightness(1.3); }
/* hover-reveal the × delete (like the dock bin controls) — present but quiet until
   the row is hovered, then a danger ghost. */
.well-del { flex-shrink: 0; background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 14px; line-height: 1; padding: 0 4px 0 2px; }
.well-del:hover { color: var(--danger); }
.well-row .well-del { opacity: 0; transition: opacity var(--t-fast); }
.well-row:hover .well-del, .well-row .well-del:focus-visible { opacity: 1; }
/* Inline-body expand: the wrap stacks the row + its read-only description as a column; it is
   the direct flex child of .wellwin-list (flex:0 0 auto so it never compresses — the list
   scrolls instead, keeping the window geometry fixed). */
.well-row-wrap { flex: 0 0 auto; display: flex; flex-direction: column; }
/* Rotating chevron caret (leftmost). Static glyph swapped by rotation on .expanded, matching
   the dock caret's ▸/▾ idiom. Quiet until hover, brightens with the row. */
.well-row-caret { flex: 0 0 auto; width: 13px; margin-left: 5px; text-align: center; font-size: 9px; line-height: 1; color: var(--text-dim); cursor: pointer; user-select: none; transition: transform var(--t-fast), color var(--t-fast); }
.well-row-caret.expanded { transform: rotate(90deg); color: var(--text); }
.well-row:hover .well-row-caret { color: var(--text); }
/* "✎ Edit" — the primary open-editor key. A labeled, always-visible raised HOUSE key (reads
   as clearly clickable, not a bare glyph), seated at the LEFT of the control cluster so it is
   never adjacent to the destructive × at the far right. */
.well-edit { flex-shrink: 0; display: inline-flex; align-items: center; gap: 3px; background: var(--raised-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 3px 9px; font-size: 10px; letter-spacing: .04em; cursor: pointer; box-shadow: var(--raised); white-space: nowrap; transition: color var(--t-fast), filter var(--t-fast); }
.well-edit:hover { color: var(--accent); filter: brightness(1.25); }
.well-edit:focus-visible { color: var(--accent); outline: 1px solid var(--accent-dim); }
/* Inline read-only description under a row: a recessed panel indented under the name, using
   the shared md .body-line typography. Sits flush beneath its row (small negative-ish seat via
   the wrap's zero gap), scrolls with the list. */
.well-row-body { margin: 2px 0 2px 21px; padding: 6px 9px; font-size: 12px; line-height: 1.5; color: var(--text); background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); box-shadow: var(--recess); overflow-wrap: break-word; }
.well-row-body-empty { color: var(--text-dim); font-style: italic; }
/* Thin list toolbar above the rows: hosts the labeled expand/collapse-all toggle, right-
   aligned so it reads as a list-wide action rather than window chrome. Non-scrolling band. */
.wellwin-listbar { display: flex; justify-content: flex-end; align-items: center; padding: 5px 10px 0; flex-shrink: 0; }
/* Labeled expand/collapse-all toggle: caret glyph + text ("▸ Expand all" / "▾ Collapse all").
   A quiet recessed-key affordance — clearly a control, distinct from the raised action keys. */
.wellwin-expand-all { background: var(--raised-bg); border: 1px solid #000; color: var(--text-dim); cursor: pointer; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; padding: 3px 9px; border-radius: var(--r-sm); box-shadow: var(--raised); transition: color var(--t-fast), filter var(--t-fast); }
.wellwin-expand-all:hover { color: var(--text); filter: brightness(1.2); }
.wellwin-expand-all:disabled { opacity: .4; cursor: default; filter: none; }
.well-fixed { flex-shrink: 0; font-size: 10px; color: var(--ok); padding-right: 4px; }
.well-empty { padding: 2px 12px; font-size: 11px; color: var(--text-dim); font-style: italic; }
.canvas-drop-hint { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); z-index: 60; background: rgba(var(--task-rgb),.92); color: #fff; padding: 5px 12px; border-radius: var(--r-pill); font-size: 12px; pointer-events: none; box-shadow: 0 4px 16px rgba(0,0,0,.4); }
/* ── — shared RECESSED-MONO READOUT WINDOW ─────────────────────────────
   The ONE source for the "07d"-style readout pill, reused by the Summary dock,
   the Lanes dock, and any future dock. Recessed dark inset window + near-black
   border + inset top-highlight bevel + rounded, IBM Plex Mono tabular numerals. The
   window is NEUTRAL-dark for every state; the SEMANTIC hue rides ONLY in the numeral
   ink via --readout-ink (default = the phosphor cyan, for NEUTRAL magnitudes; a debt
   readout overrides --readout-ink to its category hue). text-shadow glows the same hue
   so the readout reads as an emitting phosphor segment, never a flat label. */
.readout {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 2px 7px; border-radius: var(--r-sm); border: 1px solid #000;
  background: var(--readout-bg); box-shadow: var(--readout-shadow);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 11px; line-height: 1.3; letter-spacing: .02em; white-space: nowrap;
  color: var(--readout-ink, var(--cyan));
  text-shadow: 0 0 8px rgba(var(--readout-ink-rgb, var(--cyan-rgb)), .45);
}

.summary-empty { padding: 16px 12px; color: var(--text-dim); font-size: 12px; }
/* — engraved uppercase Space-Grotesk category header (the WELLS · CAPTURE BINS
   family). The category hue tints the LABEL itself (a quiet semantic cue); the magnitude
   readout below carries the same hue in its --readout-ink. */
.summary-cat { padding: 11px 12px 5px; font-family: var(--font-display); font-size: 10px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); text-shadow: 0 1px 0 rgba(0,0,0,.6); }
.summary-cat.cat-decision { color: var(--amber); }
.summary-cat.cat-overbox { color: var(--seq); }
.summary-cat.cat-work { color: var(--red); }
.summary-cat.cat-blocked { color: var(--conflict); }
.summary-cat.cat-soon { color: var(--cyan); }   /* NEUTRAL category — header matches its cyan readout */
/* — HOUSE row idiom: a raised key on the recessed dock tray. Near-black keyline +
   inset top-highlight separates rows now that bg ≈ surface. Name in --text-hi. */
.summary-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 12px; cursor: pointer; border-top: 1px solid var(--keyline); box-shadow: inset 0 1px 0 rgba(150,160,210,.05); }
.summary-row:hover { background: var(--surface2); }
.summary-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; color: var(--text-hi); }
/* — the magnitude/value renders in the shared .readout window. Default ink is cyan
   (NEUTRAL magnitudes, e.g. "due in Nd"); each DEBT category overrides --readout-ink to
   keep its SEMANTIC hue (the magnitude is debt, not a neutral duration). --readout-ink-rgb
   feeds the same-hue text-shadow glow. */
.summary-detail { flex-shrink: 0; }
.summary-detail.cat-decision { --readout-ink: var(--amber);    --readout-ink-rgb: var(--amber-rgb); }
.summary-detail.cat-overbox  { --readout-ink: var(--seq);      --readout-ink-rgb: var(--seq-rgb); }
.summary-detail.cat-work     { --readout-ink: var(--red);      --readout-ink-rgb: var(--red-rgb); }
.summary-detail.cat-blocked  { --readout-ink: var(--conflict); --readout-ink-rgb: var(--conflict-rgb); }
.summary-detail.cat-soon     { --readout-ink: var(--cyan);     --readout-ink-rgb: var(--cyan-rgb); }   /* NEUTRAL magnitude → cyan (the user-resolved widening) */
/* — PROSE details ("decision overdue", "blocked by X") are NOT magnitudes, so they
   stay plain text (no readout pill). They keep their category's SEMANTIC hue via the same
   per-cat --readout-ink, and are allowed to wrap (no nowrap) so a long blocker name never
   clips the track name in the narrow Summary panel. */
.summary-detail-prose { font-size: 11px; color: var(--readout-ink, var(--text-dim)); max-width: 55%; text-align: right; }
/* Item #14 — the inspector window box is shared between the primary #inspector and the
   tail .inspector-card windows via .insp-window (both carry the class). The primary keeps
   its own display:none + CSS-default anchor (top/right); cards are always shown and set
   their left/top/width/height inline (cascade). */
.insp-window { position: absolute; width: 340px; height: 470px; background: var(--grad-surface); border: 1px solid var(--keyline-strong); border-radius: var(--r-md); box-shadow: var(--lifted); overflow: hidden; z-index: 40; }
#inspector { display: none; top: 48px; right: 12px; }
#inspector.show { display: block; }
.inspector-card.show { display: block; }
.insp-content { height: 100%; overflow-y: auto; padding: var(--space-loose); display: flex; flex-direction: column; line-height: var(--lh-loose); }
/*  item 11 — resize handles. The bottom-right CORNER is the caller-supplied
   .insp-resize (kept as makeFloating's "se" handler); the simplified glyph replaces the
   busy diagonal hatch — a quiet 2-line corner mark that reads as a grip without noise.
   makeFloating ALSO injects three thin edge zones (.fl-resize-{e,w,s}) into every window. */
.insp-resize { position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 3; touch-action: none; }
.insp-resize::after { content: ""; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px; border-right: 2px solid var(--text-dim); border-bottom: 2px solid var(--text-dim); opacity: .5; }
.insp-resize:hover::after { opacity: .8; }
/* Thin invisible-but-hoverable edge strips. Positioned on the absolute edges, above content
   (z-index:2) but only ~6px wide so they don't cover the content scrollbar/interaction; the
   se corner (z-index:3) wins the overlap at the bottom-right. The cursor is the only visible
   affordance — quiet, on-brand. */
.fl-resize-e, .fl-resize-w, .fl-resize-s { position: absolute; z-index: 2; touch-action: none; }
.fl-resize-e { top: 0; bottom: 0; right: 0; width: 6px; cursor: ew-resize; }
.fl-resize-w { top: 0; bottom: 0; left: 0; width: 6px; cursor: ew-resize; }
.fl-resize-s { left: 0; right: 0; bottom: 0; height: 6px; cursor: ns-resize; }
.insp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; cursor: move; touch-action: none; }
/* HOUSE — kind badge: TASK reads as a white-cap plate (white fill, dark ink);
   bet/seq keep their semantic hue so the kind stays scannable at a glance. */
.insp-kind { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; padding: 2px 7px; border-radius: var(--r-sm); color: #060609; background: var(--text-hi); box-shadow: inset 0 1px 0 rgba(255,255,255,.5); }
.insp-kind.kind-bet { background: var(--bet); color: #1a1a1a; }
.insp-kind.kind-seq { background: var(--seq); color: var(--text-hi); }
.insp-close { background: none; border: none; color: var(--text-dim); font-size: 18px; cursor: pointer; line-height: 1; margin-left: 10px; }
.insp-close:hover { color: var(--text); }
/* #6 copy-link — the kind badge (.insp-kind) IS the "copy a direct link to this track"
   control (the standalone 🔗 icon was removed as ugly; well rows no longer carry one either).
   `.copyable` marks it pressable (pointer + faint hover lift); `.copied` flashes a brief
   success-green confirmation while the label reads "COPIED ✓", then reverts. */
.insp-kind.copyable { cursor: pointer; transition: filter var(--t-fast), box-shadow var(--t-fast); }
.insp-kind.copyable:hover { filter: brightness(1.18); }
.insp-kind.copyable:active { filter: brightness(.95); }
.insp-kind.copied { color: var(--ok); background: rgba(var(--ok-rgb),.22); box-shadow: inset 0 0 0 1px rgba(var(--ok-rgb),.6); }
/* name row groups the name field + the per-track color-override swatch. */
.insp-name-row { display: flex; align-items: flex-start; gap: 7px; margin-bottom: 10px; }
.insp-name { flex: 1 1 auto; min-width: 0; background: var(--recess-bg); border: 1px solid #000; color: var(--text-hi); padding: 7px 9px; border-radius: var(--r-sm); font-family: var(--font-display); font-size: 15px; font-weight: 500; box-shadow: var(--recess); resize: none; overflow: hidden; line-height: 1.35; }
.insp-name:focus { outline: none; border-color: var(--accent-dim); }
/* Track color-override swatch: the filled square shows the override; click opens the
   native picker (the input is overlaid + transparent). `.unset` shows a neutral chip. */
.insp-color-swatch { position: relative; flex: 0 0 auto; width: 22px; height: 22px; border: 1px solid var(--border); border-radius: 4px; cursor: pointer; box-shadow: var(--elev-1); }
.insp-color-swatch.unset { background: repeating-linear-gradient(45deg, var(--surface2), var(--surface2) 4px, var(--surface) 4px, var(--surface) 8px); }
.insp-color-swatch input[type=color] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: none; padding: 0; }
.insp-color-reset { flex: 0 0 auto; width: 22px; height: 22px; font-size: 13px; line-height: 1; border: 1px solid var(--border); border-radius: 4px; background: var(--surface2); color: var(--text-dim); cursor: pointer; padding: 0; }
/* The name field is now a textarea that top-grows with `align-items: flex-start` on the
   row (so the swatch anchors to the FIRST line when the name wraps). Nudge the swatch +
   reset down to sit centered on that first text line — matching the old `align-items:
   center` look when the name is a single line. */
.insp-name-row .insp-color-swatch, .insp-name-row .insp-color-reset { margin-top: 6px; }
.insp-color-reset:hover { color: var(--text); }
/* Lane color-swatch in the gutter tools cluster (sits beside solo/mute/×). */
.lane-color-swatch { position: relative; width: 18px; height: 18px; border: 1px solid var(--border); border-radius: 3px; cursor: pointer; display: inline-block; }
.lane-color-swatch.unset { background: repeating-linear-gradient(45deg, var(--surface2), var(--surface2) 3px, var(--surface) 3px, var(--surface) 6px); }
.lane-color-swatch input[type=color] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: none; padding: 0; }
/* the visible lane-color reset ↺ (a .lane-toggle sibling, 18px to match). */
.lane-toggle.t-color-reset:hover { color: var(--text); border-color: var(--border-control); }
/* Lane drag affordance + ghost. The drop indicator / draggable cursor / reordering
   state has its own visible cue so the landing position is clear. */
.lane-draggable { cursor: grab; }
.lane-draggable:active { cursor: grabbing; }
.lanes-reordering, .lanes-reordering .lane-draggable { cursor: grabbing; }
/* A bright accent rule marking the drop slot between rows (absolutely positioned in
   the gutter's rowIndex*ROW_H space by startLaneDrag). */
.lane-drop-indicator { position: absolute; left: 6px; right: 6px; height: 2px; background: var(--accent); box-shadow: 0 0 6px rgba(var(--accent-rgb),.7); border-radius: 1px; pointer-events: none; z-index: 6; }
/* The drop indicator signals grouped-vs-ungrouped intent BEFORE release. When the
   drop will land the lane INSIDE a group, it indents (set inline, matching the member-row
   indent) and takes the group's color (--group-accent); a small leading dot reinforces "into
   this group". Ungrouped/above drops keep the flush neutral bar. */
.lane-drop-indicator.drop-in-group { background: var(--group-accent, var(--tangelo)); box-shadow: 0 0 7px var(--group-accent, var(--tangelo)); }
.lane-drop-indicator.drop-in-group::before { content: ""; position: absolute; left: -7px; top: -2px; width: 6px; height: 6px; border-radius: 50%; background: var(--group-accent, var(--tangelo)); }
/* The lifted lane label trailing the pointer during a reorder (fixed to <body>). */
.lane-drag-ghost { position: fixed; pointer-events: none; z-index: 1000; font-size: 12px; color: var(--text); background: var(--surface2); border: 1px solid var(--accent); border-radius: var(--r-sm); padding: 3px 9px; box-shadow: var(--elev-1), var(--ring-accent); opacity: .92; white-space: nowrap; max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
.insp-meta { font-size: 12px; line-height: 1.6; margin-bottom: 12px; }
.insp-dim { color: var(--text-dim); }
.st-overdue-task { color: var(--red); }
.st-overdue-bet { color: var(--amber); }
.st-due-soon { color: var(--info); }
.st-done { color: var(--ok); }
/* inspector layout: status badge row + tightened meta. */
.insp-status-row { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.insp-status-badge { font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; padding: 2px 8px; border-radius: 10px; background: var(--surface2); border: 1px solid var(--border); }
.insp-status-badge.st-ok { color: var(--text-dim); }
.insp-status-badge.st-overdue-task { color: var(--red); border-color: rgba(var(--red-rgb),.4); background: rgba(var(--red-rgb),.10); }
.insp-status-badge.st-overdue-bet { color: var(--amber); border-color: rgba(251,202,18,.4); background: rgba(251,202,18,.10); }
.insp-status-badge.st-due-soon { color: var(--tangelo-tint); border-color: var(--accent-dim); background: rgba(var(--accent-rgb),.10); }
.insp-status-badge.st-spilling { color: var(--red); border-color: rgba(var(--red-rgb),.4); background: rgba(var(--red-rgb),.10); }
.insp-status-badge.st-done { color: var(--ok); border-color: rgba(var(--ok-rgb),.4); background: rgba(var(--ok-rgb),.10); }
.insp-status-working { font-size: 11px; color: var(--accent); }
.insp-meta-dates { font-size: 12px; }
.insp-meta-note { font-size: 11px; margin-top: 2px; }
/* Inspector roles + dependencies (P7) */
.insp-roles, .insp-deps { border-top: 1px solid var(--border); padding: 9px 0; margin-bottom: 2px; }
.insp-role-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
/* HOUSE — engraved field label: small, uppercase, tracked, recessed. Structural
   text sits INTO the panel (the dark text-shadow) while live values stay bright. */
.insp-role-label { font-size: 9px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .18em; font-weight: 500; text-shadow: 0 1px 0 rgba(0,0,0,.7); }
.insp-role-sel, .insp-dep-add { flex: 1; max-width: 170px; background: var(--recess-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 5px 7px; font-size: 12px; box-shadow: var(--recess); }
.insp-role-sel.insp-role-missing { border-color: var(--warn); }
.insp-warn { font-size: 11px; color: var(--warn); margin-top: 2px; }
.insp-role-hint { font-size: 11px; margin-top: 2px; }
.insp-deps-hdr { font-size: 11px; color: var(--text-dim); margin-bottom: 6px; }
.insp-deps-hdr .dep-conflict { color: var(--conflict); }
.insp-deps-hdr .dep-waiting { color: var(--warn); }
/* #15.1 — quiet section-header for Tags / Attachments / Referenced-by, matching the
   established .insp-deps-hdr treatment (small + dim) so every section label is consistent.
   A hair of letter-spacing settles it as a label without going loud/uppercase. */
.insp-body-hdr { font-size: 11px; color: var(--text-dim); letter-spacing: .02em; margin-bottom: 6px; }
.insp-dep-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; padding: 2px 0; }
.insp-dep-rm { background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 15px; line-height: 1; }
.insp-dep-rm:hover { color: var(--danger); }
.insp-dep-add { width: 100%; max-width: none; margin-top: 4px; }
/* Fuzzy type-ahead picker — roles + blocked-by */
.fuzzy-field { position: relative; display: inline-flex; align-items: center; }
.insp-role-row .fuzzy-field { flex: 1; max-width: 170px; }
.insp-deps .fuzzy-field { width: 100%; margin-top: 4px; }
.fuzzy-input { width: 100%; background: var(--recess-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 5px 7px; font-size: 12px; box-shadow: var(--recess); }
.fuzzy-input:focus { outline: none; border-color: var(--accent-dim); }
/* #15.2 — the inspector's role + add-blocker pickers land on the shared small-input recipe
   (the .insp-attach-name baseline: 6px 8px / 12px) so every inspector text field is one size
   (the title is the sole larger exception). Scoped to the inspector so the base .fuzzy-input
   (review / well-window surfaces) keeps its own 5/7 size. */
.insp-roles .fuzzy-input, .insp-deps .fuzzy-input { padding: 6px 8px; }
.fuzzy-input.fuzzy-missing { border-color: var(--warn); }
.fuzzy-clear { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 13px; line-height: 1; padding: 0 2px; }
.fuzzy-clear:hover { color: var(--text); }
.fuzzy-pop { top: 100%; left: 0; margin-top: 2px; min-width: 160px; max-height: 200px; overflow-y: auto; }
.ref-pop-item.active { background: rgba(255,255,255,.12); }
/* create-on-no-match row + Shift-Enter tip. */
.ref-pop-item.ref-pop-create { display: flex; align-items: center; justify-content: space-between; gap: 8px; color: var(--accent); }
.ref-pop-tip { font-size: 10px; color: var(--text-dim); border: 1px solid var(--border); border-radius: 3px; padding: 0 4px; flex-shrink: 0; }
/* Inspector body + references + attachments (P8) */
.insp-body, .insp-backlinks, .insp-attach { border-top: 1px solid var(--border); padding: 10px 0; }
/* The body is the leaf's detail view — give it the slack in a resized window. */
.insp-body { flex: 1; display: flex; flex-direction: column; min-height: 120px; }
.insp-body-bar { display: flex; justify-content: flex-end; margin-bottom: 6px; }
.insp-preview-toggle { font-size: 11px; padding: 2px 8px; border: 1px solid #000; border-radius: var(--r-sm); background: var(--raised-bg); color: var(--text-dim); cursor: pointer; box-shadow: var(--raised); }
.insp-preview-toggle:active { transform: translateY(1px); }
.insp-preview-toggle.on { color: var(--focus); border-color: var(--accent-dim); }
/* caret-aware live editor: rendered lines + one raw textarea line. */
.insp-body-live { flex: 1; min-height: 80px; background: var(--surface2); border: 1px solid var(--border); border-radius: 4px; padding: var(--space-tight) var(--sp-4); font: var(--fs-base)/var(--lh-loose) var(--font-mono); overflow-y: auto; cursor: text; }
.body-line { white-space: pre-wrap; word-break: break-word; min-height: 1.6em; }
.body-line.empty { color: var(--text-dim); }
/* Tier-1 collab: a line another user is editing. `position: relative` anchors the peer chip;
   `peer-draft` (a peer's live line preview) gets a faint tint so a viewer sees it's in flux. */
.body-line.peer-editing { position: relative; }
.body-line.peer-draft { background: color-mix(in oklab, var(--primary-bg) 10%, transparent); border-radius: 3px; }
/* Peer presence chips: pointer-none so they never steal a click meant for the line (the line's
   own click activates / arms the soft-lock). Right-anchored initials capsule per peer. */
.body-line-peers { position: absolute; top: 1px; right: 2px; display: flex; gap: 3px; pointer-events: none; user-select: none; z-index: 1; }
.peer-chip { font: 600 9px/1.3 var(--font-mono); color: #0b0f14; padding: 1px 5px; border-radius: 7px; letter-spacing: .02em; white-space: nowrap; box-shadow: 0 1px 2px rgba(0,0,0,.35); }
/* The armed soft-lock affordance (step 5): a fuller "… click to take over" pill. */
.peer-chip.takeover { font-size: 10px; padding: 2px 7px; }
/* Rendered markdown blocks (caret line stays raw source). */
.body-line.body-h1 { font-size: 16px; font-weight: 700; line-height: 1.4; margin: 2px 0; }
.body-line.body-h2 { font-size: 14px; font-weight: 700; line-height: 1.4; margin: 2px 0; }
.body-line.body-h3 { font-size: 13px; font-weight: 700; color: var(--text); margin: 1px 0; }
.body-line.body-li { padding-left: 6px; }
.body-line .body-bullet { color: var(--text-dim); }
.body-line.body-check { display: flex; align-items: baseline; gap: 6px; }
/*  item 8: appearance/box/check now come from the shared HOUSE checkbox recipe above;
   this only keeps the body-row vertical alignment. */
.body-line .body-checkbox { align-self: center; }
.body-line .body-check-done { color: var(--text-dim); text-decoration: line-through; }
.body-line.body-quote { border-left: 2px solid var(--border); padding-left: 8px; color: var(--text-dim); }
.insp-body-live code { background: var(--hover-bg); border-radius: 3px; padding: 0 3px; font-family: var(--font-mono); font-size: 11px; }
.insp-body-live strong { font-weight: 700; }
.insp-body-live em { font-style: italic; }
.body-line-edit { width: 100%; resize: none; background: transparent; border: none; color: var(--text); font: inherit; padding: 0; margin: 0; outline: none; overflow: hidden; display: block; }
.body-embed-img { max-width: 100%; max-height: 200px; border-radius: 4px; display: block; margin: 4px 0; }
.body-embed-yt { width: 100%; aspect-ratio: 16/9; border: 0; border-radius: 4px; margin: 4px 0; }
.body-link { color: var(--link); }
/*  item 5 — TACTILE reference chips, harmonized with the .tag-chip family (line 588):
   a RECESSED dark window (--readout-bg + #000 border + inset shadow, radius 3) with a faint
   per-kind colored wash layered over it, the per-kind ink riding on top. So refs and tags
   read as one inset-window idiom. The wash hue MATCHES the ink (link/bet/seq) — cleaner than
   the old slate-wash/blue-ink mismatch — and still satisfies "track=link-blue …". Inline-flow
   safe: inline-flex + an explicit baseline nudge (vertical-align) since inline-flex sits a hair
   low in running markdown text (can't be eyeballed here, so it's set deliberately). */
.ref-chip { display: inline-flex; align-items: center; vertical-align: -0.12em; padding: 1px 6px; margin: 0 1px; border-radius: 3px; font-size: 11px; line-height: 1.35; white-space: nowrap; background: var(--readout-bg); border: 1px solid #000; box-shadow: inset 0 1px 3px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.04); color: var(--text); cursor: pointer; }
/* Per-kind: low-alpha hue wash over the dark window + matching ink. The wash is layered as a
   gradient(tint,tint) so it sits ON the recess without replacing it (the tag-chip idiom). */
.ref-chip.ref-track { background: linear-gradient(rgba(var(--link-rgb),.15),rgba(var(--link-rgb),.15)), var(--readout-bg); color: var(--link); }
.ref-chip.ref-well  { background: linear-gradient(rgba(var(--bet-rgb),.15),rgba(var(--bet-rgb),.15)), var(--readout-bg); color: var(--bet-ink); cursor: pointer; }
.ref-chip.ref-user  { background: linear-gradient(rgba(var(--seq-rgb),.16),rgba(var(--seq-rgb),.16)), var(--readout-bg); color: var(--seq-ink); cursor: default; }
.ref-chip.ref-dangling { background: var(--readout-bg); color: var(--text-dim); text-decoration: line-through; cursor: default; }
/* Pressable affordance — CLICKABLE chips only: track/well AND not dangling (a dangling chip
   keeps its kind class — ref-track ref-dangling — but has no click handler, so it must NOT
   light up). Hover lifts brightness; active presses with a deeper inset (reads right on a
   recessed chip, vs translateY on a raised one). */
.ref-chip.ref-track:not(.ref-dangling):hover, .ref-chip.ref-well:not(.ref-dangling):hover { filter: brightness(1.2); }
.ref-chip.ref-track:not(.ref-dangling):active, .ref-chip.ref-well:not(.ref-dangling):active { box-shadow: inset 0 2px 5px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.03); }
.ref-pop { position: absolute; z-index: 1500; background: var(--surface2); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 8px 24px rgba(0,0,0,.45); padding: 4px; min-width: 200px; max-width: 340px; }
.ref-pop-item { padding: 5px 9px; border-radius: 4px; font-size: 12px; cursor: pointer; word-break: break-word; }
.ref-pop-item:hover { background: var(--hover-bg); }
.insp-backlink { font-size: 12px; padding: 3px 0; color: var(--link); cursor: pointer; }
.insp-backlink:hover { text-decoration: underline; }
.insp-attach-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; padding: 3px 0; }
.insp-attach-main { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1; }
.attach-thumb { max-height: 40px; max-width: 64px; border-radius: 4px; border: 1px solid var(--border); object-fit: cover; }
.insp-attach-name-link { color: var(--link); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.insp-attach-name-link:hover { text-decoration: underline; }
.attach-canvas-badge { font-size: 9px; padding: 1px 5px; border-radius: 8px; background: var(--seq); color: #042; letter-spacing: .04em; flex-shrink: 0; }
/* Comments — lightweight annotations on a track / well item. */
/* "Created by" attribution line (inspector). */
.insp-created-by { font-size: 11.5px; margin: -4px 0 8px; }
/* comments now open in their own floating window — the inspector + well-item editor
   show a "Comments (N)" launcher instead of an inline thread. */
.insp-comments-launch-wrap { border-top: 1px solid var(--border); padding: 10px 0; }
.insp-comments-launch { display: inline-flex; align-items: center; gap: 6px; background: var(--raised-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 4px 12px; font-size: 12px; cursor: pointer; box-shadow: var(--raised); }
.insp-comments-launch:hover { color: var(--focus); filter: brightness(1.25); }
.insp-comments-launch:active { transform: translateY(1px); }
/* HOUSE — the shared floating-window header (panel-head.ts), used by the well, well-item
   and comments windows. Same language as the inspector's `.insp-head`: a kind BADGE +
   Space-Grotesk title + muted meta on the left, one ✕ close on the right. Layout only here;
   the titlebar gradient/groove/active recipe is shared via the grouped selectors below.
   It is a non-scrolling `flex-shrink:0` band (NOT the inspector's sticky-scroll head). */
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 9px 12px 8px; cursor: move; flex-shrink: 0; touch-action: none; }
.panel-head-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* Reuse the inspector kind-badge plate exactly (white-cap TASK look; tinted per kind). */
.panel-badge { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; padding: 2px 7px; border-radius: var(--r-sm); color: #060609; background: var(--text-hi); box-shadow: inset 0 1px 0 rgba(255,255,255,.5); flex-shrink: 0; }
/* Copy-link affordance on the panel badge (same pattern as .insp-kind.copyable). */
.panel-badge.copyable { cursor: pointer; transition: filter var(--t-fast); }
.panel-badge.copyable:hover { filter: brightness(1.18); }
.panel-badge.copied { color: var(--ok); background: rgba(var(--ok-rgb),.25); box-shadow: inset 0 0 0 1px rgba(var(--ok-rgb),.6), inset 0 1px 0 rgba(255,255,255,.06); }
.panel-head-titles { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.panel-title { font-family: var(--font-display); font-size: 14px; font-weight: 600; color: var(--text-hi); max-width: 220px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.insp-window .panel-title { white-space: normal; text-overflow: clip; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }
.panel-meta { font-size: 11px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.panel-close { background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 18px; line-height: 1; padding: 0 2px; flex-shrink: 0; }
.panel-close:hover { color: var(--text); }
/* HOUSE: the comments floating window. Geometry only here — the panel chrome
   (elevation, header gradient/groove, resize chevron) is shared with the inspector/well/
   well-item windows via the grouped floating-window selectors below (no per-window dup). */
#comments-window { position: absolute; left: 360px; bottom: 220px; width: 340px; height: 380px; border-radius: var(--r-lg); overflow: hidden; z-index: 41; display: flex; flex-direction: column; }
.commentswin-content { flex: 1; min-height: 0; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.commentswin-resize { position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 3; touch-action: none; }
.commentswin-resize::after { content: ""; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px; border-right: 2px solid var(--text-dim); border-bottom: 2px solid var(--text-dim); opacity: .5; }
.commentswin-resize:hover::after { opacity: .8; }
/*  styling pass: the comments thread (hosted in the window above), refreshed to the
    design language using bridged theme tokens — no raw literals. */
/* — comments window conforms to HOUSE: spacing to the inspector's 12px section
   rhythm; rows on the raised-key surface; composer/edit boxes on the recessed-input
   recipe (matching .insp-name / .fuzzy-input) so the thread reads as the same instrument
   as the inspector. The header already says "<name> · comments", so .insp-comments-head
   is only ever a bare count (never the word "Comments") — styled as a quiet count, not a
   redundant section label. */
.insp-comments { display: flex; flex-direction: column; gap: 12px; }
.insp-comments-head { font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: var(--text-dim); letter-spacing: .04em; font-variant-numeric: tabular-nums; }
.insp-comments-head:empty { display: none; }
.insp-comments-list { display: flex; flex-direction: column; gap: 8px; }
.comment-row { background: var(--raised-bg); border: 1px solid #000; border-radius: var(--r-md); padding: 8px 10px; box-shadow: var(--raised); }
.comment-meta { display: flex; align-items: baseline; gap: 6px; font-size: 11px; }
.comment-author { font-weight: 600; color: var(--text-hi); }
.comment-time { color: var(--text-dim); }
.comment-actions { margin-left: auto; display: flex; gap: 4px; }
.comment-edit, .comment-del { background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 12px; padding: 0 3px; line-height: 1; border-radius: var(--r-sm); }
.comment-edit:hover { color: var(--text); background: var(--hover-bg); }
.comment-del:hover { color: var(--danger); background: rgba(var(--red-rgb),.1); }
.comment-body { margin-top: 6px; font: var(--fs-base)/var(--lh-loose) var(--font-mono); color: var(--text); word-break: break-word; }
.comment-body code { background: var(--hover-bg); border-radius: var(--r-sm); padding: 0 3px; font-size: 11px; }
.comment-body strong { font-weight: 700; }
.comment-body em { font-style: italic; }
.comment-body .body-line.empty { min-height: .8em; }
/* Recessed-input recipe (engraved field) — identical to .insp-name / .fuzzy-input. */
.comment-edit-box, .comment-add-box { width: 100%; box-sizing: border-box; resize: vertical; min-height: 52px; background: var(--recess-bg); border: 1px solid #000; border-radius: var(--r-sm); color: var(--text); font: 12px/1.5 var(--font-mono); padding: 7px 9px; outline: none; box-shadow: var(--recess); }
.comment-edit-box:focus, .comment-add-box:focus { border-color: var(--focus-border); }
.comment-edit-actions { display: flex; gap: 6px; margin-top: 6px; }
.comment-add { display: flex; flex-direction: column; gap: 8px; }
/* HOUSE: the add button now wears the inspector `.verb-active` primary; pin flex:none so
   .verb's flex:1 can't stretch it in the comment-add column (deterministic, not space-dependent). */
.comment-add-btn { align-self: flex-start; flex: none; }
.attach-link-badge { font-size: 9px; padding: 1px 5px; border-radius: 8px; background: var(--surface2); border: 1px solid var(--border); color: var(--text-dim); letter-spacing: .04em; flex-shrink: 0; }
.insp-attach-add { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; align-items: center; }
.insp-attach-name { flex: 1; min-width: 0; background: var(--recess-bg); border: 1px solid #000; color: var(--text); border-radius: var(--r-sm); padding: 6px 8px; font-size: 12px; box-shadow: var(--recess); outline: none; }
.insp-attach-name:focus { border-color: var(--focus-border); }
/* the +file / +link attachment buttons wear the neutral raised `.verb` taxonomy.
   Re-scope `.verb`'s action-row sizing (flex:1 / min-width:64 / 9px pad) down so the two
   buttons stay compact and the URL input keeps leading the row (same trick `.comment-add-btn`
   uses to tame `.verb` outside the action row). */
.insp-attach-act { flex: 0 0 auto; min-width: 0; padding: 6px 11px; font-size: 12px; }
/* HOUSE — inspector action row, button taxonomy by intent:
   • base .verb = RAISED neutral key (ghost-ish).  • .verb-active (Start) = the ONE
   solid Tangelo PRIMARY (glows).  • .verb-done = green outline.  • cut/kill/convert =
   ghost.  • .verb-delete-forever = danger ghost, right-isolated (margin-left:auto). */
.insp-verbs { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.verb { flex: 1; min-width: 64px; padding: 9px 8px; border: 1px solid #000; border-radius: var(--r-sm); background: var(--raised-bg); color: var(--text); cursor: pointer; font-size: 12px; box-shadow: var(--raised); }
.verb:hover { filter: brightness(1.3); }
/*  later: disabled verbs (e.g. Close when children aren't all done) visibly
   gray out — they must not hover-brighten or look clickable. */
.verb:disabled { opacity: .35; cursor: default; filter: none; }
.verb-done { border-color: rgba(var(--ok-rgb),.5); background: rgba(var(--ok-rgb),.08); color: var(--ok); box-shadow: none; }
.verb-slip { border-color: rgba(var(--warn-rgb),.5); background: transparent; color: var(--amber); box-shadow: none; }
.verb-cut, .verb-convert { background: transparent; border-color: var(--border-control); color: var(--text); box-shadow: none; }
.verb-cut { color: var(--danger); border-color: rgba(var(--danger-rgb),.4); }
/*  hard-delete: danger ghost, right-isolated so the permanent action can't be
   fat-fingered next to Cut/Kill. */
.verb-delete-forever { margin-left: auto; flex: 0 0 auto; border-color: rgba(var(--danger-rgb),.4); background: transparent; color: var(--danger); font-weight: 600; box-shadow: none; }
.verb-delete-forever:hover { background: rgba(var(--red-rgb),.16); filter: none; }
.verb-reopen { border-color: var(--border-control); background: transparent; color: var(--info); box-shadow: none; }
/* Start / Focus = the single primary Tangelo CTA per context (the one that glows). */
.verb-active { color: var(--primary-ink); background: var(--primary-bg); border: 1px solid var(--primary-border); box-shadow: var(--primary-shadow); font-weight: 600; }
.verb-active:hover { filter: brightness(1.06); }
.verb-active.on { color: var(--primary-ink); background: var(--primary-bg); border-color: var(--primary-border); box-shadow: var(--primary-shadow); }
/* Verb confirmation pulses the (persistent) inspector panel with a brief
   accent ring when any verb fires, acknowledging the action registered. Driven by
   inspector.ts flashVerbConfirm(); robust to the content re-render / verb removal. */
.insp-window.verb-fired { animation: verb-fired .42s ease-out; }
@keyframes verb-fired {
  0%   { box-shadow: var(--lifted), 0 0 0 2px var(--focus); }
  100% { box-shadow: var(--lifted); }
}

/* Auth overlay (passkey login / register) */
#auth-overlay { position: fixed; inset: 0; z-index: 2000; background: rgba(10,10,10,.82); display: flex; align-items: center; justify-content: center; }
.auth-card { width: 320px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 28px 24px; box-shadow: 0 20px 60px rgba(0,0,0,.5); }
.auth-title { font-family: var(--font-display); font-size: 20px; font-weight: 700; letter-spacing: .18em; color: var(--text); }
.auth-sub { font-size: 12px; color: var(--text-dim); margin: 4px 0 18px; }
.auth-handle { width: 100%; background: var(--surface2); border: 1px solid var(--border); color: var(--text); padding: 9px 10px; border-radius: 6px; font-size: 14px; margin-bottom: 12px; }
.auth-handle:focus { outline: none; border-color: var(--accent); }
.auth-row { display: flex; gap: 8px; }
.auth-btn { flex: 1; padding: 9px; border: 1px solid #000; border-radius: var(--r-sm); background: var(--raised-bg); color: var(--text); cursor: pointer; font-size: 13px; box-shadow: var(--raised); }
.auth-btn:hover { filter: brightness(1.3); }
.auth-btn:active { transform: translateY(1px); }
.auth-primary { background: var(--primary-bg); border-color: var(--primary-border); color: var(--primary-ink); font-weight: 600; box-shadow: var(--primary-shadow); }
.auth-status { min-height: 16px; margin-top: 12px; font-size: 12px; color: var(--danger); }

/* Context menu (right-click) */
.ctx-menu { position: fixed; z-index: 1000; min-width: 150px; background: var(--surface2); border: 1px solid var(--border); border-radius: 6px; padding: 4px; box-shadow: 0 8px 28px rgba(0,0,0,.45); display: flex; flex-direction: column; }
.ctx-item { text-align: left; background: none; border: none; color: var(--text); padding: 7px 10px; border-radius: 4px; cursor: pointer; font-size: 13px; }
.ctx-item:hover:not(:disabled) { background: var(--hover-bg); }
.ctx-item:disabled { color: var(--text-dim); cursor: default; }
.ctx-item.ctx-danger { color: var(--danger); }
.ctx-sep { height: 1px; background: var(--border); margin: 4px 2px; }

/* ════════════════════════════════════════════════════════════════════════
 — tactile design pass. Everything below consumes the :root tokens
   (--elev-*, --t-*, --r-*, --sep*, --grad-*). Rules of the system:
    • Elevation = box-shadow tier only. Hover/press/raise change the TIER.
    • Motion is scoped to background/border/box-shadow/opacity/filter — NEVER
      to left/top/width/height/transform on floating windows (would lag drag).
    • Group boundaries use the recessed --sep rule, not a faint 1px line.
   ════════════════════════════════════════════════════════════════════════ */

/* Slim dark scrollbars across panels */
* { scrollbar-width: thin; scrollbar-color: var(--border-control) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: var(--keyline-strong); border-radius: 5px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--border-control); background-clip: padding-box; }
::-webkit-scrollbar-track { background: transparent; }

/* Structural panels — gentle top-lit gradient + a stronger dividing edge so the
   gutter / canvas / summary read as distinct planes, not one flat sheet. */
#gutter   { background: var(--grad-surface); box-shadow: 1px 0 0 rgba(255,255,255,.03); }
#summary  { background: var(--grad-surface); box-shadow: -1px 0 0 rgba(255,255,255,.03); }
#wells-dock { background: var(--grad-header); box-shadow: 0 -6px 18px rgba(0,0,0,.34), inset 0 1px 0 rgba(150,160,210,.06); }
#summary-header, #gutter-ruler { background: linear-gradient(180deg, rgba(255,255,255,.04), transparent); box-shadow: var(--sep-groove); border-bottom-color: var(--sep); }
#topbar { box-shadow: 0 1px 0 rgba(0,0,0,.45), 0 2px 8px rgba(0,0,0,.28); border-bottom-color: var(--sep); }

/* Smooth interactive feedback + keyboard focus rings (geometry-free transition). */
button, input, textarea, select { transition: background-color var(--t-fast), border-color var(--t-fast), filter var(--t-fast), box-shadow var(--t-fast), color var(--t-fast); }
button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, a:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Press affordance: buttons sink 1px and tighten their shadow on active. */
.verb:active, .modal-btn:active, .well-act:active, .wells-dock-new:active, .lane-add:active,
.auth-btn:active, .filter-btn:active, .lane-toggle:active, .undo-redo button:active,
.menu-item:active, .ctx-item:active, .well-card-arrow:active, .hamburger:active { transform: translateY(1px); }

/* ── Floating windows: elevation tiers + focused-window lift ───────────── */
/* Resting windows sit at tier 3; the topmost (.win-top, set by window-manager
   on raise) lifts to tier 4 so "which window is focused" reads instantly.
   Transition only the shadow — position/size stay instant for drag/resize. */
/* HOUSE: all four floating windows (inspector + well + well-item + comments) share the
   lifted Penn-Blue surface + elevation tier. The well-item + comments windows previously
   re-declared background/border/box-shadow per-window; they now inherit it here. */
.insp-window, .well-window, .wellitem-window, #comments-window {
  background: var(--grad-surface);
  border: 1px solid var(--sep);
  box-shadow: var(--elev-3);
  transition: box-shadow var(--t-med), border-color var(--t-med);
}
.insp-window.win-top, .well-window.win-top, .wellitem-window.win-top, #comments-window.win-top { box-shadow: var(--elev-4); }
/* Drag-to-park arm cue keeps its accent ring but on the elevation system. */
.well-window.park-armed { border-color: var(--accent); box-shadow: var(--elev-4), var(--ring-accent-strong); }
/* Window header: a subtle title-bar gradient + a real groove under it, so the
   draggable header reads as a grabbable surface (tactile drag affordance). HOUSE  folds
   the well/well-item/comments heads into the shared `.panel-head` (built by panel-head.ts);
   the inspector keeps its own `.insp-head` (it carries inspector-only sticky-scroll layout). */
.insp-head, .panel-head {
  background: var(--grad-surface2);
  box-shadow: var(--sep-groove);
  border-bottom-color: var(--sep);
}
.insp-head:active, .panel-head:active { filter: brightness(1.08); }
/* inspector header stays put while the body scrolls (scoped to .insp-window — both
   the primary #inspector and Item #14 tail cards; the OTHER windows are flex-columns with
   a non-scrolling `flex-shrink:0` header, so the sticky / negative-margin geometry must
   NOT leak onto their shared `.panel-head`). */
.insp-window .insp-head { position: sticky; top: -12px; margin: -12px -12px 8px; padding: 12px 12px 8px; z-index: 5; }
/* Resize handles: brighten the corner chevron on hover so it invites a drag. */
/*  item 17 — knurled diagonal-hatch resize grip (console-grade, matches the prototype);
   hover lifts the hatch to full opacity (was a chevron whose border-color brightened). */
.insp-resize:hover::after, .wellwin-resize:hover::after, .wellitem-resize:hover::after, .commentswin-resize:hover::after {
  opacity: 1;
}
.insp-resize::after, .wellwin-resize::after, .wellitem-resize::after, .commentswin-resize::after { transition: opacity var(--t-fast); }

/* Modals & menus ride the same tier system. */
.modal-card { box-shadow: var(--elev-4); border-color: var(--sep); }
.menu-pop, .ctx-menu, .ref-pop, .fuzzy-pop { box-shadow: var(--elev-2); border-color: var(--sep); }
.modal-head { background: var(--grad-surface2); box-shadow: var(--sep-groove); border-bottom-color: var(--sep); }

/* Group separators — promote every faint 1px rule to the recessed groove. */
.menu-sep, .ctx-sep { background: var(--sep); box-shadow: 0 1px 0 rgba(255,255,255,.04); }
.manage-section-head { border-top-color: var(--sep); }
.modal-row { border-bottom-color: var(--sep); }
/* Summary category groups: a separated header band, not just colored text. */
.summary-cat { border-top: 1px solid var(--sep); box-shadow: var(--sep-groove); margin-top: 6px; padding-top: 12px; }
.summary-cat:first-child { border-top: none; box-shadow: none; margin-top: 0; }
/* Gutter nested-lane group: a clearer tinted band + a left accent spine so a
   sequence's child lanes read as a visually grouped block. */
.lane-header.lane-nested { background: rgba(var(--seq-rgb),.08); box-shadow: inset 2px 0 0 var(--seq); }

/* Dock cards: resting tier-1, hover lifts to tier-2 (tactile pop), open/armed
   carry the accent ring. */
.well-card { box-shadow: var(--elev-1); transition: border-color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast); }
.well-card:hover { box-shadow: var(--elev-2); transform: translateY(-1px); }
.well-card:active { transform: translateY(0); box-shadow: var(--elev-1); }
.well-card.open { box-shadow: var(--elev-2), var(--ring-accent); }
.well-card.park-armed { box-shadow: var(--elev-2), var(--ring-accent-strong); }

/* Pills: a hair of elevation, lifting on hover; grab feels liftable. */
.well-pill { box-shadow: var(--elev-1); transition: border-color var(--t-fast), box-shadow var(--t-fast), opacity var(--t-fast); }
.well-pill:hover { box-shadow: var(--elev-2); border-color: var(--accent-dim); }
.well-pill:active { box-shadow: var(--elev-1); }

/* HOUSE — filter pills are GHOST on the header (no resting elevation); the active
   white cap reads as a pressed physical key via a top highlight + inset settle. */
.wells-dock-new { box-shadow: var(--raised); }
/* item 14 — engaged top-cluster key = a quiet PRESSED recess (was a bright white-cap bevel). */
.filter-btn.active, #filter-mode.on { box-shadow: inset 0 2px 5px rgba(0,0,0,.45), inset 0 1px 0 rgba(150,160,210,.06); }

/* ── — tabular numerals on the date/day/count surfaces ──────────────────
   Monospaced figures so columns of dates, day-counts and stat numbers line up
   and don't jitter as digits change. Static glyph selection (no layout/paint
   cost on update). Inspector date meta, summary detail counts, review date
   inputs/cells, the management stat grid, and the well item counts opt in. */
.insp-meta-dates, .insp-meta-note, .summary-detail, .manage-stat-num,
.review-date, .review-cell, .well-card-count,
#gutter-ruler, #user-chip { font-variant-numeric: tabular-nums; }

/* ── Respect prefers-reduced-motion ─────────────────────────────────────
   Collapse every CSS transition + keyframe animation to instant for users who
   ask for reduced motion. The depth/elevation language (shadows, gradients)
   stays — only the MOTION is removed. The WebGL kinetic effects (marching-ants,
   hover breathing, rake pulse) honor the same query in scene.ts. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/*  (LOCKED the specification): prefers-contrast:more bumps the day-rule alpha to .07 (day
   boundaries only). The WebGL canvas mirrors this in scene.ts (_contrastMore → the
   shader's rule alpha); this keeps the DOM --tl-rule token consistent for any DOM well
   chrome that consumes it. The lane-band (--tl-band) intentionally stays subordinate. */
@media (prefers-contrast: more) {
  :root { --tl-rule: rgba(150,168,214,.07); }
}
/* ──  Activity: bell + unread badge, live-toast stack, change-feed dropdown ──────────
   All HOUSE tokens (navy raised surfaces + Tangelo signal). The toast/feed are VIEWS over
   the server feed_events log — no new color authority, reusing --ok/--warn/--tangelo for the
   three derived states (done = ok green, slipped = warn amber, unblocked = tangelo signal). */
#activity-bell, #project-links-btn {
  position: relative; width: 30px; height: 30px; flex: 0 0 auto; padding: 0;
  border: 1px solid #000; border-radius: var(--r-sm); cursor: pointer;
  background: var(--raised-bg); box-shadow: var(--raised);
  color: var(--text-mut); font-size: 15px; line-height: 1;
}
#activity-bell::before { content: "\1F514"; } /* 🔔 */
#project-links-btn { font-family: var(--font-display); font-weight: 700; font-style: italic; }
#activity-bell:hover, #project-links-btn:hover { color: var(--text-hi); }
#activity-bell:focus-visible, #project-links-btn:focus-visible { outline: 1px solid var(--tangelo); outline-offset: 2px; }
#activity-bell[aria-expanded="true"], #project-links-btn[aria-expanded="true"] { color: var(--text-hi); box-shadow: var(--recess); }
#activity-badge {
  position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px; padding: 0 4px;
  box-sizing: border-box; border-radius: 8px; background: var(--tangelo); color: #2a0f06;
  font-family: var(--font-mono); font-size: 10px; font-weight: 700; line-height: 16px;
  text-align: center; box-shadow: var(--glow-tangelo); pointer-events: none;
}

/* Toast stack — fixed top-right, above the floating-window band (40–49), at topbar z. */
#toast-stack {
  position: fixed; top: 56px; right: 14px; z-index: 50;
  display: flex; flex-direction: column; gap: 8px; width: 280px; pointer-events: none;
}
.toast {
  pointer-events: auto; cursor: pointer;
  background: var(--lifted-bg, var(--raised-bg)); border: 1px solid #000;
  border-left: 3px solid var(--text-mut); border-radius: var(--r-sm);
  box-shadow: var(--lifted); padding: 9px 11px;
  opacity: 0; transform: translateY(-6px); transition: opacity var(--t-med), transform var(--t-med);
  animation: toast-in var(--t-med) ease forwards;
}
.toast-out { opacity: 0 !important; transform: translateY(-6px) !important; }
@keyframes toast-in { to { opacity: 1; transform: translateY(0); } }
.toast-title { font-size: 12px; color: var(--text); }
.toast-title b { color: var(--text-hi); font-weight: 600; }
.toast-sub { font-size: 10px; color: var(--text-dim); margin-top: 2px; }
.toast.toast-track-done { border-left-color: var(--ok); }
.toast.toast-track-slipped { border-left-color: var(--warn); }
.toast.toast-track-reopened { border-left-color: rgba(var(--amber-rgb),.5); }
.toast.toast-track-unblocked { border-left-color: var(--tangelo); }
/* item 4 — lifecycle event accents. */
.toast.toast-track-created { border-left-color: var(--info); }
.toast.toast-track-cut { border-left-color: var(--danger); }
.toast.toast-track-killed { border-left-color: var(--bet); }
.toast.toast-track-converted { border-left-color: var(--link); }
.toast.toast-comment-added { border-left-color: var(--cyan); }
.toast.toast-well-capture { border-left-color: var(--cyan); }

/* Change-feed dropdown — anchored under the topbar near the bell. */
#activity-panel {
  position: fixed; top: 52px; right: 14px; z-index: 51; width: 300px; max-height: 60vh;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 12px 36px rgba(0,0,0,.55);
}
/*  item 5 — the bell toggles via `panel.hidden`, but the ID rule above sets
   `display:flex`, which OUTRANKS the UA `[hidden]{display:none}` (specificity), so a
   second bell click set hidden=true but the panel stayed visible. Make `hidden` win for
   this panel (same idiom the filter chip uses with `:not([hidden])`). */
#activity-panel[hidden] { display: none; }
.activity-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 11px; border-bottom: 1px solid var(--border);
}
.activity-title { font-family: var(--font-display, var(--font-mono)); font-size: 13px; font-weight: 600; color: var(--text-hi); letter-spacing: .04em; }
.activity-seg { display: flex; }
.activity-tab {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em; padding: 3px 9px;
  background: var(--recess-bg); border: 1px solid #000; color: var(--text-dim); cursor: pointer;
}
.activity-tab:first-child { border-radius: var(--r-pill) 0 0 var(--r-pill); }
.activity-tab:last-child { border-radius: 0 var(--r-pill) var(--r-pill) 0; margin-left: -1px; }
.activity-tab.active { background: var(--text-hi); border-color: var(--text-hi); color: #060609; font-weight: 600; }
.activity-list { overflow-y: auto; padding: 4px 0; }
.activity-empty { padding: 18px 12px; text-align: center; color: var(--text-dim); font-size: 12px; }
.activity-row {
  padding: 8px 11px; border-left: 3px solid transparent; border-bottom: 1px solid rgba(0,0,0,.35);
}
.activity-row:last-child { border-bottom: none; }
.activity-row.activity-track-done { border-left-color: var(--ok); }
.activity-row.activity-track-slipped { border-left-color: var(--warn); }
/* reopen is informational — a quiet muted-amber tint (not the full --amber/--warn used by
   slipped, so the two stay distinct). */
.activity-row.activity-track-reopened { border-left-color: rgba(var(--amber-rgb),.5); }
.activity-row.activity-track-unblocked { border-left-color: var(--tangelo); }
/* item 4 — lifecycle event accents (match the toast set). */
.activity-row.activity-track-created { border-left-color: var(--info); }
.activity-row.activity-track-cut { border-left-color: var(--danger); }
.activity-row.activity-track-killed { border-left-color: var(--bet); }
.activity-row.activity-track-converted { border-left-color: var(--link); }
.activity-row.activity-comment-added { border-left-color: var(--cyan); }
.activity-row.activity-well-capture { border-left-color: var(--cyan); }
.activity-row-main { font-size: 12px; color: var(--text); }
.activity-row-main b { color: var(--text-hi); font-weight: 600; }
.activity-row-meta { font-size: 10px; color: var(--text-dim); margin-top: 2px; }
/* Clickable feed rows jump to their subject (track / well-item). Name wears the cool HOUSE
   link ink (mirrors .ref-chip.ref-track); hover lifts the whole row. Dangling subjects are
   non-clickable + dimmed (mirrors .ref-chip.ref-dangling). */
.activity-row-clickable { cursor: pointer; }
.activity-row-clickable:hover { background: rgba(var(--link-rgb),.08); }
.activity-row-clickable .activity-row-link { color: var(--link); }
.activity-row-clickable:hover .activity-row-link { text-decoration: underline; }
.activity-row-dangling { opacity: .55; }
/* "Clear all" — quiet raised key in the panel header (same taxonomy as .manage-btn, shrunk). */
.activity-clear {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em; padding: 3px 8px;
  margin-left: 8px; background: var(--raised-bg); border: 1px solid #000; color: var(--text-dim);
  border-radius: var(--r-sm); cursor: pointer; white-space: nowrap; box-shadow: var(--raised);
}
.activity-clear:hover { filter: brightness(1.3); color: var(--text); }

/* ════════════════════════════════════════════════════════════════════════════
   BODY-EDITOR EXPAND OVERLAY — pop the shared live-preview markdown editor into a
   centered, dimmed modal. Reuses .modal-overlay (dim + z-index band) but re-centers
   and enlarges. The editor node itself is REPARENTED in (not re-instantiated), so
   .insp-body.expanded just needs to fill the card and let .insp-body-live scroll.
   ════════════════════════════════════════════════════════════════════════════ */
.body-expand-overlay { align-items: center; padding: 5vh 4vw; }
.body-expand-card {
  display: flex; flex-direction: column;
  width: min(80vw, 900px); height: min(84vh, 760px); max-width: 100%;
  background: var(--grad-surface); border: 1px solid var(--keyline-strong);
  border-radius: var(--r-lg); box-shadow: var(--lifted); overflow: hidden;
  animation: body-expand-in .16s ease-out;
}
@keyframes body-expand-in { from { opacity: 0; transform: translateY(6px) scale(.985); } to { opacity: 1; transform: none; } }
.body-expand-head {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--keyline-strong);
  box-shadow: inset 0 1px 0 rgba(150,160,210,.10);
}
.body-expand-title {
  font-family: var(--font-display); font-size: 15px; font-weight: 600; color: var(--text);
  letter-spacing: .01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.body-expand-collapse {
  flex: 0 0 auto; background: var(--raised-bg); border: 1px solid #000; color: var(--text-dim);
  border-radius: var(--r-sm); font-size: 12px; line-height: 1; padding: 6px 10px; height: 28px;
  cursor: pointer; box-shadow: var(--raised); white-space: nowrap;
}
.body-expand-collapse:hover { color: var(--text); border-color: var(--accent-dim); }
.body-expand-collapse:active { transform: translateY(1px); }
/* The reparented editor fills the card and gives the live area all the slack. */
.body-expand-card .insp-body.expanded { flex: 1; min-height: 0; border-top: none; padding: 14px 16px; }
.body-expand-card .insp-body.expanded .insp-body-live { flex: 1; min-height: 0; font-size: var(--fs-base); }
/* Toolbar expand affordance — mirrors the Preview toggle recipe (line ~1325). */
.insp-body-expand {
  margin-left: 6px; font-size: 12px; line-height: 1; padding: 2px 7px; border: 1px solid #000;
  border-radius: var(--r-sm); background: var(--raised-bg); color: var(--text-dim);
  cursor: pointer; box-shadow: var(--raised);
}
.insp-body-expand:hover { color: var(--text); border-color: var(--accent-dim); }
.insp-body-expand:active { transform: translateY(1px); }

/* Move item chip (meta row in well-item editor) — styled like well-status-chip but as a button */
.well-move-chip { background: transparent; border: none; padding: 2px 7px; border-radius: var(--r-sm); cursor: pointer; font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text); transition: color var(--t-fast), background var(--t-fast); }
.well-move-chip:hover { color: var(--accent); background: var(--accent-dim); }
.well-move-chip:focus-visible { outline: 1px solid var(--accent); }

/* Quick move button (hover-revealed on item row) — small icon button */
.well-move-btn { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; background: transparent; border: none; color: var(--text-dim); cursor: pointer; font-size: 12px; border-radius: var(--r-sm); transition: color var(--t-fast), background var(--t-fast); }
.well-move-btn:hover { color: var(--accent); background: var(--raised-bg); }
.well-move-btn:focus-visible { outline: 1px solid var(--accent); }

/* Drop-target highlight for well windows and cards during drag */
.well-window.drop-target { background-color: var(--accent-dim); }
.well-card.drop-target { background-color: var(--accent-dim); }


/* ════════════════════════════════════════════════════════════════════════════
   MOBILE VIEWER MODE — read-only mobile interface (body.mobile scoped).
   Timeline full-bleed, bottom-sheet modals, collapsed gutter, minimal topbar.
   TS injects .mobile on <body> at boot and toggles .wells-open when sheet opens.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Full-bleed timeline layout: hide summary, collapse gutter ────────────── */
body.mobile #summary { display: none; }
body.mobile #gutter { width: 60px; min-width: 60px; max-width: 60px; }
body.mobile #gutter-ruler span { display: none; }  /* Hide "LANES" label */
body.mobile #gutter-lanes { font-size: var(--fs-2xs); }  /* Truncate lane labels */
body.mobile #gutter-lanes > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.mobile #gutter-lanes .lane-header { min-width: 0; overflow: hidden; }
body.mobile #gutter-lanes .lane-name,
body.mobile #gutter-lanes .group-name,
body.mobile #gutter-lanes .group-roster {
  min-width: 0; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Topbar: keep logo, project name, search; hide the rest ──────────────── */
body.mobile #transport { display: none; }
body.mobile #activity-bell { display: none; }
body.mobile #project-links-btn { display: none; }
body.mobile #user-chip { display: none; }
body.mobile .topbar-divider { display: none; }
body.mobile #topbar-spacer { display: none; }
body.mobile #filter-bar { flex: 1; min-width: 0; }  /* Let search expand */
body.mobile #filter-seg,
body.mobile #tag-filter-btn,
body.mobile #filter-chip { display: none; }          /* My work / @ / # chips overflow the narrow topbar */
body.mobile #search-box { width: 100%; min-width: 0; }

body.mobile button:disabled {
  color: var(--text-dim) !important;
  background: var(--raised-bg) !important;
  border-color: #000 !important;
  box-shadow: var(--raised) !important;
  opacity: .45;
  filter: grayscale(1) saturate(.35);
  cursor: default;
}

/* ── Mobile toolbar: fixed bottom bar with icon buttons ───────────────────── */
body.mobile #mobile-toolbar {
  position: fixed; left: 0; right: 0; bottom: 0;
  height: 54px; padding-bottom: env(safe-area-inset-bottom);
  background: var(--grad-header); border-top: 1px solid #000;
  box-shadow: inset 0 1px 0 rgba(150,160,210,.14), 0 -1px 0 rgba(0,0,0,.6);
  z-index: 39; display: flex; align-items: center; justify-content: space-around;
  gap: 4px; padding-left: 4px; padding-right: 4px;
}
body.mobile .mtb-item {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  flex: 1; min-width: 0;
}
body.mobile .mtb-btn {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; font-size: 18px; line-height: 1;
  background: var(--raised-bg); border: 1px solid #000; border-radius: var(--r-sm);
  color: var(--text); cursor: pointer; box-shadow: var(--raised);
  transition: color var(--t-fast), background var(--t-fast);
}
body.mobile .mtb-btn:active { transform: translateY(1px); }
body.mobile .mtb-label {
  font-family: var(--font-mono); font-size: var(--fs-2xs); letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-dim); text-align: center; line-height: 1;
}

/* ── Canvas bottom padding for toolbar clearance (optional; sheet overlay is fine) ── */
body.mobile #canvas-wrap { padding-bottom: 54px; }

/* ── Floating windows as bottom sheets (z-index ≥ 44) ────────────────────── */
/* All floating window types (inspector, well, well-item, comments) become bottom sheets. */
body.mobile .fl-sheet {
  position: fixed !important; left: 0 !important; right: 0 !important;
  bottom: 0 !important; top: auto !important;
  max-height: 85vh !important; width: 100% !important;
  border-radius: 12px 12px 0 0 !important;
  overflow-y: auto !important; z-index: 44 !important;
}

/* Override inspector geometry: desktop CSS pins it to top/right; sheet must override. */
body.mobile #inspector.fl-sheet {
  display: block !important; width: 100% !important; height: auto !important;
  bottom: 0 !important; left: 0 !important; right: 0 !important; top: auto !important;
}

/* Hide all resize handles on mobile sheets. */
body.mobile .insp-resize,
body.mobile .wellwin-resize,
body.mobile .wellitem-resize,
body.mobile .commentswin-resize,
body.mobile .fl-resize-e,
body.mobile .fl-resize-w,
body.mobile .fl-resize-s {
  display: none;
}

/* ── Wells sheet: fixed bottom sheet above toolbar, below floating sheets ─────────── */
body.mobile #wells-dock {
  display: none !important;
  height: 0 !important;
  visibility: hidden;
  pointer-events: none;
}
body.mobile.wells-open #wells-dock {
  position: fixed !important; left: 0 !important; right: 0 !important;
  bottom: calc(54px + env(safe-area-inset-bottom)) !important;
  height: min(68vh, calc(100vh - 54px - env(safe-area-inset-bottom) - 48px)) !important;
  max-height: 70vh !important;
  background: var(--grad-header) !important; border-top: 1px solid #000 !important;
  box-shadow: inset 0 1px 0 rgba(150,160,210,.1), 0 -3px 12px rgba(0,0,0,.3) !important;
  border-radius: 12px 12px 0 0 !important;
  overflow: hidden !important; display: flex !important; flex-direction: column !important;
  visibility: visible; pointer-events: auto; z-index: 40 !important;
}
body.mobile.wells-open #wells-dock .wells-dock-bar { flex-shrink: 0; }
body.mobile.wells-open #wells-dock .wells-dock-body {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  margin: 0 10px 10px;
}

/* Read-only viewer: hide create affordances that overflow or imply editing. */
body.mobile .wells-dock-new,
body.mobile .lane-add,
body.mobile .wellwin-add,
body.mobile .ref-pop-create {
  display: none !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Touch target rule (GLOBAL — outside body.mobile).
   Ensure interactive chrome meets 44px min touch size on coarse-pointer devices. ═════════ */
@media (pointer: coarse) {
  #mobile-toolbar .mtb-btn, .filter-btn, .tp-btn, .tp-toggle, #mobile-wells-btn {
    min-height: 44px; min-width: 44px;
  }
}
