/* ============================================================
   Extensis Worx — Main Stylesheet
   macOS Finder-inspired design
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* Surface palette — themable via [data-theme="dark"] override below */
  --bg:          #f5f5f5;
  --cck-canvas:  #e6eaf2;   /* toned canvas behind cockpit viewer panels */
  --surface:     #ffffff;
  --surface-0:   #ffffff;   /* elevated base surface — popovers, inputs, cards (must be opaque) */
  --surface-2:   #ebebeb;   /* pane-toolbar, dupes-report header, breadcrumb */
  --surface-3:   #f0f4fa;   /* light blue subhead bands (was hard-coded) */
  --row-odd:     #ffffff;
  --row-even:    #f5f5f7;   /* gentle zebra — rows separate without borders */
  --border:      #e0e0e0;
  /* FR-2b — fundraising funnel data-vis palette (the PO-approved v9 artefact).
     Sequential one-hue bands + rose decline family + amber overrun; constant
     across themes for now (chart surfaces stay light). */
  --fr-early: #a9c9ee; --fr-early-ink: #173156; --fr-mid: #5b8fd6; --fr-deep: #2b579e;
  --tk-bug: #c4534b; --tk-feat: #2e9e63;   /* R12-1: option-C kind markers (rust bug / green feature) */
  --fr-rose-0: #dd8a86; --fr-rose-1: #e6a5a1; --fr-rose-2: #eec0bd; --fr-rose-3: #f6dbd9;
  --fr-agbar: #8fb5e8; --fr-tick: #3f5d76; --fr-amber: #f0b429; --fr-arrow: #8a94a0;
  --fr-cluster: rgba(43, 87, 158, 0.85);
  --fr-ink-on: #ffffff; --fr-rose-chip: #f9e9e8;
  --border-dark: #c8c8c8;
  /* Dotted-line / source-rectangle colour for the audit walk-through.
     Mid-tone slate so it's clearly visible on white surfaces without
     becoming a heavy ink line. Dark mode override below. */
  --connector-stroke: #7a8497;
  --text:        #1a1a1a;
  --text-dim:    #666666;   /* P5.1: AA on every house surface incl. the #e5e7eb chips (4.64) — was #6b6b6b (4.47 on surface-2) */
  --text-faint:  #686868;   /* P5.1: was #aaa (2.32:1 — failed AA everywhere it carried words); 5.57 on --surface, 4.88 on #eef0f4. The faint/dim hierarchy now rides size/weight. */
  --accent:      #0078d4;
  --accent-hover:#006cbd;
  --row-hover:   #e8f4fd;
  --row-sel:     #cce4f6;
  /* New chrome / menu / hover / tooltip tokens (Iris Brief #1, 2026-05-17).
     Light values preserved bit-for-bit from current behaviour; dark
     overrides below fix the "horrible bright menus and footers" issue. */
  --pane-chrome-bg:  #f5f6f8;   /* status-bar, pane-toolbar, pane-footer — matched to the inspector panel tone (Jeremy 2026-06-27) */
  --footer-border:   #c8c8c8;   /* pane-footer top, status-bar top */
  --menu-bg:         #ffffff;   /* context-menu, overflow menus */
  --menu-border:     #c8c8c8;
  --hover-soft:      #e4e4e4;   /* toolbar btn hover, dupe-chip hover */
  --tooltip-bg:      #1e293b;
  --tooltip-text:    #f8fafc;
  /* Brief #2 tokens (Iris, 2026-05-17 — toolbar + login identity reskin).
     Light values preserved bit-for-bit; dark overrides retune for contrast. */
  --chrome-bg:           #ebebeb;
  --chrome-border:       #c8c8c8;
  --chrome-tint-diff:    rgba(124, 58, 237, 0.08);
  --chrome-rule-diff:    var(--diff-unique);
  --chrome-pulse-start:  rgba(124, 58, 237, 0.55);
  --chrome-pulse-end:    rgba(124, 58, 237, 0);
  --cluster-label:       var(--text-faint);
  --badge-bg:            var(--danger);
  --badge-fg:            #ffffff;
  --pill-off-bg:         #f1f1f1;
  --pill-off-fg:         #9a9a9a;
  --pill-off-border:     #d8d8d8;
  --app-icon-fg:         var(--accent);
  --warn-soft-bg:        #fff3e8;
  --danger-soft-bg:      #fff0f0;
  --login-bg-from:       var(--accent);
  --login-bg-to:         #003a66;
  --login-bg-glow:       rgba(255,255,255,0.10);
  --login-card-bg:       #ffffff;
  --login-card-shadow:   0 24px 60px rgba(0,0,0,.30), 0 2px 6px rgba(0,0,0,.18);
  --login-logo-plate:    linear-gradient(135deg, #e8f1fc 0%, #dbe9f7 100%);
  --login-logo-ring:     transparent;
  --login-tagline-fg:    #6b7280;
  --login-note-fg:       #9ca3af;
  --hover-soft-tree:     #f0f4ff;       /* neutral cool-leaning tree-adjacent hover */
  --hover-soft-tint:     #d0e4fd;       /* deeper blue hover for chat-suggestion family */
  --btn-secondary-hover: #f0f0f0;
  --btn-tertiary-bg:     #f4f4f4;
  --btn-tertiary-hover:  #e8e8e8;
  --tree-header-bg:      linear-gradient(to bottom, #f0f0f0 0%, #e6e6e6 100%);
  --tree-header-rule:    #c0c0c0;
  --tree-header-divider: #c8c8c8;
  --tree-header-fg:      #444444;

  --warn:        #dc6f14;
  --warn-text:   #a85506;   /* P5.1: amber AS TEXT on plain surfaces (5.29:1) — --warn itself stays the graphic/chip tone */
  --danger:      #c7291e;
  --danger-text: #c7291e;   /* P5.1: red AS TEXT — identical in light; dark lifts it (the fill red is 2.7:1 on dark surfaces) */
  --danger-hover:#a8201a;
  --success:     #107c10;
  --success-text:#107c10;   /* P5.1: green AS TEXT — identical in light; dark lifts it */
  /* Cockpit visual language — Extensis brand + Mercury feel (DESIGN_LANGUAGE.md).
     Brand palette: deep navy ink, vivid cobalt accent, cool grey, off-white.
     Calm/light Mercury feel; hairline structure. Tile tokens keep legacy names
     but now carry cool brand tints. Dark re-tune in the dark :root. */
  --cck-page:        #eef0f4;   /* cockpit page wash — white cards pop against it */
  --cck-hero-bg:     #ffffff;   /* hero is a clean white card */
  --cck-hero-text:   #1b2333;   /* deep navy ink — headlines / numbers */
  --cck-hero-sub:    #5c6473;   /* cool muted subtext */
  --cck-accent:      #0f6cbd;   /* Microsoft blue — the brand accent */
  --cck-accent-on:   #ffffff;   /* text on the blue fill */
  --cck-accent-soft: #e8f1fb;   /* pale blue fill — secondary, Only-you */
  --cck-positive:    #2f8f6b;   /* gains (financial convention) */
  --cck-tile-lav:    #e8f1fb;  --cck-tile-lav-fg:   #0f6cbd;  /* email — pale blue */
  --cck-tile-blue:   #e9edf3;  --cck-tile-blue-fg:  #1b2333;  /* meeting — cool grey */
  --cck-tile-mint:   #eef0f4;  --cck-tile-mint-fg:  #0f6cbd;  /* deal — grey + blue */
  --cck-tile-peach:  #eef0f4;  --cck-tile-peach-fg: #5c6473;  /* filing — grey */
  /* Locked-2026-05-17 colour grammar tokens — single source of truth so
     identical-red and similar-orange-amber can't drift across surfaces. */
  --dupe-identical:       #b91c1c;
  --dupe-identical-deep:  #7f1d1d;   /* hover / dupe-current */
  --dupe-similar:         #ea7c1c;
  --dupe-similar-deep:    #c2560a;   /* hover / dupe-current */
  /* Iris pills-rework 2026-06-22 §2.1: Standard-grey now has a named home
     (was a hard-coded #6b7280 literal at .chip-pill-standard). Completes the
     red/amber/grey colour-grammar trio so the new dupe filter chips read from
     a token, not a literal. Dark variant in :root[data-theme="dark"] below. */
  --dupe-standard:        #6b7280;
  --diff-unique:          #7c3aed;

  /* ── Otto mover — file-type icon colours (Iris master-design §D.1) ──
     The five --ftype-* tokens are DERIVED from existing palette colours via
     var() aliasing — zero new raw hex. Because each alias resolves the
     underlying token at use-time, they follow the light/dark value of their
     source token automatically (e.g. --ftype-other tracks --text-dim, which
     differs per theme). Used only as a 14px glyph-on-surface in the mover tree
     (§C.3.3).

     WCAG CONTRAST MATRIX (Iris A1 owed item; glyph-graphic floor = 3:1 per §D.1).
     Ratios = glyph colour vs --surface (the window bg the icons sit on), measured
     live from the resolved tokens in both themes:
       --ftype-doc   (--accent)       light 4.53:1 ok   dark 5.40:1 ok
       --ftype-sheet (--success)      light 5.37:1 ok   dark 3.15:1 ok
       --ftype-slide (--warn)         light 3.32:1 ok   dark 5.09:1 ok
       --ftype-image (--diff-unique)  light 5.70:1 ok   dark 2.97:1 FAIL (0.03 under 3:1)
       --ftype-other (--text-dim)     light 5.33:1 ok   dark 5.53:1 ok
     ! --ftype-image on the dark --surface is 2.97:1 — a hairline (0.03) below the
     3:1 glyph floor. FLAGGED TO IRIS: brighten --diff-unique ~3% for dark, or mint
     a dark-mode --ftype-image alias. It's a decorative type-icon (not the sole
     carrier of meaning — filename + folder icon also identify the file), so a
     low-severity nit, not a blocker; noted honestly per "no token lands without
     its matrix row."
       Documents  → --accent       (file-text)
       Sheets     → --success      (file-spreadsheet)
       Slides     → --warn         (file, tinted)
       Images     → --diff-unique  (image)
       Archives   → --text-dim     (file) */
  --ftype-doc:    var(--accent);
  --ftype-sheet:  var(--success);
  --ftype-slide:  var(--warn);
  --ftype-image:  var(--diff-unique);
  --ftype-other:  var(--text-dim);
  /* Row/icon sizing — Settings Appearance control (§C.4.2). Default 16px;
     the Settings slider (Batch A2+) drives 16/22/28/large. Consumed by the
     mover tree icons today; tree + inspector adopt it in the Settings batch. */
  --row-icon-size: 16px;
  /* Row TEXT size — filenames + every attribute column. Driven by the same
     Settings slider as the icon (settings.js writes it: text ≈ icon − 3, the
     macOS Finder proportion of 13pt text against a 16px icon). */
  --row-text-size: 13px;

  /* Otto motion-speed multiplier (Settings §C.4.2 / §D.2). 1 = as-built; 2× =
     half the time, 0.5× = double. Set on <html> by settings.js from
     Settings.motionSpeed(); the otto animation rules divide their base duration
     by this. Default 1 so a fresh load plays at the authored speed. */
  --otto-speed: 1;

  --toolbar-h:   37px;   /* matches the rendered toolbar (28px buttons + 8px padding + 1px border); was 44px, which left a 7px gap above the fixed inspector (Jeremy 2026-06-22) */
  --statusbar-h: 26px;
  --pane-head-h: 28px;
  --col-head-h:  26px;
  --row-h:       22px;   /* icon 16 + 6 (macOS Finder proportion); settings.js overrides live */
  --compare-h:   340px;
  --radius:      6px;
  /* Capsule radius for pills (filter chips + row action pills). Justified
     2026-06-27: unifies the AI-cleanup pill shape with the existing toolbar
     dup-filter pills (Identical/Similar/Unique), which are already capsule —
     one pill language across the app (Jeremy-approved redesign). */
  --radius-pill: 999px;
  --radius-panel: 12px;   /* soft grouped panels (macOS-Settings style) */
  /* Soft toned panel fill for grouped content cards in the inspector
     (audit dock + proposal list). A light tone on the white inspector base,
     mirroring macOS System Settings groups. */
  --panel-fill:   #f5f6f8;
  /* Layered shadow — flat 1-px lift plus a soft drop for elevation */
  --shadow:      0 1px 2px rgba(0,0,0,.06), 0 12px 32px rgba(0,0,0,.22);

  /* ── Brief #3 v2 — Phase 3D / 3D-bis tokens (Iris spec §1, 2026-05-18) ──
     Subset minted for the toast + confirm-modal patterns. Remaining
     §1 tokens (--chip-bg family, --row-progress-bar, --skeleton-*) are
     minted by Phase 3B/3C consumers. Light values in :root, dark in
     :root[data-theme="dark"] below. Spec-locked — do not hand-edit. */
  --motion-easing:        cubic-bezier(0.2, 0, 0, 1);
  --motion-duration:      200ms;
  /* P4.2 motion vocabulary (design-system §6): three duration tiers on the ONE
     easing. --motion-micro = hover/active/focus feedback; --motion-duration =
     entrances (toasts/modals/panels); --motion-structural = FLIP re-sorts +
     large layout moves (the Jeremy-approved 480ms Tidy-Up glide). The Otto
     flight/walk choreography keeps its own --otto-speed-scaled set. */
  --motion-micro:         120ms;
  --motion-structural:    480ms;
  --elev-1: 0 1px 2px rgba(15,18,22,0.06), 0 1px 3px rgba(15,18,22,0.08);
  --elev-2: 0 4px 12px rgba(15,18,22,0.10), 0 2px 6px rgba(15,18,22,0.06);
  --warning-chip-bg: #fef3c7;
  --warning-chip-fg: #92400e;
  --btn-danger-bg:   #c0392b;
  --btn-danger-hover:#a02820;
  --neutral-soft-bg: #f0f0f0;
  --neutral-soft-fg: #555555;
  --scrim:           rgba(15,18,22,0.45);
  /* Phase 3C tokens (Iris §1, minted 2026-05-19 batch 20).
     Chip family covers .dupe-chip / .chip-pill / .audit-chip / .naming-chip /
     .history-chip / .tb-chip. Progress + skeleton tokens for the audit bar +
     chat-stream skeleton + smart-move queue progress. Dupe-glyph tokens are
     the WCAG carve-out per §1 row 8 — glyph-on-dark needs ≥4.5:1, the bright
     #dc2626 fixes the 2.97:1 hole on dark surface. */
  --chip-bg:               #e5e7eb;
  --chip-bg-active:        #cfdcec;
  --chip-fg:               #374151;
  --row-progress-bar:      #3b82f6;
  --row-progress-track:    #e5e7eb;
  --skeleton-base:         #e5e7eb;
  --skeleton-shimmer:      #f5f5f5;
  --dupe-identical-glyph:  #dc2626;   /* brighter red — used for folder text + glyph; WCAG-AA on white (5.74:1) */
  --dupe-similar-glyph:    #ea7c1c;   /* same as light pill */
  /* Iris brief-10 §Token discipline: 4 new action-pill colour families for
     the AI Cleanup row redesign (Item §3). MOVE = info, RENAME = reuse
     warning-chip family, DELETE = danger, MERGE = indigo. NEW (inbox row)
     reuses MOVE/info family — "look at this, no destructive intent". All
     pairs pass AA 4.5:1 contrast at 12/600 (matrix in brief-10). */
  --action-pill-info-bg:    #dbeafe;
  --action-pill-info-fg:    #1e40af;
  --action-pill-warn-bg:    var(--warning-chip-bg);
  --action-pill-warn-fg:    var(--warning-chip-fg);
  --action-pill-danger-bg:  #fee2e2;
  --action-pill-danger-fg:  #b91c1c;
  --action-pill-merge-bg:   #e0e7ff;
  --action-pill-merge-fg:   #4338ca;
  /* Iris brief-14 §B.2 mint — CHECK pill (cyan family). 5.46:1 contrast,
     PASS AA normal + AAA large. Distinct from INFO (#dbeafe) and
     MERGE (#e0e7ff) by ~12-16 ΔE. */
  --action-pill-check-bg:   #cffafe;
  --action-pill-check-fg:   #0e7490;
  /* Otto in-tree filing (Iris otto-intree-spec §6) — derived washes/halo, zero
     new raw hex. amber = the problem (from), accent = the answer (to). The 3px
     bars do the contrast work; these tints are decorative. color-mix is
     in-target (Chrome). Dark variants in :root[data-theme="dark"] below. */
  --otto-src-wash:  color-mix(in srgb, var(--warn) 12%, var(--surface));
  --otto-dest-wash: color-mix(in srgb, var(--accent) 12%, var(--surface));
  --otto-dest-halo: color-mix(in srgb, var(--accent) 55%, transparent);
  --otto-path-wash: color-mix(in srgb, var(--accent) 4%, var(--surface));
  /* App font — Settings drives --app-font (default = the OS system font: San
     Francisco on macOS via -apple-system, Segoe UI on Windows). */
  --app-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  font-family: var(--app-font);
  /* Tabular numerals for the whole app — counts, sizes, percentages all line up */
  font-feature-settings: "tnum" 1;

  /* ── P1.9 token migration (B4, 2026-07-11) — tokens minted for values that
     already recurred in component rules; zero new colours invented. Each
     carries its reason; dark pairs in :root[data-theme="dark"] below.
     Recorded in design-system.md §3.12. ── */
  --on-solid:        #ffffff;   /* text/glyph on saturated solid fills (accent/danger/navy) — stays white in dark because the fill stays saturated */
  --media-ink:       #000000;   /* media chrome: crop hardware, video letterbox, RTE ink swatch — sits on user content, theme-independent */
  --media-paper:     #ffffff;   /* email reading frame + CAD light stage — the content assumes a white page, theme-independent */
  --media-stage-dark:#1e1e1e;   /* CAD viewer's own dark stage (a viewer-level toggle, not the app theme) */
  --cad-dim:         #e0245e;   /* CAD measurement overlay — magenta per drawing convention, sits on the stage not app surfaces */
  --ms-logo-red:     #f25022;  --ms-logo-green: #7fba00;  --ms-logo-blue: #00a4ef;  --ms-logo-yellow: #ffb900;  /* Microsoft sign-in mark — fixed brand values */
  --ok:              #16a34a;   /* status green — dots, ticks, applied badges (semantic, theme-stable) */
  --ok-soft-bg:      #dcfce7;   /* green status-chip family (mirrors the action-pill families) */
  --ok-soft-fg:      #166534;
  --ok-soft-border:  #86efac;
  --sky-soft-bg:     #e0f2fe;   /* sky status-chip family — "renamed" legend, whitespace flags */
  --sky-soft-fg:     #075985;
  --violet-soft-bg:  #ede9fe;   /* violet chip family — housekeeping/extension flags */
  --violet-soft-fg:  #5b21b6;
  --pink-soft-bg:    #fce7f3;   /* pink chip family — naming/generic flags, "both" legend */
  --pink-soft-fg:    #9d174d;
  --orange-soft-bg:  #ffedd5;   /* orange chip family — version flags, unresolved tags */
  --orange-soft-fg:  #9a3412;
  --orange-soft-border: #fed7aa;
  --danger-soft-border: #fca5a5;  /* border for danger-soft surfaces (error cards, failed rows) */
  --warning-chip-border: #f6c552; /* border for warning-chip surfaces (amber scores, hint boxes) */
  --cck-danger:      #e0564f;   /* cockpit flag/danger tint — brighter than --danger for small glyphs on white */
  --ai-panel-bg:     #eef3fc;   /* AI-assist panel family (results header, chat dock, pin dock) */
  --ai-panel-border: #c5d8f8;
  --ai-tint:         #a855f7;   /* AI-scan identity tint (progress label + gradient start) */
  --diff-unique-text:#6d28d9;   /* diff-unique as TEXT — dark pair lightens for contrast */
  --diff-unique-deep:#6d28d9;   /* hover of --diff-unique FILLS — stays deep so --on-solid text holds in both themes */
  --border-strong:   #c5cad1;   /* strong border/divider (dropzone, resizer, row hover) — was an undefined-token fallback */
  --presence-on:     #1fb87a;  --presence-call: #e8a33d;  --presence-away: #b6bcc8;  --presence-off: #cfd4dd;  /* office presence dots (always paired with labels; theme-stable) */
  --live-green:      #086b3f;   /* LIVE badge green — AA on the tinted header (design-system §3.11) */
  --mail-flag-wash:  #fdf6e3;   /* flagged mail-row wash */
  --table-hdr-bg:    #1f3a5f;   /* Tidy-Up dense-table column header — deep navy, --on-solid text pinned */
  --dupe-contains:   #c0524a;   /* light-red "contains duplicates" folder text (§3.5 colour grammar) */
}

/* Dark theme — only surface/border/text/accent tokens flip. Semantic colours
   (dupe red, amber, danger, success) stay identical so the product's visual
   contract still reads correctly in either theme. */
:root[data-theme="dark"] {
  /* FR-2b — fundraising funnel data-vis palette (the PO-approved v9 artefact).
     Sequential one-hue bands + rose decline family + amber overrun; constant
     across themes for now (chart surfaces stay light). */
  --fr-early: #a9c9ee; --fr-early-ink: #173156; --fr-mid: #5b8fd6; --fr-deep: #2b579e;
  --tk-bug: #d9776f; --tk-feat: #5fb98a;   /* R12-1 dark: the same markers, lifted for dark surfaces */
  --fr-rose-0: #dd8a86; --fr-rose-1: #e6a5a1; --fr-rose-2: #eec0bd; --fr-rose-3: #f6dbd9;
  --fr-agbar: #8fb5e8; --fr-tick: #3f5d76; --fr-amber: #f0b429; --fr-arrow: #8a94a0;
  --fr-cluster: rgba(43, 87, 158, 0.85);
  --fr-ink-on: #ffffff; --fr-rose-chip: #f9e9e8;
  --bg:          #15171b;
  --cck-canvas:  #101216;   /* toned canvas behind cockpit viewer panels */
  --surface:     #1a1d22;
  --surface-0:   #22262e;   /* elevated base surface — popovers, inputs, cards (opaque) */
  --surface-2:   #20242b;
  --surface-3:   #262b33;
  /* Striping kept barely-perceptible (2 brightness points apart) so rows
     still separate without producing visible banding on long lists. */
  --row-odd:     #1a1d22;
  --row-even:    #1c1f25;
  /* Borders sit BELOW lifted surfaces, not above — stops outlines from
     glowing as the brightest pixels in every framed control. (Iris Brief #1) */
  --border:      #23262d;
  --border-dark: #2b2f37;
  /* Connector re-picked per addendum: #5a6271 failed 3:1 against surface-2.
     #7a8394 = 4.16:1 with comfortable headroom across all surfaces. */
  --connector-stroke: #7a8394;
  /* Text pulled down ~4 luma points — brightest pixels in body text
     dominate dark-mode glare perception. */
  --text:        #dadde2;
  --text-dim:    #9aa2ae;   /* P5.1: was #8d94a0 (4.09:1 on the #2f343c chips) — 4.59 now */
  --text-faint:  #98a0ac;   /* P5.1: was #6c7480 (3.3:1 on dark surfaces) — 5.9+ now */
  --warn-text:   var(--warn);   /* P5.1: the amber itself passes on dark surfaces (5.09:1) */
  --danger-text: #ef6d64;   /* P5.1: 5.1:1+ on every dark surface incl. the soft-red table cells */
  --success-text:#4cc79a;   /* P5.1: 7:1 on dark surfaces */
  --accent:      #3a96e8;
  --accent-hover:#5fa7ed;
  /* Cockpit Extensis-brand layer — dark re-tune (not an inversion): a deep navy
     hero (the brand ink), light text, brighter cobalt accent. */
  --cck-page:        #15171b;
  --cck-hero-bg:     #1b2333;
  --cck-hero-text:   #eef0f4;
  --cck-hero-sub:    #9aa3b2;
  --cck-accent:      #4aa3e6;
  --cck-accent-on:   #0e1018;
  --cck-accent-soft: #17304a;
  --cck-positive:    #4cc79a;
  --cck-tile-lav:    #232a44;  --cck-tile-lav-fg:   #9a9bff;
  --cck-tile-blue:   #20283a;  --cck-tile-blue-fg:  #c4ccda;
  --cck-tile-mint:   #20283a;  --cck-tile-mint-fg:  #8f90ff;
  --cck-tile-peach:  #20283a;  --cck-tile-peach-fg: #9aa3b2;
  /* Hover/sel desaturated — drops blue-shift brightness without losing semantic. */
  --row-hover:   #232934;
  --row-sel:     #26334d;
  /* Chrome / menu / hover / tooltip dark overrides (Iris Brief #1 + addendum).
     pane-chrome-bg covers status-bar, pane-toolbar, pane-footer — the three
     surfaces previously hard-coded to #ebebeb with no dark override. */
  --pane-chrome-bg:  #232830;
  --footer-border:   #1f2228;
  --menu-bg:         #1e2127;
  --menu-border:     #2a2e36;
  --hover-soft:      #222730;
  --tooltip-bg:      #0d1014;
  --tooltip-text:    #c8ccd4;
  --panel-fill:      #1f242c;   /* soft toned grouped panel — dark */
  /* Brief #2 dark overrides (Iris, 2026-05-17). */
  --chrome-bg:           #1d2025;
  --chrome-border:       #2b2f37;
  --chrome-tint-diff:    rgba(124, 58, 237, 0.18);
  --chrome-rule-diff:    var(--diff-unique);
  --chrome-pulse-start:  rgba(124, 58, 237, 0.65);
  --chrome-pulse-end:    rgba(124, 58, 237, 0);
  --cluster-label:       var(--text-faint);
  --badge-bg:            #ef5b50;       /* brightened ~15% per Iris's "semantic +15% in dark" position */
  --badge-fg:            #ffffff;
  --pill-off-bg:         #22262d;
  --pill-off-fg:         #5e646e;
  --pill-off-border:     #2d323b;
  --app-icon-fg:         #5fa7ed;
  --warn-soft-bg:        #3a2a18;
  --danger-soft-bg:      #3a1d1d;
  --login-bg-from:       #0d2742;
  --login-bg-to:         #040e1c;
  --login-bg-glow:       rgba(255,255,255,0.05);
  --login-card-bg:       #1c2129;
  --login-card-shadow:   0 24px 60px rgba(0,0,0,.65), 0 2px 6px rgba(0,0,0,.50);
  --login-logo-plate:    linear-gradient(135deg, #1e2b40 0%, #18243a 100%);
  --login-logo-ring:     rgba(95, 167, 237, 0.18);
  --login-tagline-fg:    #9aa3b2;
  --login-note-fg:       #8a93a3;        /* brightened per bug-tester WCAG fix: 4.54:1 on --login-card-bg */
  --hover-soft-tree:     #1f2330;
  --hover-soft-tint:     #233650;
  --btn-secondary-hover: #252a32;
  --btn-tertiary-bg:     #22262d;
  --btn-tertiary-hover:  #2a2f37;
  --tree-header-bg:      linear-gradient(to bottom, #20242b 0%, #1a1d22 100%);
  --tree-header-rule:    #2b2f37;
  --tree-header-divider: #262a31;
  --tree-header-fg:      #c6cdd7;
  /* Shadow does the elevation work borders used to do — deeper drop,
     tighter lift. */
  --shadow:      0 1px 0 rgba(0,0,0,.6), 0 8px 24px rgba(0,0,0,.65);

  /* Otto mover --ftype-* tokens (§D.1): the var() aliases declared in :root
     re-resolve here against the dark values of their source tokens (dark
     --accent #3a96e8, --warn/--success/--diff-unique inherit light, dark
     --text-dim #8d94a0), so no per-token dark override is needed. Restated as
     a contract note, not a redefinition. --row-icon-size is theme-independent. */

  /* Brief #3 v2 — Phase 3D / 3D-bis dark overrides (Iris spec §1). */
  --elev-1: 0 1px 2px rgba(0,0,0,0.4), 0 1px 3px rgba(0,0,0,0.5);
  --elev-2: 0 4px 12px rgba(0,0,0,0.55), 0 2px 6px rgba(0,0,0,0.45);
  --warning-chip-bg: #3a2e0a;
  --warning-chip-fg: #fde68a;
  --btn-danger-bg:   #d54c3d;  /* WCAG fix — 4.69:1 on dark --surface-bg */
  --btn-danger-hover:#b83a2c;
  --neutral-soft-bg: #2a2e34;
  --neutral-soft-fg: #a8acb3;
  --scrim:           rgba(0,0,0,0.65);
  /* Phase 3C dark overrides */
  --chip-bg:               #2f343c;
  --chip-bg-active:        #3b4756;
  --chip-fg:               #d1d5db;
  --row-progress-bar:      #60a5fa;
  --row-progress-track:    #2a2e34;
  --skeleton-base:         #252930;
  --skeleton-shimmer:      #2f343c;
  --dupe-identical-glyph:  #dc2626;   /* WCAG carve-out: 5.42:1 on #1a1d22, fixes 2.97:1 hole */
  --dupe-similar-glyph:    #f59e3a;   /* derived for parity, 7.1:1 on dark */
  /* Iris pills-rework 2026-06-22 §2.1: brighter Standard-grey for dark mode so
     the dot/word stay legible on dark --surface (mirrors the -glyph carve-out
     pattern the tree uses for identical/similar). */
  --dupe-standard:         #9ca3af;
  /* Iris brief-10 §Token discipline: dark variants for AI Cleanup pills. */
  --action-pill-info-bg:    #1e3a5f;
  --action-pill-info-fg:    #bfdbfe;
  --action-pill-danger-bg:  #4a1818;
  --action-pill-danger-fg:  #fca5a5;
  --action-pill-merge-bg:   #312e81;
  --action-pill-merge-fg:   #c7d2fe;
  /* Iris brief-14 §B.2 mint — CHECK pill dark mode. 7.84:1, PASS AA+AAA. */
  --action-pill-check-bg:   #164e63;
  --action-pill-check-fg:   #a5f3fc;
  /* Otto in-tree filing (§6) dark — deeper mixes so the wash reads against the
     dark --surface without washing out (mirrors the dupe-glyph dark carve-out). */
  --otto-src-wash:  color-mix(in srgb, var(--warn) 18%, var(--surface));
  --otto-dest-wash: color-mix(in srgb, var(--accent) 18%, var(--surface));
  --otto-dest-halo: color-mix(in srgb, var(--accent) 60%, transparent);
  --otto-path-wash: color-mix(in srgb, var(--accent) 7%, var(--surface));

  /* ── P1.9 dark pairs (light values above). The soft chip families follow
     the action-pill dark recipe (Iris brief-10): deep 900-level fill +
     200-level text. Several chips previously stayed light-on-light in dark —
     that was the bug, not the design. Tokens not restated here are
     theme-stable by intent (see the light-block comments). ── */
  --ok-soft-bg:      #14532d;
  --ok-soft-fg:      #bbf7d0;
  --ok-soft-border:  #166534;
  --sky-soft-bg:     #0c4a6e;
  --sky-soft-fg:     #bae6fd;
  --violet-soft-bg:  #4c1d95;
  --violet-soft-fg:  #ddd6fe;
  --pink-soft-bg:    #831843;
  --pink-soft-fg:    #fbcfe8;
  --orange-soft-bg:  #7c2d12;
  --orange-soft-fg:  #fed7aa;
  --orange-soft-border: #9a3412;
  --danger-soft-border: #7a2828;
  --warning-chip-border: #92400e;
  --ai-panel-bg:     #1a1f2e;
  --ai-panel-border: #2a3142;
  --diff-unique-text:#c4b5fd;
  --border-strong:   #3a4458;
  --live-green:      #4cc79a;   /* matches --cck-positive dark */
  --mail-flag-wash:  #3a2e0a;   /* was a light cream on dark — unreadable with dark-theme text; warning-chip dark fill */
}

html, body {
  height: 100%; overflow: hidden;
  background: var(--bg); color: var(--text);
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Theme toggle button — show the icon for the theme you'd switch TO,
   not the one you're already in. So in light mode we show ☾ (switch to dark);
   in dark mode we show ☀ (switch to light). */
#btn-theme .theme-icon-light { display: none; }
#btn-theme .theme-icon-dark  { display: inline; }
:root[data-theme="dark"] #btn-theme .theme-icon-light { display: inline; }
:root[data-theme="dark"] #btn-theme .theme-icon-dark  { display: none; }

/* ── P1.9 t3 (2026-07-11): rules moved OUT of JS cssText / template-string
   style attributes so component JS carries no literal px style values.
   Values are verbatim from the JS they replace; snapping them onto the §1
   spacing scale stays the recorded design-system §10.1 debt. ── */
.app-toast { position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%); color: var(--on-solid); padding: 8px 16px; border-radius: 6px; z-index: 9999; font-size: 13px; }
.app-toast-accent { background: var(--accent); box-shadow: 0 4px 12px rgba(0,0,0,0.2); }
/* .app-toast-neutral deleted P2.1 (census §6) — the copy-confirm rides Toast.show now.
   .app-toast(-accent) remains ONLY as showInlineProgress's download busy pill (census §7 remainder). */
.offscreen-ta { position: fixed; top: -1000px; }
.zip-status { position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%); background: var(--accent); color: var(--on-solid); padding: 10px 18px; border-radius: 8px; z-index: 10000; font-size: 13px; box-shadow: 0 6px 20px rgba(0,0,0,0.25); min-width: 280px; text-align: center; }
.dnd-chip { position: fixed; pointer-events: none; z-index: 99999; padding: 3px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; letter-spacing: .03em; color: var(--on-solid); box-shadow: 0 2px 8px rgba(0,0,0,0.25); transform: translate(14px, 14px); transition: background-color var(--motion-micro) var(--motion-easing); }
.tree-flash-ring { box-shadow: inset 0 0 0 2px var(--accent); }
.tree-folder-glyph { display: inline-block; vertical-align: middle; margin-bottom: 1px; }

/* ── EMPTY STATES — one grammar (P2.1 census §3, 2026-07-11) ─────────────
   .empty-state is the canonical class for all NEW empty states; the legacy
   family classes are grouped here as aliases so every surface renders the
   same grammar (13px/1.5 --text-dim, centred, 32px/16px pad — §1 scale).
   Family rules elsewhere keep ONLY genuine geometry deltas (compact
   containers, pane min-heights, the VAT card chrome, the projects prose
   block). Copy rule stays DESIGN_JUDGEMENT's: say what happened, never
   pretend content. eval-grammar G03 holds this selector list. */
.empty-state, .ins-empty, .aic-empty, .cck-rail-empty, .cck-plate-empty,
.cck-col-empty, .cck-work-empty, .cck-mempty, .cck-empty, .dupe-empty,
.fin-emptyrow, .vat-empty, .pjw-empty, .aw-preview-empty, .ofc-chat-empty,
.architect-empty, .tb-dropdown-empty {
  font-size: 13px; line-height: 1.5;
  color: var(--text-dim);
  text-align: center;
  padding: 32px 16px;
}
/* Glyph-led empties stack a Lucide glyph over title + sub; full-pane
   empties earn the roomier on-scale padding. */
.empty-state, .ins-empty, .aic-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.ins-empty, .aic-empty { padding: 48px 24px; }
.empty-state .lucide-icon, .ins-empty .lucide-icon, .aic-empty .lucide-icon {
  color: var(--text-faint); margin-bottom: 12px;
}
.empty-state-title, .ins-empty-title, .aic-empty-title {
  font-size: 13px; font-weight: 600; color: var(--text); margin: 0 0 4px;
}
.empty-state-sub, .ins-empty-sub, .aic-empty-sub {
  font-size: 12px; color: var(--text-dim); margin: 0; line-height: 1.5; max-width: 240px;
}

/* ── KIND TAGS — one micro-tag grammar (P2.1 census §5, 2026-07-11) ──────
   The 9.5px 700 uppercase action/kind tag tier (the S2 mockup's "DUPLICATE"
   row tag). .wx-kind-tag is the canonical class for new code; the legacy
   duplicate implementations are grouped in as aliases. Fills come from the
   design-system §3.6 action-pill / §3.12 soft-chip token pairs ONLY (the
   old per-class rgba() tints were a token-gate blind spot and sat
   light-on-dark wrong in dark mode). eval-grammar G05 holds this. */
.wx-kind-tag, .sa-live-tag, .sa-row-action-tag, .ai-op-row-tag, .sm-row-badge {
  display: inline-block;
  font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  padding: 1px 6px; border-radius: 3px;
  white-space: nowrap;
}

/* duplicates surface (dupesUI.js) */
.dupe-loadmore { margin: 12px auto; display: block; padding: 6px 20px; }
.dupe-filter-pill { background: var(--action-pill-info-bg); color: var(--accent); padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 600; margin-left: 8px; }
.dupe-star-newest { font-size: 10px; color: var(--success-text); padding: 2px 6px; }
.dupe-arrow { font-size: 11px; color: var(--text-faint); }
.dupe-cluster-actions { padding: 8px 0 2px; display: flex; gap: 6px; }
.dupe-pair-actions { padding: 4px 0 0; text-align: right; }
/* .dupe-empty is fully carried by the shared empty-state grammar above (P2.1). */
.dupe-hint { color: var(--text-faint); font-size: 11px; }
.dupe-report-subhead { margin: 18px 0 8px; font-size: 12px; font-weight: 600; color: var(--text-dim); border-top: 1px solid var(--border); padding-top: 14px; }
.dupe-pair-meta { padding: 6px 0 2px; font-size: 11px; color: var(--text-dim); font-style: italic; display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.wt-ai-tag { font-size: 9px; background: var(--ai-tint); color: var(--on-solid); padding: 1px 6px; border-radius: 8px; font-weight: 700; }
.wt-reason { font-size: 11px; font-style: italic; padding: 2px 0 4px 26px; }
/* compare/diff readout (app.js) */
.diff-md-h { font-size: 13px; }
.diff-sec { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.diff-ai-h { font-size: 11px; font-weight: 600; color: var(--ai-tint); margin-bottom: 6px; }
.diff-err { color: var(--danger-text); padding: 8px; background: var(--danger-soft-bg); border: 1px solid var(--danger-soft-border); border-radius: 6px; font-size: 11px; }
.diff-mt { margin-top: 14px; }
.diff-banner { padding: 10px 12px; border-radius: 6px; font-size: 12px; }
.diff-banner-ok { background: var(--ok-soft-bg); border: 1px solid var(--ok-soft-border); }
.diff-banner-warn { background: var(--warning-chip-bg); border: 1px solid var(--warning-chip-border); margin-bottom: 10px; }
.diff-more { font-size: 11px; color: var(--text-faint); margin-top: 4px; }
.diff-row { font-size: 11px; font-family: monospace; padding: 1px 0; }
.diff-group { margin-top: 8px; }
.diff-sec-h { font-size: 11px; font-weight: 600; margin-bottom: 4px; }
.ai-summary-pre { white-space: pre-wrap; font-size: 12px; }
.ai-title-glyph { display: inline-block; vertical-align: middle; margin-right: 5px; }
.ai-title-count { font-weight: 400; color: var(--text-dim); font-size: 11px; margin-left: 4px; }
.naming-note { color: var(--text-faint); font-size: 10px; }
.cm-block { display: block; margin-top: 10px; }
.cm-block-note { display: block; margin-top: 8px; color: var(--text-dim); font-size: 12px; }
.lm-dialog { width: 520px; max-width: 92vw; }
.lm-input { width: 100%; margin: 8px 0 14px; }
/* M12-UX-1c: the mount dialog reuses the ONE folder picker (.crm-pk grammar,
   crm.js openFolderPicker with a local loader) — the build-33 bespoke browser
   classes were retired the same day Jeremy reviewed them ("just like the
   other picker in DD folder"). .lm-dialog stays: the Full-Disk-Access helper
   dialog (M12-UX-1d) uses it. */
/* tidy-up dialogs */
.cck-icr-w420 { max-width: 420px; }
.cck-icr-w520 { max-width: 520px; }
.cck-icr-w560 { max-width: 560px; }
.ty-ex-summary { margin-top: 8px; }
.ty-ex-input { width: 100%; margin: 8px 0; }
.ty-ex-chips { display: flex; gap: 6px; margin: 4px 0 12px; flex-wrap: wrap; }
.ty-adm-input { width: 100%; margin: 10px 0; }
.ty-adm-note { margin-top: 10px; }
.ty-tag-inline { margin-left: 6px; }
.ty-pick-list { display: flex; flex-direction: column; gap: 6px; margin: 10px 0 14px; }
/* crm */
.crm-impsub-gap { margin: 6px 0 2px; }
.crm-stage-label-gap { margin: 8px 0 4px; }
.crm-ddstage-label-gap { margin: 2px 0 4px; }
.crm-map-note { margin-bottom: 10px; }
.crm-map-actions { margin-top: 12px; }
.crm-pk-note-pad { padding: 8px; }
.crm-report-label-gap { margin-bottom: 8px; }
/* misc surfaces */
.ins-empty-roomy { padding: 24px 0; }
.ins-empty-think-gap { margin-top: 14px; }
.aic-empty-tight { padding-bottom: 8px; }
.settings-inline-num { display: inline-flex; align-items: center; gap: 8px; }
.pjw-onlynew-row { display: flex; gap: 8px; align-items: center; }
/* P1.9 t4 — index.html inline style= attributes moved to classes. .js-hidden
   is the boot-hidden state; JS shows these with explicit style.display values
   (inline wins over the class), so the toggle semantics are unchanged. */
.js-hidden { display: none; }
/* P4.1: elements whose IDs also carry a display rule need the combined selector,
   or the id rule (1-0-0) defeats the class (0-1-0) and the element paints at
   boot — the empty AI Results panel sat visible under the Explorer right tree
   since t4. Inline style.display from the show-sites still wins at runtime. */
#ai-results-panel.js-hidden, #app.js-hidden { display: none; }
.icon-block { display: block; }
.ai-results-glyph { vertical-align: middle; margin-right: 6px; }
.sync-idle-chip { cursor: pointer; user-select: none; }
.modal-box-w520 { max-width: 520px; }
.merge-subtitle { font-size: 12px; color: var(--text-dim); margin: 2px 0 14px; }

/* ── RESPONSIVE FLOOR ──────────────────────────────────────────
   Iris brief-10 §7 + Addendum A1 (Jeremy 2026-05-22): ≥1280px hard floor.
   Below 1280px innerWidth the tool can't lay out (Inspector 420 + dual-pane
   ≥800 + toolbar > 1240). Decision ratified 2026-05-22: block with notice,
   don't try to responsively rebuild. JS toggles `data-visible` on resize;
   @media query is the backstop for "JS didn't load".

   The 14px sub-copy font-size is the one deviation from the 11/12/13/16/20
   ramp — see brief §7 carve-out: at the resize-your-window screen the user
   is at-rest reading a single sentence, not scanning chrome. 14/20 keeps
   the sentence readable without crowding. Not a precedent for normal
   screens.
   ─────────────────────────────────────────────────────────── */
.responsive-floor {
  position: fixed; inset: 0;
  z-index: 99999;                       /* above everything including modals */
  display: none;
  align-items: center; justify-content: center;
  background: var(--surface);
  padding: 32px;
  opacity: 0;
  transition: opacity var(--motion-duration) var(--motion-easing);
}
.responsive-floor[data-visible="1"] {
  display: flex;
  opacity: 1;
}
.responsive-floor-card {
  max-width: 480px;
  text-align: center;
  color: var(--text);
}
.responsive-floor-icon {
  color: var(--accent);
  margin-bottom: 24px;
}
.responsive-floor-headline {
  font: 600 20px/28px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  margin: 0 0 12px;
}
.responsive-floor-sub {
  font: 400 14px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  margin: 0 0 16px;
}
.responsive-floor-meta {
  font: 400 12px/16px ui-monospace, 'SF Mono', Consolas, monospace;
  color: var(--text-faint);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* @media query backstop: even if JS doesn't load, hide the app shell
   below 1280px. The floor element is forced visible via its own rule.
   Strict less-than per Iris spec (≥1280 is the supported floor). */
@media (max-width: 1279.99px) {
  #app, header, #explorer, #inspector, #status-bar { display: none !important; }
  .responsive-floor { display: flex; opacity: 1; }
}

/* ── LOGIN ─────────────────────────────────────────────────────
   Refined 2026-05-14 by Iris as the "bar-setter" — first-pixel rule.
   Whatever quality bar this screen sets, every subsequent feature has
   to clear it. Replaced the 56px folder emoji with a Lucide SVG on an
   accent-tinted plate, retuned spacing to the 4/8/12/16/24 scale, gave
   the sign-in button a proper Microsoft 4-square mark instead of a
   plain label.
   ─────────────────────────────────────────────────────────── */
#login-screen {
  height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(ellipse at 30% 20%, var(--login-bg-glow), transparent 60%),
    linear-gradient(135deg, var(--login-bg-from) 0%, var(--login-bg-to) 100%);
  padding: 24px;
}
.login-box {
  background: var(--login-card-bg);
  border-radius: 16px;
  padding: 40px 40px 32px;
  text-align: center;
  box-shadow: var(--login-card-shadow);
  max-width: 380px;
  width: 100%;
}
.login-logo {
  /* Brief #2 D1 Option A — plate carries identity, glyph carries meaning.
     Plate uses --login-logo-plate gradient + optional inset ring for dark. */
  width: 88px; height: 88px;
  margin: 0 auto 24px;
  display: flex; align-items: center; justify-content: center;
  background: var(--login-logo-plate);
  border-radius: 16px;
  color: var(--app-icon-fg);
  box-shadow: inset 0 0 0 1px var(--login-logo-ring);
}
.login-logo-glyph {
  /* Lucide `folders` glyph (the svg itself carries this class — Lucide's
     replaceIcons preserves classes from the <i data-lucide> source).
     2px stroke via Lucide default, sized for the plate. No drop-shadow —
     Iris's rule: Lucide outlined glyphs don't carry shadows in this product. */
  width: 56px; height: 56px;
  display: block;
}
/* Product icon on the sign-in splash — the real ExtensisWorx mark (no plate). */
.login-logo:has(.login-logo-img) { background: none; box-shadow: none; border-radius: 0; }
.login-logo-img { width: 88px; height: 88px; object-fit: contain; display: block; }

/* Toolbar brand-mark plate — 28×28 tinted-accent plate holding a 22×22
   Lucide `folders` glyph in --app-icon-fg. Adjacent toolbar controls
   have no backplate so the brand mark visually outranks them. */
.app-icon-logo {
  flex-shrink: 0;
  width: 28px; height: 28px;
  display: block;
}
.app-icon-plate {
  /* Smoke-test polish 2026-05-19 (Jeremy): the rounded blue backplate was
     "bleeding through the edges" of the folder glyph — looked unprofessional.
     Stripped the plate background + border-radius; the folder glyph itself
     now carries the brand colour without an aura. Wrapper still sizes the
     icon (28×28 footprint) so toolbar layout doesn't shift. */
  flex-shrink: 0;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--app-icon-fg);
}
.app-icon-glyph { width: 26px; height: 26px; display: block; }
.login-box h1 {
  font-size: 20px; font-weight: 600; letter-spacing: -0.01em;
  margin: 0 0 8px;
  color: var(--text);
}
.login-tagline {
  font-size: 13px; color: var(--login-tagline-fg); line-height: 1.5;
  margin: 0 0 24px;
}
.btn-large {
  width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  min-height: 44px;            /* Apple HIG touch-target minimum */
  padding: 12px;
  font-size: 13px; font-weight: 600;   /* Iris §0.1: explicit 600 over inherited 500 */
  border-radius: 8px;
  white-space: nowrap;          /* never wrap label behind the MS logo */
  line-height: 1;
}
/* Microsoft 4-square colour logo — pure CSS, no asset. The official
   Microsoft brand mark; sign-in buttons that show it convert ~30 %
   better than plain-text variants on enterprise SaaS. */
.btn-ms-logo {
  display: inline-grid;
  grid-template-columns: 9px 9px;
  grid-template-rows: 9px 9px;
  gap: 2px;
  width: 20px; height: 20px;
}
.btn-ms-logo > span:nth-child(1) { background: var(--ms-logo-red); }
.btn-ms-logo > span:nth-child(2) { background: var(--ms-logo-green); }
.btn-ms-logo > span:nth-child(3) { background: var(--ms-logo-blue); }
.btn-ms-logo > span:nth-child(4) { background: var(--ms-logo-yellow); }

.login-note {
  font-size: 11px; color: var(--login-note-fg);
  margin: 16px 0 0;
  line-height: 1.45;
}
/* Iris Brief #2: all login dark overrides removed — light/dark variance
   lives on the tokens themselves (--login-card-bg, --login-logo-plate,
   --login-tagline-fg, --login-note-fg, --app-icon-fg, --login-logo-ring). */

/* ── APP LAYOUT ─────────────────────────────────────────────── */
#app {
  height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr var(--statusbar-h);
  grid-template-areas: "toolbar" "explorer" "statusbar";
}
#app.compare-open {
  grid-template-rows: auto 1fr var(--compare-h) var(--statusbar-h);
  grid-template-areas: "toolbar" "explorer" "compare" "statusbar";
}
/* #app.audit-file-open #explorer reserve deleted 2026-06-22 dead-code sweep
   N3 (the #audit-file-panel that pushed #explorer's edge inward is gone). */

/* ── TOOLBAR ─────────────────────────────────────────────────── */
/* Iris menu-redesign v3 §1.4: the toolbar is the single flex-wrap line. All
   controls sit on ONE physical row on a wide screen; the row wraps to a second
   line only when geometry forces it (≥1280 floor + Inspector open). No
   overflow:hidden — the row is allowed to wrap (that's the feature). */
#toolbar {
  grid-area: toolbar;
  display: flex; align-items: center; flex-wrap: wrap;
  row-gap: 8px;            /* vertical air between the two lines when it wraps */
  column-gap: 8px;         /* base inter-item gap; cluster overrides to 6 internally */
  padding: 4px 12px; min-height: 36px;
  /* D1 (v5) — clean-white toolbar surface to MATCH the approved mockup.
     Was: var(--chrome-bg) — resolved to var(--surface-2) grey (== --surface-2).
     The 1px --chrome-border bottom rule now does the pane separation the
     grey band used to. Do NOT edit the --chrome-bg token itself. */
  background: var(--surface);
  border-bottom: 1px solid var(--chrome-border);
  user-select: none;
}
.toolbar-section { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
.toolbar-left  { flex: 0 0 auto; gap: 10px; padding-right: 4px; }
.toolbar-center{ flex: 1 1 auto; justify-content: center; min-width: 0; }
.toolbar-right { flex: 0 0 auto; gap: 4px; }
/* Right chrome pinned to the far edge; never wraps off (v3 §1.6). The flex
   spacer is margin-left:auto — pushes home/theme/⋯/user to the right; on a
   wrapped layout the filter group drops BENEATH it, the chrome stays top-right. */
#toolbar > .tb-right-chrome { margin-left: auto; flex-wrap: nowrap; flex-shrink: 0; }
/* Identity pinned left, never wraps off (v3 §1.6). */
#toolbar > .toolbar-left { flex-shrink: 0; }

/* Compare cluster — atomic: [Dups][Diff][◂Find▸] wrap to line 2 as ONE welded
   unit, 6px internal gap (v3 §1.6). flex-wrap:nowrap = the parent can only
   break BETWEEN children, never inside this nowrap child. */
.tb-cluster { display: inline-flex; align-items: center; gap: 6px; flex-wrap: nowrap; flex-shrink: 0; }

/* Filter group — atomic: the relocated band drops to line 2 as one unit (all
   three pills + both toggles + both micro-labels together), 8px internal gap
   (v3 §1.4 / §1.6). */
.tb-filter-group { display: inline-flex; align-items: center; gap: 8px; flex-wrap: nowrap; flex-shrink: 0; }

/* D2 (v5) — the SHOW/SCOPE micro-labels (.filter-strip-label) and the in-group
   divider (.filter-strip-sep) were removed to match the mockup's one uniform
   filter row. Their CSS is deleted as dead code. The group's aria-label carries
   the accessible name. .filter-strip-caption (below) is KEPT. */

/* Empty-scope hint (both toggles off) — muted, recoverable, NOT error grammar. */
.filter-strip-caption {
  font-size: 11px; line-height: 1.4; color: var(--text-faint);
  white-space: nowrap;
}
.filter-strip-caption[hidden] { display: none; }

/* Two independent scope toggles (drop "Both"). Independent booleans look
   independent — standalone, not a joined segment (v2 §4.1). */
.tb-scope { display: inline-flex; align-items: center; gap: 8px; }   /* D3 (v5) — 8px to match .dupe-fchips + group gap; one uniform row */
.tb-scope-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px;   /* R2 (B6): was 24px — uniform 28px band */
  border: 1px solid var(--border-dark); border-radius: 6px;
  background: var(--surface); color: var(--text-dim);
  font: 500 12px/1 inherit; font-family: inherit; cursor: pointer;
  white-space: nowrap; flex-shrink: 0;
  transition: background var(--motion-duration) var(--motion-easing),
              color var(--motion-duration) var(--motion-easing),
              border-color var(--motion-duration) var(--motion-easing);
}
.tb-scope-toggle .lucide-icon { width: 13px; height: 13px; flex-shrink: 0; }
.tb-scope-toggle:hover { background: var(--hover-soft); }
.tb-scope-toggle[aria-pressed="true"] { background: var(--chip-bg-active); color: var(--text); font-weight: 600; }
.tb-scope-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Iris Brief #2: legacy .app-icon now superseded by .app-icon-plate +
   .app-icon-glyph (Lucide `folders` on a tinted plate). The rule stays
   as a no-op safety in case any legacy markup is still rendered. */
.app-name {
  font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', sans-serif;
  font-weight: 600; font-size: 14.5px; color: var(--text);   /* Iris §0.1: 700 → 600 */
  letter-spacing: -0.015em;
  white-space: nowrap;
}
.app-name-accent {
  color: var(--accent);
  font-weight: 600;
}
.tb-separator { width: 1px; height: 18px; background: var(--chrome-border); margin: 0 8px; flex-shrink: 0; }

/* Find Prev/Next pair — joined visually so they read as one control */
.tb-pair { display: inline-flex; align-items: center; gap: 0; }
.tb-pair > .tb-btn { border-radius: 0; }
.tb-pair > .tb-btn:first-of-type { border-radius: 4px 0 0 4px; }
.tb-pair > .tb-btn:last-child  { border-radius: 0 4px 4px 0; border-left: none; }

/* ◂ Find ▸ — the word FIND centred BETWEEN the chevrons (Iris v2 §7.2 / v3
   §1.6). Three cells in one segmented unit: chevron · Find · chevron. The pair
   is 28px (toolbar button height); chevron cells are 26px square either side of
   the centred label, so the arrows visibly bracket the word. */
.tb-find-pair {
  display: inline-flex; align-items: center;
  height: 28px;
  border: 1px solid var(--border-dark); border-radius: 6px;
  background: var(--surface); overflow: hidden;
  flex-shrink: 0;
}
.tb-find-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 100%;
  border: 0; background: transparent; color: var(--text-dim); cursor: pointer;
  transition: background var(--motion-duration) var(--motion-easing),
              color var(--motion-duration) var(--motion-easing);
}
.tb-find-btn .lucide-icon { width: 14px; height: 14px; }
.tb-find-btn:hover:not(:disabled) { background: var(--hover-soft); color: var(--text); }
.tb-find-btn:disabled { cursor: default; }
.tb-find-label {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; padding: 0 8px; height: 100%;
  font-size: 12px; font-weight: 600; color: var(--text-dim);
  letter-spacing: 0.01em; white-space: nowrap;
  border-left: 1px solid var(--chrome-border);
  border-right: 1px solid var(--chrome-border);
}
/* Whole-pair disabled — when nothing's findable, the word greys WITH the arrows
   so it reads as one disabled unit (v2 §7.2). Driven by data-disabled on the
   pair (JS) OR by both buttons being natively disabled (boot). */
.tb-find-pair[data-disabled="1"] { opacity: 0.45; }
.tb-find-pair[data-disabled="1"] .tb-find-btn { pointer-events: none; }
.tb-find-pair[data-disabled="1"] .tb-find-label,
.tb-find-pair[data-disabled="1"] .tb-find-btn { color: var(--text-faint); }

/* INLINE DIFF READOUT (v4 R1 / Batch B B2) — lives in .tb-cluster, between
   #btn-diff and .tb-find-pair. Shows ONLY the per-side unique counts. */
.tb-diff-readout {
  display: inline-flex; align-items: center; gap: 8px;
  height: 28px;                                  /* R2 uniform band height */
  min-width: 168px;                              /* RESERVED SLOT — holds whether shown or empty */
  padding: 0 10px;                               /* matches .tb-btn inset */
  white-space: nowrap; flex-shrink: 0;
  font-size: 11.5px; font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  transition: opacity var(--motion-duration) var(--motion-easing);
}
/* RESERVE THE SPACE: when Diff is OFF the element keeps its min-width box but its
   contents are hidden — so Find/pills never shift sideways on the on↔off toggle.
   This DELIBERATELY overrides the default [hidden]{display:none} for THIS element
   only: keep it in layout, hide contents. Do NOT "fix" this to display:none. */
.tb-diff-readout[hidden] { display: inline-flex; visibility: hidden; }
.tb-diff-readout:not([hidden]) { visibility: visible; }

/* The purple-tinted "unique" key — the only tonal accent in the readout. Reuses
   the established Diff purple (var(--diff-unique) — the retired banner's DIFF pill + the
   #btn-diff active state + the tree diff highlight all used it). Tinted wash, not
   a solid fill, so it reads quiet on the white toolbar. Zero new tokens. */
.tb-diff-readout-key {
  font-weight: 600; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--diff-unique);
  background: rgba(124, 58, 237, 0.10);
  padding: 2px 7px; border-radius: 3px;
  line-height: 1;
}
.tb-diff-readout-stat { color: var(--text-dim); }
.tb-diff-arrow { color: var(--text-faint); font-size: 11px; }

:root[data-theme="dark"] .tb-diff-readout-key {
  color: var(--diff-unique-text);                                /* carried from the retired banner's dark purple text */
  background: rgba(124, 58, 237, 0.22);          /* stronger tint to hold on the dark toolbar */
}
/* "Find:" / "Show:" / "Duplicates:" labels in front of grouped toolbar
   controls so the intent of each cluster is obvious instead of just "two
   chevrons" or "five coloured pills". Iris's call: small caps, dim,
   comfortable spacing. */
.tb-group-label {
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--cluster-label);
  padding: 0 8px 0 2px;
  white-space: nowrap;
}
/* Toolbar count badge — small pill that hangs off a toolbar button (Naming,
   etc.) showing how many items the underlying tool found. */
.tb-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 16px; margin-left: 6px;
  padding: 0 5px; border-radius: 999px;
  background: var(--badge-bg); color: var(--badge-fg);
  font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums;
  line-height: 1;
}
.tb-count[hidden] { display: none; }

/* Iris Brief #2: cluster backplates removed. At toolbar density, second-level
   containers inside a clearly-bounded chrome strip create visual noise. The
   strip itself is the cluster boundary; tb-separator + 8px gaps carry the
   rhythm. v3: the toolbar now uses column-gap:8px, so the separator carries NO
   horizontal margin (the gap is the rhythm) — a margin here would double the
   space around each rule. */
#toolbar .tb-separator { width: 1px; height: 18px; background: var(--chrome-border); margin: 0; }

/* Compare-mode tint — layered gradient over --chrome-bg so both themes
   tint identically (Iris Brief #2 §5.4). Tint is a translucent purple
   wash; rule is the locked --diff-unique colour. */
body.compare-mode #toolbar {
  background:
    linear-gradient(180deg, var(--chrome-tint-diff), transparent 60%),
    var(--surface);   /* D1 (v5) — white base to match #toolbar; was --chrome-bg grey */
  box-shadow: inset 0 -2px 0 var(--chrome-rule-diff);
}

/* First-activation pulse on the Compare button — single 1.2s ripple.
   Iris Brief #2: two pulse tokens drive start (visible) and end
   (transparent) so the keyframe is themable per Iris's "elevation via
   alpha-fade" rule. */
@keyframes tb-btn-pulse {
  0%   { box-shadow: 0 0 0 0 var(--chrome-pulse-start); }
  100% { box-shadow: 0 0 0 14px var(--chrome-pulse-end); }
}
.tb-btn.tb-btn-pulse {
  animation: tb-btn-pulse 1.2s cubic-bezier(0.4, 0, 0.2, 1) 1;
  border-radius: 4px;
}

/* Uniform 28px height across every toolbar button so icon-only and text-label
   buttons line up. Padding shifts to keep the visible glyph centred. */
.tb-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  height: 28px; padding: 0 10px;
  border-radius: 4px; border: 1px solid var(--border-dark);
  background: var(--surface); color: var(--text); cursor: pointer;
  font-size: 12px; font-family: inherit; white-space: nowrap;
  transition: background var(--motion-micro), border-color var(--motion-micro);
  flex-shrink: 0;
}
.tb-btn.tb-icon { padding: 0 8px; min-width: 28px; }
/* Module navigation — a segmented control at the far left (Home / Files / …).
   Grows as modules are added (DD, CRM). The active segment carries the accent. */
.tb-nav { display: inline-flex; gap: 2px; padding: 2px; border-radius: 8px; background: var(--surface-1, rgba(20,24,33,0.05)); flex-shrink: 0; }
.tb-nav-btn { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px; border: none; border-radius: 6px; background: none; color: var(--text-dim); font: 500 12px/1 inherit; cursor: pointer; white-space: nowrap; transition: background var(--motion-micro), color var(--motion-micro); }
.tb-nav-btn .tb-nav-lbl { font-size: 12px; }
.tb-nav-btn:hover { background: rgba(20,24,33,0.06); color: var(--text); }
.tb-nav-btn.active { background: var(--accent); color: var(--on-solid); }
.tb-nav-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Iris aicleanup-redesign §4.4 (Stage 3 P2): keyboard focus ring. The shared
   accent-outline convention (~30 components) was promised in the spec but never
   existed for .tb-btn; Stage 3B newly makes #user-pill a focusable role=button and
   the Account-menu items take programmatic focus on open, so without this a keyboard
   user tabbing the toolbar / opening the menu sees no ring. Zero new tokens. */
.tb-btn:focus-visible,
#user-pill:focus-visible,
.tb-more-menu button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tb-glyph { font-size: 13px; line-height: 1; }
/* Lucide SVG glyphs sit on the same baseline as text labels — align so the
   button hit-area visually centres on the icon, not the leftover descender. */
.tb-glyph.lucide-icon,
.tb-btn > .lucide-icon { display: inline-block; vertical-align: -2px; }

/* ── Iris menu-redesign v3 2026-06-22 — duplicate filter group on the toolbar ─
   The #dupe-filter-band was RELOCATED out of the Duplicates sub-tab and onto
   the shared toolbar row as an inline flex child (.tb-filter-group, styled
   above). On the shared row it lives ON the toolbar surface — NO --surface-2
   band fill, NO border-bottom (those were the own-row strip's job, dropped per
   v3 §1.4 / §2.4). The chips keep their own chip borders/dots for legibility
   against the toolbar surface. Reuses the --pill-off-* OFF treatment (see
   .dupe-fchip.off below) so the whole app speaks one dialect. Zero new tokens.
   Single 200ms motion. */

/* Three self-labelling filter chips (§2) */
.dupe-fchips { display: inline-flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
.dupe-fchip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px;   /* R2 (B6): was 24px — uniform 28px band */
  border: 1px solid var(--border-dark); border-radius: var(--radius);   /* "make it exact" — was 999px pill; now rounded RECT matching .tb-scope-toggle (Files) 6px */
  background: var(--surface); color: var(--text);
  font-size: 12px; font-family: inherit; cursor: pointer;
  white-space: nowrap; user-select: none;
  transition: background var(--motion-duration) var(--motion-easing),
              border-color var(--motion-duration) var(--motion-easing),
              opacity var(--motion-duration) var(--motion-easing);
}
.dupe-fchip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* R3 (B7) — uniform width for the 5 filter buttons (3 chips + 2 scope toggles).
   All equal to the natural max (Identical chip ≈ 132px), content centred — a
   tidy grid of equal 132×28 tiles. The Show/Scope micro-labels are NOT included
   (they're labels, not buttons). */
.tb-filter-group .dupe-fchip,
.tb-filter-group .tb-scope-toggle {
  min-width: 132px;
  justify-content: center;
}
.dupe-fchip-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.dupe-fchip-dot[data-cat="identical"] { background: var(--dupe-identical); }
.dupe-fchip-dot[data-cat="similar"]   { background: var(--dupe-similar); }
.dupe-fchip-dot[data-cat="standard"]  { background: var(--dupe-standard); }
/* Dark-mode dot fix (v3 §… / v2 §4.2): the muted light values fail contrast on
   the dark toolbar surface (the #b91c1c identical dot is a 2.97:1 hole). Use
   the brightened -glyph tokens the tree + pills already use in dark mode.
   (standard grey #9ca3af is already legible in dark — no carve-out needed.) */
:root[data-theme="dark"] .dupe-fchip-dot[data-cat="identical"] { background: var(--dupe-identical-glyph); }
:root[data-theme="dark"] .dupe-fchip-dot[data-cat="similar"]   { background: var(--dupe-similar-glyph); }
.dupe-fchip-name { font-weight: 500; }
.dupe-fchip-count {
  color: var(--text-dim); font-variant-numeric: tabular-nums;
}
.dupe-fchip-count[data-empty="1"] { opacity: 0.5; }
/* .dupe-fchip-eye removed (Iris v3 ledger row 6 — Unique chip de-eyed to a
   plain dot+word+count, one grammar with Identical/Similar). */

/* Active (filter ON — visible + walked) */
.dupe-fchip.active {
  background: var(--chip-bg-active);
  /* No accent (blue) border on active — match the Files button's outline:
     chip-bg-active fill on the neutral --border-dark border, exactly like
     .tb-scope-toggle[aria-pressed="true"] (Jeremy 2026-06-22 "match Files"). */
}
.dupe-fchip.active .dupe-fchip-name { font-weight: 600; color: var(--text); }

/* Mixed (Both mode, file flag ≠ folder flag) — active styling, dot at 0.6 */
.dupe-fchip.mixed .dupe-fchip-dot { opacity: 0.6; }

/* ── Design polish (Jeremy 2026-06-27): the duplicate filter chips + the Files
   scope toggle become content-width capsule toggles, tinted by category when ON
   — one grammar with the AI Cleanup / History chips. Behaviour unchanged (same
   .active toggle + aria-pressed). ──────────────────────────────────────────── */
.dupe-fchip, .tb-scope-toggle { height: 26px; border-radius: var(--radius-pill); }
.tb-filter-group .dupe-fchip,
.tb-filter-group .tb-scope-toggle { min-width: 0; justify-content: flex-start; padding: 0 12px; }
.dupe-fchip:not(.active), .tb-scope-toggle[aria-pressed="false"] { color: var(--text-dim); }
.dupe-fchip.active[data-dupe-cat="identical"] { background: var(--action-pill-danger-bg); border-color: transparent; color: var(--action-pill-danger-fg); }
.dupe-fchip.active[data-dupe-cat="similar"]   { background: var(--action-pill-warn-bg);   border-color: transparent; color: var(--action-pill-warn-fg); }
.dupe-fchip.active[data-dupe-cat="standard"],
.tb-scope-toggle[aria-pressed="true"] { background: var(--hover-soft); border-color: var(--border); color: var(--text); }
.dupe-fchip.active .dupe-fchip-count { color: inherit; }   /* P5.1: the 0.75 opacity blended the count below AA on the tinted chip */

/* Off (filter OFF — hidden from tree + skipped by Find). Reuses .pill-off
   treatment verbatim: struck-out name, desaturated dot, dimmed. */
.dupe-fchip.off {
  background: var(--pill-off-bg);
  color: var(--pill-off-fg);
  border-color: var(--pill-off-border);
  opacity: 0.65;
}
.dupe-fchip.off .dupe-fchip-name {
  text-decoration: line-through;
  font-weight: 500;
  color: var(--pill-off-fg);
}
.dupe-fchip.off .dupe-fchip-dot  { background: var(--pill-off-fg); }
.dupe-fchip.off .dupe-fchip-count { color: var(--pill-off-fg); }
.dupe-fchip.off:hover {
  opacity: 0.9;
}
.dupe-fchip.off:hover .dupe-fchip-name { text-decoration: none; }

/* Both-off empty-scope affordance (v2 §4.3): when BOTH scope toggles are off
   nothing is in scope — the three category chips dim + go inert, and the
   faint empty-scope hint shows. Recoverable user state, not a fault, so
   muted-dim NOT amber/error grammar. Driven by data-empty-scope on the group. */
.tb-filter-group[data-empty-scope="1"] .dupe-fchip {
  opacity: 0.5; cursor: not-allowed; pointer-events: none;
}

/* Home-mode (v3 §2.3): the three Explorer-only groups dim in place on the
   shared toolbar row — 45% + grayscale + inert, state parked not reset. Global
   controls (Sync, theme, identity, right chrome) stay live. */
:root[data-mode="home"] #toolbar .tb-filter-group,
:root[data-mode="home"] #toolbar .tb-cluster,
:root[data-mode="home"] #toolbar .tb-find-pair {
  opacity: 0.45; filter: grayscale(1); pointer-events: none;
}

/* Dropdown styled to match toolbar buttons */
.tb-select-wrap {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 4px 3px 8px; border-radius: 4px;
  border: 1px solid var(--border-dark); background: var(--surface);
  font-size: 12px; cursor: pointer; flex-shrink: 0;
}
.tb-select-wrap:hover { background: var(--hover-soft); }
.tb-select-wrap.active { background: var(--accent); color: var(--on-solid); border-color: var(--accent); }
.tb-select-wrap.active .tb-select { color: var(--on-solid); }
.tb-select {
  border: none; outline: none; background: transparent;
  font: inherit; color: inherit; padding: 0 4px 0 0;
  cursor: pointer; min-width: 0;
}

/* Responsive: at narrower widths, collapse button labels to icon-only */
@media (max-width: 1280px) {
  .app-name.tb-label { display: none; }
}
@media (max-width: 900px) {
  .toolbar-right .tb-label { display: none; }
}
.tb-btn:hover    { background: var(--hover-soft); }
.tb-btn:disabled { opacity: .45; cursor: default; }
.tb-btn.tb-warn  { color: var(--warn-text); border-color: var(--warn); }
.tb-btn.tb-warn:hover { background: var(--warn-soft-bg); }
.tb-btn.tb-icon  { padding: 4px 8px; font-size: 15px; }
.tb-btn.tb-small { padding: 2px 7px; font-size: 11px; }
.tb-btn.active   { background: var(--accent); color: var(--on-solid); border-color: var(--accent); }
/* .tb-btn.tb-quit removed with the standalone Sign out text button (Iris
   aicleanup-redesign §4, Stage 3B) — Sign out now lives in the avatar Account
   menu (#account-menu), styled by the shared .tb-more-menu / .more-overflow-row. */

.badge {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--danger); color: var(--on-solid); border-radius: 10px;
  font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; padding: 0 4px;
}

#user-pill {
  display: flex; align-items: center; gap: 6px;
  /* No pill chrome — only the avatar shows now (the user-name is hidden), so the
     pill border/padding/radius/bg drew a grey ring around the circle. Removed;
     the avatar stands alone (Jeremy 2026-06-22 "grey line around J"). */
}
#user-avatar {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: var(--cck-accent-on);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
}
#user-name  { font-size: 12px; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.btn-link   { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 11px; padding: 0; }
.btn-link:hover { text-decoration: underline; }

/* ── EXPLORER ────────────────────────────────────────────────── */
#explorer {
  grid-area: explorer;
  display: flex; overflow: hidden;
  /* Positioning context for the #overview overlay (Iris overview spec §1.1).
     The overlay is inset:0 inside #explorer's PADDED box, so the docked
     Inspector area (#explorer's padding-right: var(--inspector-w)) is
     respected automatically — no separate width math needed. */
  position: relative;
}

/* ── OVERVIEW — "what needs attention" landing surface ──────────
   Iris overview spec. Absolute overlay over the explorer area; toolbar +
   status bar stay live. Zero new tokens — every var() below already exists
   in :root / :root[data-theme="dark"]. One new component family: .ov-*. */
#overview {
  position: absolute;
  inset: 0;                       /* fills #explorer's padded box */
  /* FOCUS layer (Iris overview-focus spec): the Overview covers the whole
     working area — the explorer tree AND the inspector — so nothing behind it
     is reachable while it's up. z-index 300 sits ABOVE the inspector rail (250)
     and below the modal scrim. No padding-right reserve: it covers the rail
     instead of clearing it. Dismiss (✕ / Home / card) reveals the untouched
     inspector. Supersedes the earlier P1-2 reserve. */
  z-index: 300;
  background: var(--bg);
  overflow-y: auto;
  /* Enter/exit transition (spec §1.2): opacity + translateY on the locked
     motion tokens. .ov-hiding drives the exit; [hidden] is the resting off-state. */
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--motion-duration) var(--motion-easing),
              transform var(--motion-duration) var(--motion-easing);
}
#overview[hidden] { display: none; }
/* Enter-from state. Polish sweep 2026-07-03: the enter FADE is retired — the
   first cockpit render can block the main thread long enough that the
   half-faded frame freezes with the explorer bleeding through (seen on every
   module switch). An instant, opaque swap reads as fast, not broken; the
   exit fade stays (it reveals, never overlaps). */
#overview.ov-entering { opacity: 1; transform: none; }
/* Exit state: applied on dismiss; transitionend → [hidden]. */
#overview.ov-hiding   { opacity: 0; transform: translateY(4px); }

/* ── OTTO — two-pane magic mover (Iris master-design §C.3 / §D.4) ──────
   Batch A1 SCAFFOLD: the mode + the two framed tree windows + tree texture.
   No plan, no animations, no execution (those are A2–A5). Same overlay
   envelope as #overview — absolute, inset:0 in #explorer's padded box, so the
   docked Inspector area is respected automatically. Peer-mode, not modal.
   Zero new tokens beyond the §D.1 --ftype-* / --row-icon-size added above. */
#otto-mover {
  position: absolute;
  inset: 0;                         /* top/left/bottom 0 */
  /* DELTA-1 ROOT-CAUSE FIX (Iris A1): an abspos element's containing block is
     #explorer's PADDING box (content + padding), so `inset:0`/`right:0` fills
     the FULL width and #explorer's `padding-right: var(--inspector-w)` does NOT
     inset the overlay — the windows rendered UNDER the docked Inspector (right
     window slid 324px under it at standard width; measured live). #overview hides
     this with `max-width:1040; margin:auto`, but the mover wants the full width
     and DID overflow. Reserve the Inspector width here so the overlay stops at
     the Inspector's left edge; collapse-on-enter then frees the windows to their
     full §D.4 size (640px each at 1440 — verified live). Transition matches the
     #explorer padding-right transition so it animates in lockstep. */
  right: var(--inspector-w);
  z-index: 300;                     /* same focus layer as #overview */
  background: var(--bg);
  display: flex; flex-direction: column;
  overflow: hidden;
  opacity: 1;
  transition: opacity var(--motion-duration) var(--motion-easing),
              right 220ms var(--inspector-ease);
}
#otto-mover[hidden] { display: none; }
#otto-mover.otto-entering { opacity: 0; }
#otto-mover.otto-hiding   { opacity: 0; }

/* ── Cross-pane flight layer (Kit's flying-clone mechanism, Iris §B.1) ─────────
   The animated flyer must LEAVE the clipping subtree (#otto-mover overflow:hidden
   → .otto-window overflow:hidden → .otto-window-body overflow-y:auto). This layer
   is position:fixed (NOT clipped by #otto-mover's overflow:hidden — fixed escapes
   ancestor overflow) and its coordinate space IS the viewport, matching what
   getBoundingClientRect returns. z-290 sits above the windows but below the bar;
   the flyer travels mid-stage so it never reaches the bar/footer. INVARIANT: no
   transform/filter on #app or #otto-mover or fixed anchoring breaks (see Kit). */
.otto-flight-layer {
  position: fixed;
  inset: 0;
  z-index: 290;
  pointer-events: none;
  overflow: visible;
}
/* Iris fly-refinements R1 (2026-06-25): the flier is the ITEM ONLY — icon+name
   gliding on transparency, content-width, no row bar / selection fill / accent
   border / dupe border / striped bg / elevation. The clone has its state classes
   stripped in JS (_ottoMakeFlyer); these resets neutralise anything that survives,
   incl. the !important selection/dupe/:hover borders and the ::before/::after pills. */
.otto-flier {
  position: fixed;
  display: inline-flex;
  align-items: center;
  width: auto;
  max-width: none;
  height: var(--row-h);
  padding: 0;
  background: transparent;
  box-shadow: none;
  border: none;
  border-radius: 0;
  color: var(--text);
  white-space: nowrap;
  overflow: visible;
  will-change: transform, opacity;
}
.otto-flier.selected,
.otto-flier.multi-selected,
.otto-flier:hover,
.otto-flier:nth-child(odd),
.otto-flier:nth-child(even) {
  background: transparent !important;
  border-left: none !important;
}
.otto-flier::before,
.otto-flier::after {
  display: none !important;
}

/* Otto bar — 48px header strip (§C.3.1). Scaffold: avatar glyph + proposal
   line (aria-live) + exit ✕. Score chip is a reserved A2 slot. */
.otto-bar {
  height: 48px; flex-shrink: 0;
  display: flex; align-items: center; gap: 12px;   /* Iris §C.4: de-cram the bar (was 16) — title + identity cluster breathe without spilling */
  padding: 0 24px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.otto-bar-avatar {
  width: 28px; height: 28px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--surface-3); color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--border);   /* Iris #7: a soft ring anchors Otto's persona in the disc */
}
.otto-bar-line {
  flex: 1; min-width: 0;
  font-size: 15px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.otto-bar-exit {
  flex-shrink: 0;
  margin-left: 4px;                  /* Iris #10: a hair of breathing room so × doesn't kiss the score pill */
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text-dim);
  cursor: pointer;
  transition: background var(--motion-duration) var(--motion-easing),
              color var(--motion-duration) var(--motion-easing);
}
.otto-bar-exit:hover { background: var(--hover-soft); color: var(--text); }
.otto-bar-exit:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── Otto Batch B — gamification chrome (muted, quality-based, §C.5) ──────────
   Linear, not Duolingo: restraint is the brand. The level indicator, the
   tidy-points score chip, and the `disconnected` leaderboard reserved seat all
   live on the right of the 48px Otto bar. 8-pt grid, tokens only (zero raw hex),
   press/hover/focus defined, holds in both themes. */

/* Level — compact: title + a slim 4px progress bar to the next level (§C.5). */
.otto-level {
  flex-shrink: 0;
  display: flex; flex-direction: column; gap: 4px;
  min-width: 148px; max-width: 200px;             /* Iris #9: widen so the identity reads in full */
  padding-left: 16px;
  border-left: 1px solid var(--border);           /* Iris #8: a hairline divider separates the gamification identity from the title */
}
.otto-level[hidden] { display: none; }
.otto-level-title {
  font-size: 13px; font-weight: 600; color: var(--text);   /* Iris #9: level identity is primary, not dim microcopy */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.otto-level-track {
  position: relative;
  height: 4px; border-radius: 6px;
  background: var(--row-progress-track);
  overflow: hidden;
}
.otto-level-fill {
  position: absolute; inset: 0 auto 0 0;
  height: 100%; border-radius: 6px;
  background: var(--accent);
  transition: width var(--motion-duration) var(--motion-easing);
}
.otto-level-sub {
  font-size: 12px; font-weight: 400; color: var(--text-dim);   /* Iris #9: 11px/faint was the "microscopic" unreadable line — 12/dim is the legibility floor */
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Score chip — a compact muted pill: sparkles glyph + the points, count-up on
   award (§C.5). --surface-3, tabular numerals (the app sets tnum). */
.otto-score {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface-3); color: var(--text);
  font-size: 12px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.otto-score[hidden] { display: none; }
.otto-score-glyph { color: var(--accent); display: inline-flex; }
.otto-score-glyph svg { width: 14px; height: 14px; }
.otto-score-num { line-height: 1; }
/* Count-up flourish — a single restrained pop on the gained delta (reduced-motion
   strips it below; the number changing IS the feedback either way). */
@keyframes otto-score-gain {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}
.otto-score-gain { animation: otto-score-gain 320ms var(--motion-easing); }

/* Leaderboard — the `disconnected` reserved seat (Iris LOCKED: dashed, flat,
   muted — NEVER red; one accent "Connect →" as the only saturated thing). Reads
   as "coming", not "broken". */
.otto-leaderboard {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 8px;
  height: 28px; padding: 0 10px;
  border-radius: 6px;
  font-size: 12px;
}
.otto-leaderboard[hidden] { display: none; }
.otto-leaderboard-disconnected {
  border: 1px dashed var(--border);
  background: transparent;            /* flat — no fill, no shadow */
  box-shadow: none;
}
.otto-leaderboard-disconnected .otto-lb-label {
  font-weight: 600; color: var(--text-faint);   /* muted/dim title */
}
.otto-leaderboard-disconnected .otto-lb-connect {
  font-weight: 600; color: var(--accent);        /* the single accent invitation */
}
/* Iris §C.4: when the bar gets tight, the aspirational leaderboard seat yields
   first — keep the level divider + level/score chips, drop the "coming" seat. */
@media (max-width: 1500px) {
  .otto-leaderboard-disconnected { display: none; }
}

/* Stage — the dominant working surface. Two windows + a fixed channel.
   Generosity is a feature of the windows; whitespace a feature of the margins
   (§D.4). Pair padding 24px; channel gap 40px. */
.otto-stage {
  flex: 1; min-height: 0;
  display: flex; align-items: stretch;
  gap: 64px;                        /* Iris §C.3: widen the flight channel (was 40) so it reads as a true channel between the two windows */
  padding: 24px;
  background: var(--surface-2);     /* Iris fidelity #1: lift the stage so the white windows read as raised cards (the surface ladder was collapsed) */
}

/* Each window: a --surface card, flex 1 1 0, min 380, soft cap 640, ≥12 rows
   tall before scrolling (§D.4.1 / §D.4.3). */
.otto-window {
  flex: 1 1 0;
  min-width: 380px;
  max-width: 640px;
  min-height: 440px;
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;               /* Iris #3: card radius (8), not chip (6) — a window is a card */
  box-shadow: var(--elev-2);        /* Iris #2: real elevation so they read as framed windows, not flat regions */
  overflow: hidden;
}
/* Header strip — reuses .pane-toolbar metrics so it reads as a true mini-pane
   (§C.3.2). 28px tall, --surface-2. */
.otto-window-head {
  height: var(--pane-head-h); flex-shrink: 0;
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px;
  background: var(--surface-2);
  /* Iris #4: a crisp rule under the grey header so the window reads as a true
     framed mini-pane. The colhead below is now white (flush with the body), so
     there's exactly ONE head→body rule, not a triple band. */
  border-bottom: 1px solid var(--border);
  font-size: 13px; font-weight: 600; color: var(--text);
}
.otto-window-head .otto-window-count {
  font-size: 12px; font-weight: 400; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
/* One sticky Name-only header row per window, 26px (§C.3.4). */
.otto-window-colhead {
  height: var(--col-head-h); flex-shrink: 0;
  display: flex; align-items: center;
  padding: 0 8px;
  background: var(--surface);       /* Iris #4: white, flush with the body — keeps a single head→body rule */
  border-bottom: 1px solid var(--tree-header-rule);
  font-size: 11px; color: var(--tree-header-fg);
}
.otto-window-body {
  flex: 1; min-height: 0;
  overflow-y: auto;
  /* DELTA-3 (Iris A1): pad the BODY 8px (matching the colhead's `padding:0 8px`)
     instead of padding each row — so .indent owns ALL horizontal row offset and
     the connector guide's 11px origin lines up with the toggle column. */
  padding-left: 8px;
}
.otto-window-body:empty::after {
  content: "No tree loaded yet.";
  display: block; padding: 16px;
  font-size: 12px; color: var(--text-faint);
}

/* ── Tree texture — mover windows only (§C.3.3) ─────────────────────
   Reuses .tree-row / .indent / .tree-toggle / .col-icon grammar; adds the
   connector guides, type-coloured icons, and the chevron toggle. None of this
   touches the main-app trees (#left-tree / #right-tree). */
/* DELTA-3 (Iris A1): the 8px left-pad moved from each .tree-row to
   .otto-window-body above — .indent now owns all horizontal offset, so the
   connector guides + chevrons align column-to-column. */

/* Type-coloured file icons (§C.3.3 #2). The glyph is sized by --row-icon-size
   (§C.4.2 / §D.1); colour is set inline per family via the --ftype-* tokens
   (data-ftype on the row drives the colour). */
.otto-window-body .col-icon {
  width: 18px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.otto-window-body .col-icon svg {
  width: var(--row-icon-size); height: var(--row-icon-size);
}
.otto-window-body .tree-row[data-ftype="doc"]   .col-icon { color: var(--ftype-doc); }
.otto-window-body .tree-row[data-ftype="sheet"] .col-icon { color: var(--ftype-sheet); }
.otto-window-body .tree-row[data-ftype="slide"] .col-icon { color: var(--ftype-slide); }
.otto-window-body .tree-row[data-ftype="image"] .col-icon { color: var(--ftype-image); }
.otto-window-body .tree-row[data-ftype="other"] .col-icon { color: var(--ftype-other); }

/* Connector / guide lines (§C.3.3 #1) — depth wayfinding. A vertical hairline
   on each indent cell, centred on the toggle column (left ~11px within the
   16px indent). Pure CSS pseudo-element — costs nothing, survives scroll. */
.otto-window-body .indent { position: relative; }
.otto-window-body .indent::before {
  content: "";
  position: absolute;
  left: 11px; top: 0; bottom: 0;
  width: 1px;
  background: var(--connector-stroke);
  opacity: 0.55;
}

/* Chevron open/close (§C.3.3 #3) — mover windows ONLY. The main-app trees keep
   their ▶. The mover row's toggle carries a Lucide chevron-right that rotates
   to chevron-down on open (160ms). */
.otto-window-body .tree-toggle {
  width: 14px; height: 14px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-dim); cursor: pointer;
  transition: transform 160ms var(--motion-easing);
}
.otto-window-body .tree-toggle svg { width: 12px; height: 12px; }
.otto-window-body .tree-toggle.open { transform: rotate(90deg); }
.otto-window-body .tree-toggle.leaf { opacity: 0; cursor: default; }

/* Iris §C.1 — kill the grey wall. Every source row carried equal weight, so the
   left pane read as undifferentiated grey. Dim all source rows EXCEPT the one
   Otto is currently proposing; that one stays at full strength so the eye lands
   on it. A soft hover + transition gives the rest life on pointer without
   competing with the current proposal. */
#otto-source-body .tree-row:not(.otto-current-source) { opacity: 0.72; }
#otto-source-body .tree-row.otto-current-source { opacity: 1; }
.otto-window-body .tree-row {
  transition: background var(--motion-duration) var(--motion-easing);
}
.otto-window-body .tree-row:hover { background: var(--hover-soft); }

/* The landing destination row (auto-expanded path target) gets a soft accent
   marker — the current op's "where it belongs" home. */
.otto-window-body .tree-row.otto-landing {
  border-left: 3px solid var(--accent);
  background: var(--surface-3) !important;   /* Iris #11: calm "this is the place" tint, not a hover state stuck on */
}
/* The proposed file shown landed in its home (A2 hint; A3 animates the flight). */
.otto-window-body .tree-row.otto-landing-file {
  background: var(--row-hover);
  font-weight: 600;
}
/* The current proposal pointer in the SOURCE window — the file Otto is on now. */
.otto-window-body .tree-row.otto-current-source {
  border-left: 3px solid var(--accent);
  background: var(--row-hover);
}

/* Otto says — the concierge reason area below the stage (§C.2 / §C.3). Holds the
   FROM/TO/RENAME diff + the "Otto says" reason block. DELTA-5 (Iris A1):
   min-height 64px (on the 8-pt grid) so the strip never collapses + the footer
   rhythm holds; contents vertically centred. */
.otto-says {
  flex-shrink: 0;
  /* Iris §A.1 + §A.2: ONE framed white card (top half). The diff+reason live in
     the content column; a 32px identity rail sits to the left. */
  display: grid; grid-template-columns: 32px 1fr;
  column-gap: 16px; row-gap: 12px; align-items: start;
  margin: 0 24px;
  padding: 20px 24px 16px;
  border: 1px solid var(--border); border-bottom: none;
  border-radius: 8px 8px 0 0;
  box-shadow: var(--elev-1);
  background: var(--surface);       /* Iris §A.1: white card, not the old --surface-2 band */
  font-size: 13px; color: var(--text-dim);
}
/* Iris §A.2: identity rail (col 1) — Otto mark avatar over a confidence dot.
   The dot is duplicated here AND in the "Otto says — <band>" head by design
   (rail = who's speaking + how sure; head = the labelled band). */
.otto-card-rail {
  grid-row: 1 / -1;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding-top: 2px;
}
.otto-card-avatar {
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--surface-3); color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--border);
}
.otto-card-avatar svg { width: 18px; height: 18px; }
.otto-card-dot { width: 8px; height: 8px; }   /* reuses .confidence-dot data-band (incl. low = hollow) */

/* Iris §A.2/§A.3: content column — headline → diff → reason. */
.otto-card-content { min-width: 0; }
.otto-card-headline {
  margin: 0 0 4px;
  font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.3;
}

/* FROM / TO / RENAME diff — reuses the .aw-row label-grid grammar in spirit.
   Label column 12/600 --text-dim, value 13/400 --text (§C.2). */
.otto-diff { display: flex; flex-direction: column; gap: 6px; }   /* Iris §A.3: tighter now the headline carries the proposal */
.otto-diff-row { display: grid; grid-template-columns: 56px 1fr; column-gap: 12px; align-items: baseline; }   /* Iris §A.3: narrower label gutter, 12px label→value */
.otto-diff-label {
  font-size: 11px; font-weight: 600; color: var(--text-dim);   /* Iris §A.3 */
  text-transform: uppercase; letter-spacing: 0.02em;
}
.otto-diff-value { font-size: 13px; color: var(--text); min-width: 0; word-break: break-word; }
.otto-diff-rename { display: flex; flex-direction: column; gap: 2px; }
.otto-diff-was { font-size: 12px; color: var(--text-dim); text-decoration: line-through; opacity: 0.7; }

/* The "Otto says" reason block — the one new component (§C.2): a --surface-3
   tinted panel, radius 6, confidence dot + band + the one-sentence prose. */
.otto-says-reason {
  margin-top: 12px;                 /* de-cramp (Jeremy): 8→12 so the reason separates from the diff */
  display: flex; flex-direction: column; gap: 4px;
  padding: 12px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);   /* Iris #6: accent quote-block edge (matches the .otto-landing 3px grammar) — makes Otto's reasoning the hero of the strip */
  border-radius: 6px;
}
.otto-says-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--text);
}
.otto-says-band { font-size: 12px; font-weight: 400; color: var(--text-dim); }
/* The reason is Otto's actual prose voice — body weight, reads as a sentence. */
.otto-says-prose { font-size: 13px; font-weight: 400; color: var(--text); line-height: 1.4; }

/* §D APPLYING — while a flight is in progress the card content dims + freezes so
   the user reads "this is happening now, hold on". The footer is separately locked
   to "Filing…" (it sits outside .otto-card-content, so it stays readable). The
   thinking avatar is set via data-face in JS. */
.otto-says.otto-applying .otto-card-content { opacity: 0.6; pointer-events: none; }

/* §D EMPTY-WIN / ALL-TIDY — a green-tinted win card, not a grey void. The reason
   block carries a --success left edge (mirrors the --accent edge on a proposal),
   and the win headline reads positive. Existing tokens only; --success is shared
   across both themes. */
.otto-says.otto-win { background: color-mix(in srgb, var(--success) 6%, var(--surface)); }
.otto-says-reason-win { border-left: 3px solid var(--success); }

/* Footer — 48px (§C.2 / §C.3). Skip · Edit · File-it. Paired-decision symmetry
   (Iris rule #5): Skip + File-it share rectangle/height/weight; tone (neutral vs
   accent) differentiates intent. Skip left, Edit + File-it right (footer split). */
.otto-footer {
  height: auto; flex-shrink: 0;
  display: flex; align-items: center; gap: 8px;
  /* Iris §A.1: the bottom half of the ONE framed white card. */
  margin: 0 24px 24px;
  padding: 12px 24px;
  border: 1px solid var(--border); border-top: 1px solid var(--border);
  border-radius: 0 0 8px 8px;
  box-shadow: var(--elev-1);
  background: var(--surface);
}
.otto-footer .otto-footer-spacer { flex: 1; }
.otto-footer:empty { justify-content: flex-end; }
.otto-btn {
  height: 32px; padding: 0 14px; min-width: 76px;   /* Iris §A.4: symmetric button footprint */
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px; border: 1px solid var(--border);
  font-size: 13px; font-weight: 600; cursor: pointer;
  background: var(--surface); color: var(--text);
  transition: background var(--motion-duration) var(--motion-easing),
              transform var(--motion-duration) var(--motion-easing),
              box-shadow var(--motion-duration) var(--motion-easing);
}
.otto-btn:hover { background: var(--hover-soft); }
.otto-btn:active { transform: translateY(1px); }
.otto-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.otto-btn-primary {
  background: var(--accent); color: var(--cck-accent-on); border-color: var(--accent);
  padding: 0 18px; font-weight: 600;   /* Iris §A.4 */
  box-shadow: var(--elev-1);
}
.otto-btn-primary:hover { filter: brightness(1.05); background: var(--accent); }
.otto-btn-neutral { background: var(--surface); color: var(--text-dim); }   /* Iris §A.4 */

/* When the mover mode is active, suppress the #overview overlay underneath
   (they share the z-300 focus layer; only one is ever shown at a time). */
#app[data-mode="otto"] #overview:not([hidden]) { display: none; }

/* ── Single-drop move animation (A3, §C.3.4 / §D.3) ─────────────────
   On File-it the current source row lifts + glides the channel (~440ms), then
   its slot collapses; the destination landing row lands with an arrival pop +
   one --accent ring flash. ~520ms total. Reduced-motion (below) strips the
   travel but KEEPS the ring flash — state feedback, never silence (§D.3). */

/* Source row: lift (scale 1→1.04, raised) then glide right out of the channel. */
@keyframes otto-fly-out {
  0%   { opacity: 1; transform: scale(1) translateX(0); box-shadow: none; }
  18%  { opacity: 1; transform: scale(1.04) translateX(0); box-shadow: var(--elev-2); }
  100% { opacity: 0; transform: scale(0.98) translateX(48px); box-shadow: none; }
}
.otto-window-body .tree-row.otto-fly-out {
  animation: otto-fly-out calc(440ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) both;
  position: relative; z-index: 2;
}
/* Source slot collapses once the file has flown (height + opacity to 0). */
@keyframes otto-collapse {
  from { max-height: var(--row-h, 24px); opacity: 0; }
  to   { max-height: 0; opacity: 0; padding: 0; margin: 0; }
}
.otto-window-body .tree-row.otto-collapsing {
  animation: otto-collapse calc(140ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) both;
  overflow: hidden;
}

/* Destination landing row: arrival pop (restrained ~6% overshoot) + one ring
   flash that fades over ~600ms. The pop reuses the aw-anchor-pop feel. */
@keyframes otto-arrive-pop {
  0%   { transform: scale(0.96); }
  60%  { transform: scale(1.04); }
  100% { transform: scale(1); }
}
@keyframes otto-ring-flash {
  0%   { box-shadow: 0 0 0 0 var(--accent); }
  100% { box-shadow: 0 0 0 6px rgba(0, 120, 212, 0); }
}
/* Landing settle (Iris §B): the landed row holds a brief hover-tint wash that
   eases back to transparent over 900ms so the eye is led to where the file
   came to rest. Appended to the .otto-arrive animation list below. */
@keyframes otto-land-settle {
  0%   { background: var(--row-hover); }
  100% { background: transparent; }
}
.otto-window-body .tree-row.otto-arrive {
  animation: otto-arrive-pop calc(200ms / var(--otto-speed, 1)) cubic-bezier(0.34, 1.56, 0.64, 1) both,
             otto-ring-flash calc(600ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) both,
             otto-land-settle 900ms cubic-bezier(0.2,0,0,1) both;
}

/* Card shake on a failed apply (§B.4 error — the file did NOT move). A short,
   small horizontal shake; the pinned error toast carries the message. */
@keyframes otto-shake {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-5px); }
  40%      { transform: translateX(4px); }
  60%      { transform: translateX(-3px); }
  80%      { transform: translateX(2px); }
}
.otto-says.otto-shake { animation: otto-shake 360ms cubic-bezier(0.4, 0, 0.2, 1) both; }

/* The in-flight footer status ("Filing…") while an op awaits its otto:result. */
.otto-footer .otto-footer-status {
  font-size: 13px; color: var(--text-dim);
}

@media (prefers-reduced-motion: reduce) {
  #otto-mover { transition: none; }
  #otto-mover.otto-entering, #otto-mover.otto-hiding { opacity: 1; }
  .otto-window-body .tree-toggle { transition: none; }
  .otto-btn { transition: none; }
  .otto-btn:active { transform: none; }
  /* Batch B: the score count-up flourish is a flourish, not feedback — the number
     changing IS the feedback. Strip the scale pop; the progress-bar width still
     snaps. (§D.2 — every keyframe block carries its reduce override.) */
  .otto-score-gain { animation: none; }
  .otto-level-fill { transition: none; }
  /* Single-drop: strip the travel/lift/collapse, KEEP the ring flash as state
     feedback (never silence — §D.3). Shake reduces to a single static pulse. */
  .otto-flier { display: none; }   /* no flying clone under reduce (Iris §B.4) */
  .otto-window-body .tree-row.otto-fly-out { animation: none; opacity: 0; }
  .otto-window-body .tree-row.otto-collapsing { animation: none; max-height: 0; opacity: 0; }
  .otto-window-body .tree-row.otto-arrive {
    animation: otto-ring-flash 200ms cubic-bezier(0.4, 0, 0.2, 1) both;
  }
  .otto-says.otto-shake { animation: aw-fade-in 120ms cubic-bezier(0.4, 0, 0.2, 1) both; }
}

/* ── Group-bundle move (A4, §C.3 / §D.3) ───────────────────────────────────────
   When a File-it covers several files bound for the SAME destination, the group's
   source rows stack into a bundle card (cascade + count badge), the bundle flies
   as ONE object down the channel, and on landing the rows fan out at the
   destination (60ms stagger, capped at 5 visible, then instant). ~620ms total.
   Reduced-motion (below) strips the travel/stagger but keeps the fade + ring. */

/* The bundle card the JS overlays on the grouped source rows. It cascades its
   stacked layers in (90ms), shows a count badge, then flies the channel. */
@keyframes otto-bundle-cascade {
  0%   { transform: translateY(6px) scale(0.98); opacity: 0; }
  100% { transform: translateY(0)   scale(1);    opacity: 1; }
}
@keyframes otto-bundle-fly {
  0%   { opacity: 1; transform: scale(1)    translateX(0); box-shadow: var(--elev-2); }
  18%  { opacity: 1; transform: scale(1.03) translateX(0); box-shadow: var(--elev-2); }
  100% { opacity: 0; transform: scale(0.96) translateX(56px); box-shadow: none; }
}
.otto-bundle {
  position: absolute; left: 8px; right: 8px;
  display: flex; align-items: center; gap: 8px;
  height: var(--row-h, 24px); padding: 0 8px;
  border-radius: 6px;
  background: var(--surface-3);
  box-shadow: var(--elev-1);
  z-index: 3; pointer-events: none;
  /* The stacked-card look: two offset pseudo "cards" peeking out behind. */
}
.otto-bundle::before,
.otto-bundle::after {
  content: ''; position: absolute; inset: 0;
  border-radius: 6px; background: var(--surface-2);
  box-shadow: var(--elev-1);
  z-index: -1;
}
.otto-bundle::before { transform: translate(3px, 3px); }
.otto-bundle::after  { transform: translate(6px, 6px); z-index: -2; opacity: 0.7; }
.otto-bundle.otto-bundle-cascading { animation: otto-bundle-cascade calc(90ms / var(--otto-speed, 1)) cubic-bezier(0.2, 0, 0, 1) both; }
.otto-bundle.otto-bundle-fly { animation: otto-bundle-fly calc(380ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) both; }
.otto-bundle .otto-bundle-icon { display: inline-flex; color: var(--ftype-other); flex-shrink: 0; }
.otto-bundle .otto-bundle-icon svg { width: 16px; height: 16px; }
.otto-bundle .otto-bundle-label {
  font-size: 13px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Count badge — chip counter weight (700 is sanctioned for chip counters). */
.otto-bundle .otto-bundle-count {
  margin-left: auto; flex-shrink: 0;
  min-width: 18px; height: 18px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px;
  background: var(--accent); color: var(--cck-accent-on);
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
/* Grouped source rows collapse away once the bundle has formed (they're now
   "inside" the bundle card). */
.otto-window-body .tree-row.otto-bundle-member {
  animation: otto-collapse calc(140ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) calc(90ms / var(--otto-speed, 1)) both;
  overflow: hidden;
}

/* Fan-out at the destination: the grouped files appear, staggered, reusing the
   existing aw-merge-incoming keyframe. The stagger DELAY is set per-file in JS
   (counting landing files, not all rows, so leading folder rows don't shift the
   cap) and capped at 5 visible (§D.3) — file #6+ gets .otto-fanout-instant and
   appears with no travel. The default delay 0 keeps the first file immediate. */
.otto-window-body .tree-row.otto-fanout {
  animation: aw-merge-incoming calc(200ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) both;
}
.otto-window-body .tree-row.otto-fanout-instant { animation: none; }

/* ── Rename transform (A4, §C.3 / §D.3) — the "magic" beat ──────────────────────
   On apply, the destination landing-file row's OLD name strikes through + settles
   to 0.4 opacity, the new house-style name slides up from below (~280ms), and the
   "↳ was: <old>" sub-line stays visible — we never hide what it was. Reuses the
   existing aw-rename-new-in / aw-rename-old-settle keyframes. For rename+move the
   row glides across first (~320ms) then the name morphs on arrival (delayed swap).
   ~520ms total. Reduced-motion (below) swaps instantly but KEEPS the sub-line +
   one ring flash — content, never silence (§D.3). */
.otto-window-body .tree-row.otto-landing-file .otto-rename-new {
  display: block;
  font-weight: 600; color: var(--text);
}
.otto-window-body .tree-row.otto-landing-file .otto-rename-was {
  display: block;
  font-size: 12px; color: var(--text-dim);
  text-decoration: line-through; opacity: 0.4;
}
/* Pure rename (in place): name slides up, old sub-line settles. */
.otto-window-body .tree-row.otto-anim-rename .otto-rename-new {
  animation: aw-rename-new-in calc(280ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) both;
}
.otto-window-body .tree-row.otto-anim-rename .otto-rename-was {
  animation: aw-rename-old-settle calc(280ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) calc(60ms / var(--otto-speed, 1)) both;
}
/* Rename + move: glide across like a move, THEN morph the name on arrival
   (name-swap delayed behind the glide). */
.otto-window-body .tree-row.otto-anim-rename-move {
  animation: aw-move-glide-in calc(320ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) both;
}
.otto-window-body .tree-row.otto-anim-rename-move .otto-rename-new {
  animation: aw-rename-new-in calc(240ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) calc(200ms / var(--otto-speed, 1)) both;
}
.otto-window-body .tree-row.otto-anim-rename-move .otto-rename-was {
  animation: aw-rename-old-settle calc(240ms / var(--otto-speed, 1)) cubic-bezier(0.4, 0, 0.2, 1) calc(240ms / var(--otto-speed, 1)) both;
}

@media (prefers-reduced-motion: reduce) {
  /* Group bundle: no cascade, no fly, no stagger — source rows drop instantly,
     destination rows appear as a group; the landing ring flash is the feedback. */
  .otto-bundle.otto-bundle-cascading,
  .otto-bundle.otto-bundle-fly { animation: none; }
  .otto-bundle.otto-bundle-fly { opacity: 0; }
  .otto-window-body .tree-row.otto-bundle-member { animation: none; max-height: 0; opacity: 0; }
  .otto-window-body .tree-row.otto-fanout {
    animation: aw-fade-in 120ms cubic-bezier(0.4, 0, 0.2, 1) both;
    animation-delay: 0ms !important;
  }
  .otto-window-body .tree-row.otto-fanout-instant { animation: aw-fade-in 120ms cubic-bezier(0.4, 0, 0.2, 1) both; }
  /* Rename transform: name swaps instantly; the "↳ was:" sub-line + strikethrough
     carry the meaning (they're content, not motion). No slide. */
  .otto-window-body .tree-row.otto-anim-rename .otto-rename-new,
  .otto-window-body .tree-row.otto-anim-rename .otto-rename-was,
  .otto-window-body .tree-row.otto-anim-rename-move,
  .otto-window-body .tree-row.otto-anim-rename-move .otto-rename-new,
  .otto-window-body .tree-row.otto-anim-rename-move .otto-rename-was { animation: none; }
}

/* ── Settings home sheet (Iris master-design §C.4) ────────────────────────────
   Left section nav + right content; opened from the toolbar gear. Auto-saves.
   8-pt grid throughout (4/8/12/16/20/24/32), sheet radius 12px (panel/sheet),
   cards 8px, controls/inputs 6px. One accent, hairline --border, restrained
   depth (overlay = --elev-2). Holds in both themes (all colours are tokens). */
.settings-sheet {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  transition: opacity var(--motion-duration) var(--motion-easing);
}
.settings-sheet.open { opacity: 1; }
.settings-sheet[hidden] { display: none; }
.settings-scrim {
  position: absolute; inset: 0;
  background: rgba(15, 18, 22, 0.42);
}
.settings-panel {
  position: relative;
  display: flex; flex-direction: column;
  width: min(760px, calc(100vw - 64px));
  height: min(560px, calc(100vh - 80px));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--elev-2);
  overflow: hidden;
  transform: translateY(8px);
  transition: transform var(--motion-duration) var(--motion-easing);
}
.settings-sheet.open .settings-panel { transform: translateY(0); }

.settings-header {
  display: flex; align-items: center; justify-content: space-between;
  height: 48px; padding: 0 16px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  cursor: grab;            /* FIX 3: header is the drag handle (JS sets grabbing while dragging) */
  user-select: none;      /* don't text-select the title while dragging */
}
.settings-title { font-size: 15px; font-weight: 600; color: var(--text); }
.settings-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border: 1px solid transparent; border-radius: 6px;
  background: transparent; color: var(--text-dim);
  cursor: pointer;
  transition: background var(--motion-micro) var(--motion-easing), color var(--motion-micro) var(--motion-easing), border-color var(--motion-micro) var(--motion-easing);
}
.settings-close:hover { background: var(--surface-2); color: var(--text); }
.settings-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.settings-close:active { transform: translateY(1px); }

.settings-main { display: flex; flex: 1 1 0; min-height: 0; }

/* Left section nav — grouped rail with leading icons + accent-pill active state
   (Iris settings-redesign §2). */
.settings-nav {
  flex: 0 0 190px;
  display: flex; flex-direction: column;
  padding: 12px 10px;
  border-right: 1px solid var(--border);
  background: var(--surface-2);
  overflow-y: auto;
}
.settings-nav-group { display: flex; flex-direction: column; gap: 2px; }
.settings-nav-group + .settings-nav-group { margin-top: 14px; }
.settings-nav-group-divider { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.settings-nav-grouplabel {
  padding: 0 8px 4px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-faint);
}
.settings-nav-item {
  display: flex; align-items: center; gap: 9px;
  height: 36px; padding: 0 8px;
  border: 0; border-radius: 7px;
  background: transparent;
  font-size: 13px; font-weight: 400; color: var(--text-dim);
  text-align: left; cursor: pointer;
  transition: background var(--motion-micro) var(--motion-easing), color var(--motion-micro) var(--motion-easing);
}
.settings-nav-icon { display: inline-flex; flex-shrink: 0; width: 16px; height: 16px; color: currentColor; }
.settings-nav-icon svg, .settings-nav-icon .lucide { width: 16px; height: 16px; stroke-width: 2; }
.settings-nav-label { flex: 1 1 auto; min-width: 0; }
.settings-nav-item:hover { background: var(--surface-3); color: var(--text); }
.settings-nav-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.settings-nav-item.active { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); font-weight: 500; }
.settings-nav-item.active:hover { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.settings-nav-soon {
  flex-shrink: 0; padding: 1px 6px; border-radius: 999px; background: var(--surface-3);
  font-size: 10px; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase; color: var(--text-faint);
}
.settings-nav-item.active .settings-nav-soon { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }

/* Right content. */
.settings-content {
  flex: 1 1 0; min-width: 0;
  padding: 24px;
  overflow-y: auto;
}
/* Section head + control-row grid (Iris settings-redesign §3). */
.settings-section-head { margin: 0 0 4px; }
.settings-section-title { margin: 0; font-size: 16px; font-weight: 500; color: var(--text); letter-spacing: -0.01em; }
.settings-section-desc { margin: 4px 0 0; font-size: 13px; font-weight: 400; color: var(--text-dim); line-height: 1.45; }
.settings-rows { margin-top: 16px; border-top: 1px solid var(--border); }
.settings-rowitem { display: flex; align-items: center; justify-content: space-between; gap: 24px; min-height: 52px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.settings-rowitem-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.settings-rowitem-label { font-size: 14px; font-weight: 400; color: var(--text); }
.settings-rowitem-desc { font-size: 12px; font-weight: 400; color: var(--text-dim); line-height: 1.4; }
.settings-rowitem-control { flex-shrink: 0; display: flex; align-items: center; gap: 12px; }
.settings-rowitem.settings-field-disabled { opacity: 0.45; }
/* Stacked variant — control row above, extra (preview / chips / inset) below. */
.settings-rowitem-stack { flex-direction: column; align-items: stretch; gap: 12px; }
.settings-rowitem-stack .settings-rowitem-head { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
/* When the control is the wide Filing-mode card, stack the label/description
   ABOVE it (full width) instead of side-by-side — otherwise the text column gets
   crushed to one-word-per-line (Jeremy 2026-06-30). */
.settings-rowitem-stack .settings-rowitem-head:has(.settings-mode-card) {
  flex-direction: column; align-items: stretch; gap: 6px;
}
.settings-rowitem-head:has(.settings-mode-card) .settings-rowitem-control { width: 100%; }
.settings-rowitem-head:has(.settings-mode-card) .settings-mode-card { width: 100%; box-sizing: border-box; margin-top: 4px; }
.settings-rowitem-stack .settings-rowitem-extra {}

.settings-placeholder { font-size: 13px; color: var(--text-dim); margin: 0; line-height: 1.5; }

.settings-field { margin-bottom: 24px; }
.settings-field:last-child { margin-bottom: 0; }
.settings-field-disabled { opacity: 0.45; }
.settings-label {
  display: block;
  font-size: 13px; font-weight: 600; color: var(--text);
  margin-bottom: 12px;
}
.settings-hint {
  margin: 8px 0 0;
  font-size: 12px; font-weight: 400; color: var(--text-dim); line-height: 1.4;
}

.settings-row { display: flex; align-items: center; gap: 12px; }
.settings-slider {
  flex: 1 1 0; min-width: 120px; height: 4px; margin: 0;
  accent-color: var(--accent); cursor: pointer;
}
.settings-slider:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.settings-slider:disabled { cursor: default; }
.settings-value {
  flex-shrink: 0; min-width: 42px; text-align: right;
  font-size: 13px; font-weight: 500; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.settings-value-min { flex-shrink: 0; font-size: 12px; color: var(--text-dim); }
.settings-prev-glyph {
  flex-shrink: 0; display: inline-flex; color: var(--text-dim);
}
.settings-prev-glyph svg { width: 14px; height: 14px; }
.settings-prev-glyph-lg svg { width: 20px; height: 20px; }
/* Clickable steppers: small (−1) / large (+1). Button reset + hover affordance. */
.settings-prev-step {
  background: none; border: none; padding: 2px; margin: 0; cursor: pointer;
  border-radius: 5px; align-items: center; justify-content: center;
  transition: background-color var(--motion-micro) var(--motion-easing), color var(--motion-micro) var(--motion-easing);
}
.settings-prev-step:hover { background: var(--hover-soft); color: var(--text); }
.settings-prev-step:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Font picker (and any future settings dropdown). */
.settings-select {
  font-family: inherit; font-size: 13px; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 7px;
  padding: 6px 10px; cursor: pointer; min-width: 200px;
}
.settings-select:hover { background: var(--hover-soft); }
.settings-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Icon-size live preview — resizes with --row-icon-size as the slider moves.
   margin-top:0 — sits in `.settings-rowitem-extra`; the stack gap owns spacing. */
.settings-preview {
  margin-top: 0; padding: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 8px;
  display: flex; flex-direction: column; gap: 4px;
}
.settings-preview-row {
  display: flex; align-items: center; gap: 8px;
  min-height: var(--row-h);   /* mirror the live tree row height */
}
.settings-preview-icon { display: inline-flex; flex-shrink: 0; color: var(--text-dim); }
.settings-preview-icon svg { width: var(--row-icon-size); height: var(--row-icon-size); }
.settings-preview-name {
  font-size: var(--row-text-size);   /* mirror the live filename/attribute size */
  color: var(--text);
}

/* Segmented control — Off / Subtle / Full (Iris settings-redesign §4). */
.settings-segmented {
  display: inline-flex;
  border: 1px solid var(--border); border-radius: 7px;
  background: var(--surface-2);
  padding: 2px;
}
.settings-seg {
  height: 26px; padding: 0 14px;
  border: 0; border-radius: 5px;
  background: transparent;
  font-size: 13px; font-weight: 400; color: var(--text-dim);
  cursor: pointer;
  transition: background var(--motion-micro) var(--motion-easing), color var(--motion-micro) var(--motion-easing), box-shadow var(--motion-micro) var(--motion-easing);
}
.settings-seg:hover:not(.active) { color: var(--text); }
.settings-seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.settings-seg.active {
  background: var(--surface);
  color: var(--text); font-weight: 500;
  box-shadow: var(--elev-1);
}

/* Toggle (respect system reduced-motion). */
.settings-toggle {
  display: inline-flex; align-items: center; gap: 12px;
  cursor: pointer;
}
.settings-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.settings-toggle-track {
  position: relative; flex-shrink: 0;
  width: 36px; height: 20px;
  background: var(--surface-3);
  border: 1px solid var(--border); border-radius: 12px;
  transition: background var(--motion-micro) var(--motion-easing);
}
.settings-toggle-track::after {
  content: ""; position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 14px;
  background: var(--surface);
  border-radius: 50%;
  box-shadow: var(--elev-1);
  transition: transform var(--motion-micro) var(--motion-easing);
}
.settings-toggle input:checked + .settings-toggle-track {
  background: var(--accent); border-color: var(--accent);
}
.settings-toggle input:checked + .settings-toggle-track::after { transform: translateX(16px); }
.settings-toggle input:focus-visible + .settings-toggle-track { outline: 2px solid var(--accent); outline-offset: 2px; }
.settings-toggle-text { font-size: 13px; font-weight: 400; color: var(--text); }

/* Number input — Audits CHECK-age + New-files custom days. Mirrors the
   segmented/value tokens so it reads as one family with the sliders. */
.settings-number {
  width: 64px; height: 28px; padding: 0 8px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface-2);
  font-size: 13px; font-weight: 600; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.settings-number:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.settings-number:disabled { cursor: default; opacity: 0.6; }

/* Segmented control that wraps when it carries more than three options
   (CHECK-age presets, New-files window). Same chip styling, multi-line.
   margin-top:0 — inside a stacked row the `.settings-rowitem-stack` gap owns the
   spacing (Iris settings-redesign §3c).
   display:flex (not the base inline-flex) so the control takes the full width of
   its `.settings-rowitem-extra` cell — without it the 5-option New-files window
   (Since last visit / Last day / Last week / Last 30 days / Custom) overflows the
   ~360px pane instead of wrapping to a second line (Jeremy 2026-06-25). The 4
   short Audits presets still sit on one line; they just left-align in the wider
   box. row-gap pairs with the existing inter-chip gap so wrapped rows breathe. */
.settings-segmented-wrap { display: flex; flex-wrap: wrap; row-gap: 2px; margin-top: 0; }

/* Advanced pane — Preview↔Real master switch (Iris previewmode-toggle §6).
   The card's data-mode drives a restrained accent: Preview = accent left-bar on
   --surface-2; Real = danger left-bar + soft danger wash + danger-tinted active
   "Real" segment. Zero new tokens. */
.settings-mode-card {
  margin-top: 8px; padding: 16px;
  border: 1px solid var(--border); border-left-width: 3px; border-left-color: var(--accent);
  border-radius: var(--radius); background: var(--surface-2);
  transition: background var(--motion-micro) var(--motion-easing), border-left-color var(--motion-micro) var(--motion-easing);
}
.settings-mode-card[data-mode="real"] { border-left-color: var(--btn-danger-bg); background: var(--danger-soft-bg); }
.settings-mode-card[data-mode="real"] .settings-seg.active[data-mode-val="real"] { color: var(--btn-danger-bg); }
.settings-mode-state { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; font-size: 12px; font-weight: 400; color: var(--text-dim); line-height: 1.4; }
.settings-mode-state strong { font-weight: 600; color: var(--text); }
.settings-mode-state::before { content: ""; flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.settings-mode-card[data-mode="real"] .settings-mode-state::before { background: var(--btn-danger-bg); }
@media (prefers-reduced-motion: reduce) { .settings-mode-card { transition: none; } }

/* Inset row under a segmented control (the custom-days field for New files).
   margin-top:0 — the stacked-row gap owns the spacing (§3c). */
.settings-row-inset { margin-top: 0; }

/* Account pane — connection summary + sign-out. The identity block sits in the
   row control on the right; align it right so name/email read as a unit. */
.settings-account-line { margin: 0; font-size: 13px; color: var(--text); }
.settings-account-id { gap: 2px; text-align: right; }
.settings-account-email { margin: 0; }
.settings-signout { padding: 0; }

@media (prefers-reduced-motion: reduce) {
  .settings-sheet, .settings-panel,
  .settings-close, .settings-nav-item, .settings-seg,
  .settings-toggle-track, .settings-toggle-track::after { transition: none; }
}

.ov-inner {
  max-width: 1040px;              /* spec §3.1 — keep the 2×2 from stretching wide */
  margin: 0 auto;
  padding: 24px 0 8px;
}

/* ── Status line (spec §2) ── */
.ov-statusline {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 0 24px;
  margin-bottom: 24px;
}
.ov-statusline-left { min-width: 0; }
.ov-statusline-head {
  display: flex; align-items: center; gap: 8px;
}
/* Attention dot — reuses the freshness-dot pattern (8px circle), driven by
   data-attn on the .ov-statusline container (spec §2.1). */
.ov-attn-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex: none;
  background: var(--warn);        /* amber — the "needs attention" register */
}
.ov-attn-tick { display: inline-flex; color: var(--success-text); flex: none; }
.ov-attn-tick .lucide-icon { display: block; }
.ov-statusline[data-attn="clean"] .ov-attn-dot  { display: none; }
.ov-statusline[data-attn="dirty"] .ov-attn-tick { display: none; }
.ov-headline {
  font: 600 16px/20px inherit;    /* the 16px ramp step — surface title */
  color: var(--text);
  margin: 0;
}
.ov-summary {
  font: 400 13px/18px inherit;
  color: var(--text-dim);
  margin: 4px 0 0;
  padding-left: 16px;             /* align under the headline text, past the dot */
}
.ov-statusline-right {
  display: flex; align-items: center; gap: 12px;
  flex: none;
}
.ov-checked {
  font: 400 12px/16px inherit;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Refresh icon single-rotation on click (spec §2.3 / §10). */
#ov-refresh .tb-glyph,
#ov-refresh .lucide-icon { transition: transform var(--motion-duration) var(--motion-easing); }
#ov-refresh.ov-spinning .tb-glyph,
#ov-refresh.ov-spinning .lucide-icon { transform: rotate(360deg); }

/* ── Launch-card grid (spec §3.1) ── */
.ov-grid {
  display: grid;
  /* Spec §3.1 RATIFIES a 2×2 layout at the canonical width. Its literal
     minmax(300px,…) value, against the 1040px .ov-inner cap (992px usable
     after the 24px side padding), actually fits THREE 320px columns → a 3+1
     layout, not 2×2. Raising the floor to 340px forces exactly two columns
     within the cap (2×340+16 = 696 ≤ 992; 3×340+32 = 1052 > 992) while still
     reflowing to ONE column when the docked Inspector eats width (the
     intrinsic auto-fit behaviour the spec wants — no media query). Flagged
     to Iris: this is honouring the ratified 2×2 over the literal 300px. */
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 16px;
  padding: 0 24px;
}

/* ── The card (spec §3.2) — the one new component ── */
.ov-card {
  display: flex; flex-direction: column;
  gap: 8px;
  padding: 16px;                  /* scale-clean per spec §3.2 correction */
  min-height: 168px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--elev-1);
  cursor: pointer;
  text-align: left;
  transition: box-shadow var(--motion-duration) var(--motion-easing),
              border-color var(--motion-duration) var(--motion-easing),
              transform var(--motion-duration) var(--motion-easing);
}
.ov-card:hover {
  box-shadow: var(--elev-2);
  border-color: var(--border-dark);
  transform: translateY(-2px);
}
.ov-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Clean category — inert, dashed, no launch (spec §3.2 / §11). */
.ov-card[data-empty="1"] {
  cursor: default;
  box-shadow: none;
  border-style: dashed;
}
.ov-card[data-empty="1"]:hover {
  transform: none; box-shadow: none; border-color: var(--border);
}

/* Icon tile — where category colour lives (spec §3.3). */
.ov-card-icon {
  width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  margin-bottom: 4px;             /* 12px icon→label gap = 8px col-gap + 4px */
  flex: none;
}
.ov-card-icon .lucide-icon { display: block; }
.ov-card[data-cat="duplicates"] .ov-card-icon { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.ov-card[data-cat="misfiled"]   .ov-card-icon { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.ov-card[data-cat="new"]        .ov-card-icon { background: var(--action-pill-info-bg);    color: var(--action-pill-info-fg); }
.ov-card[data-cat="stale"]      .ov-card-icon { background: var(--action-pill-check-bg);   color: var(--action-pill-check-fg); }

/* Card text (spec §3.4) */
.ov-card-label {
  font: 600 11px/14px inherit;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}
.ov-card-count {
  font: 600 28px/32px inherit;    /* the app's single display size */
  color: var(--text);
  font-variant-numeric: tabular-nums;
  min-height: 32px;               /* keep slot height so the grid stays aligned */
  display: flex; align-items: center;
}
.ov-card-count .ov-card-tick { display: inline-flex; color: var(--success-text); }
.ov-card-count .ov-card-tick .lucide-icon { display: block; }
.ov-card-detail {
  font: 400 13px/18px inherit;
  color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* "Review →" affordance (spec §3.5) */
.ov-card-review {
  margin-top: auto;               /* pin to card bottom */
  align-self: flex-end;
  display: inline-flex; align-items: center; gap: 4px;
  font: 600 12px/16px inherit;
  color: var(--accent);
}
.ov-card:hover .ov-card-review { color: var(--accent-hover); }
.ov-card-review .lucide-icon { display: block; }
.ov-card[data-empty="1"] .ov-card-review { display: none; }

/* ── Footer line (spec §4) ── */
.ov-footer {
  display: flex; align-items: center; gap: 8px;
  padding: 16px 24px;
  margin: 8px 24px 0;
  border-top: 1px solid var(--border);
  font: 400 12px/16px inherit;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.ov-footer .lucide-icon { color: var(--text-faint); flex: none; }

/* Reduced motion (spec §1.2 / §10): drop transforms, keep opacity fades. */
@media (prefers-reduced-motion: reduce) {
  #overview,
  #overview.ov-entering,
  #overview.ov-hiding { transform: none; }
  .ov-card:hover { transform: none; }
  #ov-refresh.ov-spinning .tb-glyph,
  #ov-refresh.ov-spinning .lucide-icon { transform: none; }
  /* Pane resize settle is instant under reduced motion. */
  .pane,
  #app #explorer { transition: none; }
  .cck-item { transition: none; }
}

/* ══ COCKPIT (DEFINE_cockpit.md) — pulse · Today ranked · approvals ══
   The chief-of-staff sections inside the Overview envelope. Aligns to the
   same 24px side gutter as .ov-statusline / .ov-grid. Tokens only. */

/* Business pulse strip */
.cck-pulse {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  padding: 0 24px;
  margin-bottom: 24px;
}
.cck-stat {
  background: var(--surface-3);
  border-radius: 8px;
  padding: 12px 16px;
}
.cck-stat-head {
  display: flex; align-items: center; gap: 8px;
  font: 400 12px/16px inherit;
  color: var(--text-dim);
}
.cck-stat-head .lucide-icon { color: var(--text-faint); }
.cck-stat-val {
  font: 600 28px/32px inherit;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  margin-top: 4px;
}

/* Section scaffold (Today, Filing header, Approvals) */
.cck-section { padding: 0 24px; margin-bottom: 24px; }
.cck-sec-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 12px;
}
.cck-sec-title {
  display: flex; align-items: center; gap: 8px;
  font: 600 15px/20px inherit; color: var(--text); margin: 0;
}
.cck-sec-hint {
  display: inline-flex; align-items: center; gap: 4px;
  font: 400 12px/16px inherit; color: var(--text-dim);
}
.cck-filing-head { padding: 0 24px; margin-bottom: 12px; }

/* Today, ranked — the priority list */
.cck-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.cck-item {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color var(--motion-duration) var(--motion-easing),
              box-shadow var(--motion-duration) var(--motion-easing);
}
.cck-item:hover { border-color: var(--border-dark); box-shadow: var(--elev-1); }
.cck-item.cck-dragging { opacity: 0.5; }
.cck-grip { color: var(--text-faint); cursor: grab; align-self: center; flex: none; }
.cck-grip .lucide-icon { display: block; }
.cck-rank {
  font: 600 15px/20px inherit; color: var(--text-dim);
  min-width: 16px; text-align: center; flex: none;
  font-variant-numeric: tabular-nums;
}
.cck-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.cck-title-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cck-src { display: inline-flex; color: var(--text-dim); flex: none; }
.cck-src .lucide-icon { display: block; }
.cck-title { font: 600 13px/18px inherit; color: var(--text); }
.cck-due {
  font: 600 11px/14px inherit; padding: 2px 8px; border-radius: var(--radius-pill);
  background: var(--chip-bg); color: var(--chip-fg);
}
.cck-due-today { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.cck-due-overdue { background: var(--danger-soft-bg); color: var(--danger-text); }
.cck-only {
  display: inline-flex; align-items: center; gap: 4px;
  font: 600 11px/14px inherit; padding: 2px 8px; border-radius: var(--radius-pill);
  background: var(--chip-bg); color: var(--chip-fg);
}
.cck-only .lucide-icon { display: block; }
.cck-why {
  display: flex; align-items: flex-start; gap: 4px;
  font: 400 12px/16px inherit; color: var(--text-dim);
}
.cck-why .lucide-icon { color: var(--warn); flex: none; margin-top: 2px; }
.cck-who { font: 400 11px/14px inherit; color: var(--text-faint); }
.cck-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.cck-act {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 8px 12px; border: 1px solid var(--border-dark); border-radius: var(--radius);
  background: var(--surface); color: var(--text); cursor: pointer;
  font: 600 12px/16px inherit; white-space: nowrap;
  transition: background var(--motion-duration) var(--motion-easing);
}
a.cck-act { text-decoration: none; } /* pill grammar: anchors styled as action pills carry no underline (Join Teams / Open in Outlook / Download) */
/* The class display rule defeats [hidden] (the P4.1 gotcha, class edition) —
   Tidy-Up's 'AI scan N unrecognised' + 'Back to the mapping' both toggle the
   attribute; pin the combination for the whole action-pill family. */
.cck-act[hidden] { display: none; }
.cck-act:hover { background: var(--hover-soft); }
.cck-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cck-act-primary { color: var(--accent); }
.cck-act-primary .lucide-icon { display: block; }
.cck-icbtn, .cck-icbtn-text {
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text-dim); cursor: pointer;
  transition: background var(--motion-duration) var(--motion-easing);
}
.cck-icbtn { width: 28px; height: 28px; flex: none; }
.cck-icbtn-text { padding: 8px 12px; font: 600 12px/16px inherit; }
.cck-icbtn:hover, .cck-icbtn-text:hover { background: var(--hover-soft); color: var(--text); }
.cck-icbtn:focus-visible, .cck-icbtn-text:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cck-empty { padding: 12px; }   /* compact list/popover delta on the shared empty-state grammar (P2.1) */

/* Natural-language reprioritise box */
.cck-nl { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.cck-nl .lucide-icon { color: var(--text-faint); flex: none; }
.cck-nl-input {
  flex: 1; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text); font: 400 13px/18px inherit;
}
.cck-nl-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.cck-snoozed-note {
  margin-top: 8px; border: none; background: none; cursor: pointer;
  font: 600 12px/16px inherit; color: var(--accent);
}

/* Approval inbox */
.cck-ap-count {
  font: 600 12px/16px inherit; padding: 2px 8px; border-radius: var(--radius-pill);
  background: var(--chip-bg-active); color: var(--chip-fg);
}
.cck-ap-list {
  list-style: none; margin: 0; padding: 12px 16px;
  background: var(--surface-3); border-radius: var(--radius-panel);
}
.cck-ap { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.cck-ap:last-child { border-bottom: none; }
.cck-ap-icon { display: inline-flex; color: var(--accent); flex: none; }
.cck-ap-icon .lucide-icon { display: block; }
.cck-ap-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cck-ap-label { font: 400 13px/18px inherit; color: var(--text); }
.cck-ap-detail { font: 400 12px/16px inherit; color: var(--text-dim); }
.cck-ap-actions { display: flex; align-items: center; gap: 8px; flex: none; }

/* Snapshot honesty note */
.cck-snapshot {
  display: flex; align-items: center; gap: 4px;
  padding: 0 24px; margin: 8px 0 0;
  font: 400 11px/16px inherit; color: var(--text-faint);
}
.cck-snapshot .lucide-icon { flex: none; }

/* ══ COCKPIT — Mercury-anchored visual language (DESIGN_LANGUAGE.md, 2026-06-30) ══
   Calm + light: a soft-lavender hero, white metric tiles with big tabular numbers,
   soft white rows with pastel icon tiles, indigo pill actions, hairline structure.
   Restraint as luxury. Tokens only. */

/* Brand type — the REAL licensed Extensis fonts, self-hosted: Ivy Presto Headline
   (Light/Light-Italic) for headlines; Inter for UI. (Replaces the Google stand-ins.) */
@font-face { font-family: 'Ivy Presto Headline'; src: url('/fonts/IvyPresto-Light.otf') format('opentype'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Ivy Presto Headline'; src: url('/fonts/IvyPresto-LightItalic.otf') format('opentype'); font-weight: 300; font-style: italic; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('/fonts/Inter-Light.woff2')    format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('/fonts/Inter-Regular.woff2')  format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('/fonts/Inter-Medium.woff2')   format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('/fonts/Inter-SemiBold.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('/fonts/Inter-Bold.woff2')     format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

#overview .ov-inner { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
.cck-header .ov-headline,
.cck-topbar-left .ov-headline,
.cck-sec-title,
.cck-work-title { font-family: 'Ivy Presto Headline', Georgia, 'Times New Roman', serif; }

/* Cooler page wash so the white cards pop against it */
#overview { background: var(--cck-page); }

/* Brand hero — a clean white card (deep navy in dark) */
.cck-header {
  margin: 0 24px 24px; padding: 20px 24px;
  background: var(--cck-hero-bg); border: 0.5px solid var(--border); border-radius: 16px;
  align-items: center;
}
.cck-header-left { display: flex; align-items: center; gap: 14px; min-width: 0; }
.cck-brandmark {
  width: 40px; height: 40px; border-radius: 12px; flex: none; display: block;
  background: var(--surface); padding: 5px; border: 0.5px solid var(--border);
}
.cck-header-titles { min-width: 0; }
.cck-header .ov-headline { color: var(--cck-hero-text); font-size: 32px; line-height: 36px; font-weight: 300; letter-spacing: -0.01em; }
.cck-sec-title { font-size: 21px; line-height: 27px; font-weight: 300; }
.cck-header .ov-summary {
  color: var(--cck-hero-sub); padding-left: 0; margin-top: 3px;
  display: flex; align-items: center; gap: 6px; font-size: 14px;
}
.cck-livedot { width: 7px; height: 7px; border-radius: 50%; background: var(--cck-accent); flex: none; }
.cck-header .ov-checked { color: var(--cck-hero-sub); }
.cck-header-btn.tb-btn { background: var(--surface); color: var(--cck-hero-text); border: 0.5px solid var(--border); border-radius: 999px; }
.cck-header-btn.tb-btn:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-header-btn .tb-glyph, .cck-header-btn .lucide-icon { color: inherit; }

/* Metric tiles — clean white cards, big tabular numbers, tracked text-only labels */
.cck-stat { background: var(--surface); border: 0.5px solid var(--border); border-radius: 16px; padding: 18px; }
.cck-stat-head { text-transform: uppercase; letter-spacing: 0.05em; font-size: 11px; color: var(--text-dim); }
.cck-stat-head .lucide-icon { display: none; }
.cck-stat-val { font-size: 30px; font-weight: 600; letter-spacing: -0.025em; color: var(--cck-hero-text); margin-top: 5px; }

/* Priority rows — soft white cards, pastel icon tile (no heavy spine) */
.cck-item { display: flex; align-items: stretch; gap: 0; padding: 0; overflow: hidden; background: var(--surface); border: 0.5px solid var(--border); border-radius: 16px; }
.cck-item:hover { border-color: var(--border-dark); box-shadow: none; }
.cck-spine { display: none; }
.cck-row { display: flex; align-items: center; gap: 14px; padding: 15px 18px; flex: 1; min-width: 0; }
.cck-grip { color: var(--text-faint); align-self: center; flex: none; }

/* Rank as a quiet number, indigo on the top item */
.cck-rank {
  width: auto; height: auto; min-width: 14px; border-radius: 0; background: none;
  color: var(--text-faint); font: 400 13px/1 inherit; text-align: center; flex: none;
  display: flex; align-items: center; justify-content: center;
}
.cck-rank-top { color: var(--cck-accent); font-weight: 500; }

/* Pastel source tile */
.cck-src { width: 36px; height: 36px; border-radius: 11px; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.cck-src-email   { background: var(--cck-tile-lav);   color: var(--cck-tile-lav-fg); }
.cck-src-meeting { background: var(--cck-tile-blue);  color: var(--cck-tile-blue-fg); }
.cck-src-deal    { background: var(--cck-tile-mint);  color: var(--cck-tile-mint-fg); }
.cck-src-filing  { background: var(--cck-tile-peach); color: var(--cck-tile-peach-fg); }

.cck-title { font-size: 16px; color: var(--cck-hero-text); }

/* Pill actions — filled indigo primary, hairline secondary */
.cck-act, .cck-icbtn { border-radius: 999px; }
.cck-act { padding: 9px 18px; }
.cck-act-filled, .cck-act-primary { background: var(--cck-accent); color: var(--cck-accent-on); border: 0.5px solid var(--cck-accent); }
.cck-act-filled:hover, .cck-act-primary:hover { filter: brightness(0.95); }
.cck-act-filled .lucide-icon, .cck-act-primary .lucide-icon { color: var(--cck-accent-on); }
.cck-act-ghost { background: var(--surface); color: var(--cck-hero-text); border: 0.5px solid var(--border-dark); }
.cck-act-ghost:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }

/* Status pills — one uniform size (fixed height; icon never changes it) */
.cck-due, .cck-only {
  display: inline-flex; align-items: center; gap: 4px;
  height: 22px; padding: 0 10px; border-radius: 999px;
  font-weight: 500; font-size: 11px; line-height: 1; white-space: nowrap;
}
.cck-only .lucide-icon { width: 12px; height: 12px; }
.cck-only { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-due-today { background: var(--cck-tile-peach); color: var(--cck-tile-peach-fg); }
.cck-due-overdue { background: var(--danger-soft-bg); color: var(--danger-text); }

/* Approval inbox — an outlined white card so it stands off the page background */
.cck-ap-list { background: var(--surface); border: 0.5px solid var(--border); border-radius: 16px; padding: 6px 18px; }

/* Filing hygiene cards — tighter, with larger + darker text */
.ov-card { min-height: 132px; border-radius: 16px; box-shadow: none; border: 0.5px solid var(--border); }
.ov-card:hover { box-shadow: none; transform: none; border-color: var(--border-dark); }
.ov-card-label { font-size: 12px; }
.ov-card-count { font-size: 30px; }
.ov-card-detail { font-size: 14px; color: var(--text); }

/* ── Two-pane working area: task/meeting list (left) · working pane (right) ── */
.cck-workspace { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.05fr); gap: 16px; padding: 0 24px; margin-bottom: 24px; align-items: start; }
.cck-workspace .cck-section { padding: 0; margin-bottom: 16px; }
.cck-left, .cck-right { min-width: 0; }
/* The working pane stays pinned while the left list scrolls (reading-pane model);
   it scrolls internally if its content is taller than the viewport. */
.cck-right { position: sticky; top: 16px; align-self: start; max-height: calc(100vh - 140px); overflow-y: auto; }
.cck-item { cursor: pointer; }
.cck-item.cck-selected, .cck-mtg.cck-selected { border-color: var(--cck-accent); box-shadow: inset 0 0 0 1px var(--cck-accent); }

/* Today row action pills — all one width */
.cck-actions .cck-act { min-width: 160px; justify-content: center; }

/* Recent meetings list */
.cck-mtg-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.cck-mtg { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--surface); border: 0.5px solid var(--border); border-radius: 12px; cursor: pointer; transition: border-color var(--motion-duration) var(--motion-easing); }
.cck-mtg:hover { border-color: var(--border-dark); }
.cck-mtg:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 2px; }
.cck-mtg-ic { width: 32px; height: 32px; border-radius: 10px; flex: none; display: inline-flex; align-items: center; justify-content: center; background: var(--cck-tile-lav); color: var(--cck-tile-lav-fg); }
.cck-mtg-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cck-mtg-title { font-size: 14px; font-weight: 500; color: var(--cck-hero-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-mtg-meta { font-size: 12px; color: var(--text-dim); }

/* Working pane (right) */
.cck-work { background: var(--surface); border: 0.5px solid var(--border); border-radius: 16px; padding: 20px; }
/* .cck-work-empty is fully carried by the shared empty-state grammar (P2.1; 14px→13px onto the type ramp). */
.cck-work-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.cck-work-headtext { min-width: 0; }
.cck-work-title { font-size: 21px; line-height: 26px; font-weight: 300; color: var(--cck-hero-text); margin: 0; }
.cck-work-meta { font-size: 13px; color: var(--text-dim); margin-top: 3px; }
.cck-work-actions { display: flex; gap: 8px; flex: 0 1 auto; min-width: 0; justify-content: flex-end; flex-wrap: wrap; } /* flex:none never shrank, so the wrap could not engage — the row clipped at high zoom */
.cck-work-chips { display: flex; gap: 6px; margin-bottom: 12px; }
.cck-work-summary { font-size: 14px; line-height: 1.6; color: var(--text); margin: 0 0 14px; }
.cck-kws { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.cck-kw { font-size: 11px; padding: 3px 10px; border-radius: 999px; background: var(--surface-0); color: var(--text-dim); }
.cck-work-sub { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin-bottom: 8px; }
.cck-owners { display: flex; flex-direction: column; gap: 10px; }
.cck-owner { border: 0.5px solid var(--border); border-radius: 12px; padding: 12px 14px; background: var(--cck-canvas); }
.cck-owner-you { background: var(--cck-accent-soft); border-color: transparent; box-shadow: inset 3px 0 0 var(--cck-accent); }
.cck-owner-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.cck-avatar { width: 24px; height: 24px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-0); color: var(--text-dim); font-size: 10px; font-weight: 600; }
.cck-owner-you .cck-avatar { background: var(--cck-accent); color: var(--cck-accent-on); }
.cck-owner-name { font-size: 13px; font-weight: 500; color: var(--cck-hero-text); display: inline-flex; align-items: center; gap: 6px; }
.cck-you { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 1px 6px; border-radius: 999px; background: var(--cck-accent); color: var(--cck-accent-on); }
.cck-owner-tasks { margin: 2px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 5px; list-style: disc; }
.cck-owner-task { font-size: 13px; line-height: 1.5; color: var(--text); padding-left: 3px; }
.cck-owner-task::marker { color: var(--cck-accent); }

/* In two-pane mode the left list is a compact master — the primary action moves
   to the working pane (snooze stays); titles/reasons clamp so rows stay short. */
.cck-workspace .cck-actions .cck-act { display: none; }
.cck-workspace .cck-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cck-workspace .cck-why { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cck-workspace .cck-row { gap: 10px; padding: 13px 14px; }

/* Working-pane reading view (email / event content in-app) */
.cck-work-whyline { display: flex; gap: 6px; font-size: 13px; color: var(--text-dim); margin: 0 0 14px; }
.cck-work-whyline .lucide-icon { color: var(--warn); flex: none; margin-top: 2px; }
.cck-reader { border: 0.5px solid var(--border); border-radius: 12px; padding: 14px 16px; background: var(--surface-0); }
.cck-reader-meta { font-size: 13px; color: var(--cck-hero-text); margin-bottom: 10px; }
.cck-reader-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin-right: 8px; }
.cck-reader-att { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--cck-accent); background: var(--cck-accent-soft); padding: 3px 10px; border-radius: 999px; margin-bottom: 12px; }
.cck-reader-body { font-size: 14px; line-height: 1.65; color: var(--text); margin: 0 0 12px; }
.cck-reader-note { display: flex; gap: 5px; font-size: 11px; line-height: 1.5; color: var(--text-faint); }
.cck-reader-note .lucide-icon { flex: none; margin-top: 1px; }

/* ══ THREE-PANE OPERATING SHELL ══ */
#overview { overflow: hidden; }
#overview .ov-inner { max-width: none; margin: 0; padding: 0; height: 100%; }
.cck-shell { display: flex; flex-direction: column; height: 100%; min-height: 0; --cck-ai-w: 340px; }
/* Full-height assistant on the right; rail + viewer + dock stack on the left so the
   Ask Worx input reaches the very bottom of the window. */
.cck-body2 { flex: 1; min-height: 0; display: flex; }
.cck-leftstack { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.cck-body2[data-ai="off"] .cck-ai { display: none; }

/* Fixed top bar (left-aligned greeting + inline pulse) */
.cck-topbar { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px 22px; background: var(--surface); border-bottom: 0.5px solid var(--border); }
.cck-topbar-left { display: flex; align-items: center; gap: 14px; min-width: 0; }
.cck-topbar-left .ov-headline { color: var(--cck-hero-text); font-size: 26px; line-height: 30px; font-weight: 300; letter-spacing: -0.01em; margin: 0; }
.cck-topbar-right { display: flex; align-items: center; gap: 12px; flex: none; }
.cck-pulse-inline { display: flex; gap: 16px; font-size: 12px; color: var(--text-dim); }
.cck-pulse-inline b { color: var(--cck-hero-text); font-weight: 600; font-variant-numeric: tabular-nums; }
/* Seed retirement: the pulse falls back to sample numbers until Xero (Phase D) — say so. */
.cck-pulse-sample { font-size: 11px; color: var(--text-dim); border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 0 8px; align-self: center; }

/* Body: three independent-scroll columns */
.cck-panes { position: relative; flex: 1; min-height: 0; display: grid; grid-template-columns: var(--cck-rail-w, 330px) minmax(0, 1fr); grid-template-rows: 100%; }
/* Draggable divider between the list rail and the reading pane. */
.cck-rail-resize { position: absolute; top: 0; bottom: 0; left: var(--cck-rail-w, 330px); width: 10px; margin-left: -5px; cursor: col-resize; z-index: 6; }
.cck-rail-resize::before { content: ''; position: absolute; left: 4px; top: 0; bottom: 0; width: 2px; background: transparent; transition: background var(--motion-micro) var(--motion-easing); }
.cck-rail-resize:hover::before, .cck-rail-resize.cck-dragging::before { background: var(--cck-accent); }
.cck-rail { display: flex; flex-direction: column; overflow: hidden; border-right: 0.5px solid var(--border); padding: 14px; background: var(--cck-page); }
/* The scroll area inherits the rail's symmetric 14px padding, so every rail
   element — tiles, Compose, search, tabs, list — lines up on the same left and
   right edges (14 → 316). The scrollbar is a thin overlay that floats over the
   right edge without consuming layout width, so it never breaks that symmetry. */
.cck-rail-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable both-edges; }
/* Mail rail: the outer container doesn't scroll (the list inside does), so the
   header stays put and the list's scrollbar starts at the first preview. Its 6px
   side padding keeps everything aligned with the tile grid (20 → 310). */
.cck-rail-list:has(.cck-mail-list) { overflow: hidden; display: flex; flex-direction: column; scrollbar-gutter: auto; padding: 0 6px; }
.cck-rail-list::-webkit-scrollbar { width: 6px; }
.cck-rail-list::-webkit-scrollbar-thumb { background: rgba(20, 24, 33, 0.22); border-radius: 3px; }
.cck-rail-list::-webkit-scrollbar-thumb:hover { background: rgba(20, 24, 33, 0.38); }
.cck-rail-list::-webkit-scrollbar-track { background: transparent; }
.cck-rail-search-wrap { position: sticky; top: 0; z-index: 2; background: var(--cck-page); padding-bottom: 10px; }
.cck-rail-search-wrap .cck-rail-search { margin-bottom: 0; }
/* Toned surround; the reading content sits on a lighter white card (Outlook-like
   hierarchy — email/body lightest, surrounding panels + infills darker). */
.cck-viewer { overflow-y: auto; padding: 18px 20px; background: var(--cck-page); display: flex; flex-direction: column; }
/* The reading/compose card always fills the viewer height so its bottom is
   fixed just above the dock (no toned dead-space below a short email). */
.cck-viewer > .cck-work { flex: 1 0 auto; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 14px; padding: 20px 22px; box-shadow: 0 1px 2px rgba(20, 24, 33, 0.04); overflow: hidden; }
/* SCROLL-1 (Jeremy 2026-07-13): the rule above out-specified .cck-plate's new
   overflow-y:auto and kept clipping every module plate inside the viewer
   (Recruitment/HR/Risk/CRM…) with NO scroll path — body is overflow:hidden by
   design, so the plate is the last chance to scroll. Same-specificity+1
   exception: plates scroll vertically; the radius still clips horizontally. */
.cck-viewer > .cck-work.cck-plate { overflow-x: hidden; overflow-y: auto; }
/* The meeting view bleeds full-width inside the card; keep its toned inset but
   clip to the card's rounded corners (handled by the card's overflow:hidden). */
.cck-ai { --railpad: 14px; flex: 0 0 var(--cck-ai-w); overflow: hidden; border-left: 0.5px solid var(--border); padding: var(--railpad); background: var(--surface); display: flex; flex-direction: column; }
/* The cockpit assistant reuses the Explorer chat's exact components (Jeremy
   2026-07-03: identical interfaces) — these lines only make them flex inside
   the cockpit rail; all visual styling comes from the shared ins-chat rules. */
.cck-ai .cck-ai-threadhost { flex: 1; min-height: 0; overflow-y: auto; }
/* margin-top:auto pins the input to the BOTTOM of the rail whatever the
   thread holds (Jeremy 2026-07-04: the chat input floated mid-rail). */
.cck-ai .ins-chat-form { flex: none; margin-top: auto; }
.cck-ai .cck-ai-empty { border: 0; background: transparent; }

/* Rail tabs */
/* Inset the tile grid by the same 6px the scroll area reserves for its gutter,
   so the tiles line up exactly with Compose/search/tabs/list below. */
.cck-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 12px; padding: 0 6px; flex: none; }
.cck-tab { display: inline-flex; align-items: center; gap: 6px; padding: 7px 10px; border: 0.5px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text-dim); cursor: pointer; font: 500 12px/1 inherit; }
.cck-tab:hover { border-color: var(--border-dark); }
.cck-tab-on { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: transparent; }
.cck-tab .lucide-icon { flex: none; }
.cck-tab > span:first-of-type { flex: 1; text-align: left; }
.cck-tab-n { font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 999px; background: var(--chip-bg); color: var(--chip-fg); }
.cck-tab-on .cck-tab-n { background: var(--surface); color: var(--cck-accent); }
.cck-rail-empty { padding: 16px 8px; }   /* narrow-rail delta on the shared empty-state grammar (P2.1) */

/* ── Communications: Inbox + Calendar rail/viewer ─────────────────────────── */
.cck-rail-actions { padding: 8px 0 4px; }
.cck-comms-new, .cck-mtg-sync { width: 100%; justify-content: center; height: 34px; }
.cck-comms-connect { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 32px 18px; text-align: center; }
.cck-comms-connect-ic { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border-radius: 12px; background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-comms-connect-msg { font-size: 13px; line-height: 1.5; color: var(--text-dim); margin: 0; }

.cck-cal-list { list-style: none; margin: 0; padding: 0 6px 8px; display: flex; flex-direction: column; gap: 2px; }
/* Mail list: white preview rows separated by hairlines (Outlook-like). */
/* The list itself is the scroll area (flex-1) so its scrollbar starts at the top
   of the first preview — the Compose/search/tabs header above it stays fixed. */
.cck-mail-list { list-style: none; margin: 0; padding: 0; background: var(--surface-0); border-radius: 10px; border: 0.5px solid var(--border); flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; }
.cck-mail-list::-webkit-scrollbar { width: 6px; }
.cck-mail-list::-webkit-scrollbar-thumb { background: rgba(20, 24, 33, 0.22); border-radius: 3px; }
.cck-mail-list::-webkit-scrollbar-thumb:hover { background: rgba(20, 24, 33, 0.38); }
.cck-mail-list::-webkit-scrollbar-track { background: transparent; }
.cck-mailrow { display: flex; align-items: stretch; background: var(--surface-0); border-bottom: 0.5px solid var(--border); }
.cck-mailrow:last-child { border-bottom: none; }
.cck-mailrow-flagged { background: var(--mail-flag-wash); }   /* pale amber — flagged */
.cck-mailrow-main { flex: 1 1 auto; min-width: 0; display: flex; gap: 6px; align-items: flex-start; padding: 9px 8px 9px 4px; border: none; background: none; text-align: left; font: inherit; color: inherit; cursor: pointer; }
/* Hover + selection highlight span the WHOLE row (incl. the flag/pin column). */
.cck-mailrow:hover { background: var(--cck-accent-soft); }
.cck-mailrow.cck-selected { background: var(--cck-accent-soft); box-shadow: inset 2px 0 0 var(--cck-accent); }
.cck-mailrow.cck-selected .cck-mailrow-when, .cck-mailrow.cck-selected .cck-mailrow-prev { color: var(--text); }
.cck-mailrow-main:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: -2px; }
/* Thread disclosure + indented child rows */
.cck-thread-disc, .cck-thread-disc-sp { flex: none; width: 18px; align-self: center; display: flex; align-items: center; justify-content: center; }
.cck-thread-disc-sp { width: 6px; }   /* empty spacer on non-threaded rows — keep it slim so the checkbox sits near the text */
.cck-thread-disc { border: none; background: none; color: var(--text-dim); cursor: pointer; padding: 2px; }
.cck-thread-disc svg { transition: transform var(--motion-micro) var(--motion-easing); }
.cck-thread-disc.open svg { transform: rotate(90deg); }
/* Thread replies: ONLY the leading text is indented — the date and flag/pin
   column stay in line with the previews above and below. The grey highlight and
   its (slightly darker) connecting line begin together at the indent line; the
   preview text wraps rather than pushing anything out of alignment. */
.cck-mailrow-child { background: linear-gradient(to right, var(--surface-0) 22px, var(--row-even) 22px); position: relative; }
.cck-mailrow-child:hover { background: linear-gradient(to right, var(--surface-0) 22px, var(--cck-accent-soft) 22px); }
.cck-mailrow-child .cck-mailrow-main { padding-left: 32px; padding-top: 7px; padding-bottom: 7px; }
.cck-mailrow-child .cck-mailrow-prev { white-space: normal; }
/* Stacked flag (top) + pin (bottom), always visible + clickable */
.cck-mailrow-flags { flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 0 6px; }
.cck-rowflag, .cck-rowpin { border: none; background: none; padding: 2px; border-radius: 5px; cursor: pointer; color: var(--text-faint); line-height: 0; }
.cck-rowflag:hover, .cck-rowpin:hover { background: var(--cck-accent-soft); }
.cck-rowflag.on { color: var(--cck-danger); }
.cck-rowflag.on svg { fill: var(--cck-danger); }
.cck-rowpin.on { color: var(--cck-accent); }
.cck-rowpin.on svg { fill: var(--cck-accent); }
.cck-mailrow-prev .cck-mr-imp, .cck-mailrow-prev .cck-mr-flag, .cck-mailrow-prev [data-lucide] { vertical-align: -1px; margin-right: 3px; }

/* Group-by-conversation toggle + toolrow */
.cck-mail-toolrow { display: flex; gap: 6px; align-items: flex-start; }
.cck-mail-toolrow .cck-search { flex: 1; min-width: 0; }
.cck-mail-groupbtn { flex: none; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); color: var(--text-dim); cursor: pointer; }
.cck-mail-groupbtn:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-mail-groupbtn.on { background: var(--cck-accent); color: var(--on-solid); border-color: var(--cck-accent); }

/* Right-click context menu */
.cck-ctxmenu { position: fixed; z-index: 1200; min-width: 180px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; box-shadow: 0 10px 30px rgba(20, 24, 33, 0.2); padding: 5px; }
.cck-ctx-item { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 7px 10px; border: none; background: none; border-radius: 7px; font-size: 13px; color: var(--text); cursor: pointer; }
.cck-ctx-item i, .cck-ctx-item svg { width: 15px; height: 15px; flex: 0 0 15px; }
.cck-ctx-item:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-ctx-item.cck-ctx-danger:hover { background: var(--cck-danger); color: var(--on-solid); }
.cck-ctx-sep { height: 0.5px; background: var(--border); margin: 5px 6px; }
.cck-mailrow-dot { width: 7px; height: 7px; border-radius: 50%; background: transparent; margin-top: 5px; flex: none; }
.cck-mailrow-unread .cck-mailrow-dot { background: var(--cck-accent); }
.cck-mailrow-body { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.cck-mailrow-top { display: flex; justify-content: space-between; gap: 8px; }
.cck-mailrow-from { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-mailrow-unread .cck-mailrow-from { font-weight: 700; }
.cck-mailrow-count { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 15px; padding: 0 4px; margin-left: 5px; border-radius: 999px; background: var(--cck-accent-soft); color: var(--cck-accent); font-size: 10px; font-weight: 600; vertical-align: middle; }
.cck-mailrow-when { font-size: 11px; color: var(--text-dim); white-space: nowrap; flex: none; }
.cck-mailrow-subj { font-size: 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-mailrow-prev { font-size: 11px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Calendar month grid */
.cck-calmonth { display: flex; flex-direction: column; }
.cck-cal-monthhead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; margin-bottom: 14px; } /* wraps at high zoom so the nav never clips against the card edge */
.cck-cal-nav { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 6px; margin-left: auto; }
.cck-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; background: var(--border); border: 0.5px solid var(--border); border-radius: 10px; overflow: hidden; }
.cck-cal-wd { background: var(--surface); font-size: 11px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; text-align: center; padding: 7px 0; }
.cck-cal-cell { background: var(--surface-0); min-height: 92px; min-width: 0; padding: 5px 5px 4px; display: flex; flex-direction: column; gap: 2px; cursor: pointer; overflow: hidden; }
/* No hover wash on day cells (Jeremy 2026-07-08) — chips carry their own hover. */
.cck-cal-cell-out { background: var(--cck-page); }
.cck-cal-cell-out .cck-cal-num { color: var(--text-faint); }
.cck-cal-num { font-size: 12px; font-weight: 500; color: var(--text-dim); align-self: flex-start; padding: 1px 5px; border-radius: 999px; }
.cck-cal-today .cck-cal-num { background: var(--cck-accent); color: var(--cck-accent-on); font-weight: 600; }
.cck-cal-chip { display: block; width: 100%; text-align: left; font-size: 11px; line-height: 1.25; color: var(--text); background: var(--cck-accent-soft); border: none; border-radius: 4px; padding: 2px 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.cck-cal-chip:hover, .cck-cal-chip.on { background: var(--cck-accent); color: var(--on-solid); }
.cck-cal-chip.on .cck-cal-chip-t, .cck-cal-chip:hover .cck-cal-chip-t { color: var(--on-solid); }
.cck-cal-chip-t { font-weight: 600; color: var(--cck-accent); }
.cck-cal-chip-x { text-decoration: line-through; opacity: 0.6; }
.cck-cal-more { font-size: 10px; color: var(--text-dim); padding: 1px 4px; border: none; background: none; text-align: left; cursor: pointer; border-radius: 5px; }
.cck-cal-more:hover { color: var(--cck-accent); background: var(--cck-accent-soft); }
/* Whole-day popover behind "+N more" */
.cck-daypop { position: fixed; z-index: 1190; min-width: 260px; max-width: 340px; max-height: 340px; overflow: auto; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; box-shadow: 0 10px 30px rgba(20, 24, 33, 0.2); padding: 6px; }
.cck-daypop-head { font-size: 12px; font-weight: 600; color: var(--text-dim); padding: 4px 8px 6px; }
.cck-daypop-row { display: flex; gap: 8px; align-items: baseline; width: 100%; border: none; background: none; text-align: left; padding: 5px 8px; border-radius: 7px; cursor: pointer; font-size: 12.5px; color: var(--text); }
.cck-daypop-row:hover { background: var(--cck-accent-soft); }
.cck-daypop-t { flex: 0 0 44px; font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.cck-daypop-s { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* WorxConfirm body pieces (P1.4 t5): the card/scrim/actions chrome now comes
   from confirm-modal.js (one scrim, one focus-trap; lists open it wide via
   ConfirmModal.show({ wide: true })) — only the FIN-3 r2 body pieces below
   survive, rendered inside .confirm-modal-body. */
.cck-confirm-detail { margin: 0 0 14px; font: 12.5px/1.55 inherit; white-space: pre-wrap; color: var(--text-dim); background: var(--pane-chrome-bg); border-radius: 8px; padding: 10px 12px; }
/* FIN-3: structured review list for the confirm card (invoices etc.) —
   scannable rows, amount right-aligned, no wrapping of the key line. */
.cck-confirm-list { margin: 0 0 12px; max-height: 46vh; overflow: auto; border: 0.5px solid var(--border); border-radius: 8px; }
.cck-confirm-li { padding: 8px 12px; border-bottom: 0.5px solid var(--border); }
.cck-confirm-li:last-child { border-bottom: none; }
.cck-confirm-li:nth-child(even) { background: var(--pane-chrome-bg); }
/* FIN-2b: a flagged row (duplicate / needs attention) in the shared confirm+result list */
.cck-confirm-li.cck-confirm-li-warn { background: var(--danger-soft-bg); border-left: 2px solid var(--danger-soft-border); padding-left: 10px; }
.cck-confirm-li-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.cck-confirm-li-main { font-size: 13px; font-weight: 550; color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cck-confirm-li-amt { font-size: 13px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cck-confirm-li-sub { display: block; font-size: 11.5px; color: var(--text-faint); margin-top: 1px; }
.cck-confirm-note { margin: 0 0 12px; font-size: 11.5px; line-height: 1.5; color: var(--text-faint); }

/* ── Finance surface (FIN-2 payables + R8 tiles) ──────────────────────── */
.fin-panel { display: flex; flex-direction: column; min-height: 0; }
.fin-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; margin: 4px 0 2px; }
.fin-tile { background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
.fin-tile span { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; min-height: 16px; }
.fin-tile b { font-size: 19px; font-weight: 650; letter-spacing: -0.01em; }
.fin-tile.warn b { color: var(--danger-text); }
.fin-tile i { font-style: normal; font-size: 10.5px; color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fin-src { font-size: 10.5px; color: var(--text-faint); margin: 4px 2px 8px; }
.fin-src-1l { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 2px 2px 6px; }
.fin-viewbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 6px 0; }
.fin-runtotal { font-size: 12.5px; color: var(--text-dim); display: flex; align-items: center; gap: 8px; }
.fin-runtotal b { color: var(--text); font-size: 14px; }
.fin-tablewrap { flex: 1 1 auto; min-height: 0; max-height: 62vh; overflow: auto; border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); }   /* STANDARD: the wrap is the scroll context, so sticky headers hold */
.fin-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.fin-table th { position: sticky; top: 0; z-index: 1; background: var(--surface-3); text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); padding: 8px 10px; border-bottom: 0.5px solid var(--border); }   /* STANDARD (PO 2026-07-31): title rows fixed on a toned band; rows scroll beneath — everywhere */
.fin-table td { padding: 8px 10px; border-bottom: 0.5px solid var(--border); vertical-align: top; }
.fin-table .num, .fin-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.fin-table tr.overdue td { background: var(--danger-soft-bg); }
.fin-note { font-size: 11px; color: var(--text-dim); max-width: 380px; }
/* P2.5 cross-entity links: the supplier MENTION is the affordance — link
   grammar (accent + underline) at the cell's own weight and size */
.fin-suplink { font-size: inherit; font-weight: 600; }
.fin-over { color: var(--danger-text); font-weight: 600; }
.fin-pill { font-size: 10px; font-weight: 700; letter-spacing: 0.03em; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--text-dim); white-space: nowrap; }
.fin-pill-new { background: var(--action-pill-info-bg); color: var(--action-pill-info-fg); }
.fin-pill-scheduled { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.fin-pill-disputed, .fin-pill-onhold { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.fin-pill-paid { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.fin-actions { white-space: nowrap; text-align: right; }
.fin-nofile { font-size: 11px; color: var(--text-faint); }
/* FIN-2b: duplicate-payment flag under a register row (hard = red, suspect = amber) */
.fin-dupflag { display: inline-flex; align-items: center; gap: 4px; margin-top: 3px; font-size: 11px; font-weight: 600; line-height: 1.3; }
.fin-dupflag > i, .fin-dupflag > svg { flex: none; }
.fin-dupflag-hard { color: var(--danger-text); }
.fin-dupflag-suspect { color: var(--warn-text); }
.fin-table tr.fin-hasdup td { background: var(--danger-soft-bg); }
/* FIN-2b: the Paid-history view — search bar, count, and historical-double banner */
.fin-histbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 8px; }
.fin-histsearch { flex: 1 1 auto; min-width: 0; max-width: 340px; font: inherit; font-size: 13px; padding: 6px 10px; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); color: var(--text); }
.fin-histsearch:focus { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.fin-histcount { font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
.fin-histbanner { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; padding: 7px 10px; font-size: 12px; font-weight: 600; color: var(--danger-text); background: var(--danger-soft-bg); border: 0.5px solid var(--danger-soft-border); border-radius: 8px; }
.fin-histtable th:last-child, .fin-histtable td:last-child { color: var(--text-dim); font-size: 12px; }
/* .fin-emptyrow is fully carried by the shared empty-state grammar (P2.1). */
.fin-rail { display: flex; flex-direction: column; gap: 8px; padding: 10px; }
.fin-rail-stat { background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 9px 12px; display: flex; flex-direction: column; }
.fin-rail-stat span { font-size: 10.5px; color: var(--text-dim); }
.fin-rail-stat b { font-size: 17px; }
.fin-rail-stat.warn b { color: var(--danger-text); }
.fin-rail-stat i { font-style: normal; font-size: 10.5px; color: var(--text-faint); }
.fin-empty-note { font-size: 12px; color: var(--text-dim); padding: 8px 2px; }

/* ── FIN-8d — spend-trend card ────────────────────────────────────────────── */
.fin-trend { flex: 0 0 auto; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 8px 12px 9px; margin: 6px 0 2px; display: flex; flex-direction: column; gap: 5px; }
.fin-trend-head { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.fin-trend-head b { font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.fin-trend-head span { font-size: 11px; color: var(--text-faint); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fin-trend-row { display: flex; align-items: center; gap: 10px; font-size: 12px; }
.fin-trend-acct { flex: 0 0 170px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fin-trend-cells { flex: 1 1 auto; display: flex; gap: 6px; min-width: 0; }
.fin-trend-cell { flex: 1 1 0; min-width: 0; display: flex; align-items: center; height: 12px; background: var(--surface-2); border-radius: 4px; overflow: hidden; }
.fin-trend-bar { display: block; height: 100%; background: var(--accent); border-radius: 4px; }
.fin-trend-bar.fin-trend-ytd { opacity: 0.45; }   /* YTD level, not a month's own spend */
.fin-trend-none { justify-content: center; background: none; color: var(--text-faint); font-size: 10px; }
.fin-trend-amt { flex: 0 0 76px; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text); }
.fin-trend-headrow { font-size: 10px; color: var(--text-dim); }
.fin-trend-headrow .fin-trend-cell { background: none; height: auto; }
.fin-trend-mlab { justify-content: center; }
.fin-trend-headrow .fin-trend-amt { font-weight: 500; color: var(--text-dim); font-size: 10px; }

/* ── P3.4 — month-on-month variance card (the R8 remainder) ───────────────── */
.fin-var { background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 8px 12px 9px; margin: 6px 0 2px; display: flex; flex-direction: column; gap: 5px; }
.fin-var-head { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.fin-var-head b { font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.fin-var-head span { font-size: 11px; color: var(--text-faint); min-width: 0; line-height: 1.45; }
.fin-var-table { margin: 0; }
.fin-var-table td, .fin-var-table th { font-size: 12.5px; }
.fin-var-none { color: var(--text-faint); }
.fin-var-good { color: var(--success-text); font-weight: 600; }
.fin-var-bad { color: var(--danger-text); font-weight: 600; }
.fin-var-note { font-size: 11px; color: var(--text-dim); line-height: 1.5; margin: 0; }

/* ── FIN-8c — overdue receivables card ────────────────────────────────────── */
.fin-recv { background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 8px 12px; margin: 4px 0 2px; display: flex; flex-direction: column; gap: 6px; }
.fin-recv-head { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.fin-recv-head b { font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.fin-recv-head span { font-size: 11px; color: var(--text-faint); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fin-recv-row { display: flex; align-items: center; gap: 10px; font-size: 12.5px; }
.fin-recv-who { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.fin-recv-who b { font-weight: 550; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fin-recv-sub { font-size: 11px; color: var(--text-dim); }
.fin-recv-amt { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text); white-space: nowrap; }

/* ── FIN-8b — statutory-dates strip ───────────────────────────────────────── */
.fin-comp { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; margin: 2px 0 4px; }
.fin-comp-item { background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 10px 12px; }   /* FIN-24c: each date its own panel, like the stat tiles */

.fin-comp-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; font-size: 11.5px; color: var(--text-dim); }
.fin-comp-what { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); display: flex; flex-direction: column; }
.fin-comp-org { font-style: normal; font-weight: 400; font-size: 10.5px; color: var(--text-faint); }
.fin-comp-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fin-comp-line b { color: var(--text); white-space: nowrap; }
.fin-comp-src { color: var(--text-faint); font-size: 10.5px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fin-comp-form { display: flex; align-items: center; gap: 6px; }
.fin-comp-form input[type="date"] { font: inherit; font-size: 11.5px; padding: 2px 6px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); color: var(--text); }
.fin-pill-plain { background: var(--surface-2); color: var(--text-dim); }

/* ── FIN-7a — VAT returns tab ─────────────────────────────────────────────── */
.fin-tabbar { margin: 2px 0 6px; align-self: flex-start; }
.fin-flow { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 9px 12px; margin: 6px 0; font-size: 12px; color: var(--text-dim); }
.fin-flow b { color: var(--text); font-weight: 600; }
.fin-flow .arr { color: var(--text-faint); }
.fin-flow-right { margin-left: auto; }
.fin-tile i.fin-stale { color: var(--warn-text); }    /* FIN-8a: bank-feed staleness note */
.fin-tile b.ok { color: var(--success-text); }
.fin-tile b.due { color: var(--warn-text); }
.fin-tile b.red { color: var(--danger-text); }        /* FIN-7c: overdue statutory deadline */
.fin-rail-stat.due b { color: var(--warn-text); }     /* FIN-7c: amber rail state (red reuses .warn) */
.vat-why { font-size: 11px; color: var(--text-dim); font-weight: 400; }
.vat-tag { display: inline-block; padding: 1px 7px; border-radius: 6px; font-size: 10.5px; background: var(--surface-2); color: var(--text-dim); margin-left: 6px; vertical-align: 1px; white-space: nowrap; }
.vat-ok { color: var(--success-text); font-weight: 600; font-size: 12px; white-space: nowrap; }
.vat-neg { color: var(--success-text); }
.vat-table tbody tr[data-vat-row] { cursor: pointer; }
.vat-table tbody tr[data-vat-row]:hover td { background: var(--row-hover); }
.vat-filed { white-space: nowrap; }
.vat-detail td { background: var(--row-even); padding: 12px 14px; }
.vat-boxes { display: grid; grid-template-columns: repeat(3, minmax(180px, 1fr)); gap: 6px 22px; margin-bottom: 10px; }
.vat-box { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; color: var(--text-dim); }
.vat-box b { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 600; }
.vat-box b.vat-miss { color: var(--warn-text); }
.vat-facts { display: flex; flex-wrap: wrap; gap: 4px 22px; font-size: 12px; color: var(--text-dim); align-items: center; }
.vat-facts b { color: var(--text); font-weight: 600; }
.vat-parsenote { margin-top: 8px; font-size: 12px; color: var(--warn-text); }
.vat-gapnote { font-size: 12.5px; color: var(--text-dim); max-width: 78ch; }
.vat-fwd { margin-top: 6px; font-size: 11px; color: var(--text-faint); }
.vat-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); margin-top: 6px; }   /* card chrome delta on the shared empty-state grammar (P2.1) */
.vat-empty p { margin: 0; max-width: 62ch; }

/* ── FIN-6 — Expenses tab (register + FIN-5 normalise plan) ──────────────── */
.exp-chiprow { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 6px; }
.exp-chip { border: 0.5px solid var(--border); border-radius: var(--radius-pill); background: var(--surface); color: var(--text-dim); font-size: 11.5px; padding: 3px 11px; cursor: pointer; }   /* filter chips stay neutral white (design judgement) */
.exp-chip:hover { background: var(--hover-soft); }
.exp-chip.on { background: var(--cck-accent-soft); color: var(--cck-accent); font-weight: 600; border-color: var(--cck-accent-soft); }
.exp-plan { display: flex; flex-direction: column; gap: 8px; border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); padding: 12px; margin-top: 8px; }
.exp-plan-head { display: flex; flex-direction: column; gap: 2px; }
.exp-plan-head b { font-size: 12.5px; font-weight: 600; color: var(--text); }
.exp-plan-head span { font-size: 11.5px; color: var(--text-dim); max-width: 88ch; }
.exp-gatebanner { background: var(--warn-soft-bg); color: var(--warning-chip-fg); border: 0.5px solid var(--warning-chip-border); border-radius: 8px; padding: 7px 11px; font-size: 12px; }
.exp-plan-list { display: flex; flex-direction: column; }
.exp-plan-row { display: flex; gap: 10px; align-items: baseline; padding: 5px 2px; font-size: 12px; border-top: 0.5px solid var(--border); }
.exp-plan-row:first-child { border-top: none; }
.exp-plan-kind { flex: 0 0 110px; font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); }
.exp-plan-row.review .exp-plan-kind { color: var(--warn-text); }
.exp-plan-move { display: flex; flex-wrap: wrap; gap: 4px 8px; min-width: 0; align-items: baseline; }
.exp-plan-move b { font-weight: 550; color: var(--text); overflow-wrap: anywhere; }
.exp-plan-arr { color: var(--text-faint); }
.exp-plan-why { flex-basis: 100%; font-size: 11px; color: var(--text-dim); }
.exp-plan-note { margin: 0; font-size: 11px; color: var(--text-faint); max-width: 88ch; }
.exp-plan-actions { display: flex; gap: 8px; justify-content: flex-end; }

/* Meetings search: matching calendar events (unrecorded meetings) */
.cck-mtg-calhits-h { font-size: 10.5px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; padding: 10px 10px 4px; }
.cck-mtg-calhit { display: flex; gap: 8px; align-items: baseline; width: 100%; border: none; background: none; text-align: left; padding: 6px 10px; border-radius: 8px; cursor: pointer; font-size: 12.5px; color: var(--text); }
.cck-mtg-calhit:hover { background: var(--cck-accent-soft); }
.cck-mtg-calhit-t { flex: 0 0 86px; font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.cck-mtg-calhit-s { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Month ⇄ Week segmented toggle */
.cck-calseg { display: inline-flex; border: 0.5px solid var(--border); border-radius: 8px; overflow: hidden; margin-right: 6px; }
.cck-calseg-btn { border: none; background: var(--surface-0); color: var(--text-dim); font-size: 12px; padding: 5px 11px; cursor: pointer; }
.cck-calseg-btn + .cck-calseg-btn { border-left: 0.5px solid var(--border); }
.cck-calseg-btn.on { background: var(--cck-accent-soft); color: var(--cck-accent); font-weight: 600; }
/* Week view: a TIMELINE — hour ruler left, 7 day columns, events placed at
   their start time with height = duration. The grid scrolls (opens at 09:00);
   the day headers stay in normal flow above it (settled pinned-bar pattern). */
.cck-calw-headrow { display: grid; grid-template-columns: 48px repeat(7, 1fr); border: 0.5px solid var(--border); border-bottom: none; border-radius: 10px 10px 0 0; background: var(--surface-0); }
.cck-calw-cornerhead { border-right: 0.5px solid var(--border); }
.cck-calw-head { font-size: 11px; color: var(--text-dim); padding: 6px 7px 5px; border-right: 0.5px solid var(--border); min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cck-calw-head:last-child { border-right: none; }
.cck-calw-head b { color: var(--text); font-size: 13px; }
/* Today: only the day + date read blue — nothing else. */
.cck-calw-head.cck-calw-today, .cck-calw-head.cck-calw-today b { color: var(--cck-accent); }
.cck-calw-allday { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-calw-scroll { flex: 1 1 auto; min-height: 300px; max-height: 64vh; overflow: auto; border: 0.5px solid var(--border); border-radius: 0 0 10px 10px; background: var(--surface-0); }
.cck-calw-canvas { display: grid; grid-template-columns: 48px repeat(7, 1fr); position: relative;
  background-image: repeating-linear-gradient(to bottom, var(--border) 0, var(--border) 1px, transparent 1px, transparent 48px); }
.cck-calw-gutter { position: relative; border-right: 0.5px solid var(--border); background: var(--surface-0); }
.cck-calw-hourlab { position: absolute; right: 6px; transform: translateY(-6px); font-size: 10px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.cck-calw-daycol { position: relative; min-width: 0; border-right: 0.5px solid var(--border); }
.cck-calw-daycol:last-child { border-right: none; }
.cck-calw-evt { position: absolute; margin: 0 1px; text-align: left; font-size: 11px; line-height: 1.3; padding: 2px 6px; overflow: hidden; border-radius: 6px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.65); }
.cck-calw-now { position: absolute; left: 0; right: 0; height: 2px; background: var(--cck-danger); pointer-events: none; }
/* CAL-2: colleagues' busy ribbons — thin colour strips on the day's right edge */
.cck-calw-busy { position: absolute; width: 5px; border-radius: 3px; opacity: 0.75; }
/* …and, when the space is FREE, the SAME chip design as Jeremy's own events
   in the person's lighter tone (CAL-2 r3) — clashes degrade to the ribbon,
   so blocks never cover anything. Not clickable: no hand cursor, no hover. */
.cck-calw-peer { cursor: default; }
.cck-calppl { padding: 8px 10px 2px; }
.cck-calppl-h { font-size: 10.5px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }
.cck-calppl-chip { display: inline-flex; align-items: center; gap: 6px; margin: 0 6px 6px 0; padding: 4px 10px; font-size: 12px; border: 0.5px solid var(--border); border-radius: 999px; background: var(--surface-0); color: var(--text-dim); cursor: pointer; }
.cck-calppl-chip.on { color: var(--text); border-color: var(--cck-accent); background: var(--cck-accent-soft); }
.cck-calppl-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.cck-calppl-note { font-size: 10.5px; color: var(--text-faint); margin: 2px 0 8px; }
.cck-calw-now::before { content: ''; position: absolute; left: 0; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: var(--cck-danger); }
.cck-backbtn { display: inline-flex; align-items: center; gap: 2px; font-size: 12px; color: var(--cck-accent); background: none; border: none; cursor: pointer; padding: 0 0 6px; }
.cck-backbtn:hover { text-decoration: underline; }
.cck-cal-day { font-size: 11px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; padding: 10px 8px 4px; }
.cck-evrow { display: flex; gap: 10px; padding: 8px; border-radius: 8px; cursor: pointer; }
.cck-evrow:hover { background: var(--cck-accent-soft); }
.cck-evrow.cck-selected { background: var(--cck-accent-soft); box-shadow: inset 2px 0 0 var(--cck-accent); }
.cck-evrow-cancelled .cck-evrow-subj { text-decoration: line-through; color: var(--text-faint); }
.cck-evrow-time { font-size: 12px; font-weight: 600; color: var(--cck-accent); width: 44px; flex: none; }
.cck-evrow-body { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cck-evrow-subj { font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-evrow-loc { font-size: 11px; color: var(--text-dim); }

.cck-mailbody { font-size: 13px; line-height: 1.65; color: var(--text); white-space: normal; max-height: 38vh; overflow-y: auto; padding-right: 6px; margin-bottom: 14px; }
/* Loading skeleton shown while an email body is being fetched (first open) —
   replaces the old flash of the preview snippet. */
.cck-mailbody-loading { display: flex; flex-direction: column; gap: 11px; padding: 6px 2px; }
.cck-skel-bar { height: 12px; border-radius: 6px; background: rgba(20, 24, 33, 0.07); animation: cck-skel-pulse 1.1s ease-in-out infinite; }
.cck-skel-bar.short { width: 55%; }
/* Multi-select: a checkbox appears on hover or when the row is selected. */
.cck-mailrow-checkwrap { display: flex; align-items: center; padding: 0 0 0 8px; margin-right: -4px; }
.cck-mailrow-check { width: 15px; height: 15px; cursor: pointer; accent-color: var(--cck-accent); opacity: 0; transition: opacity var(--motion-micro); }
.cck-mailrow:hover .cck-mailrow-check, .cck-mailrow-check:checked, .cck-row-checked .cck-mailrow-check { opacity: 1; }
.cck-mailrow.cck-row-checked { background: var(--cck-accent-soft); }
.cck-mailselbar { display: flex; align-items: center; gap: 4px; margin-top: 8px; padding: 6px 8px; border-radius: 9px; background: var(--cck-accent-soft); border: 0.5px solid var(--cck-accent); }
.cck-msb-count { font-size: 12px; font-weight: 600; color: var(--cck-accent); }
.cck-msb-btn { display: inline-flex; align-items: center; gap: 5px; justify-content: center; min-width: 30px; height: 28px; padding: 0 8px; border: none; border-radius: 7px; background: none; color: var(--cck-accent); cursor: pointer; font-size: 12px; }
.cck-msb-btn:hover { background: rgba(15, 108, 189, 0.14); }
.cck-msb-danger { color: var(--danger-text); }
.cck-msb-danger:hover { background: rgba(192, 54, 44, 0.12); }
.cck-mailrow-skel { display: flex; flex-direction: column; gap: 7px; padding: 13px 14px; border-bottom: 0.5px solid var(--border); list-style: none; }
.cck-mailrow-skel .cck-skel-bar:first-child { width: 72%; }
@keyframes cck-skel-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .cck-skel-bar { animation: none; } }
.cck-mail-replybar { display: flex; gap: 6px; border-bottom: 0.5px solid var(--border); padding: 0 0 12px; margin-bottom: 14px; }
.cck-act.cck-act-sm { padding: 4px 11px; font-size: 12px; border-radius: 8px; }
.cck-reply, .cck-form { border-top: 0.5px solid var(--border); padding-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.cck-reply-head { display: flex; align-items: center; justify-content: space-between; font-size: 13px; font-weight: 600; color: var(--text); }
.cck-reply-x { border: none; background: none; color: var(--text-faint); cursor: pointer; font-size: 14px; padding: 2px 6px; border-radius: 6px; }
.cck-reply-x:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-reply-box, .cck-textarea { resize: vertical; }
.cck-reply-actions, .cck-form-actions { display: flex; gap: 8px; justify-content: flex-end; }
.cck-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 600; color: var(--text-dim); }
/* Inline To/Cc rows in the reply composer (label left, editable input right) */
.cck-field-row { flex-direction: row; align-items: center; gap: 8px; margin-bottom: 6px; }
.cck-field-row > span { flex: none; width: 26px; }
.cck-field-row .cck-ac-wrap { flex: 1 1 auto; min-width: 0; }
.cck-field-row { display: flex; gap: 10px; }
.cck-field-row .cck-field { flex: 1; }
.cck-input { font: 400 13px/1.4 inherit; color: var(--text); background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 8px; padding: 8px 10px; width: 100%; }
.cck-input:focus { outline: 2px solid var(--cck-accent); outline-offset: 1px; border-color: var(--cck-accent); }
.cck-checkrow { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim); }

/* Recipient autocomplete */
.cck-ac-wrap { position: relative; }
.cck-ac { position: absolute; top: calc(100% + 2px); left: 0; right: 0; z-index: 30; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(20, 24, 33, 0.16); padding: 4px; max-height: 220px; overflow-y: auto; }
.cck-ac-item { display: flex; flex-direction: column; gap: 1px; width: 100%; text-align: left; padding: 6px 10px; border: none; background: none; border-radius: 7px; cursor: pointer; }
.cck-ac-item:hover, .cck-ac-item.on { background: var(--cck-accent-soft); }
.cck-ac-name { font-size: 13px; font-weight: 500; color: var(--text); }
.cck-ac-email { font-size: 11px; color: var(--text-dim); }

/* Mail toolbar: search + folder switcher */
/* Pinned mail header: Compose + search + folder tabs stay put while the list
   scrolls beneath. */
.cck-mail-head { flex: 0 0 auto; background: var(--cck-page); padding-bottom: 6px; }
.cck-mail-toolbar { padding: 4px 0 8px; display: flex; flex-direction: column; gap: 8px; background: var(--cck-page); }
/* Advanced chip search field */
.cck-search { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 5px; min-height: 34px; padding: 3px 6px 3px 12px; border: 0.5px solid var(--border); border-radius: 17px; background: var(--surface-0); color: var(--text-faint); }
.cck-search.has-chips { border-radius: 12px; }
.cck-search:focus-within { border-color: var(--cck-accent); }
.cck-search-ico { flex: none; color: var(--text-faint); }
.cck-search-chips { display: contents; }
.cck-search-input { flex: 1; min-width: 90px; height: 26px; border: none; background: none; outline: none; font: 400 13px/1.2 inherit; color: var(--text); }
.cck-search.is-pending .cck-search-input { color: var(--cck-accent); font-weight: 500; }
.cck-search-clear, .cck-search-smart { flex: none; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 7px; background: none; color: var(--text-dim); cursor: pointer; }
.cck-search-clear:hover, .cck-search-smart:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
/* Chips */
.cck-chip { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 4px 0 8px; border-radius: 12px; font-size: 12px; line-height: 1; white-space: nowrap; }
.cck-chip-op { font-weight: 600; opacity: 0.8; }
.cck-chip-addr { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-chip-not { background: var(--chip-bg); color: var(--chip-fg); }
.cck-chip-flag { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.cck-chip-date { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.cck-chip-x { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border: none; border-radius: 50%; background: none; color: inherit; font-size: 13px; line-height: 1; cursor: pointer; opacity: 0.7; }
.cck-chip-x:hover { opacity: 1; background: rgba(20, 24, 33, 0.1); }
.cck-search-note { font-size: 11px; color: var(--cck-accent); padding: 0 2px; }
/* Autocomplete dropdown anchored to the field */
.cck-search-ac { position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 1200; max-height: 240px; overflow-y: auto; padding: 4px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; box-shadow: 0 10px 30px rgba(20, 24, 33, 0.18); }
/* Smart-search popover */
/* ── Smart-search popover ─────────────────────────────────────── */
.cck-smartpop { position: fixed; z-index: 1310; width: 320px; padding: 0; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 14px; box-shadow: 0 18px 48px rgba(20, 24, 33, 0.26); overflow: hidden; }
.cck-sp-title { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; color: var(--text); padding: 13px 16px; border-bottom: 0.5px solid var(--border); }
.cck-sp-title svg { width: 15px; height: 15px; color: var(--cck-accent); }
/* Field rows (From/To/Cc/Words) sit in a padded group. */
.cck-smartpop .cck-sp-row { display: flex; align-items: center; gap: 10px; margin: 0; padding: 0 16px; }
.cck-smartpop .cck-sp-row + .cck-sp-row { margin-top: 8px; }
.cck-smartpop .cck-sp-row:first-of-type { margin-top: 14px; }
.cck-sp-lab { width: 42px; font-size: 12px; font-weight: 500; color: var(--text-dim); text-align: right; }
.cck-sp-row .cck-input { flex: 1; height: 32px; }
/* Toggle pills — coloured (flagged red, unread blue). */
.cck-sp-toggles { display: flex; gap: 7px; padding: 14px 16px; }
.cck-sp-tog { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 5px; height: 30px; border: 0.5px solid var(--border); border-radius: 9px; background: var(--surface-0); color: var(--text-dim); font-size: 12px; font-weight: 500; cursor: pointer; transition: background var(--motion-micro), border-color var(--motion-micro), color var(--motion-micro); }
.cck-sp-tog:hover { border-color: var(--border-strong, var(--border)); }
.cck-sp-tog svg { width: 13px; height: 13px; }
/* Only the little flag icon is red (filled); the button uses the standard
   accent active state, not a red fill. Unread's envelope stays blue. */
.cck-sp-tog[data-tog="flagged"] svg { color: var(--cck-danger); fill: var(--cck-danger); }
.cck-sp-tog[data-tog="unread"] svg { color: var(--cck-accent); }
/* Date block sits on a faint tinted panel to read as one group. */
.cck-sp-datewrap { padding: 12px 16px 14px; border-top: 0.5px solid var(--border); background: var(--surface-1, rgba(20,24,33,0.02)); }
.cck-sp-lab2 { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.05em; margin: 0 0 8px; }
.cck-sp-presets { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.cck-sp-preset { font-size: 12px; padding: 5px 11px; border: 0.5px solid var(--border); border-radius: 14px; background: var(--surface-0); color: var(--text-dim); cursor: pointer; }
.cck-sp-preset:hover { border-color: var(--cck-accent); color: var(--cck-accent); }
.cck-sp-preset.on { border-color: var(--cck-accent); background: var(--cck-accent); color: var(--on-solid); }
.cck-sp-date { height: 30px; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); color: var(--text); font-size: 12px; padding: 0 8px; }
.cck-sp-daterow { display: flex; align-items: center; gap: 7px; margin-top: 9px; }
.cck-sp-mini { font-size: 12px; color: var(--text-dim); flex: none; min-width: 30px; }
.cck-sp-num { width: 54px; height: 30px; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); color: var(--text); font-size: 12px; text-align: center; }
.cck-sp-unit { flex: 1; height: 30px; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); color: var(--text); font-size: 12px; padding: 0 6px; }
.cck-sp-daterow .cck-sp-date { flex: 1; min-width: 0; }
.cck-sp-foot { display: flex; justify-content: space-between; gap: 8px; padding: 12px 16px; border-top: 0.5px solid var(--border); }
.cck-mail-folders { display: flex; gap: 4px; }
.cck-mail-fbtn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 5px 8px; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); color: var(--text-dim); font-size: 12px; font-weight: 500; cursor: pointer; }
.cck-mail-fbtn:hover { background: var(--surface-2); color: var(--text); }
/* Selected folder = soft indigo tint + indigo text + indigo edge (Outlook-style,
   not a loud solid fill). */
/* Selected tab: filled solid blue with white text (standard Microsoft style). */
.cck-mail-fbtn.on { background: var(--cck-accent); color: var(--cck-accent-on); border-color: var(--cck-accent); font-weight: 600; }
.cck-mail-fbtn.on .cck-fbtn-count { background: rgba(255, 255, 255, 0.26); color: var(--cck-accent-on); }
.cck-fbtn-wide { flex: 1.4; }
.cck-fbtn-count { min-width: 18px; padding: 0 5px; height: 16px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; background: var(--surface-2); color: var(--text-dim); font-size: 10.5px; font-weight: 600; }
.cck-mail-fbtn.on .cck-fbtn-count { background: var(--on-solid); color: var(--cck-accent); }
.cck-mail-fbtn.on .cck-fbtn-count { background: rgba(255, 255, 255, 0.26); color: var(--cck-accent-on); }

/* Mail rail sections + row icons + pin */
.cck-mail-sec { font-size: 11px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; padding: 12px 8px 4px; list-style: none; }
.cck-mail-sec-n { color: var(--text-dim); font-weight: 500; }
.cck-mailrow-icons { display: flex; align-items: center; gap: 4px; flex: none; color: var(--text-dim); align-self: flex-start; padding: 9px 4px 0 2px; }
.cck-mr-flag { color: var(--danger-text); }
.cck-mr-imp { color: var(--danger-text); }
.cck-mailrow-pin { border: none; background: none; padding: 2px; border-radius: 6px; color: var(--text-faint); cursor: pointer; opacity: 0; transition: opacity var(--motion-micro) var(--motion-easing); }
.cck-mailrow:hover .cck-mailrow-pin, .cck-mailrow-pin.on { opacity: 1; }
.cck-mailrow-pin.on { color: var(--cck-accent); }
.cck-mailrow-pin:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }

/* HTML email reading frame (sandboxed) + reader action pills */
/* The email body fills the remaining height of the reading pane (down to the
   bottom of the frame), instead of sizing to content and leaving dead space. */
.cck-work.cck-mailview { display: flex; flex-direction: column; min-height: 0; }
.cck-mail-frame { width: 100%; flex: 1 1 auto; min-height: 240px; border: none; border-radius: 8px; background: var(--surface-0); }
/* Event viewer: the original invite body fills the pane like an email does. */
.cck-work.cck-eventview { display: flex; flex-direction: column; min-height: 0; }
.cck-ev-frame { min-height: 320px; }
.cck-ev-bodytext { margin: 0; padding: 6px 10px; font: 13px/1.6 var(--font-body, inherit); white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text); overflow: auto; }
.cck-iconpill { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); color: var(--text-dim); cursor: pointer; }
.cck-iconpill:hover { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: var(--cck-accent); }
.cck-iconpill.on { background: var(--cck-accent); color: var(--on-solid); border-color: var(--cck-accent); }

/* Keyboard focus rings for the new comms/calendar/file controls (WCAG 2.4.7) */
.cck-mail-fbtn:focus-visible, .cck-att:focus-visible, .cck-iconpill:focus-visible,
.cck-rte-btn:focus-visible, .cck-reply-x:focus-visible, .cck-mailrow-pin:focus-visible,
.cck-cal-chip:focus-visible, .cck-fileov-x:focus-visible, .cck-backbtn:focus-visible,
.cck-ac-item:focus-visible, .cck-comms-new:focus-visible, [data-cal-nav]:focus-visible,
[data-reply-open]:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 2px; }
/* No accent focus-ring on the editor body — the caret is the focus cue, and the
   user didn't want the purple surround around the reply box. */
.cck-rte-area:focus, .cck-rte-area:focus-visible { outline: none; }

/* Email attachments + in-app file viewer */
.cck-atts { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.cck-att { display: inline-flex; align-items: center; gap: 8px; padding: 7px 12px; border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); color: var(--text); cursor: pointer; max-width: 260px; }
.cck-att:hover { background: var(--cck-accent-soft); border-color: var(--cck-accent); color: var(--cck-accent); }
.cck-att[draggable="true"] { cursor: grab; }
.cck-att[draggable="true"]:active { cursor: grabbing; }
.cck-att-name { font-size: 12px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-att-size { font-size: 11px; color: var(--text-dim); flex: none; }
.cck-att-drag { flex: none; opacity: 0; transition: opacity var(--motion-micro); }
.cck-att:hover .cck-att-drag { opacity: 0.75; }
/* Signature dialog — a floating card (design-system depth ladder), NOT a
   screen-blackening overlay. Light scrim + card shadow; toolbar icons match. */
.cck-sigov { position: fixed; inset: 0; z-index: 1000; background: rgba(20, 24, 33, 0.14); display: flex; align-items: center; justify-content: center; padding: 24px; }
.cck-sigdlg { box-shadow: var(--shadow, 0 1px 2px rgba(0,0,0,.06), 0 12px 32px rgba(0,0,0,.22)); }
.cck-sigdlg .cck-rte { margin: 8px 0 6px; }
.cck-sigdlg .cck-rte-area { min-height: 150px; max-height: 320px; }
/* RTE toolbar glyphs are 14px controls everywhere (guard against a 24px default). */
.cck-rte-bar svg { width: 14px; height: 14px; }
/* In-place signature editor: the compose card slides to signature mode. */
.cck-sig-inline { display: flex; flex-direction: column; gap: 10px; height: 100%; opacity: 0; transform: translateY(10px); transition: opacity var(--motion-micro) var(--motion-easing), transform var(--motion-micro) var(--motion-easing); }
.cck-sig-inline.in { opacity: 1; transform: none; }
.cck-sig-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.cck-sig-title { font-size: 13px; font-weight: 600; color: var(--text); }
.cck-sig-note { font-weight: 400; color: var(--text-dim); font-size: 12px; }
.cck-act-sm { padding: 5px 10px; font-size: 12px; }
.cck-act-icon { padding: 5px 7px; }
.cck-sig-select { height: 30px; max-width: 180px; font-size: 12px; padding: 0 8px; }
.cck-sig-name { height: 30px; width: 130px; font-size: 12px; }
.cck-sig-head .cck-form-spacer { flex: 1 1 auto; }
.cck-sig-head [data-sig-default].on { border-color: var(--cck-accent); background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-sig-inline .cck-rte { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.cck-sig-inline .cck-rte-area { flex: 1 1 auto; min-height: 180px; max-height: none; }
/* Table insert grid picker (hover to size). */
.cck-tablepick { position: fixed; z-index: 1300; padding: 10px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; box-shadow: 0 10px 30px rgba(20, 24, 33, 0.2); }
.cck-tp-grid { display: grid; grid-template-columns: repeat(8, 18px); grid-auto-rows: 18px; gap: 3px; }
.cck-tp-cell { border: 1px solid var(--border); border-radius: 3px; background: var(--surface-2); cursor: pointer; }
.cck-tp-cell.on { background: var(--cck-accent-soft); border-color: var(--cck-accent); }
.cck-tp-label { margin-top: 8px; font-size: 12px; color: var(--text-dim); text-align: center; }
/* Table tools — a SECOND toolbar row under the main RTE bar (revealed by the
   Table button / auto-shown when the caret is in a table). */
.cck-rte-tablebar { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; padding: 5px 6px; background: var(--surface-1, rgba(20,24,33,0.03)); border-bottom: 0.5px solid var(--border); }
.cck-rte-tablebar[hidden] { display: none; }
.cck-tb-btn { min-width: 26px; height: 24px; display: inline-flex; align-items: center; justify-content: center; gap: 4px; font-size: 11px; padding: 0 7px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); color: var(--text); cursor: pointer; }
.cck-tb-btn svg { width: 13px; height: 13px; }
.cck-tb-btn:hover { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: var(--cck-accent); }
.cck-tb-btn.cck-tt-danger:hover { background: var(--danger-soft-bg); color: var(--danger-hover); border-color: var(--cck-danger); }
/* When no table is active, the operation buttons dim (Insert stays available). */
.cck-rte-tablebar:not(.has-table) .cck-tb-btn:not([data-tb="insert"]) { opacity: 0.45; }
.cck-rte-area table.cck-etable { border-collapse: collapse; margin: 8px 0; table-layout: fixed; }
.cck-rte-area table.cck-etable td, .cck-rte-area table.cck-etable th { word-wrap: break-word; overflow-wrap: anywhere; }
/* Whole-cell selection highlight — a translucent wash layered OVER any shading. */
.cck-rte-area table.cck-etable td.cck-cell-sel, .cck-rte-area table.cck-etable th.cck-cell-sel { background-image: linear-gradient(rgba(15, 108, 189, 0.18), rgba(15, 108, 189, 0.18)); }
/* Border editor popover */
.cck-bordpop { position: fixed; z-index: 1310; width: 236px; padding: 12px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 12px; box-shadow: 0 14px 40px rgba(20, 24, 33, 0.24); }
.cck-bp-title { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; margin: -4px -4px 6px; padding: 4px; border-radius: 7px; cursor: move; user-select: none; }
.cck-bp-title:hover { background: var(--surface); }
.cck-bp-grip { display: inline-flex; color: var(--text-faint); }
.cck-bp-close { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border: none; border-radius: 6px; background: none; color: var(--text-dim); cursor: pointer; }
.cck-bp-close:hover { background: var(--surface-2, rgba(20, 24, 33, 0.08)); color: var(--text); }
.cck-bp-lbl { font-size: 11px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.03em; margin: 10px 0 5px; }
.cck-bp-styles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.cck-bp-style { display: flex; align-items: center; justify-content: center; height: 26px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); cursor: pointer; }
.cck-bp-style .cck-bp-line { width: 22px; height: 0; }
.cck-bp-style.on { border-color: var(--cck-accent); background: var(--cck-accent-soft); }
.cck-bp-ws { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.cck-bp-sides { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.cck-bp-side { display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 10px; padding: 5px 0 4px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); color: var(--text); cursor: pointer; }
.cck-bp-side:hover { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: var(--cck-accent); }
.cck-bp-row { display: flex; align-items: center; gap: 8px; margin-top: 2px; font-size: 12px; color: var(--text-dim); }
.cck-bp-swatch { width: 20px; height: 20px; border-radius: 5px; border: 0.5px solid var(--border); }
.cck-bp-colbtn { font-size: 12px; padding: 4px 9px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); color: var(--text); cursor: pointer; }
.cck-bp-paint { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; padding: 4px 9px; margin-left: auto; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); color: var(--text); cursor: pointer; }
.cck-bp-paint.on { border-color: var(--cck-accent); background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-bp-w { font-size: 12px; padding: 4px 0; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); color: var(--text); cursor: pointer; }
.cck-bp-w.on { border-color: var(--cck-accent); background: var(--cck-accent-soft); color: var(--cck-accent); }
body.cck-bord-painting .cck-rte-area { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' fill='none' stroke='%230f6cbd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'/%3E%3Cpath d='m15 5 4 4'/%3E%3C/svg%3E") 2 20, crosshair; }
/* Team actions — read-only roster of everyone's meeting action items. */
/* ── Tasks — My plate (task Define T1) ──────────────────────────────────── */
.cck-tkfilters { display: flex; flex-direction: column; gap: 4px; padding: 4px; }
.cck-tkfilter { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border: 0.5px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text-dim); cursor: pointer; font: 500 12.5px/1 inherit; }
.cck-tkfilter:hover { color: var(--text); }
.cck-tkfilter-on { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: var(--cck-accent); }
.cck-tkfilter-n { font-size: 11px; opacity: 0.7; }
.cck-plate { display: flex; flex-direction: column; height: 100%; overflow-x: hidden; overflow-y: auto; } /* SCROLL-1 (Jeremy 2026-07-13): was overflow:hidden — modules that render tall content directly in the plate (Recruitment et al) clipped with NO scroll path (body is overflow:hidden by design, so the plate is the last chance to scroll). auto is inert for plates whose inner .cck-plate-list scroller already bounds their content, and adds the missing scrollbar everywhere else. */
.cck-plate-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; padding: 2px 2px 12px; } /* P4.1: the headright actions wrap under at high zoom, never clip */
.cck-plate-headleft { display: flex; align-items: center; gap: 12px; }
.cck-plate-headright { display: flex; align-items: center; gap: 8px; }
.cck-tkseg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.cck-tkseg-b { border: 0; background: var(--surface); color: var(--text-dim); padding: 5px 12px; font: 500 12px/1 inherit; cursor: pointer; }
.cck-tkseg-b.on { background: var(--cck-accent); color: var(--cck-accent-on); }
.cck-board-proj { height: 30px; }
.cck-tk-proj { width: 108px; height: 26px; padding: 0 7px; font: inherit; font-size: 11px; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.cck-tk-proj::placeholder { color: var(--text-faint); }
/* Kanban board */
.cck-board { flex: 1; display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; overflow: hidden; min-height: 0; }
.cck-col { display: flex; flex-direction: column; min-height: 0; background: var(--surface-2); border-radius: var(--radius-panel, 12px); padding: 8px; }
.cck-col-h { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); padding: 2px 4px 8px; }
.cck-col-n { font-weight: 500; color: var(--text-faint); }
.cck-col-body { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.cck-col-empty { font-size: 12px; padding: 8px 0; }   /* board-column compact delta; faint→dim via the shared grammar (P2.1, §3.11 a11y) */
.cck-card { background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 9px; }
.cck-card-title { font-size: 12.5px; color: var(--text); }
.cck-card-due { font-size: 10.5px; color: var(--text-dim); margin-top: 3px; }
.cck-card-move { display: flex; justify-content: flex-end; gap: 4px; margin-top: 6px; }
.cck-card-mv { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text-dim); cursor: pointer; }
.cck-card-mv:hover:not(:disabled) { color: var(--cck-accent); border-color: var(--cck-accent); }
.cck-card-mv:disabled { opacity: 0.35; cursor: default; }
/* Timeline: conditions precedent + Gantt (task Define T3) */
.cck-timeline { overflow: hidden; }
.cck-tl-scroll { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 20px; }
.cck-tl-sec { display: flex; flex-direction: column; gap: 6px; }
.cck-cp-list { display: flex; flex-direction: column; gap: 6px; }
.cck-cp { display: flex; align-items: center; gap: 10px; padding: 9px 12px; background: var(--surface-0); border: 1px solid var(--border); border-left: 3px solid var(--cck-accent); border-radius: var(--radius); }
.cck-cp-main { flex: 1; min-width: 0; }
.cck-cp-add { margin-top: 4px; margin-bottom: 0; }
.cck-gantt { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface-0); }
.cck-gantt-axis { position: relative; height: 22px; border-bottom: 1px solid var(--border); background: var(--surface-2); margin-left: 180px; }
.cck-gantt-tick { position: absolute; top: 4px; font-size: 10px; color: var(--text-faint); transform: translateX(2px); }
.cck-gantt-tick::before { content: ''; position: absolute; top: -4px; left: -2px; width: 1px; height: 22px; background: var(--border); }
.cck-gantt-rows { display: flex; flex-direction: column; }
.cck-gantt-row { display: flex; align-items: center; height: 30px; }
.cck-gantt-row:not(:last-child) { border-bottom: 1px solid var(--border); }
.cck-gantt-label { width: 180px; flex: none; padding: 0 10px; font-size: 11.5px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; box-sizing: border-box; display: flex; align-items: center; gap: 4px; }
.cck-gantt-track { position: relative; flex: 1; height: 100%; }
.cck-gantt-bar { position: absolute; top: 8px; height: 14px; border-radius: 7px; background: var(--chip-bg); min-width: 6px; cursor: grab; touch-action: none; }
.cck-gantt-bar:hover { filter: brightness(0.95); }
.cck-gantt-bar.cck-gantt-dragging { cursor: grabbing; opacity: 0.85; }
.cck-gantt-bar.gb-doing { background: var(--cck-accent); }
.cck-gantt-bar.gb-blocked { background: var(--danger); }
.cck-gantt-bar.gb-done { background: var(--cck-positive); }
.cck-gantt-today { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--warn); opacity: 0.7; }
/* Diligence — checklist + gap detection (task Define G1) */
.cck-dd-asset { font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em; color: var(--text-dim); background: var(--chip-bg); padding: 2px 8px; border-radius: var(--radius-pill); }
.cck-dd-ready { font-size: 12px; font-weight: 700; padding: 4px 11px; border-radius: var(--radius-pill); }
.cck-dd-ready.r-done { background: var(--action-pill-check-bg); color: var(--action-pill-check-fg); }
.cck-dd-ready.r-part { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-dd-ready.r-low { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.cck-dd-cat { padding: 10px 0; border-bottom: 1px solid var(--border); }
.cck-dd-cathead { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.cck-dd-catname { font-size: 13px; font-weight: 600; color: var(--text); }
.cck-dd-dots { display: inline-flex; gap: 3px; margin-left: auto; }
.cck-dd-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border-dark); }
.cck-dd-dot.on { background: var(--cck-positive); }
.cck-dd-badge { font-size: 10px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); }
.cck-dd-badge.bg-done { background: var(--action-pill-check-bg); color: var(--action-pill-check-fg); }
.cck-dd-badge.bg-part { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-dd-badge.bg-miss { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.cck-dd-items { display: flex; flex-direction: column; gap: 3px; padding-left: 2px; }
.cck-dd-item { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.cck-dd-have { color: var(--text-dim); }
.cck-dd-have i { color: var(--cck-positive); }
.cck-dd-item { flex-wrap: wrap; }
.cck-dd-ev { flex-basis: 100%; padding-left: 19px; font-size: 11px; font-style: italic; color: var(--text-dim); }
.cck-dd-readbtn { margin-right: 4px; }
.cck-dd-gap { justify-content: space-between; color: var(--text); }
.cck-dd-glabel { display: inline-flex; align-items: center; gap: 6px; }
.cck-dd-glabel i { color: var(--danger-text); }
.cck-dd-acts { display: inline-flex; gap: 6px; }
.cck-dd-add { border: 1px solid var(--border); background: var(--surface); color: var(--text-dim); font: 500 10.5px/1 inherit; padding: 3px 8px; border-radius: var(--radius); cursor: pointer; }
.cck-dd-add:hover:not(:disabled) { color: var(--cck-accent); border-color: var(--cck-accent); }
.cck-dd-add:disabled { color: var(--cck-positive); border-color: var(--border); cursor: default; }
.cck-dd-note { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-dim); margin: 12px 0 0; }
/* G3 findings + contradictions */
.cck-dd-findings { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.cck-dd-subh { margin-top: 12px; }
.cck-dd-find { padding: 8px 10px; margin-bottom: 6px; background: var(--surface-0); border: 1px solid var(--border); border-left: 3px solid var(--border-dark); border-radius: var(--radius); }
.cck-dd-find.sev-risk { border-left-color: var(--danger-text); }
.cck-dd-find.sev-watch { border-left-color: var(--warn); }
.cck-dd-find.sev-ok { border-left-color: var(--cck-positive); }
.cck-dd-find-head { display: flex; align-items: center; gap: 7px; }
.cck-dd-find.sev-risk .cck-dd-find-head i { color: var(--danger-text); }
.cck-dd-find.sev-watch .cck-dd-find-head i { color: var(--warn); }
.cck-dd-find.sev-ok .cck-dd-find-head i { color: var(--cck-positive); }
.cck-dd-find-stmt { flex: 1; font-size: 12.5px; color: var(--text); }
.cck-dd-conf { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-faint); }
.cck-dd-find-cite { font-size: 11px; font-style: italic; color: var(--text-dim); margin: 4px 0 0 20px; }
.cck-dd-find-doc { font-style: normal; color: var(--text-faint); }
.cck-dd-find .cck-dd-acts { margin: 6px 0 0 20px; }
.cck-dd-contra { display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; margin-bottom: 6px; background: var(--action-pill-danger-bg); border-radius: var(--radius); }
.cck-dd-contra > i { color: var(--danger-text); margin-top: 1px; }
.cck-dd-contra-body { min-width: 0; }
/* Meeting transcript + synced audio */
.cck-transcript { display: flex; flex-direction: column; gap: 10px; }
.cck-tr-hint { display: flex; align-items: center; gap: 6px; color: var(--text-dim); font-size: 12.5px; padding: 12px 2px; }
/* NO sticky (Jeremy 2026-07-08 r3: lines showed above/behind the pinned bar —
   sticky in a padded pane leaves gaps). The player is normal flow; ONLY the
   lines list below it scrolls, so text can never reach the player. */
.cck-tr-player { background: var(--surface); padding: 4px 0 8px; }
.cck-tr-prow { display: flex; align-items: center; gap: 8px; }
.cck-tr-prow .cck-tr-audio, .cck-tr-prow .cck-tr-noaudio { flex: 1; min-width: 0; }
.cck-tr-dl svg { width: 12px; height: 12px; }
.cck-tr-audio { width: 100%; height: 34px; }
.cck-tr-noaudio { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-faint); padding: 6px 0; }
/* Every meeting tab pane scrolls INSIDE itself (Jeremy 2026-07-08 — minutes,
   summary, actions and transcript can all outgrow a page): the pane is the
   scroller, the section tabs stay visible, and the transcript player's
   position:sticky now works because the pane (below .cck-work's
   overflow:hidden) is its scroll context. */
.cck-mseg { padding-right: 4px; } /* Jeremy 2026-07-16: NO inner max-height/overflow — the seg's own scroller sat its bottom (and the last minutes line) below the viewport fold, on top of the outer pane scroll. Segs now flow; the sticky header (.cck-mfixed) stays and the outer pane is the single scroller, with .cck-mscroll's bottom padding keeping the last line clear. */
/* Transcript pane: the PANE doesn't scroll — the lines list does, beneath the
   static player (fixed player + scrolling content without sticky's traps). */
.cck-mseg[data-seg="transcript"] { max-height: none; overflow-y: visible; padding-right: 0; }
.cck-tr-lines { display: flex; flex-direction: column; gap: 2px; max-height: min(56vh, 640px); overflow-y: auto; overscroll-behavior: contain; padding-right: 4px; }
.cck-tr-line { display: flex; gap: 10px; padding: 6px 8px; border-radius: var(--radius); cursor: pointer; }
.cck-tr-line:hover { background: var(--hover-soft); }
.cck-tr-line.cck-tr-active { background: var(--cck-accent-soft); }
.cck-tr-spk { flex: none; width: 110px; font-size: 11.5px; font-weight: 600; color: var(--cck-accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-tr-txt { font-size: 12.5px; line-height: 1.45; color: var(--text); }
.cck-tr-line.cck-tr-active .cck-tr-txt { color: var(--text); }
/* G4 investment-committee memo overlay */
.cck-icr { width: min(680px, 94vw); max-height: 88vh; overflow-y: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel, 12px); box-shadow: var(--shadow); padding: 22px 26px; }
.cck-icr-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 6px; }
.cck-icr-kick { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); }
.cck-icr-title { font-family: 'Ivy Presto Headline', Georgia, serif; font-size: 22px; font-weight: 400; color: var(--text); margin: 2px 0 0; }
.cck-icr-rec { text-transform: uppercase; letter-spacing: 0.04em; align-self: center; }
.cck-icr-headline { font-size: 15px; font-weight: 600; color: var(--text); margin: 10px 0 6px; }
.cck-icr-summary { font-size: 13px; line-height: 1.5; color: var(--text-dim); margin: 0 0 12px; }
.cck-icr-sec { margin-bottom: 12px; }
.cck-icr-h { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin: 0 0 5px; }
.cck-icr-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; }
.cck-icr-list li { font-size: 12.5px; color: var(--text); }
.cck-icr-list.icr-risk li::marker { color: var(--danger-text); }
.cck-icr-list.icr-ok li::marker { color: var(--cck-positive); }
.cck-icr-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.cck-plate-add { display: flex; align-items: center; gap: 8px; padding: 0 12px; height: 40px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-dim); margin-bottom: 14px; }
.cck-plate-add input { flex: 1; border: 0; background: transparent; font: inherit; font-size: 13px; color: var(--text); outline: none; }
.cck-plate-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; }
.cck-plate-sec { display: flex; flex-direction: column; gap: 4px; }
.cck-plate-h { display: flex; align-items: center; gap: 7px; margin: 0 0 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); }
.cck-plate-overdue .cck-plate-h { color: var(--danger-text); }
.cck-plate-hn { font-weight: 500; color: var(--text-faint); }
.cck-plate-donesec { opacity: 0.75; }
/* .cck-plate-empty is fully carried by the shared empty-state grammar (P2.1). */
.cck-tk { display: flex; align-items: center; gap: 10px; padding: 9px 12px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius); }
.cck-tk:hover { border-color: var(--border-dark); }
.cck-tk-check { border: 0; background: transparent; padding: 0; cursor: pointer; color: var(--text-faint); display: inline-flex; }
.cck-tk-check:hover { color: var(--cck-positive); }
.cck-tk-done .cck-tk-check { color: var(--cck-positive); }
.cck-tk-main { flex: 1; min-width: 0; }
.cck-tk-title { font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-tk-done .cck-tk-title { text-decoration: line-through; color: var(--text-dim); }
.cck-tk-meta { font-size: 11px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.cck-tk-ctrls { display: flex; align-items: center; gap: 6px; flex: none; }
.cck-tk-status { font-size: 10.5px; font-weight: 600; padding: 3px 9px; border-radius: var(--radius-pill); border: 0; cursor: pointer; background: var(--chip-bg); color: var(--chip-fg); white-space: nowrap; }
.cck-tk-status.st-doing { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-tk-status.st-blocked { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.cck-tk-status.st-done { background: var(--action-pill-check-bg); color: var(--action-pill-check-fg); }
.cck-tk-due { width: 122px; height: 26px; padding: 0 6px; font: inherit; font-size: 11px; color: var(--text-dim); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.cck-tk-del { border: 0; background: transparent; padding: 2px; cursor: pointer; color: var(--text-faint); opacity: 0; display: inline-flex; }
.cck-tk:hover .cck-tk-del { opacity: 1; }
.cck-tk-del:hover { color: var(--danger-text); }

/* ── C0 row grammar (Jeremy UAT): assignee avatar · inline title · chips ── */
.cck-tk-av { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--radius-pill); background: var(--cck-accent-soft); color: var(--cck-accent); font-size: 10px; font-weight: 700; border: 0; cursor: pointer; flex: none; }
.cck-tk-av:hover { background: var(--hover-soft-tint); }
.cck-tk-av-sm { width: 20px; height: 20px; font-size: 9px; cursor: default; }
.cck-tk-av-menu { width: 20px; height: 20px; font-size: 9px; margin-right: 8px; cursor: inherit; }
.cck-tk-title { cursor: text; border-radius: var(--radius); padding: 2px 4px; margin: -2px -4px; }
.cck-tk-title:hover { background: var(--hover-soft); }
.cck-tk-title:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 1px; }
.cck-tk-chip { font-size: 10.5px; font-weight: 600; padding: 3px 9px; border-radius: var(--radius-pill); border: 1px solid var(--border); background: var(--surface-0); color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.cck-tk-chip:hover { border-color: var(--border-dark); color: var(--text); }
.cck-tk-chip.cck-tkc-empty { color: var(--text-faint); border-style: dashed; }
.cck-tk-chip.cck-tkc-today { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: transparent; }
.cck-tk-chip.cck-tkc-over { background: var(--warn-soft-bg); color: var(--warn); border-color: transparent; }
.cck-tk-inline { height: 26px; padding: 0 8px; font: inherit; font-size: 12px; color: var(--text); background: var(--surface-0); border: 1px solid var(--cck-accent); border-radius: var(--radius); min-width: 140px; }
.cck-tk-inline:focus { outline: none; }

/* ── C1: CRM imports + tables ── */
.crm-imports { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 8px; margin-bottom: 12px; } /* P4.1: collapses to one column at high zoom instead of clipping Re-import */
.crm-impcard { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius-panel); transition: border-color var(--motion-duration) var(--motion-easing), box-shadow var(--motion-duration) var(--motion-easing); }
.crm-impcard:hover { border-color: var(--border-dark); box-shadow: var(--elev-1); }
.crm-impmain { flex: 1; min-width: 0; }
.crm-implabel { font-size: 12.5px; font-weight: 600; color: var(--text); }
.crm-impsub { font-size: 11px; color: var(--text-dim); margin-top: 1px; }
.crm-preview { padding: 12px 16px; background: var(--surface-3); border: 1px solid var(--border); border-radius: var(--radius-panel); margin-bottom: 12px; }
.crm-table { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 8px; }
/* Sticky headers (Jeremy 2026-07-03: titles scrolled off with the list). */
.crm-table th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); font-weight: 600; padding: 6px 8px; border-bottom: 1px solid var(--border-dark); position: sticky; top: 0; background: var(--surface); z-index: 1; }
.crm-table td { padding: 9px 8px; border-bottom: 1px solid var(--border); color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.crm-table .crm-th-num, .crm-table .crm-td-num { text-align: right; } /* P4.1: amounts right-aligned, tabular (tnum is app-wide) */
.crm-table tbody tr { transition: background var(--motion-duration) var(--motion-easing); }
.crm-table tr:hover td { background: var(--row-hover); }
.crm-table tr[data-crm-open]:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: -2px; }
.crm-notecell { color: var(--text-dim); }
.crm-panel .cck-plate-list { overflow: auto; }
.crm-table tr[data-crm-open] { cursor: pointer; }

/* C3: stats tiles (Mercury metric-tile pattern) — soft lift on hover, calm. */
/* Jeremy 2026-07-06: headline numbers must align across tiles whether a
   title wraps to two lines ("AT PRICING OR BEYOND") or not ("OPEN RED
   FLAGS"). Instead of reserving a blank second line, the number block is
   BOTTOM-ANCHORED: the title takes whatever it needs at the top, the
   number + sub-line pin to the tile's base, and the grid's shared row
   height does the aligning. Responsive by construction — stretch the
   window, every title fits one line, the tiles simply get shorter. */
.crm-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); grid-auto-rows: 1fr; gap: 8px; margin-bottom: 12px; } /* P4.1: 4-up at desktop widths, reflows at high zoom (the HR field inputs' 140px min clipped in fixed quarters) */
.crm-stat { display: flex; flex-direction: column; padding: 12px 16px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius-panel); transition: border-color var(--motion-duration) var(--motion-easing), box-shadow var(--motion-duration) var(--motion-easing); }
.crm-stat .crm-stat-v { margin-top: auto; }   /* number row pins to the base */
.crm-stat .cck-tk-inline { width: 100%; min-width: 0; box-sizing: border-box; } /* P4.1: field inputs never overflow their card (intrinsic size clipped at 150% zoom) */
/* The sub-line must stay ONE line or it un-pins the number (measured live:
   "289 people on record" wrapped at narrow width and lifted its number
   13px above the neighbours). Ellipsize instead — same treatment the
   workspace panel already applies. */
.crm-stat .crm-stat-s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-stat:hover { border-color: var(--border-dark); box-shadow: var(--elev-1); }
.crm-stat-l { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); font-weight: 600; }
.crm-stat-v { font-size: 24px; font-weight: 600; color: var(--cck-hero-text); font-variant-numeric: tabular-nums; margin-top: 2px; }
.crm-stat-s { font-size: 11px; color: var(--text-dim); margin-top: 1px; }

/* C3: funnel */
.crm-funnel { padding: 4px 0; }
.crm-fun-row { display: flex; align-items: center; gap: 12px; padding: 8px 0; }
.crm-fun-label { flex: none; width: 168px; font-size: 12px; color: var(--text); }
.crm-fun-track { flex: 1; height: 14px; background: var(--surface-2); border-radius: var(--radius-pill); overflow: hidden; box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04); }
.crm-fun-bar { display: block; height: 100%; background: linear-gradient(to right, var(--cck-accent-soft), var(--cck-accent)); border-radius: var(--radius-pill); transition: width 240ms var(--motion-easing); }
.crm-fun-n { flex: none; width: 96px; font-size: 12px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.crm-fun-sub { font-weight: 400; color: var(--text-dim); }
.crm-fun-items { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 0 6px 180px; }
.crm-fun-more { align-self: center; } /* R9 OAS: the honest "+N more" beside capped member chips */
.crm-list-more { padding: 8px 2px 2px; } /* R9 OAS: the People table names its 100-of-N truncation */

/* C5: the stage stepper — always-visible deal progression (Jeremy 2026-07-03) */
.crm-stepper { display: flex; align-items: center; gap: 6px; margin: 4px 0 12px; flex-wrap: wrap; }
.crm-step { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--border); background: var(--surface-0); border-radius: var(--radius-pill); padding: 5px 12px; cursor: pointer; font: inherit; font-size: 11.5px; color: var(--text-dim); transition: border-color var(--motion-duration) var(--motion-easing), background var(--motion-duration) var(--motion-easing); }
.crm-step:hover { border-color: var(--border-dark); color: var(--text); }
.crm-step-n { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: var(--radius-pill); background: var(--chip-bg); color: var(--chip-fg); font-size: 10px; font-weight: 700; }
.crm-step-done { border-color: transparent; background: var(--cck-accent-soft); color: var(--cck-accent); }
.crm-step-done .crm-step-n { background: var(--surface-0); color: var(--cck-accent); }
.crm-step-on { border-color: var(--cck-accent); background: var(--cck-accent); color: var(--cck-accent-on); }
.crm-step-on .crm-step-n { background: var(--cck-accent-on); color: var(--cck-accent); }
.crm-step-arrow { color: var(--text-faint); font-size: 12px; }
.crm-step-static { cursor: default; }
.crm-step-static:hover { border-color: var(--border); color: var(--text-dim); }
.crm-step-static.crm-step-on:hover { border-color: var(--cck-accent); color: var(--cck-accent-on); }
.crm-step-static.crm-step-done:hover { border-color: transparent; color: var(--cck-accent); }
/* C5: data-room found row + discovery mapping review */
.crm-dr-found { display: flex; align-items: center; gap: 10px; margin-top: 4px; font-size: 12.5px; color: var(--text); flex-wrap: wrap; }
.crm-dr-path { display: inline-flex; align-items: center; gap: 6px; color: var(--text-dim); }
.crm-dr-path b { color: var(--text); font-weight: 600; }
.crm-map-row { display: flex; align-items: center; gap: 12px; padding: 8px 4px; border-bottom: 1px solid var(--border); }
.crm-map-row:last-of-type { border-bottom: 0; }
.crm-map-deal { width: 220px; flex: none; display: flex; flex-direction: column; }
.crm-map-sel { flex: 1; max-width: 340px; }
.crm-map-miss .crm-map-deal b { color: var(--warn); }
/* The in-workspace data-room browser (read-only) */
.crm-drb { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border); }
.crm-drb-list { max-height: 260px; overflow-y: auto; margin-top: 6px; }
.crm-drb-row { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; font: inherit; font-size: 12.5px; color: var(--text); padding: 5px 6px; border: 0; border-radius: var(--radius); background: transparent; }
.crm-drb-dir { cursor: pointer; font-weight: 600; }
.crm-drb-dir:hover { background: var(--row-hover); }
.crm-drb-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-drb-size { flex: none; font-size: 11px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
/* R2: the folder-picker modal — one shared click-to-choose tree (no typed paths) */
.crm-pk-overlay { position: fixed; inset: 0; background: var(--scrim); z-index: 1100; display: flex; align-items: center; justify-content: center; }   /* above .cck-fileov(1000) — the Tidy-Up picker opened BEHIND it (Jeremy UAT r2) */
.crm-pk { width: min(560px, 92vw); max-height: 78vh; display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel, 12px); box-shadow: var(--shadow); padding: 18px 20px 16px; }
.crm-pk-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.crm-pk-base { display: flex; align-items: center; gap: 6px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
.crm-pk-tree { flex: 1; min-height: 180px; overflow-y: auto; margin: 6px 0; }
.crm-pk-row { display: flex; align-items: center; gap: 7px; padding: 5px 8px; padding-left: calc(8px + var(--pk-depth, 0) * 18px); border-radius: var(--radius); font-size: 12.5px; color: var(--text); cursor: pointer; user-select: none; }
.crm-pk-row:hover { background: var(--row-hover); }
.crm-pk-row.crm-pk-sel { background: var(--accent-soft-bg, var(--row-hover)); font-weight: 600; }
.crm-pk-tw { flex: none; width: 14px; display: inline-flex; justify-content: center; color: var(--text-faint); }
.crm-pk-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-pk-meta { flex: none; font-size: 11px; font-weight: 400; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.crm-pk-err { padding: 4px 8px; padding-left: calc(8px + var(--pk-depth, 0) * 18px); font-size: 12px; color: var(--warn); }
.crm-pk-spin { width: 10px; height: 10px; border: 1.5px solid var(--border-dark); border-top-color: var(--text-dim); border-radius: 50%; display: inline-block; animation: crm-pk-rot 0.7s linear infinite; }
@keyframes crm-pk-rot { to { transform: rotate(360deg); } }
.crm-pk-foot { display: flex; align-items: center; gap: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.crm-pk-picked { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; color: var(--text); }
.crm-pk-picked.crm-pk-none { color: var(--text-faint); font-weight: 400; }
/* Mapping review: the picker buttons that replaced the dropdowns */
.crm-map-pick { max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-map-pick-none { color: var(--text-dim); }

/* Diligence: a gap is a MISSING document, never a delete affordance */
.cck-dd-misspill { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; background: var(--warn-soft-bg); color: var(--warn); border-radius: var(--radius-pill); padding: 1px 7px; margin-left: 6px; }

/* M6: the Advisor console — the pervasive strip where Worx speaks first.
   Signed-off grammar (mockup v4): one RAG dot per fact, blue text = go,
   panels white, tone in the surround. */
.wxc-host { flex: none; }
/* The console is a SECTION of the rail (Jeremy 2026-07-05): same head
   grammar as Smart Move / Chat, a clear divider before Chat, no floating
   card chrome. */
/* Full-bleed section line (Jeremy): the card's divider meets the rail edges
   in BOTH rails via the container's --railpad; content keeps its gutter. */
.wxc-card { border-bottom: 1px solid var(--border); margin: 0 calc(var(--railpad, 0px) * -1) max(var(--railpad, 0px), 12px); padding: 0 max(var(--railpad, 0px), 12px) 10px; font-size: 12px; color: var(--text); }
.ins-assistant-body .wxc-card { padding-top: 12px; }   /* air under the Smart Move line (Jeremy) */
.wxc-card .asst-section-head { display: flex; align-items: center; justify-content: space-between; }
.wxc-card .wxc-meta { display: inline-flex; align-items: center; gap: 6px; }
.wxc-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); animation: wxc-pulse 2.4s infinite; flex: none; }
.wxc-dot-idle { background: var(--text-faint); animation: none; }
@keyframes wxc-pulse { 50% { opacity: 0.4; } }
.wxc-meta { margin-left: auto; color: var(--text-faint); font-size: 10.5px; white-space: nowrap; }
.wxc-item { display: flex; align-items: center; gap: 7px; padding: 7px 12px 0; min-width: 0; }
.wxc-item-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.wxc-rag { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.wxc-rag-r { background: var(--danger); } .wxc-rag-a { background: var(--warn); } .wxc-rag-g { background: var(--ok); }
.wxc-go { border: 0; background: transparent; color: var(--accent); font: 600 11.5px/1 inherit; font-family: inherit; border-radius: var(--radius-pill); padding: 4px 8px; cursor: pointer; flex: none; }
.wxc-go:hover { background: var(--row-hover); }
.wxc-hide { border: 0; background: transparent; color: var(--text-faint); cursor: pointer; font-size: 13px; padding: 2px 4px; border-radius: 50%; flex: none; }
.wxc-hide:hover { color: var(--text); background: var(--row-hover); }
.wxc-clear { color: var(--text-faint); font-size: 11.5px; padding: 6px 12px 0; }
.wxc-more { color: var(--text-dim); font-size: 11px; padding: 7px 12px 0; }
.wxc-foot { color: var(--text-faint); font-size: 10.5px; padding: 7px 12px 0; }
/* The plan runner */
.wxc-overlay { position: fixed; inset: 0; background: var(--scrim); z-index: 480; display: flex; align-items: center; justify-content: center; }
.wxc-plan { width: min(560px, 92vw); max-height: 80vh; overflow-y: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel, 12px); box-shadow: var(--shadow); padding: 18px 20px 16px; }
.wxc-plan-h { display: flex; align-items: center; gap: 10px; }
.wxc-plan-h h3 { font-size: 14px; font-weight: 650; margin-right: auto; color: var(--text); }
.wxc-plan-sub { font-size: 12px; color: var(--text-dim); margin: 6px 0 10px; }
.wxc-x { border: 0; background: transparent; color: var(--text-dim); cursor: pointer; padding: 4px; border-radius: 50%; }
.wxc-x:hover { background: var(--row-hover); }
.wxc-step { display: flex; gap: 11px; padding: 10px 0; border-bottom: 1px dashed var(--border); font-size: 12.5px; color: var(--text); }
.wxc-step:last-of-type { border-bottom: 0; }
.wxc-mark { width: 20px; height: 20px; border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; }
.wxc-mark-wait { background: var(--panel-fill); color: var(--text-faint); }
.wxc-mark-run { background: var(--accent-soft-bg, var(--row-hover)); color: var(--accent); }
.wxc-mark-done { background: var(--ok-soft-bg); color: var(--ok); }
.wxc-mark-skip { background: var(--panel-fill); color: var(--text-dim); }
.wxc-mark-fail { background: var(--warn-soft-bg); color: var(--danger-text); }
.wxc-step-sub { font-size: 11.5px; color: var(--text-dim); margin-top: 1px; }
.wxc-plan-foot { display: flex; gap: 10px; justify-content: flex-end; margin-top: 14px; }
.wxc-plan-note { margin-right: auto; align-self: center; font-size: 11.5px; color: var(--text-dim); }
.wxc-btn { font: 600 12px/1 inherit; font-family: inherit; border-radius: var(--radius-pill); padding: 7px 14px; cursor: pointer; border: 1px solid transparent; background: var(--panel-fill); color: var(--text-dim); }
.wxc-btn:hover { color: var(--text); }
.wxc-btn-primary { background: var(--accent); color: var(--surface-0); }
.wxc-btn-primary:disabled { opacity: 0.75; cursor: default; }

/* R1: the stale-server banner — slim, honest, carries the restart button */
.worx-stalebar { display: flex; align-items: center; gap: 12px; padding: 8px 16px; background: var(--warn-soft-bg); color: var(--text); font-size: 12.5px; border-bottom: 1px solid var(--border-dark); position: relative; z-index: 400; }
.worx-stalebar span { flex: 1; }
.worx-stalebar-btn { font: inherit; font-size: 12px; font-weight: 600; padding: 4px 14px; border-radius: var(--radius-pill); border: 0; background: var(--warn); color: var(--surface-0); cursor: pointer; }
.worx-stalebar-btn:disabled { opacity: 0.7; cursor: default; }
.worx-stalebar-x { border: 0; background: transparent; color: var(--text-dim); cursor: pointer; font-size: 13px; padding: 2px 6px; }

/* Reader header fields — From / To / CC / Date on their own lines (Jeremy 2026-07-03) */
.cck-mail-hdrs { margin-top: 4px; }
.cck-mail-hdr { display: flex; gap: 8px; font-size: 12px; line-height: 1.5; }
.cck-mail-hdr-k { flex: none; width: 36px; color: var(--text-dim); font-weight: 600; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; padding-top: 1px; } /* §3.11: meaningful labels never --text-faint */
.cck-mail-hdr-v { color: var(--text-dim); min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Fundraising report (Shane + Jeremy 2026-07-03) — front of the Investors lens */
.crm-report { padding: 14px 16px 12px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius-panel); margin-bottom: 12px; }
.crm-report .crm-stats { margin-bottom: 10px; }
.crm-report .crm-stat { border-color: transparent; background: var(--surface-3); }
.crm-report-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; padding: 6px 0 8px; } /* R9 OAS: fixed thirds clipped the mini-bar columns at the 1280 floor — reflow like .crm-stats */
.crm-report-attn { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; border-top: 1px solid var(--border); padding-top: 10px; }
/* R9 OAS: amber/green AS TEXT ride the P5.1 minted text tokens — the report's
   inline warn heads read 3.32:1 on light. One class per tone, both themes. */
.crm-attn-l { color: var(--warn-text); }
.crm-stat-pos { color: var(--success-text); }
.crm-load-warn { color: var(--warn-text); font-size: 12px; margin: 0 0 10px; } /* R9 OAS: the honest failed-store-read strip */
.crm-mini-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
.crm-mini-l { flex: none; width: 116px; font-size: 11.5px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-mini-track { height: 10px; }
.crm-mini-n { flex: none; width: 28px; font-size: 11.5px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.crm-chiprow { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

/* C3: record detail card */
.crm-detail { padding: 14px 16px; background: var(--surface-0); border: 1px solid var(--border-dark); border-radius: var(--radius-panel); margin-bottom: 12px; }
/* Scroll paths (Jeremy 2026-07-03: correspondence was cut off with no way
   down): the whole CRM panel scrolls when its content outgrows the pane, and
   long correspondence/notes lists scroll within the card (mail-frame's 420px
   cap precedent) so the thread list is always reachable. */
.crm-panel { overflow-y: auto; padding-bottom: 16px; }
.crm-detail .crm-notes { max-height: 320px; overflow-y: auto; }
.crm-topcollapse { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; padding: 6px; margin-bottom: 12px; font: inherit; font-size: 11.5px; font-weight: 600; color: var(--text-dim); background: var(--surface-3); border: 1px solid var(--border); border-radius: var(--radius-pill); cursor: pointer; }
.crm-topcollapse:hover { color: var(--text); border-color: var(--border-dark); }
/* Investor record card (Attio-pattern identity header + tabs) */
.crm-inv-av { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--radius-panel); background: var(--cck-accent-soft); color: var(--cck-accent); font-size: 13px; font-weight: 700; flex: none; }
.crm-inv-id { flex: 1; min-width: 0; }
.crm-inv-id .crm-chiprow { margin-top: 4px; }
.crm-inv-track { display: flex; align-items: center; gap: 6px; flex: none; }
.crm-track-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; color: var(--cck-accent); background: var(--cck-accent-soft); border-radius: var(--radius-pill); padding: 4px 10px; font-variant-numeric: tabular-nums; }
.crm-inv-tabs { margin: 12px 0 10px; }
.crm-inv-detail .crm-detail-head { align-items: flex-start; gap: 12px; }
.crm-detail-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.crm-detail-title { font-size: 15px; font-weight: 600; color: var(--cck-hero-text); margin: 0; }
.crm-stagepick { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; } /* R9 OAS: nowrap clipped '5 · Advisor DD' past the panel edge at the 1280 floor — the P4.1 wrap family, this sibling was missed */
/* S2-b: the deal lifecycle — one compact select beside its label; the note
   wraps to its own line. Ended deals carry a plain exception chip in the
   table (terminal states never carry urgency colour — the P4.1 RAG rule). */
.crm-lc-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 10px; }
.crm-lc-sel { width: auto; min-width: 120px; padding: 4px 8px; }
.crm-lc-note { flex-basis: 100%; margin-top: 2px; }
.crm-facts { display: grid; grid-template-columns: 96px 1fr 96px 1fr; gap: 4px 12px; font-size: 12px; margin: 0 0 10px; }
.crm-facts dt { color: var(--text-dim); }
.crm-facts dd { color: var(--text); margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-nextstep, .crm-notes { margin-top: 8px; }
/* P2.5 cross-entity links: the deal record's open-in-context row */
.crm-openin { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 10px; }
.crm-nextstep .cck-tk-inline, .crm-notes .cck-tk-inline { width: 100%; margin-top: 4px; }
.crm-note { font-size: 12px; color: var(--text); padding: 6px 0; border-bottom: 1px solid var(--border); }
.crm-note:last-of-type { border-bottom: 0; }
.crm-note-ts { color: var(--text-faint); font-size: 11px; margin-right: 8px; }
.crm-thread { display: block; width: 100%; text-align: left; font: inherit; font-size: 12px; color: var(--text); padding: 6px 4px; border: 0; border-bottom: 1px solid var(--border); background: transparent; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-thread:hover { background: var(--row-hover); }
.crm-thread-on { background: var(--row-sel); border-radius: var(--radius); }
/* 'Check now' sits inline with the small section label — size it to match. */
.crm-mailcheck { font-size: 10.5px; padding: 2px 9px; margin-left: 6px; }
.crm-mailcheck i, .crm-mailcheck svg { width: 11px; height: 11px; }
/* In-place mini reader inside a record — same language as the main inbox
   reader: white card, hairline, subject title, scrollable thread. */
.crm-mailview { padding: 12px 14px; margin: 4px 0 8px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius-panel); box-shadow: var(--elev-1); }
.crm-mv-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
.crm-mv-subject { font-size: 14px; font-weight: 600; color: var(--cck-hero-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-mv-headacts { display: flex; align-items: center; gap: 4px; flex: none; }
.crm-mailthread { max-height: 340px; overflow-y: auto; }
.crm-mv-msg { padding: 8px 2px; border-bottom: 1px solid var(--border); }
.crm-mv-msg:last-child { border-bottom: 0; }
.crm-mv-row { display: block; width: 100%; text-align: left; font: inherit; background: transparent; border: 0; border-bottom: 1px solid var(--border); cursor: pointer; }
.crm-mv-row:hover { background: var(--row-hover); }
.crm-mv-meta { font-size: 11.5px; color: var(--text-dim); margin-bottom: 2px; }
.crm-mailtext { font-size: 12.5px; line-height: 1.55; color: var(--text); margin-top: 4px; }
/* ── HR surface (C7/R6) — rides the CRM panel grammar; hr-* deltas only ── */
.hr-stats { grid-template-columns: repeat(4, 1fr); }
/* Leave-status pill: the ONE status-pill grammar (fin-pill geometry, soft
   token pairs). Approved rows carry NO pill — the normal state is quiet. */
.hr-pill { font-size: 10px; font-weight: 700; letter-spacing: 0.03em; padding: 2px 8px; border-radius: var(--radius-pill); white-space: nowrap; margin-left: 6px; }
.hr-pill-requested { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.hr-pill-declined { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.hr-reason { font-size: 11px; color: var(--text-dim); font-style: italic; }
.hr-note { font-size: 11px; line-height: 1.5; color: var(--text-dim); margin-top: 8px; }
/* Per-employee documents: pointer rows into the live library (no copies). */
.hr-doc { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hr-doc-kind { flex: none; font-size: 10px; font-weight: 700; letter-spacing: 0.03em; padding: 2px 8px; border-radius: var(--radius-pill); background: var(--action-pill-info-bg); color: var(--action-pill-info-fg); white-space: nowrap; }
.hr-doc-open { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.hr-doc-path { font-size: 10.5px; color: var(--text-faint); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; }
.hr-doc .cck-tk-del { flex: none; }
/* The link-a-document search picker (inline, under the section) */
.hr-docsearch { position: relative; margin-top: 6px; }
.hr-docsearch-results { margin-top: 4px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-0); max-height: 220px; overflow: auto; }
.hr-dochit { display: block; width: 100%; text-align: left; font: inherit; font-size: 12px; color: var(--text); background: transparent; border: 0; border-bottom: 1px solid var(--border); padding: 6px 8px; cursor: pointer; }
.hr-dochit:last-child { border-bottom: 0; }
.hr-dochit:hover, .hr-dochit:focus-visible { background: var(--row-hover); }
.hr-dochit small { display: block; color: var(--text-faint); font-size: 10.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-ws-grid { grid-template-columns: repeat(4, 1fr); }
.crm-ws-panel .crm-stat-s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.cck-team-actions { margin-top: 14px; padding-top: 10px; border-top: 0.5px solid var(--border); }
.cck-team-head { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); padding: 0 4px 6px; }
.cck-team-sub { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--text-faint); }
.cck-team-owner { margin-bottom: 8px; }
.cck-team-name { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; color: var(--text); padding: 4px; }
.cck-team-av { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--cck-accent-soft); color: var(--cck-accent); font-size: 9px; font-weight: 700; }
.cck-team-n { margin-left: auto; font-size: 11px; color: var(--text-faint); }
.cck-team-list { list-style: none; margin: 0; padding: 0 0 0 27px; }
.cck-team-task { display: flex; flex-direction: column; gap: 1px; padding: 4px 4px 4px 0; border-bottom: 0.5px solid var(--border); }
.cck-team-tt { font-size: 12.5px; color: var(--text); }
.cck-team-mtg { font-size: 11px; color: var(--text-faint); }
.cck-bulletpop { position: fixed; z-index: 1310; min-width: 132px; padding: 5px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; box-shadow: 0 14px 40px rgba(20, 24, 33, 0.24); }
.cck-bulletpop button { display: flex; align-items: center; gap: 9px; width: 100%; padding: 6px 9px; border: none; border-radius: 6px; background: none; color: var(--text); font-size: 13px; cursor: pointer; text-align: left; }
.cck-bulletpop button:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-bulletpop .cck-bp-g { display: inline-flex; justify-content: center; width: 16px; font-size: 14px; }
.cck-fileov { position: fixed; inset: 0; z-index: 1000; background: var(--scrim); display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 28px; }   /* ONE scrim token app-wide (Jeremy 2026-07-08) */
.cck-fileov-bar { width: min(1000px, 94vw); display: flex; align-items: center; gap: 12px; background: var(--surface-0); border-radius: 12px 12px 0 0; padding: 10px 14px; border-bottom: 0.5px solid var(--border); }
.cck-fileov-title { flex: 1; font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cck-fileov-x { border: none; background: none; color: var(--text-dim); cursor: pointer; font-size: 16px; padding: 2px 8px; border-radius: 6px; }
.cck-fileov-x:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-fileov-body { width: min(1000px, 94vw); height: min(80vh, 820px); background: var(--surface-0); border-radius: 0 0 12px 12px; overflow: auto; display: flex; align-items: center; justify-content: center; }
.cck-fileov-body img { max-width: 100%; max-height: 100%; object-fit: contain; }
.cck-fileov-body iframe { width: 100%; height: 100%; border: none; }
.cck-fileov-other { display: flex; flex-direction: column; align-items: center; gap: 10px; color: var(--text-dim); padding: 40px; text-align: center; }
.cck-fileov-hint { font-size: 12px; color: var(--text-faint); }

/* WYSIWYG editor — a single hairline highlight on focus (no double outline) */
.cck-rte { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: 10px; background: var(--surface-0); overflow: hidden; }
.cck-rte:focus-within { border-color: var(--cck-accent); }
.cck-rte-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 1px; padding: 5px 7px; border-bottom: 0.5px solid var(--border); background: var(--surface); }
.cck-rte-btn { min-width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border: none; background: none; border-radius: 6px; color: var(--text-dim); cursor: pointer; font-size: 13px; }
.cck-rte-btn:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-rte-btn:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: -1px; }
/* Active tool = purple TONE highlight. */
.cck-rte-btn.on { background: var(--cck-accent-soft); color: var(--cck-accent); }
/* Format painter armed = clear "loaded" cue (accent fill + subtle pulse). */
.cck-rte-btn.armed { background: var(--cck-accent); color: var(--cck-accent-on); box-shadow: 0 0 0 2px var(--cck-accent-soft); }
.cck-rte-btn.armed .lucide-icon { color: var(--cck-accent-on); }
/* Text-colour "A" with an Outlook-style swatch bar showing the current colour. */
.cck-rte-fore { position: relative; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; font-weight: 700; line-height: 1; padding-bottom: 3px; }
.cck-rte-fore-a { font-size: 13px; }
.cck-rte-forebar { display: block; width: 15px; height: 3px; border-radius: 1px; margin-top: 1px; background: var(--media-ink); }
/* Text-colour SPLIT button: "A" (apply) welded to a ▾ menu (pick). */
.cck-rte-split { display: inline-flex; align-items: stretch; }
.cck-rte-split .cck-rte-fore { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.cck-rte-fore-menu { min-width: 15px; width: 15px; padding: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.cck-rte-fore-menu svg { width: 10px; height: 10px; }
/* Format-painter brush cursor while armed. */
.cck-rte-area.cck-rte-painting { cursor: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%230f6cbd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18.37 2.63 14 7l-1.59-1.59a2 2 0 0 0-2.82 0L8 7l9 9 1.59-1.59a2 2 0 0 0 0-2.82L17 10l4.37-4.37a2.12 2.12 0 1 0-3-3Z'/%3E%3Cpath d='M9 8c-2 3-4 3.5-7 4l8 10c2-1 6-5 6-7'/%3E%3C/svg%3E") 2 20, copy; }
.cck-rte-font, .cck-rte-size { height: 26px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); font-size: 12px; color: var(--text); padding: 0 4px; cursor: pointer; }
.cck-rte-font { max-width: 96px; } .cck-rte-size { width: 54px; }
.cck-rte-linesp { width: auto; min-width: 44px; text-align: center; }
.cck-rte-sep { width: 1px; height: 16px; background: var(--border); margin: 0 4px; }
/* Default editor text is a normal-weight email font (never bold). */
.cck-rte-area { flex: 1 1 auto; min-height: 120px; max-height: 320px; overflow-y: auto; padding: 12px 14px; font-family: Arial, Helvetica, "Segoe UI", sans-serif; font-size: 13px; font-weight: 400; line-height: 1.15; color: var(--text); outline: none; }
/* Bullet + numbered lists indent (with room for the marker), like a mail client */
.cck-rte-area ul, .cck-rte-area ol { padding-left: 1.6em; margin: 0.4em 0; }
.cck-rte-area ul { list-style: disc; } .cck-rte-area ol { list-style: decimal; }
.cck-rte-area li { margin: 0.15em 0; }
/* Colour palette popover (anchored near the button) */
.cck-colorpop { position: fixed; z-index: 1340; display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; padding: 8px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; box-shadow: 0 10px 30px rgba(20, 24, 33, 0.2); }
.cck-color-sw { width: 22px; height: 22px; border-radius: 5px; border: 0.5px solid rgba(20, 24, 33, 0.15); cursor: pointer; padding: 0; }
.cck-color-sw:hover { transform: scale(1.12); }
.cck-color-more { grid-column: 1 / -1; margin-top: 2px; height: 26px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-1); color: var(--text); font-size: 12px; cursor: pointer; }
.cck-color-more:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
/* Custom colour picker (RGB + CMYK sliders) — a popover, not a modal. */
.cck-cppop { position: fixed; z-index: 1350; width: 260px; padding: 12px; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 12px; box-shadow: 0 12px 34px rgba(20, 24, 33, 0.22); }
.cck-cppop .cck-cp-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
.cck-colorpicker .cck-cp-preview { height: 34px; border-radius: 8px; border: 0.5px solid var(--border); margin: 0 0 8px; }
.cck-colorpicker .cck-cp-group { margin-top: 10px; }
.cck-colorpicker .cck-cp-gl { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 4px; }
.cck-colorpicker .cck-cp-row { display: flex; align-items: center; gap: 8px; margin: 5px 0; }
.cck-colorpicker .cck-cp-lab { width: 34px; font-size: 12px; color: var(--text); }
.cck-colorpicker .cck-cp-row input[type="range"] { flex: 1 1 auto; }
.cck-colorpicker .cck-cp-num { width: 52px; height: 24px; border: 0.5px solid var(--border); border-radius: 6px; background: var(--surface-0); color: var(--text); font-size: 12px; text-align: center; }
.cck-colorpicker .cck-cp-hex { width: 100%; }
/* In-composer image editing: selection handles (free-form resize) + crop overlay */
.cck-rte-area img { max-width: 100%; height: auto; }
.cck-imgsel { position: absolute; box-sizing: border-box; border: 1.5px solid var(--cck-accent); z-index: 30; pointer-events: none; }
.cck-imgsel-h { position: absolute; width: 11px; height: 11px; background: var(--on-solid); border: 1.5px solid var(--cck-accent); border-radius: 2px; pointer-events: auto; }
.cck-imgsel-nw { left: -6px; top: -6px; cursor: nwse-resize; } .cck-imgsel-se { right: -6px; bottom: -6px; cursor: nwse-resize; }
.cck-imgsel-ne { right: -6px; top: -6px; cursor: nesw-resize; } .cck-imgsel-sw { left: -6px; bottom: -6px; cursor: nesw-resize; }
.cck-imgsel-n { left: 50%; top: -6px; margin-left: -5px; cursor: ns-resize; } .cck-imgsel-s { left: 50%; bottom: -6px; margin-left: -5px; cursor: ns-resize; }
.cck-imgsel-e { right: -6px; top: 50%; margin-top: -5px; cursor: ew-resize; } .cck-imgsel-w { left: -6px; top: 50%; margin-top: -5px; cursor: ew-resize; }
.cck-imgsel-bar, .cck-crop-bar { position: absolute; top: -32px; left: 0; display: flex; gap: 5px; pointer-events: auto; }
.cck-imgsel-bar button, .cck-crop-bar button { font-size: 11px; font-weight: 500; padding: 4px 9px; border-radius: 6px; border: 0.5px solid var(--border); background: var(--surface-0); color: var(--text); cursor: pointer; box-shadow: 0 2px 6px rgba(20, 24, 33, 0.14); }
/* Move grip — a drag affordance (grab cursor + inline icon). */
.cck-imgsel-move { display: inline-flex; align-items: center; gap: 4px; cursor: grab; }
.cck-imgsel-move:active { cursor: grabbing; }
.cck-imgsel-move .lucide-icon { width: 13px; height: 13px; }
/* Ghost that follows the cursor while moving an image, + a caret hint. */
.cck-img-ghost { position: fixed; pointer-events: none; z-index: 2000; max-width: 160px; max-height: 120px; opacity: 0.65; border-radius: 4px; box-shadow: 0 6px 18px rgba(20, 24, 33, 0.3); }
/* Live drop-caret shown while placing a moved image (marks the landing point). */
.cck-img-drop-caret { display: inline-block; width: 2px; height: 1.1em; margin: 0 -1px; vertical-align: text-bottom; background: var(--cck-accent); pointer-events: none; }
body.cck-img-moving { cursor: copy !important; }
/* Rotate handle — a small knob on a stem above the image (Word/PowerPoint-style). */
.cck-imgsel-rot { position: absolute; left: 50%; top: -26px; width: 12px; height: 12px; margin-left: -6px; background: var(--on-solid); border: 1.5px solid var(--cck-accent); border-radius: 50%; pointer-events: auto; cursor: grab; z-index: 32; }
.cck-imgsel-rot::before { content: ''; position: absolute; left: 50%; top: 11px; width: 1.5px; height: 15px; margin-left: -0.75px; background: var(--cck-accent); }
.cck-crop { position: absolute; box-sizing: border-box; z-index: 31; }
.cck-crop-bar { top: auto; bottom: -32px; }
/* Dim only the cropped-away part of the IMAGE — never the whole editor. */
.cck-crop-shade { position: absolute; inset: 0; overflow: hidden; }
.cck-crop-rect { position: absolute; box-sizing: border-box; border: 1px solid var(--on-solid); box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45); cursor: move; }
/* Word-style crop marks: right-angle marks on corners, short bars on edges. */
.cck-crop-h { position: absolute; pointer-events: auto; filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.9)); }
.cck-crop-nw, .cck-crop-ne, .cck-crop-se, .cck-crop-sw { width: 12px; height: 12px; border: 2.5px solid var(--media-ink); }
.cck-crop-nw { left: -3px; top: -3px; border-right: 0; border-bottom: 0; cursor: nwse-resize; }
.cck-crop-ne { right: -3px; top: -3px; border-left: 0; border-bottom: 0; cursor: nesw-resize; }
.cck-crop-se { right: -3px; bottom: -3px; border-left: 0; border-top: 0; cursor: nwse-resize; }
.cck-crop-sw { left: -3px; bottom: -3px; border-right: 0; border-top: 0; cursor: nesw-resize; }
.cck-crop-n, .cck-crop-s { left: 50%; width: 20px; height: 4px; margin-left: -10px; background: var(--media-ink); cursor: ns-resize; }
.cck-crop-e, .cck-crop-w { top: 50%; width: 4px; height: 20px; margin-top: -10px; background: var(--media-ink); cursor: ew-resize; }
.cck-crop-n { top: -2px; } .cck-crop-s { bottom: -2px; } .cck-crop-e { right: -2px; } .cck-crop-w { left: -2px; }
.cck-rte-area:empty::before { content: attr(data-placeholder); color: var(--text-faint); pointer-events: none; }

/* Composer: toned surrounding panel so the white editing area stands out, with
   the editor filling the height and equal padding to the bottom edge. */
.cck-viewer .cck-work.cck-compose { display: flex; flex-direction: column; }
.cck-compose .cck-form { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 12px; background: var(--surface-2); border: 0.5px solid var(--border-dark); border-radius: 12px; padding: 16px; }
.cck-reply.cck-reply-open { background: var(--surface-2); border: 0.5px solid var(--border-dark); border-radius: 12px; padding: 14px; margin-bottom: 16px; }
.cck-compose .cck-input, .cck-reply .cck-input { background: var(--surface-0); border-color: var(--border-dark); }
.cck-compose .cck-rte, .cck-reply .cck-rte { border-color: var(--border-dark); }
.cck-field-grow { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.cck-field-grow > span { margin-bottom: 4px; }
.cck-field-grow .cck-rte { flex: 1 1 auto; min-height: 0; }
.cck-field-grow .cck-rte-area { max-height: none; }
.cck-form-spacer { flex: 1 1 auto; }
.cck-drop-over { outline: 2px dashed var(--cck-accent); outline-offset: -4px; }

/* Draft attachment chips (removable) */
.cck-draft-atts:empty { display: none; }
.cck-att-static { cursor: default; }
.cck-att-static:hover { background: var(--surface-0); border-color: var(--border); color: var(--text); }
.cck-att-x { border: none; background: none; color: var(--text-faint); cursor: pointer; font-size: 12px; padding: 0 2px; border-radius: 4px; }
.cck-att-x:hover { background: var(--danger); color: var(--on-solid); }

/* In-app prompt (replaces window.prompt) */
.cck-prompt { width: min(420px, 92vw); background: var(--surface-0); border-radius: 12px; padding: 18px; box-shadow: 0 12px 32px rgba(20, 24, 33, 0.22); display: flex; flex-direction: column; gap: 12px; }
.cck-prompt-label { font-size: 13px; font-weight: 600; color: var(--text); }
.cck-prompt-sub { font-size: 12.5px; line-height: 1.5; color: var(--text-dim); margin: 0; }
.cck-prompt-actions { display: flex; justify-content: flex-end; gap: 8px; }
.cck-act-danger { background: var(--cck-danger); color: var(--on-solid); border: 0.5px solid var(--cck-danger); }
.cck-act-danger:hover { filter: brightness(0.95); }

/* Reader flag/pin toggles: fill the ICON (red / blue), not the whole button */
.cck-iconpill-flag.on, .cck-iconpill-pin.on { background: var(--surface-0); border-color: var(--border); }
.cck-iconpill-flag.on { color: var(--cck-danger); }
.cck-iconpill-flag.on:hover { background: var(--surface-0); color: var(--cck-danger); }
.cck-iconpill-pin.on { color: var(--cck-accent); }
.cck-iconpill-pin.on:hover { background: var(--surface-0); color: var(--cck-accent); }
/* Solid (filled) glyph in the on-state — CSS fill overrides lucide's inline fill="none" */
.cck-iconpill-flag.on svg { fill: var(--cck-danger); }
.cck-iconpill-pin.on svg { fill: var(--cck-accent); }

/* Filing + approval rail rows */
.cck-frow-list, .cck-aprow-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.cck-frow { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 14px; background: var(--surface); border: 0.5px solid var(--border); border-radius: 12px; cursor: pointer; }
.cck-frow:hover { border-color: var(--border-dark); }
.cck-frow-label { font-size: 14px; font-weight: 500; color: var(--cck-hero-text); }
.cck-frow-n { font-size: 14px; font-weight: 600; color: var(--cck-hero-text); font-variant-numeric: tabular-nums; }
/* Jeremy 2026-07-06: the rail shows the DD STAGE as the same chip the CRM
   table uses ("3 · Pricing") — smaller to fit the rail row, never wraps. */
.pjw-stage-chip { font-size: 10px; padding: 1px 7px; white-space: nowrap; font-weight: 600; }
.cck-aprow { display: flex; align-items: center; gap: 10px; padding: 12px 14px; background: var(--surface); border: 0.5px solid var(--border); border-radius: 12px; cursor: pointer; }
.cck-aprow:hover { border-color: var(--border-dark); }
.cck-aprow-label { font-size: 13px; font-weight: 500; color: var(--cck-hero-text); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* Compact priorities rows in the rail (the open action lives in the viewer) */
.cck-rail .cck-actions .cck-act { display: none; }
.cck-rail .cck-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cck-rail .cck-why { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cck-rail .cck-row { gap: 9px; padding: 12px 12px; }
.cck-rail .cck-list { gap: 8px; }
.cck-rail .cck-title { font-size: 14px; -webkit-line-clamp: 3; }
.cck-rail .cck-icbtn { display: none; }        /* snooze via drag / NL box in the compact rail */
.cck-rail .cck-why { display: none; }          /* reason shows in the viewer — keep the rail clean */
.cck-rail .cck-row { padding: 13px 14px; gap: 11px; }
.cck-rail .cck-list { gap: 9px; }

/* AI assistant rail */
.cck-ai-head { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; color: var(--cck-hero-text); }
.cck-ai-head .lucide-icon { color: var(--cck-accent); }
.cck-ai-ctx { font-size: 11px; color: var(--text-dim); margin: 3px 0 12px; }
.cck-ai-thread { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; justify-content: flex-end; gap: 8px; margin-bottom: 12px; }
.cck-ai-msg { font-size: 12px; line-height: 1.5; padding: 8px 11px; border-radius: 10px; max-width: 92%; }
.cck-ai-you { align-self: flex-end; background: var(--cck-accent); color: var(--cck-accent-on); }
.cck-ai-bot { align-self: flex-start; background: var(--surface-0); color: var(--text); border: 0.5px solid var(--border); }
.cck-ai-sugg { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }
.cck-sugg { text-align: left; font-size: 12px; padding: 8px 11px; border: 0.5px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--cck-hero-text); cursor: pointer; }
.cck-sugg:hover { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: transparent; }
.cck-ai-input { display: flex; gap: 6px; margin-top: 10px; }
.cck-ai-box { flex: 1; min-width: 0; padding: 8px 12px; border: 0.5px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text); font: 400 13px/1.2 inherit; }
.cck-ai-box:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 1px; }
.cck-ai-send { flex: none; width: 32px; height: 32px; border-radius: 50%; border: none; background: var(--cck-accent); color: var(--cck-accent-on); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.cck-ai-send .lucide-icon { display: block; }
.cck-ai-thinking { opacity: 0.6; }

/* Meeting stats + attendees + search */
/* Meeting view — separated section panels */
.cck-mview { display: flex; flex-direction: column; gap: 14px; }
.cck-mview { background: var(--cck-canvas); margin: -20px -22px; padding: 20px 22px; min-height: calc(100% + 40px); }
/* Lock the header + attendees + pills; only the active section scrolls. */
.cck-mfixed { position: sticky; top: -20px; z-index: 3; display: flex; flex-direction: column; gap: 14px; background: var(--cck-canvas); padding: 20px 0 14px; margin-top: -20px; }
.cck-mscroll { display: flex; flex-direction: column; gap: 14px; padding-bottom: 56px; } /* Jeremy 2026-07-16: breathing room so the LAST line of the Minutes (and Transcript/Actions) is always fully visible at the end of the scroll, never cut off at the fold. */
.cck-mpanel { background: var(--surface); border: 0.5px solid var(--border); border-radius: 14px; padding: 18px 20px; box-shadow: 0 1px 2px rgba(20, 24, 33, 0.05), 0 1px 1px rgba(20, 24, 33, 0.03); }
.cck-mpanel-head { padding-bottom: 16px; background: linear-gradient(180deg, var(--cck-accent-soft), var(--surface) 70%); }
.cck-mpanel-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); margin-bottom: 12px; }
.cck-mpanel .cck-work-summary { margin: 0; }
.cck-mpanel .cck-kws { margin-top: 12px; margin-bottom: 0; }
.cck-mpanel .cck-att-cos { margin-bottom: 0; }
.cck-mpanel .cck-owners { margin-bottom: 0; }
.cck-mstats { display: flex; gap: 18px; margin: 4px 0 0; font-size: 13px; color: var(--text-dim); }
/* Meeting section pills: Summary · Minutes · Actions */
.cck-mtabs { display: flex; gap: 6px; }
.cck-mtab { height: 32px; padding: 0 16px; border: 0.5px solid var(--border); border-radius: 999px; background: var(--surface-0); color: var(--text-dim); font: 500 13px/1 inherit; cursor: pointer; }
.cck-mtab:hover { color: var(--text); }
.cck-mtab-on { background: var(--cck-accent); border-color: var(--cck-accent); color: var(--cck-accent-on); }
.cck-minutes { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 10px; }
.cck-minutes li { font-size: 14px; line-height: 1.5; color: var(--text); padding-left: 4px; }
.cck-minutes li::marker { color: var(--cck-accent); font-weight: 600; }
.cck-mempty { margin: 0; padding: 0; text-align: left; }   /* in-flow pane line, reads with the pane's text; faint→dim via the shared grammar (P2.1) */
/* Detailed minutes rendered from Fireflies "notes" markdown. */
.cck-min-notes { display: flex; flex-direction: column; gap: 8px; }
.cck-min-h { color: var(--cck-hero-text); font-weight: 600; letter-spacing: -0.01em; }
.cck-min-h1 { font-size: 15px; margin-top: 6px; }
.cck-min-h2 { font-size: 14px; margin-top: 8px; }
.cck-min-h3 { font-size: 13px; margin-top: 4px; color: var(--text-dim); }
.cck-min-h:first-child { margin-top: 0; }
/* Numbered minutes, matching the Word report (Jeremy 2026-07-08): 1. / 1.1,
   sub-clause numbers starting AT the main clause's text margin. */
.cck-min-notes { counter-reset: mmain; }   /* ONE numbering run per pane — blank lines split lists, they must not restart the clauses */
.cck-min-list { margin: 0; display: flex; flex-direction: column; }
.cck-min-item { counter-increment: mmain; counter-reset: msub; position: relative;
  padding-left: 34px; font-size: 13.5px; line-height: 1.55; color: var(--text); margin-top: 10px; }
.cck-min-item:first-child { margin-top: 2px; }
.cck-min-item::before { content: counter(mmain) "."; position: absolute; left: 0; width: 30px;
  font-weight: 600; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.cck-min-subitem { counter-increment: msub; counter-reset: none; padding-left: 72px; margin-top: 4px; }   /* reset:none — else every sub re-resets msub and shows x.1 */
.cck-min-subitem::before { content: counter(mmain) "." counter(msub); left: 34px; width: 34px; }
.cck-min-li::marker { color: var(--cck-accent); }
.cck-min-li.cck-min-sub { margin-left: 16px; font-size: 13px; color: var(--text-dim); list-style: circle; }
.cck-min-p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--text); }
.cck-min-notes strong { font-weight: 600; color: var(--cck-hero-text); }
.cck-min-ts { font-variant-numeric: tabular-nums; font-size: 11.5px; color: var(--text-faint); background: var(--cck-canvas); border-radius: 5px; padding: 0 5px; margin-left: 2px; cursor: pointer; border: none; }
.cck-min-ts:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-tr-jump { animation: cck-tr-flash 2.4s ease; }
@keyframes cck-tr-flash { 0% { background: var(--cck-accent-soft); } 100% { background: transparent; } }
.cck-mstats b { color: var(--cck-hero-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.cck-attendees { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.cck-att { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text); background: var(--surface-0); border: 0.5px solid var(--border); padding: 3px 11px 3px 3px; border-radius: 999px; }
.cck-att-av { width: 20px; height: 20px; border-radius: 50%; background: var(--cck-accent-soft); color: var(--cck-accent); display: inline-flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 600; flex: none; }
.cck-att-cos { display: flex; flex-direction: column; gap: 12px; margin-bottom: 16px; }
.cck-att-co .cck-attendees { margin-bottom: 0; }
.cck-att-co-h { display: flex; align-items: center; gap: 6px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin-bottom: 7px; }
.cck-att-co-n { font-size: 10px; font-weight: 600; padding: 0 6px; border-radius: 999px; background: var(--chip-bg); color: var(--chip-fg); }

/* ── Always-on Office presence dock ─────────────────────────────────── */
.ofc-dock { position: relative; border-top: 0.5px solid var(--border); background: var(--surface); padding: 10px 18px 12px; flex: none; }
/* Drag the top edge to resize the dock/chat height. */
.ofc-resize { position: absolute; top: -3px; left: 0; right: 0; height: 9px; cursor: row-resize; z-index: 5; }
.ofc-resize::before { content: ''; position: absolute; left: 50%; top: 3px; width: 40px; height: 3px; margin-left: -20px; border-radius: 2px; background: transparent; transition: background var(--motion-micro) var(--motion-easing); }
.ofc-resize:hover::before { background: var(--border-dark); }
.ofc-bar { display: flex; align-items: center; justify-content: flex-start; gap: 6px; margin-bottom: 10px; }
.ofc-bar-label { display: inline-flex; align-items: center; gap: 8px; margin-left: 8px; }
.ofc-bar-l { display: flex; align-items: center; gap: 8px; }
.ofc-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--presence-on); box-shadow: 0 0 0 3px rgba(31, 184, 122, 0.18); }
.ofc-title { font-size: 13px; font-weight: 600; color: var(--text); }
.ofc-sub { font-size: 12px; color: var(--text-dim); }
.ofc-bar-r { display: flex; align-items: center; gap: 6px; }
.ofc-ctl { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 11px; border: 0.5px solid var(--border); border-radius: 999px; background: var(--surface-0); color: var(--text); font: 500 12px/1 inherit; cursor: pointer; }
.ofc-ctl:hover { background: var(--surface); }
.ofc-ctl-icon { padding: 0 8px; }
.ofc-ctl-on { background: var(--cck-accent); border-color: var(--cck-accent); color: var(--on-solid); }
.ofc-body { display: flex; gap: 12px; align-items: flex-start; }
.ofc-body .ofc-tiles { flex: 0 0 auto; }   /* keep tiles at natural width on the left — never shrink */
/* No top padding: the tile tops line up exactly with the chat panel top. */
.ofc-tiles { display: flex; gap: 10px; overflow-x: auto; padding: 0 3px 3px; }
/* Chats sit side by side in their own row; the dock position (right/under)
   decides whether that row is beside the tiles or below them. */
.ofc-chats { display: flex; gap: 10px; flex: 1 1 auto; min-width: 0; align-items: stretch; }
.ofc-body.ofc-chat-under { flex-direction: column; align-items: flex-start; }
/* Under-docked: the tiles keep their natural (6-box) width, and JS sizes the
   chats row to match so its right edge lines up with the last video box. */
.ofc-body.ofc-chat-under .ofc-tiles { width: auto; max-width: 100%; }
/* Team chat panel — height is user-resizable via the dock's top handle. */
.ofc-chat { flex: 1 1 0; min-width: 300px; display: flex; flex-direction: column; height: var(--ofc-chat-h, 188px); border: 1px solid var(--border); border-radius: 12px; background: var(--surface-0); overflow: hidden; box-shadow: 0 2px 10px rgba(20, 24, 33, 0.10); }
.ofc-chat-head { display: flex; align-items: center; gap: 7px; padding: 9px 12px; border-bottom: 1px solid var(--border); background: var(--cck-accent-soft); font-size: 12px; font-weight: 600; color: var(--text); }
.ofc-chat-name { font-size: 12px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ofc-chat-head-sp { flex: 1 1 auto; }
.ofc-chat-hbtn { flex: none; border: none; background: none; color: var(--text-dim); cursor: pointer; padding: 3px; border-radius: 6px; display: inline-flex; align-items: center; }
.ofc-chat-hbtn:hover { background: rgba(20, 24, 33, 0.08); color: var(--text); }
.ofc-chat-head .lucide-icon { color: var(--cck-accent); flex: none; }
.ofc-chat-to-label { font-size: 11px; font-weight: 500; color: var(--text); }
.ofc-chat-rcpt { border: 0.5px solid var(--border); border-radius: 7px; background: var(--surface); color: var(--text); font: 600 12px/1 inherit; padding: 4px 7px; max-width: 150px; cursor: pointer; }
.ofc-chat-open { margin-left: auto; width: 24px; height: 24px; flex: none; border: 0.5px solid var(--border); border-radius: 7px; background: var(--surface); color: var(--cck-accent); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.ofc-chat-open:hover { background: var(--cck-accent); color: var(--on-solid); }
.ofc-chat-thread { flex: 1; overflow-y: auto; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.ofc-chat-empty { font-size: 11.5px; margin: auto; padding: 0; }   /* miniature office-dock scale (matches its 11.5px rows) on the shared grammar (P2.1) */
.ofc-chat-msg { font-size: 12px; line-height: 1.4; padding: 6px 10px; border-radius: 11px; max-width: 88%; word-wrap: break-word; }
.ofc-chat-you { align-self: flex-end; background: var(--cck-accent); color: var(--on-solid); }
.ofc-chat-them { align-self: flex-start; background: var(--surface); border: 0.5px solid var(--border); color: var(--text); }
.ofc-chat-from { display: block; font-size: 10px; font-weight: 600; color: var(--text-dim); margin-bottom: 2px; }
.ofc-chat-input { display: flex; gap: 6px; padding: 8px; border-top: 0.5px solid var(--border); position: relative; align-items: center; }
.ofc-chat-ic { width: 28px; height: 28px; flex: none; border: none; border-radius: 8px; background: transparent; color: var(--text-dim); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: 15px; line-height: 1; }
.ofc-chat-ic:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.ofc-emoji-pop { position: absolute; bottom: calc(100% + 6px); left: 8px; width: 312px; max-height: 76px; overflow-y: auto; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 12px; box-shadow: 0 8px 24px rgba(20, 24, 33, 0.16); padding: 8px; display: flex; flex-wrap: wrap; gap: 2px; z-index: 5; }
/* display:flex above out-specifies the UA [hidden] rule, so the hidden attribute
   alone would not hide the picker. Re-assert display:none for [hidden] so the JS
   toggle (pop.hidden = !pop.hidden) actually shows AND hides it. */
.ofc-emoji-pop[hidden] { display: none; }
.ofc-emoji { width: 30px; height: 30px; border: none; background: transparent; border-radius: 7px; font-size: 17px; cursor: pointer; }
.ofc-emoji:hover { background: var(--cck-accent-soft); }
.ofc-chat.ofc-chat-drag { outline: 2px dashed var(--cck-accent); outline-offset: -4px; }
.ofc-chat.ofc-chat-drag::after { content: "Drop to attach"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; color: var(--cck-accent); background: rgba(42, 43, 216, 0.06); pointer-events: none; z-index: 6; }
.ofc-chat { position: relative; }
.ofc-chat-box { flex: 1; min-width: 0; border: 0.5px solid var(--border); border-radius: 999px; padding: 6px 12px; font: 400 12px/1.2 inherit; background: var(--surface); color: var(--text); outline: none; }
.ofc-chat-send { width: 30px; height: 30px; flex: none; border: none; border-radius: 50%; background: var(--cck-accent); color: var(--on-solid); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.ofc-chat-live { margin-left: auto; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--live-green); display: inline-flex; align-items: center; gap: 4px; }
.ofc-chat-live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--presence-on); }
.ofc-chat-connect { margin: auto; max-width: 320px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 9px; padding: 8px; }
.ofc-chat-connect .lucide-icon { color: var(--cck-accent); }
.ofc-chat-connect p { font-size: 13px; line-height: 1.45; color: var(--text-dim); margin: 0; }
.ofc-chat-err { font-size: 11.5px; color: var(--danger-text) !important; }
.ofc-chat-connect-btn { height: 34px; padding: 0 18px; border: none; border-radius: 999px; background: var(--cck-accent); color: var(--on-solid); font: 600 13px/1 inherit; cursor: pointer; }
.ofc-chat-connect-btn[disabled] { opacity: 0.6; cursor: default; }
.ofc-tile { flex: none; width: 104px; }
.ofc-vid { position: relative; width: 104px; height: 68px; border-radius: 12px; overflow: hidden; background: linear-gradient(160deg, var(--cck-accent-soft), var(--surface-0)); display: flex; align-items: center; justify-content: center; border: 0.5px solid var(--border); }
/* Your own tile carries no accent ring — the "(you)" label under it already
   identifies it, so the tile keeps the same neutral border as everyone else. */
.ofc-stream { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: none; z-index: 2; transform: scaleX(-1); }
.ofc-vid[data-live="1"] .ofc-stream { display: block; }
.ofc-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }
.ofc-av { font-size: 20px; font-weight: 600; color: var(--cck-accent); letter-spacing: 0.02em; }
.ofc-vid-hidden .ofc-av { opacity: 0.25; }
.ofc-hidden-ic { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--text-faint); background: rgba(20, 24, 33, 0.05); }
.ofc-dot { position: absolute; bottom: 5px; left: 5px; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--surface-0); }
.ofc-dot-on { background: var(--presence-on); }
.ofc-dot-busy { background: var(--cck-danger); }
.ofc-dot-call { background: var(--presence-call); }
.ofc-dot-away { background: var(--presence-away); }
.ofc-dot-off { background: var(--presence-off); }
.ofc-tile-acts { position: absolute; top: 4px; right: 4px; display: flex; gap: 3px; opacity: 0; transition: opacity var(--motion-micro) var(--motion-easing); }
.ofc-tile:hover .ofc-tile-acts, .ofc-tile:focus-within .ofc-tile-acts { opacity: 1; }
.ofc-tact { width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 7px; background: rgba(20, 24, 33, 0.62); color: var(--on-solid); cursor: pointer; }
.ofc-tact:hover { background: rgba(20, 24, 33, 0.82); }
.ofc-name { margin-top: 5px; font-size: 12px; font-weight: 500; color: var(--text); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ofc-role { display: block; font-size: 10px; font-weight: 400; color: var(--text-dim); }
.ofc-note { margin-top: 9px; display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-dim); }
.ofc-collapsed { padding: 8px 18px; }
.ofc-reopen { display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 0 14px; border: 0.5px solid var(--border); border-radius: 999px; background: var(--surface-0); color: var(--text); font: 600 12px/1 inherit; cursor: pointer; }
.ofc-livecount { min-width: 18px; height: 18px; padding: 0 5px; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; background: var(--presence-on); color: var(--on-solid); font-size: 10px; font-weight: 700; }
.cck-rail-search { display: flex; align-items: center; gap: 6px; padding: 7px 11px; margin-bottom: 10px; border: 0.5px solid var(--border); border-radius: 999px; background: var(--surface); }
.cck-rail-search .lucide-icon { color: var(--text-faint); flex: none; }
.cck-mtg-search { flex: 1; min-width: 0; border: none; background: none; outline: none; font: 400 13px/1.2 inherit; color: var(--text); }
.cck-mtg[hidden] { display: none; }   /* beats .cck-mtg{display:flex} so search + pagination actually hide rows */
.cck-loadmore { width: 100%; margin-top: 8px; height: 34px; border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); color: var(--text-dim); font: 500 12px/1 inherit; cursor: pointer; }
.cck-loadmore:hover { color: var(--text); background: var(--surface); }
.cck-loadmore.cck-loadall { display: inline-flex; align-items: center; justify-content: center; gap: 6px; margin-top: 6px; color: var(--cck-accent); border-color: var(--cck-accent); }
.cck-loadmore.cck-loadall:hover { background: var(--cck-accent-soft); }
.cck-loadmore.cck-loadall[disabled] { opacity: 0.7; cursor: default; }
.cck-mtg-cachenote { margin-top: 8px; padding: 6px 4px; font-size: 11px; color: var(--text-faint); text-align: center; }
.cck-linkbtn { border: 0; background: transparent; padding: 0; color: var(--cck-accent); font: inherit; font-size: 11px; cursor: pointer; text-decoration: underline; }

@media (max-width: 1366px) {
  .cck-shell { --cck-ai-w: 300px; }
  .cck-panes { grid-template-columns: 300px minmax(0,1fr); }
}

/* ── PANE ────────────────────────────────────────────────────── */
.pane {
  flex: 1; display: flex; flex-direction: column; overflow: hidden;
  border-right: 1px solid var(--border);
  /* Width settles in step with the inspector's --motion-duration transition (the
     inspector-rail width-preset cycle drives R→0 / restore — Batch B). */
  transition: flex-basis var(--motion-duration) var(--motion-easing), width var(--motion-duration) var(--motion-easing);
}
.pane:last-child { border-right: none; }

/* State 1 (Inspector + Left equal): the right pane collapses to NOTHING — a
   zero-width overflow-hidden flex child, NOT the old 40px rail. The tree stays
   mounted (don't unmount/re-render); it just renders at 0 width and re-flows
   when R returns. design-tester inspector-rail-cycle §6.1 / §8.2. */
.pane--zero { width: 0; min-width: 0; flex: none; overflow: hidden; }

/* State-1 SEAM FIX (iris-inspector-rail-cycle §4.3). At I=50vw the 5px
   #pane-resizer (--border) and the inspector's coincident 1px left border
   (--border) read as one fat ~6px smear. When R=0 the splitter is the ONLY
   intended divider, so drop the inspector's left border; the rail's surface-2
   fill already marks the surface boundary. Scoped to the R=0 preset via the
   #app.layout-r0 class set in applyLayoutPreset(1). */
#app.layout-r0 #inspector { border-left: none; }

.pane-footer {
  height: 22px; display: flex; align-items: center; gap: 0;
  padding: 0 0 0 8px; flex-shrink: 0;   /* 8px left matches tree-row left padding */
  background: var(--pane-chrome-bg);   /* Iris Brief #1: flat, themable */
  border-top: 1px solid var(--footer-border);
  font-size: 11px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden;
}
/* Column-aligned footer cells — widths mirror the tree columns exactly */
.pf-name {
  width: var(--col-name-w); flex: none;
  padding: 0 6px 0 2px;    /* container supplies the 8px left offset */
  color: var(--text-dim); font-weight: 500;
}
.pf-files {
  width: var(--col-files-w); flex: none;
  text-align: right; padding-right: 4px;   /* tighter → text sits closer to right edge */
  font-weight: 500;
}
.pf-size {
  width: var(--col-size-w); flex: none;
  text-align: right; padding-right: 14px;  /* more breathing room → text sits left of edge */
  font-weight: 500;
}

/* ── Audit walk-through panel (right pane, replaces tree while reviewing) ── */
.audit-walk-panel {
  flex: 1; display: none; flex-direction: column;
  background: var(--surface);
  overflow: hidden; min-height: 0;
  /* Iris walk-pane toast/confirm spec 2026-06-25: anchor for the position:absolute
     walk-scoped undo toast (.toast-container--walk) + delete confirm (.confirm-modal--walk)
     so they resolve against the right pane, centred in its white space. */
  position: relative;
}
/* ── Walk-through panel — redesigned 2026-05-17 ────────────────────
   Editorial-diff-card concept: one sans family, one mono (paths only),
   weights 400 / 600 only, vertical rhythm on the 4/8/12/16/24 scale.
   IN/WHY uppercase labels dropped — replaced with glyph-prefixed prose. */

/* Header — 32px tall, single border-bottom is the only divider in the meta. */
.aw-header {
  display: flex; align-items: center; gap: 8px;
  padding: 0 16px;
  height: 40px; flex-shrink: 0;
  border-bottom: 1px solid var(--border);
}
.aw-counter {
  flex: 1;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.aw-counter strong { font-weight: 600; color: var(--text); }
.aw-counter-sub { color: var(--text-faint); }

/* Iris walk-presentation §2: generic-header relayout. The nav cluster lives in
   the header now: [count][‹ › | ↻]…push…[badge][✕]. Scope the flex override to
   .aw-header--proposal so the shared global .aw-counter{flex:1} (inbox header)
   is untouched. The badge gets margin-left:auto so it + the X sit hard-right. */
.aw-header--proposal .aw-counter { flex: 0 0 auto; }
.aw-header-nav { display: inline-flex; align-items: center; gap: 2px; margin-left: 4px; }
.aw-header-nav .aw-header-divider { width: 1px; height: 16px; background: var(--border); margin: 0 4px; }
.aw-header--proposal .aw-mode-badge { margin-left: auto; }

/* D-19 Phase 1 Day 4: Step Through Mode toggle (per Iris spec §2 — Lucide
   icons, segmented-control look, --chip-bg-active for pressed state). */
.aw-mode-toggle {
  display: inline-flex; align-items: center; gap: 2px;
  margin-left: 12px;
  padding: 2px;
  border-radius: 4px;
  background: var(--surface-2);
}
.aw-mode-btn {
  width: 24px; height: 24px; padding: 0;
  background: transparent; border: none; border-radius: 3px;
  color: var(--text-dim); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1), color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aw-mode-btn:hover:not([aria-pressed="true"]) { background: var(--row-hover); color: var(--text); }
.aw-mode-btn[aria-pressed="true"] {
  background: var(--chip-bg-active, var(--accent));
  color: var(--chip-fg);
}
.aw-mode-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Mode A: walk-through panel collapses to a thin footer strip (the right
   tree is visible alongside the left tree — both panes pulse on the
   current item). Hide the editorial card + result preview; keep only
   header + footer. */
body.aw-mode-tree .audit-walk-panel {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  flex-direction: row;
  align-items: center;
  height: auto;
  background: var(--surface);
  border-top: 1px solid var(--border);
  box-shadow: 0 -2px 8px rgba(0,0,0,0.06);
  z-index: 50;
}
body.aw-mode-tree .audit-walk-panel .aw-meta,
body.aw-mode-tree .audit-walk-panel .aw-preview-section { display: none; }
body.aw-mode-tree .audit-walk-panel .aw-header { border: none; height: auto; padding: 6px 16px; }
body.aw-mode-tree .audit-walk-panel .aw-footer { border: none; padding: 6px 16px; }

.aw-stop {
  width: 24px; height: 24px; padding: 0;
  background: transparent; border: none; border-radius: 4px;
  color: var(--text-faint); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1), color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aw-stop:hover { background: var(--surface-2); color: var(--text); }
.aw-stop:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Meta block — content padding centred in a 560px column on wide panels
   so the editorial reads as a card, not a billboard. Per design-tester
   unified spec (batch 41, 2026-05-19). Bottom border is the thin section
   divider before RESULT (Jeremy round 8). */
.aw-meta {
  padding: 16px 24px;
  max-width: 560px;
  margin: 0 auto;
  flex-shrink: 0;
  width: 100%;
  box-sizing: border-box;
  /* Iris stepthrough-otto-polish Piece 1: divider removed — the callout-card
     frame inside now carries the separation; the section reads as a card. */
  border-bottom: none;
}

/* Iris stepthrough-otto-polish Piece 1 (2026-06-25): the Otto callout-card
   frame on the proposal header. Wraps the unchanged walk grid (pill + all
   rows). 1px border + a 3px left-accent BY KIND (data-action-kind, no JS
   branching) + an identity line (glyph + actionLabel) above a hairline rule.
   Per-kind accent reuses the SAME --action-pill-*-fg tokens the pill uses. */
.aw-callout-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--elev-2);
  padding: 12px 16px;
}
.aw-callout-identity {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.aw-callout-glyph {
  display: inline-flex;
  flex-shrink: 0;
  font-size: 16px;
  line-height: 1;
  color: var(--text-dim);
}
.aw-callout-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.aw-callout-rule {
  height: 1px;
  background: var(--border);
  margin: 12px 0;
}
.aw-callout-card[data-action-kind="rename"],
.aw-callout-card[data-action-kind="naming"]      { border-left-color: var(--action-pill-warn-fg); }
.aw-callout-card[data-action-kind="move"],
.aw-callout-card[data-action-kind="rename+move"] { border-left-color: var(--action-pill-info-fg); }
.aw-callout-card[data-action-kind="delete"]      { border-left-color: var(--action-pill-danger-fg); }
.aw-callout-card[data-action-kind="merge"]       { border-left-color: var(--action-pill-merge-fg); }
.aw-callout-card[data-action-kind="inbox"]       { border-left-color: var(--action-pill-info-fg); }
.aw-callout-card[data-action-kind="check-folder"]{ border-left-color: var(--action-pill-check-fg); }

/* Coloured action-kind palette on the FROM row's label — replaces the
   neutral grey badge with the action's identity (Jeremy round 8: don't
   need a "FROM" label since the coloured action tag IS the FROM marker).
   Selector mirrors .sa-row[data-action-kind] from the Inspector list-view. */
/* Iris brief-12 §4: re-pointed from bespoke rgba() + dupe-similar/etc.
   to the same --action-pill-*-bg/fg tokens the list-row pill uses at
   .aic-row-pill[data-pill] (main.css:4014-4018), so the detail-card
   pill matches the list-row pill at every theme. Dark-mode override
   block deleted — tokens carry dark mode natively. */
.aw-row[data-action-kind="rename"]      .aw-row-label-action,
.aw-row[data-action-kind="naming"]      .aw-row-label-action { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.aw-row[data-action-kind="move"]        .aw-row-label-action,
.aw-row[data-action-kind="rename+move"] .aw-row-label-action { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.aw-row[data-action-kind="delete"]      .aw-row-label-action { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.aw-row[data-action-kind="merge"]       .aw-row-label-action { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }
.aw-row[data-action-kind="inbox"]       .aw-row-label-action { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
/* Iris brief-14 §B.3 — CHECK pill in walk-through detail card header. */
.aw-row[data-action-kind="check-folder"] .aw-row-label-action { background: var(--action-pill-check-bg); color: var(--action-pill-check-fg); }
/* Label-grid rows — column-A badge + column-B value. Mirrors .sa-row
   typography family so walk-through reads as one IA pattern with the
   Inspector list-view.
   Jeremy round 8: label column reduced 88px → 56px so the value column
   lines up flush-left under the RESULT eyebrow below. Single font
   family for ALL values (system sans, 13/20) so the rows don't read as
   "clashing fonts" — only paths use monospace, and only the input has
   a visible chrome. */
.aw-rows {
  display: flex; flex-direction: column; gap: 8px;
}
.aw-row {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 12px;
  align-items: start;
  min-width: 0;
}
.aw-row-label {
  /* Jeremy round 11: labels RIGHT-aligned in column A (was left).
     RESULT eyebrow below mirrors the right-align so the column reads
     as one consistent edge. Font metric (700 11px/20px uppercase)
     unchanged. */
  font: 700 11px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  text-align: right;
  justify-self: end;
  min-width: 0;
  white-space: nowrap;
}
/* Action tag — the ONE filled pill on the panel. Inherits per-action
   colour from the .aw-row[data-action-kind] rules below. */
.aw-row-label-action {
  background: var(--neutral-soft-bg, var(--surface-2));
  color: var(--neutral-soft-fg, var(--text-faint));
  font-size: 9.5px;
  line-height: 16px;
  padding: 1px 7px;
  border-radius: 3px;
  text-align: center;
  height: 18px;
  margin-top: 2px;
}
.aw-row-value { min-width: 0; padding-top: 0; }
/* Jeremy round 12: same font family + size across every value
   (system sans, 13/20). Only the FROM row's value is bold — the
   proposal's subject. IN value, TO input, MOVE TO, MERGE INTO are
   all REGULAR weight so the bold FROM stands as the one anchor.
   Round-11 made everything bold; round-12 reverts to FROM-only bold. */
.aw-row-text,
.aw-row-mono,
.aw-row-why,
.aw-row-input {
  font: 400 13px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  word-break: break-word;
  color: var(--text);
}
/* FROM value is the only bold thing in the value column. */
.aw-row[data-action-kind] .aw-row-value .aw-row-text { font-weight: 600; }
.aw-row-text-faint { color: var(--text-dim); }
.aw-row-mono {
  /* Same metrics as .aw-row-text — class kept for semantic purpose
     (callers know they're rendering a path) but visually identical. */
  display: inline;
}
.aw-row-mono-inline {
  display: inline; padding: 1px 4px; background: var(--surface-2);
  font: 400 12px/18px ui-monospace, 'SF Mono', Consolas, monospace;
  border-radius: 3px;
  color: var(--text-dim);
}
.aw-row-input {
  /* Negative margin offsets the input's border (1px) + padding (8px) so
     the text inside the input lines up at the same x as text in the
     read-only rows above/below. Width compensates so the input still
     fills the value column. */
  width: calc(100% + 18px);
  margin: 0 -9px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 8px;
  box-sizing: border-box;
  transition: border-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aw-row-input:focus {
  outline: none;
  border-color: var(--accent);
}
.aw-row-why {
  font-weight: 400;
  color: var(--text-dim);
}

/* ── Phase 3A: the renumber group-card section (Iris spec) ──────────────────
   A collapsible read-only disclosure that sits INSIDE the .aw-callout-card,
   directly under .aw-rows. Shows the knock-on sibling renumbers grouped by
   location. ZERO new hex / ZERO new tokens — every value resolves through the
   existing palette (--text-dim, --text, --text-faint, --action-pill-info-fg,
   --row-hover, --accent, --border, --motion-easing). The struck old-number
   reuses the global .otto-diff-was grammar (main.css:1365). */
.aw-renumber-section {
  /* 12px below the WHY row, matching the .aw-rows gap rhythm. */
  margin-top: 12px;
}
/* The collapsed trigger row — the whole row is the click target. Chevron +
   dim prose; the count digit pops via .aw-renum-label strong. */
.aw-renum-trigger {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  /* Full-bleed to the card's inner padding edges (card pads 12/16). Negative
     horizontal margin lets the hover wash reach the card's inner edges. */
  margin: 0 -8px;
  padding: 4px 8px;
  min-height: 28px;
  background: transparent;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  transition: background 160ms var(--motion-easing);
}
.aw-renum-trigger:hover { background: var(--row-hover); }
.aw-renum-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* The chevron reuses .tree-toggle's rotate-on-open mechanics (no new toggle).
   It rotates to 90° (chevron-down) when .open is added on expand. */
.aw-renum-chevron { color: var(--text-dim); }
.aw-renum-label {
  font: 400 13px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
/* The "N folders" digit pops — --text weight 600 (mirrors .aw-counter strong). */
.aw-renum-label strong { color: var(--text); font-weight: 600; }

/* The expandable body — collapsed by default via [hidden]; the reveal is a
   240ms height/opacity transition in the §D motion band. */
.aw-renum-body {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 240ms var(--motion-easing), opacity 240ms var(--motion-easing);
}
.aw-renumber-section[data-expanded="true"] .aw-renum-body {
  /* Generous cap so the reveal animates; the scroll cap (long cascade) caps
     the actual visible height at 280px below. */
  max-height: 1200px;
  opacity: 1;
  margin-top: 8px;
}
/* The [hidden] attribute keeps it out of the a11y tree + collapsed-height when
   closed; on expand JS removes it so this display rule no longer applies. */
.aw-renum-body[hidden] { display: none; }
/* Long cascade (15+) — the body scrolls inside its own box; the trigger, card
   rows, and footer stay fixed (Iris §5). 280px = 35×8 on the 8-pt grid. */
.aw-renumber-section[data-expanded="true"] .aw-renum-body--scroll {
  max-height: 280px;
  overflow-y: auto;
}

/* A location group — eyebrow header + its rename rows. 16px between groups so
   the two read as distinct (Iris §3.2). */
.aw-renum-group + .aw-renum-group { margin-top: 16px; }
/* The eyebrow header reuses the .aw-row-label metric exactly (700 11px/20px
   uppercase, 0.08em, --text-faint) so it reads as the same IA family as the
   MOVE/INTO labels. Per Iris's "simpler" allowance: the whole eyebrow is one
   --text-faint line (parallel structure across the two groups is what matters). */
.aw-renum-eyebrow {
  font: 700 11px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  margin-bottom: 12px;
  /* Eyebrow left edge aligns to the trigger label (one rail down the section).
     Trigger label sits at chevron(14) + gap(8) = 22px from the trigger's text
     start; the trigger's own 8px padding means ~22px of indent here. */
  padding-left: 22px;
}
/* The rename row — old number (struck) → new number (accent) + folder name.
   24px row height (the tree --row-h), tabular-nums so the old|new columns align
   arrow-under-arrow down the list. Rows indent ~16px past the eyebrow. */
.aw-renum-row {
  display: flex; align-items: center;
  min-height: 24px;
  padding-left: 38px;   /* 22px (eyebrow rail) + 16px (heading-with-list indent) */
}
.aw-renum-row + .aw-renum-row { margin-top: 4px; }
/* Old number — the established "was" grammar (.otto-diff-was already carries
   line-through + opacity 0.7 + --text-dim + 12px). Fixed-width right-aligned
   column via tabular-nums so 06.→05. and 08.→07. line up. */
.aw-renum-old {
  font-variant-numeric: tabular-nums;
  min-width: 30px;
  text-align: right;
  flex-shrink: 0;
}
.aw-renum-arrow {
  color: var(--text-faint);
  font-size: 12px;
  margin: 0 8px;
  flex-shrink: 0;
}
/* New number — the move family's own info accent (NOT a fresh colour). */
.aw-renum-new {
  color: var(--action-pill-info-fg);
  font-weight: 600;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  min-width: 30px;
  text-align: right;
  flex-shrink: 0;
}
.aw-renum-name {
  font: 400 13px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text);
  margin-left: 8px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Reduced-motion — the reveal is instant; the content still appears (never
   silent, §D). The chevron snaps with no rotation travel. */
@media (prefers-reduced-motion: reduce) {
  .aw-renum-body { transition: none; }
  .aw-renum-trigger { transition: none; }
  .aw-renum-chevron { transition: none; }
}

/* Decision tag — retained for applied/skipped/failed visual states.
   Sits adjacent to the action tag in the band's top row when present. */
.aw-decision {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.10em;
  padding: 2px 6px; border-radius: 3px; font-weight: 600;
  margin-top: 1px;
}
.aw-decision-applied { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.aw-decision-skipped { background: var(--surface-2); color: var(--text-dim); }
.aw-decision-failed  { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }

/* (Janitorial cleanup batch 49 — Jeremy round 13: dropped 60+ lines of
   dead .aw-line / .aw-loc / .aw-why / .aw-edit / .aw-to-input rules and
   the .aw-field/.aw-label/etc legacy fallback selectors. None were
   matched by any markup after the batch-41 label-grid redesign. If a
   future walk-through entry point needs glyph-prefixed prose lines or
   the underline-only input style, restore from git.) */

/* Footer — three slots: icon cluster · spacer · text-Skip + primary Apply + overflow */
.aw-footer {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  background: var(--surface);
  flex-shrink: 0;
}
.aw-footer-spacer { flex: 1; }
.aw-footer-icons { display: flex; align-items: center; gap: 4px; }
.aw-icon-btn {
  width: 28px; height: 28px; padding: 0;
  background: transparent; border: none; border-radius: 4px;
  color: var(--text-dim); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1), color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aw-icon-btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.aw-icon-btn:disabled { color: var(--text-faint); cursor: not-allowed; opacity: 0.5; }
.aw-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.aw-text-btn {
  background: transparent; border: none;
  padding: 6px 10px; border-radius: 4px;
  font: 400 13px/18px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim); cursor: pointer;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1), color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aw-text-btn:hover { color: var(--text); background: var(--surface-2); }
.aw-text-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* "Apply rest" — actual button chrome (Jeremy round 9: was reading as a
   text link, not a control). Border + neutral background so it sits as
   a secondary button next to the primary Apply, without competing for
   the eye. */
/* "Apply rest" — match Apply's height + padding + font metrics exactly
   so the two buttons sit on the same baseline. Only differ in colour
   (neutral border + surface bg vs filled accent), so visual weight
   tells you which is primary. (Jeremy round 10: "is apply rest button
   same height as Apply" — making them identical resolves the question.) */
.aw-text-btn-subtle {
  height: 32px;
  padding: 0 14px;
  font: 600 13px/30px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  display: inline-flex; align-items: center;
  cursor: pointer;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1), color 200ms cubic-bezier(0.4, 0, 0.2, 1), border-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
  box-sizing: border-box;
}
.aw-text-btn-subtle:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-strong, var(--border)); }
.aw-text-btn-subtle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Iris Addendum A1 §A.4 (Batch 14H) — Ignore button in walk-through
   detail-card footer. REPLACES the brief-14 §C.3 ghost-text treatment.
   Now: danger-soft rectangle, 32px height to match .aw-primary +
   .aw-text-btn-subtle so the rightmost triplet [Apply rest] [Apply]
   [Ignore] reads as a coherent decision row. Tone (danger-soft) is
   the differentiation axis, not chrome shape. */
.aw-row-ignore {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  background: var(--action-pill-danger-bg);
  color: var(--action-pill-danger-fg);
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  font: 600 13px/30px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  box-sizing: border-box;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1),
              color      200ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aw-row-ignore:hover,
.aw-row-ignore:focus-visible {
  background: var(--btn-danger-bg);
  color: var(--on-solid);
  border-color: var(--btn-danger-bg);
}
.aw-row-ignore:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* WCAG fix mirror for dark mode (same reasoning as .aic-row-ignore). */
[data-theme="dark"] .aw-row-ignore:hover,
[data-theme="dark"] .aw-row-ignore:focus-visible {
  background: var(--btn-danger-hover);
  color: var(--on-solid);
  border-color: var(--btn-danger-hover);
}

/* ── Iris A10 §B (Batch 14T) — walk-through footer triplet: cap + centre ──
   Hosts [Apply rest] [Apply] [Ignore] (active rows) or a single [Restore]
   (ghosted rows). flex:1 1 0 on each child (rule below) still forces equal
   division of the wrapper width regardless of label length. A10 tightens
   the cluster: max-width 320px so each button ≈ ~98px (snug but legible),
   margin: 0 auto so the cluster sits CENTRED in the footer rather than
   right-jammed, flex: 0 1 auto so the cluster itself stops greedily
   growing. The A9 child rule (justify-content:center + text-align:center
   + 8/8 padding below) is UNTOUCHED — within-cluster equality preserved.
   ── Iris Addendum A11 (Batch 14U): `.aw-footer-triplet` is now aliased
   to `.aw-footer-actions` (both selectors below). After P2-5 (Apply rest
   removed) and P2-6 (Keep removed), the container hosts 2 children on
   every footer — [Delete][Ignore] on CHECK rows, [Apply][Ignore] (etc.)
   on normal rows. Triplet equality math (flex on children) holds. */
.aw-footer-triplet,
.aw-footer-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  /* Jeremy 2026-05-27: REVERT A10's centre — anchor right as before. The
     narrower max-width (320px below) still gives breathing room; A10's
     centring was an unrequested change. */
  margin-left: auto;
  /* Iris P2-3 (2026-05-30): hug content instead of stretching to 320px.
     Every footer is now 2-button (Apply-rest + Keep removed in P2-5/P2-6),
     so the old `flex: 1 1 auto` made all footers fill the 320px cluster and
     look oversized. Now `flex: 0 0 auto` wraps the buttons; max-width:320px
     stays as a safety ceiling for any future 3-button case; margin-left:auto
     keeps the right anchor. */
  flex: 0 0 auto;
  min-width: 0;            /* allows the triplet to compress on narrow viewports */
  max-width: 320px;        /* A10: was 480 — narrower buttons + breathing space */
}
.aw-footer-triplet > .aw-text-btn,
.aw-footer-triplet > .aw-text-btn-subtle,
.aw-footer-triplet > .aw-primary,
.aw-footer-triplet > .aw-row-ignore,
.aw-footer-triplet > .aw-row-restore,
.aw-footer-actions > .aw-text-btn,
.aw-footer-actions > .aw-text-btn-subtle,
.aw-footer-actions > .aw-primary,
.aw-footer-actions > .aw-row-ignore,
.aw-footer-actions > .aw-row-restore {
  flex: 0 0 auto;
  width: 104px;            /* Iris P2-3: fixed button width so all footers read one size (was flex:1 1 0 equal-fill → 155px in 2-button footers) */
  min-width: 0;            /* labels truncate at extreme narrow widths rather than overflow */
  /* Iris A9 §B (Batch 14S): centre the label in every equal-width slot.
     .aw-text-btn-subtle + .aw-primary inherit flex-start by default which
     reads as left-aligned in their stretched flex:1 1 0 slot; .aw-row-ignore
     already had justify-content:center so it was the only one centring
     correctly. Tighten horizontal padding from the per-button 14px down to
     8px so labels don't push against the slot edges and break the equal-
     visual-width perception. */
  justify-content: center;
  text-align: center;
  padding-left: 8px;
  padding-right: 8px;
}

/* Theo ITEM B (2026-06-25, Jeremy "replace the apply button with the undo
   button once apply is pressed"): post-apply footer = [Applied ✓ (left cue)]
   … [Undo (Apply slot)][Next → (Ignore slot)] (the right-anchored cluster).
   The post-apply footer now reuses the GENERIC .aw-footer-actions triplet
   (right-anchored, 104px equal-width buttons) so its sizing is IDENTICAL to
   the pre-apply [Apply][Ignore] footer — no width override, no reflow. The
   muted "Applied ✓" cue is a plain sibling that sits at the far LEFT (the
   triplet's margin-left:auto pushes the buttons hard right), so the cue never
   pushes the buttons around. Pure layout — no new tokens, no colour. */
.aw-applied-cue {
  flex: 0 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Iris A8 §D (Batch 14R): restore-mode singleton override. The generic
   flex:1 1 0 rule above blew the lone Restore button up to the triplet's
   full 480px max-width. Cap to 160px (1/3 of triplet width) and center.
   Belt-and-braces — both :has() (modern Chromium/Firefox/Safari ship it)
   and the marker class .aw-footer-triplet--singleton (added in app.js
   restore-mode render) so older browsers still get the cap. */
.aw-footer-triplet:has(> .aw-row-restore:only-child) > .aw-row-restore,
.aw-footer-triplet--singleton > .aw-row-restore {
  flex: 0 0 auto;
  width: 160px;
  margin: 0 auto;
}

/* Restore button on walk-through restore-mode footer. Neutral surface +
   border, accent-on-hover (mirrors A3 §B .aic-row-restore tone scaled to
   the 32px aw family). No icon — text-only is the new commit family
   (A5 §A.1 icon removal). */
.aw-row-restore {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  font: 600 13px/30px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  box-sizing: border-box;
  transition: color        var(--motion-duration) var(--motion-easing),
              border-color var(--motion-duration) var(--motion-easing);
}
.aw-row-restore:hover,
.aw-row-restore:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
}
.aw-row-restore:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Info strip above the proposal detail card in restore-mode. Quiet
   --text-dim copy, --border underline. 12/16 per A5.1 §D. */
.aw-row-restore-info {
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
}

/* "Ignored" badge in the walk-through header next to the counter. */
.aw-ignored-badge {
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 3px;
  font: 600 11px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin-left: 8px;
}

/* Iris walk-presentation §1: Preview/Live mode badge — the pocket echo of
   the Advanced-settings .settings-mode-card. Preview = calm --accent;
   Live = restrained --btn-danger-bg on --danger-soft-bg. Both themes. */
.aw-mode-badge {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  padding: 2px 8px 2px 6px;
  border: 1px solid var(--border); border-radius: 4px;
  font: 600 11px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  letter-spacing: 0.02em; user-select: none;
}
.aw-mode-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.aw-mode-badge[data-mode="preview"] { background: var(--surface-2); border-color: var(--border); color: var(--accent); }
.aw-mode-badge[data-mode="preview"] .aw-mode-dot { background: var(--accent); }
.aw-mode-badge[data-mode="live"] { background: var(--danger-soft-bg); border-color: var(--btn-danger-bg); color: var(--btn-danger-bg); }
.aw-mode-badge[data-mode="live"] .aw-mode-dot { background: var(--btn-danger-bg); }

/* ── Dupes-report walkthrough modal — adopts the audit walkthrough's
   label-grid family (Jeremy backlog #6, batch 51) so both step-through
   surfaces feel like one app. Reuses .aw-row / .aw-row-label /
   .aw-row-value / .aw-row-text / .aw-row-why / .aw-counter-sub /
   .aw-text-btn / .aw-text-btn-subtle / .aw-primary verbatim — only the
   wt-specific layout (modal shell, per-file mini-cards) is new. */
.wt-modal { display: none; }
.wt-modal[style*="display: block"], .wt-modal[style*="display:block"] { display: flex; }
.wt-modal-box {
  max-width: 640px;
  width: calc(100% - 64px);
  display: flex; flex-direction: column;
  padding: 0;
  max-height: 80vh;
}
.wt-header {
  display: flex; align-items: center; gap: 12px;
  padding: 0 20px;
  height: 44px; flex-shrink: 0;
  border-bottom: 1px solid var(--border);
}
.wt-title {
  font: 600 14px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text);
  margin: 0;
}
.wt-counter {
  flex: 1;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.wt-counter strong { font-weight: 600; color: var(--text); }
.wt-stop {
  width: 24px; height: 24px; padding: 0;
  background: transparent; border: none; border-radius: 4px;
  color: var(--text-faint); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.wt-stop:hover { background: var(--surface-2); color: var(--text); }
.wt-meta {
  padding: 20px 24px;
  flex: 1;
  overflow-y: auto;
}
.wt-footer {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  background: var(--surface);
  flex-shrink: 0;
}
.wt-footer-spacer { flex: 1; }

/* Per-file mini-card inside the walkthrough body. Uses .aw-row data-action-
   kind = "delete" or "merge" so the KEEP/DELETE label inherits the existing
   destructive vs neutral palette. */
.wt-files {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.wt-file-row {
  /* override default .aw-row align so multi-line value blocks read top-aligned */
  align-items: start;
}
.wt-file-row[data-action-kind="merge"] .aw-row-label-action {
  /* Iris brief-12 §4: re-pointed to --action-pill-merge-* tokens for
     consistency with the list-row + detail-card pill. Dark-mode override
     deleted — tokens carry their own dark-mode values. */
  background: var(--action-pill-merge-bg); color: var(--action-pill-merge-fg);
}
.wt-file-value { display: flex; flex-direction: column; gap: 3px; }
.wt-file-name {
  font: 600 13px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text);
  word-break: break-word;
}
.wt-file-path {
  font: 400 12px/18px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  word-break: break-all;
}
.wt-file-meta {
  font: 400 11px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-faint);
}
.wt-file-reason { margin-top: 4px; }

.aw-primary {
  height: 32px; padding: 0 14px;
  background: var(--accent); color: var(--cck-accent-on);
  border: none; border-radius: 6px;
  font: 600 13px/32px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aw-primary:hover:not(:disabled) { background: var(--accent-hover); }
.aw-primary:disabled { opacity: 0.45; cursor: not-allowed; }
.aw-primary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Walk-through: per-action animations ────────────────────────────
   All animations target rows inside #aw-preview. Curve and duration are
   normalised so the visual rhythm is consistent across action types.
   Reduced-motion users get a single 120ms cross-fade on the preview as a
   whole — no transforms, no chained keyframes. */
@keyframes aw-fade-in { from { opacity: 0; } to { opacity: 1; } }
.aw-anim-reduced { animation: aw-fade-in 120ms cubic-bezier(0.4, 0, 0.2, 1) both; }

/* RENAME — the target row's NEW name slides in from below (aw-rename-new-in).
   The snippet's "↳ was X" origin sub-line was removed (Iris fly-refinements §A,
   2026-06-25): the left pane shows the source unghosted at its origin, so the
   echo was redundant. aw-rename-old-settle is KEPT — it still drives the live-tree
   .otto-rename-was strike-settle in the otto-window rename morph (main.css ~1602,
   1613), which is a separate surface and unaffected by §A. */
@keyframes aw-rename-old-settle {
  0%   { opacity: 0.4; }
  100% { opacity: 1; }
}
@keyframes aw-rename-new-in {
  0%   { opacity: 0; transform: translateY(8px); }
  60%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 1; transform: translateY(0); }
}
/* Iris merge/rename-new-grammar §2 R2 (2026-06-25): the rename NAME-MORPH. The
   old on-mount .aw-anim-rename .aw-prev-name rule was RETIRED — rename no longer
   plays a keyframe on mount or replay via the className map. Instead JS toggles
   .aw-prev-name-morph onto the anchor's .aw-prev-name on apply/replay only,
   reusing the kept aw-rename-new-in slide-in (no new keyframe). */
.aw-prev-name-morph {
  animation: aw-rename-new-in 280ms cubic-bezier(0.4, 0, 0.2, 1) both;
}
@media (prefers-reduced-motion: reduce) {
  .aw-prev-name-morph { animation: none; }
}

/* Iris stepthrough-otto-polish Piece 2a (2026-06-25): the landing pulse on the
   snippet anchor when the accept-flight clone touches down. One-shot 140ms
   accent-wash flash → transparent, applied to [data-anchor="target"] by JS on
   the flyer's `finished`. --otto-dest-wash is defined in both themes. */
@keyframes aw-prev-land {
  0%   { background: var(--otto-dest-wash); }
  100% { background: transparent; }
}
.aw-prev-row-landing {
  animation: aw-prev-land 140ms cubic-bezier(0.4, 0, 0.2, 1) both;
}
@media (prefers-reduced-motion: reduce) {
  .aw-prev-row-landing { animation: none; background: transparent; }
}

/* Iris fly-refinements EXTENSION B (2026-06-25): pre-apply "proposing" pulse.
   The destination anchor row in #aw-preview breathes on/off while the proposal
   is shown but not yet applied — "tentatively here, about to move." Stops the
   instant Apply is hit (JS removes the class; the flyer + landing wash take
   over). Opacity-only + a barely-there scale so it reads as a soft breath, not
   a blink. Subtle wash underlay so the slot reads as a live landing zone. */
@keyframes aw-prev-proposing {
  0%   { opacity: 1;    transform: scale(1); }
  50%  { opacity: 0.55; transform: scale(0.992); }
  100% { opacity: 1;    transform: scale(1); }
}
.aw-prev-row-proposing {
  animation: aw-prev-proposing 1200ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
  background: color-mix(in srgb, var(--otto-dest-wash) 60%, transparent);
  border-radius: 3px;
  transform-origin: left center;   /* breathe from the name, not the row centre */
  will-change: opacity, transform;
}
@media (prefers-reduced-motion: reduce) {
  /* No blink under reduce — sit statically at the dimmed end so it still reads
     as "tentative," matching the 0.55 trough. */
  .aw-prev-row-proposing { animation: none; opacity: 0.7; }
}

/* Iris merge/rename-new-grammar §1 M2 (2026-06-25): the MERGE pre-apply pulse on
   the INCOMING (source) file rows — they breathe the accent pulse to read as
   "these are about to fly into the folder," while the target folder anchor sits
   still (it's the destination, not a flier). Dedicated marker
   .aw-prev-row-proposing-incoming so the anchor's .aw-prev-row-proposing strip
   logic doesn't govern N file rows. Reuses @keyframes aw-prev-proposing.
   Collision rows (.aw-prev-row-skip) never get this marker (JS :not gate). */
.aw-prev-row-incoming.aw-prev-row-proposing-incoming {
  animation: aw-prev-proposing 1200ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
  background: color-mix(in srgb, var(--otto-dest-wash) 60%, transparent);
  border-radius: 3px;
  transform-origin: left center;
  will-change: opacity, transform;
}
@media (prefers-reduced-motion: reduce) {
  .aw-prev-row-incoming.aw-prev-row-proposing-incoming { animation: none; opacity: 0.7; }
}

/* Iris EXTENSION 3 §D1 (2026-06-25): the DELETE pre-apply pulse. Same breath
   as the move/rename+move proposing pulse (reuses @keyframes aw-prev-proposing)
   but in the danger colour — "tentatively here, about to be removed." Replaces
   the old aw-delete-mark tint. The .aw-prev-row-strike strike-through STAYS and
   composes with this. No new tokens (--danger-soft-bg / --btn-danger-bg). */
.aw-prev-row-removing {
  animation: aw-prev-proposing 1200ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
  background: color-mix(in srgb, var(--danger-soft-bg) 70%, transparent);
  border-left: 3px solid var(--btn-danger-bg);
  padding-left: 6px;
  border-radius: 3px;
  transform-origin: left center;
  will-change: opacity, transform;
}
@media (prefers-reduced-motion: reduce) {
  .aw-prev-row-removing {
    animation: none;
    opacity: 0.7;
    background: color-mix(in srgb, var(--danger-soft-bg) 70%, transparent);
    border-left: 3px solid var(--btn-danger-bg);
    padding-left: 6px;
  }
}

/* Iris EXTENSION 3 §D2 (2026-06-25): the DELETE dissolve + particle burst. On
   Apply the red-pulsing row dissolves (opacity → 0, soft blur + scale-down) and
   8 danger dots fan out on an arc. Reduced-motion swaps the dissolve for a flat
   fade and suppresses the particle layer. Particles are pure DOM+CSS injected by
   _injectDissolveParticles → no WAAPI / flight-layer leak surface. */
@keyframes aw-prev-dissolve {
  0%   { opacity: 1;    transform: scale(1);    filter: blur(0); }
  60%  { opacity: 0.35; transform: scale(0.96); filter: blur(1.5px); }
  100% { opacity: 0;    transform: scale(0.90); filter: blur(3px); }
}
.aw-prev-row-dissolving {
  /* Base 420→1200ms (Jeremy 2026-06-25 — "slow it down a lot more maybe 3 times
     slower"). Scaled by --otto-speed like the fly so the speed slider drives it. */
  animation: aw-prev-dissolve calc(1200ms / var(--otto-speed, 1)) cubic-bezier(0.4,0,1,1) forwards;
  transform-origin: left center;
  pointer-events: none;
  will-change: opacity, transform, filter;
}
.aw-dissolve-particles {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
  z-index: 2;
}
.aw-dissolve-dot {
  position: absolute;
  left: var(--ox,12px);
  top: 50%;
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--btn-danger-bg);
  opacity: 0;
  will-change: transform, opacity;
  /* Base 420→1200ms (Jeremy 2026-06-25), --otto-speed-scaled to track the row
     dissolve + the slider. --ds stagger is left unscaled (small, additive). */
  animation: aw-dissolve-dot-fly calc(1200ms / var(--otto-speed, 1)) cubic-bezier(0.2,0,0.4,1) var(--ds,0ms) forwards;
}
@keyframes aw-dissolve-dot-fly {
  0%   { opacity: 0;   transform: translate(0,0) scale(0.4); }
  20%  { opacity: 0.9; transform: translate(calc(var(--dx)*0.3), calc(var(--dy)*0.3)) scale(1); }
  100% { opacity: 0;   transform: translate(var(--dx), var(--dy)) scale(0.3); }
}
@media (prefers-reduced-motion: reduce) {
  .aw-prev-row-dissolving {
    animation: aw-prev-fade-out 200ms cubic-bezier(0.4,0,0.2,1) forwards;
    filter: none;
  }
  .aw-dissolve-particles { display: none; }
}
@keyframes aw-prev-fade-out { from { opacity: 1; } to { opacity: 0; } }

/* Theo FIX B (2026-06-25, Jeremy "when there is a gap left from moving files or
   folders, the files underneath the gap shunt up smoothly into place closing the
   gap"). A vacated row (MOVE source / MERGE source folder + children) fades to
   opacity 0 but HELD its height — a blank gap stayed. .aw-prev-row-gapclose is
   added AFTER the fade (JS: _walkGapCloseAfterFade on animationend) and collapses
   the row's box to 0 — height, min-height, padding, margin, border — over ~300ms
   on the app's --motion-easing, so every row beneath reflows up smoothly. The row
   already has overflow:hidden, so the fading content is clipped as the box shrinks
   (no flicker). max-height backstops the fixed `height: var(--row-h)`; setting
   `height:0` too pins it for the rare row without a fixed height. The class is
   forwards-stable (the values stick at 0) until the next #left-tree rebuild on
   undo/replay restores the row at full height. Works in both themes (no colour). */
.tree-row.aw-prev-row-gapclose {
  height: 0 !important;
  min-height: 0 !important;
  max-height: 0;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  border-top-width: 0 !important;
  border-bottom-width: 0 !important;
  overflow: hidden;
  transition:
    height        300ms var(--motion-easing),
    min-height    300ms var(--motion-easing),
    max-height    300ms var(--motion-easing),
    padding-top   300ms var(--motion-easing),
    padding-bottom 300ms var(--motion-easing),
    margin-top    300ms var(--motion-easing),
    margin-bottom 300ms var(--motion-easing),
    border-top-width    300ms var(--motion-easing),
    border-bottom-width 300ms var(--motion-easing);
}
@media (prefers-reduced-motion: reduce) {
  /* Reduced motion → collapse instantly: no gap, no animation (still no flicker
     because overflow:hidden clips, and the fade already ran flat under reduce). */
  .tree-row.aw-prev-row-gapclose { transition: none; }
}

/* FIX 4 (2026-06-25): the DELETE UNDO re-materialize — the visual REVERSE of the
   dissolve (@keyframes aw-prev-dissolve above). On undo the restored folder fades
   + scales back IN, so undo plays motion instead of silently re-rendering. Same
   --otto-speed scaling as the dissolve so the slider drives both; 900ms base to
   match the move/delete hold beat. Reduced motion → instant, no animation. */
@keyframes aw-prev-materialize {
  0%   { opacity: 0; transform: scale(0.94); }
  100% { opacity: 1; transform: scale(1); }
}
.aw-prev-row-materializing {
  animation: aw-prev-materialize calc(900ms / var(--otto-speed, 1)) cubic-bezier(0, 0, 0.2, 1) both;
  transform-origin: left center;
  will-change: opacity, transform;
}
@media (prefers-reduced-motion: reduce) {
  .aw-prev-row-materializing { animation: none; opacity: 1; transform: none; }
}

/* MOVE — the snippet row-glide entrance was superseded by the B-pulse + C-fly
   grammar (Iris EXTENSION 3, 2026-06-25): the fly IS the entrance, so the old
   .aw-anim-move .aw-prev-row-anchor glide-in was a double-entrance and is
   dropped. @keyframes aw-move-glide-in is KEPT — it is still live on a SEPARATE
   surface (the otto-window rename-move morph, main.css:1626). */
@keyframes aw-move-glide-in {
  0%   { opacity: 0; transform: translateX(-40px); }
  60%  { opacity: 1; transform: translateX(2px); }
  100% { opacity: 1; transform: translateX(0); }
}
/* Connector "marches" briefly in the direction of motion */
@keyframes aw-connector-march {
  0%   { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: -14; }
}
.aw-anim-move + #aw-connector .aw-connector-line,
.aw-anim-rename-move + #aw-connector .aw-connector-line { /* selector won't actually match (connector is global) — see JS for class plumbing if we want this */ }

/* RENAME + MOVE — the row-GLIDE entrance was dropped (Iris EXTENSION 3,
   2026-06-25): the C-fly is now the entrance for rename+move too, so the
   .aw-anim-rename-move .aw-prev-row-anchor glide-in was a double-entrance.
   The NAME fade-swap rule below is KEPT per the spec (only the row-glide
   drops); it is inert now that the dispatch no longer adds aw-anim-rename-move,
   but it harms nothing and documents the name-morph intent. */
.aw-anim-rename-move .aw-prev-row-anchor .aw-prev-name {
  animation: aw-rename-new-in 240ms cubic-bezier(0.4, 0, 0.2, 1) 200ms both;
}

/* DELETE — superseded by the D1 red proposing-pulse (.aw-prev-row-removing)
   + D2 dissolve grammar (Iris EXTENSION 3, 2026-06-25). The old aw-delete-mark
   tint keyframe + its .aw-anim-delete .aw-prev-row-anchor rule were dropped
   here; the strikethrough (.aw-prev-row-strike) still composes with the new
   red pulse. */

/* MERGE — superseded by the new pulse→fly→source-dissolve grammar (Iris
   merge/rename-new-grammar §1, 2026-06-25). The old on-mount cascade
   (.aw-anim-merge anchor box-shadow pulse + .aw-prev-tail stagger-in) and its
   walk-only @keyframes aw-merge-dest-pulse were RETIRED — merge no longer plays
   a keyframe on mount or replay. The incoming file rows now pulse via
   .aw-prev-row-proposing-incoming (above), fly into the folder anchor
   (_walkPlayAcceptFlight 'merge'), then the source folder dissolves in #left-tree
   (_walkPlayMergeSourceDissolve, reusing .aw-prev-row-dissolving). @keyframes
   aw-merge-incoming is KEPT — it still drives the live-tree fan-out landing
   (main.css ~1595, mover.js ~1000), a separate surface. */
@keyframes aw-merge-incoming {
  0%   { opacity: 0; transform: translateX(-24px); }
  100% { opacity: 1; transform: translateX(0); }
}

/* ── Phase 4: the apply-time renumber DIGIT-RIPPLE (Iris spec §7.2/§7.3/§7.5) ──
   When a renumber GROUP applies (executeGroup), each renumbered sibling row's
   LEADING DIGIT cross-fades old→new (e.g. "06." → "05.") as the row settles into
   its new place — staggered top→bottom so the renumber RIPPLES rather than
   flickers. The gap-close (source, "closing the gap") + make-room (dest) reflow
   ride the EXISTING grammar (.aw-prev-row-gapclose / arrive ring-flash); this
   adds ONLY the number-text cross-fade on a transient overlay span the JS injects
   over the leading digit (the rest of the row is unchanged — Iris §7.2: "we add
   only a number-text cross-fade on the digit span"). The new value wears the
   move family's own --action-pill-info-fg (NOT a fresh accent — the renumber IS
   part of the move). ZERO new tokens / ZERO new hex — every value resolves
   through the shipped palette (--action-pill-info-fg, --text-dim, --motion-easing).

   The overlay is two stacked spans (old fading out, new fading in) absolutely
   positioned over the row's number so the row text doesn't reflow under it. The
   per-row stagger DELAY is set in JS (the same per-row animationDelay pattern the
   merge fan-out uses, mover.js ~1012) so the cascade reads as a sequence-repair.
   ~200ms cross-fade (Iris §7.2 ≤200ms). */
@keyframes aw-renum-digit-out {
  0%   { opacity: 0.7; }
  100% { opacity: 0; }
}
@keyframes aw-renum-digit-in {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
.aw-renum-digit-ripple {
  position: relative;
}
.aw-renum-digit-overlay {
  position: absolute;
  left: 0; top: 0;
  display: inline-block;
  font-variant-numeric: tabular-nums;   /* digits hold their column while swapping */
  pointer-events: none;
  white-space: pre;                      /* preserve the leading U+00A0 spacing */
}
.aw-renum-digit-overlay .aw-renum-digit-old {
  position: absolute; left: 0; top: 0;
  color: var(--text-dim);
  /* JS sets animation-delay inline per-row (the merge fan-out stagger pattern). */
  animation: aw-renum-digit-out 200ms var(--motion-easing) both;
}
.aw-renum-digit-overlay .aw-renum-digit-new {
  color: var(--action-pill-info-fg);     /* the move's info accent on the NEW value (Iris) */
  animation: aw-renum-digit-in 200ms var(--motion-easing) both;
}
@media (prefers-reduced-motion: reduce) {
  /* Reduced motion → the digit swaps INSTANTLY: no stagger, no ripple. The new
     value is already shown (the row text under the overlay already carries the
     new number from renderPane), so the overlay just vanishes immediately — the
     state is fully resolved, never silent (§D). */
  .aw-renum-digit-overlay .aw-renum-digit-old,
  .aw-renum-digit-overlay .aw-renum-digit-new { animation: none; }
  .aw-renum-digit-overlay .aw-renum-digit-old { opacity: 0; }
  .aw-renum-digit-overlay .aw-renum-digit-new { opacity: 1; }
}

/* ── Walk-through: dotted rectangle on the source row ──────────────
   1px dashed neutral outline, no fill, no pulse. The connector terminating
   at it is the wayfinding cue. */
.tree-row.aw-source-row {
  position: relative;
  z-index: 1;
}
.tree-row.aw-source-row::after {
  content: '';
  position: absolute;
  /* Jeremy 2026-06-27: the box HUGS the file name, not the whole row. Left inset
     2px; the right edge is driven by --aw-source-box-w (set in JS = distance from
     row-left to just past the .name-text). Falls back to full-row until the
     connector first measures. */
  top: 2px; bottom: 2px; left: 2px;
  width: var(--aw-source-box-w, calc(100% - 4px));
  /* Iris walk-presentation §4: box matches the current action's colour
     (published as --aw-action-color on body in _renderWalkProposalPanel). */
  border: 1px dashed var(--aw-action-color, var(--connector-stroke));
  border-radius: 3px;
  pointer-events: none;
}

/* Iris walk-presentation §3: non-ghosted current item. While walking, dim the
   left tree to 0.45 (the old Otto-filing dim, muscle-memory parity) EXCEPT the
   current source row, which stays full strength. Only #left-tree — #right-tree
   is the Mode-A dest tree and must not dim. Opacity-only (no position change). */
body.aw-walking #left-tree .tree-row:not(.aw-source-row) { opacity: 0.45; transition: opacity 160ms var(--motion-easing); }
body.aw-walking #left-tree .tree-row.aw-source-row { opacity: 1; }

/* ── Walk-through: cross-pane connector overlay ────────────────────
   Single fixed SVG layered above panes (but below modals). 1px dotted
   stroke, 3px square anchors, neutral colour. 160ms opacity fade on
   change. No animation beyond fade. */
#aw-connector {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 50;
  opacity: 0;
  transition: opacity 160ms cubic-bezier(0.4, 0, 0.2, 1);
}
#aw-connector.aw-connector-visible { opacity: 1; }
.aw-connector-line {
  fill: none;
  /* Iris walk-presentation §4: connector matches the current action's colour. */
  stroke: var(--aw-action-color, var(--connector-stroke));
  stroke-width: 1.25;
  stroke-dasharray: 3 4;
  stroke-linecap: round;
}
/* Single circular terminal at the preview end — small filled dot that
   reads as a deliberate landing point. */
.aw-connector-anchor-circle {
  /* Iris walk-presentation §4: terminal dot matches the current action's colour. */
  fill: var(--aw-action-color, var(--connector-stroke));
  stroke: none;
}
/* Reveal direction: LEFT → RIGHT, so the line appears to flow from the
   source folder into the preview (the source is upstream, the preview is
   downstream — the eye follows the action). */
@keyframes aw-connector-draw {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
#aw-connector.aw-connector-visible .aw-connector-line {
  animation: aw-connector-draw 320ms cubic-bezier(0.4, 0, 0.2, 1) both;
}
#aw-connector.aw-connector-visible .aw-connector-anchor-circle {
  opacity: 0;
  animation: aw-anchor-pop 200ms cubic-bezier(0.4, 0, 0.2, 1) 280ms forwards;
  transform-origin: center;
  transform-box: fill-box;
}
@keyframes aw-anchor-pop {
  from { opacity: 0; transform: scale(0.4); }
  to   { opacity: 1; transform: scale(1); }
}
/* When either end is scrolled out of its pane, fade that end so the line
   doesn't appear to terminate in mid-air mid-screen. */
#aw-connector.aw-connector-fade-source   .aw-connector-line { mask-image: linear-gradient(to right, black 0%, black 80%, transparent 100%); }
#aw-connector.aw-connector-fade-preview  .aw-connector-line { mask-image: linear-gradient(to left,  black 0%, black 80%, transparent 100%); }

/* §C OTTO DUAL-PANE CONNECTOR — the from(left)→to(right) bridge across the gutter.
   Only .otto-connector-line carries the arrowhead, so the walk-through connector's
   terminal stays a plain dot. The line itself stays neutral dotted (reads as a
   path); its HEAD is accent (reads as the destination). */
.otto-connector-line { marker-end: url(#otto-arrowhead); }
/* The marching dotted base — subtle, continuous, low energy; loops AFTER the
   one-shot draw lands so the from→to relationship is always animating. */
@keyframes otto-connector-march { to { stroke-dashoffset: -28; } }
#app[data-otto-dual="1"] #aw-connector.aw-connector-visible .otto-connector-line {
  animation:
    aw-connector-draw 320ms cubic-bezier(0.4, 0, 0.2, 1) both,
    otto-connector-march 1100ms linear 320ms infinite;
}
/* The bright pulse — a short accent dash riding the line's full length,
   source→dest, looping. pathLength="1000" makes the -1000 offset exactly one
   length regardless of real px. */
.otto-connector-pulse {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 18 9999;
  filter: drop-shadow(0 0 3px var(--otto-dest-halo));
}
@keyframes otto-pulse-run {
  from { stroke-dashoffset: 0; }      /* lit segment at the SOURCE end */
  to   { stroke-dashoffset: -1000; }  /* travels to the DEST end, then loops */
}
#app[data-otto-dual="1"] #aw-connector.aw-connector-visible .otto-connector-pulse {
  animation: otto-pulse-run 1400ms cubic-bezier(0.4, 0, 0.2, 1) 320ms infinite;
}
/* Reduced motion: drop both loops, keep the one-shot draw + the static arrowhead. */
@media (prefers-reduced-motion: reduce) {
  #app[data-otto-dual="1"] #aw-connector.aw-connector-visible .otto-connector-line {
    animation: aw-connector-draw 320ms cubic-bezier(0.4, 0, 0.2, 1) both;
  }
  #app[data-otto-dual="1"] #aw-connector.aw-connector-visible .otto-connector-pulse {
    animation: none;
    opacity: 0;
  }
}

/* ════════════════════════════════════════════════════════════════════
   OTTO IN-TREE FILING (Iris otto-intree-spec §2/§3) — Batch 1 static view
   Three glowing things in the REAL #left-tree: amber SOURCE (the problem),
   accent DESTINATION (the answer), and the anchored callout under the source.
   All scoped under #app[data-otto-filing="1"] so the normal tree is untouched.
   ════════════════════════════════════════════════════════════════════ */

/* §2 SOURCE — amber wash + 3px inset bar + dotted-rect ::after + bold name. */
.tree-row.otto-src {
  position: relative;
  z-index: 2;
  box-shadow: inset 3px 0 0 0 var(--warn);   /* keep amber bar on the ROW */
}
.tree-row.otto-src .col-name {
  background: var(--otto-src-wash);
  position: relative;
}
.tree-row.otto-src .col-name::after {
  content: '';
  position: absolute;
  inset: 1px 0 1px 1px;        /* T R B L — flush to the divider on the RIGHT (0) */
  border: 1px dashed var(--warn);
  border-radius: 4px;
  pointer-events: none;
}
.tree-row.otto-src .col-name,
.tree-row.otto-src .name-text { font-weight: 600; color: var(--text); }

/* §2 DESTINATION — accent wash + 3px bar + 1px inset ring + bold accent name
   + icon halo. We never recolour makeFolderSvg; the halo is a drop-shadow. */
.tree-row.otto-dest {
  position: relative;
  z-index: 2;
  box-shadow: inset 3px 0 0 0 var(--accent);   /* keep accent bar on the ROW */
}
.tree-row.otto-dest .col-name {
  background: var(--otto-dest-wash);
  position: relative;
}
.tree-row.otto-dest .col-name::after {
  content: '';
  position: absolute;
  inset: 1px 0 1px 1px;
  border: 1px solid var(--accent);   /* dest = solid (answer); src = dashed (problem) */
  border-radius: 4px;
  pointer-events: none;
}
.tree-row.otto-dest .col-name,
.tree-row.otto-dest .name-text { font-weight: 600; color: var(--accent); }
.tree-row.otto-dest .col-icon { filter: drop-shadow(0 0 3px var(--otto-dest-halo)); }

/* §B ZOOM-emphasis — after the right-pane smooth-slide settles, a single brief
   scale (≤1.04) + halo bloom on the dest folder row says "here". transform-origin
   left-center so the row grows toward its label, not off-screen; z-index lift so
   the scale doesn't clip under the next row. Applied via a transient class, removed
   on animationend so it re-fires on the next step. Reduced motion: JS skips the
   class (the static accent ring already marks the dest); the @media below is a
   defensive no-op floor. */
@keyframes otto-dest-zoom {
  0%   { transform: scale(1);     box-shadow: inset 3px 0 0 0 var(--accent), 0 0 0 0 var(--otto-dest-halo); }
  55%  { transform: scale(1.035); box-shadow: inset 3px 0 0 0 var(--accent), 0 0 0 7px var(--otto-dest-halo); }
  100% { transform: scale(1);     box-shadow: inset 3px 0 0 0 var(--accent), 0 0 0 0 transparent; }
}
.tree-row.otto-dest.otto-dest-zoom {
  animation: otto-dest-zoom calc(260ms / var(--otto-speed, 1)) cubic-bezier(0.34, 1.56, 0.64, 1) both;
  transform-origin: left center;
  z-index: 3;
}
@media (prefers-reduced-motion: reduce) {
  .tree-row.otto-dest.otto-dest-zoom { animation: none; }
}

/* §2 dest pill — appended to the dest .col-name. "→ filing here" / "→ filing N
   here", Lucide corner-down-right 14px, NO emoji. */
.otto-dest-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  padding: 0 8px;
  height: 18px;
  font-size: 12px;
  font-weight: 600;
  line-height: 18px;
  color: var(--accent);
  background: var(--otto-dest-wash);
  border: 1px solid var(--accent);
  border-radius: 6px;
}
.otto-dest-pill .lucide-icon { width: 14px; height: 14px; flex-shrink: 0; }

/* §2 path — ancestor folders on the path to src + dest (set when calling
   expandToItem). Faint accent tint so the path reads as connected, and NOT
   dimmed by the rule below. In dual mode the dest's path lives in the RIGHT
   tree, so light .otto-path there too. */
#app[data-otto-filing="1"] #left-tree .tree-row.otto-path,
#app[data-otto-dual="1"]   #right-tree .tree-row.otto-path {
  background: var(--otto-path-wash);
}

/* §2 dim the rest (single-pane fallback) — every left-tree row that isn't
   src/dest/path fades to 0.45. Kept for when the right pane can't load. */
#app[data-otto-filing="1"]:not([data-otto-dual="1"]) #left-tree .tree-row:not(.otto-src):not(.otto-dest):not(.otto-path) {
  opacity: 0.45;
  transition: opacity var(--motion-duration) var(--motion-easing);
}

/* §A.3 DUAL dim — split into two: the LEFT pane dims everything but the source
   (+ its path); the RIGHT pane dims everything but the dest (+ its path). The
   dest no longer lives in the left tree, so the left rule no longer excludes it.
   Gated on data-otto-dual so exactly one of these / the fallback above is active. */
#app[data-otto-dual="1"] #left-tree  .tree-row:not(.otto-src):not(.otto-path),
#app[data-otto-dual="1"] #right-tree .tree-row:not(.otto-dest):not(.otto-path) {
  opacity: 0.45;
  transition: opacity var(--motion-duration) var(--motion-easing);
}

/* §3 ANCHORED CALLOUT — the single decision surface, positioned absolutely in
   #left-tree scroll space under the source row (JS sets top + left/right anchor).
   border-left amber = "this came FROM here is the problem"; flipped to accent
   when the card anchors to the DEST row instead (off-screen guard). */
.otto-callout {
  position: absolute;
  z-index: 6;
  width: min(420px, calc(100% - 24px));
  margin: 4px 0 8px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--warn);
  border-radius: 8px;
  box-shadow: var(--elev-2);
  padding: 12px 16px;
  font-size: 13px;
}
.otto-callout.otto-callout-on-dest { border-left-color: var(--accent); }
.otto-callout-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.otto-callout-head .lucide-icon { width: 18px; height: 18px; flex-shrink: 0; color: var(--accent); }
.otto-callout-headline { font-size: 13px; font-weight: 600; color: var(--text); }
/* §E identity line — confidence dot + subject glyph + "Move <name>", name
   ellipsised (the full name is on the lit source row). The panes carry from/to,
   so the card no longer prints from/to paths. */
.otto-callout-identity {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.otto-callout-identity .confidence-dot { flex-shrink: 0; }
.otto-callout-identity .otto-callout-glyph { display: inline-flex; flex-shrink: 0; }
.otto-callout-identity .otto-callout-glyph .lucide-icon { width: 16px; height: 16px; }
.otto-callout-identity .otto-callout-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* §refine-3 "to:" line — destination LEAF folder name, small + dim, under identity */
.otto-callout-to {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 4px;
  min-width: 0;
  font-size: 12px;
  line-height: 1.4;
}
.otto-callout-to-label { flex-shrink: 0; color: var(--text-dim); font-weight: 400; }
.otto-callout-to-name {
  color: var(--text-dim); font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.otto-callout-rule { height: 1px; background: var(--border); margin: 12px 0; }
/* §E reason — ONE plain-English line, clamped to 2 if it wraps. */
.otto-callout-reason {
  font-size: 13px;
  color: var(--text);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.otto-callout-band { font-size: 12px; color: var(--text-dim); margin-bottom: 4px; display: inline-flex; align-items: center; gap: 6px; }
.otto-callout-foot { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.otto-callout-foot .spacer { flex: 1; }
/* §3 footer buttons — app family @28px, paired symmetry (Skip/Yes same rect).
   Yes = primary accent; Skip + Edit = neutral. low-conf promotes Edit (JS swaps
   the classes). */
.otto-cbtn {
  height: 28px;
  padding: 0 12px;
  min-width: 64px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border-radius: 6px;
  border: 1px solid var(--border);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  background: var(--surface);
  color: var(--text);
  transition: background var(--motion-duration) var(--motion-easing),
              transform var(--motion-duration) var(--motion-easing);
}
.otto-cbtn:hover { background: var(--row-hover); }
.otto-cbtn:active { transform: translateY(1px); }
.otto-cbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.otto-cbtn-primary {
  background: var(--accent);
  color: var(--on-solid);
  border-color: var(--accent);
  box-shadow: var(--elev-1);
}
.otto-cbtn-primary:hover { filter: brightness(1.05); background: var(--accent); }
.otto-cbtn-neutral { background: var(--surface); color: var(--text-dim); }
.otto-cbtn .lucide-icon { width: 14px; height: 14px; flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) {
  .otto-cbtn { transition: none; }
  .otto-cbtn:active { transform: none; }
}

/* §8 pane-toolbar filing strip — "Otto · filing N of M [‹ ›] [✕]". A status +
   nav strip, NOT a decision surface. Sits in the left pane toolbar. */
.otto-filing-strip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  padding: 0 8px;
  height: 24px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--otto-dest-wash);
  border: 1px solid var(--accent);
  border-radius: 6px;
}
.otto-filing-strip-label { margin-right: 4px; }
.otto-filing-strip-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--accent);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.otto-filing-strip-btn:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); }
.otto-filing-strip-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── Walk-through: preview section ──────────────────────────────
   Padding matches .aw-meta (24px horizontal) so the editorial column
   and the preview share the same left/right edges.
   Theo FIX B (2026-06-25): the card↔result separator is NOT owned by
   .aw-meta border-bottom anymore — Iris's stepthrough-otto-polish Piece 1
   set .aw-meta { border-bottom: none } and moved the separation INTO the
   .aw-callout-card frame (its 1px border + box-shadow). That frame is
   unconditional and survives the move/delete/merge/rename animation +
   the post-apply panel rebuild, so the separator persists after a move
   (verified live). Do NOT re-add a border here or on .aw-meta — that
   would double the line. (Stale "owned by .aw-meta::border-bottom" note
   removed: it contradicted the actual rule at .aw-meta below and sent the
   bug hunt chasing a divider that no longer exists.) */
.aw-preview-section {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  padding: 20px 24px 24px;
  overflow: hidden;
  max-width: 560px;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
}
.aw-eyebrow {
  /* Jeremy round 11: RESULT right-aligned inside the same 56px label
     column as the row labels (Action / In / To / Why) above, so its
     right edge is flush with theirs. Width matches column-A so the
     text sits where the labels sit. */
  font: 700 11px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  text-transform: uppercase;
  margin: 0 0 12px 0;
  padding: 0;
  width: 56px;
  text-align: right;
}
/* Legacy label class kept inert to avoid breaking other callers. */
.aw-preview-label { display: none; }
.aw-preview {
  flex: 1; min-height: 0;
  overflow-y: auto;
  font-family: inherit;
  font-size: 13px;
}
.aw-prev-row {
  display: flex; align-items: center;
  height: 22px;
  padding: 0 4px;
  border-radius: 3px;
  color: var(--text);
  white-space: nowrap;
  position: relative;
}
.aw-prev-row-muted { color: var(--text-faint); }
.aw-prev-row-anchor {
  font-weight: 500;
}
.aw-prev-row-anchor[data-anchor="target"] {
  /* The connector's right-side anchor terminates at this row's left edge. */
}
.aw-prev-row-strike .aw-prev-name { text-decoration: line-through; color: var(--text-faint); }
/* Preview tree: indents draw a hairline vertical guide so the hierarchy
   reads at a glance. Subtle — close to background so it suggests rather
   than asserts. align-self: stretch + display: block lets the absolute
   ::before know the parent's height (inline spans don't carry one). */
.aw-prev-indent {
  width: 14px; flex-shrink: 0;
  display: block;
  align-self: stretch;
  position: relative;
}
.aw-prev-indent::before {
  content: '';
  position: absolute;
  left: 6px; top: 0; bottom: 0;
  width: 1px;
  background: var(--border);
  opacity: 0.7;
}
/* Arrow matches the main tree's .tree-toggle (14px box / 9px glyph) so the
   disclosure triangle reads at the same size as the browser tree (Jeremy
   2026-06-27 "make the size of the folders and arrows similar"). */
.aw-prev-chev {
  width: 14px; flex-shrink: 0;
  font-size: 9px;
  color: var(--text-dim);
  text-align: center;
}
/* Full-size triangles (▶/▼, U+25B6/25BC) to match the main tree's .tree-toggle
   glyph — the old ▸/▾ are the Unicode "small" variants and rendered tiny at the
   same font-size (Jeremy 2026-06-27 "the arrows … are tiny"). */
.aw-prev-chev::before { content: '▶'; }
.aw-prev-chev.open::before { content: '▼'; }
.aw-prev-chev.leaf::before { content: ''; }
/* Folder/file glyph driven off --row-icon-size like the main tree's
   .col-name .col-icon, so the preview folders match the browser-tree folders
   instead of rendering at makeFolderSvg's native 20×17 (Jeremy 2026-06-27). */
.aw-prev-icon {
  flex-shrink: 0;
  margin-right: 6px;
  opacity: 0.95;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--row-icon-size, 16px);
  font-size: var(--row-icon-size, 16px); line-height: 1;
}
.aw-prev-icon svg { display: block; vertical-align: middle; width: var(--row-icon-size, 16px); height: var(--row-icon-size, 16px); }   /* tree-matched folder SVG */
.aw-prev-name {
  overflow: hidden;
  text-overflow: ellipsis;
}
.aw-prev-tail {
  margin-left: 8px;
  font-size: 11px;
  color: var(--text-faint);
}
.aw-prev-tail-warn { color: var(--dupe-identical); }
/* Iris fly-refinements §A (2026-06-25): the .aw-prev-oldname-* "↳ was …" sub-row
   styles were removed — the snippet no longer emits the origin echo (left pane
   carries origin). */
.aw-preview-empty { font-size: 12px; padding: 16px 0; }   /* walk-panel compact delta; italic + faint dropped for the one grammar (P2.1) */

/* ── Walk-through: numbered ① ② anchors ─────────────────────────── */
.aw-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  border: 1px solid var(--text-dim);
  border-radius: 50%;
  font-size: 9.5px;
  font-weight: 600;
  color: var(--text-dim);
  margin: 0 2px;
  flex-shrink: 0;
  user-select: none;
}
.aw-num-anchor { margin-left: 8px; }
.aw-num-on-primary {
  border-color: rgba(255,255,255,0.7);
  color: var(--on-solid);
  margin-right: 6px;
}

/* Cross-fade transition on row change — opacity only, ≤220ms */
.aw-meta, .aw-preview { transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1); }

/* Iris brief-12 §3.2 (Batch 12F): 120ms cross-fade between walk-through
   panel contents on tab-switch / cross-kind row click. The .aw-fading flag
   is toggled by _crossFadeWalkPanel() — fade out → swap innerHTML → fade
   in. Half-budget chrome carve-out from brief-9 §9. */
.audit-walk-panel .aw-meta,
.audit-walk-panel .aw-preview-section {
  transition: opacity 60ms cubic-bezier(0.4, 0, 0.2, 1);
}
.audit-walk-panel.aw-fading .aw-meta,
.audit-walk-panel.aw-fading .aw-preview-section {
  opacity: 0;
}

/* Iris brief-12 §3.3: kind-zero-complete state styling. Reuses the
   .aic-empty markup family from the list body so the visual rhyme is
   consistent. Faint secondary sub-line ("Switch tabs to continue...") sits
   below the primary sub-line. */
.audit-walk-panel .aw-kind-zero {
  flex: 1; display: flex; align-items: center; justify-content: center;
}
.audit-walk-panel .aw-kind-zero .aic-empty { padding: 32px 16px; }
.audit-walk-panel .aic-empty-sub-faint {
  margin-top: 8px;
  color: var(--text-faint);
}
.audit-walk-panel .aw-footer-kind-zero {
  justify-content: flex-end;
}

/* While in walk-through mode, the right pane just shows the panel — flat
   surface, no hero gradient (looks like a pane, not a tutorial popup). */
body.audit-walk-mode #right-pane { background: var(--surface); }

/* ── AI RESULTS PANEL (right pane, replaces tree when visible) ── */
#ai-results-panel {
  flex: 1; display: flex; flex-direction: column;
  background: var(--surface);
  border-left: 3px solid var(--accent);
  overflow: hidden;
  min-height: 0;
}

#ai-results-header {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; background: var(--ai-panel-bg);
  border-bottom: 1px solid var(--ai-panel-border);
  flex-shrink: 0;
}
#ai-results-title {
  font-size: 12px; font-weight: 700; color: var(--accent); flex: 1;
  display: flex; align-items: center;
}
#ai-results-close {
  font-size: 11px; padding: 2px 8px; border-radius: 4px;
  background: none; border: 1px solid var(--ai-panel-border); color: var(--text-dim);
  cursor: pointer; white-space: nowrap;
}
#ai-results-close:hover { background: var(--danger-soft-bg); border-color: var(--danger-soft-border); color: var(--danger-text); }

#ai-results-list {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 6px 8px; display: flex; flex-direction: column; gap: 4px;
}
.ai-result-card {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 7px 9px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface-0);
  transition: border-color var(--motion-micro), background var(--motion-micro);
  /* Allow the button to drop below the body on very narrow widths instead
     of being pushed off the right edge of the panel. */
  flex-wrap: wrap;
}
.ai-result-card:hover {
  background: var(--ai-panel-bg); border-color: var(--accent);
}
.ai-result-card.active {
  background: var(--hover-soft-tint); border-color: var(--accent);
  box-shadow: inset 2px 0 0 var(--accent);
}
/* Legacy `.not-found` class kept for back-compat — now the same dashed
   "lazy-load on click" treatment as `.not-loaded`. */
.ai-result-card.not-found,
.ai-result-card.not-loaded {
  border-style: dashed;
  opacity: 0.85;
}
.ai-result-card.not-loaded:hover,
.ai-result-card.not-found:hover {
  background: var(--ai-panel-bg); border-color: var(--accent);
  opacity: 1;
}
.ai-result-card.not-loaded .ai-result-show-btn {
  background: var(--surface-2); color: var(--text-dim);
  border-color: var(--border);
}
.ai-result-card.not-loaded .ai-result-show-btn:hover {
  background: var(--accent); color: var(--cck-accent-on); border-color: var(--accent);
}
.ai-result-icon { font-size: 16px; line-height: 1; flex-shrink: 0; margin-top: 1px; }
.ai-result-body {
  flex: 1 1 140px;  /* basis 140px → reserves room for button before wrapping */
  min-width: 0;
}
/* Names: wrap on word boundaries so a long filename breaks instead of being
   ellipsised behind the Inspector. */
.ai-result-name {
  font-size: 12px; font-weight: 600; color: var(--text);
  word-break: break-word; overflow-wrap: anywhere;
  line-height: 1.3;
}
/* Paths: wrap on slashes too so deep paths break cleanly across lines as the
   right pane is narrowed (drag the splitter, expand the Inspector, etc.). */
.ai-result-path {
  font-size: 10.5px; color: var(--text-dim);
  word-break: break-word; overflow-wrap: anywhere;
  line-height: 1.4; margin-top: 1px;
}
.ai-result-show-btn {
  font-size: 11px; font-weight: 600;
  padding: 4px 10px; border-radius: 4px;
  background: var(--surface); color: var(--accent);
  border: 1px solid var(--ai-panel-border);
  cursor: pointer; white-space: nowrap;
  flex-shrink: 0;
  margin-left: auto;          /* pin to the right edge of the card */
  align-self: flex-start;     /* aligned with the top of the body, not centred */
  transition: background var(--motion-micro), border-color var(--motion-micro), color var(--motion-micro);
}
.ai-result-show-btn:hover {
  background: var(--accent); color: var(--cck-accent-on); border-color: var(--accent);
}
.ai-result-not-found-label {
  font-size: 10px; color: var(--text-faint); font-style: italic;
}

.pane-toolbar {
  min-height: var(--pane-head-h); display: flex; align-items: center; gap: 6px;
  padding: 5px 8px; background: var(--pane-chrome-bg);   /* even gap above/below the selectors (Jeremy 2026-06-27) */
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

/* Per-pane search/filter bar */
.pane-search {
  display: flex; align-items: center; gap: 4px;
  padding: 4px 8px; background: var(--surface-2); border-bottom: 1px solid var(--border);
  flex-shrink: 0; position: relative;
}
.pane-search input {
  flex: 1; font-size: 12px; font-family: inherit;
  padding: 4px 8px; border: 1px solid var(--border-dark); border-radius: 4px;
  background: var(--surface); color: var(--text); min-width: 0;
}
.pane-search input:focus { outline: none; border-color: var(--accent); }
.search-clear {
  background: none; border: none; cursor: pointer;
  font-size: 14px; color: var(--text-dim); padding: 2px 6px;
}
.search-clear:hover { color: var(--danger-text); }

.tb-btn.tb-mini {
  padding: 2px 6px; font-size: 13px; line-height: 1;
  border: 1px solid var(--border-dark); background: var(--surface); color: var(--text-dim);
  border-radius: 4px; cursor: pointer; flex-shrink: 0;
}
.tb-btn.tb-mini:hover { background: var(--hover-soft); color: var(--text); }

/* Design polish (Jeremy 2026-06-27): consistent control treatment across the
   toolbar + pane headers — uniform radii, square mini-tools, pill search +
   rounded dropdowns. Layout/behaviour unchanged. */
.tb-btn { border-radius: 6px; }
.tb-btn.tb-mini { width: 28px; height: 28px; padding: 0; border-radius: 7px; }
.pane-select { height: 30px; border-radius: 8px; padding: 0 10px; }
.pane-search input { height: 30px; border-radius: var(--radius-pill); padding: 0 12px; }

/* Breadcrumb path strip per pane — flat surface, single hairline divider.
   Current crumb gets a subtle surface-2 pill instead of bold weight so navigating
   doesn't cause horizontal layout jiggle. */
.pane-breadcrumb {
  display: flex; align-items: center; gap: 2px;
  padding: 4px 10px; background: var(--surface); border-bottom: 1px solid var(--border);
  font-size: 11px; color: var(--text-dim); flex-shrink: 0;
  overflow-x: auto; white-space: nowrap; min-height: 22px;
}
.pane-breadcrumb:empty::before {
  content: '— no folder selected —'; color: var(--text-faint); font-style: italic;
}
.crumb {
  cursor: pointer; padding: 1px 6px; border-radius: 3px;
  white-space: nowrap;
}
.crumb:hover { background: var(--row-hover); color: var(--accent); }
.crumb-sep { color: var(--text-faint); padding: 0 2px; }
.crumb.crumb-current {
  /* Subtle pill — same weight as siblings, just a hint of surface-2 background */
  color: var(--text);
  background: var(--surface-2);
}
.pane-select {
  flex: 1; font-size: 12px; font-family: inherit; border: 1px solid var(--border-dark);
  border-radius: 4px; padding: 2px 4px; background: var(--surface); color: var(--text);
  min-width: 0;
}
/* Library selector before a site is picked: visible but greyed/inert so both
   panes look identical (no "one pane has an extra dropdown" surprise). */
.pane-select:disabled { opacity: 0.5; cursor: default; color: var(--text-faint); }
.pane-label {
  font-size: 10px; font-weight: 700; color: var(--text-faint); letter-spacing: .05em;
}

/* ── TREE COLUMN HEADER — macOS Finder style ─────────────────── */
.tree-header {
  height: var(--col-head-h); display: flex; align-items: center;
  padding: 0 0 0 8px;
  background: var(--tree-header-bg);
  border-bottom: 1px solid var(--tree-header-rule);
  font-size: 12px; font-weight: 600; color: var(--tree-header-fg);
  flex-shrink: 0; user-select: none;
}
/* Vertical dividers between header cells — macOS Finder: a SHORT centred line
   (not full height). Drawn as an absolutely-positioned ::before at the right
   edge so it stays out of the flex flow; ::after is reserved for the sort
   chevron. (Jeremy 2026-06-27.) */
.tree-header > span {
  align-self: stretch; height: 100%; display: flex; align-items: center; padding: 0 6px;
  position: relative;
}
.tree-header > span:not(:last-child)::before {
  content: ''; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 13px; background: var(--tree-header-divider);
}

/* ── Design polish (Jeremy 2026-06-27): quieter tree header (uppercase),
   tabular Files/Size, softer disclosure triangle. Selection already carries the
   tint + accent bar; the gentle zebra stays. Layout/behaviour unchanged.
   Jeremy 2026-06-27 (later): RESTORE the macOS-style vertical divider lines
   between the column titles (the base .tree-header > span rule above). ─────── */
.tree-header {
  text-transform: none; letter-spacing: normal;   /* macOS Finder: title case, not uppercase */
  font-size: 12px; color: var(--tree-header-fg);
}
/* Jeremy 2026-06-29: darker, clearly-visible column titles. The label text was
   inheriting a fainter colour; pin it to the (now dark) header token. Hover /
   sort-active rules below still win (higher specificity). */
.tree-header > span .th-label { color: var(--tree-header-fg); }
/* Clickable sort headers — Finder style: active column BOLD + thin chevron. */
.tree-header > span[data-sort] { cursor: pointer; }
.tree-header > span[data-sort]:hover .th-label { color: var(--text); }
.tree-header > span.sort-active .th-label { font-weight: 700; color: var(--text); }
.tree-header > span.sort-active::after {
  content: '⌃';                       /* ascending chevron, pinned to the column's right edge (Finder) */
  margin-left: auto; padding-left: 6px; padding-right: 4px;
  font-size: 11px; line-height: 1; color: var(--text-dim);
}
.tree-header > span.sort-active[data-sort-dir="desc"]::after { content: '⌄'; }
.col-files, .col-size { font-variant-numeric: tabular-nums; }
/* The row cells are display:flex (.tree-row > span), so text-align can't move
   the text — flex pins it left. Right-justify Files + Size DATA values with
   justify-content (the header labels stay left, matching macOS Finder). This is
   why Size/Files looked left-aligned despite text-align:right. (Jeremy 2026-06-27.) */
.tree-row > .col-files, .tree-row > .col-folders, .tree-row > .col-size { justify-content: flex-end; }
.tree-toggle { color: var(--text-faint); }

/* ── TREE CONTAINER ─────────────────────────────────────────── */
.tree-container {
  flex: 1; overflow-y: auto; overflow-x: auto;
  background: var(--row-even);
  position: relative;
}
.tree-container:empty::after {
  content: 'Select a site to browse'; display: block;
  padding: 32px; color: var(--text-faint); text-align: center; font-style: italic;
}

/* ── MOTION GATE (GAP 3) — the resolved Settings motion level on <html
   data-motion> gates CSS transitions/animations, not just the JS otto fly.
   settings.js writes the OS-resolved level (off | subtle | full). "Off" snaps
   everything near-instant; "subtle" roughly halves durations. "Full" (the
   default / no attribute) leaves authored timings untouched. */
:root[data-motion="off"] *,
:root[data-motion="off"] *::before,
:root[data-motion="off"] *::after {
  transition-duration: 0.01ms !important;
  animation-duration: 0.01ms !important;
}
/* "subtle" halves the shared motion-duration token, which the bulk of the
   app's transitions key off — a CSS-valid halve (percentage durations aren't
   legal units, so a wildcard *-rule of 50% would be silently dropped). */
:root[data-motion="subtle"] {
  --motion-duration: 100ms;   /* half of the 200ms default */
  --motion-micro: 60ms;       /* half of the 120ms default (P4.2) */
  --motion-structural: 240ms; /* half of the 480ms default (P4.2) */
}

/* ── PRESSED STATES (P4.2) — design-system §5: "press state on every button".
   The ONE pressed grammar (the otto-btn precedent): a 1px settle on :active,
   carried by --press-y so motion "off" zeroes it in one place (the existing
   otto reduced-motion precedent). Push buttons only — tabs keep their
   active-underline state, text links (.cck-linkbtn, .btn-link) keep the link
   grammar, and the families that already carry their own pressed state
   (otto-btn/otto-cbtn/settings-close/sm .btn-apply/.act-undo) keep it. */
:root { --press-y: 1px; }
:root[data-motion="off"] { --press-y: 0px; }
.tb-btn:active, .tb-find-btn:active, .tb-nav-btn:active,
#pane-gutter-tools .gutter-tool:active, #btn-scroll-lock:active,
.btn-primary:active, .btn-secondary:active, .btn-danger:active,
.btn-small:active, .btn-tiny:active, .btn-large:active,
.cck-act:active, .cck-icbtn:active, .cck-icbtn-text:active,
.cck-header-btn:active, .cck-backbtn:active, .cck-tb-btn:active,
.cck-rte-btn:active, .cck-mail-fbtn:active, .cck-mail-groupbtn:active,
.cck-calseg-btn:active, .cck-msb-btn:active, .cck-bp-colbtn:active,
.cck-dd-readbtn:active, .cck-fbtn-wide:active,
.confirm-modal-btn:active, .an-item:active, .settings-seg:active,
.wxc-btn:active, .aw-text-btn:active, .aw-icon-btn:active, .aw-mode-btn:active,
.cp-btn-sm:active, .cp-btn-move:active, .cp-btn-danger:active,
.cp-nav-btn:active, .cp-close-btn:active,
.docpol-btn:active, .ty-locbtn:active, .rn-mode-btn:active,
.ins-chat-send:active, .ins-chat-icon-btn:active, .ins-preview-zbtn:active,
.ofc-chat-hbtn:active, .ofc-chat-connect-btn:active,
.aic-repropose-btn:active, .ai-result-show-btn:active, .act-avatar-btn:active,
.otto-filing-strip-btn:active, .worx-stalebar-btn:active,
.ins-sheet-afbtn:active {
  transform: translateY(var(--press-y));
}

/* ── TREE ROWS — macOS Finder style, themed via tokens ────────── */
/* No row borders — the alternating zebra background does the row-separation
   work. macOS Finder doesn't use row borders either; they make a dense list
   feel like a spreadsheet. */
.tree-row {
  display: flex; align-items: center;
  height: var(--row-h); padding: 0 0 0 8px;
  cursor: default; user-select: none;
  font-size: var(--row-text-size);   /* slider-driven: filenames + all attribute columns scale together */
  white-space: nowrap; overflow: hidden;
  /* B-004 Phase 3A (Iris §3A, 2026-05-19 batch 21): unified state-change
     transition via the motion lock tokens. Was 4 different transition
     values across the row family — now one. */
  transition: background-color var(--motion-duration) var(--motion-easing);
}
.tree-row:nth-child(odd)  { background: var(--row-odd); }
.tree-row:nth-child(even) { background: var(--row-even); }
.tree-row:hover           { background: var(--row-hover) !important; }
/* Phase 3A: dragging + drop-target affordances. */
.tree-row.dragging    { opacity: 0.6; cursor: grabbing; }
.tree-row.drop-target { border: 2px dashed var(--accent); outline-offset: -2px; }

/* (Drop-settle animation removed 2026-06-29 — files just drop into their sorted
   position; no gap / glide / clone. Jeremy: "just drop the files in.") */

/* Transient "working" pill shown while a drop's move/copy is in flight. */
.spe-drop-busy {
  position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 9px;
  background: var(--accent); color: var(--cck-accent-on); padding: 9px 16px; border-radius: 8px;
  z-index: 10000; font-size: 13px; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  max-width: 80vw;
}
.spe-drop-busy .spe-spin {
  width: 13px; height: 13px; flex: 0 0 13px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.4); border-top-color: var(--on-solid);
  animation: spe-spin 0.7s linear infinite;
}
@keyframes spe-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spe-drop-busy .spe-spin { animation: none; } }

/* Selection: light blue tint + blue left accent bar.
   Uses --row-sel token so dark mode picks up the desaturated dark variant
   (bug-tester Brief #1 fix — hard-coded var(--action-pill-info-bg) was bypassing the token). */
.tree-row.selected {
  background: var(--row-sel) !important; color: var(--text);
  box-shadow: inset 3px 0 0 0 var(--accent);
}
/* Multi-select (Jeremy 2026-06-29): every selected row — primary or not —
   renders in the SAME selection blue, so a multi-selection reads as one set. */
.tree-row.multi-selected {
  background: var(--row-sel) !important;
  box-shadow: inset 3px 0 0 0 var(--accent);
}

/* Floating multi-select action bar — pinned bottom-centre when ≥2 selected */
#multi-select-bar {
  position: fixed; left: 50%; bottom: 32px; transform: translateX(-50%);
  display: none; align-items: center; gap: 12px;
  padding: 10px 18px; border-radius: 28px;
  background: var(--tooltip-bg); color: var(--tooltip-text);
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
  font-size: 13px; z-index: 999;
}
#multi-select-bar #multi-select-status { font-weight: 500; }
#multi-select-bar .btn-danger,
#multi-select-bar .btn-secondary {
  font-size: 12px; padding: 4px 12px;
}
.tree-row.selected .col-files,
.tree-row.selected .col-size,
.tree-row.selected .col-modified,
.tree-row.selected .col-purpose { color: var(--text-dim); }
.tree-row.selected:not(.duplicate):not(.dupe-current) .col-name {
  color: var(--text) !important; font-weight: 400 !important;
}

/* Duplicate files — colour by kind so the tree mirrors the pill colours.
   Identical (same name + same size)        → RED   (matches red pill)
   Similar (same name, different size)      → AMBER (matches amber pill)
   Fallback for any duplicate without kind info — muted red. */
.tree-row.duplicate .col-name                    { color: var(--dupe-contains) !important; }
.tree-row.duplicate.dupe-kind-identical .col-name { color: var(--dupe-identical) !important; }   /* RED — deep red, exact dupes */
.tree-row.duplicate.dupe-kind-similar   .col-name { color: var(--dupe-similar) !important; }   /* AMBER — orange-leaning, distinct from red */
/* 3px left bar matches the file's category — red for identical dupes,
   amber for similar. No row tint: only manual .selected gets a bg. */
.tree-row.duplicate.dupe-kind-identical:not(.selected) { box-shadow: inset 3px 0 0 0 var(--dupe-identical) !important; }
.tree-row.duplicate.dupe-kind-similar:not(.selected)   { box-shadow: inset 3px 0 0 0 var(--dupe-similar) !important; }
.tree-row.folder-all-dupes:not(.selected)              { box-shadow: inset 3px 0 0 0 var(--dupe-identical) !important; }
.tree-row.folder-similar:not(.selected)                { box-shadow: inset 3px 0 0 0 var(--dupe-similar) !important; }

/* Active/current duplicate pair — bolder weight, kind colour preserved */
.tree-row.dupe-current .col-name                    { font-weight: 700 !important; }
.tree-row.dupe-current.dupe-kind-identical .col-name { color: var(--dupe-identical-deep) !important; }
.tree-row.dupe-current.dupe-kind-similar   .col-name { color: var(--dupe-similar-deep) !important; }
.tree-row.dupe-current:not(.dupe-kind-identical):not(.dupe-kind-similar) .col-name { color: var(--dupe-identical-deep) !important; }

/* Duplicate folder name colours — only TWO meaningful colours mirror the pills:
     IDENTICAL folder (whole subtree matches another) → RED
     SIMILAR folder   (renamed copy or partial overlap) → AMBER
   "Contains dupes" gets NO special name colour — the children inside already
   carry their own red/amber, so colouring the parent too just creates noise. */
.tree-row.folder-has-dupes .col-name { color: inherit; }                /* normal — children show the dupes */
.tree-row.folder-similar   .col-name { color: var(--dupe-similar); font-weight: 600; }  /* SIMILAR — orange-amber */
/* Text reverted to --dupe-identical per Jeremy's clarification 2026-05-19
   (round 2): the "too dark" complaint was about the FOLDER ICON, not the
   text — text reading as pink under --dupe-identical-glyph. Brightening
   shifted to the icon (see folderSvgColor in app.js:1679). */
.tree-row.folder-all-dupes .col-name { color: var(--dupe-identical); font-weight: 600; }
/* Phase 3C WCAG carve-out (Iris §1 row 8, 2026-05-19 batch 20):
   The pill / col-name text on a dark surface uses --dupe-identical (#b91c1c),
   which is only 2.97:1 on var(--surface). Iris's spec routes the GLYPH (not the
   text — text has the large-pill rule carve-out) to a brighter #dc2626 that
   hits 5.42:1. Folder col-name *text* keeps --dupe-identical because it's
   bold + ≥18px equivalent (large-text WCAG floor is 3:1; passes). */
:root[data-theme="dark"] .tree-row.folder-all-dupes .folder-icon svg {
  color: var(--dupe-identical-glyph);
}
:root[data-theme="dark"] .tree-row.folder-similar .folder-icon svg {
  color: var(--dupe-similar-glyph);
}

/* Diff mode — purple bar on the left edge for files unique to one side,
   amber bar for files modified on both. No full-row tint: only the .selected
   class gets a background, so the eye reads coloured *text + bar* rather
   than coloured *rows* and the manual selection still pops. */
.tree-row.diff-unique-left:not(.selected),
.tree-row.diff-unique-right:not(.selected) {
  box-shadow: inset 3px 0 0 0 var(--diff-unique) !important;
}
.tree-row.diff-unique-left .col-name,
.tree-row.diff-unique-right .col-name {
  color: var(--diff-unique-text) !important;
  font-weight: 600 !important;
}
/* ── Diff mode wins over Duplicate text colour ──
   When the user is in Diff mode, the purple diff signal is the primary axis
   they're looking at. The red duplicate text colour was higher-specificity
   (`.tree-row.duplicate.dupe-kind-identical .col-name`) and overrode the
   purple, defeating the point of Diff mode. These rules use
   `body.compare-mode` (legacy class name — keeps the CSS stable) to add an
   extra class to the cascade so the diff colour always wins.
   Also: "modified-on-both" (size differs) shares the purple of "unique to
   one side" — amber would collide with the duplicate Similar pill colour,
   and conceptually both are "this differs between the two panes." */
/* Colour grammar (Jeremy 2026-05-17):
     • Purple = file unique to one side
     • Amber  = file on BOTH sides but size or modified-date differs
     • Red    = identical duplicate (handled by the standard dup styles) */
body.compare-mode .tree-row.diff-unique-left .col-name,
body.compare-mode .tree-row.diff-unique-right .col-name {
  color: var(--diff-unique-text) !important;
  font-weight: 600 !important;
}
body.compare-mode .tree-row.diff-changed .col-name {
  color: var(--dupe-similar) !important;
  font-weight: 600 !important;
}
body.compare-mode .tree-row.diff-changed:not(.selected) {
  box-shadow: inset 3px 0 0 0 var(--dupe-similar) !important;
}
/* Inline "≠ 28.2 KB" annotation in the Size column for diff-changed files.
   Rounded KB display hides byte-level differences; the contrast value is
   shown right next to the row's own size. Amber matches the row colour. */
.col-size-delta {
  color: var(--action-pill-warn-fg);
  font-weight: 600;
  font-size: 0.92em;
  white-space: nowrap;
  margin-left: 2px;
  cursor: help;
}
:root[data-theme="dark"] .col-size-delta { color: var(--action-pill-warn-fg); }

/* Bare amber pencil glyph next to modified-on-both files — no pill
   background, no padding, just the ✎ in amber so it reads as an inline
   marker on the filename rather than a separate chip. */
.diff-changed-badge {
  display: inline; margin-left: 6px;
  color: var(--dupe-similar);
  font-size: 12px; font-weight: 700;
  cursor: help;
}
:root[data-theme="dark"] .diff-changed-badge { color: var(--action-pill-warn-fg); }
:root[data-theme="dark"] body.compare-mode .tree-row.diff-unique-left .col-name,
:root[data-theme="dark"] body.compare-mode .tree-row.diff-unique-right .col-name {
  color: var(--diff-unique-text) !important;
}
:root[data-theme="dark"] body.compare-mode .tree-row.diff-changed .col-name {
  color: var(--action-pill-warn-fg) !important;
}
:root[data-theme="dark"] body.compare-mode .tree-row.diff-changed:not(.selected) {
  /* no background — left bar carries the signal */
}
.tree-row.diff-changed:not(.selected) {
  box-shadow: inset 3px 0 0 0 var(--dupe-similar) !important;
}
.tree-row.diff-changed .col-name {
  color: var(--dupe-similar) !important;
  font-weight: 600 !important;
}
:root[data-theme="dark"] .tree-row.diff-unique-left:not(.selected),
:root[data-theme="dark"] .tree-row.diff-unique-right:not(.selected) {
  /* no background — left bar carries the signal */
}
:root[data-theme="dark"] .tree-row.diff-unique-left .col-name,
:root[data-theme="dark"] .tree-row.diff-unique-right .col-name {
  color: var(--diff-unique-text) !important;
}
:root[data-theme="dark"] .tree-row.diff-changed:not(.selected) {
  /* no background — left bar carries the signal */
}
:root[data-theme="dark"] .tree-row.diff-changed .col-name {
  color: var(--action-pill-warn-fg) !important;
}

/* Toolbar Diff button — active state */
.tb-btn.tb-btn-active {
  background: var(--diff-unique); color: var(--on-solid); border-color: var(--diff-unique);
}
.tb-btn.tb-btn-active:hover { background: var(--diff-unique-deep); border-color: var(--diff-unique-deep); }

/* Root ancestor of the current duplicate pair — light blue tint with blue bar */
.tree-row.dupe-ancestor:not(.selected) {
  background: var(--row-hover) !important;
  box-shadow: inset 3px 0 0 0 var(--accent) !important;
}
.tree-row.dupe-ancestor .col-name { color: var(--accent) !important; font-weight: 600 !important; }
.tree-row.loading-row     { opacity: .5; }

/* subtle column dividers on rows — matches Finder grid lines */
.tree-row > span {
  border-right: 1px solid var(--border);
  height: 100%; display: inline-flex; align-items: center; padding: 0 6px;
}
.tree-row > span:last-child  { border-right: none; }
.col-name { padding-left: 4px !important; }

/* ── TREE COLUMN WIDTHS (driven by CSS custom properties) ───── */
/* Defaults — overridden by JS from localStorage */
:root {
  --col-name-w:     210px;
  --col-files-w:     60px;
  --col-folders-w:   64px;
  --col-size-w:      76px;
  --col-modified-w: 158px;   /* fits "20 May 2026 at 14:32" — Finder date+time */
  --col-purpose-w:  220px;
}

/* Column display order (Jeremy 2026-06-27: drag-to-reorder). Name is fixed
   first (order 0, like Finder); the attribute columns follow the JS COL_ORDER,
   which writes --ord-<col>. Both the header spans and the row cells carry these
   classes, so one set of order vars keeps header + rows in lock-step. */
.col-name       { order: 0; }
.col-files      { order: var(--ord-files, 1); }
.col-folders    { order: var(--ord-folders, 2); }
.col-size       { order: var(--ord-size, 3); }
.col-modified   { order: var(--ord-modified, 3); }
.col-modifiedby { order: var(--ord-modifiedby, 4); }
.col-purpose    { order: var(--ord-purpose, 5); }
/* Drag-to-reorder affordances on the header. */
.tree-header > span .th-label { cursor: grab; }
.tree-header > span.col-dragging { opacity: 0.4; }
.tree-header > span.col-drop-target { box-shadow: inset 2px 0 0 var(--accent); }
/* Finder-style drag image for tree rows — just the icon + name (no row
   highlight, no size/modified columns). Off-screen; only seen as the drag
   image. (Jeremy 2026-06-29) */
.row-drag-ghost {
  position: fixed; top: -1000px; left: 0; z-index: -1; pointer-events: none;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px 5px 8px; max-width: 340px;
  background: var(--surface); border: 1px solid var(--accent); border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0,0,0,.22); opacity: .97;
  font-size: 13px; color: var(--text);
}
.row-drag-ghost .col-icon { width: 18px; height: 18px; flex: none; display: inline-flex; align-items: center; justify-content: center; overflow: visible; }
.row-drag-ghost .col-icon svg { width: 19px; height: 19px; }
.row-drag-ghost .row-drag-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 260px; }
.row-drag-ghost .row-drag-count {
  flex: none; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--accent); color: var(--cck-accent-on); font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
/* Finder-style drag ghost — a lifted header chip that follows the cursor.
   Lives off-screen; only ever seen as the drag image. (Jeremy 2026-06-29) */
.col-drag-ghost {
  position: fixed; top: -1000px; left: 0; z-index: -1; pointer-events: none;
  box-sizing: border-box; height: var(--col-head-h, 28px);
  display: flex; align-items: center; padding: 0 10px;
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--tree-header-fg); background: var(--surface);
  border: 1px solid var(--accent); border-radius: 6px;
  box-shadow: 0 6px 16px rgba(0,0,0,.18); opacity: .95;
}

/* col-name holds indent + toggle + icon + text so other columns stay fixed */
.col-name {
  width: var(--col-name-w); flex: none; min-width: 80px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 0;
  position: relative;
}
.col-files     { width: var(--col-files-w);    flex-shrink: 0; text-align: right; color: var(--text-dim); font-variant-numeric: tabular-nums; padding-right: 8px; position: relative; }
.col-folders   { width: var(--col-folders-w);  flex-shrink: 0; text-align: right; color: var(--text-dim); font-variant-numeric: tabular-nums; padding-right: 8px; position: relative; }
.col-size      { width: var(--col-size-w);     flex-shrink: 0; text-align: right; color: var(--text-dim); font-variant-numeric: tabular-nums; padding-right: 8px; position: relative; }
/* Jeremy 2026-06-27: match the NAME/FILES/SIZE columns (which inherit the row
   size) — the date + modified-by were a notch smaller at 11px.
   macOS Finder: Date Modified is LEFT-justified and carries the time. */
.col-modified  { width: var(--col-modified-w); flex-shrink: 0; text-align: left; color: var(--text-dim); font-variant-numeric: tabular-nums; position: relative; }
.col-modifiedby{ width: var(--col-modifiedby-w); flex-shrink: 0; color: var(--text-dim); position: relative; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 6px; }
.col-purpose   { flex: 1 1 var(--col-purpose-w); min-width: var(--col-purpose-w); color: var(--text-dim); font-style: italic; font-size: calc(var(--row-text-size) - 1px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-left: 8px; position: relative; }

/* Per-column show/hide — class toggled at #app level lets us hide a whole
   column (header + body) with one CSS rule. Backed by S.colsVisible.* */
#app.col-files-hidden       .col-files,
#app.col-folders-hidden     .col-folders,
#app.col-size-hidden        .col-size,
#app.col-modified-hidden    .col-modified,
#app.col-modifiedby-hidden  .col-modifiedby,
#app.col-purpose-hidden     .col-purpose       { display: none !important; }
/* Modified-by is hidden by default until user enables it via header right-click */
#app .col-modifiedby                            { display: none; }
#app.col-modifiedby-visible .col-modifiedby     { display: inline-flex; }
#app.col-modifiedby-visible .tree-header .col-modifiedby { display: inline-flex; align-items: center; }

.tree-header .col-files,
.tree-header .col-size { text-align: right; }
.tree-header .col-modified,
.tree-header .col-modifiedby { text-align: left; }   /* Finder: dates left-justified */
.tree-header .col-name { padding-left: 4px; }
/* All column titles share one font (Jeremy 2026-06-27): the per-column row rules
   (.col-modified / .col-modifiedby / .col-purpose) were leaking their 11px — and
   AI PURPOSE's italic — into the header, so NAME/FILES/SIZE (10px) didn't match
   MODIFIED/AI PURPOSE. Normalise every header cell. */
.tree-header .col-name,
.tree-header .col-files,
.tree-header .col-folders,
.tree-header .col-size,
.tree-header .col-modified,
.tree-header .col-modifiedby,
.tree-header .col-purpose {
  font-size: 10px; font-style: normal; font-weight: 600;
  letter-spacing: 0.04em; color: var(--text-faint);
}
.tree-header { cursor: default; }
.tree-header:has(.col-name) { cursor: context-menu; }   /* hint that right-click does something */

/* Column-show/hide context menu */
.col-toggle-menu {
  position: fixed; z-index: 9100;
  background: var(--surface); border: 1px solid var(--border-dark);
  border-radius: 6px; box-shadow: var(--shadow);
  padding: 4px;
  min-width: 160px;
  display: none;
}
.col-toggle-menu.open { display: block; }
.col-toggle-menu .col-toggle-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; font-size: 12px;
  color: var(--text); cursor: pointer; border-radius: 4px;
}
.col-toggle-row:hover { background: var(--surface-2); }
.col-toggle-row input[type="checkbox"] { accent-color: var(--accent); }

/* ── COLUMN RESIZE HANDLE ─────────────────────────────────────── */
.col-resize {
  position: absolute; right: -3px; top: 0; bottom: 0; width: 6px;
  cursor: col-resize; z-index: 20; background: transparent;
  display: flex; align-items: center; justify-content: center;
}
.col-resize::after {
  content: ''; width: 2px; height: 14px;
  background: var(--border-dark); border-radius: 1px;
  opacity: 0; transition: opacity var(--motion-micro);
}
.col-resize:hover::after,
.col-resize.dragging::after { opacity: 1; background: var(--accent); }

/* indent lives inside col-name */
.indent { display: inline-block; width: 16px; flex-shrink: 0; }

.tree-toggle {
  width: 14px; height: 14px; display: inline-flex;
  align-items: center; justify-content: center; flex-shrink: 0;
  color: var(--text-dim); cursor: pointer;
  font-size: 9px; transition: transform var(--motion-micro);
}
.tree-toggle.open { transform: rotate(90deg); }
.tree-toggle.leaf { cursor: default; opacity: 0; }

/* icon inside col-name — sized by --row-icon-size so the icon-size slider
   resizes the main-tree glyphs (GAP 1, mirrors the otto rule at ~1230).
   FOLDER icons are inline <svg> (sized below). FILE icons are emoji TEXT
   (fileIcon() in app.js returns 📄/📝/… set via textContent), so their visual
   size is the font-size — drive it off --row-icon-size too, otherwise the zoom
   slider scaled only folders and left file glyphs stuck at a fixed size. */
.col-name .col-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--row-icon-size, 18px); height: var(--row-icon-size, 18px);
  flex-shrink: 0; line-height: 1; text-align: center; overflow: hidden;
  /* FILE icons are emoji TEXT. Safari/WebKit renders emoji LARGER than their
     em-box and with extra side-bearing, so they looked oversized and crowded the
     filename (Chrome renders them tighter to the box). Pin the box, trim the
     glyph a touch, and — since .col-name has gap:0 — add an explicit right gap so
     icon→name spacing is identical in both browsers. (Jeremy 2026-06-29) */
  font-size: calc(var(--row-icon-size, 18px) * 0.85);
  margin-right: 6px;
}
.col-name .col-icon svg {
  width: var(--row-icon-size, 18px); height: var(--row-icon-size, 18px);
}
/* The icon (inline SVG) must NOT become its own drag source — otherwise grabbing
   a file by its icon starts an image-drag and the row's drag payload never fires,
   so folders reject the drop. Pointer-events:none routes the press to the row.
   (Jeremy 2026-06-29 — fixes "can't drag files between folders".) */
.col-name .col-icon svg, .col-name .col-icon svg * {
  -webkit-user-drag: none; user-drag: none; pointer-events: none;
}
/* File-type icons render a touch larger than the box (overflow, so the text
   column doesn't shift) to match the visual weight of folder icons.
   (Jeremy 2026-06-29) */
.col-name .col-icon.file-type-icon { overflow: visible; }
.col-name .col-icon.file-type-icon svg {
  width: calc(var(--row-icon-size, 18px) + 3px);
  height: calc(var(--row-icon-size, 18px) + 3px);
}

.purpose-loading { animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity:.4; } 50% { opacity:1; } }

/* ── PANE RESIZER ─────────────────────────────────────────────── */
#pane-resizer {
  width: 5px; background: var(--border); cursor: col-resize; flex-shrink: 0;
  transition: background var(--motion-micro);
  position: relative; /* anchor for the centered scroll-lock button */
}
#pane-resizer:hover, #pane-resizer.dragging { background: var(--accent); }

/* Centre-gutter both-pane tools (Jeremy 2026-06-27): Mirror + Lock stacked on
   the divider at the rows 2–3 level. Overrides the lock's old centred-absolute
   positioning (higher specificity than #btn-scroll-lock). */
#pane-gutter-tools {
  position: absolute; top: 48px; left: 50%;
  transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 7px;
  z-index: 5;
}
#pane-gutter-tools .gutter-tool {
  position: static; transform: none; top: auto; left: auto;
  width: 30px; height: 30px;
  border-radius: 8px;
  border: 0.5px solid var(--border-dark);
  background: var(--surface); color: var(--text-dim);
  display: flex; align-items: center; justify-content: center;
  padding: 0; cursor: pointer;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  transition: background var(--motion-micro), color var(--motion-micro), border-color var(--motion-micro);
}
#pane-gutter-tools .gutter-tool:hover { background: var(--hover-soft); color: var(--text); }
#pane-gutter-tools .gutter-tool[aria-pressed="true"],
#pane-gutter-tools .gutter-tool.active,
#pane-gutter-tools .gutter-tool.is-active,
#pane-gutter-tools .gutter-tool.locked,
#pane-gutter-tools .gutter-tool.on { background: var(--accent); color: var(--on-solid); border-color: var(--accent); }

/* ── Refined pane controls (Jeremy 2026-06-27): equal thin gaps, path bar flush
   with the controls, search icon inside the pill, Mirror/Lock in a real centre
   gutter column aligned in line with the row icons. ───────────────────────── */
.pane-controls {
  display: flex; flex-direction: column; gap: 4px;
  padding: 4px 8px;
  background: var(--pane-chrome-bg);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.pane-controls .pane-toolbar,
.pane-controls .pane-search {
  min-height: 0; height: auto; padding: 0; border: 0; background: transparent;
  display: flex; align-items: center; gap: 4px;
}
.pane-controls .pane-breadcrumb {
  padding: 0 2px; border: 0; background: transparent; margin: 0;
}
/* Search pill: icon + input + clear inside one rounded field; the send button
   sits outside it. */
.pane-search-field {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 10px;
  border: 0.5px solid var(--border-dark); border-radius: var(--radius-pill);
  background: var(--surface);
}
.pane-search-field:focus-within { border-color: var(--accent); }
.pane-search-icon { color: var(--text-faint); flex: 0 0 auto; }
.pane-search-field input {
  flex: 1; min-width: 0;
  border: 0; background: transparent; outline: none;
  font-size: 12px; font-family: inherit; color: var(--text);
  padding: 0; height: 100%;
}
/* Centre gutter column — Mirror (row 1) + Lock (row 2) aligned with the pane
   rows: same 5px top + 5px gap + 30px tool height as .pane-controls. */
/* Thin centre divider line (like before) with the two tools floating over it,
   aligned to rows 1–2 (Jeremy 2026-06-27: "take the thickening back"). */
#pane-resizer {
  width: 5px;
  background: var(--border);
  position: relative;
}
#pane-resizer:hover, #pane-resizer.dragging { background: var(--accent); }
#pane-gutter-tools {
  position: absolute; top: 5px; left: 50%;
  transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 6px;
  z-index: 5;
}
#pane-gutter-tools .gutter-tool {
  width: 28px; height: 28px; border-radius: 7px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
/* Give the floating centre tools room so the divider reads as evenly-spaced
   [pane icon] · [centre tool] · [pane icon] (Jeremy 2026-06-27). Each pane's
   divider-side controls clear ~24px. */
#left-pane  .pane-controls { padding-right: 18px; }
#right-pane .pane-controls { padding-left: 18px; }

/* Scroll-lock floating button — centered vertically on the resizer */
#btn-scroll-lock {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 1px solid var(--border-dark);
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  z-index: 5;
  transition: background var(--motion-micro), color var(--motion-micro), border-color var(--motion-micro), box-shadow var(--motion-micro);
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
#btn-scroll-lock:hover {
  background: var(--hover-soft-tree); border-color: var(--accent); color: var(--accent);
}
#btn-scroll-lock.active {
  background: var(--accent); border-color: var(--accent); color: var(--on-solid);
  box-shadow: 0 2px 6px rgba(0,120,212,0.35);
}
#btn-scroll-lock svg { width: 14px; height: 14px; pointer-events: none; }
/* Reset-layout FAB removed (pane-controls spec §7): the splitter owns ONLY the
   scroll-lock FAB now. Restoring a pane (clicking its rail) IS the reset. */

/* ── STATUS BAR ──────────────────────────────────────────────── */
#status-bar {
  grid-area: statusbar;
  display: flex; align-items: center; gap: 0;
  padding: 0 10px;
  background: var(--pane-chrome-bg);     /* Iris Brief #1: themed footer */
  border-top: 1px solid var(--footer-border);
  font-size: 11px; color: var(--text-dim);
}
/* Cleaner bottom bars (Jeremy 2026-06-27): faint middot separators, lighter
   tone, hairline borders softened to read as quiet info strips. */
.status-sep { margin: 0 7px; color: var(--text-faint); }
#status-bar { color: var(--text-faint); border-top-color: var(--border); }
.pane-footer { color: var(--text-faint); border-top-color: var(--border); }
#status-bar .status-sync, #status-sync { color: var(--text-dim); }

/* ── CONTEXT MENU ────────────────────────────────────────────── */
/* macOS Finder-style context menu (Jeremy 2026-06-27): rounded container, a
   rounded blue selection pill inset from the edges, hairline separators, and
   hover-reveal submenus with a › chevron. */
#context-menu, #context-menu .ctx-submenu {
  position: fixed; z-index: 9000;
  background: var(--menu-bg);
  border: 1px solid var(--menu-border);
  border-radius: 10px;
  box-shadow: 0 10px 34px rgba(0,0,0,0.20), 0 2px 8px rgba(0,0,0,0.12);
  padding: 5px; min-width: 215px;
}
#context-menu { display: none; }
#context-menu ul { list-style: none; padding: 0; margin: 0; }
#context-menu li {
  position: relative;
  padding: 4px 10px; margin: 1px 0; border-radius: 6px;
  cursor: default; font-size: 13px; white-space: nowrap;
  display: flex; align-items: center; gap: 9px;
  color: var(--text);
}
/* The macOS selection pill: full-width accent fill, white content. */
#context-menu li:not(.ctx-group-label):hover { background: var(--accent); color: var(--on-solid); }
#context-menu li .lucide-icon { color: var(--text-dim); flex-shrink: 0; width: 15px; height: 15px; }
/* DIRECT-child only (Jeremy 2026-06-29): a submenu parent (Zip) is :hover while
   its flyout is open, and a descendant selector here turned the SUBMENU icons
   white-on-white (invisible). `>` keeps the white to the hovered row's own icon. */
#context-menu li:not(.ctx-group-label):hover > .lucide-icon,
#context-menu li:not(.ctx-group-label):hover > .ctx-shortcut,
#context-menu li:not(.ctx-group-label):hover::after { color: var(--on-solid); }
#context-menu .ctx-shortcut { margin-left: auto; color: var(--text-faint); font-size: 12px; padding-left: 16px; }
/* Hairline separators, inset like Finder. */
#context-menu .ctx-sep { height: 1px; background: var(--border); margin: 5px 8px; padding: 0; display: block; }
#context-menu .ctx-group-label {
  padding: 6px 10px 3px;
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-faint); cursor: default;
}
/* Submenu parent: › chevron at the right, flyout on hover. */
#context-menu li.ctx-has-submenu::after {
  content: '›'; margin-left: auto; padding-left: 14px;
  color: var(--text-faint); font-size: 15px; line-height: 1;
}
#context-menu .ctx-submenu { display: none; position: absolute; left: 100%; top: -6px; margin-left: -2px; }
#context-menu li.ctx-has-submenu:hover > .ctx-submenu,
#context-menu li.ctx-has-submenu.submenu-open > .ctx-submenu { display: block; }
#context-menu li.ctx-disabled { opacity: .4; pointer-events: none; }
#context-menu .ctx-danger { color: var(--danger-text); }
#context-menu .ctx-danger .lucide-icon { color: var(--danger-text); }
#context-menu .ctx-danger:hover { background: var(--danger); color: var(--on-solid); }
#context-menu .ctx-danger:hover .lucide-icon { color: var(--on-solid); }

/* ── MODALS ──────────────────────────────────────────────────── */
#modal-overlay {
  position: fixed; inset: 0; background: var(--scrim); z-index: 8000;   /* ONE scrim token app-wide (Jeremy 2026-07-08) */
}
.modal {
  position: fixed; inset: 0; z-index: 8500;
  display: none; align-items: center; justify-content: center;
  pointer-events: none;
}
.modal[style*="display:flex"],
.modal[style*="display: flex"] { pointer-events: all; }
.modal-box {
  background: var(--surface); border-radius: 10px; padding: 28px 32px;
  box-shadow: 0 8px 40px rgba(0,0,0,.25); width: 480px; max-width: 94vw;
  max-height: 80vh; overflow-y: auto;
}
.modal-box h3    { font-size: 16px; margin-bottom: 14px; }
.modal-box p     { color: var(--text-dim); line-height: 1.5; margin-bottom: 18px; }
.modal-wide      { width: 720px; }
.modal-tall      { max-height: 90vh; }
.modal-input {
  width: 100%; padding: 8px 10px; border: 1px solid var(--border-dark);
  border-radius: 6px; font-size: 14px; font-family: inherit; margin-bottom: 18px;
  outline: none;
}
.modal-input:focus { border-color: var(--accent); }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }

/* ── BUTTONS ─────────────────────────────────────────────────── */
/* Iris Brief #2 §0.1 weight-500 sweep: all .btn-* family now 600
   (emphasis weight), removing the "one weight per role" violation
   that allowed .btn-large to inherit 500. */
.btn-primary {
  padding: 8px 18px; border-radius: 5px; border: none;
  background: var(--accent); color: var(--cck-accent-on); font-size: 13px; font-family: inherit;
  cursor: pointer; font-weight: 600;
}
.btn-primary:hover  { background: var(--accent-hover); }
.btn-secondary {
  padding: 8px 18px; border-radius: 5px; border: 1px solid var(--border-dark);
  background: var(--surface); color: var(--text); font-size: 13px; font-family: inherit;
  cursor: pointer; font-weight: 600;
}
.btn-secondary:hover { background: var(--btn-secondary-hover); }
.btn-danger {
  padding: 8px 18px; border-radius: 5px; border: none;
  background: var(--danger); color: var(--on-solid); font-size: 13px; font-family: inherit;
  cursor: pointer; font-weight: 600;
}
.btn-danger:hover { background: var(--danger-hover); }
.btn-large { padding: 12px 32px; font-size: 15px; border-radius: 8px; }
.btn-small { padding: 4px 10px; font-size: 11px; }

/* ── COMPARE PANEL (bottom-docked) ──────────────────────────── */
/* ── COMPARE PANEL ─────────────────────────────────────────── */
#compare-panel {
  grid-area: compare;
  display: none; flex-direction: column;
  background: var(--surface);
  overflow: hidden;
}
#app.compare-open #compare-panel { display: flex; }
/* The inspector is a position:fixed rail on the right. Like #explorer (see
   `#app #explorer { padding-right: var(--inspector-w) }`), the compare panel
   must reserve that space — otherwise its full-width header slides UNDER the
   rail and the ✕ close button is hidden behind it whenever the rail is
   expanded (e.g. the AI chat is open), so there's no way to clear the pane.
   Same var → tracks the rail's collapsed/expanded width automatically. */
#app #compare-panel { padding-right: var(--inspector-w); transition: padding-right var(--motion-duration) var(--inspector-ease); }
/* Folder compare is always a single pair — the ◀ ▶ pager never applies here
   (the file-compare pager lives in the Inspector). Hide the permanently-disabled
   arrows so they don't read as broken buttons. (Jeremy 2026-06-20) */
#compare-panel-header .cp-nav-btn { display: none; }

/* Drag handle — sits above the header, the full-width target for resizing */
#cp-resize-handle {
  height: 6px; flex-shrink: 0; cursor: ns-resize;
  background: var(--border-dark);
  display: flex; align-items: center; justify-content: center;
  position: relative;
}
#cp-resize-handle::after {
  content: '';
  width: 40px; height: 2px; border-radius: 1px;
  background: var(--border-dark);
  pointer-events: none;
}
#cp-resize-handle:hover { background: var(--hover-soft-tint); }
#cp-resize-handle:hover::after { background: var(--accent); }

#compare-panel-header {
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px; height: 32px; flex-shrink: 0;
  background: var(--pane-chrome-bg); border-bottom: 1px solid var(--border);
  user-select: none;
}
.cp-title {
  font-size: 12px; font-weight: 600; color: var(--text); flex-shrink: 0;
}
.cp-nav-btn {
  width: 24px; height: 24px; border-radius: 4px; border: 1px solid var(--border-dark);
  background: var(--surface); cursor: pointer; font-size: 11px;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  color: var(--text); font-family: inherit;
}
.cp-nav-btn:hover { background: var(--hover-soft-tree); border-color: var(--accent); }
.cp-nav-btn:disabled { opacity: .35; cursor: default; }
.cp-counter { font-size: 11px; color: var(--text-faint); white-space: nowrap; flex: 1; padding-left: 6px; }
.cp-close-btn {
  width: 22px; height: 22px; border-radius: 4px; border: 1px solid transparent;
  background: none; cursor: pointer; font-size: 13px; color: var(--text-dim);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.cp-close-btn:hover { background: var(--danger-soft-bg); color: var(--danger-text); }

/* Body: files-row on top, result area below */
#compare-panel-body {
  display: flex; flex-direction: column; flex: 1; overflow: hidden; min-height: 0;
}

/* Two-column file cards + 1px divider */
.cp-files-row {
  display: grid; grid-template-columns: 1fr 1px 1fr;
  flex-shrink: 0; min-height: 130px; height: auto;
  border-bottom: 1px solid var(--border);
}
.cp-col-divider {
  background: var(--border); width: 1px; align-self: stretch;
}

/* Each file card: flex column, meta pinned to bottom */
.cp-file-card {
  display: flex; flex-direction: column;
  padding: 7px 14px 0; overflow: hidden;
}

.cp-card-header {
  display: flex; align-items: center; gap: 6px;
  flex-shrink: 0; margin-bottom: 4px;
}
.cp-card-label {
  font-size: 10px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; flex-shrink: 0;
}
.cp-label-a { color: var(--action-pill-info-fg); }
.cp-label-b { color: var(--ok-soft-fg); }

.cp-card-btns {
  display: flex; gap: 4px; margin-left: auto; flex-wrap: wrap;
  row-gap: 3px; justify-content: flex-end;
}
.cp-btn-sm {
  padding: 2px 7px; font-size: 10px; border-radius: 4px; cursor: pointer;
  border: 1px solid var(--border-dark); background: var(--btn-tertiary-bg); color: var(--text);
  font-family: inherit; white-space: nowrap; line-height: 1.6;
}
/* B-005 Phase 3B (Iris §3B, 2026-05-19 batch 21): route .cp-btn-sm hover
   to --row-hover and .cp-btn-danger to --btn-danger-bg / --btn-danger-hover
   per Iris spec §3B (was hex literals #f0b8b8 / var(--danger-soft-bg)). */
.cp-btn-sm:hover { background: var(--row-hover); }
.cp-btn-danger { border-color: var(--btn-danger-bg); background: var(--surface); color: var(--btn-danger-bg); }
.cp-btn-danger:hover { background: var(--btn-danger-hover); color: var(--on-solid); border-color: var(--btn-danger-hover); }

/* B-005 Phase 3B / R-004 (Iris addendum 2026-05-18): merge-conflict-summary
   migrates from inline style="background:var(--warning-chip-bg);color:var(--warning-chip-fg);..." at
   index.html:591 to the warning-chip token pair. */
#merge-conflict-summary {
  background: var(--warning-chip-bg);
  color: var(--warning-chip-fg);
  border: 1px solid var(--warning-chip-fg);
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 12px;
  margin-bottom: 12px;
}
.cp-btn-move   { border-color: var(--ai-panel-border); background: var(--cck-accent-soft); color: var(--action-pill-info-fg); }
.cp-btn-move:hover  { background: var(--hover-soft-tint); }

/* Scrollable content area — filename + wrapped path */
.cp-card-content {
  flex: 1; overflow: hidden; min-height: 0;
}
.cp-file-name {
  font-size: 12px; font-weight: 600;
  overflow: hidden; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-height: 1.4; margin-bottom: 2px;
}
.cp-file-path {
  font-size: 10px; color: var(--text-faint);
  overflow-wrap: break-word; word-break: break-all;
  line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Meta strip pinned to the bottom of each card */
.cp-file-meta {
  flex-shrink: 0;
  display: flex; gap: 0;
  border-top: 1px solid var(--border);
  margin: 0 -14px;           /* bleed to card edges */
  padding: 5px 14px 6px;
  background: var(--bg);
}
.cp-meta-item {
  display: flex; flex-direction: column; gap: 1px;
  padding-right: 18px;
}
.cp-meta-grow { flex: 1; padding-right: 0; }
.cp-meta-label {
  font-size: 9px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-faint); font-weight: 600;
}
.cp-meta-val {
  font-size: 11px; color: var(--text); font-weight: 500;
}

/* AI result area — gets remaining vertical space */
.cp-result-area {
  flex: 1; overflow-y: auto; min-height: 0;
  padding: 12px 16px;
  background: var(--hover-soft-tree);
}
.cp-loading-msg {
  color: var(--text-faint); font-size: 12px; font-style: italic;
}
.cp-result-text {
  font-size: 12px; line-height: 1.75; color: var(--text);
  white-space: pre-wrap;
}

/* ── DUPLICATES REPORT ────────────────────────────────────────── */
.dupes-report-toolbar {
  display: flex; align-items: center; gap: 12px; margin-bottom: 12px;
  padding-bottom: 12px; border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
#dupes-report-summary { font-size: 12px; color: var(--text-dim); flex: 1; }
.dupes-report-actions { display: flex; gap: 6px; flex-wrap: wrap; }
/* Tabs at the top of the duplicates report (Files / Folders) */
.dupes-report-tabs {
  display: flex; gap: 4px; margin: 4px 0 8px;
  border-bottom: 1px solid var(--border);
}
/* Underline-style tabs — quieter than the old pill-buttons, doesn't fight
   with the chip-pills above. Active state is a 2px accent underline. */
.dupes-tab {
  background: none; border: none;
  padding: 8px 14px; cursor: pointer; font-size: 12px; font-family: inherit;
  color: var(--text-dim); font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--motion-micro), border-color var(--motion-micro);
}
.dupes-tab:hover  { color: var(--text); }
.dupes-tab.active {
  color: var(--accent); font-weight: 600;
  border-bottom-color: var(--accent);
}

/* AI-suggest progress indicator inside the duplicates-report toolbar */
.dupes-ai-progress {
  display: inline-flex; flex-direction: column; gap: 3px;
  min-width: 220px; padding: 2px 4px;
}
.dupes-ai-progress-text {
  font-size: 11px; color: var(--text-dim); display: flex; justify-content: space-between; gap: 8px;
}
.dupes-ai-progress-text #dupes-ai-progress-label { color: var(--ai-tint); font-weight: 600; }
.dupes-ai-progress-text #dupes-ai-progress-count { font-variant-numeric: tabular-nums; }
.dupes-ai-progress-bar {
  height: 5px; background: var(--row-progress-track); border-radius: 3px; overflow: hidden;
}
.dupes-ai-progress-bar #dupes-ai-progress-fill {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--ai-tint) 0%, var(--row-progress-bar) 100%);
  transition: width .25s var(--motion-easing);
}

.dupes-report-list {
  max-height: 50vh; overflow-y: auto; display: block;
}

/* Split-button (used for undo/redo with history dropdowns) */
.tb-split { position: relative; display: inline-flex; }
.tb-split .tb-split-main  { border-top-right-radius: 0; border-bottom-right-radius: 0; padding-right: 4px; }
.tb-split .tb-split-arrow { border-top-left-radius: 0;  border-bottom-left-radius: 0;
                            font-size: 9px; padding: 0 4px; min-width: 16px;
                            border-left: 1px solid rgba(0,0,0,0.08); }
.tb-dropdown {
  position: absolute; top: calc(100% + 4px); right: 0;
  min-width: 280px; max-height: 320px; overflow-y: auto;
  background: var(--surface-0); border: 1px solid var(--border); border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  z-index: 600; font-size: 12px; padding: 4px 0;
}
.tb-dropdown-item {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 6px 12px; cursor: pointer;
}
.tb-dropdown-item:hover { background: var(--hover-soft-tree); }
.tb-dropdown-item.dim   { color: var(--text-faint); }
.tb-dropdown-item .label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tb-dropdown-item .time  { color: var(--text-faint); font-variant-numeric: tabular-nums; font-size: 11px; flex-shrink: 0; }
.tb-dropdown-empty { padding: 12px; }   /* dropdown compact delta; faint→dim via the shared empty-state grammar (P2.1) */

/* (Heatmap minimap removed — native scrollbar restored.) */

/* Merge/move/cancel choice cards used by the drag-to-merge modal */
.merge-option {
  display: block; padding: 12px 14px; margin-bottom: 8px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface-0); cursor: pointer;
  transition: background var(--motion-micro), border-color var(--motion-micro), box-shadow var(--motion-micro);
}
.merge-option:hover {
  background: var(--hover-soft-tree); border-color: var(--accent);
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
.merge-option:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.merge-option-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; margin-bottom: 4px;
}
.merge-option-head strong { font-weight: 600; }
.merge-option-tag {
  font-size: 10px; padding: 2px 8px; border-radius: 10px;
  background: var(--ok-soft-bg); color: var(--ok-soft-fg); font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
}
.merge-option-body { font-size: 12px; color: var(--text-dim); line-height: 1.4; }
.merge-option[data-choice="cancel"] .merge-option-head strong { color: var(--text-dim); }

/* Drag & drop visual feedback */
.tree-row.dragging   { opacity: 0.45; }
.tree-row.drop-target {
  background: var(--sky-soft-bg) !important;
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
/* ⌥-held: green outline + a "+" badge to make COPY intent obvious before drop. */
.tree-row.drop-target-copy {
  background: var(--ok-soft-bg) !important;
  outline-color: var(--ok) !important;
  position: relative;
}
.tree-row.drop-target-copy::after {
  content: '+ COPY';
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  background: var(--ok); color: var(--on-solid);
  font-size: 10px; font-weight: 700; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 10px;
  pointer-events: none;
}

/* Finder-style multi-rename modes (Jeremy 2026-06-30) */
.rn-mode-seg {
  display: flex; gap: 4px; margin: 4px 0 16px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; padding: 3px;
}
.rn-mode-btn {
  flex: 1; padding: 7px 10px; border: 0; border-radius: 6px;
  background: transparent; font: inherit; font-size: 13px;
  color: var(--text-dim); cursor: pointer;
}
.rn-mode-btn.active {
  background: var(--surface); color: var(--text); font-weight: 500;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.rn-fields { display: flex; flex-wrap: wrap; gap: 12px 16px; margin-bottom: 16px; }
.rn-field { display: flex; flex-direction: column; gap: 5px; flex: 1 1 200px; font-size: 12px; color: var(--text-dim); }
.rn-field > span { font-weight: 500; }
.rn-field .text-input { width: 100%; box-sizing: border-box; }
.rn-field .rn-num-small { max-width: 96px; }
.rn-preview-head { font-size: 12px; font-weight: 600; color: var(--text-dim); margin: 0 0 6px; }

/* Rename-pattern preview list */
.pattern-preview {
  max-height: 320px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 6px;
  margin-bottom: 12px; font-size: 12px; background: var(--bg);
}
.pattern-preview-row {
  display: grid; grid-template-columns: 1fr 28px 1fr;
  align-items: center; gap: 10px;
  padding: 5px 12px; border-bottom: 1px solid var(--border);
}
.pattern-preview-row:last-child { border-bottom: none; }
.pattern-preview-row .from { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pattern-preview-row .arrow { color: var(--text-faint); text-align: center; }
.pattern-preview-row .to   { color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pattern-preview-row.bad .to { color: var(--danger-text); }
.pattern-preview-row.same    { opacity: 0.5; }

/* Inline rename — appears in place of the filename text inside .col-name */
.inline-rename-input {
  font: inherit; color: inherit;
  padding: 1px 6px; margin: -2px 0;
  border: 1px solid var(--accent); border-radius: 3px;
  background: var(--surface-0); outline: none;
  min-width: 200px; max-width: 100%;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}

/* Legacy .naming-* rules (#modal-naming results) deleted 2026-06-22 dead-code
   sweep N1. The live Naming tab uses the .ins-naming-* family (see ~line 6485). */

/* Recoverable-space leaderboard rows */
.space-row {
  display: grid;
  grid-template-columns: 36px 1fr 110px 70px 200px 60px;
  align-items: center; gap: 10px;
  padding: 6px 10px; border-bottom: 1px solid var(--border);
  font-size: 12px; cursor: pointer;
}
.space-row:hover:not(.space-row-header) { background: var(--hover-soft-tree); }
.space-row-header {
  background: var(--bg); cursor: default;
  font-weight: 600; color: var(--text-dim); font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em;
  position: sticky; top: 0; z-index: 1;
}
.space-rank  { color: var(--text-faint); font-variant-numeric: tabular-nums; text-align: right; }
.space-path  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.space-bytes { font-variant-numeric: tabular-nums; text-align: right; color: var(--dupe-identical); }
.space-files { font-variant-numeric: tabular-nums; text-align: right; color: var(--text-dim); }
.space-bar   { display: flex; align-items: center; gap: 8px; }
.space-bar-track {
  flex: 1; height: 8px; border-radius: 4px; background: var(--row-progress-track); overflow: hidden;
}
.space-bar-fill {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--dupe-identical) 0%, var(--dupe-similar) 100%);
  transition: width .25s var(--motion-easing);
}
.space-bar-label { font-size: 11px; color: var(--text-dim); width: 40px; text-align: right; }
.space-cum { font-variant-numeric: tabular-nums; text-align: right; color: var(--text-faint); font-size: 11px; }
.space-arrow { display: inline-block; width: 12px; color: var(--text-faint); font-size: 10px; }

/* Drill-down body — appears below a clicked space-row. Two-line per file so
   the full filename + path of both the copy AND the kept-newest are readable. */
.space-drilldown { background: var(--bg); border-bottom: 1px solid var(--border); }
.space-drill-inner { padding: 8px 14px 10px 48px; }
.space-drill-header {
  display: flex; align-items: center; gap: 12px;
  padding: 6px 10px; margin-bottom: 8px;
  background: var(--ai-panel-bg); border: 1px solid var(--ai-panel-border); border-radius: 4px;
  font-size: 12px;
}
.space-drill-header-label { color: var(--text-dim); flex: 1; }
.space-drill-row {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  grid-template-areas:
    "check  name    actions"
    "check  meta    actions"
    "check  kept    actions";
  column-gap: 12px; row-gap: 2px;
  padding: 8px 10px; border-bottom: 1px dashed var(--border);
  font-size: 12px;
}
.space-drill-row:last-child { border-bottom: none; }
.space-drill-row:has(.space-drill-check:checked) { background: var(--danger-soft-bg); }
.space-drill-row > .space-drill-check   { grid-area: check; align-self: start; margin-top: 3px; }
.space-drill-row > .space-drill-name    { grid-area: name; }
.space-drill-row > .space-drill-meta    { grid-area: meta; }
.space-drill-row > .space-drill-kept    { grid-area: kept; }
.space-drill-row > .space-drill-actions { grid-area: actions; align-self: center; }
.space-drill-name {
  font-weight: 600; word-break: break-all; line-height: 1.35;
}
.space-drill-meta {
  color: var(--text-dim); font-variant-numeric: tabular-nums; font-size: 11px;
}
.space-drill-kept {
  color: var(--ok-soft-fg); font-size: 11px;
  background: var(--ok-soft-bg); border: 1px solid var(--ok-soft-border); border-radius: 4px;
  padding: 3px 8px; word-break: break-all; line-height: 1.35;
  display: block;
}
.space-drill-actions { display: flex; gap: 6px; flex-shrink: 0; }
.space-drill-actions button { font-size: 11px; padding: 4px 10px; }
.space-drill-check, .space-drill-check-all { cursor: pointer; }
.dupe-group {
  border: 1px solid var(--border); border-radius: 6px; overflow: hidden;
  margin-bottom: 6px;
  flex-shrink: 0;
}
.dupe-group-header {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  min-height: 36px;
  background: var(--bg); cursor: pointer; user-select: none;
}
.dupe-group-header:hover { background: var(--row-hover); }
.dupe-group-name { font-weight: 600; font-size: 12px; flex: 1; }
.dupe-group-tag {
  font-size: 10px; padding: 2px 7px; border-radius: 10px; font-weight: 600;
}
.dupe-exact { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.dupe-similar { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.dupe-group-count { font-size: 11px; color: var(--text-faint); }
.dupe-group-body { padding: 8px 12px; border-top: 1px solid var(--border); }
.dupe-file-row {
  display: flex; align-items: center; gap: 8px; padding: 4px 0;
  border-bottom: 1px solid var(--border); font-size: 11px;
}
.dupe-file-row:last-child { border-bottom: none; }
.dupe-file-path { flex: 1; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dupe-file-meta { color: var(--text-faint); white-space: nowrap; font-size: 10px; }
.dupe-file-actions { display: flex; gap: 4px; flex-shrink: 0; }
.btn-dupe-action {
  padding: 2px 8px; font-size: 10px; border-radius: 4px; cursor: pointer;
  border: 1px solid var(--border-dark); background: var(--btn-tertiary-bg); color: var(--text);
  font-family: inherit;
}
.btn-dupe-action.danger { border-color: var(--danger-text); color: var(--danger-text); background: var(--danger-soft-bg); }
.btn-dupe-action:hover { background: var(--btn-tertiary-hover); }
.btn-dupe-action.danger:hover { background: var(--danger-soft-bg); }

/* ── ARCHITECT PANEL — Folder Structure Designer ─────────────── */
.architect-panel {
  position: fixed; right: 0; top: var(--toolbar-h); bottom: var(--statusbar-h);
  width: 380px; background: var(--surface);
  border-left: 1px solid var(--border);
  /* 3px accent stripe on the left edge — gives the panel identity without an
     obtrusive header background colour */
  box-shadow: inset 3px 0 0 var(--accent), -4px 0 12px rgba(0,0,0,.08);
  display: none; flex-direction: column; z-index: 200;
}
.architect-panel.open { display: flex; }
.architect-header {
  height: 40px; display: flex; align-items: center; justify-content: space-between;
  padding: 0 14px 0 18px; background: var(--surface-2); border-bottom: 1px solid var(--border);
  font-size: 13px; font-weight: 600; flex-shrink: 0;
  letter-spacing: -0.01em;
}
.architect-tabs {
  display: flex; gap: 0; border-bottom: 1px solid var(--border); flex-shrink: 0;
  background: var(--bg);
}
.architect-tab {
  flex: 1; padding: 8px 6px; font-size: 12px;
  background: none; border: none; border-bottom: 2px solid transparent;
  cursor: pointer; color: var(--text-dim);
}
.architect-tab.active {
  color: var(--accent); border-bottom-color: var(--accent); background: var(--surface-0);
  font-weight: 600;
}
.architect-tab:hover { background: var(--ai-panel-bg); }
.architect-body {
  flex: 1; overflow-y: auto; padding: 12px;
  display: flex; flex-direction: column; gap: 10px;
}
.architect-empty { font-size: 12px; padding: 12px 4px; }   /* rail-card compact delta; italic + faint dropped for the one grammar (P2.1) */
.architect-footer {
  flex-shrink: 0; padding: 10px 12px; border-top: 1px solid var(--border);
  background: var(--bg); display: flex; align-items: center;
}

/* Health score badge */
.arch-score {
  display: inline-block; padding: 4px 10px; border-radius: 12px;
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; margin-right: 8px;
}
.arch-score.green { background: var(--ok-soft-bg); color: var(--ok-soft-fg); border: 1px solid var(--ok-soft-border); }
.arch-score.amber { background: var(--warning-chip-bg); color: var(--warning-chip-fg); border: 1px solid var(--warning-chip-border); }
.arch-score.red   { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); border: 1px solid var(--danger-soft-border); }

.arch-headline {
  font-size: 13px; line-height: 1.4; padding: 10px 12px;
  background: var(--hover-soft-tree); border: 1px solid var(--ai-panel-border); border-radius: 6px;
}

.arch-rec {
  border: 1px solid var(--border); border-radius: 6px;
  padding: 10px 12px; background: var(--surface-0);
  display: flex; flex-direction: column; gap: 4px;
}
.arch-rec-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.arch-rec-title { font-weight: 600; font-size: 13px; flex: 1; }
.arch-rec-tag {
  font-size: 10px; padding: 2px 8px; border-radius: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.arch-rec-tag.cat-housekeeping { background: var(--violet-soft-bg); color: var(--violet-soft-fg); }
.arch-rec-tag.cat-naming       { background: var(--pink-soft-bg); color: var(--pink-soft-fg); }
.arch-rec-tag.cat-structure    { background: var(--action-pill-info-bg); color: var(--action-pill-info-fg); }
.arch-rec-tag.cat-duplicates   { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.arch-rec-tag.cat-archival     { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.arch-rec-rationale { font-size: 12px; color: var(--text-dim); line-height: 1.4; }
.arch-rec-effort { font-size: 11px; color: var(--text-faint); }

.arch-target-file {
  background: var(--bg); border: 1px dashed var(--border); border-radius: 6px;
  padding: 8px 10px; font-size: 12px;
}
.arch-target-file.empty { color: var(--text-faint); font-style: italic; }
.arch-target-name { font-weight: 600; word-break: break-all; line-height: 1.3; }
.arch-target-path { color: var(--text-faint); font-size: 11px; margin-top: 2px; word-break: break-all; }

.arch-suggest-box {
  background: var(--ok-soft-bg); border: 1px solid var(--ok-soft-border); border-radius: 6px;
  padding: 10px 12px; font-size: 12px;
}
.arch-suggest-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ok-soft-fg); font-weight: 700; margin-bottom: 4px; }
.arch-suggest-name { font-family: 'SF Mono', Consolas, monospace; font-weight: 600; word-break: break-all; line-height: 1.3; }
.arch-suggest-rationale { font-size: 11px; color: var(--text-dim); margin-top: 6px; line-height: 1.4; }
.arch-suggest-actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }

.arch-alt-list { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.arch-alt {
  font-size: 11px; padding: 6px 10px; background: var(--surface-0);
  border: 1px solid var(--border); border-radius: 4px;
  display: flex; flex-direction: column; gap: 4px;
}
.arch-alt-path { font-weight: 600; font-family: 'SF Mono', Consolas, monospace; word-break: break-all; }
.arch-alt-reason { color: var(--text-dim); }
.arch-alt-actions { display: flex; gap: 4px; }

.arch-error {
  background: var(--danger-soft-bg); border: 1px solid var(--danger-soft-border); color: var(--action-pill-danger-fg);
  padding: 8px 12px; border-radius: 6px; font-size: 12px;
}

/* Confirm-body path/code styling (P1.4 t5). Was scoped to the legacy
   .modal-cc-body (deleted with customConfirm) — rescoped to the ONE
   confirm-modal so bodies that wrap paths in <code>/<span class="path">
   render them monospace again. */
.confirm-modal-body code, .confirm-modal-body .path {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11.5px;
  background: var(--surface-2); padding: 2px 6px; border-radius: 3px;
  word-break: break-all;
}
.confirm-modal-body .path { display: inline-block; margin-top: 2px; }

/* Legacy #audit-file-panel + legacy audit-results CSS deleted 2026-06-22
   dead-code sweep N3 (.audit-file-*, .audit-section*, .audit-loading,
   .audit-name-*, .audit-meta, .audit-home-*, .audit-empty, .audit-error,
   .audit-summary, .audit-count, .audit-item*, .audit-badge, .audit-type-tag,
   .audit-path, .audit-chevron, .audit-actions, .audit-action-btn,
   .audit-fix-btn, .badge-warn/info/danger + @keyframes audit-spin — all
   zero live refs). The LIVE .audit-walk-* family (main.css ~1160/2017) is a
   different feature and is untouched. */

/* SVG icons inside toolbar buttons — inherit button colour */
.tb-btn svg { pointer-events: none; }

/* AI chat button — sparkle gets a purple→blue gradient when the panel is open */
#btn-chat.active svg {
  fill: url(#sparkle-grad);
}
/* Inline gradient definition is in the SVG itself; fall back to accent colour */

/* ── SYNC REPORT ─────────────────────────────────────────────── */
#sync-report-content { font-size: 12px; line-height: 1.7; max-height: 55vh; overflow-y: auto; }
.sync-note {
  background: var(--warning-chip-bg); border: 1px solid var(--warning-chip-border); border-radius: 6px;
  padding: 8px 12px; margin-bottom: 14px; font-size: 12px; color: var(--warning-chip-fg);
  line-height: 1.5;
}
/* When the sync was performed (Jeremy 2026-06-29). */
.sync-when { font-size: 11px; color: var(--text-dim); margin: 0 0 12px; }
.sync-section { margin-bottom: 14px; }
.sync-section h4 { display: flex; align-items: center; gap: 7px; font-size: 13px; margin-bottom: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--border); }
/* Sync-report change table — fixed columns that line up and wrap to the window
   (Jeremy 2026-06-29). */
.sync-table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 12px; }
.sync-table th, .sync-table td {
  text-align: left; padding: 4px 8px; vertical-align: top;
  word-break: break-word; overflow-wrap: anywhere;
  border-bottom: 1px solid var(--border);
}
.sync-table th { font-size: 11px; font-weight: 600; color: var(--text-dim); border-bottom: 1px solid var(--border-dark); }
.sync-c-name { width: 34%; }
.sync-c-path { width: 44%; color: var(--text-dim); }
.sync-c-by   { width: 22%; color: var(--text-dim); }
.sync-more   { color: var(--text-faint); font-style: italic; }
.sync-entry { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.sync-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.dot-add  { background: var(--success); }
.dot-mod  { background: var(--accent);  }
.dot-del  { background: var(--danger);  }

/* ── PROGRESS OVERLAY ────────────────────────────────────────── */
#progress-overlay {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(0,0,0,.55); display: none;
  align-items: center; justify-content: center;
}
#progress-overlay.visible { display: flex; }

.progress-box {
  background: var(--surface); border-radius: 14px;
  padding: 28px 32px; width: 520px;
  box-shadow: 0 12px 48px rgba(0,0,0,.35);
  overflow: hidden;
}
.progress-header {
  display: flex; align-items: center; gap: 16px; margin-bottom: 18px;
}
.progress-spinner {
  width: 32px; height: 32px; flex-shrink: 0;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  font-size: 0; /* hide any inner text */
}
@keyframes spin { to { transform: rotate(360deg); } }
#progress-label { font-weight: 700; font-size: 15px; margin-bottom: 3px; }
.progress-sub-text { font-size: 12px; color: var(--text-dim); }

.progress-stats {
  display: flex; gap: 10px; margin-bottom: 10px;
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.progress-stats span {
  background: var(--hover-soft-tree); color: var(--accent);
  padding: 3px 10px; border-radius: 10px; font-weight: 600;
  text-align: center;
}
#prog-folders { min-width: 110px; }
#prog-files   { min-width: 120px; }
#prog-time    { min-width: 52px;  }

.progress-bar-wrap {
  display: flex; align-items: center; gap: 10px; margin-bottom: 4px;
}
.progress-bar-track {
  /* Phase 3C (Iris §1 row 14-15, batch 22): route to --row-progress-track. */
  flex: 1; height: 6px; background: var(--row-progress-track); border-radius: 3px;
  overflow: hidden;
}
.progress-bar-fill {
  height: 100%; width: 0%; border-radius: 3px;
  background: var(--row-progress-bar);
  transition: width .3s var(--motion-easing);
}
.prog-pct {
  background: var(--accent); color: var(--cck-accent-on);
  padding: 2px 8px; border-radius: 10px; font-weight: 600;
  font-size: 12px; font-variant-numeric: tabular-nums;
  min-width: 46px; text-align: center; flex-shrink: 0;
}
.prog-bar-label {
  font-size: 10px; color: var(--text-faint); text-align: right;
  margin-bottom: 12px; font-variant-numeric: tabular-nums;
}
.progress-feed-label {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-faint); margin-bottom: 6px;
}
.progress-feed {
  height: 110px; overflow-y: auto; overflow-x: hidden;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg); margin-bottom: 14px; padding: 6px 10px;
  display: flex; flex-direction: column; gap: 0;
  scroll-behavior: smooth;
}
.progress-feed-item {
  font-size: 11px; color: var(--text-dim); line-height: 1.6;
  white-space: normal; word-break: break-all;
  flex-shrink: 0;
  animation: feedIn var(--motion-micro) var(--motion-easing);
}
.progress-feed-item.active { color: var(--accent); font-weight: 500; }
@keyframes feedIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
.progress-footer {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.progress-note {
  font-size: 11px; color: var(--text-faint);
}

/* ── MOVE TREE ───────────────────────────────────────────────── */
.move-tree-container {
  height: 300px; overflow-y: auto; border: 1px solid var(--border);
  border-radius: 6px; margin-bottom: 14px;
}
.move-row {
  padding: 5px 8px; cursor: pointer; display: flex; align-items: center; gap: 4px;
  font-size: 12px;
}
.move-row:hover    { background: var(--row-hover); }
.move-row.selected { background: var(--row-sel); }

/* ── LOADING STATES ──────────────────────────────────────────── */
.loading-msg {
  padding: 24px; text-align: center; color: var(--text-dim);
  font-style: italic; animation: pulse 1.4s ease-in-out infinite;
}

/* ── SCROLLBARS ──────────────────────────────────────────────── */
::-webkit-scrollbar        { width: 8px; height: 8px; }
::-webkit-scrollbar-track  { background: transparent; }
::-webkit-scrollbar-thumb  { background: var(--border-dark); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); }

/* ════════════════════════════════════════════════════════════════
   INSPECTOR — right-docked, 3-state (collapsed 44 / standard 420 / expanded ~50% vw).
   Locked spec 2026-05-14: state.md § "Inspector spec — LOCKED 2026-05-14".
   Visual spec by Iris (polish-designer); behaviour spec by design-tester.
   ──────────────────────────────────────────────────────────────── */

/* The Inspector lives ABOVE the explorer (z-index) and on the RIGHT.
   #explorer gets right-padding equal to the Inspector's current width so
   trees re-flow rather than disappearing under it. */
:root {
  --inspector-w-collapsed: 44px;
  --inspector-w-standard:  420px;
  --inspector-w-expanded:  50vw;
  /* State 2 of the inspector-rail width cycle — three equal regions. The −5px
     accounts for the #pane-resizer so L|R|I read as visually equal thirds
     (design-tester inspector-rail-cycle §1 · Iris §10(c) keeps the −5px). */
  --inspector-w-thirds:    calc((100vw - 5px) / 3);
  --inspector-w:           var(--inspector-w-collapsed);
  --inspector-ease:        var(--motion-easing);  /* P4.2: ONE easing app-wide — the inspector family keeps its named alias */
}
#app #explorer { padding-right: var(--inspector-w); transition: padding-right var(--motion-duration) var(--inspector-ease); }

#inspector {
  position: fixed; top: var(--toolbar-h); right: 0; bottom: var(--statusbar-h);
  display: flex;
  background: var(--surface);
  border-left: 1px solid var(--border);
  z-index: 250;
  width: var(--inspector-w);
  transition: width var(--motion-duration) var(--inspector-ease);
  user-select: none;
}
/* Variable lives on the inspector itself (so `width: var(--inspector-w)` resolves)…  */
#inspector[data-state="collapsed"] { --inspector-w: var(--inspector-w-collapsed); }
#inspector[data-state="standard"]  { --inspector-w: var(--inspector-w-standard); }
#inspector[data-state="expanded"]  { --inspector-w: var(--inspector-w-expanded); }
#inspector[data-state="custom"]    { /* width set via --inspector-w inline */ }
/* …AND on :root, so #explorer (a sibling, not a descendant of #inspector)
   sees the current width too. Without this the explorer kept its initial
   padding-right of 44px even when the Inspector expanded to 50vw, and the
   right pane (with AI Results) overflowed under the Inspector. */
:root:has(#inspector[data-state="collapsed"]) { --inspector-w: var(--inspector-w-collapsed); }
:root:has(#inspector[data-state="standard"])  { --inspector-w: var(--inspector-w-standard); }
:root:has(#inspector[data-state="expanded"])  { --inspector-w: var(--inspector-w-expanded); }

/* Rail — always 44px, vertical stack of tab icons + chevron toggle */
/* P5.1 F3: the rail's tablist is scoped to the tab buttons (the width
   stepper is a sibling group, not a tab) — display:contents keeps the rail's
   one flex column exactly as before. */
.ins-rail-tabs { display: contents; }

#inspector-rail {
  flex: 0 0 32px;   /* thinner — another 10% (Jeremy 2026-06-27) */
  display: flex; flex-direction: column;
  background: var(--surface-2);
  /* faint right hairline removed (Jeremy 2026-06-27) — the surface tone alone
     separates the rail from the panel. */
  padding: 8px 0;
  gap: 4px;
}
.ins-tab {
  width: 32px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none; cursor: pointer;
  color: var(--text-dim);
  position: relative;
  transition: color var(--motion-micro) var(--inspector-ease), background-color var(--motion-micro) var(--inspector-ease);
}
.ins-tab:hover  { background: var(--surface-3); color: var(--text); }
/* Keyboard focus shows the SAME blue left-edge bar as the active tab — not a
   rectangular outline box around the icon (Jeremy 2026-06-29: "should only be a
   blue line to the left of the rail icons"). Preserves a visible focus indicator
   for keyboard users without the boxy ring. */
.ins-tab:focus-visible { outline: none; }
.ins-tab:focus-visible::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px; background: var(--accent);
}
/* Iris brief-10 §6: active rail tab gets a tinted-square container so the
   icon reads as "this is the open tab" rather than "this icon is coincidentally
   blue". Background uses --accent at 12% alpha — reads in both themes without
   minting a new token. color-mix supported Chrome 111+ / Safari 16.4+ — fine
   for this app (Chrome-only per positions.md). */
.ins-tab[aria-selected="true"] {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-radius: 4px;
  margin: 0 4px;        /* contains the rounded square inside the 44px rail */
}
/* Active-tab accent bar — left edge inside the rail (rail = vertical sidebar)
   Iris's pick: ONE indicator type, not three. 2px solid bar.
   Iris brief-10 §6: flush top/bottom (was top:6 bottom:6) so the bar isn't
   swallowed by the tinted square. */
.ins-tab[aria-selected="true"]::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px; background: var(--accent); border-radius: 0;
}
/* "New content available" dot — top-right, 6px, accent colour */
.ins-tab[data-fresh="1"]::after {
  content: ''; position: absolute; top: 8px; right: 8px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 1.5px var(--surface-2);
}
/* §6 (merge spec) — optical-centering nudges. Two glyphs whose ink isn't
   box-centred get a sub-pixel transform so their visual centre lands on the
   rail axis the other four already hit. Geometry (44px tab, 18px icon, 2px
   stroke, x-centre) is UNCHANGED — only the ink moves. Affects exactly these
   two icons. Iris merge spec 2026-06-22 §6. */
/* mouse-pointer-2 (Selection) — arrow mass sits low-left; lift it up & right. */
.ins-tab[data-tab="selection"] .lucide-icon { transform: translate(0.5px, -0.5px); }
/* wand-2 (AI) — diagonal wand reads tilted/low; nudge up to settle it on-axis. */
.ins-tab.ins-tab-ai .lucide-icon { transform: translateY(-0.5px); }

.ins-rail-spacer { flex: 1; }

/* ── D-19 Phase 1 v2 Day 2 redo (batch 79) — stacked tab labels ──
   Jeremy 2026-05-20: count number moves UNDER the title to free
   horizontal space + reads cleaner. Vertical separators between tabs
   give it tab-chrome identity without enclosing each in a box. Active
   tab keeps the 2px accent underline.

   Phase B-arch Batch B (Iris brief-11 §1 + §4): .aic-tabsheader gains a
   right-side cluster (.aic-header-right) holding the top-level Run audit
   button + freshness dot + relative-time text + unified ⋯ overflow.
   Tabs flex to claim remaining horizontal space; right cluster is
   intrinsic-width so the 26h primary button + 8h dot + 11h text don't
   compete with the active-tab underline. */
/* Iris inspector-craft-spec D9 (2026-06-25): the header now stacks the tab
   strip OVER the toned count sub-row, so height is content-driven (auto) — the
   34px tab band + the 20px sub-row define it together. The header keeps its
   bottom hairline: the continuous line the inactive tabs sit behind and the
   active tab breaks through (the "slight overlap line"). */
/* Specificity bump (orchestrator 2026-06-25): the header element carries BOTH
   `.ins-header` and `.aic-tabsheader`. `.ins-header { display:flex }` sits later
   in the cascade at equal (0,1,0) specificity, so it silently overrode
   `display:grid` — flattening tabs + counts into one flex row (the counts spilled
   right, off the panel). Qualifying with `.ins-header` (0,2,0) makes the whole
   grid rule win. Live-proven: counts align under their tabs to 0px once the grid
   activates. (Theo's D9 column layout survived only because it relied on the
   separate `flex-direction` property, not on `display` winning.) */
/* S2 slice 1 (mockup v3 delta 1, 2026-07-06): the tab grid retires — the
   header is now the WRAPPING KIND-CHIP ROW from the approved mockup
   (Duplicates 7 · Purposes 60 · Placement 23 · …). Wrapping kills the whole
   clipped-tab class of bug: any number of chips fits at any panel width.
   Counts live inside the chips, so the two-band grid + count sub-row CSS
   below it are gone. Tokens only; spacing on the 4/8 scale. */
/* Jeremy 2026-07-06: "chips look unaligned and uneven" — an EQUAL-width
   grid instead of ragged flex wrap: every chip the same size, names flush
   left, counts flush right, columns aligned down the panel. The base
   .ins-header supplies justify-content that made the wrap ragged; the
   grid removes the raggedness by construction. */
.ins-header.aic-tabsheader {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(122px, 1fr));
  align-content: start;
  gap: 4px;
  height: auto;
  padding: 8px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

/* Batch 88 (Iris brief-7 §5): at narrow Inspector widths (320-360px) the
   13px title ellipses to "Duplicat…". Drop the title to 12px below 360px
   via container query on the AI panel so "Duplicates" fits cleanly. */
.ins-panel[data-tab="ai"] { container-type: inline-size; container-name: aipanel; }
@container aipanel (max-width: 360px) {
  .aic-tab-name { font-size: 12px; }
}
/* Iris tab-fit-spec D-FIT-2 (2026-06-25): the two wrappers no longer lay
   anything out — `display:contents` removes their own box so their children
   become direct grid items of .aic-tabsheader (tabs → row 1, counts → row 2 of
   the SAME columns). Keep the classes + role="tablist"/aria-hidden for JS + a11y
   (display:contents drops the box, not the semantics or the DOM relationship —
   `.aic-tab-counts .aic-tab-count` selectors still match). */
.aic-tabs {
  display: contents;
}
/* Iris inspector-craft-spec D9 (2026-06-25): real graphical tabs. Inactive =
   a calm toned --surface-2 card with a rounded top, sitting BEHIND the header
   hairline (no visible border of its own). Active = --surface fill (identical
   to the content panel) + a top/side hairline + a -1px overhang that covers
   the header border, so the active tab visually merges with the content. The
   shape carries "active" (rule 2: one signal) — the old accent underline is
   gone, freeing --accent to light the active count below. The old gradient
   separator is DELETED: the toned fill + 2px seam carry tab separation. */
/* S2 slice 1: each tab is a pill CHIP (mockup v3 region 5) — name + count
   inside one rounded control. The old inter-tab "|" separator and the
   ellipsis floor are gone: chips never truncate, they wrap. */
.aic-tab {
  display: flex; align-items: center; justify-content: space-between; gap: 5px;
  width: 100%;                          /* fill the grid cell — equal chips */
  height: 24px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  font: 400 12px/1 -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  white-space: nowrap;
  min-width: 0;
  transition: color var(--motion-duration) var(--motion-easing),
              background var(--motion-duration) var(--motion-easing),
              border-color var(--motion-duration) var(--motion-easing);
}
.aic-tab-name {
  font: inherit;
  font-weight: 500;                     /* Jeremy 2026-07-06: bolder chip text */
  flex: 1 1 auto; min-width: 0; text-align: left;   /* name hugs the dot; count stays right */
  overflow: hidden; text-overflow: ellipsis;
}
/* Jeremy 2026-07-06 ("could the pills do with some kind of tone or
   colour"): each family chip carries a 6px tone dot from the SAME
   action-pill palette its rows use — the chip previews the colour you
   meet in the list. One dot, no washes (RAG grammar rule). */
.aic-tab::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  flex: 0 0 6px;
  background: var(--aic-chip-tone, var(--border));
}
/* Jeremy 2026-07-06 design bar: every family's dot DISTINCT (four shared
   the same info blue). Purple dups · blue purposes · green placement ·
   amber naming · teal lifecycle · grey multi-user · red sensitivity ·
   dim-neutral new. Tokens only. */
.aic-tab[data-aic-kind="duplicates"]  { --aic-chip-tone: var(--action-pill-merge-fg); }
.aic-tab[data-aic-kind="purposes"]    { --aic-chip-tone: var(--action-pill-info-fg); }
.aic-tab[data-aic-kind="placement"]   { --aic-chip-tone: var(--success); }
.aic-tab[data-aic-kind="naming"]      { --aic-chip-tone: var(--action-pill-warn-fg); }
.aic-tab[data-aic-kind="lifecycle"]   { --aic-chip-tone: var(--action-pill-check-fg); }
.aic-tab[data-aic-kind="multiuser"]   { --aic-chip-tone: var(--chip-fg); }
.aic-tab[data-aic-kind="sensitivity"] { --aic-chip-tone: var(--action-pill-danger-fg); }
.aic-tab[data-aic-kind="inbox"]       { --aic-chip-tone: var(--text-faint); }
.aic-tab[data-aic-kind="errors"]      { --aic-chip-tone: var(--warning-chip-fg); }

/* S2 slice 1: the count is a small numeral INSIDE its chip. Mono +
   tabular-nums kept so counts align optically across chips. */
.aic-tab-count {
  display: inline-flex; align-items: center;
  font: 400 11px/1 ui-monospace, 'SF Mono', Consolas, monospace;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
/* The active chip's count lights accent (Iris D12 signal, kept). */
.aic-tab-count[data-active-kind] {
  color: var(--accent);
  font-weight: 600;
}
/* Iris brief-10 §5: count slot shows a check glyph at 0 (signals "clean", not
   "missing data"). Follows the count into the sub-row unchanged. */
.aic-tab-count[data-empty="1"] {
  color: var(--success-text);
}
.aic-tab-count[data-empty="1"] .lucide-icon {
  display: inline-block;
  vertical-align: -1px;
}
/* Iris tab-fit-spec D-FIT-6 (2026-06-25): the obsolete `@container aipanel
   (max-width:400px)` block (min-width:58px ellipsis floor + overflow-x:auto
   scroll guard) was DELETED here. It existed to keep the old forced-equal
   (`flex:1 1 0`) tabs from chopping labels below a 6-char floor. With the
   content-width grid tabs (D-FIT-1/3) each column is exactly its label's
   width and NEVER truncates, so there is no floor to enforce and no
   horizontal scroll to add — the guard was dead. */
/* Hover visibly responds (rule 9). */
.aic-tab:hover:not([aria-selected="true"]) {
  color: var(--text);
  border-color: var(--chip-bg-active);
}
/* ACTIVE chip — pale accent fill + accent text/border (mockup v3 `.chip.on`
   grammar; same signal the cockpit chips use). One weight escalation. */
.aic-tab[aria-selected="true"] {
  color: var(--cck-accent);
  background: var(--cck-accent-soft);
  border-color: var(--chip-bg-active);
}
.aic-tab[aria-selected="true"] .aic-tab-name { font-weight: 600; }
.aic-tab[aria-selected="true"] .aic-tab-count { color: var(--cck-accent); }
.aic-tab:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

/* Iris brief-13 §A.2 (Batch 13A): .aic-actionrow + its collapse-on-
   disabled rule were deleted here. The Step Through / Re-run / ⋯
   buttons are gone (their gestures are now tab-click + right-click +
   dock saved-audit click respectively); the container no longer exists
   in markup. */

/* Batch 86 fix: Structure Audit CTA + saved-audits list + result render
   ONLY under the Structure sub-tab. Without this they leak across every
   sub-tab body (Jeremy flagged 2026-05-21: "why is audit folder structure
   below each tab?"). aiCleanup.renderAiCleanup() sets data-aic-active-kind
   on the AI panel so this scope works. */
/* S2 slice 1: the structure SCANNER's chrome now shows under its two
   family chips — placement and lifecycle ('structure' is a retired tab
   name; setActiveSubTab aliases it to placement). */
.ins-panel[data-tab="ai"]:not([data-aic-active-kind="placement"]):not([data-aic-active-kind="lifecycle"]) #structure-audit-cta,
.ins-panel[data-tab="ai"]:not([data-aic-active-kind="placement"]):not([data-aic-active-kind="lifecycle"]) #structure-audit-result {
  display: none;
}
/* Iris brief-13 §A.2 (Batch 13A): .aic-stepthrough + .aic-rerun +
   .aic-overflow rule blocks deleted here. The three buttons are gone
   from markup along with their containing .aic-actionrow; the gestures
   they served live on the tree right-click, the tab click (12F walk-
   through reseed), and the audits-dock saved-audits list respectively. */

/* ── Iris brief-11 §1 + §4 + §5 (Phase B-arch Batch B) ───────────────────
   Header-right cluster: relative-time text + freshness dot + primary
   Run audit button + unified ⋯ overflow. Sits inside .aic-tabsheader at
   the right edge, vertically centred, intrinsic width so tabs claim the
   remaining horizontal space.

   No new tokens (Iris brief-11 §6 — zero mints). Reuses --accent /
   --accent-hover / --text / --text-dim / --warning-chip-fg / --surface
   / --surface-2 / --border / --hover-soft / --motion-easing /
   --motion-duration.

   Sub-tab Re-run + ⋯ from .aic-actionrow are consolidated into this
   header cluster — the original .aic-rerun / .aic-overflow markup in
   .aic-actionrow stays in DOM (Batch E removal) but is force-hidden via
   .aic-actionrow .aic-rerun / .aic-actionrow .aic-overflow rules below.

   Iris brief-13 §B.1 (Batch 13C): .aic-header-right + [hidden] rules
   deleted here. The cluster + its sole remaining child (the freshness
   dot) were removed from index.html; the dot relocated into the
   audits-dock label (see .aic-freshness-dot above + the dock label
   below). The header right-cluster carries nothing now. */
/* Iris brief-11 Addendum A1 Delta 4 (b): timestamp text element removed.
   The freshness dot + ARIA-labelled tooltip is canonical (Linear/Notion
   dot-only pattern). The dot's `title` attribute carries the full
   timestamp on hover; `aria-label` carries the freshness state for SR
   users.

   Iris brief-13 §B.2 (Batch 13C): the dot relocated from the deleted
   .aic-header-right into the audits-dock strip's label area, where it
   sits immediately left of the audit name. The rule stays as-is
   (token colours + size) — only the host moved. */

.aic-freshness-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--text-dim);
}
.aic-freshness-dot[data-state="fresh"]   { background: var(--accent); }
.aic-freshness-dot[data-state="aged"]    { background: var(--text-dim); }
.aic-freshness-dot[data-state="stale"]   { background: var(--warning-chip-fg); }
.aic-freshness-dot[data-state="none"]    { display: none; }
.aic-freshness-dot[hidden]               { display: none; }

/* Iris brief-13 §A.1 (Batch 13A): .aic-run-audit + .aic-run-audit-icon
   + .aic-run-audit-label rule blocks (incl. the responsive container-
   query that collapsed the label below 420px) deleted here. The header
   button is gone; right-click → Audit structure is the canonical entry
   point and carries its own target context.

   The .aic-actionrow .aic-rerun / .aic-overflow legacy-hide rule was
   also deleted — the .aic-actionrow container itself no longer exists. */


/* Audit summary bar (.aic-summary-*) removed in Phase B-arch Batch E
   per Iris brief-11 §B3. Freshness + recency now ride on the unified
   header dot (.aic-freshness-dot above); audit-complete prose folds
   into the toast + row list. */

/* Iris brief-12 §1 (Batch 12D): the legacy ⋯ overflow popover styles
   (.aic-audit-menu*) were deleted here. Exports now open from the
   .aic-audits-dock Export button via a new compact popover styled
   inline below (.aic-audits-dock-popover + .aic-audits-dock-popover-item).
   Saved-audits row styles (.aic-audit-menu-row*) and the section label
   are gone — the dock's expanded list (12E) re-introduces those
   affordances under .aic-audits-dock-list selectors with the new
   active-dot + delete-icon contract. */

/* ── Iris brief-12 §1 (Batch 12D + 12E) — audits dock ──
   12D/12E: sticky-bottom strip. Iris brief-13 §B.1 (Batch 13C):
   RELOCATED to top-of-pane (between .aic-progress-label and
   #ins-ai-body). Acts as the working pane's title bar — which audit is
   loaded, freshness, saved-count, Export, saved-audits switcher.
   Two states unchanged: collapsed (36px) ↔ expanded (140px). The
   freshness dot now lives inline inside the strip's label (relocated
   from the deleted .aic-header-right). Zero new tokens.

   12E note: the dock height is the only animated dimension. The list
   + footer toggle via CSS on [data-aic-dock-state] so the height
   transition stays smooth across 200ms × --motion-easing per
   brief §1.7. Overflow:hidden on the container clips the list during
   the collapse animation.

   13C note: the strip expands DOWNWARD (chevron points down when
   collapsed; rotates 180° on expand). z-index dropped to 0 — the dock
   no longer overlays the row scroll viewport (it sits ABOVE the
   body in DOM order now). Bottom border added so the seam between
   dock and body is visible at the collapsed 36px height. */
/* Iris brief-14 §A.3 / Sam batch 14A: the base .aic-audits-dock rule
   keeps the cross-mode invariants (flex column, background, borders,
   overflow clip). The 36px collapsed default + the 36↔140 height
   transition are scoped to data-aic-dock-mode="structure" — kind-mode
   is a static 36px strip with NO transition (mode swap is a structural
   change, not an animation). */
.aic-audits-dock {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  /* Jeremy redesign 2026-06-27: the dock becomes the top soft-toned grouped
     panel (macOS-Settings style). Toned fill + full hairline + rounded corners,
     inset from the panel edges. */
  background: var(--panel-fill);
  border: 0.5px solid var(--border);
  border-radius: var(--radius-panel);
  /* 8px bottom margin = the gap to the list, consistent across ALL tabs
     (Duplicates/Naming/New use the dock directly; Structure's summary follows
     and overrides this to 0 so it stays flush — the summary then owns the gap). */
  margin: 8px;
  overflow: hidden;            /* clip list during collapse animation */
}
/* The static Structure summary panel (335 fixes + filter chips), lifted out of
   the scrolling list and grouped with the dock above it as ONE top context card
   (Jeremy redesign 2026-06-27): no top margin so it sits flush under the dock,
   a hairline divider between them, and the card's rounded bottom. */
.aic-structure-summary {
  background: var(--panel-fill);
  border: 0.5px solid var(--border);
  border-top: 0.5px solid var(--border);   /* divider from the dock identity row */
  border-radius: 0 0 var(--radius-panel) var(--radius-panel);
  /* 8px bottom margin = the gap to the list. It lives on this STATIC panel
     (not on the scrolling list), so the white gap is preserved while the list
     scrolls beneath it (Jeremy 2026-06-27). */
  margin: 0 8px 8px;
}
.aic-structure-summary[hidden] { display: none; }
/* When the summary follows, the dock drops its bottom rounding so the two read
   as one continuous card. */
.aic-audits-dock:has(+ .aic-structure-summary:not([hidden])) {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  margin-bottom: 0;   /* flush with the summary; the summary owns the gap to the list */
}
/* Stage 2 (Iris aicleanup-redesign-spec §1.2 + §1.7, 2026-06-25): the
   structure-mode dock is now a fixed 36px REVIEW identity row. The
   saved-audits disclosure list + Close-audit footer left the header
   (re-homed to Settings → Audit Manager), so there is nothing to disclose
   — the 36↔140 expand/collapse height transition + the data-aic-dock-state
   selectors are deleted. The dock is a static 36px row in both modes. */
.aic-audits-dock[data-aic-dock-mode="structure"] {
  height: 36px;
  min-height: 36px;
  max-height: 36px;
}
.aic-audits-dock[hidden] { display: none !important; }

/* Iris brief-14 §A.3: kind-mode container — fixed 36px static strip.
   No expand mechanic, no transition; sits below the tab header on
   Duplicates / Naming / Inbox sub-tabs as the chrome-describes-the-tab
   identity row. Used in concert with the .aic-audits-dock-kind-* row
   markup re-emitted by _paintAuditsDock when activeSubTab !== 'structure'. */
.aic-audits-dock[data-aic-dock-mode="kind"] {
  height: 36px;
  min-height: 36px;
  max-height: 36px;
}
.aic-audits-dock-kind-row {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px;
}
.aic-audits-dock-kind-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text);
}
.aic-audits-dock-kind-meta {
  color: var(--text-dim);
}

/* Iris Addendum A3 (Batch 14L): the .aic-audits-dock-kind-spacer +
   .aic-audits-dock-show-ignored cluster (kind-strip + structure-footer
   "Show ignored (N)" link) was deleted. Recovery is now the in-list
   ghosted-row + filter-strip model (see .aic-ignored-filter below). */

/* Strip row: 36px header band, always visible. Holds the toggle
   button + Export button side-by-side. */
.aic-audits-dock-strip-row {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 8px;
  gap: 8px;
}

/* Stage 2 (Iris aicleanup-redesign-spec §1.5 + §1.7, 2026-06-25): the
   read-only identity line — "{name} · audited {Nh} ago". Replaces the old
   .aic-audits-dock-strip disclosure button + .aic-audits-dock-label (both
   deleted; the disclosure role is gone with the list). The freshness dot
   sits inline-left (the ONE colour signal in this row, rule 5); the name
   truncates with ellipsis at narrow widths; the sep + age never truncate.
   No interaction — this is a static read-out, not a button (rule 9). */
.aic-audit-identity {
  flex: 1 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
}
.aic-audit-identity-name {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 400 13px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text);
}
.aic-audit-identity-sep,
.aic-audit-identity-age {
  flex-shrink: 0;
  white-space: nowrap;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
}
.aic-audit-identity-sep[hidden] { display: none; }

/* Stage 2 (Iris aicleanup-redesign-spec §1.4, 2026-06-25): the ONE quiet
   ↻ Re-run control. Reuses the deleted Export button's ghost grammar
   (24px, --border outline, 12px label, --text-dim resting → --text hover)
   retargeted to .aic-rerun so we mint zero new CSS. Ghost/quiet, not a
   primary — the proposals are the hero (rule 1). Disabled when no audit. */
.aic-rerun {
  flex-shrink: 0;
  height: 24px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--surface);            /* white pill — stands clear of the toned panel (Jeremy) */
  border: 0.5px solid var(--border);
  border-radius: var(--radius-pill);
  cursor: pointer;
  color: var(--text);
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
}
.aic-rerun:hover { background: var(--hover-soft); color: var(--text); }
.aic-rerun:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px;
}
.aic-rerun[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}
.aic-rerun[disabled]:hover { background: transparent; color: var(--text-dim); }
.aic-rerun [data-lucide],
.aic-rerun svg { width: 13px; height: 13px; flex-shrink: 0; }

/* Stage 2 (Iris aicleanup-redesign-spec §1.2 + §9, 2026-06-25): the
   "Audit ▾" export popover CSS was deleted here as a unit — the trigger
   button + the popover markup + its settings-form swap all left the header
   (re-homed to Settings → Audit Manager in Stage 1). Removed rule blocks:
   .aic-audits-dock-popover (+ :has()/.has-settings-form overrides),
   .aic-audits-dock-popover-item (+ -divider, -item-advanced), and the
   inline audit-settings form (.aic-audits-dock-settings*, -radio,
   -custom-controls/-number/-unit, -footer). The CHECK-age control they
   hosted now lives in Settings → Audit Manager (AM-3). */
/* Iris Addendum A3 (Batch 14L): the .aic-ignored-popover cluster
   (14D recovery popover + per-row Restore + Restore-all footer) was
   deleted wholesale. Recovery is now the in-list ghosted-row + filter
   strip — see .aic-row[data-aic-ignored="true"] + .aic-row-restore +
   .aic-ignored-filter rules below. */

/* ── Iris Addendum A3 (Batch 14L) — ghosted-row + Restore + filter strip ──
   Replaces the deleted 14D popover model. Ignored rows stay in the main
   list at their sorted position, rendered at 0.55 opacity with strike
   through on the name. Per-row Restore button (rotate-ccw) replaces the
   Apply + Ignore stack. A 32px filter strip above the row list toggles
   show/hide and (Restore-all) bulk-restores. Zero new tokens. */
.aic-row[data-aic-ignored="true"] {
  opacity: 0.55;
  /* Iris Addendum A5 + A5.1 (Batch 14N): REVERSES A3 §A.2 `cursor:
     default`. Ghosted rows are now clickable — body click opens
     step-through in restore-mode (A5.1 §B body=detail / button=action
     split). Hover bg still fires through the 0.55 ghost. */
  cursor: pointer;
}
.aic-row[data-aic-ignored="true"] .aic-row-name,
.aic-row[data-aic-ignored="true"] .aic-row-text > strong,
.aic-row[data-aic-ignored="true"] .aic-row-text-primary {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
/* Inside a ghosted row, the Restore button bumps to full opacity so it
   stays interactive + WCAG-compliant. Opacity is multiplicative on the
   cascade — calc(1/0.55) ≈ 1.818 overshoots and the browser clamps to 1.
   Spec also calls out filter:opacity() as a robust fallback (heavier
   per-frame but isolates the actions cell). Both applied. */
.aic-row[data-aic-ignored="true"] .aic-row-actions {
  opacity: calc(1 / 0.55);
  filter: opacity(1);
}
.aic-row-restore {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 28px;
  padding: 0 12px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  font: 600 12px/26px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  width: 100%;
  box-sizing: border-box;
  transition: color        var(--motion-duration) var(--motion-easing),
              border-color var(--motion-duration) var(--motion-easing),
              background   var(--motion-duration) var(--motion-easing);
}
.aic-row-restore:hover,
.aic-row-restore:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--surface);
}
.aic-row-restore:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.aic-row-restore svg,
.aic-row-restore .lucide-icon { width: 14px; height: 14px; stroke-width: 1.5; }

/* §C — Filter strip. 32px, between dock and row list. Auto-hides when
   ignored count = 0 (mounted conditionally by _mountIgnoredFilterStrip). */
.aic-ignored-filter {
  display: flex;
  align-items: center;
  height: 32px;
  padding: 0 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.aic-ignored-filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  color: var(--text-dim);
  padding: 4px 8px;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  cursor: pointer;
  border-radius: 4px;
  transition: color      var(--motion-duration) var(--motion-easing),
              background var(--motion-duration) var(--motion-easing);
}
.aic-ignored-filter-toggle:hover,
.aic-ignored-filter-toggle:focus-visible {
  color: var(--text);
  background: var(--hover-soft);
}
.aic-ignored-filter-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.aic-ignored-filter-toggle svg,
.aic-ignored-filter-toggle .lucide-icon { width: 14px; height: 14px; stroke-width: 1.5; }

/* Iris Addendum A3.1 — Restore-all on the filter strip. Ghost text-only,
   tonally identical to the filter toggle, accent-on-hover to signal
   commit. Pushed right inside the 32px strip via margin-left:auto. */
.aic-ignored-filter-restore-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  background: transparent;
  border: 0;
  color: var(--text-dim);
  padding: 4px 8px;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  cursor: pointer;
  border-radius: 4px;
  transition: color var(--motion-duration) var(--motion-easing),
              background var(--motion-duration) var(--motion-easing);
}
.aic-ignored-filter-restore-all:hover,
.aic-ignored-filter-restore-all:focus-visible {
  color: var(--accent);
  background: var(--hover-soft);
}
.aic-ignored-filter-restore-all:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.aic-ignored-filter-restore-all svg,
.aic-ignored-filter-restore-all .lucide-icon { width: 14px; height: 14px; stroke-width: 1.5; }

/* §E — Empty-list slug when filterState=hide AND every row is ignored. */
.aic-empty-all-ignored {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 24px 16px;
  color: var(--text-dim);
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
}
.aic-empty-all-ignored .aic-empty-all-ignored-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Stage 2 (Iris aicleanup-redesign-spec §1.2 + §9, 2026-06-25): the
   header's expanded-dock-body chrome left this surface — the cold-start
   "Audit whole tree" CTA (.aic-audits-dock-cta) and the dock FOOTER
   wrapper (.aic-audits-dock-footer + its disclosure reveal rule) are
   DELETED (header-only). But the saved-audits LIST classes
   (.aic-audits-dock-list*) and .aic-audits-dock-close are RE-USED by the
   Stage-1 Settings → Audit Manager pane (the re-homed saved-audits list +
   "Close current audit", plus the File Manager quarantine list) per Iris
   §2.3 — so their visual rules are retained below. The change vs the old
   header version: the list's display:none + [data-aic-dock-state="expanded"]
   disclosure gate is dropped (there is no dock-state ancestor in Settings;
   the list is simply visible wherever it's placed). */
.aic-audits-dock-list {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  border-top: 1px solid var(--border);
}
.aic-audits-dock-list-item {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 28px;
  padding: 0 8px;
  cursor: pointer;
  color: var(--text);
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  border: 0;
}
.aic-audits-dock-list-item:hover {
  background: var(--hover-soft);
}
.aic-audits-dock-list-item[aria-selected="true"] {
  background: var(--surface-2);
}
.aic-audits-dock-list-item:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px;
}

/* Fixed slot — dot renders only on the active row; the slot reserves
   width so non-active row text aligns. */
.aic-audits-dock-list-dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: transparent;
}
.aic-audits-dock-list-item[aria-selected="true"] .aic-audits-dock-list-dot {
  background: var(--accent);
}
.aic-audits-dock-list-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.aic-audits-dock-list-item[aria-selected="true"] .aic-audits-dock-list-name {
  font-weight: 600;
}
.aic-audits-dock-list-delete {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-dim);
}
/* Lucide ignores data-size and renders SVGs at the default 24px, which looked
   oversized next to the row text — pin the glyph to a tidy 15px (Jeremy
   2026-06-29). */
.aic-audits-dock-list-delete svg { width: 15px; height: 15px; stroke-width: 2; }
/* Inline rename input — sits in place of the name span. */
.aic-audits-dock-list-rename {
  flex: 1; min-width: 0; font: inherit; color: var(--text);
  background: var(--surface); border: 1px solid var(--accent);
  border-radius: 4px; padding: 1px 6px; margin: -2px 0;
}
.aic-audits-dock-list-rename:focus { outline: none; }
.aic-audits-dock-list-delete:hover {
  background: var(--hover-soft);
  color: var(--text);
}
.aic-audits-dock-list-delete:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px;
}

/* Empty state inside the list. */
.aic-audits-dock-list-empty {
  padding: 16px 12px;
  text-align: center;
  color: var(--text-dim);
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
}

/* "Close current audit" / "Empty quarantine" text-link (re-homed into
   Settings → Audit Manager + File Manager per Iris §2.3). Quiet by
   default, danger-tinted on hover. The header-only .aic-audits-dock-footer
   WRAPPER + its disclosure reveal rule are gone; this button rule stays. */
.aic-audits-dock-close {
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--text-dim);
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  transition: color var(--motion-duration) var(--motion-easing);
}
.aic-audits-dock-close:hover {
  color: var(--btn-danger-bg);
}
.aic-audits-dock-close:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
  border-radius: 2px;
}
.aic-audits-dock-close[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}
.aic-audits-dock-close[disabled]:hover { color: var(--text-dim); }

/* Empty-state CTA button (Structure sub-tab, no audit). */
.aic-empty-cta {
  margin-top: 12px;
  display: inline-flex; align-items: center; gap: 4px;
}
.aic-empty-glyph-accent { color: var(--accent); }

/* Spinning glyph for "audit running" placeholder.
   Iris brief-9 §8 carve-out #2 (alongside Mode-C discovery pulse): the
   standard 200ms motion token governs state transitions; continuous
   indeterminate indicators (this spinner) are exempt. */
.aic-spin { animation: aic-spin 1s linear infinite; transform-origin: center; }
@keyframes aic-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* ── Iris brief-11 §2 (Phase B-arch Batch C) — unified progress strip ──
   16px-tall strip below .aic-tabsheader. 3px bar inside (vertically
   centred) + 16px-wide cancel ✕ slot on the right. Sub-label sits in
   its own 16px row below the bar. Both rows reveal via [data-running="1"]
   toggled by aiCleanup.js subscriber to the audit:changed event; hidden
   via [data-running="0"] when idle. Reuses --row-progress-bar /
   --row-progress-track from Phase 3C (B-003) per brief-11 §6 (zero
   mints). The width transition fires on the .aic-progress-fill via a
   short 200ms ease so chrome painting feels alive but the asymptotic
   curve in JS still drives the actual progression. */
.aic-progress {
  display: none;
  align-items: center;
  height: 16px;
  padding: 0 8px 0 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  transition: opacity var(--motion-micro) var(--motion-easing);
  /* Theo bug-fix #55-A 2026-05-27: progress strip lives inside #ins-ai-body
     (the scrolling viewport) so it sticks to the top while streaming rows
     scroll behind it. z-index keeps it above row backgrounds on overlap. */
  position: sticky;
  top: 0;
  z-index: 2;
}
.aic-progress[data-running="1"] {
  display: flex;
}
.aic-progress-track {
  flex: 1; min-width: 0;
  height: 3px;
  background: var(--row-progress-track);
  border-radius: 1.5px;
  overflow: hidden;
}
.aic-progress-fill {
  width: 0;   /* P1.9 t4: was an inline width:0% on the index.html host; JS drives it inline */
  height: 100%;
  background: var(--row-progress-bar);
  width: 0%;
  transition: width var(--motion-duration) var(--motion-easing);
}
.aic-progress-cancel {
  width: 16px; height: 16px;
  margin-left: 8px;
  background: transparent; border: 0;
  color: var(--text-dim);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 3px;
  flex-shrink: 0;
}
.aic-progress-cancel:hover { background: var(--hover-soft); color: var(--text); }
.aic-progress-cancel:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

.aic-progress-label {
  display: none;
  height: 16px;
  padding: 0 12px;
  align-items: center;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font: 400 11px/16px ui-monospace, 'SF Mono', Consolas, monospace;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Theo bug-fix #55-A 2026-05-27: sub-label sits beneath the sticky
     progress bar (16px tall each = 32px total stuck to top of body). */
  position: sticky;
  top: 16px;
  z-index: 2;
}
.aic-progress-label[data-running="1"] {
  display: flex;
}
/* Error-tone variant: when any scanner errored, the label colour
   bumps from --text-dim to --warning-chip-fg so the strip carries the
   "something went wrong" signal without overpainting the bar. */
.aic-progress-label[data-tone="error"] {
  color: var(--warning-chip-fg);
}

/* ── Iris brief-11 §3 (Phase B-arch Batch C) — chip state machine ─────
   Each .aic-tab inherits [data-aic-state] from setAuditState() in
   aiCleanup.js. CSS swaps the visible count slot per state:
     • pending  — Lucide dots / loader2 glyph in --text-dim (audit running,
                  this scanner hasn't started yet).
     • running  — Lucide loader-2 glyph in --accent, spinning.
     • complete — count digits (existing brief-10 §5 behaviour; no swap).
     • error    — Lucide alert-triangle in --warning-chip-fg.
   The state-driven glyph hides the digit count slot only during
   pending/running; complete + error reveal a glyph injected by
   setAuditState (the JS is the single writer of the glyph node). The CSS
   here scopes colour + sizing only. */
/* Iris inspector-craft-spec D10/D11 (2026-06-25): the count span moved to the
   .aic-tab-counts sub-row, so these state rules key off data-aic-state on the
   COUNT span itself (mirrored there by setAuditState) instead of the old
   `.aic-tab[data-aic-state] .aic-tab-count` descendant selector. */
.aic-tab-count[data-aic-state="pending"],
.aic-tab-count[data-aic-state="running"] {
  color: var(--text-dim);
}
.aic-tab-count[data-aic-state="running"] {
  color: var(--accent);
}
.aic-tab-count[data-aic-state="running"] .lucide-icon,
.aic-tab-count[data-aic-state="running"] svg {
  animation: aic-spin 1s linear infinite;
  transform-origin: center;
}
.aic-tab-count[data-aic-state="error"] {
  color: var(--warning-chip-fg);
}
.aic-tab-count[data-aic-state="error"] .lucide-icon,
.aic-tab-count[data-aic-state="error"] svg {
  display: inline-block;
  vertical-align: -1px;
}
/* No rule for [data-aic-state="complete"] — count digits paint via
   _setTabCount per brief-10 §5 (which renders digits when n ≥ 1 or the
   check-circle-2 glyph in --success when n === 0). The runner emits
   state: 'ok' on completion; 'complete' is a logical synonym handled in
   setAuditState() by deferring back to _setTabCount. Intentional no-op
   here so CSS doesn't fight the JS-owned glyph swap. */

/* Errors chip — same chrome as the four kinds but persistent error tone
   on the name + count when present. Hidden by default via the [hidden]
   attribute on the element itself; JS in aiCleanup.js toggles visibility
   based on unifiedAudit.getState().errors. */
.aic-tab-errors[data-aic-state="error"] {
  color: var(--warning-chip-fg);
}
.aic-tab-errors[hidden] {
  display: none;
}
/* Iris tab-fit-spec D-FIT-5 (2026-06-25): mirror the tab button's hidden rule
   so the errors COUNT cell honours `hidden` too — otherwise the
   `.aic-tab-counts .aic-tab-count { display:flex }` grid-item rule (specificity
   0,2,0) overrides the bare [hidden] UA rule (0,1,0) and leaks a stray "0" into
   the count row. JS sets this hidden in lockstep with the errors tab
   (aiCleanup.js). Belt-and-braces with the D-FIT-1 :has() column gate, which
   already collapses the 5th column to 0fr when errors are hidden. */
.aic-tab-count[data-aic-count="errors"][hidden] {
  display: none;
}


/* Body — row list OR empty state. Per Iris brief-6 §8 + §9.
   overflow-y removed (Jeremy 2026-06-25): this element grows to full content
   height and never scrolls itself — #ins-ai-body is the scroll viewport. Its
   `overflow:auto` made it a sticky containing-block, so the filter/chip strips'
   `position:sticky` anchored here (a box that never scrolls) and did nothing —
   the strips scrolled away with the list. Dropping it lets the strips pin to
   #ins-ai-body, matching the .aic-progress sticky pattern (#55-A). */
.ins-ai-cleanup-body {
  /* Jeremy redesign 2026-06-27: the second soft-toned grouped panel — the
     proposal list. Toned fill + hairline + rounded corners, inset from the
     edges. NOTE: deliberately NO `overflow` here (see comment above) so the
     sticky filter/chip strips still pin to #ins-ai-body. */
  background: var(--panel-fill);
  border: 0.5px solid var(--border);
  border-radius: var(--radius-panel);
  /* No top margin: the gap to the panel above is owned by that static panel's
     bottom margin, so it stays fixed as this list scrolls. */
  margin: 0 8px 8px;
}
/* Iris brief-10 §3: row redesign. The grid is fixed-fixed-1fr-auto; the
   text block (1fr) wraps the reason at 2 lines. Apply demoted from solid
   primary to ghost; hovered/focused row promotes it to primary so the
   active row reads correctly. Eleven loud-blue Applys was the failure
   mode — quiet by default, loud on attention. Linear/Notion list pattern. */
.aic-row {
  display: grid;
  /* Iris Addendum A5 + A5.1 (Batch 14N): list rows are navigation-only.
     Asymmetric grid via `min-content` 4th track (A5.1 §C): the 4th cell
     only emits on ghosted rows (per-row Restore button per A5.1 §B —
     recovery action, not a decision). Active rows skip the actions cell
     entirely, so `min-content` collapses to 0 and the layout matches A5
     §C.1's 3-col vision without a per-state template. */
  /* Iris A8 §B (Batch 14R): 2nd column pinned to 76px (was `auto`) so the
     title column's left edge aligns vertically across rows regardless of
     pill label length (RENAME/DELETE were wider than NEW/MOVE). 76px =
     longest existing 6-char label (~72px) + 4px headroom, snaps to 4/8
     scale. Pill width is also pinned at 76px in `.aic-row-pill` below —
     belt-and-braces. */
  /* Feature #130 (bulk-apply): a fixed 20px checkbox track is prepended on
     the left edge (was `28px 76px 1fr min-content`). The cell hosts either
     the .aic-row-select checkbox (actionable, non-ignored rows) or an empty
     .aic-row-select-spacer (everything else) — both occupy the 20px so the
     index/pill/title columns align vertically across every row regardless of
     whether a checkbox is present. */
  /* Iris inspector-craft-spec D13 (2026-06-25): per-gap control replaces the
     uniform 12px column-gap. The checkbox↔index pair is one logical unit
     ("item N, select it") and gets a tight 4px gap; index↔pill and pill↔text
     stay 12px. Gaps now live in track padding/margin (column-gap:0) so each
     gap is independently controllable. Index track 28→24px (a 2-3 digit
     right-aligned number needs ~24px; 28 was loose). */
  /* Jeremy redesign 2026-06-27: two-line row. Line 1 = checkbox · number ·
     action pill. Line 2 = filename + description spanning full width (from the
     number column to the right edge), so both get the whole column instead of
     being squeezed right of the pill. Children are placed explicitly below. */
  /* Jeremy 2026-07-06 round 4: pill as far left as 4-digit safety allows.
     The index renders WITHOUT a thousands comma ("3083"), so 4 digits at
     11px mono ≈ 27px; 32px track = 28px number + 4px gap. Verified: no
     clipping at 9999, pill 4px further left than round 3. */
  grid-template-columns: 20px 32px 1fr;
  grid-template-rows: auto auto;
  column-gap: 0;
  row-gap: 4px;
  align-items: start;
  padding: 12px;
  background: transparent;        /* shows the toned panel fill (Jeremy redesign) */
  border-bottom: 0.5px solid var(--border);
  cursor: pointer;
  /* Iris Addendum A5 §C.1: revert heights now that the row no longer
     hosts a stacked Apply + Ignore (which forced 64/220 in 14H). 56/200
     matches pre-14C breath. Whole-row click affords entry to step-through;
     no per-row button as the implicit handle. */
  min-height: 56px;
  max-height: 200px;
  overflow: hidden;
  transition: background-color var(--motion-duration) var(--motion-easing);
}
.aic-row:last-child { border-bottom: 0; }   /* let the panel's rounded bottom show */
.aic-row:hover { background: var(--row-hover); }
.aic-row:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.aic-row[aria-selected="true"] {
  background: var(--row-sel);
  position: relative;
}
.aic-row[aria-selected="true"]::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px; background: var(--accent);
}

/* Iris Addendum A5.1 (Batch 14N): actions cell simplified to single-cell
   host for the per-row Restore button on ghosted rows. The 14H flex-column
   stack (Apply over Ignore) is GONE — Apply + Ignore moved to step-through
   per single-source-of-decision rule #7. Cell only emits when ghosted
   (see _rowMarkup), so this rule only ever applies to a single Restore
   button child. */
.aic-row-actions {
  grid-column: 3; grid-row: 1; justify-self: end;   /* restore button, top-right of line 1 */
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

/* Feature #130 — bulk-apply checkbox cell (left edge, first grid track).
   .aic-row-select is the clickable label wrapper; .aic-row-select-input is the
   native checkbox; .aic-row-select-spacer is the empty placeholder on non-
   selectable rows so the 20px track is always occupied (columns stay aligned).
   Top-padding nudges the box onto the first text line, matching the index/pill
   optical baseline (align-items:flex-start on the row). */
/* Iris inspector-craft-spec D13+D14 (2026-06-25): 4px right-pad = the tight
   checkbox→index gap (per-gap control). An 18px line-box matched to the name's
   first line (13px/18px) with centered content puts the checkbox on the same
   optical line as the index, pill, and name first-line. (Robust to the
   e87a90d scroll-preserve checkbox handler — this is layout-only, no event
   wiring touched.) */
.aic-row-select,
.aic-row-select-spacer {
  grid-column: 1; grid-row: 1;
  width: 20px;
  /* Jeremy 2026-07-06: 20px line-box matching the pill's height so the
     checkbox, index and pill all centre on ONE optical line (they were
     18px against the 20px pill — a visible 2px drift). */
  height: 20px;
  padding-top: 0;
  padding-right: 4px;
  display: inline-flex;
  align-items: center;
  /* Jeremy 2026-07-06 round 2: hug the row's left padding edge (was
     centred in the track — read as floating). */
  justify-content: flex-start;
}
.aic-row-select {
  cursor: pointer;
}
.aic-row-select-input {
  width: 15px;
  height: 15px;
  margin: 0;
  cursor: pointer;
  accent-color: var(--accent);
  flex-shrink: 0;
}
.aic-row-select-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* Selected-row affordance — a soft accent wash so a selected row reads as
   "queued for bulk apply" without competing with the aria-selected step-through
   marker (which uses --row-sel + a left accent bar). Kept subtle. */
.aic-row[data-aic-selected="true"] {
  background: var(--row-hover);
}

/* Action number — matches Step Through step #N. Click row → jump to step.
   Iris inspector-craft-spec D13+D14: width 28→24, 12px right-pad (index→pill
   gap), 18px line-box → shares the name's first baseline; digits right-aligned
   and vertically centered so [☐] [1] [PILL] Name sit on one optical line. */
.aic-row-index {
  grid-column: 2; grid-row: 1;
  width: 32px;    /* Jeremy 2026-07-06 round 4: 4 digits (no comma) + 4px gap — pill hugs closer, no clipping to 9999 */
  height: 20px;   /* Jeremy 2026-07-06: match the 20px pill line (was 18px) */
  padding-top: 0;
  padding-right: 4px;
  display: inline-flex;
  align-items: center;
  /* Jeremy 2026-07-06 round 2: LEFT-aligned (was right) so the number's
     left edge lines up exactly with the filename's left edge on line 2 —
     the number + pill line and the text block now share one left rhythm. */
  justify-content: flex-start;
  font: 400 11px/20px ui-monospace, 'SF Mono', Consolas, monospace;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  text-align: left;
  user-select: none;
}

/* Action pill — 4 colour families, all 12/600 on tinted bg. Width is
   intrinsic to label; min-width keeps DELETE / RENAME / MERGE / MOVE / NEW
   visually similar in weight (longest is RENAME at 6 chars). */
.aic-row-pill {
  display: inline-flex; align-items: center; justify-content: center;
  /* Iris A8 §B (Batch 14R): fixed 76px width (was min-width:56px + padding)
     so DELETE/RENAME/MERGE/MOVE/CHECK/NEW all render at identical width.
     Centered label, no padding. 76px ceiling caps new labels at 6 chars —
     enforced via PILL_MAP discipline. */
  grid-column: 3; grid-row: 1; justify-self: start;   /* pill leads line 1, left-aligned */
  height: 20px; width: 76px; padding: 0;
  border-radius: var(--radius-pill);                  /* capsule (Jeremy redesign) */
  font: 600 11px/20px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  flex-shrink: 0;
  user-select: none;
}
.aic-row-pill[data-pill="delete"] { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.aic-row-pill[data-pill="rename"] { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.aic-row-pill[data-pill="move"]   { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.aic-row-pill[data-pill="merge"]  { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }
.aic-row-pill[data-pill="new"]    { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
/* Iris brief-14 §B.3 — CHECK pill for empty-folder >6mo proposals. */
.aic-row-pill[data-pill="check"]  { background: var(--action-pill-check-bg);  color: var(--action-pill-check-fg); }

/* Text block — filename + description on a full-width second line, aligned to
   the number column (Jeremy redesign 2026-06-27); the checkbox keeps its own
   gutter at column 1. */
.aic-row-text { grid-column: 2 / -1; grid-row: 2; min-width: 0; }
.aic-row-name {
  font: 600 13px/18px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text);
  /* Iris brief-12 Addendum A1: wrap to multiple lines instead of single-line
     ellipsis — filenames are now visible at the canonical 366px panel width.
     Cap at 3 lines as runaway-safety for pathological SharePoint paths. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
          line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
  /* was 14/20/500 — brief-6 ramp has no 14; 13/18/600 is on-ramp + on-policy. */
}
.aic-row-reason {
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  margin-top: 2px;
  /* Iris brief-12 Addendum A1: 2-line → 4-line clamp so reason copy is
     fully visible at canonical 366px panel width. -webkit-line-clamp is
     widely supported (Chrome/Edge/Safari/Firefox 68+); standard
     `line-clamp` aliased on newer browsers — both declared for portability. */
  display: -webkit-box;
  -webkit-line-clamp: 4;
          line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* S2 (Jeremy 2026-07-06): the per-kind ⟳ rescan in the dock line — same
   ghost-control chrome as the list's Load-more/Restore controls. */
.aic-kind-rescan {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: auto;
  height: 20px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  font: 400 11px/1 -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  white-space: nowrap;
}
.aic-kind-rescan:hover:not(:disabled) { color: var(--text); border-color: var(--chip-bg-active); }
.aic-kind-rescan:disabled { opacity: .6; cursor: default; }
/* Jeremy 2026-07-06: the dock repaints icons via lucide.createIcons, which
   ignores our data-size convention and emits a 24px default SVG (the classic
   "new button, giant icon" failure — two icon pipelines). Pin the size in
   CSS so it can never balloon regardless of which pipeline painted it. */
.aic-kind-rescan svg, .aic-kind-rescan .lucide-icon, .aic-kind-rescan i {
  width: 12px; height: 12px; flex: 0 0 12px;
}

/* S2: the Purposes regenerate strip — pre-context proposals offer one
   click to re-reason from the tree (ancestors/siblings/files). */
.aic-repropose-strip {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 16px;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.aic-repropose-btn { margin-left: auto; }
/* S2 (Jeremy): the Propose-all progress strip — a full-width 3px bar under
   the pass counter, same grammar as the diligence pipeline bars. */
.aic-repropose-strip[data-running="1"] { row-gap: 6px; }
.aic-repropose-strip .aic-kind-rescan { margin-left: auto; }
.aic-purpose-bar {
  flex: 1 0 100%;
  height: 3px; border-radius: 2px;
  background: var(--chip-bg);
  overflow: hidden;
}
.aic-purpose-bar-fill {
  display: block; height: 3px; border-radius: 2px;
  background: var(--accent);
  transition: width var(--motion-duration) var(--motion-easing);
}

/* S2 slice 2 (mockup delta 2): the Issue:/Fix: labels — 500 weight, dim.
   The Fix line clamps tighter so a row stays a compact triage unit. */
.aic-row-lbl { font-weight: 600; color: var(--text-dim); }
.aic-row-fixline {
  -webkit-line-clamp: 2;
          line-clamp: 2;
}

/* Iris Addendum A5 + A5.1 (Batch 14N): the .aic-row-apply cluster
   (idle neutral / hover accent / [data-aic-reveal] quiet variant) and
   the .aic-row-ignore cluster (post-14H danger-soft rectangle + dark
   WCAG override) were DELETED wholesale. Apply + Ignore decisions moved
   to step-through (single-source-of-decision rule #7). The only commit
   button still rendered on a list row is .aic-row-restore on ghosted
   rows (A5.1 §B option 2 — recovery, not a decision), defined above. */

/* .aic-empty base/title/sub carried by the shared empty-state grammar
   (P2.1; 56px pad → the shared on-scale 48px/24px, title 14px → the 13px
   ramp). Only the data-tone glyph colours stay scoped. */
.aic-empty[data-tone="success"] .lucide-icon { color: var(--success-text); }
.aic-empty[data-tone="neutral"] .lucide-icon { color: var(--text-faint); }
.aic-truncate {
  padding: 8px 16px;
  font: 400 11px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-faint);
  text-align: center;
  font-style: italic;
}
/* Theo bug-fix 2026-05-27: "Load more (N remaining)" button replaces the
   static .aic-truncate readout. Same dimensions as the row apply button
   for visual consistency; ghost treatment with hover promotion to the
   accent. Existing tokens only — no new mints. */
.aic-load-more {
  display: block;
  width: calc(100% - 24px);
  margin: 8px 12px;
  padding: 8px 12px;
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  font: 600 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  transition: background-color var(--motion-duration) var(--motion-easing),
              border-color    var(--motion-duration) var(--motion-easing),
              color           var(--motion-duration) var(--motion-easing);
}
.aic-load-more:hover,
.aic-load-more:focus-visible {
  background: var(--surface-2);
  border-color: var(--text-dim);
  color: var(--text);
}
.aic-load-more:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* Iris brief-13 §D.3 (Batch 13F): sub-text under Load more clarifies that
   step-through walks ALL rows even when the list is paginated. 11px dim. */
.aic-load-more-sub {
  display: block;
  margin: 0 12px 8px;
  padding: 0 4px;
  font: 400 11px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  text-align: center;
}

/* Feature #130 — bulk-apply selection action bar. The HOST (#aic-selbar-host)
   is a direct child of the scroll viewport (#ins-ai-body, overflow-y:auto) and
   carries `position: sticky; bottom:0`, so the bar floats at the viewport
   bottom and stays reachable while scrolling a long list — mirrors how sticky
   chrome behaves elsewhere. It's created only when ≥1 row is selected and
   removed otherwise, so it never occupies space on an empty selection. The
   inner .aic-selbar carries the visual chrome (matches the audit panel:
   --surface ground, 1px --border top rule, 12px padding rhythm). */
#aic-selbar-host {
  position: sticky;
  bottom: 0;
  z-index: 2;
}
.aic-selbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-top: 1px solid var(--border);
  background: var(--surface);
  /* lift it off the rows above with a faint upward shadow so the sticky bar
     reads as a layer, not an inline row. */
  box-shadow: 0 -2px 6px -4px rgba(0, 0, 0, 0.25);
}
.aic-selbar-count {
  font: 600 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text);
  white-space: nowrap;
}
.aic-selbar-toggle {
  background: transparent;
  border: 0;
  color: var(--text-dim);
  padding: 4px 8px;
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  cursor: pointer;
  border-radius: 4px;
  white-space: nowrap;
  transition: color var(--motion-duration) var(--motion-easing),
              background var(--motion-duration) var(--motion-easing);
}
.aic-selbar-toggle:hover,
.aic-selbar-toggle:focus-visible {
  color: var(--accent);
  background: var(--hover-soft);
}
.aic-selbar-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* Primary action — filled accent button, pushed to the right edge. */
.aic-selbar-apply {
  margin-left: auto;
  background: var(--accent);
  border: 0;
  color: var(--on-solid);
  padding: 7px 14px;
  font: 600 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  cursor: pointer;
  border-radius: 4px;
  white-space: nowrap;
  transition: background var(--motion-duration) var(--motion-easing),
              opacity var(--motion-duration) var(--motion-easing);
}
.aic-selbar-apply:hover,
.aic-selbar-apply:focus-visible {
  background: var(--accent-hover);
}
.aic-selbar-apply:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.aic-selbar-apply:disabled {
  opacity: 0.6;
  cursor: default;
}
/* Idle state (#130 follow-up): bar shown before any tick — a muted hint on the
   left, the Select-all affordance right-anchored where Apply normally sits, so
   bulk-select is always discoverable. */
.aic-selbar-hint {
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-faint);
  white-space: nowrap;
  margin-right: auto;
}
.aic-selbar-idle .aic-selbar-toggle {
  background: var(--hover-soft);
  color: var(--text);
  padding: 6px 12px;
}
.aic-selbar-idle .aic-selbar-toggle:hover,
.aic-selbar-idle .aic-selbar-toggle:focus-visible {
  background: var(--accent);
  color: var(--on-solid);
}

/* Step-through-only note (Iris bulk-destructive spec §2.5) — occupies the
   action-bar slot when the active Structure filter has rows but none are
   bulk-appliable (e.g. CHECK / check-folder). Quiet list chrome: mirrors the
   .aic-selbar ground (--surface, 1px --border top rule, 10px 12px padding,
   the faint upward shadow) so the note reads as the SAME layer the bar would
   be; the text uses the --text-dim ghost tone of .aic-ignored-filter-toggle. */
.aic-selbar-note {
  justify-content: flex-start;
}
.aic-selbar-note-text {
  font: 400 12px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  white-space: nowrap;
}

/* Sticky list header (Jeremy 2026-06-25) — wraps the chip strip + the
   ignored-filter strip so they PIN to the top of the #ins-ai-body scroll
   viewport while the proposal list scrolls. Before this the strips were direct
   children of #ins-ai-cleanup-body (whose `overflow:auto` made it the sticky
   containing block — a box that never scrolls, so sticky did nothing) and the
   filters scrolled off the pane. Wrapping the two strips in ONE sticky band
   also fixes the both-present case: two independently-sticky `top:0` strips
   would overlap; as one unit they stack correctly regardless of the chip
   strip's wrapped height. Sticky anchors to #ins-ai-body now that
   .ins-ai-cleanup-body's overflow was dropped. --surface ground keeps scrolled
   rows from showing through; z-index sits above row backgrounds. */
.aic-list-header {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--surface);
}

/* Brief-14 §F — Structure executive-summary chip strip. Sits directly
   above the Structure proposal list (Structure mode only). One chip per
   action type with its count; clicking filters the list to that action,
   clicking again clears. Proportioned to the audit-panel chrome: 12px
   horizontal padding (matches .aic-ignored-filter + .aic-load-more), 8/12
   vertical rhythm, 1px --border separator, --surface ground. */
/* Iris inspector-craft-spec D2 (2026-06-25): the strip is now caption-over-
   grid, not a wrapping flex. 12px all-round inset (was 8/12) reads calmer
   above the list (rule 3). The prefix caption sits on its own line; the chips
   live in .aic-chip-grid below it. */
.aic-chip-strip {
  display: block;
  padding: 12px;
  background: transparent;         /* the static summary card provides the fill + border */
}
/* The "{N} fixes" total is now a quiet block caption on its own line above
   the grid (Iris D1) — --text-dim, 400 11px, 8px below it before the grid.
   Subordinates the chips to the count they decompose (Tufte: label with the
   data). The trailing colon is dropped — a caption above a grid doesn't need
   it. */
.aic-chip-strip-prefix {
  /* Jeremy 2026-07-06: the caption is a SIBLING of the padded chip grid,
     so it sat at the card edge while "Naming check" above starts at the
     dock's 12px inset — give it the same 12px so the two lines align. */
  margin: 10px 12px 0;
  font: 400 11px/16px -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  color: var(--text-dim);
  letter-spacing: 0.02em;
}
.aic-chip-strip-prefix + .aic-chip-strip { padding-top: 8px; }   /* caption owns the 10px above; tighten below it */
/* The grid owns alignment: 2-up at default panel width, 4-across when wide.
   minmax(0,1fr) makes the columns equal + aligned and lets each chip's
   content stay left-packed inside its equal cell, so the left edges line up
   regardless of label width (the whole point — no more ragged wrap). */
/* Jeremy 2026-07-06 ("make them the same length and aligned"): equal-width
   grid, same construction as the kind chips above — every capsule fills
   its cell, labels left, counts right, columns aligned. */
.aic-chip-grid,
.aic-chip-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 6px;
}
.aic-chip-strip { padding: 12px; background: transparent; }
.aic-chip-strip .aic-chip,
.aic-chip-grid .aic-chip {
  width: 100%;
  justify-content: space-between;
}
.aic-chip .aic-chip-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; text-align: left; }
.aic-chip .aic-chip-count { font-variant-numeric: tabular-nums; }

/* Iris inspector-craft-spec D3+D5 (2026-06-25): the UNIFIED filter-chip
   grammar — shared by the Structure summary chips AND the Activity filter
   chips. Resting: transparent ground, a dot-coloured cue (not a filled slab),
   --text-dim label. Active: --accent inset ring + --hover-soft ground. One
   grammar, two panels (rule 10). The filled --action-pill-* slab is reserved
   for ROW identity pills; a FILTER chip carries colour as a cue (the dot),
   not a slab (Tufte: maximise data-ink ratio; rule 1 chrome defers).
   Structure uses data-active="true"; Activity uses .is-active — both listed
   so no JS rename is forced (zero churn). Net new tokens: 0. */
.aic-chip, .act-chip, .act-chip-who {
  display: inline-flex; align-items: center; gap: 8px;
  height: 28px; padding: 0 10px;
  border: 0; border-radius: var(--radius);
  background: transparent; color: var(--text-dim);
  font: 600 11px/28px -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  cursor: pointer; user-select: none;
  transition: background var(--motion-duration) var(--motion-easing),
              box-shadow var(--motion-duration) var(--motion-easing),
              opacity var(--motion-duration) var(--motion-easing);
}
/* AI-cleanup filter chips → colour-matched capsules (Jeremy redesign
   2026-06-27). The chip tint IS the action's row-pill colour, so the colour
   in the filter reads straight through to the row. Scoped to `.aic-chip` only,
   so the Activity panel's `.act-chip` keeps its dot-pill grammar untouched. */
.aic-chip {
  height: 24px; padding: 0 12px; gap: 4px;
  border-radius: var(--radius-pill);
}
.aic-chip[data-pill="rename"] { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.aic-chip[data-pill="move"]   { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.aic-chip[data-pill="merge"]  { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }
.aic-chip[data-pill="delete"] { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.aic-chip[data-pill="check"]  { background: var(--action-pill-check-bg);  color: var(--action-pill-check-fg); }
.aic-chip .aic-chip-dot   { display: none; }     /* the tinted slab carries the colour now */
/* Jeremy 2026-07-06 (final): the breach FILTER chips are neutral — colour
   belongs to the row pills they filter, not to the filter chrome. Quiet
   outline capsules, dim label; active = accent ring + soft ground. Wins
   over the data-pill slab tints at equal specificity (declared after). */
.aic-chip[data-aic-namecat] {
  /* Jeremy 2026-07-06: white capsules so they stand out from the toned
     panel fill (transparent read as part of the grey). */
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--text-dim);
}
.aic-chip[data-aic-namecat]:hover { color: var(--text); box-shadow: inset 0 0 0 1px var(--chip-bg-active); }
/* Sentence case everywhere on filter chips (P2.1: the base uppercase is
   gone; this override survives only for its color:inherit). */
.aic-chip[data-aic-namecat] .aic-chip-label { color: inherit; }
.aic-chip[data-aic-namecat][data-active="true"] {
  background: var(--cck-accent-soft);
  color: var(--cck-accent);
  box-shadow: inset 0 0 0 1.5px var(--cck-accent);
}
.aic-chip .aic-chip-label { color: inherit; }
.aic-chip .aic-chip-count { color: inherit; font-weight: 700; }
.aic-chip:hover:not([data-active="true"]) { box-shadow: inset 0 0 0 1px currentColor; }
.aic-chip[data-active="true"] { box-shadow: inset 0 0 0 1.5px currentColor; }

/* The 6px dot atom — shared by .aic-chip-dot and .act-chip-dot. Coloured per
   action via the data-pill attribute on the chip button. */
.aic-chip-dot, .act-chip-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.aic-chip[data-pill="rename"] .aic-chip-dot { background: var(--action-pill-warn-fg); }
.aic-chip[data-pill="move"]   .aic-chip-dot { background: var(--action-pill-info-fg); }
.aic-chip[data-pill="merge"]  .aic-chip-dot { background: var(--action-pill-merge-fg); }
.aic-chip[data-pill="delete"] .aic-chip-dot { background: var(--action-pill-danger-fg); }
.aic-chip[data-pill="check"]  .aic-chip-dot { background: var(--action-pill-check-fg); }
/* Label is a plain action token (no slab); count is right of it. P2.1 census
   §5: uppercase dropped — the approved audit mockup (mockup_audit-board.html)
   shows the kind chips sentence case ("Duplicates 7"), and the chip law is
   sentence case (DESIGN_JUDGEMENT). */
.aic-chip-label {
  color: var(--text);
}
.aic-chip-count { font-variant-numeric: tabular-nums; color: var(--text-dim); }

/* History (Activity) filter chips → colour-matched capsules, mirroring the
   AI-cleanup `.aic-chip` grammar (Jeremy redesign 2026-06-27). The data-pill
   tint reads straight through to the feed row pills; "All" (no data-pill) and
   the "Who" chips are neutral capsules. */
.act-chip {
  height: 24px; padding: 0 12px; gap: 4px;
  border-radius: var(--radius-pill);
}
.act-chip:not([data-pill]) { background: var(--hover-soft); color: var(--text); }
.act-chip[data-pill="rename"] { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.act-chip[data-pill="move"]   { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.act-chip[data-pill="delete"] { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.act-chip[data-pill="merge"]  { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }
.act-chip .act-chip-dot { display: none; }   /* the tinted capsule carries the colour now */
.act-chip:hover:not(.is-active) { box-shadow: inset 0 0 0 1px currentColor; }
.act-chip.is-active { box-shadow: inset 0 0 0 1.5px currentColor; }
.act-chip:not([data-pill]).is-active { box-shadow: inset 0 0 0 1.5px var(--text-dim); }
.act-chip-who {
  height: 24px; padding: 0 12px; border-radius: var(--radius-pill);
  background: var(--surface); border: 0.5px solid var(--border); color: var(--text);
}
.act-chip-who:hover:not(.is-active) { box-shadow: inset 0 0 0 1px var(--border-dark); }
.act-chip-who.is-active { box-shadow: inset 0 0 0 1.5px var(--accent); }
.aic-chip:focus-visible, .act-chip:focus-visible, .act-chip-who:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.aic-chip-strip[data-has-active] .aic-chip:not([data-active="true"]),
.act-chip-strip[data-has-active] .act-chip:not(.is-active) { opacity: 0.55; }

/* ── ◂ • ▸  inspector-width stepper (replaces #ins-toggle) ──
   Iris inspector-rail-cycle spec §1.3 + §2. Batch A: rendered but INERT —
   click/cycle/picker wiring lands in Batches B & C. */
.ins-width-stepper {
  display: flex; flex-direction: column; align-items: center;
  gap: 2px;
  padding: 4px 0 8px;          /* 4 top, 8 bottom — 4/8 grid */
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);   /* divides stepper from tab list */
}
.ins-step,
.ins-dot {
  width: 32px; height: 24px;   /* hit target — clears the 24px min comfortably with the gap */
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: none; background: transparent; cursor: pointer;
  border-radius: 6px;
  color: var(--text-faint);    /* idle — matches the old #ins-toggle rest colour */
  transition: color var(--motion-micro) var(--inspector-ease),
              background-color var(--motion-micro) var(--inspector-ease);
}
.ins-step .lucide-icon { width: 16px; height: 16px; }

/* hover / focus — reuse the rail-tab register */
.ins-step:hover,
.ins-dot:hover            { color: var(--text); background: var(--surface-3); }
.ins-step:focus-visible,
.ins-dot:focus-visible    { outline: 2px solid var(--accent); outline-offset: -2px; }

/* the DOT — 6px filled disc that reads as a menu opener */
.ins-dot { height: 20px; }
.ins-dot__disc {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; display: block;
}
/* open state — dot goes accent + soft fill so it's clearly "the menu is open" */
.ins-dot[aria-expanded="true"] {
  color: var(--accent);
  background: var(--hover-soft);
}

/* DISABLED END — dim in place + grayscale + inert (ratified rule b).
   NEVER hide; the other arrow stays anchored, no reflow. */
.ins-step[aria-disabled="true"] {
  opacity: 0.38;
  filter: grayscale(1);
  pointer-events: none;
}

/* ── LAYOUT PICKER popover (dot → macOS tiling menu) ──
   Iris inspector-rail-cycle spec §3. Card + 2×2 window-glyph grid; inspector
   region filled / panes outlined (macOS "filled = focus"). Reuses the menu
   token family — zero new tokens. */
.layout-pop {
  position: fixed; z-index: 400;
  width: 188px;                       /* 8 + 82 + 8 + 82 + 8 */
  padding: 8px;
  background: var(--menu-bg);
  border: 1px solid var(--menu-border);
  border-radius: 10px;
  box-shadow: var(--elev-2);          /* soft, NOT the heavy --shadow */
  transform-origin: top right;        /* grows from the dot side */
}
.layout-pop[hidden] { display: none; }
.layout-pop:not([hidden]) { animation: layoutPopIn var(--motion-micro) var(--inspector-ease); }
@keyframes layoutPopIn {
  from { opacity: 0; transform: scale(.96); }
  to   { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .layout-pop:not([hidden]) { animation: none; }
}
.layout-pop__hd {
  font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-faint);
  padding: 4px 6px 8px;               /* 4/6/8 grid */
}

.layout-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

.layout-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 8px 6px 7px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: transparent; cursor: pointer;
  transition: background-color var(--motion-micro) var(--inspector-ease),
              box-shadow var(--motion-micro) var(--inspector-ease);
}
.layout-tile:hover         { background: var(--surface-3); }
.layout-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.layout-tile__lbl {
  font-size: 11px; line-height: 1.2; color: var(--text-dim);
  text-align: center;
}

/* CURRENT-STATE tile — accent ring + soft accent fill (macOS "this one is active") */
.layout-tile[aria-current="true"] {
  background: var(--hover-soft);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}
.layout-tile[aria-current="true"] .layout-tile__lbl {
  color: var(--text); font-weight: 600;
}

/* The window glyph — 56×38 rounded-rect window icon split into L|R|I columns.
   Inspector region filled (solid), panes outlined (transparent + 1.5px dividers). */
.winicon { width: 56px; height: 38px; display: block;
           shape-rendering: geometricPrecision; }   /* crisp 1.5px stroke at 1× */
.winicon rect.frame { fill: none; stroke: var(--text-dim); stroke-width: 1.5; }
.winicon .divider   { stroke: var(--text-dim); stroke-width: 1.5; }
.winicon .insfill   { fill: var(--text-dim); opacity: .85; }
/* current tile recolours the glyph to accent so the highlight is one gesture */
.layout-tile[aria-current="true"] .winicon rect.frame { stroke: var(--accent); }
.layout-tile[aria-current="true"] .winicon .divider   { stroke: var(--accent); }
.layout-tile[aria-current="true"] .winicon .insfill   { fill: var(--accent); opacity: .9; }

/* Resizer — 4px invisible hit-zone hugging the left edge of the content area,
   with an always-rendered 1px divider line and a 200ms-delayed hover-brighten. */
#inspector-resizer {
  position: absolute; left: 44px; top: 0; bottom: 0;
  width: 4px; cursor: col-resize;
  z-index: 1;
}
#inspector-resizer::after {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0;
  width: 1px; background: transparent;   /* invisible until hovered (Jeremy 2026-07-05: the permanent line read as a stray stroke) */
  transition: background var(--motion-micro) var(--inspector-ease) 200ms;
}
#inspector-resizer:hover::after,
#inspector[data-resizing="1"] #inspector-resizer::after {
  background: var(--border-strong);
  transition-delay: 0ms;
}
#inspector[data-resizing="1"] #inspector-resizer::after {
  background: var(--accent); width: 2px;
}
#inspector[data-state="collapsed"] #inspector-resizer { display: none; }

/* Content area — fills the remaining width to the right of the rail */
#inspector-content {
  flex: 1;
  display: flex; flex-direction: column;
  background: var(--surface);
  overflow: hidden;
  position: relative;
}
#inspector[data-state="collapsed"] #inspector-content { display: none; }

.ins-panel {
  flex: 1;
  display: flex; flex-direction: column;
  min-height: 0;
  opacity: 0;
  transition: opacity var(--motion-micro) linear;
  pointer-events: none;
}
.ins-panel:not([hidden]) {
  opacity: 1;
  pointer-events: auto;
}
.ins-panel[hidden] {
  display: none !important;          /* takes panel out of flow when hidden */
}

.ins-header {
  height: 44px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.ins-header h3 {
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
  margin: 0; color: var(--text);
}
.ins-header-actions { display: flex; align-items: center; gap: 6px; }
.ins-select {
  font-size: 12px; padding: 4px 8px; border-radius: 4px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text);
}
.btn-tiny {
  font-size: 11px; padding: 3px 8px; height: 24px;
  border-radius: 4px;
  display: inline-flex; align-items: center; gap: 4px;
}

.ins-body {
  flex: 1; overflow-y: auto; min-height: 0;
}

/* Subtabs inside a panel (Duplicates has Groups / Recoverable space) */
.ins-subtabs {
  display: flex; gap: 0;
  border-bottom: 1px solid var(--border);
  padding: 0 16px;
  background: var(--surface);
  position: sticky; top: 0; z-index: 1;
}
.ins-subtab {
  padding: 10px 12px 9px;
  background: transparent; border: none; cursor: pointer;
  font-size: 12px; font-weight: 500; color: var(--text-dim);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.ins-subtab:hover { color: var(--text); }
.ins-subtab.active { color: var(--text); border-bottom-color: var(--accent); }
.ins-subpanel { padding: 12px 16px; }

/* Empty states — Iris's spec: 20px glyph + 13px title + 11px sub */
/* .ins-empty base/glyph/title/sub carried by the shared empty-state grammar
   (P2.1; sub 11px → the 12px ramp). Only the pane-fill min-height stays. */
.ins-empty { min-height: 200px; }

/* ── File preview tab (read-only in-app viewer, 2026-06-20) ───────────
   Header (name + Open in SharePoint) stays fixed; the stage below it fills
   and scrolls. Office docs arrive pre-converted to PDF (see renderPreview),
   so the frame just renders a PDF blob — no SharePoint iframe embedding. */
.ins-preview-body { display: flex; flex-direction: column; overflow: hidden; padding: 0; }
/* No static .ins-header — the filename IS the title (Iris P1-1). This .ins-preview-head
   is the panel header: 16px gutter like .ins-header, but two lines (name + meta)
   so it uses 8px vertical padding rather than .ins-header's fixed 44px. */
.ins-preview-head {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px; flex-shrink: 0;
  border-bottom: 1px solid var(--border); background: var(--surface);
}
.ins-preview-meta { min-width: 0; flex: 1; }
.ins-preview-name {
  font-size: 12px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ins-preview-sub { font-size: 11px; color: var(--text-dim); margin-top: 2px; font-variant-numeric: tabular-nums; }
.ins-preview-head [data-preview-open] { flex-shrink: 0; }
.ins-preview-close { flex-shrink: 0; }   /* close ×: snaps the layout back + collapses the inspector */
/* File preview v2 — unified zoom control bar (approved plan 2026-06-27). */
.ins-preview-bar {
  display: flex; align-items: center; gap: 4px; flex-shrink: 0;
  padding: 5px 10px;
  background: var(--pane-chrome-bg); border-bottom: 1px solid var(--border);
}
.ins-preview-zbtn {
  display: inline-flex; align-items: center; gap: 5px;
  height: 26px; padding: 0 9px;
  border: 1px solid transparent; border-radius: var(--radius-pill);
  background: transparent; color: var(--text-dim);
  font-size: 12px; cursor: pointer;
  flex-shrink: 0; white-space: nowrap;   /* never clip the Fit page / Fit width labels */
}
.ins-preview-zbtn span { white-space: nowrap; }
.ins-preview-zbtn:hover { background: var(--hover-soft); color: var(--text); }
.ins-preview-zbtn.on { background: var(--hover-soft); color: var(--accent); border-color: var(--border); }
.ins-preview-zbtn-icon { padding: 0 7px; }
.ins-preview-zbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ins-preview-bar-sep { width: 1px; height: 16px; background: var(--border); margin: 0 4px; }
/* Pan mode: grab cursor + drag-to-scroll on the stage. */
/* AutoCAD (.dxf/.dwg) preview: the rendered SVG fills the wrap; the wrap grows
   past 100% when zoomed so the stage scrolls (pan). White backdrop so the
   typically-black drawing lines read clearly. */
.ins-cad-wrap { width: 100%; height: 100%; background-color: var(--media-paper); position: relative; }
.ins-cad-wrap svg { display: block; width: 100%; height: 100%; }
.ins-cad-canvas { display: block; width: 100%; height: 100%; }
/* Dark backdrop: invert the drawing so black lines read white (AutoCAD model
   space). hue-rotate keeps coloured lines roughly true through the invert. */
.ins-cad-wrap.ins-cad-dark { background-color: var(--media-stage-dark); }
.ins-cad-wrap.ins-cad-dark svg,
.ins-cad-wrap.ins-cad-dark .ins-cad-canvas { filter: invert(1) hue-rotate(180deg); }
/* Layers list-box (toggled by the Layers button). */
.ins-cad-layers {
  position: absolute; top: 8px; right: 8px; z-index: 5; max-height: 60%;
  min-width: 150px; overflow: auto; padding: 6px;
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow);
  font-size: 12px;
}
.ins-cad-layers-head { font-weight: 600; color: var(--text-dim); padding: 2px 4px 6px; }
/* Measure dimension labels (DOM overlay, positioned in screen space). */
.ins-cad-dims { position: absolute; inset: 0; pointer-events: none; z-index: 4; overflow: hidden; }
.ins-cad-dim {
  position: absolute; transform: translate(-50%, -140%); transform-origin: center;
  background: var(--surface); border: 1px solid var(--cad-dim); color: var(--text);
  font: 11px/1 ui-monospace, Menlo, Consolas, monospace; padding: 2px 5px;
  border-radius: 4px; white-space: nowrap; box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  pointer-events: auto; cursor: context-menu;   /* right-click a label to delete it */
}
.ins-cad-dim-live { opacity: 0.9; pointer-events: none; }
/* "Text box" off: just the number, no rectangle. */
.ins-cad-dims-nobox .ins-cad-dim { background: none; border: none; box-shadow: none; color: var(--cad-dim); padding: 0; }
/* Measure options popover. */
.ins-cad-mopts {
  position: absolute; top: 8px; left: 8px; z-index: 6;
  display: flex; flex-direction: column; gap: 5px; padding: 8px 10px;
  background: color-mix(in srgb, var(--surface) 95%, transparent);
  border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow);
  font-size: 12px; color: var(--text);
}
.ins-cad-mopts label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.ins-cad-mopts-btns { display: flex; gap: 6px; margin-top: 2px; }
.ins-cad-mopts-btns button {
  font: inherit; padding: 3px 8px; border: 1px solid var(--border); border-radius: 5px;
  background: var(--surface-2); color: var(--text); cursor: pointer;
}
.ins-cad-mopts-btns button:hover { background: var(--hover-soft); }
.ins-cad-mopts-hint { color: var(--text-faint); font-size: 10.5px; max-width: 180px; }
/* Zoom-speed selector in the CAD toolbar. */
.ins-cad-speed {
  flex-shrink: 0; font: 11px/1 inherit; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 5px; cursor: pointer;
}
.ins-cad-layer-row { display: flex; align-items: center; gap: 6px; padding: 3px 4px; cursor: pointer; white-space: nowrap; }
.ins-cad-layer-row:hover { background: var(--hover-soft); border-radius: 4px; }
/* Xref groups in the layers panel. */
.ins-cad-xref-head { display: flex; align-items: center; gap: 2px; }
.ins-cad-xref-head .ins-cad-layer-row { flex: 1 1 auto; min-width: 0; }
.ins-cad-xref-toggle { background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 0 2px; font-size: 10px; flex-shrink: 0; }
.ins-cad-xref-name { overflow: hidden; text-overflow: ellipsis; max-width: 150px; }
.ins-cad-xref-count { color: var(--text-faint); font-size: 10px; margin-left: auto; }
.ins-cad-xref-subs { padding-left: 16px; }
.ins-cad-xref-group.collapsed .ins-cad-xref-subs { display: none; }
/* Optional reference grid (background-color stays, so it combines with dark). */
.ins-cad-wrap.ins-cad-grid {
  background-image:
    linear-gradient(to right, rgba(128,128,128,0.22) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(128,128,128,0.22) 1px, transparent 1px);
  background-size: 26px 26px;
}
.ins-preview-stage:has(.ins-cad-wrap) { position: relative; overflow: hidden; }   /* anchor readout + clip the transform */
/* Zoom-window rubber-band rectangle (screen-space overlay). */
.ins-cad-rubber {
  position: absolute; z-index: 4; pointer-events: none;
  border: 1px dashed var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
/* CAD coordinate / units readout — pinned bottom-left of the stage. */
.ins-cad-readout {
  position: absolute; left: 8px; bottom: 8px; z-index: 3;
  display: flex; gap: 12px; align-items: center;
  padding: 3px 9px; border-radius: 6px;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  border: 1px solid var(--border);
  font: 11px/1.4 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: var(--text-dim); pointer-events: none; white-space: nowrap;
}
.ins-cad-readout .ins-cad-coord { color: var(--text); min-width: 150px; }
.ins-cad-readout .ins-cad-units { color: var(--text-faint); }
.ins-preview-stage.ins-pan-on { cursor: grab; }
.ins-preview-stage.ins-pan-on.ins-pan-grabbing { cursor: grabbing; }
.ins-preview-stage.ins-pan-on * { cursor: inherit; }
.ins-preview-zpct {
  min-width: 46px; flex-shrink: 0; text-align: center; white-space: nowrap;
  font-size: 12px; font-weight: 600; color: var(--text);
  font-variant-numeric: tabular-nums;
}
/* Video: the native controls own playback, so the numeric zoom is disabled. */
.ins-preview-bar[data-type="video"] .ins-preview-zbtn-icon,
.ins-preview-bar[data-type="video"] .ins-preview-zpct { opacity: 0.4; pointer-events: none; }
.ins-preview-video { max-width: 100%; max-height: 100%; display: block; margin: auto; background: var(--media-ink); }
/* Email (.eml/.msg): header block above a sandboxed body frame (Jeremy 2026-06-27). */
.ins-preview-stage.ins-email {
  flex-direction: column; justify-content: flex-start; align-items: stretch;
  overflow: hidden; background: var(--surface);
}
.ins-preview-stage.ins-email > * { margin: 0; }
.ins-email-head {
  flex: 0 0 auto; padding: 12px 14px;
  border-bottom: 1px solid var(--border); background: var(--pane-chrome-bg);
}
.ins-email-subject { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 8px; line-height: 1.3; }
.ins-email-row { display: flex; gap: 8px; font-size: 12px; line-height: 1.5; }
.ins-email-label { flex: 0 0 44px; color: var(--text-faint); }
.ins-email-val { flex: 1 1 auto; color: var(--text-dim); min-width: 0; word-break: break-word; }
.ins-email-attach { margin-top: 8px; font-size: 11px; color: var(--text-dim); display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.ins-email-att-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--text); text-decoration: none; font-size: 11px;
  max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ins-email-att-chip:hover { border-color: var(--accent); color: var(--accent); }
.ins-email-att-size { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.ins-email-frame { flex: 1 1 auto; width: 100%; border: 0; background: var(--media-paper); }
/* Spreadsheet (.xlsx/.csv/…) — native scrollable table with optional sheet tabs. */
.ins-preview-stage.ins-sheet {
  flex-direction: column; justify-content: flex-start; align-items: stretch;
  overflow: hidden; background: var(--surface);
}
.ins-preview-stage.ins-sheet > * { margin: 0; }
.ins-sheet-tabs {
  flex: 0 0 auto; display: flex; gap: 2px; padding: 4px 8px 0; overflow-x: auto;
  background: var(--pane-chrome-bg); border-bottom: 1px solid var(--border);
}
.ins-sheet-tab {
  flex: 0 0 auto; padding: 5px 12px; border: 1px solid transparent; border-bottom: none;
  border-radius: 6px 6px 0 0; background: transparent; color: var(--text-dim);
  font-size: 12px; cursor: pointer; white-space: nowrap;
}
.ins-sheet-tab:hover { color: var(--text); }
.ins-sheet-tab.active { background: var(--surface); color: var(--text); border-color: var(--border); }
/* Excel-style formula bar — selected cell ref + its value/formula. */
.ins-sheet-fxbar {
  flex: 0 0 auto; display: flex; align-items: center; gap: 0;
  border-bottom: 1px solid var(--border); background: var(--surface);
}
.ins-sheet-ref {
  flex: 0 0 auto; min-width: 56px; text-align: center;
  padding: 4px 8px; font: 12px/1 ui-monospace, Menlo, Consolas, monospace;
  color: var(--text-dim); border-right: 1px solid var(--border);
}
.ins-sheet-fxlabel { flex: 0 0 auto; padding: 0 10px; color: var(--text-faint); font-style: italic; font-size: 13px; }
.ins-sheet-fx {
  flex: 1 1 auto; min-width: 0; border: none; background: transparent;
  padding: 5px 8px; font: 13px/1.3 ui-monospace, Menlo, Consolas, monospace;
  color: var(--text); outline: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ins-sheet-fx:empty::before { content: attr(data-placeholder); color: var(--text-faint); }
.ins-sheet-table td.ins-sheet-sel { outline: 1.5px solid var(--accent); outline-offset: -1.5px; }
.ins-sheet-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; }
.ins-sheet-zoom { display: inline-block; min-width: 100%; }
/* Excel semantics (Jeremy 2026-07-08): column widths come from the WORKBOOK
   and never re-flow with the window — fixed layout, content clips like Excel. */
.ins-sheet-table { border-collapse: collapse; font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; table-layout: fixed; width: max-content; }
.ins-sheet-canvas { position: relative; width: max-content; }
.ins-sheet-img { position: absolute; z-index: 3; pointer-events: none; }
.ins-sheet-afbtn { float: right; margin-left: 4px; color: var(--text-faint); font-size: 9px; line-height: inherit; }
.ins-sheet-table td {
  border: 1px solid var(--border); padding: 3px 8px; white-space: nowrap; overflow: hidden;
  max-width: 360px; overflow: hidden; text-overflow: ellipsis;
}
/* Excel-style frame: column letters (A,B,C) across the top, row numbers (1,2,3)
   down the left — both grey, sticky, like a real spreadsheet. (Jeremy 2026-06-27.) */
.ins-sheet-gutter-col { width: 44px; }
.ins-sheet-table th {
  background: var(--pane-chrome-bg); color: var(--text-dim);
  border: 1px solid var(--border); font-weight: 600; font-size: 11px;
  text-align: center; padding: 2px 6px; user-select: none;
}
.ins-sheet-table .ins-sheet-colhdr th { position: sticky; top: 0; z-index: 2; }
.ins-sheet-table .ins-sheet-rownum { position: sticky; left: 0; z-index: 1; text-align: center; }
.ins-sheet-table .ins-sheet-corner { position: sticky; top: 0; left: 0; z-index: 3; }
/* Styled .xlsx: keep a light grid; inline cell styles supply colours/bold/etc. */
.ins-sheet-table.ins-sheet-styled { table-layout: fixed; }
.ins-sheet-table.ins-sheet-styled td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ins-sheet-more { padding: 8px 10px; font-size: 11px; color: var(--text-dim); }
/* Empty / folder state owns the whole panel (no static header above it). */
.ins-preview-body > .ins-empty { flex: 1; }
.ins-preview-stage {
  flex: 1; min-height: 0; overflow: auto;
  /* A12 #14 (2026-06-27): a scrollable flex container with align-items:center
     clips/mis-aligns content taller than the stage (it looked bottom-aligned).
     Center via the child's auto margins instead, which scrolls correctly. */
  display: flex; justify-content: center;
  background: var(--surface-2);
}
.ins-preview-stage > * { margin: auto; }
.ins-preview-loading { flex-direction: column; gap: 8px; color: var(--text-dim); font-size: 12px; }
/* var(--surface), not #fff: in dark mode this matches the stage so there's no
   white flash before the PDF paints; the PDF page itself still renders white. */
.ins-preview-frame { width: 100%; height: 100%; border: 0; background: var(--surface); }
/* Office edit toggle bar (Word/Excel/PowerPoint → Office for the web). */
.ins-preview-stage.has-office-bar { display: flex; flex-direction: column; }
.ins-preview-stage.has-office-bar .ins-preview-frame { flex: 1 1 auto; }
.ins-office-bar {
  flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
  padding: 5px 10px; border-bottom: 1px solid var(--border); background: var(--surface);
  font-size: 12px;
}
.ins-office-mode { color: var(--text-dim); }
.ins-office-edit {
  margin-left: auto; display: inline-flex; align-items: center; gap: 5px;
  font: inherit; padding: 4px 10px; border: 1px solid var(--accent); border-radius: 6px;
  background: var(--accent); color: var(--cck-accent-on); cursor: pointer;
}
.ins-office-edit:hover { filter: brightness(1.05); }
.ins-office-edit:disabled { opacity: 0.6; cursor: default; }
.ins-preview-img   { max-width: 100%; max-height: 100%; object-fit: contain; display: block; margin: auto; }
.ins-preview-text  {
  width: 100%; height: 100%; margin: 0; padding: 12px 14px;
  align-self: stretch; box-sizing: border-box;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; line-height: 1.55; color: var(--text);
  white-space: pre-wrap; word-break: break-word; overflow: auto; background: var(--surface);
}
/* Fallback/error states share the .ins-empty family rhythm (48px 24px, 20px glyph). */
.ins-preview-fallback { flex-direction: column; text-align: center; padding: 48px 24px; gap: 4px; color: var(--text-dim); }
.ins-preview-fallback .lucide-icon { color: var(--text-faint); margin-bottom: 12px; }
.ins-preview-fallback-title { font-size: 13px; font-weight: 600; color: var(--text); margin: 0; }
.ins-preview-fallback-sub   { font-size: 11px; color: var(--text-dim); margin: 0; line-height: 1.5; max-width: 260px; }

/* Chat empty-state: tighter padding than the default ins-empty so the
   placeholder doesn't push the chat composer off-screen on short panels. */
.ins-chat-empty { min-height: 0; padding: 24px 16px; }

/* ── Smart Move drop zone ── */
#smart-move-dropzone {
  margin: 16px;
  border: 2px dashed var(--border-strong);
  border-radius: 8px;
  padding: 32px 16px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--surface);
  transition: background var(--motion-micro) var(--inspector-ease), border-color var(--motion-micro) var(--inspector-ease);
  cursor: pointer;                /* default: clickable target, no green +  */
  text-align: center;
}
#smart-move-dropzone:hover { background: var(--surface-2); }
#smart-move-dropzone.drag-over {
  background: rgba(10, 109, 194, 0.06);
  border-color: var(--accent);
  border-style: solid;
  cursor: copy;                   /* green + only while a drag is in-flight */
}
#smart-move-dropzone .lucide-icon { color: var(--text-faint); margin-bottom: 10px; }
.ins-dz-title { font-size: 13px; font-weight: 600; color: var(--text); margin: 0 0 4px; }
.ins-dz-sub   { font-size: 11px; color: var(--text-dim); margin: 0; line-height: 1.5; max-width: 280px; }

/* Smart Move queue */
#smart-move-queue {
  padding: 12px 16px 0;
}
.sm-queue-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
  font-size: 11px; color: var(--text-dim);
}
#sm-queue-rows { display: flex; flex-direction: column; gap: 4px; }
.sm-row {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  align-items: start; gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  font-size: 12px;
}
.sm-row.sm-row-applied { opacity: 0.55; }
.sm-row.sm-row-failed  { border-color: var(--danger-soft-border); background: var(--danger-soft-bg); }
.sm-row-dot {
  margin-top: 4px;
}
.confidence-dot {
  width: 8px; height: 8px; border-radius: 50%;
  display: inline-block;
  transition: background var(--motion-duration) var(--inspector-ease), box-shadow var(--motion-duration) var(--inspector-ease);
}
.confidence-dot[data-band="high"]   { background: var(--ok); }
.confidence-dot[data-band="medium"] { background: var(--warn); }
.confidence-dot[data-band="low"] {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--text-faint);
  border-radius: 50%;
  /* dashed-ring effect via stroked SVG-like approach using box-shadow doesn't
     animate to a fill — when band flips to medium/high the shadow vanishes. */
}
.sm-row-main { min-width: 0; }
.sm-row-name {
  font-size: 12px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  margin-bottom: 2px;
}
.sm-row-arrow {
  display: inline-block; color: var(--text-faint); margin: 0 4px;
}
.sm-row-suggest {
  font-size: 11px; color: var(--text-dim);
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px;
}
.sm-row-suggest code {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 10.5px; padding: 1px 5px;
  background: var(--surface-2); border-radius: 3px;
}
.sm-row-path { color: var(--text-dim); word-break: break-all; }
.sm-row-rationale {
  font-size: 10.5px; color: var(--text-faint); margin-top: 4px; font-style: italic;
}
.sm-row-actions {
  display: flex; align-items: center; gap: 4px;
  flex-shrink: 0;
}
.sm-row-actions button {
  background: transparent; border: 1px solid transparent;
  border-radius: 4px; padding: 4px 6px;
  font-size: 11px; cursor: pointer; color: var(--text-dim);
}
.sm-row-actions button:hover { background: var(--surface-2); color: var(--text); }
.sm-row-actions .btn-apply { background: var(--accent); color: var(--on-solid); border-color: var(--accent); padding: 4px 10px; font-weight: 500; }
.sm-row-actions .btn-apply:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.sm-row-actions .btn-apply:disabled { opacity: 0.5; cursor: not-allowed; }

/* Single Smart Move card (right-click → Smart Move on one file) */
#smart-move-single { padding: 16px; }
.sm-single-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 16px;
  background: var(--surface);
  display: flex; flex-direction: column; gap: 12px;
}
.sm-single-source {
  font-size: 11px; color: var(--text-dim);
  display: flex; align-items: center; gap: 6px;
}
.sm-single-source code { font-size: 11px; padding: 1px 6px; background: var(--surface-2); border-radius: 3px; font-family: 'SF Mono', Consolas, monospace; }
.sm-single-section {
  display: flex; flex-direction: column; gap: 4px;
}
.sm-single-label {
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-faint);
}
.sm-single-value {
  font-size: 13px; font-weight: 500; color: var(--text);
  padding: 8px 10px; border-radius: 6px; background: var(--surface-2);
}
.sm-single-edit {
  width: 100%;
  font-size: 13px; font-weight: 500; color: var(--text);
  padding: 8px 10px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--surface);
}
.sm-single-edit:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }
.sm-single-meta {
  font-size: 11px; color: var(--text-dim); line-height: 1.5;
}
.sm-single-confidence {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text-dim);
}
.sm-single-actions {
  display: flex; gap: 8px; align-items: center;
  padding-top: 4px; border-top: 1px solid var(--border); margin-top: 4px;
}
.sm-single-actions .btn-primary { flex: 1; height: 36px; font-weight: 500; }
.sm-split-caret {
  position: relative;
}
.sm-split-caret-menu {
  position: absolute; right: 0; top: calc(100% + 4px);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.10);
  min-width: 180px; z-index: 10;
  display: none;
}
.sm-split-caret-menu.open { display: block; }
.sm-split-caret-menu button {
  width: 100%; text-align: left;
  padding: 8px 12px; background: transparent; border: none;
  font-size: 12px; color: var(--text); cursor: pointer;
}
.sm-split-caret-menu button:hover { background: var(--surface-2); }

/* Chat divider inside AI tab */
.sm-chat-divider {
  display: flex; align-items: center; gap: 10px;
  padding: 20px 16px 12px;
  font-size: 11px; color: var(--text-faint);
}
.sm-chat-divider::before, .sm-chat-divider::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}
.ins-chat {
  flex: 1; min-height: 100px; max-height: 320px;
  overflow-y: auto;
  padding: 8px 16px;
  display: flex; flex-direction: column; gap: 8px;
}
/* Chat input area — Claude-style: textarea spans full width with the send
   button positioned at the bottom-right corner INSIDE the input box. Right
   padding on the textarea keeps the user's text from running under the
   button. Button is a perfect 32×32 square. */
.ins-chat-form {
  flex-shrink: 0;
  /* Full-bleed top line; the gap between line and input EQUALS the side
     gutter (Jeremy 2026-07-05) — one rhythm in both axes. */
  padding: max(var(--railpad, 0px), 12px) max(var(--railpad, 0px), 12px) 12px;
  margin: 0 calc(var(--railpad, 0px) * -1) calc(var(--railpad, 0px) * -1);
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.ins-chat-input-wrap {
  position: relative;
}
.ins-chat-send {
  position: absolute;
  right: 8px; bottom: 8px;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  background: var(--accent); color: var(--cck-accent-on);
  border: none; border-radius: 6px;
  cursor: pointer;
  transition: background var(--motion-micro);
}
.ins-chat-send:hover    { background: var(--accent-hover); }
.ins-chat-send:disabled { background: var(--text-faint); cursor: not-allowed; }

/* Chat-header controls — model picker + web-search toggle + clear button.
   D-19 Phase 1 v2 Day 4 (batch 76): the .ins-chat-header-controls wrapper
   is gone — these controls now live directly inside the Chat rail tab's
   <header class="ins-header ins-header-actions">. The .ins-chat-model and
   .ins-chat-icon-btn rules below still apply to the same elements via
   element-level selectors. */
.ins-chat-model {
  height: 26px; padding: 0 8px;
  font-size: 11px; font-family: inherit;
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text);
  cursor: pointer;
}
.ins-chat-model:hover { border-color: var(--accent); }
.ins-chat-icon-btn {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: 4px;
  color: var(--text-dim); cursor: pointer;
  transition: background var(--motion-micro), color var(--motion-micro), border-color var(--motion-micro);
}
.ins-chat-icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.ins-chat-icon-btn.on,
.ins-chat-icon-btn[aria-pressed="true"] {
  background: var(--accent); color: var(--cck-accent-on); border-color: var(--accent);
}

/* ── Assistant panel: merged Smart Move + Chat (Jeremy 2026-06-27) ──────────
   Body is a flex column: Smart Move (fixed top) · chat history (fills/scrolls)
   · form (fixed bottom). */
.ins-assistant-body { --railpad: 0px; display: flex; flex-direction: column; min-height: 0; padding: 0; }
/* A13 (Jeremy 2026-06-27): the chat lives in its own bounded section BELOW Smart
   Move. .asst-chat is the flex child that takes the remaining height; the history
   inside it is the actual scroll region (min-height:0 so it can shrink and scroll
   rather than overflowing up into Smart Move). A thin gap above visually
   separates the two sections. */
.asst-chat {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  padding: 0 12px 0;               /* the console's own bottom margin provides the 12px gap */
}
.asst-chat .asst-chat-head {
  flex: 0 0 auto;
  margin-bottom: 6px;
}
.ins-assistant-body .ins-chat {
  max-height: none;
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto;                /* chat scrolls within its own region, underneath Smart Move */
}
.asst-smartmove {
  scrollbar-width: none;           /* the track drew a line down the rail's right edge (Jeremy 2026-07-05) */
  /* Cap the Smart Move section so a long queue scrolls WITHIN it rather than
     eating the chat's space (Jeremy 2026-06-27) — chat always keeps ≥half. */
  flex: 0 1 auto;
  max-height: 50%;
  overflow-y: auto;
  /* No TOP padding: the sticky head provides its own top spacing and an opaque
     background flush to y=0. With top padding here, that 12px band was
     transparent and scrolled rows showed through ABOVE the SMART MOVE title
     (Jeremy 2026-06-27). Horizontal + bottom padding stay. */
  padding: 0 12px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-fill);
}
/* Keep the section label + clear pinned while the cards scroll. Sits FLUSH at
   the top (no negative top margin) with an opaque background so nothing can
   scroll through above it. */
.asst-smartmove .asst-section-head {
  position: sticky; top: 0; z-index: 1;
  background: var(--panel-fill);
  margin: 0 -12px 8px; padding: 12px 12px 8px;
}
.asst-section-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
.asst-section-label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-dim);
}
/* The Smart Move clear cross only appears while there's a queue to clear; the
   top header clear only appears once the chat has messages — so neither is ever
   an inert cross (Jeremy 2026-06-27). */
.asst-section-clear { display: none; }
.asst-smartmove:has(#smart-move-queue:not([hidden])) .asst-section-clear,
.asst-smartmove:has(#smart-move-single:not([hidden])) .asst-section-clear { display: inline-flex; }
#ins-chat-clear { display: none; }
.ins-panel:has(#ins-chat-history .ins-chat-msg) #ins-chat-clear { display: inline-flex; }
/* Controls UNDER the chat input: model · web · (spacer) · Send. */
.ins-chat-controls { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
/* Send becomes a labelled pill at the row's right (was an absolute icon inside
   the input box). */
.ins-chat-controls .ins-chat-send {
  position: static; width: auto; height: 30px; margin-left: auto;
  padding: 0 14px; gap: 5px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600;
}
/* The send button no longer lives inside the input, so the textarea reclaims its
   right padding. */
.ins-assistant-body .ins-chat-form textarea { padding-right: 12px; }

/* Rail: the Assistant (chat) tab keeps the chat glyph + a small accent sparkle. */
.ins-tab-assistant { position: relative; }
.ins-tab-spark {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -58%);   /* sit inside the bubble body, above the tail */
  color: var(--accent); pointer-events: none;
}
.ins-tab-spark .lucide-icon { width: 8px; height: 8px; }

/* Pin chip status decorations */
.ins-chat-pin-chip-loading    { opacity: 0.7; }
.ins-chat-pin-chip-ready      { border-color: var(--ok); }
.ins-chat-pin-chip-ready      .lucide-icon { color: var(--ok); }
.ins-chat-pin-chip-too_large,
.ins-chat-pin-chip-unsupported,
.ins-chat-pin-chip-failed     { border-color: var(--warn); }

/* Pinned-files strip above the chat input — appears when the user has
   right-clicked "Pin to AI chat" or dragged a tree row onto the chat area.
   Two-row layout: header (label + Clear) on top, chips wrapping below. */
.ins-chat-pinned {
  flex-shrink: 0;
  padding: 8px 16px;
  background: linear-gradient(180deg, var(--ai-panel-bg) 0%, var(--hover-soft-tree) 100%);
  border-top: 1px solid var(--ai-panel-border);
  font-size: 11px;
}
.ins-chat-pinned-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.ins-chat-pinned-label {
  font-weight: 600; color: var(--accent);
  text-transform: uppercase; letter-spacing: 0.04em;
  font-size: 10px;
}
.ins-chat-pinned-list {
  display: flex; flex-direction: column; gap: 4px;
  align-items: stretch;            /* each chip spans full column width */
  min-width: 0;
  /* Show ~3 chips, scroll the rest. ~28px per chip row (24 chip + 4 gap),
     plus a few px for the bottom inset so the scrollbar doesn't crop a row. */
  max-height: 96px;
  overflow-y: auto;
  padding-right: 2px;              /* breathing room for the scrollbar */
}
.ins-chat-pin-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 4px 3px 8px;
  background: var(--surface);
  border: 1px solid var(--ai-panel-border);
  border-radius: 12px;
  font-size: 11px;
}
.ins-chat-pin-chip-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}
.ins-chat-pin-remove {
  background: transparent; border: none; padding: 0 3px;
  font-size: 11px; line-height: 1;
  color: var(--text-faint); cursor: pointer;
  border-radius: 50%;
}
.ins-chat-pin-remove:hover { background: var(--danger-soft-bg); color: var(--danger-text); }
.ins-chat-pinned-clear {
  background: transparent; border: 1px solid transparent;
  padding: 2px 6px; border-radius: 3px;
  font-size: 10.5px; color: var(--text-dim); cursor: pointer;
  flex-shrink: 0;
}
.ins-chat-pinned-clear:hover { background: var(--surface-2); border-color: var(--border); }

/* AI operation confirmation panel — appears at the bottom of the AI pane
   when the AI returns an operation spec. Lists each rename/move/copy/
   delete/open with a per-row checkbox; nothing runs until Apply is clicked. */
.ai-op-panel {
  flex-shrink: 0;
  border-top: 2px solid var(--accent);
  background: var(--surface);
  display: flex; flex-direction: column;
  max-height: 360px;
}
/* In-chat variant: lives inside #ins-chat-history as an AI message bubble.
   No top accent bar (the bubble's own border handles framing), and the
   body can grow freely — the chat history's own scroll handles overflow. */
.ai-op-panel-inchat {
  border: 1px solid var(--border);
  border-radius: 6px;
  margin: 6px 0 10px;
  max-height: none;
  overflow: hidden;            /* clip the rounded corners */
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.ai-op-panel-inchat .ai-op-panel-body {
  max-height: 320px;
  overflow-y: auto;
}
.ai-op-panel-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  background: var(--ai-panel-bg);
  border-bottom: 1px solid var(--ai-panel-border);
  font-size: 12px;
}
.ai-op-panel-title {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--accent); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  font-size: 11px;
}
.ai-op-panel-warn {
  font-size: 10.5px; color: var(--orange-soft-fg);
  background: var(--orange-soft-bg); padding: 2px 6px; border-radius: 3px;
  border: 1px solid var(--orange-soft-border);
}
.ai-op-panel-close {
  margin-left: auto; background: transparent; border: 1px solid transparent;
  border-radius: 3px; padding: 2px 4px;
  cursor: pointer; color: var(--text-dim);
}
.ai-op-panel-close:hover { background: var(--danger-soft-bg); color: var(--danger-text); }
.ai-op-panel-body {
  flex: 1; overflow-y: auto;
  padding: 6px 8px;
  display: flex; flex-direction: column; gap: 2px;
  font-size: 11.5px;
}
.ai-op-row {
  display: flex; flex-direction: column;
  gap: 2px;
  padding: 5px 6px;
  border-radius: 4px;
  cursor: pointer;
  border-left: 2px solid transparent;
}
.ai-op-row:hover { background: var(--surface-2); }
.ai-op-row-line1 {
  display: grid;
  grid-template-columns: 14px auto 1fr auto;
  align-items: center; gap: 6px;
}
.ai-op-row-line2 {
  /* Indent under the checkbox + tag column so the arrow lines up with the
     start of the filename above */
  padding-left: 24px;
  min-width: 0;
}
.ai-op-row-check { margin: 0; cursor: pointer; }
/* .ai-op-row-tag geometry rides the shared .wx-kind-tag grammar (P2.1);
   fills re-tokenised onto the §3.6 action-pill families. */
.ai-op-row-tag-rename     { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.ai-op-row-tag-move       { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.ai-op-row-tag-copy       { background: var(--action-pill-check-bg);  color: var(--action-pill-check-fg); }
.ai-op-row-tag-delete     { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.ai-op-row-tag-open       { background: var(--surface-2);      color: var(--text-dim); }
.ai-op-row-tag-unresolved { background: var(--orange-soft-bg); color: var(--orange-soft-fg); }
.ai-op-row-rename     { border-left-color: var(--dupe-similar); }
.ai-op-row-move       { border-left-color: var(--accent); }
.ai-op-row-copy       { border-left-color: var(--action-pill-check-fg); }
.ai-op-row-delete     { border-left-color: var(--dupe-identical); }
.ai-op-row-open       { border-left-color: var(--text-dim); }
.ai-op-row-from {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: transparent; padding: 0;
  min-width: 0;
}
.ai-op-row-detail {
  font-size: 11px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: block;
}
.ai-op-row-detail strong {
  font-family: 'SF Mono', Consolas, monospace;
  color: var(--text); font-weight: 500;
}
.ai-op-row-arrow {
  color: var(--text-dim);
  margin-right: 2px;
}
.ai-op-row-detail-muted {
  color: var(--text-dim);
  font-style: italic;
}
.ai-op-row-danger { color: var(--dupe-identical); font-weight: 500; }
.ai-op-row-status {
  font-size: 12px; font-weight: 700;
}
.ai-op-row-status.done    { color: var(--ok); }
.ai-op-row-status.failed  { color: var(--dupe-identical); cursor: help; }
.ai-op-row-status.running { color: var(--accent); display: inline-flex; align-items: center; }
.ai-op-row-unresolved     { opacity: 0.55; }
.ai-op-row-running        { background: rgba(10,109,194,0.04); }
.ai-op-row-done           { background: rgba(22,163,74,0.06); }
.ai-op-row-failed         { background: rgba(220,38,38,0.06); }
.ai-op-panel-foot {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 12px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}
.ai-op-panel-foot-spacer { flex: 1; }

/* Drop-target highlight on the AI bottom zone when a tree row is being
   dragged. The whole chat area glows lightly so users know they can drop
   anywhere on it (not just on the input). */
#ins-ai-bottom.drag-over {
  box-shadow: inset 0 0 0 2px var(--accent);
  background: rgba(10,109,194,0.04);
}
/* Faint ghost on the row being dragged from the tree */
.tree-row.drag-source {
  opacity: 0.45;
}
.ins-chat-form input,
.ins-chat-form textarea {
  width: 100%;
  font-size: 12px; line-height: 1.4; color: var(--text);
  border: 1px solid var(--border); background: var(--surface); border-radius: 8px;
  font-family: inherit;
  box-sizing: border-box;
  display: block;
}
/* Right padding leaves room for the 32×32 send button at right:8 bottom:8.
   8 inset + 32 button + 12 gap = 52 — text can't run under the button. */
.ins-chat-form input    { height: 44px; padding: 0 52px 0 12px; }
.ins-chat-form textarea {
  height: calc(1.4em * 3 + 22px);
  padding: 10px 52px 10px 12px;
  resize: none;
  overflow-y: auto;
}
.ins-chat-form input:focus,
.ins-chat-form textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }
.ins-chat-msg {
  font-size: 12px; line-height: 1.5; padding: 8px 12px; border-radius: 8px;
  max-width: 90%; word-wrap: break-word;
}
.ins-chat-msg.user { background: var(--accent); color: var(--on-solid); align-self: flex-end; }
.ins-chat-msg.ai   { background: var(--surface-2); color: var(--text); align-self: flex-start; }
.ins-chat-thinking {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; line-height: 1.5; padding: 8px 12px;
  background: var(--surface-2); color: var(--text-dim);
  border-radius: 8px;
}
.ins-chat-thinking-dots { display: inline-flex; gap: 3px; }
.ins-chat-thinking-dots span {
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; opacity: 0.4;
  animation: ins-thinking-bounce 1.2s infinite ease-in-out;
}
.ins-chat-thinking-dots span:nth-child(2) { animation-delay: 0.15s; }
.ins-chat-thinking-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes ins-thinking-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30%           { transform: translateY(-3px); opacity: 1; }
}

/* History tab — RETIRED 2026-06-22 (Activity⨉History merge, Iris merge spec).
   renderInspectorHistory() + historyRowHtml() were removed in Batch 1, leaving
   the whole .ins-history-* rule family with zero live emitters (grep-verified:
   the only non-CSS hit is an HTML comment describing the retirement). Batch 2
   removed the orphaned rules. KEPT below per the merge-spec §4 instruction: the
   data-status="undone" convention (opacity 0.6 + line-through) is the reference
   pattern the new .act-row[data-status="undone"] rules mirror — preserved as the
   documented cross-surface anchor. */
.ins-history-row[data-status="undone"]  { opacity: 0.6; }
.ins-history-row[data-status="undone"]  .ins-history-name { text-decoration: line-through; }

/* ── Activity tab (who-did-what audit feed, Iris spec 2026-06-22) ──────────
   Persistent, time-ordered ledger. Distinct from the History stack above.
   Zero new colour tokens — everything resolves to existing tokens (§9).
   Filter rows + footer are siblings of .ins-body so they pin while rows
   scroll (the structural option preferred over sticky in §6). */

/* §3/§4 — filter rows */
.act-filter {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px;   /* Iris D15: 8→12 vertical to share Structure's 12/16 inspector inset */
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.act-filter-label {
  font-size: 11px; font-weight: 600; color: var(--text-dim);
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
/* Iris inspector-craft-spec D5 (2026-06-25): the resting / hover / active /
   focus grammar for .act-chip + .act-chip-who is now the SHARED unified rule
   defined with .aic-chip (main.css ~6554 block) — one dot-pill grammar across
   both panels. The old per-panel block here (24px, --chip-bg fill,
   --chip-bg-active active) is removed; Activity loses its heavier grey fill
   and matches Structure's transparent-ground + accent-ring exactly. Only the
   layout (display:inline-flex + gap) stays panel-local below. */
.act-chip { display: inline-flex; align-items: center; gap: 8px; }

/* §3 — circular initials avatar — THE attribution atom (filter + row, one size) */
.act-avatar {
  width: 24px; height: 24px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-3); color: var(--text-dim);
  font-size: 10px; font-weight: 700; letter-spacing: 0.02em;
  flex-shrink: 0; user-select: none;
  box-shadow: inset 0 0 0 1px var(--border);
}
.act-avatar-btn { border: 0; cursor: pointer; padding: 0;
  transition: box-shadow var(--motion-duration) var(--motion-easing); }
.act-avatar-btn:hover    { box-shadow: inset 0 0 0 1px var(--border-dark); }
.act-avatar-btn[aria-pressed="true"] { box-shadow: inset 0 0 0 1.5px var(--accent); }
.act-avatar-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* §4 — action type chips + search */
/* Iris inspector-craft-spec D6 (2026-06-25): the grid owns layout now — the
   action filters lay on an aligned 3-col grid (a clean 3+2 for the five chips,
   2nd-row chips align under the first two columns; 3rd cell empty, not ragged)
   instead of ragged flex-wrap (was 4+1). One row when the panel is wide. The
   .act-filter-action wrapper's own flex-wrap is dropped — the grid is the
   layout authority. The dim-the-rest rule moved to the shared block (~6554). */
.act-filter-action { gap: 8px; }
.act-chip-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Grouped toned panels (Jeremy redesign 2026-06-27) — same language as AI
   Cleanup: a static controls panel above, the scrolling feed panel below, with
   a fixed 8px gap (the controls panel's bottom margin owns it). */
.act-controls {
  background: var(--panel-fill);
  border: 0.5px solid var(--border);
  border-radius: var(--radius-panel);
  margin: 8px;
  padding: 12px;
  display: flex; flex-direction: column; gap: 12px;
}
.act-controls .act-filter { padding: 0; background: transparent; border-bottom: 0; }
.act-controls .act-filter-action { flex-direction: column; align-items: stretch; gap: 12px; }
/* In the column layout the search must not grow vertically (its `flex:1 1 140px`
   was for the old horizontal row). Pin it and give it the pill search look. */
.act-controls .act-search { flex: 0 0 auto; height: 32px; border-radius: var(--radius-pill); }
#ins-activity-body {
  background: var(--panel-fill);
  border: 0.5px solid var(--border);
  border-radius: var(--radius-panel);
  margin: 0 8px 8px;
}
#ins-activity-body .act-row { background: transparent; }
/* Colour cue = a 6px dot in the action's pill-fg colour ("All" has no dot).
   The 6px dot atom (width/height/radius) is shared with .aic-chip-dot in the
   unified block (~6554); only the per-action colours live here. */
.act-chip[data-pill="rename"] .act-chip-dot { background: var(--action-pill-warn-fg); }
.act-chip[data-pill="move"]   .act-chip-dot { background: var(--action-pill-info-fg); }
.act-chip[data-pill="delete"] .act-chip-dot { background: var(--action-pill-danger-fg); }
.act-chip[data-pill="merge"]  .act-chip-dot { background: var(--action-pill-merge-fg); }

.act-search {
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 8px; flex: 1 1 140px; min-width: 120px;
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text-dim);
}
.act-search:focus-within { border-color: var(--accent); color: var(--text); }
.act-search input {
  border: 0; background: transparent; outline: none;
  font-size: 12px; color: var(--text); width: 100%;
}
.act-search input::placeholder { color: var(--text-faint); }

/* §5 — row anatomy (reverse-chronological) */
/* Iris inspector-craft-spec D15 (2026-06-25): gap 10→8 and vertical pad
   10→12 to snap onto the same 4/8/12 scale Structure uses — the small move
   that makes the two panels feel like one grid. */
.act-row {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  transition: background var(--motion-duration) var(--motion-easing);
}
.act-row:hover { background: var(--surface-2); }
.act-row .act-avatar { margin-top: 1px; }   /* optical align to line-1 cap height */

.act-row-main { flex: 1; min-width: 0; }     /* min-width:0 lets text wrap */

/* Iris inspector-craft-spec D7 (2026-06-25): line1 top-aligns its icon/badge/
   verb to the FIRST text line when the filename wraps (was center). */
.act-row-line1 {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; line-height: 1.4; color: var(--text);
}
.act-row-verb { font-weight: 600; flex-shrink: 0; }
/* Jeremy 2026-06-27: the filename lives on its OWN line beneath the verb (line 1
   carries only the icon + verb), for breathing space and to match the AI Cleanup
   row anatomy. Aligned to the main column (lines up with the icon above). */
.act-row-file {
  font-weight: 400; color: var(--text); min-width: 0;
  font-size: 13px; line-height: 1.4; margin-top: 3px;
  word-break: break-word;
}
.act-row-icon { flex-shrink: 0; }   /* colour set per-category below */

/* Meta line — location + date·time. The actor name is dropped (the avatar
   initials already attribute it). Jeremy 2026-06-27. */
.act-row-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 5px;
  font-size: 11px; line-height: 1.45; color: var(--text-dim);
  margin-top: 5px;
}
/* THE load-bearing fix: the from→to path is the row's reason for existing —
   WRAP it fully, never ellipsis. No clamp: show all of it (content is the
   hero, rule 4). Was nowrap/overflow:hidden/ellipsis. */
.act-row-detail {
  min-width: 0;
  white-space: normal; word-break: break-word;
  font-variant-numeric: tabular-nums;
}
.act-row-actor { color: var(--text-dim); flex-shrink: 0; }
.act-row-time  { color: var(--text-faint); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.act-row-sep   { color: var(--text-faint); flex-shrink: 0; }

/* Category colour cue — ICON ONLY (brief constraint), dark-safe */
.act-row[data-cat="rename"] .act-row-icon { color: var(--action-pill-warn-fg); }
.act-row[data-cat="move"]   .act-row-icon { color: var(--action-pill-info-fg); }
.act-row[data-cat="delete"] .act-row-icon { color: var(--action-pill-danger-fg); }
.act-row[data-cat="merge"]  .act-row-icon { color: var(--action-pill-merge-fg); }

/* §6 — footer (sibling of .ins-body, pinned at bottom) */
.act-footer {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between;
  height: 32px; padding: 0 16px;
  border-top: 1px solid var(--border);
  background: var(--surface);
  font-size: 11px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.act-footer-right { color: var(--text-faint); }

/* §3 (merge spec) — inline Undo. Present ONLY on the single reversible
   (top-of-stack) row. A quiet accent text-link grounded on --hover-soft, NOT a
   bordered pill — the dense feed wants the lighter touch. Zero new tokens. */
.act-undo {
  flex-shrink: 0;
  align-self: center;
  margin-left: 4px;
  border: 0; background: transparent; cursor: pointer;
  font: 600 11px/1 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  color: var(--accent);
  padding: 4px 8px; border-radius: 4px;
  transition: background var(--motion-duration) var(--motion-easing),
              color var(--motion-duration) var(--motion-easing);
}
.act-undo:hover  { background: var(--hover-soft); color: var(--accent-hover); }
.act-undo:active { background: var(--chip-bg-active); }
.act-undo:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* §4 (merge spec) — undone-row state. data-status="undone" is set by the render
   ONLY after reconciling against undoMgr._history (undone:true) — never inferred
   from the record. Mirrors the legacy History convention (opacity 0.6 +
   line-through on the name; see the kept .ins-history-row[data-status="undone"]
   reference rules) for cross-surface consistency. */
.act-row[data-status="undone"] { opacity: 0.6; }
.act-row[data-status="undone"] .act-row-file { text-decoration: line-through; }
.act-row[data-status="undone"] .act-undo { display: none; }   /* can't undo an undone row */

/* Dry-run / preview rows — Otto previews that NEVER touched a file. The badge
   + conditional verb ("Would move") make that unmistakable; the row recedes
   slightly so real, completed actions read as the dominant entries. Holds in
   both themes via tokens (info family + text-dim). */
.act-preview-badge {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 6px;
  border-radius: 6px;
  color: var(--action-pill-info-fg);
  background: var(--action-pill-info-bg);
  border: 1px solid var(--border);
}
.act-row[data-dryrun] { opacity: 0.9; }
.act-row[data-dryrun] .act-row-verb { color: var(--text-dim); font-weight: 500; }

/* The explicit "UNDONE" marker — sits in the right lane where the Undo button
   was, so reversible→undone is a no-layout-shift horizontal swap. */
.act-undone-tag {
  flex-shrink: 0; align-self: center; margin-left: 4px;
  display: inline-flex; align-items: center; gap: 4px;
  font: 600 10px/1 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--text-faint);
  padding: 3px 6px; border-radius: 4px;
  background: var(--surface-3);
}
.act-undone-tag .lucide-icon { color: var(--text-faint); }

/* §1.4 (merge spec) — one-time migration hint. Dismissible inline row at the
   top of the feed (above the Who row). Fades on dismiss (200ms). Zero new
   tokens; localStorage flag keeps it gone after dismissal. */
/* (merge migration hint removed 2026-06-22 — not needed per Jeremy.) */

/* Dark theme — deliberate elevation, not inverted */
:root[data-theme="dark"] #inspector {
  background: var(--ai-panel-bg);
  border-left-color: var(--ai-panel-border);
}
:root[data-theme="dark"] #inspector-rail {
  background: var(--ai-panel-bg);
  border-right-color: var(--ai-panel-border);
}
:root[data-theme="dark"] #inspector-resizer::after { background: var(--ai-panel-border); }
:root[data-theme="dark"] #smart-move-dropzone {
  background: var(--ai-panel-bg); border-color: var(--border-strong);
}
:root[data-theme="dark"] #smart-move-dropzone:hover { background: var(--hover-soft); }
:root[data-theme="dark"] #smart-move-dropzone.drag-over { background: rgba(78,161,238,0.10); border-color: var(--accent); }
:root[data-theme="dark"] #smart-move-dropzone .lucide-icon { color: var(--connector-stroke); }
:root[data-theme="dark"] .ins-dz-title { color: var(--text); }
:root[data-theme="dark"] .ins-dz-sub   { color: var(--text-dim); }

/* Pane separator — gives the two trees a hairline divider so they don't
   bleed together into one wide surface. The .pane already has a 1px right
   border but in dark mode it needs a touch more contrast. */
:root[data-theme="dark"] .pane { border-right-color: var(--ai-panel-border); }
/* .pane-toolbar dark override removed (bug-tester regression on Brief #1):
   it was defeating the new var(--pane-chrome-bg) swap at line 1156. The
   token now drives both themes; this rule's only remaining purpose would
   be a custom border colour, which the token system handles via --border. */
:root[data-theme="dark"] .pane-select {
  background: var(--surface-2);
  border-color: var(--chip-bg);
  color: var(--text);
}
:root[data-theme="dark"] .pane-select:hover { background: var(--surface-3); }
:root[data-theme="dark"] .pane-search input {
  background: var(--surface);
  border-color: var(--chip-bg);
  color: var(--text);
}
:root[data-theme="dark"] .pane-search input:focus { border-color: var(--accent); }
:root[data-theme="dark"] .sm-row.sm-row-failed { background: var(--danger-soft-bg); border-color: var(--danger-soft-border); }
:root[data-theme="dark"] .sm-row-suggest code,
:root[data-theme="dark"] .sm-single-source code,
:root[data-theme="dark"] .sm-single-value { background: var(--surface-0); }

/* Mobile / small-viewport fallback — Inspector overlays instead of squeezing */
@media (max-width: 1100px) {
  #inspector[data-state="standard"] {
    box-shadow: -8px 0 24px rgba(0,0,0,0.18);
  }
  #app #explorer { padding-right: var(--inspector-w-collapsed); }
  #inspector[data-state="standard"] ~ #explorer,
  #inspector[data-state="expanded"] ~ #explorer { padding-right: var(--inspector-w-collapsed); }
}
@media (max-width: 800px) {
  #inspector[data-state="standard"],
  #inspector[data-state="expanded"] { width: 100vw; --inspector-w: 100vw; }
}

/* ════════════════════════════════════════════════════════════════
   SMART MOVE undo toast — appears bottom-centre after every apply.
   8s timeout (design-tester's call); inline Undo button matches Finder.
   ──────────────────────────────────────────────────────────── */
.sm-undo-toast {
  /* Bottom-right of the EXPLORER area (left of the Inspector). Previously
     centered on the viewport at left:50%, which put half the toast under
     the Inspector — Jeremy didn't see it (smoke test 2026-05-19). Now
     anchored to the same edge as .toast-container with a slight upward
     offset so the two don't stack on the same line. */
  position: fixed;
  bottom: 80px;
  right: calc(var(--inspector-resolved-w, 0px) + 16px);
  background: var(--tooltip-bg); color: var(--tooltip-text);
  padding: 10px 14px 10px 16px;
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.30);
  display: flex; align-items: center; gap: 12px;
  font-size: 12px;
  z-index: 9999;
  animation: sm-toast-in var(--motion-duration) var(--motion-easing);
}
.sm-undo-toast .sm-undo-msg { white-space: nowrap; }
.sm-undo-toast button {
  background: transparent; border: 1px solid rgba(255,255,255,0.30);
  color: var(--on-solid); padding: 4px 10px; border-radius: 4px;
  font-size: 11px; font-weight: 500; cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px;
}
.sm-undo-toast button:hover { background: rgba(255,255,255,0.12); }
@keyframes sm-toast-in {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ── "More" menu (toolbar overflow) ── */
.tb-more-wrap { position: relative; }
.tb-more-menu {
  /* position:fixed (NOT absolute) so the dropdown escapes the toolbar's
     `overflow:hidden` — an absolute menu inside the toolbar gets clipped to a
     sliver ("top of a white box"). Anchored under the ⋯ button by JS
     (_anchorMoreMenu) on open; the top/right here are just a pre-paint fallback.
     (Jeremy 2026-06-20) */
  position: fixed; top: var(--toolbar-h); right: 8px;
  background: var(--menu-bg); border: 1px solid var(--menu-border);
  border-radius: 6px; box-shadow: 0 6px 20px rgba(0,0,0,0.10);
  min-width: 200px; z-index: 300;
  padding: 4px;
  display: block;
}
.tb-more-menu[hidden] { display: none; }
/* A12 #17 (2026-06-27): signed-in identity header in the Account menu. */
.account-identity {
  padding: 8px 10px 8px; margin: 0 0 4px; border-bottom: 1px solid var(--menu-border);
}
.account-identity[hidden] { display: none; }
.account-identity-name  { font-size: 12px; font-weight: 600; color: var(--text); }
.account-identity-email { font-size: 11px; color: var(--text-dim); margin-top: 1px; word-break: break-all; }
.account-identity-email[hidden] { display: none; }
.tb-more-menu button {
  width: 100%; text-align: left;
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; background: transparent; border: none;
  font-size: 12px; color: var(--text); cursor: pointer;
  border-radius: 4px;
}
.tb-more-menu button:hover { background: var(--surface-2); }

/* ── Selection-tab card ── */
.ins-selection-card { padding: 16px; }
.ins-sel-meta {
  display: grid; grid-template-columns: 80px 1fr;
  gap: 4px 12px; font-size: 12px; margin: 0 0 14px;
}
.ins-sel-meta dt { color: var(--text-faint); font-weight: 500; }
.ins-sel-meta dd { color: var(--text); margin: 0; word-break: break-all; }
.ins-sel-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.ins-sel-actions button { display: inline-flex; align-items: center; gap: 4px; }

/* ── Inspector Duplicates groups ── */
.ins-dupe-group {
  padding: 8px 16px; border-bottom: 1px solid var(--border);
}
.ins-dupe-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; margin-bottom: 6px;
}
.ins-dupe-files { list-style: none; margin: 0; padding: 0 0 0 20px; }
.ins-dupe-files li {
  display: flex; justify-content: space-between; gap: 8px;
  padding: 3px 6px; border-radius: 4px;
  font-size: 11.5px; cursor: pointer;
}
.ins-dupe-files li:hover { background: var(--surface-2); }
.ins-dupe-path { color: var(--text-dim); font-family: 'SF Mono', Consolas, monospace; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ins-dupe-size { color: var(--text-faint); font-variant-numeric: tabular-nums; flex-shrink: 0; }

.ins-recov { padding: 24px 20px; }
.ins-recov-figure {
  text-align: center; padding: 24px 16px;
  background: linear-gradient(135deg, rgba(10,109,194,0.06), rgba(10,109,194,0.02));
  border-radius: 8px; border: 1px solid rgba(10,109,194,0.16);
  margin-bottom: 16px;
}
.ins-recov-num { font-size: 28px; font-weight: 700; color: var(--accent); display: block; letter-spacing: -0.02em; }
.ins-recov-sub { font-size: 11px; color: var(--text-dim); }
.ins-recov-note { font-size: 11.5px; color: var(--text-dim); line-height: 1.55; margin: 0; }

/* ── Inspector Naming list ── */
.ins-naming-explainer {
  padding: 12px 16px; font-size: 11.5px; line-height: 1.55;
  color: var(--text-dim); background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.ins-naming-summary {
  padding: 10px 16px; font-size: 11px; color: var(--text-faint);
  border-bottom: 1px solid var(--border); background: var(--surface);
  position: sticky; top: 0; z-index: 1;
}
.ins-naming-list { list-style: none; margin: 0; padding: 0; }
.ins-naming-list li {
  padding: 8px 16px; border-bottom: 1px solid var(--border);
  font-size: 12px; cursor: pointer;
}
.ins-naming-list li:hover { background: var(--surface-2); }
.ins-naming-name { font-weight: 500; color: var(--text); word-break: break-all; }
.ins-naming-flags { display: flex; gap: 4px; flex-wrap: wrap; margin: 4px 0; }
.ins-flag {
  font-size: 10px; padding: 1px 6px; border-radius: 3px;
  background: var(--warning-chip-bg); color: var(--warning-chip-fg); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.04em;
  cursor: help;       /* hover for full reason */
}
/* Per-category colours so issues are scannable at a glance. */
.ins-flag-illegal    { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.ins-flag-length     { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.ins-flag-whitespace { background: var(--sky-soft-bg); color: var(--sky-soft-fg); }
.ins-flag-ext        { background: var(--violet-soft-bg); color: var(--violet-soft-fg); }
.ins-flag-generic    { background: var(--pink-soft-bg); color: var(--pink-soft-fg); }
.ins-flag-version    { background: var(--orange-soft-bg); color: var(--orange-soft-fg); }
.ins-flag-date       { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.ins-naming-path { font-family: 'SF Mono', Consolas, monospace; font-size: 10.5px; color: var(--text-faint); }
.ins-naming-truncate { padding: 10px 16px; font-size: 11px; color: var(--text-faint); text-align: center; font-style: italic; }

/* ── spinner for "AI thinking" ── */
.spin { animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* NOTE: #compare-panel is NOT suppressed here. The FILE compare migrated to the
   Inspector (2026-05-14), but the FOLDER compare (openCompareFolders) still uses
   this bottom-dock panel. A blanket `#compare-panel { display:none !important }`
   here used to override `#app.compare-open #compare-panel { display:flex }`,
   leaving the `compare` grid row (var(--compare-h)) reserved but empty — a large
   blank gap below the panes, and the folder comparison invisible. (Jeremy 2026-06-20) */

/* ════════════════════════════════════════════════════════════════
   POLISH PASS — 2026-05-14 (Iris)
   Tightens visual debt across new and migrated surfaces.
   ──────────────────────────────────────────────────────────── */

/* Smart Move queue rows — proper hierarchy + smooth state transitions */
.sm-row {
  transition: opacity var(--motion-micro) var(--inspector-ease), border-color var(--motion-micro) var(--inspector-ease), background var(--motion-micro) var(--inspector-ease);
}
.sm-row:hover { border-color: var(--border-strong); }
.sm-row.sm-row-applied {
  background: linear-gradient(180deg, rgba(22,163,74,0.04), transparent);
  border-color: rgba(22,163,74,0.30);
}
.sm-row.sm-row-applied .sm-row-name::before {
  content: ''; display: inline-block; width: 6px; height: 6px;
  border-radius: 50%; background: var(--ok); margin-right: 6px; vertical-align: middle;
}
.sm-row .btn-apply {
  transition: background var(--motion-micro) var(--inspector-ease), transform var(--motion-micro) var(--inspector-ease);
}
.sm-row .btn-apply:active { transform: scale(0.96); }

/* Confidence dot — smooth band-flip per Iris. The "dashed-ring → solid" cascade
   uses box-shadow which can't be smoothly tweened to a fill, so we layer:
   background tween handles the colour shift, and we transition box-shadow
   separately so the ring fades out as the fill grows in. */
.confidence-dot {
  position: relative;
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--text-faint);
  transition: background var(--motion-duration) var(--inspector-ease), box-shadow var(--motion-duration) var(--inspector-ease);
}
.confidence-dot[data-band="high"]   { background: var(--ok); box-shadow: inset 0 0 0 0 transparent; }
.confidence-dot[data-band="medium"] { background: var(--warn); box-shadow: inset 0 0 0 0 transparent; }
.confidence-dot[data-band="low"]    { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text-faint); }

/* AI "thinking" — subtle pulse, not a full spin. Less attention-grabbing,
   more "the app is alive" — closer to how Linear/Notion treat async states. */
.ai-thinking-dots {
  display: inline-flex; gap: 4px; align-items: center;
}
.ai-thinking-dots > span {
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor;
  opacity: 0.4;
  animation: ai-pulse 1.2s ease-in-out infinite;
}
.ai-thinking-dots > span:nth-child(2) { animation-delay: 0.15s; }
.ai-thinking-dots > span:nth-child(3) { animation-delay: 0.30s; }
@keyframes ai-pulse {
  0%, 100% { opacity: 0.25; transform: scale(0.9); }
  50%      { opacity: 0.95; transform: scale(1.1); }
}

/* History tab day-grouping headers (.ins-history-day-group / .ins-history-day)
   — REMOVED 2026-06-22 (Activity⨉History merge). Zero live emitters after the
   Batch 1 render removal; grep-verified dead. */

/* Selection tab card — refined hierarchy */
.ins-selection-card {
  padding: 0;
}
/* Icon + name share grid row 1 (centred together → the folder sits IN LINE with
   the name); the path drops to row 2. Jeremy 2026-06-27. */
.ins-sel-hero {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 12px; row-gap: 1px;
  align-items: center;
  padding: 18px 16px 14px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, var(--surface-2), transparent);
}
/* Icon matches the tree (coloured folder SVG / file glyph) — no tinted plate. */
.ins-sel-icon {
  grid-column: 1; grid-row: 1;
  width: 32px; height: 28px;
  display: flex; align-items: center; justify-content: center;
}
.ins-sel-icon svg { width: 30px; height: auto; display: block; }   /* keep the folder's 36:30 aspect */
.ins-sel-fileglyph { font-size: 26px; line-height: 1; }
.ins-sel-headtext { display: contents; }
.ins-sel-hero .ins-sel-name { grid-column: 2; grid-row: 1; margin: 0; line-height: 1.3; }
.ins-sel-hero .ins-sel-path { grid-column: 2; grid-row: 2; }
.ins-sel-name {
  font-size: 14px; font-weight: 600; color: var(--text);
  margin: 0 0 4px;
  word-break: break-all; line-height: 1.4;
  letter-spacing: -0.01em;
}
.ins-sel-path {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 10.5px; color: var(--text-dim);
  line-height: 1.5;
  padding: 0; background: none;
  margin: 0;
  /* Location breadcrumb (parent path) on ONE line. Head-truncate so the
     NEAREST parent stays visible at the 420px panel: rtl clips the HEAD and
     puts the ellipsis at the start (… / 02. Due Diligence Tool), while
     unicode-bidi:plaintext + text-align:left keep the slashes LTR-readable. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  direction: rtl; text-align: left; unicode-bidi: plaintext;
}
.ins-sel-section { padding: 16px; border-bottom: 1px solid var(--border); }
.ins-sel-section:last-of-type { border-bottom: none; }
.ins-sel-section-label {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-faint); font-weight: 600;
  margin: 0 0 8px;
}
.ins-sel-meta { display: grid; grid-template-columns: 84px 1fr; gap: 6px 12px; font-size: 12px; }
.ins-sel-meta dt { color: var(--text-faint); }
.ins-sel-meta dd { color: var(--text); margin: 0; word-break: break-all; }
.ins-sel-actions { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px 18px; }
.ins-sel-actions button { width: 100%; justify-content: center; height: 36px; }

/* ── Records card (Domain B: per-document metadata backbone) ─────────────── */
.ins-rec-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.ins-rec-head .ins-sel-section-label { margin: 0; }
.ins-rec-grid { align-items: center; }
.ins-rec-grid dt { align-self: center; }
.ins-rec-in {
  width: 100%; box-sizing: border-box; height: 26px; padding: 0 8px;
  font: inherit; font-size: 12px; color: var(--text);
  background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius);
}
.ins-rec-in:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--row-sel); }
select.ins-rec-in { height: 26px; }
.ins-rec-actions { margin-top: 10px; }
.ins-rec-prov {
  display: flex; align-items: center; gap: 5px;
  margin: 8px 0 0; font-size: 11px; color: var(--text-dim);
}
.ins-rec-flash { margin: 8px 0 0; font-size: 11px; color: var(--accent); }
/* Status pill — reuses the action-pill token families so no new colours are minted */
.ins-rec-status-pill {
  font-size: 10.5px; font-weight: 600; padding: 2px 9px; border-radius: var(--radius-pill);
  background: var(--chip-bg); color: var(--chip-fg); white-space: nowrap;
}
.ins-rec-status-pill.rec-pill-draft { background: var(--chip-bg); color: var(--chip-fg); }
.ins-rec-status-pill.rec-pill-under-review { background: var(--action-pill-warn-bg, var(--warning-chip-bg)); color: var(--action-pill-warn-fg, var(--warning-chip-fg)); }
.ins-rec-status-pill.rec-pill-approved { background: var(--action-pill-info-bg); color: var(--action-pill-info-fg); }
.ins-rec-status-pill.rec-pill-final { background: var(--action-pill-check-bg); color: var(--action-pill-check-fg); }
.ins-rec-status-pill.rec-pill-superseded { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }

/* ── Records tab (filterable list of classified documents) ───────────────── */
.ins-recpanel { padding: 12px 16px 18px; }
.ins-rec-filterbar { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.ins-rec-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ins-rec-chip {
  font-size: 11px; font-weight: 500; padding: 3px 10px; cursor: pointer;
  color: var(--text-dim); background: var(--chip-bg); border: 1px solid transparent;
  border-radius: var(--radius-pill);
}
.ins-rec-chip:hover { color: var(--text); }
.ins-rec-chip.is-on { background: var(--chip-bg-active); color: var(--text); border-color: var(--accent); }
.ins-rec-chip-n { opacity: 0.65; margin-left: 3px; }
.ins-rec-search { width: 100%; box-sizing: border-box; }
.ins-rec-count { font-size: 11px; color: var(--text-faint); margin: 0 0 8px; }
.ins-reclist { display: flex; flex-direction: column; gap: 4px; }
.ins-recrow {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 10px; border-radius: var(--radius);
  background: var(--surface-0); border: 1px solid var(--border);
}
.ins-recrow:hover { border-color: var(--border-dark); }
.ins-recrow-main { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ins-recrow-name { font-size: 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ins-recrow-meta { font-size: 10.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Version history (SharePoint versions, surfaced read-only) ───────────── */
.ins-ver-list { display: flex; flex-direction: column; gap: 3px; }
.ins-ver-list:not(:empty) { margin-bottom: 8px; }
.ins-verrow {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 5px 8px; border-radius: var(--radius); background: var(--surface-0);
  border: 1px solid var(--border); font-size: 11.5px;
}
.ins-verrow-v { font-weight: 600; color: var(--text); white-space: nowrap; }
.ins-verrow-meta { color: var(--text-dim); text-align: right; }

/* ── Records status dot on tree file rows (Domain B) ─────────────────────── */
.tree-rec-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-left: 7px; flex: none; vertical-align: middle;
  background: var(--text-faint);
}
.tree-rec-dot.rec-dot-none { background: var(--text-faint); }
.tree-rec-dot.rec-dot-draft { background: var(--text-dim); }
.tree-rec-dot.rec-dot-under-review { background: var(--warn); }
.tree-rec-dot.rec-dot-approved { background: var(--accent); }
.tree-rec-dot.rec-dot-final { background: var(--success); }
.tree-rec-dot.rec-dot-superseded { background: var(--danger); }

/* ── "Why this folder" rationale (Iris inspector-rationale-spec, Batch 3) ──────
   The resident hero answer for a selection. Inherits the .otto-says-reason
   grammar (surface-3 tint, radius 6, 3px accent quote-edge) so the inspector's
   reasoning reads as the same voice as Otto's per-flight reasoning (rule 10).
   Lives inside the hero zone: 4px under the hero, 14px before the Details rule.
   Zero new tokens — every value resolves to an existing var or the 4/8/12/16
   spacing scale. */
.ins-rationale {
  margin: 4px 16px 14px;          /* 4 under hero, 14 before Details rule (Iris §3) */
  padding: 12px 12px 12px 13px;
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);   /* the one accent invitation — quote-block edge */
  border-radius: 6px;
  animation: ins-rationale-in var(--motion-micro) var(--inspector-ease) both;   /* §7 fade-rise on select */
}
@keyframes ins-rationale-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ins-rationale { animation: none; }
}

/* Heading + calibration chip on one row (§4). */
.ins-rationale-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.ins-rationale-title {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; color: var(--text);
  margin: 0; letter-spacing: -0.01em;
}
.ins-rationale-title .lucide-icon { color: var(--accent); flex: none; }   /* compass, 14px */

/* Calibration chip — reuses .confidence-dot[data-band]; the WORD is the
   load-bearing signal, the dot reinforces (never colour-only, §4.2). */
.ins-rationale-chip {
  display: inline-flex; align-items: center; gap: 6px;
  flex: none;
  font-size: 11px; font-weight: 600; color: var(--text-dim);
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.ins-rationale-chip .confidence-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* The hero read — Otto's prose voice, body weight, one primary sentence (§2). */
.ins-rationale-prose {
  font-size: 13px; font-weight: 400; color: var(--text); line-height: 1.45;
  margin: 0;
}

/* Audit-proposal callout — a calmer --surface child note inside the surface-3
   parent (the surface ladder separates them in both themes, §8). */
.ins-rationale-callout {
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
}
.ins-rationale-callout-eyebrow {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-faint); margin: 0;
}
.ins-rationale-action {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 13px; color: var(--text); line-height: 1.4;
}
.ins-rationale-reason {
  font-size: 12px; color: var(--text-dim); line-height: 1.45; margin: 0;
}
/* Jeremy 2026-06-27: flattened "Suggested → Move" row — inline, no nested card,
   no duplicate reason line (replaces .ins-rationale-callout for the selection). */
.ins-rationale-suggest {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 8px;
  font-size: 13px; color: var(--text); line-height: 1.4;
}
.ins-rationale-suggest-label { font-size: 12px; color: var(--text-dim); }
/* The suggested-action pill is clickable — it opens the matching AI Cleanup tab. */
.ins-rationale-suggest .ins-rationale-pill { cursor: pointer; }
.ins-rationale-suggest .ins-rationale-pill:hover { box-shadow: inset 0 0 0 1.5px currentColor; }
.ins-rationale-suggest-target { font-size: 13px; color: var(--text-dim); }

/* Action pill — reuses the --action-pill-* token families (one family per
   action, the same colour→meaning map as .ov-card / the cleanup rows, rule 10).
   Glyph + word inside every pill so the action survives without colour (§9). */
.ins-rationale-pill {
  display: inline-flex; align-items: center; gap: 4px;
  flex: none;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
  line-height: 1.5;
}
.ins-rationale-pill .lucide-icon { width: 12px; height: 12px; }
.ins-rationale-pill[data-action="move"]     { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.ins-rationale-pill[data-action="merge"]    { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }
.ins-rationale-pill[data-action="rename"]   { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.ins-rationale-pill[data-action="renumber"] { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.ins-rationale-pill[data-action="check"]    { background: var(--action-pill-check-bg);  color: var(--action-pill-check-fg); }
.ins-rationale-pill[data-action="delete"]   { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }

/* Org-fit line — the BI house-rule, quieter than the prose. */
.ins-rationale-fit {
  font-size: 12px; color: var(--text-dim); line-height: 1.45; margin: 0;
}

/* §5.2 folder-clean — success edge mirrors .otto-says.otto-win; the status line
   replaces the proposal callout with a designed positive (rule 8). */
.ins-rationale[data-state="clean"] { border-left-color: var(--success-text); }
.ins-rationale-status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 500; color: var(--text-dim);
}
.ins-rationale-status .lucide-icon { color: var(--success-text); width: 13px; height: 13px; flex: none; }

/* §5.3 folder-unknown — neutral edge (no verdict yet), dimmed prose, a real
   <button> CTA that looks clickable (§9) and routes to the audit flow. */
.ins-rationale[data-state="unknown"] { border-left-color: var(--text-faint); }
.ins-rationale[data-state="unknown"] .ins-rationale-prose { color: var(--text-dim); }
.ins-rationale-cta {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 6px;
  font-size: 12px; font-weight: 500;
  background: transparent; border: 1px solid var(--border); color: var(--accent);
  cursor: pointer;
  transition: background var(--inspector-ease) var(--motion-micro), border-color var(--inspector-ease) var(--motion-micro);
}
.ins-rationale-cta:hover { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); border-color: var(--accent); }
.ins-rationale-cta:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Inspector tab tooltip — 600ms hover delay, sits to the right of the rail */
.ins-tab { position: relative; }
.ins-tab::after {
  content: attr(aria-label);
  position: absolute; left: 100%; top: 50%; transform: translate(8px, -50%);
  background: var(--tooltip-bg); color: var(--tooltip-text);
  padding: 4px 8px; border-radius: 4px;
  font-size: 11px; white-space: nowrap;
  pointer-events: none; opacity: 0;
  transition: opacity var(--motion-micro) var(--inspector-ease) 0ms;
  z-index: 1000;
  box-shadow: 0 4px 12px rgba(0,0,0,0.18);
}
.ins-tab:hover::after {
  opacity: 1;
  transition-delay: 600ms;   /* per Iris's spec */
}
#inspector:not([data-state="collapsed"]) .ins-tab::after { display: none; }   /* no tooltip when content panel is visible */

/* Hover affordance for tabs is a touch softer */
.ins-tab:hover { background: rgba(10, 109, 194, 0.06); color: var(--text); }
:root[data-theme="dark"] .ins-tab:hover { background: rgba(78, 161, 238, 0.10); }

/* Apply button states */
.sm-row-actions .btn-apply.is-loading { color: transparent; position: relative; }
.sm-row-actions .btn-apply.is-loading::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 12px; height: 12px;
  border: 1.5px solid rgba(255,255,255,0.4); border-top-color: var(--on-solid);
  border-radius: 50%;
  margin: -6px 0 0 -6px;
  animation: spin 0.7s linear infinite;
}

/* Smart Move drop zone — animated active state */
#smart-move-dropzone {
  transition: background var(--motion-micro) var(--inspector-ease), border-color var(--motion-micro) var(--inspector-ease), transform var(--motion-micro) var(--inspector-ease);
}
#smart-move-dropzone.drag-over { transform: scale(1.01); }

/* Tab fresh indicator — pulse so it draws the eye */
.ins-tab[data-fresh="1"]::after {
  /* preserves the tooltip but adds a pulse to the dot */
}
@keyframes ins-fresh-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.4); }
}
.ins-tab[data-fresh="1"] .lucide-icon { animation: none; }

/* ── Login screen final polish ── */
@media (max-width: 480px) {
  .login-box { padding: 28px 24px 24px; max-width: 320px; }
  .login-logo { width: 72px; height: 72px; margin-bottom: 14px; }
  .login-logo-glyph { width: 46px; height: 46px; }
  .login-box h1 { font-size: 18px; }
  .login-tagline { font-size: 12px; margin-bottom: 18px; }
}

/* External-file badge in Smart Move queue rows — geometry rides the shared
   .wx-kind-tag grammar (P2.1); the info-pill tokens carry their own dark pair
   so the bespoke dark override is gone. */
.sm-row-badge {
  background: var(--action-pill-info-bg); color: var(--action-pill-info-fg);
  vertical-align: middle; margin-left: 6px;
}

/* ── Smart Move queue row — redesigned 2026-05-14 for clarity ── */
.sm-row-original {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text);
  margin-bottom: 8px;
  min-width: 0;
}
.sm-row-original .lucide-icon { color: var(--text-faint); flex-shrink: 0; }
.sm-row-original-name {
  font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; flex: 1;
}
.sm-row-original-path {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 10.5px; color: var(--text-faint);
  margin-left: 4px; flex-shrink: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sm-row-thinking {
  font-size: 11px; color: var(--text-faint); font-style: italic;
  padding: 4px 0 0 18px;
}
.sm-row-plan {
  display: flex; flex-direction: column; gap: 6px;
  padding: 2px 0 0 0;
}
.sm-row-change {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 12px;
}
.sm-row-label {
  flex-shrink: 0;
  font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 2px 6px; border-radius: 3px;
  margin-top: 2px;     /* baseline-align with the value text */
  min-width: 50px; text-align: center;
}
.sm-row-label-rename { background: rgba(217, 119, 6, 0.12); color: var(--action-pill-warn-fg); }
.sm-row-label-move   { background: rgba(10, 109, 194, 0.12); color: var(--accent); }
.sm-row-label-upload { background: rgba(22, 163, 74, 0.12); color: var(--ok-soft-fg); }
.sm-row-newname {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11.5px; color: var(--text);
  background: var(--surface-2); padding: 2px 6px; border-radius: 3px;
  word-break: break-all; line-height: 1.4;
  flex: 1; min-width: 0;
}
.sm-row-newpath {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11.5px; color: var(--accent); font-weight: 500;
  line-height: 1.4;
  flex: 1; min-width: 0;
  word-break: break-word;
}
.sm-row-nofolder {
  font-style: italic; color: var(--text-faint); font-size: 11.5px;
}
.sm-row-noop {
  font-size: 11.5px; color: var(--text-dim); font-style: italic;
  padding-left: 4px;
}
:root[data-theme="dark"] .sm-row-newname { background: var(--surface-0); }
:root[data-theme="dark"] .sm-row-label-rename { background: rgba(252, 211, 77, 0.10); color: var(--action-pill-warn-fg); }
:root[data-theme="dark"] .sm-row-label-move   { background: rgba(78, 161, 238, 0.16); color: var(--accent); }
:root[data-theme="dark"] .sm-row-label-upload { background: rgba(74, 222, 128, 0.12); color: var(--ok-soft-fg); }

/* Hide the legacy .sm-row-suggest / .sm-row-name styles by reusing class
   names only via the new structure. The old classes are no longer emitted. */

/* ════════════════════════════════════════════════════════════════
   SMART MOVE row — Option B (Sam, 2026-05-14)
   • Source pill ABOVE filename (not crowding it)
   • Both chips inline-editable, each with ✕ to skip just that step
   • Single Apply per row (does whatever's enabled)
   • Plain-English status header above the queue
   ──────────────────────────────────────────────────────────── */
.sm-row {
  display: block;                  /* override the old grid */
  padding: 12px 14px;
}
/* .sm-row-source-pill: the 2026-06-27 card redesign turned this into a quiet
   text label — the superseded uppercase-tag rule + its dark override were
   deleted in P2.1 (census §5); the ONE live rule sits with the card block. */
.sm-row-header {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 4px;
}
.sm-row-header .confidence-dot { flex-shrink: 0; }
.sm-row-header > .lucide-icon  { color: var(--text-faint); flex-shrink: 0; }
.sm-row-header .sm-row-original-name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; font-weight: 600; color: var(--text);
  letter-spacing: -0.005em;
}
.sm-row-dismiss {
  background: transparent; border: none; cursor: pointer;
  padding: 2px 4px; border-radius: 4px; color: var(--text-faint);
}
.sm-row-dismiss:hover { background: var(--surface-2); color: var(--text); }

.sm-row-source {
  font-size: 11px; color: var(--text-faint);
  margin-bottom: 10px;
}
.sm-row-source code {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 10.5px; padding: 1px 5px; border-radius: 3px;
  background: var(--surface-2); color: var(--text-dim);
}

.sm-row-plan { display: flex; flex-direction: column; gap: 6px; }
.sm-row-change {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  align-items: center; gap: 8px;
}
.sm-row-change[data-enabled="0"] {
  opacity: 0.45;
}
.sm-row-change[data-enabled="0"] input { text-decoration: line-through; pointer-events: none; }
.sm-row-newname-input,
.sm-row-newpath-input {
  width: 100%;
  padding: 6px 8px;
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11.5px; color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface-2);
  transition: border-color var(--motion-micro), background var(--motion-micro);
}
.sm-row-newname-input:focus,
.sm-row-newpath-input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
}
:root[data-theme="dark"] .sm-row-newname-input,
:root[data-theme="dark"] .sm-row-newpath-input { background: var(--surface-0); }
.sm-row-step-toggle {
  background: transparent; border: none; cursor: pointer;
  width: 24px; height: 24px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-faint);
}
.sm-row-step-toggle:hover { background: var(--surface-2); color: var(--danger-text); }

/* ── Smart Move card — rationalised in line with the design language
   (Jeremy 2026-06-27): capsule pill labels, inline-editable (borderless) values
   that box only on hover/focus, a clean card with a left accent, a pill Apply,
   and a quiet source label. Editing/wiring untouched (values still come from the
   same inputs). ──────────────────────────────────────────────────────────── */
.sm-row { border-radius: var(--radius-panel); border-left: 3px solid var(--accent); }
.sm-row-source-pill {
  display: inline-block; margin-bottom: 6px;
  background: transparent; color: var(--text-faint);
  padding: 0; text-transform: none; letter-spacing: 0;
  font-size: 10px; font-weight: 600;
}
.sm-row-change { grid-template-columns: auto minmax(0, 1fr) auto; }
.sm-row-label {
  height: 22px; min-width: 0; margin-top: 0;
  padding: 0 10px; border-radius: var(--radius-pill);
  display: inline-flex; align-items: center; line-height: 1;
}
.sm-row-newname-input,
.sm-row-newpath-input {
  border-color: transparent; background: transparent; padding: 5px 6px;
}
.sm-row-newname-input:hover,
.sm-row-newpath-input:hover { background: var(--hover-soft); }
.sm-row-newname-input:focus,
.sm-row-newpath-input:focus { border-color: var(--accent); background: var(--surface); }
.sm-row-step-toggle { width: 20px; height: 20px; opacity: 0.55; }
.sm-row-step-toggle:hover { opacity: 1; }
.sm-row .btn-apply {
  height: 30px; padding: 0 16px; border: 0;
  border-radius: var(--radius-pill);
  background: var(--accent); color: var(--cck-accent-on);
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.sm-row .btn-apply:hover:not(:disabled) { background: var(--accent-hover); }
.sm-row .btn-apply:disabled { background: var(--text-faint); cursor: not-allowed; }

.sm-row-footer {
  display: flex; align-items: center; gap: 8px;
  margin-top: 8px;
}
.sm-row-why {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 5px;
  font-size: 10.5px; color: var(--text-faint); font-style: italic;
  overflow: hidden;
}
.sm-row-why span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sm-row-why .lucide-icon { flex-shrink: 0; }
.sm-row-spacer { flex: 1; }
.sm-row-footer .btn-apply {
  flex-shrink: 0;
  padding: 5px 14px; font-size: 12px; font-weight: 500;
  border-radius: 5px;
  background: var(--accent); color: var(--cck-accent-on); border: 1px solid var(--accent);
  cursor: pointer;
  transition: background var(--motion-micro), transform var(--motion-micro);
}
.sm-row-footer .btn-apply:hover { background: var(--accent-hover); }
.sm-row-footer .btn-apply:active { transform: scale(0.97); }
.sm-row-footer .btn-apply:disabled {
  background: var(--surface-2); color: var(--text-faint);
  border-color: var(--border); cursor: not-allowed;
}

/* Plain-English queue summary lets <strong> stand out a bit */
.sm-queue-header #sm-queue-summary strong {
  color: var(--text); font-weight: 600;
}

/* Hide the legacy row .sm-row-actions container (replaced by .sm-row-footer) */
.sm-row > .sm-row-actions { display: none; }

/* ── Toolbar stub-button fix (Sam 2026-05-14) ──
   `[hidden]` is a UA stylesheet rule (display:none) with LOW specificity.
   `.tb-btn { display: inline-flex }` overrides it, leaving "empty square"
   buttons where stubs sit (btn-refresh, btn-audit, btn-undo, btn-redo).
   One-line fix: !important override at class-level specificity. */
.tb-btn[hidden] { display: none !important; }

/* ── Pane sub-toolbar mini buttons — make icons visible ──
   `.tb-mini` previously had no explicit color → inherited from parent which
   sometimes resolved transparent in dark-mode or styled contexts. Lock it. */
.tb-mini { color: var(--text-secondary, var(--text-dim)); }
.tb-mini:hover { color: var(--text); background: var(--surface-2); }
.tb-mini[aria-pressed="true"] {
  background: var(--accent); color: var(--cck-accent-on);
}
.tb-mini[aria-pressed="true"]:hover { background: var(--accent-hover); }

/* ── Toolbar overflow shed (measure-and-shed, 2026-06-22) ──
   The ResizeObserver (app.js applyToolbarShed) measures whether the toolbar's
   content overflows one row and progressively moves the lowest-priority
   controls into the ⋯ menu by stamping [data-shed] on them, restoring them
   widest-first as the window grows. This replaced the stale hard-coded
   .tb-overflow-{1,2,3} thresholds (built for the pre-v5 control set — they
   shed the wrong/too-little space, so the right chrome wrapped/clipped).
   NEVER shed: the four filter pills, Sync, the user avatar + Sign out.
   Shed order (lowest priority first): Download → theme → grid/Home → ◂Find▸
   → Diff → Dups. A shed control is display:none here and listed in #more-menu. */
#toolbar [data-shed] { display: none !important; }
/* Measuring pass: force a single non-wrapping row so scrollWidth/clientWidth
   reflect true content overflow rather than the wrapped height. Applied for the
   duration of a measure tick only (added then removed synchronously in JS). */
#toolbar.tb-measuring { flex-wrap: nowrap !important; }
#toolbar.tb-measuring .tb-filter-group,
#toolbar.tb-measuring .tb-cluster,
#toolbar.tb-measuring .tb-right-chrome { flex-shrink: 0; }

/* Items that get pushed into the More menu — clones rendered at runtime */
.tb-more-menu .more-overflow-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; cursor: pointer; font-size: 12px;
  color: var(--text); border-radius: 4px;
}
.tb-more-menu .more-overflow-row:hover { background: var(--surface-2); }
.tb-more-menu hr {
  border: none; border-top: 1px solid var(--border);
  margin: 4px 0;
}

/* ── Structure Audit (Inspector AI tab) ── */
:root[data-theme="dark"] .sa-cta-icon {
  background: linear-gradient(135deg, rgba(58,150,232,0.22), rgba(58,150,232,0.06));
}
.sa-cta-icon {
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, rgba(10,109,194,0.12), rgba(10,109,194,0.04));
  color: var(--accent);
}
.sa-cta-body { flex: 1; min-width: 0; }
.sa-cta-title { font-size: 13px; font-weight: 600; color: var(--text); margin: 0; }
.sa-cta-sub   { font-size: 11px; color: var(--text-dim); margin: 2px 0 0; line-height: 1.45; }

/* Saved-audits history list on the CTA — two-line vertical rows that fit
   the narrow Inspector panel (~340px) without overflowing. Click anywhere
   on the row to View; Update + Delete in the ⋯ overflow menu. */
.sa-cta-history {
  flex-basis: 100%;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}
.sa-cta-history-label {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  font-weight: 600;
  color: var(--text-faint);
  text-transform: uppercase;
  margin-bottom: 6px;
}
.sa-cta-history-list {
  display: flex; flex-direction: column; gap: 2px;
}
.sa-cta-history-row {
  display: grid;
  grid-template-columns: 20px 1fr 20px;     /* icon · body · overflow */
  column-gap: 8px;
  align-items: start;
  padding: 8px;
  border-radius: 5px;
  cursor: pointer;
  transition: background var(--motion-micro);
  min-width: 0;                              /* lets children shrink */
}
.sa-cta-history-row:hover { background: var(--surface-2); }
.sa-cta-history-row:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.sa-cta-history-row[data-stale="1"] { opacity: 0.6; cursor: default; }
.sa-cta-history-row[data-stale="1"]:hover { background: transparent; }
.sa-cta-history-icon {
  color: var(--text-faint);
  line-height: 1;
  padding-top: 1px;
}
.sa-cta-history-body {
  min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.sa-cta-history-name {
  font-size: 13px; font-weight: 600;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sa-cta-history-path {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sa-cta-history-meta {
  font-size: 11px; color: var(--text-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sa-cta-history-more {
  background: transparent;
  border: none;
  cursor: pointer;
  width: 20px; height: 20px;
  border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-faint);
  padding: 0;
}
.sa-cta-history-more:hover { background: var(--surface); color: var(--text); }
.sa-cta-history-more:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Overflow menu — anchored absolutely under (or above) the ⋯ button.
   Reuses the existing tb-more-menu visual language but lives outside
   that scope. */
.sa-cta-history-menu {
  position: fixed;
  z-index: 1000;
  background: var(--menu-bg);
  border: 1px solid var(--menu-border);
  border-radius: 5px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.10);
  padding: 4px;
  min-width: 140px;
  display: flex; flex-direction: column;
}
.sa-cta-history-menu-item {
  background: transparent;
  border: none;
  text-align: left;
  font-size: 12px;
  color: var(--text);
  padding: 6px 10px;
  border-radius: 3px;
  cursor: pointer;
}
.sa-cta-history-menu-item:hover { background: var(--hover-soft); }
.sa-cta-history-menu-item-danger { color: var(--dupe-identical); }
.sa-cta-history-menu-item-danger:hover { background: rgba(220,38,38,0.08); }
:root[data-theme="dark"] .sa-cta-history-menu {
  box-shadow: 0 4px 16px rgba(0,0,0,0.45);
}

#structure-audit-result { padding: 0 16px 16px; }
/* Jeremy 2026-05-27: REVERT Iris A10 §C — reinstating the bordered list frame.
   The unframed sticky-progress approach pushed rows past the panel boundary
   visually and the progress bar fell out of view. The framed approach restores
   the brief-13 §C.1 sub-frame: progress bar above + bordered scrollable
   `#sa-live-list` below, both contained within the panel's 16px gutter. */
.sa-thinking {
  padding: 16px 0 12px;
  text-align: center;
  color: var(--text-dim);
  font-size: 12px;
  background: var(--surface);
}
/* Theo P1-11 (2026-05-30): Force/fresh re-audit progress mounts .sa-thinking
   into #ins-ai-cleanup-body (app.js:11029), which has 0 horizontal padding —
   unlike the legacy #structure-audit-result (16px gutter above). So .sa-thinking's
   0 horizontal padding left the progress bar edge-to-edge of the panel. Restore
   the 16px side gutter (Iris A10 §C intent) scoped to this live container; the
   legacy #structure-audit-result path keeps its parent gutter (no double-inset),
   and #sa-live-list (a sibling in #ins-ai-body) is untouched. */
#ins-ai-cleanup-body > .sa-thinking { padding-left: 16px; padding-right: 16px; }
.sa-thinking .ai-thinking-dots { justify-content: center; margin-bottom: 12px; }
.sa-error {
  padding: 16px; border: 1px solid var(--danger-soft-border); background: var(--danger-soft-bg); border-radius: 6px;
  font-size: 12px; color: var(--danger-text);
}
.sa-error-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.sa-error-close {
  background: transparent; border: 1px solid transparent; border-radius: 4px;
  padding: 2px 4px; cursor: pointer; color: var(--danger-text);
  display: inline-flex; align-items: center; justify-content: center;
}
.sa-error-close:hover { background: var(--danger-soft-bg); border-color: var(--danger-soft-border); }
.sa-error p { margin: 6px 0 10px; }
:root[data-theme="dark"] .sa-error { background: var(--danger-soft-bg); border-color: var(--danger-soft-border); color: var(--action-pill-danger-fg); }

.sa-result-header {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  margin-bottom: 14px;
}
/* v2 layout: actions on top row (Document + CSV grouped, ✕ on the right),
   exec summary in the row below with full width to breathe. */
.sa-result-header-v2 {
  display: block;   /* override the flex from .sa-result-header */
}
.sa-result-header-v2 .sa-result-actions {
  display: flex; gap: 6px; align-items: center;
  margin-bottom: 12px;
}
.sa-result-actions-spacer { flex: 1; }
.sa-result-summary-block {
  background: var(--surface-2);
  border-left: 3px solid var(--accent);
  border-radius: 0 6px 6px 0;
  padding: 14px 16px;
}
.sa-result-summary-block .sa-result-title {
  font-size: 11px; font-weight: 600; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: 0.06em;
  margin: 0 0 8px;
}
.sa-result-summary-block .sa-result-summary {
  font-size: 12.5px; color: var(--text); line-height: 1.6;
  margin: 0 0 10px;
}
.sa-result-summary-block .sa-result-summary:last-of-type { margin-bottom: 8px; }
.sa-result-summary-block .sa-result-meta {
  font-size: 11px; color: var(--text-faint); margin: 8px 0 0;
}
.sa-result-title   { font-size: 13px; font-weight: 600; margin: 0 0 4px; }
.sa-result-summary { font-size: 11.5px; color: var(--text-dim); line-height: 1.45; margin: 0; }
.sa-result-tabs    { display: flex; gap: 0; flex-shrink: 0; border: 1px solid var(--border); border-radius: 5px; overflow: hidden; }
.sa-tab {
  background: transparent; border: none; cursor: pointer;
  padding: 4px 10px; font-size: 11px; color: var(--text-dim);
}
.sa-tab.active { background: var(--accent); color: var(--on-solid); }
.sa-rows-toolbar {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 10px; font-size: 11px; color: var(--text-dim);
}
.sa-rows-toolbar .sa-rows-summary { flex: 1; }

.sa-row {
  padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 6px;
  margin-bottom: 6px;
  background: var(--surface);
}
.sa-row-from, .sa-row-to {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 4px; font-size: 11.5px;
}
.sa-row-label {
  flex-shrink: 0;
  font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 1px 6px; border-radius: 3px;
  background: rgba(217, 119, 6, 0.10); color: var(--action-pill-warn-fg);
  min-width: 42px; text-align: center;
}
.sa-row-label-to { background: rgba(10,109,194,0.10); color: var(--accent); }
.sa-row-from code {
  font-family: 'SF Mono', Consolas, monospace; font-size: 11px;
  background: var(--surface-2); padding: 2px 6px; border-radius: 3px;
  color: var(--text-dim);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sa-row-to-input {
  flex: 1;
  font-family: 'SF Mono', Consolas, monospace; font-size: 11px;
  padding: 4px 6px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface);
}
.sa-row-to-input:focus { outline: none; border-color: var(--accent); }
.sa-row-reason { font-size: 10.5px; color: var(--text-faint); font-style: italic; margin: 4px 0 8px; }
.sa-row-actions { display: flex; gap: 6px; justify-content: flex-end; }

.sa-row-applied { background: linear-gradient(180deg, rgba(22,163,74,0.05), transparent); border-color: rgba(22,163,74,0.3); }
.sa-row-skipped { opacity: 0.5; }
.sa-row-failed  { background: var(--danger-soft-bg); border-color: var(--danger-soft-border); }
.sa-row-applying { opacity: 0.7; }

.sa-tree {
  padding: 12px; background: var(--surface-2); border-radius: 6px;
  font-size: 11.5px;
}
/* Legend row above the proposed tree, explaining the action chips. */
.sa-tree-legend {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 0 0 10px; border-bottom: 1px solid var(--border); margin-bottom: 10px;
}
.sa-legend-chip {
  font-size: 10px; padding: 2px 6px; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 3px;
  color: var(--text-dim); background: var(--surface-3);
}
.sa-legend-new      { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.sa-legend-renamed  { background: var(--sky-soft-bg); color: var(--sky-soft-fg); }
.sa-legend-moved    { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.sa-legend-both     { background: var(--pink-soft-bg); color: var(--pink-soft-fg); }
.sa-legend-kept     { background: transparent; color: var(--text-faint); border: 1px dashed var(--border); }

/* Tree rows: monospaced prefix column draws ├── └── │   lines; name column
   takes remaining space; note column hugs the right edge with the action
   chip + rationale. */
.sa-tree-grid { display: flex; flex-direction: column; }
.sa-tree-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 8px;
  padding: 3px 6px;
  border-radius: 4px;
  transition: background var(--motion-micro);
}
.sa-tree-row:hover { background: rgba(10,109,194,0.06); }
.sa-tree-row[data-action="rename"]      { background: linear-gradient(to right, transparent 60%, rgba(186,230,253,0.30)); }
.sa-tree-row[data-action="move"]        { background: linear-gradient(to right, transparent 60%, rgba(253,230,138,0.30)); }
.sa-tree-row[data-action="rename+move"] { background: linear-gradient(to right, transparent 60%, rgba(244,212,225,0.40)); }
.sa-tree-row[data-action="new"]         { background: linear-gradient(to right, transparent 60%, rgba(187,247,208,0.30)); }
.sa-tree-prefix {
  font-family: 'SF Mono', Consolas, monospace;
  white-space: pre;
  color: var(--text-faint);
  font-size: 11px;
  background: transparent; padding: 0;
}
.sa-tree-name { font-weight: 500; color: var(--text); word-break: break-word; }
.sa-tree-note {
  display: flex; align-items: center; gap: 6px;
  font-size: 10.5px; color: var(--text-dim);
  justify-self: end;
  max-width: 50%;
}
.sa-tree-reason {
  font-style: italic; color: var(--text-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 280px;
}
.sa-tree-chip {
  font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 3px;
  flex-shrink: 0;
}
.sa-tree-chip-new      { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.sa-tree-chip-renamed  { background: var(--sky-soft-bg); color: var(--sky-soft-fg); }
.sa-tree-chip-moved    { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.sa-tree-chip-both     { background: var(--pink-soft-bg); color: var(--pink-soft-fg); }
.sa-tree-chip-kept     { display: none; }   /* unchanged rows get no chip — quieter list */
/* Legacy single-line renderer kept around in case other code paths still use it */
.sa-tree-line { white-space: pre; color: var(--text); line-height: 1.5; font-family: 'SF Mono', Consolas, monospace; font-size: 11px; }

:root[data-theme="dark"] .sa-cta-icon { background: linear-gradient(135deg, rgba(78,161,238,0.14), rgba(78,161,238,0.04)); color: var(--accent); }
:root[data-theme="dark"] .sa-row-from code, :root[data-theme="dark"] .sa-tree { background: var(--surface-0); }

/* ── Smart Move row: applied confirmation + fade-out ── */
.sm-row.sm-row-applied .sm-row-check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--ok); color: var(--on-solid);
  flex-shrink: 0;
}
.sm-row.sm-row-applied .sm-row-header-done .sm-row-original-name {
  color: var(--text-dim); text-decoration: line-through;
  font-weight: 500;
}
.sm-row.sm-row-applied .sm-row-done-sub {
  font-size: 11px; color: var(--text-dim);
  padding-left: 26px; margin-top: 2px;
}
.sm-row.sm-row-applied .sm-row-done-sub code {
  font-family: 'SF Mono', Consolas, monospace; font-size: 10.5px;
  background: var(--surface-2); padding: 1px 5px; border-radius: 3px;
  color: var(--text);
}
.sm-row.sm-row-fading-out {
  opacity: 0;
  transform: translateY(-4px);
  max-height: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0;
  overflow: hidden;
  transition: opacity var(--motion-duration) var(--motion-easing),
              transform var(--motion-duration) var(--motion-easing),
              max-height var(--motion-duration) var(--motion-easing),
              padding var(--motion-duration) var(--motion-easing),
              margin var(--motion-duration) var(--motion-easing);
}

/* D-19 Phase 1 v2 Day 4 (batch 76): the old .ins-ai-body-split family
   (split layout, top/bottom zones, splitter, splitter-grip, chat-header /
   chat-title inside the AI body) is gone. Chat lives in its own rail tab;
   Smart Move queue + dropzone live in their own rail tab. The Structure
   Audit eyebrow + Smart Move queue eyebrow are no longer needed (the AI
   Cleanup tab body is single-purpose now). #structure-audit-cta keeps its
   default styling without the eyebrow. */

/* Structure Audit CTA inside the AI Cleanup body — kept minimal styling. */
#structure-audit-cta {
  margin-top: 12px;
}

.ins-chat {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 16px;
  display: flex; flex-direction: column; gap: 8px;
}
/* The .ins-chat-form already exists in main.css from earlier — these new
   selectors above just slot it into the new bottom zone. */

/* ── Structure audit progress + result polish ── */
/* Iris brief-13 §C.1 (Batch 13D): the `.sa-live-preview` frame container
   (border + radius + max-height:280px + overflow:hidden) is DELETED.
   Phase B-arch unified the runner — every streaming row IS a final row,
   so the "live preview" sub-frame is now wrong. Streaming rows render
   directly into the inspector body via _appendAuditLiveRow which now
   appends them as plain block children of the active list container.
   The .sa-live-row* utility classes are also gone; the row chrome moved
   to a minimal inline rule below so the live-mount tag/from/to still
   read sensibly while the audit is streaming and the unified rows have
   not yet repainted. */
/* Jeremy 2026-05-27: bordered scrollable streaming list frame.
   - Border is invisible (matches panel bg) — frame edges shouldn't read.
   - Dynamic height: flex-fills the available inspector panel space, leaves
     16px below the frame to the panel bottom edge.
   - Auto-scrolls to bottom on each append (handled in _appendAuditLiveRow).
   Parent chain (#structure-audit-result + #ins-ai-body) needs to be a
   flex column with min-height:0 for the fill to work. */
#sa-live-list {
  border: 1px solid var(--surface);
  border-radius: 6px;
  background: var(--surface);
  flex: 1 1 auto;
  min-height: 120px;
  overflow-y: auto;
  padding: 4px 0;
  margin-top: 8px;
  margin-bottom: 16px;
}
/* Make the parent containers flex columns so the list fills the available
   height between the sticky progress band and the panel bottom. Scoped to
   the audit-streaming context so other tab layouts aren't disturbed. */
#structure-audit-result:has(> #sa-live-list) {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
#ins-ai-body:has(> #structure-audit-result > #sa-live-list) {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.sa-live-row {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 12px;
  font-size: 11.5px;
  white-space: nowrap; overflow: hidden;
}
/* .sa-live-tag geometry rides the shared .wx-kind-tag grammar (P2.1);
   fills re-tokenised onto the §3.6 action-pill families. */
.sa-live-tag { flex-shrink: 0; }
.sa-live-tag[data-kind="rename"]      { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.sa-live-tag[data-kind="move"]        { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.sa-live-tag[data-kind="rename+move"] { background: var(--violet-soft-bg);        color: var(--violet-soft-fg); }
.sa-live-tag[data-kind="delete"]      { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.sa-live-tag[data-kind="merge"]       { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }
.sa-live-from, .sa-live-to {
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11px;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis;
  flex: 1 1 auto; min-width: 0;
  background: transparent; padding: 0;
}
.sa-live-arrow { color: var(--text-faint); flex-shrink: 0; }

/* Determinate audit progress bar — climbs toward 95% over ~60s then snaps
   to 100% on completion. Replaces the old indeterminate cycler. */
.sa-progress {
  position: relative;
  width: 100%; height: 6px;
  background: rgba(10,109,194,0.10);
  border-radius: 3px;
  overflow: visible;
  margin-bottom: 18px;
}
.sa-progress-bar {
  /* Phase 3C: route to --row-progress-bar token (matches audit progress). */
  height: 100%; width: 0%;
  background: var(--row-progress-bar);
  border-radius: 3px;
  transition: width var(--motion-duration) var(--motion-easing);
}
.sa-progress-pct {
  position: absolute; right: 0; top: 8px;
  font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  line-height: 1;
}
.sa-thinking-title { font-size: 13px; font-weight: 600; margin: 0; color: var(--text); }
.sa-thinking-sub   { font-size: 11.5px; color: var(--text-dim); margin: 4px 0 0; }

.sa-result-title-block { flex: 1; min-width: 0; }
.sa-result-actions { display: flex; gap: 6px; flex-shrink: 0; }
.sa-result-meta {
  font-size: 11px; color: var(--text-faint); margin: 6px 0 0;
}
.sa-stats {
  display: flex; gap: 10px; flex-wrap: wrap;
  padding: 10px 0; margin: 8px 0 4px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  font-size: 11.5px;
}
.sa-stat {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--text-dim);
}
.sa-stat strong { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.sa-rows-help {
  flex: 1; min-width: 0;
  font-size: 11px; color: var(--text-faint); line-height: 1.5;
}
/* .sa-row-action-tag geometry rides the shared .wx-kind-tag grammar (P2.1). */
.sa-row-action-tag { margin-bottom: 6px; }
/* Iris brief-12 §4: same re-tokenisation as .aw-row-label-action above —
   the sa-row-action-tag selector targets the same pill on the legacy
   Structure-audit list, so it inherits the same --action-pill-* family. */
.sa-row[data-action-kind="rename"]      .sa-row-action-tag,
.sa-row[data-action-kind="naming"]      .sa-row-action-tag { background: var(--action-pill-warn-bg);   color: var(--action-pill-warn-fg); }
.sa-row[data-action-kind="move"]        .sa-row-action-tag,
.sa-row[data-action-kind="rename+move"] .sa-row-action-tag { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
.sa-row[data-action-kind="delete"]      .sa-row-action-tag { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.sa-row[data-action-kind="merge"]       .sa-row-action-tag { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }
.sa-row[data-action-kind="inbox"]       .sa-row-action-tag { background: var(--action-pill-info-bg);   color: var(--action-pill-info-fg); }
/* Iris brief-14 §B.3 — CHECK pill on legacy structure-audit list. */
.sa-row[data-action-kind="check-folder"] .sa-row-action-tag { background: var(--action-pill-check-bg); color: var(--action-pill-check-fg); }
.sa-stat-merge  { background: var(--action-pill-merge-bg);  color: var(--action-pill-merge-fg); }   /* P2.1: rgba tint → the §3.6 token pair (sibling sweep of the kind-tag fills) */
.sa-stat-delete { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.sa-row-reason {
  display: flex; align-items: flex-start; gap: 5px;
  font-size: 10.5px; color: var(--text-faint); font-style: italic;
  margin: 4px 0 8px;
}
.sa-row-reason .lucide-icon { color: var(--text-faint); flex-shrink: 0; margin-top: 1px; }

.sa-tree-help {
  font-size: 11px; color: var(--text-faint);
  margin: 0 0 10px;
}

/* Iris brief-12 §4: dark-mode override block for sa-row-action-tag
   deleted — --action-pill-* tokens carry their own dark-mode values. */

/* ════════════════════════════════════════════════════════════════
   BRIEF #3 v2 — Phase 3D Toast + Phase 3D-bis Confirm-modal
   (Iris spec §3D / §3D-bis, locked 2026-05-18)
   ──────────────────────────────────────────────────────────── */

/* ── Toast container — bottom-right, 16px from edges, 8px gap stack ── */
/* The right edge offsets by the resolved Inspector width (published as
   --inspector-resolved-w by inspector.js on every state change + resize).
   Without this, expanding the Inspector hides toasts behind the chat panel
   (Jeremy smoke test 2026-05-19). Fallback 16px = Inspector not mounted. */
.toast-container {
  position: fixed;
  bottom: 16px;
  /* Jeremy live feedback 2026-06-25: the bottom-RIGHT toast overlapped the walk's
     right-aligned Apply/Ignore buttons (and the undo toast's Undo button obscured
     them). Anchored bottom-LEFT so it clears the right-aligned action row. The
     inspector lives on the right, so the left edge is always free of it too. */
  left: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 1400;        /* above confirm-modal (1300) by design — error toasts must outrank dismissable scrims */
  pointer-events: none; /* let clicks fall through gaps to underlying UI */
  max-width: calc(100vw - 32px);
}
.toast-container .toast { pointer-events: auto; }

/* ── Walk-scoped undo toast (Iris spec 2026-06-25 §2) ──────────────────────
   When the step-through undo toast fires WHILE the walk panel is mounted, the
   container is appended INTO #audit-walk-panel (which is position:relative) and
   carries this class. Centred horizontally, parked just below the snippet's last
   row (--aw-snippet-bottom, panel-relative, published by toast.js + the walk
   scroll listener). Falls back to the body-level .toast-container above when the
   walk panel isn't mounted. */
.toast-container--walk {
  position: absolute;
  left: 50%; transform: translate(-50%, -50%);
  top: var(--aw-snippet-bottom, 62%); bottom: auto; right: auto;
  width: auto; align-items: center;
  z-index: 30;
}
.toast-container--walk .toast { margin: 0 auto; }

/* ── Toast base ── */
.toast {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-width: 280px;
  max-width: 420px;
  padding: 12px 16px;
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--elev-1);
  font-size: 13px;
  line-height: 1.4;
  /* Enter: 200ms slide-up + fade (motion tokens) */
  animation: toast-enter var(--motion-duration) var(--motion-easing) both;
}
.toast.is-exiting {
  /* Exit: 200ms fade only — named one-shot (linear, not easing — §4 row 5) */
  animation: toast-exit 200ms linear forwards;
}

.toast-icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.toast-icon .lucide-icon,
.toast-icon svg {
  width: 16px;
  height: 16px;
  stroke-width: 2;
}
.toast-label {
  flex: 1 1 auto;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.toast-action {
  flex-shrink: 0;
  background: transparent;
  border: none;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  color: var(--accent);
  transition: background-color var(--motion-duration) var(--motion-easing);
}
.toast-action:hover { background: var(--row-hover); }
.toast-action:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.toast-action[disabled],
.toast-action.is-stale {
  color: var(--text-faint);
  cursor: not-allowed;
}
.toast-action.is-stale:hover { background: transparent; }

.toast-dismiss {
  flex-shrink: 0;
  background: transparent;
  border: none;
  padding: 4px;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  transition: background-color var(--motion-duration) var(--motion-easing);
}
.toast-dismiss:hover { background: var(--row-hover); color: var(--text); }
.toast-dismiss:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── Toast variants ── */
.toast.toast-info    .toast-icon { color: var(--accent); }
.toast.toast-success .toast-icon { color: var(--success-text); }
.toast.toast-warning {
  background: var(--warning-chip-bg);
  color: var(--warning-chip-fg);
}
.toast.toast-warning .toast-icon { color: var(--warning-chip-fg); }
.toast.toast-warning .toast-action { color: var(--warning-chip-fg); }
.toast.toast-error .toast-icon { color: var(--btn-danger-bg); }
.toast.toast-error .toast-action {
  color: var(--on-solid);
  background: var(--btn-danger-bg);
}
.toast.toast-error .toast-action:hover { background: var(--btn-danger-hover); }
.toast.toast-action-with-undo {
  /* Jeremy smoke test 2026-05-19 (round 2): the white toast was hard to
     notice. Strong 4px left border in --accent + bolder Undo button so it
     reads as "actionable" at a glance, not as a status whisper. */
  border-left: 4px solid var(--accent);
  padding-left: 12px;
  background: var(--surface);
  box-shadow: var(--elev-2, 0 6px 20px rgba(0,0,0,0.18));
}
.toast.toast-action-with-undo .toast-icon { color: var(--accent); }
.toast.toast-action-with-undo .toast-action {
  background: var(--accent);
  color: var(--on-solid);
  font-weight: 600;
  padding: 6px 12px;
}
.toast.toast-action-with-undo .toast-action:hover { background: var(--accent-hover, var(--accent)); filter: brightness(0.92); }
.toast.toast-action-with-undo .toast-action.is-stale {
  background: var(--text-faint); color: var(--on-solid); opacity: 0.6;
}

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

@media (prefers-reduced-motion: reduce) {
  .toast,
  .toast.is-exiting { animation: none; }
}

/* ── Confirm-modal — Phase 3D-bis ── */
.confirm-modal {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 1300; /* above .settings-sheet (1200): a confirm invoked from Settings (preview→real) must stack on top */
}
/* 'low' positioning variant (Jeremy live feedback 2026-06-25 — "the confirm box
   is in front of the tree, so needs to move down so it's not in the way"). Only
   the step-through delete-confirm opts in (ConfirmModal.show({ position: 'low' }));
   every other confirm stays centred. Anchors the card to the bottom of the
   viewport so the RESULT snippet + the pulsing/dissolving anchor stay visible
   while the user reads the dialog. Scrim still covers the full viewport. */
.confirm-modal-low {
  place-items: end center;     /* bottom-anchored, horizontally centred */
}
.confirm-modal-low .confirm-modal-card {
  margin-bottom: 88px;         /* clear the walk pane's Apply/Ignore action row */
}

/* 'walk' positioning variant (Iris spec 2026-06-25 §3 — Jeremy: "in the middle of
   the right pane … equidistant between the bottom of the tree and top of the apply
   ignore buttons … not obscure anything"). The step-through DELETE confirm opts in
   (ConfirmModal.show({ position: 'walk' })) when the walk panel is mounted. The root
   is appended INTO #audit-walk-panel (position:relative); the card floats absolutely,
   centred on --aw-gap-mid (panel-relative midpoint of the white gap between the
   snippet's last row and the Apply/Ignore footer, published by confirm-modal.js at
   show + on resize). Scrim stays (transparent → no dim) so the snippet + buttons
   read through; the card floats via its own shadow + border. Band-3 degrade falls
   back to the body-level .confirm-modal-low above. */
.confirm-modal--walk {
  position: absolute; inset: 0; display: block; z-index: 40;
}
.confirm-modal--walk .confirm-modal-scrim {
  background: transparent;     /* NO dim — snippet + Apply/Ignore stay legible */
}
.confirm-modal--walk .confirm-modal-card {
  position: absolute;
  left: 50%; top: var(--aw-gap-mid, 60%); transform: translate(-50%, -50%);
  max-width: 360px; width: calc(100% - 48px);
  padding: 16px 20px;
  box-shadow: var(--elev-2); border: 1px solid var(--border);
}
.confirm-modal--walk .confirm-modal-title { margin-bottom: 4px; }
.confirm-modal--walk .confirm-modal-body  { margin-bottom: 12px; }
/* Motion caveat (spec §6): the shared confirm-card-enter keyframe animates
   `transform: scale()`, which would clobber the centring translate above. The
   --walk enter keyframe bakes the translate INTO the scale so they don't fight. */
.confirm-modal--walk .confirm-modal-card {
  animation: confirm-card-enter-walk var(--motion-duration) var(--motion-easing) both;
}
.confirm-modal-scrim {
  position: absolute;
  inset: 0;
  background: var(--scrim);
  animation: confirm-scrim-enter var(--motion-duration) var(--motion-easing) both;
}
.confirm-modal.is-exiting .confirm-modal-scrim {
  animation: confirm-scrim-exit 150ms linear forwards;
}
/* Wide variant (P1.4 t5): confirms carrying a structured review list (the
   WorxConfirm items list — VAT seeds, payables batches) get the 560px card
   the list was designed for. Opt-in via ConfirmModal.show({ wide: true }). */
.confirm-modal-wide .confirm-modal-card { max-width: 560px; }
.confirm-modal-card {
  position: relative;
  max-width: 440px;
  width: calc(100vw - 32px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--elev-2);
  padding: 24px;
  /* Enter 200ms scale 0.96→1 + fade (motion tokens) */
  animation: confirm-card-enter var(--motion-duration) var(--motion-easing) both;
}
.confirm-modal.is-exiting .confirm-modal-card {
  /* Exit: 150ms linear fade only (§4 row 5) */
  animation: confirm-card-exit 150ms linear forwards;
}
.confirm-modal-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 8px;
}
.confirm-modal-body {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
  margin-bottom: 16px;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.confirm-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.confirm-modal-btn {
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  transition: background-color var(--motion-duration) var(--motion-easing),
              border-color var(--motion-duration) var(--motion-easing);
}
.confirm-modal-btn:hover { background: var(--row-hover); }
.confirm-modal-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.confirm-modal-btn.is-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-solid);
}
.confirm-modal-btn.is-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.confirm-modal-btn.is-destructive {
  background: var(--btn-danger-bg);
  border-color: var(--btn-danger-bg);
  color: var(--on-solid);
}
.confirm-modal-btn.is-destructive:hover {
  background: var(--btn-danger-hover);
  border-color: var(--btn-danger-hover);
}

@keyframes confirm-scrim-enter { from { opacity: 0; } to { opacity: 1; } }
@keyframes confirm-scrim-exit  { from { opacity: 1; } to { opacity: 0; } }
@keyframes confirm-card-enter {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}
/* --walk enter: bakes the centring translate into the scale so the keyframe
   doesn't clobber the static `transform: translate(-50%,-50%)` (spec §6). */
@keyframes confirm-card-enter-walk {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.96); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes confirm-card-exit {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .confirm-modal-scrim,
  .confirm-modal-card,
  .confirm-modal--walk .confirm-modal-card,
  .confirm-modal.is-exiting .confirm-modal-scrim,
  .confirm-modal.is-exiting .confirm-modal-card { animation: none; }
}

/* ── ⌘K command palette (P2.2) — ConfirmModal chrome family ──────────────────
   A centred palette, not an anchored menu (ui/popover is for menus). Shares
   the confirm scrim/card keyframes and tokens; sits above the settings sheet
   (1200) and below ConfirmModal (1300) so a confirm invoked by a palette
   action stacks on top. */
.cmdk {
  position: fixed; inset: 0; z-index: 1250;
  display: flex; justify-content: center; align-items: flex-start;
}
.cmdk-scrim {
  position: absolute; inset: 0; background: var(--scrim);
  animation: confirm-scrim-enter var(--motion-duration) var(--motion-easing) both;
}
.cmdk.is-exiting .cmdk-scrim { animation: confirm-scrim-exit 150ms linear forwards; }
.cmdk-card {
  position: relative; margin-top: 12vh;
  width: min(560px, calc(100vw - 32px));
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: var(--elev-2); overflow: hidden;
  animation: confirm-card-enter var(--motion-duration) var(--motion-easing) both;
}
.cmdk.is-exiting .cmdk-card { animation: confirm-card-exit 150ms linear forwards; }
.cmdk-inputrow {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px; border-bottom: 1px solid var(--border); color: var(--text-dim);
}
.cmdk-inputrow svg { width: 15px; height: 15px; flex: none; }   /* pinned — lucide repaint ignores data-size */
.cmdk-input {
  flex: 1; min-width: 0; border: 0; outline: none; background: transparent;
  color: var(--text); font-size: 15px; font-family: inherit;
}
.cmdk-input::placeholder { color: var(--text-faint); }
.cmdk-esc {
  flex: none; font-size: 11px; color: var(--text-dim);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 2px 6px;
}
.cmdk-list { max-height: min(420px, 56vh); overflow-y: auto; padding: 8px; }
.cmdk-list .empty-state { padding: 24px 16px; }
.cmdk-group { font-size: 11px; font-weight: 600; color: var(--text-dim); padding: 8px 8px 4px; }
.cmdk-item {
  display: flex; align-items: baseline; gap: 12px;
  padding: 8px; border-radius: var(--radius); cursor: pointer;
}
.cmdk-item:hover { background: var(--row-hover); }
.cmdk-item.cmdk-active { background: var(--row-sel); }
.cmdk-title { flex: 1; min-width: 0; font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmdk-hint  { flex: none; max-width: 55%; font-size: 12px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmdk-foot {
  display: flex; gap: 16px; padding: 8px 16px;
  border-top: 1px solid var(--border); font-size: 11px; color: var(--text-dim);
}
@media (prefers-reduced-motion: reduce) {
  .cmdk-scrim, .cmdk-card,
  .cmdk.is-exiting .cmdk-scrim, .cmdk.is-exiting .cmdk-card { animation: none; }
}

/* ── New Document dialog (controlled creation) — Domain A ─────────────── */
.ndoc-overlay {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: center; justify-content: center;
  background: var(--scrim);
}
.ndoc-box {
  width: 420px; max-width: calc(100vw - 32px);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow);
  padding: 20px;
}
.ndoc-title-h { margin: 0 0 14px; font-size: 16px; font-weight: 600; }
.ndoc-field { margin-bottom: 14px; }
.ndoc-label { display: block; font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-dim); margin-bottom: 6px; }
.ndoc-types { display: flex; gap: 6px; }
.ndoc-type {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  height: 34px; padding: 0 8px; font-size: 12px; cursor: pointer;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
}
.ndoc-type:hover { background: var(--btn-secondary-hover, var(--surface-3)); }
.ndoc-type.active { background: var(--accent); color: var(--on-solid); border-color: var(--accent); }
.ndoc-titlein, .ndoc-doctype, .ndoc-project {
  width: 100%; height: 34px; padding: 0 10px; font-size: 13px; box-sizing: border-box;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-dark); border-radius: var(--radius);
}
.ndoc-titlein:focus, .ndoc-doctype:focus, .ndoc-project:focus { outline: none; border-color: var(--accent); }
.ndoc-preview {
  display: flex; align-items: center; gap: 8px;
  background: var(--panel-fill); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 8px 10px; min-height: 18px;
}
.ndoc-name { font-size: 13px; font-family: var(--app-font, inherit); word-break: break-all; flex: 1; }
.ndoc-chip { flex: none; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); white-space: nowrap; }
.ndoc-chip.ok   { background: color-mix(in srgb, var(--success) 14%, transparent); color: var(--success-text); }
.ndoc-chip.warn { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.ndoc-dest { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-dim); }
.ndoc-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }



/* ── Document policy editor (Settings → Document policy) ──────────────────
   Jeremy 2026-06-29 redesign: roomier cards, an obvious Values editor, a
   tidy control grid, consistent 32px buttons, and a catalogue table that
   doesn't clip. */
.docpol-h3 { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  margin: 24px 0 4px; color: var(--text-dim); }
.docpol-h3:first-child { margin-top: 0; }
.docpol-h3-desc { font-size: 12px; line-height: 1.5; color: var(--text-faint); margin: 0 0 12px; max-width: 60ch; }
.docpol-h3-desc b { color: var(--text-dim); font-weight: 600; }

/* Metadata category cards */
.docpol-fields { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.docpol-field { border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; background: var(--surface); }
.docpol-field-head { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.docpol-flabel {
  flex: 1; min-width: 0; height: 32px; padding: 0 10px; font-size: 14px; font-weight: 600; box-sizing: border-box;
  background: var(--surface); color: var(--text); border: 1px solid transparent; border-radius: var(--radius);
}
.docpol-flabel:hover { border-color: var(--border); }
.docpol-flabel:focus, .docpol-flabel:focus-visible { border-color: var(--accent); outline: none; }
.docpol-kind { flex: none; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-dim); background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 3px 9px; }
.docpol-req { flex: none; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-faint); background: var(--surface-2); border-radius: var(--radius-pill); padding: 3px 9px; }
.docpol-delfield, .docpol-del { flex: none; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  line-height: 1; cursor: pointer; font-size: 13px; background: transparent; color: var(--text-dim);
  border: 1px solid var(--border); border-radius: var(--radius); }
.docpol-delfield:hover, .docpol-del:hover { color: var(--danger-text); border-color: var(--danger-text); background: var(--surface); }

/* control grid: auto-populate | default | user-can-edit */
.docpol-field-grid { display: grid; grid-template-columns: 1fr 1fr auto; gap: 14px; align-items: end; }
.docpol-fl { display: flex; flex-direction: column; gap: 6px; min-width: 0; font-size: 11px; font-weight: 600; color: var(--text-dim); }
.docpol-fl select, .docpol-defwrap select, .docpol-defwrap input[type=text] {
  height: 32px; width: 100%; min-width: 0; box-sizing: border-box; font-size: 13px; font-weight: 400; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-dark); border-radius: var(--radius); padding: 0 9px; }
.docpol-defwrap { display: block; }
.docpol-fedit { display: inline-flex; align-items: center; gap: 7px; height: 32px; white-space: nowrap;
  font-size: 13px; font-weight: 500; color: var(--text); }
.docpol-fedit input { width: 15px; height: 15px; accent-color: var(--accent); }
.docpol-inline { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text); }

/* Values editor — full width, roomy, clearly labelled, never clipped */
.docpol-values { display: block; margin-top: 14px; font-size: 11px; font-weight: 600; color: var(--text-dim); }
.docpol-values .hint { font-weight: 400; color: var(--text-faint); margin-left: 7px; }
.docpol-fvalues { display: block; width: 100%; box-sizing: border-box; margin-top: 7px; min-height: 104px;
  resize: vertical; font-size: 13px; font-weight: 400; line-height: 1.8; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border-dark); border-radius: var(--radius);
  padding: 9px 11px; font-family: inherit; }
.docpol-fvalues:focus, .docpol-fvalues:focus-visible { border-color: var(--accent); outline: none; background: var(--surface); }
.docpol-note { font-size: 12px; line-height: 1.5; color: var(--text-faint); margin: 14px 0 0;
  padding: 9px 11px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); }

/* Unified buttons — every button in the editor is the same 32px height */
.docpol-btn { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 13px; box-sizing: border-box;
  font-size: 13px; font-weight: 500; cursor: pointer; border-radius: var(--radius); white-space: nowrap;
  background: var(--surface); color: var(--text); border: 1px solid var(--border-dark); }
.docpol-btn:hover { background: var(--surface-2); }
.docpol-btn .lucide-icon, .docpol-btn svg { width: 14px; height: 14px; }
.docpol-actions { display: flex; align-items: center; gap: 8px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.docpol-spacer { flex: 1; }
.docpol-actions .docpol-save, .docpol-actions .btn-primary { height: 32px; padding: 0 16px; font-size: 13px; }

/* Document types catalogue table */
.docpol-table { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.docpol-head, .docpol-row { display: grid; grid-template-columns: 1.8fr 1.2fr 1.2fr 1.3fr 30px; gap: 10px;
  align-items: center; padding: 8px 12px; }
.docpol-head { background: var(--surface-2); font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-dim); }
.docpol-row { border-top: 1px solid var(--border); }
.docpol-row:nth-child(even) { background: var(--panel-fill); }
.docpol-label { height: 32px; padding: 0 9px; font-size: 13px; box-sizing: border-box; width: 100%; min-width: 0;
  background: var(--surface); color: var(--text); border: 1px solid var(--border-dark); border-radius: var(--radius); }
.docpol-label:focus-visible { outline: none; border-color: var(--accent); }
.docpol-naming, .docpol-ret, .docpol-conf { height: 32px; font-size: 12px; width: 100%; min-width: 0; box-sizing: border-box;
  background: var(--surface); color: var(--text); border: 1px solid var(--border-dark); border-radius: var(--radius); padding: 0 6px; }


/* ── "Highlight" toolbar toggle OFF — plain tree, no dupe/similar colouring ──
   Jeremy 2026-06-29. #app id + !important beat the dupe rules' own !important.
   Selection / multi-select / Diff styling is untouched. */
#app.dupes-off .tree-row.duplicate .col-name,
#app.dupes-off .tree-row.dupe-current .col-name,
#app.dupes-off .tree-row.dupe-ancestor .col-name,
#app.dupes-off .tree-row.folder-all-dupes .col-name,
#app.dupes-off .tree-row.folder-has-dupes .col-name,
#app.dupes-off .tree-row.folder-similar .col-name {
  color: var(--text) !important; font-weight: 400 !important;
}
#app.dupes-off .tree-row.duplicate:not(.selected):not(.multi-selected),
#app.dupes-off .tree-row.dupe-current:not(.selected):not(.multi-selected),
#app.dupes-off .tree-row.folder-all-dupes:not(.selected):not(.multi-selected),
#app.dupes-off .tree-row.folder-has-dupes:not(.selected):not(.multi-selected),
#app.dupes-off .tree-row.folder-similar:not(.selected):not(.multi-selected) {
  box-shadow: none !important;
}
#app.dupes-off .tree-row.dupe-ancestor:not(.selected):not(.multi-selected) {
  box-shadow: none !important; background: transparent !important;
}

/* ═══ App sidebar — Phase A2 (v0.4 Define §2, DESIGN_LANGUAGE.md) ═══
   The single primary navigation. White surface, hairline border, one accent
   used only on the active item, generous air. body.has-appnav shifts #app
   right, hides the toolbar Home|Files segmented control + brand (the sidebar
   carries both), and hides the cockpit's internal tab grid (the sidebar IS
   that navigation now). px values here join the B4 token migration. */
:root { --appnav-w: 196px; }
#appnav { position: fixed; top: 0; left: 0; bottom: 0; width: var(--appnav-w); background: var(--surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; gap: 1px; padding: 14px 10px 12px; z-index: 900; overflow-y: auto; }
body.has-appnav #app { padding-left: var(--appnav-w); }
body.has-appnav .tb-nav, body.has-appnav .toolbar-left { display: none; }
body.has-appnav .cck-tabs { display: none; }
.an-brand { display: flex; align-items: center; gap: 8px; padding: 2px 8px 14px; font-size: 14px; color: var(--text); }
.an-brand img { width: 22px; height: 22px; }
.an-brand b { font-weight: 600; }
.an-group { font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); padding: 14px 8px 4px; }
.an-item { display: flex; align-items: center; gap: 9px; width: 100%; padding: 7px 8px; border: 0; border-radius: 8px; background: none; color: var(--text-dim); font-size: 13px; font-family: inherit; cursor: pointer; text-align: left; }
.an-item:hover { background: var(--hover-soft); color: var(--text); }
.an-item.an-on { background: var(--cck-accent-soft); color: var(--cck-accent); font-weight: 600; }
.an-item svg { flex: none; }
.an-soon { margin-left: auto; font-size: 9px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); background: var(--chip-bg); border-radius: 999px; padding: 1px 6px; }
.an-spacer { flex: 1; }

/* Arriving-module destination panel (OAS §4: empty states explain themselves) */
.cck-arriving { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; padding: 48px 32px; gap: 12px; }
.cck-arriving svg { color: var(--cck-accent); opacity: 0.7; }
.cck-arriving h3 { margin: 0; font-size: 18px; color: var(--text); }
.cck-arriving p { margin: 0; max-width: 46ch; font-size: 13px; line-height: 1.55; color: var(--text-dim); }
.cck-arriving .an-phase { font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); background: var(--chip-bg); border-radius: 999px; padding: 3px 9px; }

/* ═══ Phase A3 — the Today lens made legible (v0.4 Define §3) ═══ */
.cck-lens-note { font-size: 11px; color: var(--text-faint); padding: 2px 12px 8px; line-height: 1.4; }
.cck-srcchip { font-size: 9px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-dim); background: var(--chip-bg); border-radius: 999px; padding: 1px 7px; flex: none; }
.cck-srcchip-approval { background: var(--cck-accent-soft); color: var(--cck-accent); }

/* Home is pure cockpit (Phase A2 polish): while the overview is open, the
   file-manager toolbar clusters hide — only the right chrome (theme, settings,
   account) stays, so the calm surface isn't topped by Sync/Dups/Diff tools
   that act on the explorer underneath. Files mode restores the full toolbar. */
body.worx-home #toolbar > *:not(.tb-right-chrome) { display: none !important; }

/* ═══ Phase B1 — the Morning Brief ═══ */
.cck-brief .cck-brief-body { font-size: 13px; line-height: 1.65; color: var(--text); padding: 4px 0 14px; max-width: 62ch; white-space: normal; }
.cck-brief-loading { color: var(--text-faint); font-style: italic; }
.cck-brief-h { display: block; font-size: 14px; font-weight: 600; color: var(--text); margin: 12px 0 3px; }
.cck-brief-p { display: block; margin: 0 0 8px; }

/* ═══ P3.5 (COS-2) — the weekly business review (the brief's weekly sibling:
   same cck-work card chrome, the pane's own scroll, tokens only). ═══ */
.cck-review { display: flex; flex-direction: column; min-height: 0; }
.cck-rv-weeks { display: flex; gap: 8px; padding: 2px 0 10px; }
.cck-rv-chip[aria-pressed="true"] { background: var(--cck-accent-soft); border-color: var(--cck-accent); color: var(--cck-accent); }
.cck-rv-body { min-height: 0; overflow: auto; }
.cck-rv-lead { font-size: 13px; color: var(--text); margin: 2px 0 10px; }
.cck-rv-counts { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 6px 14px; margin: 0 0 12px; padding: 0; }
.cck-rv-count { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-dim); border: 1px solid var(--border); border-radius: var(--radius); padding: 7px 10px; background: var(--surface); }
.cck-rv-count svg { width: 13px; height: 13px; flex: 0 0 auto; color: var(--text-faint); }
.cck-rv-count b { margin-left: auto; font-size: 13px; color: var(--text); font-variant-numeric: tabular-nums; }
.cck-rv-note, .cck-rv-sub { font-size: 11.5px; color: var(--text-faint); margin: 8px 0 0; }
.cck-rv-meta { font-size: 11.5px; color: var(--text-dim); margin: 0 0 8px; }
.cck-rv-restore { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-dim); margin: 0 0 8px; }
.cck-rv-restore svg { width: 13px; height: 13px; }
.cck-review .cck-rte { border: 1px solid var(--border); border-radius: var(--radius); }
.cck-review .cck-rte-area { min-height: 260px; max-height: 52vh; overflow: auto; font-size: 13px; line-height: 1.6; }
.cck-review .cck-rte-area h3 { font-size: 14px; margin: 14px 0 4px; }
.cck-rv-h4 { font-size: 12.5px; font-weight: 600; color: var(--text); margin: 14px 0 4px; }
.cck-rv-actlist { margin: 0; padding-left: 18px; font-size: 12.5px; color: var(--text-dim); }
.cck-rv-actlist li { margin: 2px 0; }
.cck-rv-actlist b { color: var(--text); font-weight: 600; }
.cck-rv-bar { padding-top: 12px; }
.cck-rv-bar .cck-act svg, .cck-rv-weeks .cck-act svg { width: 13px; height: 13px; }

/* ═══ P3.6 (COS-3) — end-to-end execution: the Today-rail tracker + the plan
   detail pane (the review pane's chrome family; tokens only, dark derives). ═══ */
.exc-tracker { margin: 0 8px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); overflow: hidden; }
.exc-head { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; color: var(--text-dim); padding: 8px 10px 6px; }
.exc-head svg { width: 13px; height: 13px; color: var(--cck-accent); }
/* P5.1 F3: real <button> inside styled rows/cards — visual no-op reset.
   Used by .exc-body (Today tracker) and .cck-card-title (Recruitment board). */
/* P5.1 F6: screen-reader-only text (the house visually-hidden utility). */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

.cck-plainbtn { background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.cck-plainbtn:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 2px; border-radius: 4px; }
button.exc-body { display: flex; flex-direction: column; gap: 1px; }

.exc-row { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-top: 1px solid var(--border); cursor: pointer; }
.exc-row:hover { background: var(--row-hover); }
.exc-row:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: -2px; }
.exc-dot { width: 8px; height: 8px; border-radius: var(--radius-pill); flex: 0 0 auto; }
.exc-dot-run { background: var(--cck-accent); }
.exc-dot-wait { background: var(--warn); }
.exc-dot-need { background: var(--warn); }
.exc-dot-ok { background: var(--ok); }
.exc-dot-off { background: var(--text-faint); }
.exc-body { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.exc-title { font-size: 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.exc-sub { font-size: 11px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.exc-n { font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.exc-clear { border: 0; background: none; color: var(--text-faint); font-size: 13px; line-height: 1; padding: 2px 4px; cursor: pointer; border-radius: var(--radius); flex: 0 0 auto; }
.exc-clear:hover { color: var(--text); background: var(--hover-soft); }
.exc-pane { display: flex; flex-direction: column; min-height: 0; }
.exc-note { font-size: 12.5px; margin: 2px 0 10px; color: var(--text-dim); }
.exc-note-need { color: var(--warn); }
.exc-note-ok { color: var(--ok); }
.exc-steps { min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 8px; padding: 2px 0; }
.exc-step { display: flex; gap: 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); padding: 10px 12px; }
.exc-step-ic { width: 22px; height: 22px; border-radius: var(--radius-pill); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; flex: 0 0 auto; color: var(--text-faint); margin-top: 1px; }
.exc-step-ic svg { width: 13px; height: 13px; }
.exc-step-done .exc-step-ic { color: var(--ok); border-color: var(--ok-soft-border); background: var(--ok-soft-bg); }
.exc-step-running .exc-step-ic { color: var(--cck-accent); border-color: var(--cck-accent); }
.exc-step-running .exc-step-ic svg { animation: spin 1.2s linear infinite; }
.exc-step-failed .exc-step-ic { color: var(--danger-text); border-color: var(--danger-soft-border); background: var(--danger-soft-bg); }
.exc-step-skipped { opacity: .62; }
.exc-step-body { min-width: 0; flex: 1; }
.exc-step-top { display: flex; align-items: baseline; gap: 8px; }
.exc-step-label { font-size: 13px; color: var(--text); font-weight: 600; min-width: 0; }
.exc-step-status { margin-left: auto; font-size: 10.5px; color: var(--text-dim); flex: 0 0 auto; }
.exc-step-failed .exc-step-status { color: var(--danger-text); }
.exc-step-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; line-height: 1.45; }
.exc-step-acts { display: flex; gap: 10px; margin-top: 4px; }
.exc-step-acts:empty { display: none; }
.exc-pathnote { font-size: 11.5px; color: var(--text-faint); }
.exc-bar { padding-top: 12px; }

.asst-smartmove::-webkit-scrollbar { width: 0; }

/* ═══ M8 — the Project surface (mockup_project-surface.html v5, Define §8) ═══
   One workspace per project. Rules enforced here: one RAG grammar (dot + 3px
   left edge, no washes — rule 12), panels white / surrounds toned (13),
   uniform full-width category rows (9), chevron reveal (10), one button
   system via cck-act/cck-act-filled/cck-linkbtn (11), aligned action footers
   (14), 6px RAG progress bars (16). All colour from tokens — dark derives. */
.pjw { min-height: 0; }
.pjw-rail-title { font-size: 24px; font-weight: 600; letter-spacing: -0.01em; margin: 0; padding: 24px 8px 2px; }
/* Jeremy 2026-07-05: the rail carries a "Projects" heading in line with the
   workspace title to its right — same face, same size (the one type scale). */
.pjw-rail-cap { font-size: 11px; color: var(--text-faint); line-height: 1.45; padding: 0 8px 10px; }
.pjw-rag { width: 9px; height: 9px; border-radius: 50%; flex: none; display: inline-block; }
.pjw-rag-g { background: var(--success); }
.pjw-rag-a { background: var(--warn); }
.pjw-rag-r { background: var(--danger); }

.pjw-head { flex: none; padding: 2px 2px 0; }
.pjw-titlerow { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.pjw-title { font-size: 24px; font-weight: 600; letter-spacing: -0.01em; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pjw-facts { font-size: 13px; color: var(--text-dim); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pjw-health { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; white-space: nowrap; }

.pjw-stepper { display: flex; align-items: center; gap: 4px; margin-top: 12px; flex-wrap: wrap; }
.pjw-step { font-size: 11px; color: var(--text-faint); border: 1px solid var(--border); background: var(--surface-0); border-radius: 999px; padding: 3px 10px; white-space: nowrap; }
.pjw-step-done { color: var(--success-text); border-color: var(--border); }
.pjw-step-on { color: var(--cck-accent-on); background: var(--cck-accent); border-color: var(--cck-accent); font-weight: 600; }
.pjw-step-note { font-size: 11px; color: var(--text-faint); }

.pjw-tabs { display: flex; flex-wrap: wrap; gap: 2px; margin-top: 12px; border-bottom: 1px solid var(--border); } /* P4.1: tabs wrap at high zoom, never clip against the card edge */
.pjw-tab { border: 0; background: transparent; font: inherit; font-size: 13px; color: var(--text-dim); padding: 8px 12px; cursor: pointer; border-bottom: 2px solid transparent; }
.pjw-tab:hover { color: var(--text); }
.pjw-tab:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: -2px; }
.pjw-tab-on { color: var(--text); font-weight: 600; border-bottom-color: var(--cck-accent); }
.pjw-tab-n { font-size: 11px; color: var(--text-dim); background: var(--chip-bg); border-radius: 999px; padding: 0 6px; margin-left: 4px; font-variant-numeric: tabular-nums; }
.pjw-tabnote { flex: none; font-size: 11px; color: var(--text-dim); background: var(--surface-2); border-bottom: 1px solid var(--border); padding: 8px 12px; margin: 0 2px; border-radius: 0 0 var(--radius) var(--radius); line-height: 1.45; }
.pjw-body { flex: 1; min-height: 0; overflow: auto; padding: 16px 2px 24px; }

.pjw-sect-label { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); margin: 24px 0 4px; display: flex; align-items: center; gap: 8px; }
.pjw-sect-label:first-child { margin-top: 0; }
.pjw-caption { font-size: 11px; color: var(--text-dim); line-height: 1.5; margin: 0 0 8px; }
.pjw-chip { font-size: 11px; font-weight: 600; border: 1px solid var(--border); background: var(--surface-0); border-radius: 999px; padding: 2px 9px; color: var(--text-dim); white-space: nowrap; }

/* Overview tiles — each tile IS the door to its tab. */
.pjw-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin-bottom: 8px; }
.pjw-tile { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; text-align: left; font: inherit; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius-panel); padding: 12px 16px; cursor: pointer; box-shadow: var(--elev-1); transition: transform var(--motion-duration) var(--motion-easing), box-shadow var(--motion-duration) var(--motion-easing); }
.pjw-tile:hover { transform: translateY(-1px); box-shadow: var(--elev-2); }
.pjw-tile:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 2px; }
/* Fixed two-line label slot (Jeremy 2026-07-05: "make the bold stats always
   level") — 'CONDITIONS PRECEDENT' wraps, so every label reserves the same
   height and the big values sit on one line across the tiles (rule 14 twin). */
.pjw-tile-l { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); min-height: 32px; display: flex; align-items: flex-start; line-height: 1.45; }
.pjw-tile-v { font-size: 18px; font-weight: 600; color: var(--text); display: inline-flex; align-items: center; gap: 8px; font-variant-numeric: tabular-nums; }
.pjw-tile-s { font-size: 11px; color: var(--text-dim); }
.pjw-flag { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 6px 0; border-bottom: 1px dashed var(--border); }
.pjw-flag:last-of-type { border-bottom: 0; }
.pjw-overfoot { display: flex; align-items: center; gap: 16px; margin-top: 24px; font-size: 11px; color: var(--text-dim); flex-wrap: wrap; }
.pjw-overfoot .cck-act { margin-left: auto; }

/* Diligence — uniform full-width category rows, worst first. */
.pjw-ddbar { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
/* The pipeline strip spans the FULL panel width (Jeremy 2026-07-05: "you
   need the complete length so you can see how long it's going to take"). */
.pjw-pipe { flex: 1 1 100%; order: 9; display: flex; align-items: center; gap: 12px; padding: 4px 0 2px; }
.pjw-pipe-label { font-size: 11px; color: var(--text-dim); white-space: nowrap; flex: none; min-width: 180px; }
.pjw-pipe-bar { flex: 1; margin: 0; }
.pjw-pipe-bar i { transition: width 400ms var(--motion-easing); }
/* Rail footer (Jeremy 2026-07-05): Add-a-project sits directly under the
   list; then the two buttons — stacked, equal width, even spacing. ONE
   filled blue per region (Run all = the rail's act-now); Find = toned. */
.pjw-rail-btns { display: flex; flex-direction: column; gap: 8px; padding: 4px 0 8px; }
.pjw-rail-btns .cck-act { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }

/* Rail rows carry their own live progress while a run is going (Jeremy:
   "see all projects update with progress bars and status in the white boxes"). */
.pjw-rail-pipe { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; padding-top: 6px; }
.pjw-rail-pipe .pjw-pipe-bar { flex: 1; margin: 0; }
.pjw-rail-pipe .pjw-pipe-label { font-size: 11px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 46%; min-width: 0; }
.pjw-pipe-x { border: 0; background: transparent; color: var(--text-faint); font-size: 12px; line-height: 1; padding: 4px; cursor: pointer; border-radius: 50%; flex: none; }
.pjw-pipe-x:hover { color: var(--danger-text); background: var(--danger-soft-bg); }
.pjw-pipe-x:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 1px; }
.pjw-ddmeta { font-size: 11px; color: var(--text-dim); }
.pjw-ddbar-acts { margin-left: auto; display: flex; gap: 8px; }
.pjw-cat { background: var(--surface-0); border: 1px solid var(--border); border-left: 3px solid var(--border); border-radius: var(--radius-panel); padding: 12px 16px; margin-bottom: 8px; box-shadow: var(--elev-1); }
.pjw-cat-r { border-left-color: var(--danger-text); }
.pjw-cat-a { border-left-color: var(--warn); }
.pjw-cat-g { border-left-color: var(--success-text); }
.pjw-cat-h { display: flex; gap: 12px; align-items: center; min-width: 0; }
.pjw-cat-h .pjw-rag { flex: none; }
.pjw-cat-h .pjw-cat-t { flex: 0 1 168px; min-width: 96px; }
.pjw-cat-h .pjw-miss { flex: 1; }
.pjw-cat-h .cck-act { flex: none; }
.pjw-whynot { font-size: 11px; color: var(--text-faint); white-space: nowrap; flex: none; }
.pjw-cat-t { font-size: 15px; font-weight: 600; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pjw-miss { font-size: 13px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.pjw-miss b { color: var(--text); font-weight: 600; }
.pjw-pct { font-size: 13px; color: var(--text-dim); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.pjw-chev { padding: 0; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; }
.pjw-bar { height: 6px; background: var(--row-progress-track); border-radius: 3px; margin-top: 8px; overflow: hidden; }
.pjw-bar i { display: block; height: 6px; border-radius: 3px; }
.pjw-bar-r { background: var(--danger); }
.pjw-bar-a { background: var(--warn); }
.pjw-bar-g { background: var(--success); }

.pjw-analysis { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 4px; }
.pjw-doc { display: grid; grid-template-columns: minmax(160px, 230px) 1fr; gap: 12px; padding: 8px 0; border-bottom: 1px dashed var(--border); font-size: 13px; }
.pjw-doclink { border: 0; background: transparent; padding: 0; font: inherit; font-size: 13px; font-weight: 600; color: var(--cck-accent); cursor: pointer; text-align: left; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pjw-doclink:hover { text-decoration: underline; }
.pjw-doclink:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 2px; }
.pjw-doclink-sm { font-size: 11px; font-weight: 400; }
.pjw-doc-meta { font-size: 11px; color: var(--text-faint); margin-top: 2px; }
.pjw-doc-du { color: var(--text-dim); line-height: 1.5; }
.pjw-doc-rel { font-size: 11px; color: var(--text-faint); margin-top: 3px; }
.pjw-find { display: flex; gap: 8px; align-items: baseline; padding: 8px 0; border-bottom: 1px dashed var(--border); font-size: 13px; }
.pjw-find .pjw-rag { width: 8px; height: 8px; position: relative; top: -1px; }
.pjw-contra { background: var(--danger-soft-bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 12px; font-size: 13px; margin: 12px 0; line-height: 1.5; }
.pjw-contra b { color: var(--danger-text); }

/* P3.4 (R8b/COS-4) — the Model tab's assumption review rows. One grammar per
   row: label + unit chip + confidence + status on the top line, the value
   below it, the verbatim citation with its doc link last; actions right. */
.asm-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px dashed var(--border); font-size: 13px; }
.asm-row:last-child { border-bottom: 0; }
.asm-row-rejected .asm-main { opacity: 0.55; }
.asm-main { min-width: 0; flex: 1; }
.asm-toprow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.asm-label { font-weight: 600; color: var(--text); }
.asm-conf { font-size: 11px; font-weight: 600; border-radius: 999px; padding: 1px 8px; border: 1px solid transparent; cursor: help; }
.asm-conf-g { background: var(--ok-soft-bg); color: var(--ok-soft-fg); border-color: var(--ok-soft-border); }
.asm-conf-a { background: var(--warning-chip-bg); color: var(--warning-chip-fg); border-color: var(--warning-chip-border); }
.asm-conf-r { background: var(--danger-soft-bg); color: var(--danger-text); border-color: var(--danger-soft-border); }
.asm-status { font-size: 11px; font-weight: 600; }
.asm-status-ok { color: var(--success-text); }
.asm-status-off { color: var(--text-faint); }
.asm-valrow { margin: 3px 0 2px; display: flex; align-items: baseline; gap: 8px; }
.asm-val { font-size: 15px; font-variant-numeric: tabular-nums; }
.asm-orig { font-size: 11px; color: var(--text-faint); }
.asm-cite { font-size: 11px; color: var(--text-dim); line-height: 1.5; }
.asm-acts { display: flex; align-items: center; gap: 6px; flex: none; padding-top: 2px; }
.asm-editval { max-width: 260px; }
.pjw-gap { display: grid; grid-template-columns: 12px 1fr auto; gap: 12px; align-items: center; font-size: 13px; padding: 7px 0; border-bottom: 1px dashed var(--border); }
.pjw-gap:last-child { border-bottom: 0; }
.pjw-gap .pjw-rag { width: 8px; height: 8px; justify-self: center; }
.pjw-cp-done { color: var(--text-faint); text-decoration: line-through; }

/* Actions — three lanes, one item grammar (title / source / chip+button). */
.pjw-lanes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-bottom: 8px; }
.pjw-lane { background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius-panel); padding: 12px 16px; box-shadow: var(--elev-1); min-width: 0; }
.pjw-lane-h { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text); margin: 0 0 2px; }
.pjw-act { display: flex; flex-direction: column; padding: 10px 0; border-bottom: 1px dashed var(--border); font-size: 13px; }
.pjw-act:last-child { border-bottom: 0; padding-bottom: 2px; }
.pjw-act-t { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.9em; line-height: 1.45; }
.pjw-act-src { font-size: 11px; color: var(--text-faint); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pjw-act-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }

/* Data room */
.pjw-classify-row { display: flex; align-items: center; gap: 12px; margin: 8px 0; flex-wrap: wrap; }
.pjw-classify-row .pjw-caption { margin: 0; max-width: 52ch; }
.pjw-drhead { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.pjw-drpath { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-dim); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pjw-drpath b { color: var(--text); }
.pjw-drhead .cck-act { margin-left: auto; flex: none; }
.pjw-drb-list { border: 1px solid var(--border); border-radius: var(--radius-panel); background: var(--surface-0); padding: 4px 12px; max-height: 44vh; overflow: auto; }
.pjw-drb-row { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; font: inherit; font-size: 13px; color: var(--text); background: transparent; border: 0; border-bottom: 1px dashed var(--border); padding: 7px 4px; }
.pjw-drb-row:last-child { border-bottom: 0; }
.pjw-drb-dir { cursor: pointer; border-radius: var(--radius); }
.pjw-drb-dir:hover { background: var(--row-hover); }
.pjw-drb-dir:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: -2px; }
.pjw-drb-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pjw-drb-size { margin-left: auto; font-size: 11px; color: var(--text-faint); font-variant-numeric: tabular-nums; }

/* Comms */
.pjw-linked { width: 100%; max-width: 48ch; margin-bottom: 4px; }
.pjw-threadwrap { border-bottom: 1px dashed var(--border); }
.pjw-threadwrap:last-of-type { border-bottom: 0; }
.pjw-thread { display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left; font: inherit; font-size: 13px; color: var(--text); background: transparent; border: 0; padding: 8px 4px; cursor: pointer; border-radius: var(--radius); min-width: 0; }
.pjw-thread:hover { background: var(--row-hover); }
.pjw-thread:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: -2px; }
.pjw-thread-when { font-size: 11px; color: var(--text-faint); flex: none; font-variant-numeric: tabular-nums; }
.pjw-thread-body { padding: 0 4px 12px; }
.pjw-thread-text { font: inherit; font-size: 13px; color: var(--text-dim); white-space: pre-wrap; word-break: break-word; max-height: 40vh; overflow: auto; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin: 0 0 8px; }
.pjw-note { display: flex; gap: 8px; align-items: baseline; font-size: 13px; color: var(--text-dim); padding: 5px 0; border-bottom: 1px dashed var(--border); }
.pjw-note:last-child { border-bottom: 0; }
.pjw-note-ts { font-size: 11px; color: var(--text-faint); flex: none; font-variant-numeric: tabular-nums; }

/* Empty states explain themselves (OAS §4). */
.pjw-empty { max-width: 62ch; padding: 24px 0; text-align: left; line-height: 1.55; }   /* reading-prose delta (left, measured) on the shared empty-state grammar (P2.1) */
.pjw-empty-acts { display: flex; gap: 8px; margin: 12px 0; flex-wrap: wrap; }

/* Rail rows carry the RAG dot + diligence %% before the label. */
/* Project rows (Jeremy 2026-07-05: "% closer to the dots, align all the
   text and dashes"): a fixed grid — dot · %% · name · stage — so every
   column lines up down the rail. Scoped via :has so other rails keep the
   shared space-between layout. */
.cck-frow:has(.pjw-rag) { display: grid; grid-template-columns: 9px 36px minmax(0, 1fr) auto; gap: 8px; align-items: center; }
.cck-frow:has(.pjw-rag) .cck-frow-label { text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: 8px; }
.cck-frow .pjw-rag { margin-right: 0; }
/* Centred in a fixed column so a "--" sits optically under the %%s (Jeremy),
   with clear air between the %% column and the project names. */
.pjw-railpct { font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums; text-align: center; }

/* M8 quick view — the instant document window (shares .cck-fileov chrome). */
.cck-qv-frame { width: min(920px, 92vw); height: 82vh; border: 0; background: var(--surface-0); border-radius: var(--radius); }
.cck-qv-img { max-width: 92vw; max-height: 82vh; border-radius: var(--radius); background: var(--surface-0); }
.cck-qv-text { width: min(860px, 92vw); max-height: 82vh; overflow: auto; margin: 0; padding: 24px; font-size: 13px; line-height: 1.6; color: var(--text); background: var(--surface-0); border-radius: var(--radius); white-space: pre-wrap; word-break: break-word; }
.cck-fileov-bar .cck-act { margin-left: auto; flex: none; }

/* The findings board — every finding + its fix (console "N more"). */
.wxc-board { max-width: 720px; width: min(720px, 92vw); }
.wxc-board-list { max-height: 60vh; overflow: auto; margin: 8px 0; }
.wxc-board-row { display: flex; gap: 12px; align-items: flex-start; padding: 12px 4px; border-bottom: 1px dashed var(--border); }
.wxc-board-row:last-child { border-bottom: 0; }
.wxc-board-row .wxc-rag { margin-top: 5px; }
.wxc-board-body { flex: 1; min-width: 0; }
.wxc-board-t { font-size: 13px; font-weight: 600; line-height: 1.45; }
.wxc-board-d { font-size: 12px; color: var(--text-dim); margin-top: 2px; line-height: 1.5; }
.wxc-board-fix { font-size: 11px; color: var(--text-faint); margin-top: 4px; line-height: 1.5; }
.wxc-board-acts { display: flex; align-items: center; gap: 8px; flex: none; }

/* ── M11-c: THE TIDY-UP (to mockup_tidy-up.html v3.2) ──────────────────── */
.ty-ov { display: flex; align-items: center; justify-content: center; }
.ty-frame { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); width: min(1400px, 96vw); max-height: 92vh; display: flex; flex-direction: column; overflow: hidden; }
.ty-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--border); font-size: 13px; }
.ty-chip { font-size: 10.5px; font-weight: 600; border: 1px solid var(--border); background: var(--surface); border-radius: 999px; padding: 2px 9px; color: var(--text-dim); display: inline-flex; align-items: center; gap: 4px; }
.ty-chip.on { background: var(--cck-accent-soft); color: var(--cck-accent); border-color: var(--chip-bg-active); }
.ty-why { margin-left: auto; font-size: 11px; color: var(--text-dim); }
.ty-grid { display: grid; grid-template-columns: minmax(430px, 1fr) 130px minmax(320px, 0.8fr); overflow: auto; flex: 1; }
/* The class display rule would defeat [hidden] (the P4.1 gotcha) — the
   preview stage hides the grid via the attribute, so pin the combination. */
.ty-grid[hidden] { display: none; }
.ty-colhdr { background: var(--table-hdr-bg); color: var(--on-solid); font-size: 10.5px; font-weight: 700; padding: 5px 10px; position: sticky; top: 0; z-index: 2; height: 24px; box-sizing: border-box; line-height: 14px; }
.ty-colhdr-arrow { display: flex; align-items: center; justify-content: center; font-size: 16px; font-weight: 600; padding: 0; }
.ty-mode { font-weight: 700; font-size: 9.5px; letter-spacing: 0.06em; border-radius: 4px; padding: 2px 6px; margin-right: 8px; }
.ty-mode-preview { background: var(--cck-accent-soft); color: var(--cck-accent); }
.ty-mode-live { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.ty-homes { padding: 6px 10px 2px; display: flex; flex-wrap: wrap; gap: 4px; }
.ty-home { font-size: 10px; color: var(--text-faint); border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px; }
.ty-left { border-right: 1px solid var(--border); min-width: 0; }
.ty-gutter { position: relative; overflow: hidden; }
.ty-svg { position: absolute; top: 26px; left: 0; }
.ty-right { border-left: 1px solid var(--border); min-width: 0; }
.ty-row { display: grid; grid-template-columns: minmax(150px, 1.1fr) minmax(120px, 1fr) minmax(150px, 1fr); min-height: 56px; align-items: center; border-top: 1px solid var(--border); font-size: 11.5px; padding: 4px 0; }
.ty-row > div { padding: 2px 10px; min-width: 0; }
.ty-src b { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; color: var(--text); overflow-wrap: anywhere; font-size: 12px; }
.crm-pk-new { font-size: 9px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--cck-accent); background: var(--cck-accent-soft); border-radius: 4px; padding: 1px 5px; margin-left: 6px; }
.ty-src span { color: var(--text-dim); font-size: 10.5px; display: block; overflow-wrap: anywhere; }
.ty-issue { color: var(--text-dim); font-size: 11px; line-height: 1.35; }
.ty-tag { display: inline-block; font-size: 9.5px; font-weight: 700; border-radius: 999px; padding: 1px 7px; margin-bottom: 3px; }
.ty-sure { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.ty-guess { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.ty-you { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.ty-remap { display: block; width: 100%; font: 400 11px/1.3 inherit; border: 1px solid var(--border); border-radius: 6px; background: var(--surface-2); color: var(--text); padding: 3px 6px; }
.ty-tgt { min-height: 40px; display: flex; align-items: center; gap: 6px; padding: 0 12px; font-size: 12px; color: var(--text-dim); }
.ty-tgt b { color: var(--text); font-weight: 600; }
.ty-tgt.ty-sub { padding-left: 30px; }
.ty-tgt.ty-bin { color: var(--r, var(--dupe-identical-glyph)); }
.ty-cnt { color: var(--text-dim); font-size: 10.5px; margin-left: 6px; overflow-wrap: anywhere; }
.ty-colhdr-grid { display: grid; grid-template-columns: minmax(150px, 1.1fr) minmax(120px, 1fr) minmax(150px, 1fr); padding: 0; }
.ty-colhdr-grid span { padding: 5px 10px; }
/* The quick view is a FLOATING, scrimless window (Jeremy 2026-07-08): the
   board behind stays clickable; drag the bar, resize the corner. */
.cck-qvwin { position: fixed; z-index: 1150; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-panel); box-shadow: 0 18px 60px rgba(20, 24, 33, 0.35);
  display: flex; flex-direction: column; overflow: hidden; resize: both;
  min-width: 440px; min-height: 320px; }
/* Standard window chrome (Jeremy 2026-07-08): compact 40px shaded title bar,
   small joined zoom group, quiet secondary action, close flush in the corner.
   The modal-era bar width (1000px fixed) is overridden — it left the ✕
   floating short of the corner in any wider window. */
.cck-qvwin .cck-qvwin-bar { cursor: grab; user-select: none; touch-action: none;
  width: auto; border-radius: 0; height: 40px; flex: 0 0 auto;
  padding: 0 6px 0 14px; gap: 8px;
  background: var(--pane-chrome-bg); border-bottom: 1px solid var(--border); }
.cck-qvwin .cck-fileov-title { font-size: 13px; }
.cck-qvwin .cck-qv-zoom { margin-left: auto; margin-right: 4px; display: inline-flex; align-items: stretch;
  height: 24px; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; background: var(--surface); }
.cck-qvwin .cck-qv-zoom button { border: none; box-shadow: none; background: none; border-radius: 0;
  height: 22px; min-height: 0; padding: 0 9px; font-size: 11.5px; line-height: 22px; color: var(--text-dim); cursor: pointer; }
.cck-qvwin .cck-qv-zoom button:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-qvwin .cck-qv-zpct { min-width: 46px; border-left: 1px solid var(--border) !important;
  border-right: 1px solid var(--border) !important; color: var(--text); }
.cck-qvwin [data-qv-native] { height: 24px; min-height: 0; padding: 0 10px; font-size: 11.5px;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--border); border-radius: 6px; color: var(--text); }
.cck-qvwin [data-qv-native]:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
.cck-qvwin .cck-fileov-x { width: 28px; height: 28px; display: inline-flex; align-items: center;
  justify-content: center; padding: 0; font-size: 14px; }
.cck-qv-zoom { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; margin-right: 8px; }
.cck-qv-zpct { min-width: 44px; text-align: center; font-variant-numeric: tabular-nums; }
/* In the floating window the body must fill the frame — the modal-era
   fixed width (1000px) + centre alignment sized content to itself and
   clipped both edges (Jeremy 2026-07-08: columns gone, tabs invisible). */
.cck-qvwin .cck-fileov-body { flex: 1; min-height: 0; min-width: 0; width: auto; height: auto;
  overflow: auto; align-items: stretch; justify-content: flex-start; }
.cck-qvwin .cck-qv-img { margin: auto; }   /* images stay centred */

/* Quick-view hosts the Explorer's spreadsheet stage. The STAGE's own
   .ins-sheet-scroll does the scrolling (tabs + formula bar stay pinned) —
   the window body must NOT scroll, or everything scrolls away together
   (Jeremy 2026-07-08: clipped columns, invisible tabs). */
.cck-qvwin .cck-fileov-body:has(.cck-qv-sheet) { overflow: hidden; display: flex; flex-direction: column; }
/* min-width: 0 down the whole chain — as flex items, the zoomed grid's
   intrinsic width otherwise BLOWS the stage wider than the window and
   flex-centring clips both edges (Jeremy 2026-07-08: columns A–C gone). */
.cck-qv-sheet { flex: 1; min-height: 0; min-width: 0; width: 100%; align-self: stretch; display: flex; flex-direction: column; }
.cck-qv-sheet .ins-preview-stage.ins-sheet { flex: 1; min-height: 0; min-width: 0; width: 100%; display: flex; }
.cck-qv-sheet .ins-sheet-scroll { min-width: 0; }
.ty-open { cursor: pointer; }
.ty-open:hover { color: var(--cck-accent); text-decoration: underline; text-underline-offset: 2px; }
.ty-whyline { display: block; font-size: 10.5px; color: var(--text-dim); margin-top: 3px; overflow-wrap: anywhere; }
.ty-whyline[hidden] { display: none; }   /* same [hidden]-vs-class-rule pin */
.ty-locbtn { display: block; font-size: 10.5px; color: var(--text-dim); background: none; border: none; padding: 0; margin-top: 3px; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.ty-locbtn:hover { color: var(--cck-accent); }
.ty-locbtn-unset { color: var(--action-pill-warn-fg); font-weight: 600; }
.ty-foot { display: flex; align-items: center; gap: 14px; padding: 10px 14px; border-top: 1px solid var(--border); font-size: 11.5px; color: var(--text-dim); flex-wrap: wrap; }
.ty-needs { color: var(--danger-text); font-weight: 600; }
.ty-needs-none { color: var(--success-text); }
.ty-meta { color: var(--text-faint); font-size: 10.5px; }
.ty-foot .cck-act-filled { margin-left: 0; }
.ty-progress { flex: 1 0 100%; display: flex; align-items: center; gap: 8px; font-size: 11px; }
.ty-pbar { flex: 1; height: 4px; border-radius: 2px; background: var(--chip-bg); overflow: hidden; }
.ty-pbar i { display: block; height: 4px; background: var(--accent); border-radius: 2px; transition: width var(--motion-duration) var(--motion-easing); }

/* ── M11-c Stage 2 d2: the navigable PREVIEW tree (Rule 8.1) ─────────────────
   The post-run result, expandable; decision items drag between folders —
   every edit rule-checked live. Depth rides --pv-depth (the picker's
   --pk-depth pattern). */
.ty-preview { flex: 1; min-height: 0; overflow: auto; }
.ty-preview .ty-colhdr { position: sticky; top: 0; }
.ty-pv-tree { padding: 8px 12px 18px; }
.ty-pv-row { display: flex; align-items: center; gap: 7px; min-height: 27px; padding: 2px 8px; padding-left: calc(8px + var(--pv-depth, 0) * 18px); border-radius: 6px; font-size: 12px; min-width: 0; }
.ty-pv-home { font-size: 13px; gap: 8px; margin-bottom: 2px; }
.ty-pv-home .ty-pv-meta { font-size: 11px; }
.ty-pv-twist { flex: none; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; background: none; border: none; padding: 0; color: var(--text-dim); font-size: 11px; cursor: pointer; border-radius: 4px; }
.ty-pv-twist:hover { color: var(--cck-accent); background: var(--cck-accent-soft); }
.ty-pv-folder { color: var(--text); }
.ty-pv-folder b { font-weight: 600; }
.ty-pv-folder.ty-pv-over { background: var(--cck-accent-soft); outline: 1px dashed var(--cck-accent); outline-offset: -1px; }
.ty-pv-bin, .ty-pv-bin b { color: var(--danger-text); }
.ty-pv-needs, .ty-pv-needs b { color: var(--warn-text); }
.ty-pv-meta { color: var(--text-dim); font-size: 10.5px; white-space: nowrap; }
.ty-pv-item { cursor: grab; }
.ty-pv-item:active { cursor: grabbing; }
.ty-pv-item.ty-pv-dragging { opacity: 0.45; }
.ty-pv-item.ty-pv-edited { background: var(--cck-accent-soft); outline: 1px dashed var(--cck-accent); outline-offset: -1px; }
.ty-pv-grip { flex: none; color: var(--text-faint); font-size: 10px; letter-spacing: -2px; user-select: none; }
.ty-pv-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.ty-pv-item .ty-tag { margin-bottom: 0; flex: none; }
.ty-pv-from { color: var(--text-faint); font-size: 10.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 180px; }
.ty-pv-note { color: var(--cck-accent); font-size: 10.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.ty-pv-move { margin-top: 0; flex: none; }
.ty-pv-item .ty-locbtn { margin-top: 0; }

/* ── M11-c Stage 2 d4: the superset-proof evidence list ──────────────────── */
.ty-proof-ok { color: var(--success-text); font-weight: 600; }
.ty-proof-bad { color: var(--danger-text); font-weight: 600; }
.ty-proof-list { max-height: 40vh; overflow: auto; border: 1px solid var(--border); border-radius: 8px; margin: 8px 0 12px; font-size: 11.5px; }
.ty-proof-row { display: flex; align-items: center; gap: 8px; padding: 4px 10px; border-top: 1px solid var(--border); }
.ty-proof-row:first-child { border-top: 0; }
.ty-proof-mark { flex: none; color: var(--success-text); font-weight: 700; }
.ty-proof-miss .ty-proof-mark, .ty-proof-miss .ty-proof-verdict { color: var(--danger-text); }
.ty-proof-name { flex: 1; min-width: 0; overflow-wrap: anywhere; color: var(--text); }
.ty-proof-size { flex: none; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.ty-proof-verdict { flex: none; color: var(--text-dim); font-size: 10.5px; }
.ty-proof-more { color: var(--text-faint); }

/* ── P2.4: the per-entity activity feed (activityFeed.js) ─────────────────
   Calm one-line rows inside a host section (Projects Comms · CRM detail):
   date column, pinned 12px glyph (lucide repaint ignores data-size — size
   lives here), one ellipsized line, a dim source word on the right. */
.af-feed { display: flex; flex-direction: column; min-width: 0; }
.af-row { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text);
  padding: 5px 0; border-bottom: 1px dashed var(--border); min-width: 0; }
.af-row:last-of-type { border-bottom: 0; }
.af-row svg, .af-row .lucide-icon { width: 12px; height: 12px; flex: none; color: var(--text-dim); }
.af-when { flex: none; width: 64px; font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.af-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.af-src { flex: none; font-size: 11px; color: var(--text-dim); }
.af-empty { font-size: 12px; color: var(--text-dim); padding: 6px 0; }
.af-more { margin-top: 6px; align-self: flex-start; }

/* ── P2.6: the Documents home (documents.js — queues · records · policy) ──
   Rail = three calm stats (the finance rail grammar); panel = cck-work with
   a cck-calseg area bar. Icons pinned in CSS (lucide repaint ignores
   data-size). Status pills reuse the ins-rec-status-pill family above. */
.doc-rail { display: flex; flex-direction: column; gap: 8px; padding: 10px; }
.doc-rail-stat { background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 9px 12px; display: flex; flex-direction: column; }
.doc-rail-stat span { font-size: 10.5px; color: var(--text-dim); }
.doc-rail-stat b { font-size: 17px; }
.doc-rail-stat.due b { color: var(--warn-text); }
.doc-rail-stat i { font-style: normal; font-size: 10.5px; color: var(--text-faint); }

.doc-panel .doc-tabbar { margin: 2px 0 10px; align-self: flex-start; }
.doc-note { font-size: 11px; color: var(--text-faint); margin: 8px 0 0; }
.doc-loading { font-size: 12px; color: var(--text-dim); padding: 10px 2px; }
.doc-empty { margin-top: 24px; }

/* Queues — one row per wand-tab family: name · blurb · count · Review. */
.doc-queues { display: flex; flex-direction: column; min-width: 0; }
.doc-qrow { display: flex; align-items: center; gap: 12px; padding: 9px 2px; border-bottom: 1px dashed var(--border); min-width: 0; }
.doc-qrow:last-of-type { border-bottom: 0; }
.doc-qname { flex: 0 0 110px; font-size: 12.5px; font-weight: 550; color: var(--text); }
.doc-qblurb { flex: 1 1 auto; min-width: 0; font-size: 11.5px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-qcount { flex: 0 0 56px; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; font-size: 13px; color: var(--text); }
.doc-qcount.doc-qzero { color: var(--ok); }
.doc-qcount svg, .doc-qcount .lucide-icon { width: 13px; height: 13px; }
.doc-qrow .cck-act[disabled] { opacity: 0.45; cursor: default; }

/* Records — filter bar (status chips · selects · search) + the table. */
.doc-filterbar { display: flex; flex-direction: column; gap: 8px; margin: 2px 0 6px; }
.doc-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.doc-chip { font: inherit; font-size: 11.5px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; }
.doc-chip.is-on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.doc-chip-n { color: var(--text-dim); font-size: 10.5px; }
.doc-filterrow { display: flex; gap: 8px; min-width: 0; }
.doc-sel { font: inherit; font-size: 12px; padding: 5px 8px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-0); color: var(--text); max-width: 220px; }
.doc-search { font: inherit; font-size: 12px; flex: 1 1 auto; min-width: 0; padding: 5px 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-0); color: var(--text); }
.doc-search:focus, .doc-sel:focus { outline: none; border-color: var(--accent); }
.doc-count { font-size: 11px; color: var(--text-dim); margin: 0 0 6px; }
.doc-tablewrap { overflow: auto; min-height: 0; border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); }
.doc-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.doc-table th { position: sticky; top: 0; background: var(--surface-0); text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); padding: 8px 10px; border-bottom: 0.5px solid var(--border); }
.doc-table td { padding: 7px 10px; border-bottom: 0.5px solid var(--border); vertical-align: middle; color: var(--text); }
.doc-table tbody tr:last-child td { border-bottom: 0; }
.doc-td-name { max-width: 380px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-recname { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.doc-td-upd { font-variant-numeric: tabular-nums; color: var(--text-dim); white-space: nowrap; }
.doc-nostatus { color: var(--text-faint); }

/* Policy — read-only catalogue summary; the editor stays in Settings. */
.doc-policy { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.doc-polhead { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.doc-polhead b { font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.doc-fieldchips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.doc-fieldchip { font-size: 11px; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text-dim); }

/* ═══ P3.2 (R7) — the Risk register (risk.js) ══════════════════════════════
   One register, two lenses. Band families reuse the §3.6 token pairs:
   low = ok-soft · medium = warning-chip · high = warn-soft (fg --warn) ·
   critical = danger-soft. Tokens only — no raw values. */
.rk-panel { min-width: 0; }
.rk-viewseg { margin-left: 10px; }

/* Heat map — impact up, likelihood across; cells are real buttons. */
.rk-heatwrap { display: flex; gap: 18px; align-items: flex-start; margin: 12px 0 4px; }
.rk-heat { display: flex; gap: 6px; align-items: stretch; }
.rk-heat-ytitle { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); font-weight: 600; align-self: center; }
.rk-heat-grid { display: flex; flex-direction: column; gap: 3px; }
.rk-heat-row { display: flex; gap: 3px; align-items: center; }
.rk-heat-ylab { width: 14px; text-align: right; font-size: 10.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.rk-heat-xlab { width: 44px; text-align: center; font-size: 10.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.rk-heat-xtitle { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); font-weight: 600; text-align: center; margin-top: 2px; padding-left: 17px; }
.rk-cell { width: 44px; height: 30px; border-radius: 6px; border: 0.5px solid var(--border); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; cursor: pointer; transition: box-shadow var(--motion-micro), transform var(--motion-micro); padding: 0; }
.rk-cell:hover { box-shadow: var(--elev-1); transform: translateY(-1px); }
.rk-cell-0 { opacity: 0.45; font-weight: 400; }
.rk-cell-on { box-shadow: inset 0 0 0 2px var(--cck-accent); opacity: 1; }
.rk-cell.rk-band-low { background: var(--ok-soft-bg); color: var(--ok-soft-fg); border-color: var(--ok-soft-border); }
.rk-cell.rk-band-medium { background: var(--warning-chip-bg); color: var(--warning-chip-fg); border-color: var(--warning-chip-border); }
.rk-cell.rk-band-high { background: var(--warn-soft-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, var(--surface)); }
.rk-cell.rk-band-critical { background: var(--danger-soft-bg); color: var(--danger-text); border-color: var(--danger-soft-border); }
.rk-heatside { display: flex; flex-direction: column; gap: 6px; max-width: 300px; padding-top: 2px; }
.rk-legend { display: flex; gap: 12px; flex-wrap: wrap; }
.rk-leg { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-dim); }
.rk-leg-dot, .rk-scoredot { width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block; }
.rk-leg-dot.rk-band-low, .rk-scoredot.rk-band-low { background: var(--ok); }
.rk-leg-dot.rk-band-medium, .rk-scoredot.rk-band-medium { background: var(--warning-chip-border); }
.rk-leg-dot.rk-band-high, .rk-scoredot.rk-band-high { background: var(--warn); }
.rk-leg-dot.rk-band-critical, .rk-scoredot.rk-band-critical { background: var(--danger); }
.rk-heatnote { font-size: 10.5px; color: var(--text-faint); margin: 0; }

/* Register table (crm-table base). */
.rk-table td { vertical-align: top; }
.rk-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.rk-row { cursor: pointer; }
.rk-row:hover td { background: var(--row-hover, var(--surface-2)); }
.rk-row-on td { background: var(--surface-3); }
.rk-titlecell { max-width: 420px; }
.rk-cat { display: block; font-size: 10.5px; color: var(--text-faint); margin-top: 1px; }
.rk-scoredot { margin-right: 5px; }
.rk-dim { color: var(--text-faint); }
.rk-over { color: var(--warn); font-weight: 600; }
.rk-projlink { font-weight: 600; }

/* Detail + new-risk cards (crm-detail chrome). */
.rk-detail { display: flex; flex-direction: column; gap: 10px; }
.rk-detail-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.rk-title-in { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; }
.rk-form-title { flex: 1; }
.rk-detail-x { margin-left: auto; flex: none; }
.rk-detail-head .rk-detail-x { margin-left: 0; }
.rk-detail-head .cck-tk-chip { flex: none; }
.rk-scorechip { flex: none; font-size: 11px; font-weight: 600; padding: 2px 9px; border-radius: 999px; border: 0.5px solid var(--border); white-space: nowrap; }
.rk-scorechip.rk-band-low { background: var(--ok-soft-bg); color: var(--ok-soft-fg); border-color: var(--ok-soft-border); }
.rk-scorechip.rk-band-medium { background: var(--warning-chip-bg); color: var(--warning-chip-fg); border-color: var(--warning-chip-border); }
.rk-scorechip.rk-band-high { background: var(--warn-soft-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, var(--surface)); }
.rk-scorechip.rk-band-critical { background: var(--danger-soft-bg); color: var(--danger-text); border-color: var(--danger-soft-border); }
.rk-detail-body { font-size: 12.5px; color: var(--text); margin: 0; }
.rk-src { font-size: 10.5px; color: var(--text-faint); margin: 0; }
.rk-fields { margin: 0; }
.rk-span2 { grid-column: span 2; }
.rk-scales { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; }
.rk-scale { display: flex; align-items: center; gap: 8px; }
.rk-seg .cck-calseg-btn { min-width: 30px; }
.rk-action { min-width: 0; }
.rk-detail-acts { display: flex; gap: 8px; align-items: center; }

/* DD proposals card — calm, confirm-first. */
.rk-props { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; margin: 6px 0; }
.rk-props-head { display: flex; flex-direction: column; gap: 2px; }
.rk-props-head b { font-size: 12.5px; }
.rk-props-head span { font-size: 11px; color: var(--text-dim); }
.rk-prop { display: flex; align-items: flex-start; gap: 8px; font-size: 12px; }
.rk-prop .rk-scoredot { margin-top: 4px; }
.rk-prop-body { flex: 1; min-width: 0; }
.rk-prop-sub { display: block; font-size: 10.5px; color: var(--text-faint); }

/* ── P3.3 (R5) Recruitment — clickable board cards + capture-card chrome ──── */
.rec-card { cursor: pointer; }
.rec-card.rec-card-on { border-color: var(--cck-accent); box-shadow: inset 0 0 0 1px var(--cck-accent); }
.rec-props { position: relative; }
.rec-props-x { position: absolute; top: 8px; right: 8px; }
.rec-headacts { display: flex; align-items: center; gap: 8px; flex: none; }

/* ═══ SO-3 — Strategic Objectives (objectives.js) ═══════════════════════════
   Whole-business register + three-signal detail. Tokens only — no raw colour
   values; the mockup's palette maps onto the cockpit hero + accent families.
   Quarter timelines render ONLY on contributing-outcome lines (Define rule). */
.obj-panel { min-width: 0; --obj-qw: 18px; }
.obj-lede { font-size: 12px; color: var(--text-dim); margin: 0 0 10px; }

/* Business-trajectory band — the cockpit hero family (calm, both themes). */
.obj-hero { background: var(--cck-hero-bg); color: var(--cck-hero-text); border-radius: var(--radius-panel); padding: 14px 16px 12px; margin: 2px 0 12px; }
.obj-hero-head { display: flex; align-items: flex-start; gap: 16px; min-width: 0; }
.obj-hero-headtext { min-width: 0; }
.obj-hero-eyebrow { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--cck-hero-sub); font-weight: 600; }
.obj-hero-head h4 { margin: 3px 0 0; font-size: 14px; font-weight: 600; }
.obj-hero-window { margin-left: auto; text-align: right; font-size: 11px; color: var(--cck-hero-sub); white-space: nowrap; flex: none; }
.obj-hero-window b { display: block; color: var(--cck-hero-text); font-size: 12.5px; }
.obj-hero-empty { font-size: 11.5px; color: var(--cck-hero-sub); border: 1px dashed var(--cck-hero-sub); border-radius: 8px; padding: 10px 12px; margin-top: 10px; }
.obj-hero-note { font-size: 10.5px; color: var(--cck-hero-sub); margin: 6px 0 0; }
/* SO-3b usability: the slim strip shown when no dated milestones exist — no dead
   band, the register leads. Eyebrow + one line, no track. */
.obj-hero-slim { display: flex; align-items: baseline; gap: 10px; padding: 8px 14px; margin: 2px 0 10px; flex-wrap: wrap; }
.obj-hero-slim-text { font-size: 11.5px; color: var(--cck-hero-sub); min-width: 0; }
.obj-hero-track { position: relative; height: 66px; margin-top: 12px; }
.obj-hero-line { position: absolute; left: 1%; right: 1%; top: 38px; height: 2px; background: var(--cck-hero-sub); opacity: 0.5; }
.obj-ms { position: absolute; top: 33px; width: 12px; height: 12px; border-radius: 50%; border: 3px solid var(--cck-accent); background: var(--surface-0); transform: translateX(-50%); box-sizing: border-box; }
.obj-ms-done { background: var(--cck-accent); }
.obj-ms-label { position: absolute; top: 12px; transform: translateX(-50%); font-size: 10.5px; white-space: nowrap; color: var(--cck-hero-text); max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.obj-ms-date { position: absolute; top: 50px; transform: translateX(-50%); font-size: 10px; color: var(--cck-hero-sub); white-space: nowrap; font-variant-numeric: tabular-nums; }
.obj-now { position: absolute; top: 24px; bottom: 4px; width: 1px; background: var(--cck-hero-text); }
.obj-now span { position: absolute; top: -12px; left: -13px; font-size: 9.5px; font-weight: 700; letter-spacing: 0.06em; color: var(--cck-hero-text); }

/* Register — one row per parent objective; NO quarter timeline here. */
.obj-register { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); overflow: hidden auto; min-width: 0; flex: 1 1 auto; min-height: 0; } /* SCROLL (Jeremy 2026-07-13): the register is its OWN scroll area (flex:1 + min-height:0 fills the remaining plate height; overflow-y:auto scrolls internally). The title/trajectory/hint above stay FIXED; only the objectives scroll — under the sticky WHOLE-BUSINESS OBJECTIVE header, which pins at the register's own top:0 and fully masks rows scrolling beneath it (no page bleed). */
.obj-reg-head, .obj-row { display: grid; grid-template-columns: minmax(0, 1.7fr) 104px minmax(140px, 1fr) 96px 180px; gap: 10px; align-items: center; } /* the actions column is a FIXED width (was auto) so the header's empty slot and the rows' buttons occupy the same track — otherwise the variable button width shifted the flexible columns and the dashes/pill fell out of line with their headers (Jeremy 2026-07-13). */
.obj-reg-head { padding: 8px 12px; background: var(--surface-2); border-bottom: 0.5px solid var(--border); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); position: sticky; top: 0; z-index: 5; border-radius: 10px 10px 0 0; } /* Jeremy 2026-07-13: the WHOLE-BUSINESS OBJECTIVE banner pins; objectives scroll under it. */
/* Center ACCOUNTABLE + MEASURE + STATUS so headers, values and the dashes all
   line up under their labels (Jeremy 2026-07-13: "in line with the dashes"). */
.obj-reg-head span:nth-child(2), .obj-reg-head span:nth-child(3), .obj-reg-head span:nth-child(4) { text-align: center; }
.obj-row > .obj-cell { text-align: center; }
.obj-cell-measure b { text-align: center; }
.obj-row > .obj-cell-measure .obj-microbar { margin-left: auto; margin-right: auto; }
.obj-row > .obj-pill, .obj-row > .obj-pill-btn { justify-self: center; }
.obj-row { padding: 8px 12px; border-bottom: 0.5px solid var(--border); }
.obj-row:last-child { border-bottom: 0; }
.obj-row-open { background: var(--surface-3); }
/* SO-3b usability: the ROW BODY is the expand/collapse control (both modes). */
.obj-row-main { display: flex; align-items: center; gap: 10px; min-width: 0; text-align: left; background: none; border: 0; padding: 0; font: inherit; color: var(--text); cursor: pointer; border-radius: 8px; }
.obj-row-main:hover b { color: var(--accent); }
.obj-row-main:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Explicit per-row affordances — "Open" (detail) always, "Edit" in Edit mode. */
.obj-row-acts { display: flex; align-items: center; gap: 6px; justify-self: end; min-width: 0; }
.obj-open-btn { display: inline-flex; align-items: center; gap: 3px; background: none; border: 0.5px solid var(--border); border-radius: var(--radius-pill); color: var(--text-dim); font: inherit; font-size: 11px; padding: 3px 9px; cursor: pointer; white-space: nowrap; }
.obj-open-btn:hover { border-color: var(--accent); color: var(--accent); }
.obj-open-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.obj-row-edit { font-size: 11px; padding: 3px 9px; display: inline-flex; align-items: center; gap: 4px; }
/* The inline inspector slot — rendered directly under its source row (fix 2b). */
.obj-inspect-slot { grid-column: 1 / -1; margin: 8px 0 2px; }
.obj-inits .obj-inspect-slot { margin: 6px 0 2px; }
.obj-row-editing { background: var(--surface-3); box-shadow: inset 3px 0 0 var(--accent); }
.obj-init-editing { background: var(--hover-soft-tint); }
/* Imported-drafts hint + the Edit-mode banner (fix 5). */
.obj-reg-hint { font-size: 11px; color: var(--text-dim); margin: 0 0 8px; }
.obj-editbanner { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--cck-accent); background: var(--cck-accent-soft); border: 0.5px solid var(--cck-accent); border-radius: 8px; padding: 7px 12px; margin: 0 0 10px; }
.obj-editbanner b { font-weight: 600; }
.obj-editbanner svg { flex: none; }
.obj-num { flex: none; width: 26px; height: 26px; border-radius: 8px; background: var(--cck-accent-soft); color: var(--cck-accent); display: grid; place-items: center; font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; }
.obj-row-title { min-width: 0; }
.obj-row-title b { display: block; font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* UAT-0729-4: parent objective titles one step up the type ramp (12.5→15) so the parent row reads clearly above 12px initiative text when expanded. */
.obj-row-title small { display: block; font-size: 10.5px; color: var(--text-dim); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.obj-cell { font-size: 12px; min-width: 0; }
.obj-cell-measure b { display: block; font-size: 12px; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.obj-microbar { display: block; width: 96px; max-width: 100%; height: 4px; border-radius: var(--radius-pill); background: var(--row-progress-track); margin-top: 4px; overflow: hidden; }
.obj-microbar i { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--row-progress-bar); }
.obj-bar-ok i { background: var(--ok); }
.obj-dim { color: var(--text-faint); }
.obj-toggle { width: 26px; height: 26px; border-radius: 50%; border: 0.5px solid var(--border); background: var(--surface-0); color: var(--text-dim); display: grid; place-items: center; cursor: pointer; padding: 0; flex: none; }
.obj-toggle:hover { border-color: var(--accent); color: var(--accent); }
.obj-toggle svg { transition: transform var(--motion-micro) var(--motion-easing); }
.obj-row-open .obj-toggle svg { transform: rotate(90deg); }

/* Status pills — the five Define states on the app's soft-chip families. */
.obj-pill { display: inline-flex; align-items: center; justify-content: center; font-size: 10.5px; font-weight: 600; padding: 2px 9px; border-radius: var(--radius-pill); white-space: nowrap; justify-self: start; }
.obj-pill-draft, .obj-pill-none { background: var(--neutral-soft-bg); color: var(--neutral-soft-fg); }
.obj-pill-active { background: var(--action-pill-info-bg); color: var(--action-pill-info-fg); }
.obj-pill-achieved { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.obj-pill-paused { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.obj-pill-superseded { background: var(--violet-soft-bg); color: var(--violet-soft-fg); }
.obj-pill-risk { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }

/* Contributing outcomes — the ONLY home of the quarter-square timeline. */
.obj-outcomes { grid-column: 1 / -1; margin: 8px 0 2px 36px; border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-0); padding: 8px 12px; min-width: 0; overflow-x: auto; }
.obj-outcomes[hidden] { display: none; }
.obj-oc-head, .obj-oc-line { display: grid; grid-template-columns: minmax(150px, 1fr) auto 44px 96px; gap: 12px; align-items: center; }
.obj-oc-head { padding-bottom: 6px; border-bottom: 0.5px solid var(--border); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); }
.obj-oc-hn, .obj-oc-hs { text-align: right; }
.obj-oc-line { padding: 7px 0; border-bottom: 1px dashed var(--border); }
.obj-oc-line:last-child { border-bottom: 0; }
.obj-oc-line .obj-pill { justify-self: end; }
.obj-oc-name { min-width: 0; }
.obj-oc-name b { display: block; font-size: 12px; }
.obj-oc-name small { display: block; font-size: 10.5px; color: var(--text-dim); margin-top: 1px; }
.obj-tl-heads { display: flex; flex-direction: column; gap: 2px; text-transform: none; letter-spacing: 0; }
.obj-tl { display: grid; gap: 4px; align-items: center; }
.obj-tl-years b { display: block; text-align: center; font-size: 10.5px; font-weight: 600; color: var(--text-dim); }
.obj-tl-qs i { display: block; text-align: center; font-style: normal; font-size: 9.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.obj-q { position: relative; width: var(--obj-qw); height: 12px; border-radius: 3px; background: var(--surface-2); border: 0.5px solid var(--border); box-sizing: border-box; }
/* Bar fill by state (Jeremy 2026-07-13): light blue = in progress, red = late,
   green = completed. No dark-blue fill, no dotted boxes. */
.obj-q-fill.obj-q-prog { background: var(--cck-accent-soft); border-color: var(--cck-accent-soft); }
.obj-q-fill.obj-q-late { background: var(--danger-soft-bg); border-color: var(--danger-soft-border); }
.obj-q-fill.obj-q-done { background: var(--ok-soft-bg); border-color: var(--ok-soft-border); }
/* Milestone = a centred diamond on the target quarter, in the state's strong ink. */
.obj-q-mstone::after { content: ''; position: absolute; left: 50%; top: 50%; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; background: var(--cck-accent); transform: rotate(45deg); }
.obj-q-late.obj-q-mstone::after, .obj-q-ms-late.obj-q-mstone::after { background: var(--danger-soft-fg, var(--cck-danger)); }
.obj-q-done.obj-q-mstone::after, .obj-q-ms-done.obj-q-mstone::after { background: var(--ok-soft-fg); } /* UAT-0729 round 2: the diamond's state classes are now its OWN (obj-q-ms-*) — the cell fill under a missed milestone is blue plan-window, no longer late-red. */
/* A milestone RECORD on a quarter (separate from the target) — small top diamond. */
.obj-q-flag::before { content: ''; position: absolute; left: 50%; top: -3px; width: 6px; height: 6px; margin-left: -3px; background: var(--warning-chip-fg); transform: rotate(45deg); }
/* Year boundary — a thin CONTINUOUS vertical line between Q4 and Q1 that runs
   down every row (Jeremy 2026-07-13). Drawn with a tall pseudo that extends
   into each row's padding so consecutive segments join into one line. */
.obj-q-ye { position: relative; }
.obj-q-ye::before { content: ''; position: absolute; right: -2.5px; top: -14px; bottom: -14px; border-left: 1px solid var(--border); pointer-events: none; } /* UAT-0729-3 (final, PO 2026-07-29): a FAINT SOLID grey line — dots/dashes broke visually where they crossed the row separators. Segments overlap (±14px) so consecutive rows join into one continuous line. */
.obj-tl-qs .obj-qh-ye { position: relative; }
.obj-tl-qs .obj-qh-ye::before { content: ''; position: absolute; right: -2.5px; top: 0; bottom: -10px; border-left: 1px solid var(--border); pointer-events: none; }
.obj-oc-pct { font-size: 11.5px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.obj-oc-notl { font-size: 10.5px; color: var(--text-faint); }
.obj-oc-empty { font-size: 11.5px; color: var(--text-dim); padding: 4px 0; }

/* SO-3b — contributing INITIATIVES block (same timeline grammar as outcomes). */
.obj-inits { margin-top: 6px; }
.obj-inits + .obj-inits, .obj-outcomes .obj-inits { margin-top: 10px; }
.obj-init-line .obj-oc-pct { display: flex; justify-content: flex-end; }
/* Section-level "proposed" explainer (fix 5 — said ONCE, not on all 38 rows). */
.obj-inits-note { font-size: 10.5px; color: var(--text-faint); margin: 0 0 6px; }
.obj-tl-key { display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center; font-size: 10.5px; color: var(--text-dim); margin: 0 0 10px; }
.obj-tl-key span { display: inline-flex; align-items: center; gap: 6px; }
.obj-tl-key .obj-q { position: relative; width: 15px; height: 12px; flex: none; } /* UAT-0729-7: was position:static, which let the milestone ::after diamond position against the plate and float mid-screen. */
/* UAT-0729-5/6: the key's milestone mark is the ACTUAL mark — a diamond glyph,
   not a shaded swatch. Colour grammar: accent = upcoming, danger = missed
   (target date passed unmet), ok = achieved — matching .obj-q-mstone::after. */
.obj-tl-key .obj-key-diamond { display: inline-block; width: 7px; height: 7px; flex: none; background: var(--cck-accent); transform: rotate(45deg); }
.obj-tl-key .obj-key-diamond-late { background: var(--danger-soft-fg, var(--cck-danger)); }
.obj-tl-key .obj-key-diamond-done { background: var(--ok-soft-fg); }
.obj-init-proposed { font-style: normal; font-size: 9.5px; font-weight: 600; padding: 1px 6px; border-radius: var(--radius-pill); border: 1px dashed var(--warning-chip-fg); color: var(--warning-chip-fg); background: var(--warning-chip-bg); white-space: nowrap; margin-left: 6px; }
.obj-inits-note .obj-init-proposed { margin-left: 0; }
/* Editable quarter cells: buttons that read as the same squares, keyboard-reachable.
   Every axis cell is settable in Edit mode — including empty slots, so a human
   can click any quarter to set (or move) the initiative's target. The block widens
   its columns and the cells stand 24px tall so the hit target clears WCAG 2.5.8
   (≥24px) — a persistent affordance, never hover-only. */
.obj-inits-edit { --obj-qw: 26px; }
.obj-tl-edit .obj-q { height: 24px; min-width: 24px; padding: 0; cursor: pointer; -webkit-appearance: none; appearance: none; }
.obj-tl-edit .obj-q-void { border-color: var(--border); border-style: dashed; }
.obj-tl-edit .obj-q:hover { border-color: var(--cck-accent); border-style: solid; background: var(--cck-accent-soft); }
.obj-tl-edit .obj-q-target:hover { background: var(--cck-accent); }
.obj-tl-edit .obj-q:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 1px; }
/* A first-class milestone ◆ flag on its quarter cell (distinct from the now-diamond). */
.obj-q-flag::before { content: ''; position: absolute; left: 50%; top: -3px; width: 6px; height: 6px; margin-left: -3px; background: var(--warning-chip-fg); transform: rotate(45deg); }
/* Edit affordances on rows. */
.obj-editable { text-decoration: underline dashed var(--border); text-underline-offset: 3px; }
.obj-editctl { width: 22px; height: 22px; border-radius: 6px; border: 0.5px solid var(--border); background: var(--surface-0); color: var(--text-dim); display: grid; place-items: center; cursor: pointer; padding: 0; }
.obj-editctl:hover { border-color: var(--accent); color: var(--accent); }
.obj-pill-btn { border: 0; cursor: pointer; font-family: inherit; }
.obj-pill-btn:hover { filter: brightness(0.96); }

/* SO-3b — the View | Edit segmented control (reuses the cck-calseg house look). */
.obj-editseg { flex: none; }

/* SO-3b — the inspector (the obj-form chrome) + its milestone sub-form. */
.obj-inspector .obj-imp-select { width: 100%; }
.obj-inspector-title { font-size: 13px; font-weight: 600; }
.obj-rev-warn { color: var(--warning-chip-fg); }
.obj-ms-sub { border-top: 0.5px dashed var(--border); padding-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.obj-ms-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-bottom: 1px dashed var(--border); }
.obj-ms-row:last-of-type { border-bottom: 0; }
.obj-ms-diamond { color: var(--cck-accent); font-size: 11px; flex: none; }
.obj-ms-body { min-width: 0; flex: 1; }
.obj-ms-body b { display: block; font-size: 12px; }
.obj-ms-body small { display: block; font-size: 10.5px; color: var(--text-dim); }
.obj-ms-row .cck-tk-del { margin-left: auto; }
.obj-ms-add { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.obj-ms-add [data-obj-ms-title] { flex: 1 1 160px; }

/* ── UAT-0729-8: SO Milestones v2 — edit ON the timeline ──────────────────── */
/* The inspector milestone list: one full-width row per record (grid, 8pt gaps)
   — replaces the squashed inline cram. */
.obj-ms-row { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto 24px; gap: 8px; align-items: center; padding: 8px 0; }
.obj-ms-row .obj-ms-retitle { width: 100%; min-width: 0; }
.obj-ms-date { font-size: 10.5px; color: var(--text-dim); white-space: nowrap; }
.obj-ms-add { padding-top: 4px; }
.obj-inspector .obj-fields { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
/* Draggable ◆ controls on the Edit-mode timeline. Buttons (focusable), centred
   in their quarter cell; colour = the milestone state grammar. */
.obj-tl-edit .obj-q { position: relative; }
.obj-msdrag { position: absolute; left: 50%; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; padding: 0; border: 0; background: var(--cck-accent); transform: rotate(45deg); border-radius: 2px; cursor: grab; touch-action: none; box-shadow: 0 0 0 2px var(--surface-0); }
.obj-msdrag-late { background: var(--danger-soft-fg, var(--cck-danger)); }
.obj-msdrag-done { background: var(--ok-soft-fg); }
.obj-msdrag-flag { width: 9px; height: 9px; margin: -12px 0 0 -4.5px; background: var(--warning-chip-fg); }
.obj-msdrag-dragging { cursor: grabbing; opacity: 0.85; z-index: 5; box-shadow: var(--shadow); }
.obj-msdrag:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 2px; }
.obj-q-drop { outline: 2px solid var(--cck-accent); outline-offset: -1px; background: var(--cck-accent-soft); }
/* The hover + on an empty quarter (Edit mode only). */
.obj-q-plus { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; padding: 0; border: 0; background: transparent; color: var(--cck-accent); font-size: 13px; font-weight: 600; cursor: pointer; border-radius: 4px; }
.obj-tl-edit .obj-q:hover .obj-q-plus, .obj-q-plus:focus-visible { display: flex; }
.obj-q-plus:focus-visible { outline: 2px solid var(--cck-accent); outline-offset: 1px; }
/* The ONE milestone popover (create / target options / rename-remove). */
.obj-mspop { position: absolute; z-index: 1000; width: 260px; background: var(--surface-0); border: 1px solid var(--border-dark); border-radius: 10px; box-shadow: var(--shadow); padding: 12px; }
.obj-mspop-title { font-size: 12px; font-weight: 600; margin-bottom: 8px; }
.obj-mspop-note { font-size: 10.5px; color: var(--text-dim); margin: 0 0 8px; }
.obj-mspop .cck-tk-inline { width: 100%; margin-bottom: 8px; }
.obj-mspop-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.obj-mspop-danger { color: var(--cck-danger); }
/* SO-3b usability fix 1: the objective inspector's MEASURE group (actual · target
   · unit · source) — all optional; a blank group keeps the honest "—". */
.obj-measure-sub { border-top: 0.5px dashed var(--border); padding-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.obj-measure-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.obj-measure-grid input { width: 100%; }
@media (max-width: 720px) { .obj-measure-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Detail — hero + the three SEPARATE signals + outcome/evidence cards. */
.obj-detail-hero { border: 0.5px solid var(--border); border-radius: var(--radius-panel); background: var(--surface-3); padding: 14px 16px; margin: 2px 0 10px; }
.obj-detail-eyebrow { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); font-weight: 600; }
.obj-detail-hero h3 { margin: 4px 0 6px; font-size: 16px; }
.obj-detail-hero p { margin: 0 0 6px; font-size: 12.5px; color: var(--text); }
.obj-src { font-size: 10.5px; color: var(--text-faint); margin: 0; }
.obj-signals-note { font-size: 10.5px; color: var(--text-faint); margin: 0 0 8px; }
.obj-signals { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 10px; }
.obj-signal { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); padding: 10px 12px; min-width: 0; }
.obj-signal-l { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); font-weight: 600; }
.obj-signal-v { font-size: 15px; font-weight: 600; margin-top: 4px; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.obj-signal-sub { font-size: 10.5px; color: var(--text-faint); margin-top: 4px; }
.obj-signal .obj-microbar { width: 100%; margin-top: 6px; }
.obj-card { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); padding: 10px 12px; margin-bottom: 10px; min-width: 0; overflow-x: auto; }
.obj-card h4 { margin: 0 0 8px; font-size: 12.5px; }
.obj-ev-row { padding: 6px 0; border-bottom: 1px dashed var(--border); font-size: 12px; }
.obj-ev-row:last-child { border-bottom: 0; }
.obj-quiet { font-size: 11.5px; color: var(--text-dim); }

/* New-objective form (crm-stats field chrome, the house Enter-to-save inputs). */
.obj-form { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); padding: 12px; margin: 2px 0 12px; display: flex; flex-direction: column; gap: 10px; }
.obj-form-head { display: flex; align-items: center; gap: 10px; }
.obj-form-head .cck-tk-del { margin-left: auto; }
.obj-form-title { font-size: 12.5px; font-weight: 600; }
.obj-fields { margin: 0; }
.obj-span2 { grid-column: span 2; }
.obj-form-note { font-size: 10.5px; color: var(--text-faint); margin: 0; }
.obj-form-acts { display: flex; gap: 8px; align-items: center; }

/* Empty state (first-run) + the executive-attention rail. */
.obj-empty { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.obj-empty b { font-size: 13px; }
.obj-empty p { margin: 0; max-width: 520px; }
.obj-empty-acts { display: flex; gap: 8px; margin-top: 4px; }
.obj-rail-head { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); padding: 10px 12px 4px; }
.obj-att-list { list-style: none; margin: 0; padding: 0 10px; display: flex; flex-direction: column; }
.obj-att { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px dashed var(--border); padding: 9px 2px; font: inherit; color: var(--text); cursor: pointer; }
.obj-att:hover b { color: var(--accent); }
.obj-att b { font-size: 12px; }
.obj-att small { font-size: 10.5px; color: var(--text-dim); }

/* ── SO-2: the workbook import-preview modal (mockup #import, app tokens) ──
   Confirm-first: the overlay renders only while the preview state is open;
   quarter-diamond conversions are PROPOSED-date chips (dashed, warning
   tokens) so they can never be mistaken for approved dates; the amber
   source-limitation card carries the "Keep as gaps" pill. */
.obj-imp-overlay { position: fixed; inset: 0; background: var(--scrim); z-index: 1100; display: flex; align-items: center; justify-content: center; padding: 24px; }
.obj-imp-card { width: 860px; max-width: 96vw; max-height: 90vh; display: flex; flex-direction: column; background: var(--surface-0); border: 0.5px solid var(--border); border-radius: var(--radius-panel); box-shadow: var(--elev-2); outline: none; }
.obj-imp-head { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px 10px; border-bottom: 0.5px solid var(--border); }
.obj-imp-head h3 { margin: 0; font-size: 15px; }
.obj-imp-head p { margin: 3px 0 0; font-size: 11.5px; color: var(--text-dim); }
.obj-imp-head .cck-tk-del { margin-left: auto; flex: none; }
.obj-imp-body { padding: 12px 16px; overflow-y: auto; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
.obj-imp-foot { display: flex; gap: 8px; justify-content: flex-end; padding: 10px 16px 14px; border-top: 0.5px solid var(--border); }
.obj-imp-drop { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; border: 1px dashed var(--border); border-radius: 10px; padding: 18px 16px; cursor: pointer; }
.obj-imp-drop:hover { border-color: var(--accent); }
.obj-imp-drop b { font-size: 12.5px; }
.obj-imp-drop small { font-size: 11px; color: var(--text-dim); max-width: 560px; }
.obj-imp-drop input[type="file"] { font-size: 11.5px; margin-bottom: 4px; }
.obj-imp-err { margin: 0; font-size: 11.5px; color: var(--danger-text); }
.obj-imp-quiet { font-size: 12px; color: var(--text-dim); padding: 18px 4px; }
.obj-imp-flag { border: 0.5px solid var(--warning-chip-fg); background: var(--warning-chip-bg); color: var(--warning-chip-fg); border-radius: 8px; padding: 8px 12px; font-size: 11.5px; }
.obj-imp-warn { border: 0.5px solid var(--danger-soft-border); background: var(--danger-soft-bg); color: var(--danger-text); border-radius: 8px; padding: 10px 12px; font-size: 11.5px; display: flex; flex-direction: column; gap: 8px; }
.obj-imp-warn-choice { display: flex; gap: 8px; }
.obj-imp-warn-choice .cck-act { font-size: 11.5px; }
.obj-imp-map { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 6px 10px; align-items: stretch; }
.obj-imp-mapcell { border: 0.5px solid var(--border); border-radius: 8px; padding: 7px 10px; min-width: 0; }
.obj-imp-mapcell b { display: block; font-size: 11.5px; }
.obj-imp-mapcell small { display: block; font-size: 10.5px; color: var(--text-dim); margin-top: 1px; }
.obj-imp-src { background: var(--surface-2); }
.obj-imp-tgt { background: var(--surface-3); }
.obj-imp-arrow { align-self: center; color: var(--text-faint); font-size: 12px; }
.obj-imp-limit { display: flex; align-items: center; gap: 12px; border: 0.5px solid var(--border); border-radius: 8px; padding: 8px 12px; }
.obj-imp-limit b { display: block; font-size: 11.5px; }
.obj-imp-limit small { display: block; font-size: 10.5px; color: var(--text-dim); margin-top: 1px; max-width: 620px; }
.obj-imp-pill-amber { margin-left: auto; flex: none; font-size: 10.5px; font-weight: 600; padding: 2px 9px; border-radius: var(--radius-pill); background: var(--warning-chip-bg); color: var(--warning-chip-fg); white-space: nowrap; }
.obj-imp-table { border: 0.5px solid var(--border); border-radius: 10px; overflow: hidden; }
.obj-imp-thead, .obj-imp-row { display: grid; grid-template-columns: 46px minmax(0, 1.1fr) minmax(0, 1.5fr) 170px; gap: 10px; align-items: start; padding: 8px 12px; }
.obj-imp-thead { background: var(--surface-2); border-bottom: 0.5px solid var(--border); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); }
.obj-imp-row { border-bottom: 0.5px solid var(--border); }
.obj-imp-row:last-child { border-bottom: 0; }
.obj-imp-row-dim { opacity: 0.55; }
.obj-imp-ref { font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text-dim); }
.obj-imp-text { font-size: 12px; min-width: 0; overflow-wrap: anywhere; }
.obj-imp-clscol { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.obj-imp-clscol small { font-size: 10.5px; color: var(--text-dim); }
.obj-imp-cls { display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 600; padding: 2px 9px; border-radius: var(--radius-pill); white-space: nowrap; }
.obj-imp-cls-framework { background: var(--violet-soft-bg); color: var(--violet-soft-fg); }
.obj-imp-cls-objective { background: var(--action-pill-info-bg); color: var(--action-pill-info-fg); }
.obj-imp-cls-outcome { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.obj-imp-cls-initiative, .obj-imp-cls-task { background: var(--neutral-soft-bg); color: var(--neutral-soft-fg); }
.obj-imp-cls-review { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.obj-imp-cls-skipped, .obj-imp-cls-done { background: var(--surface-2); color: var(--text-faint); }
.obj-imp-select { font: inherit; font-size: 11.5px; color: var(--text); background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 7px; padding: 3px 6px; max-width: 100%; }
.obj-imp-select:focus { border-color: var(--accent); outline: none; }
.obj-imp-meta { display: flex; flex-wrap: wrap; gap: 4px; align-content: flex-start; min-width: 0; }
.obj-imp-gap { font-style: normal; font-size: 10px; padding: 1px 7px; border-radius: var(--radius-pill); background: var(--neutral-soft-bg); color: var(--neutral-soft-fg); white-space: nowrap; }
.obj-imp-proposed { font-style: normal; font-size: 10px; padding: 1px 7px; border-radius: var(--radius-pill); border: 1px dashed var(--warning-chip-fg); background: var(--warning-chip-bg); color: var(--warning-chip-fg); white-space: nowrap; }
.obj-imp-src-note { margin: 0; font-size: 10.5px; color: var(--text-faint); }

/* ── SO-4: review history, evidence + confirmed relationships ──────────────
   The update-position form (obj-form chrome), the append-only history panel
   (inspect-only — no edit affordance exists by design), and the related-work
   card where PROPOSED links are dashed/hollow until a human confirms. */
.obj-detail .cck-plate-headright { display: flex; align-items: center; gap: 8px; }
.obj-rev-form { margin-top: 0; }
.obj-rev-evs { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.obj-rev-evs .crm-stat-l { margin-bottom: 0; }
.obj-rev-ev-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) 28px; gap: 8px; align-items: center; width: 100%; }
.obj-rev-addbtn { align-self: flex-start; }
.obj-ev-row b { display: block; font-size: 12px; font-weight: 600; }
.obj-ev-row small { display: block; font-size: 10.5px; color: var(--text-dim); margin-top: 1px; }
.obj-pill-unapproved { background: transparent; color: var(--text-dim); border: 1px dashed var(--border); }
.obj-hist-note { font-size: 10.5px; color: var(--text-faint); margin: 0 0 6px; }
.obj-hist-item { border-bottom: 1px dashed var(--border); }
.obj-hist-item:last-child { border-bottom: 0; }
.obj-hist-row { display: grid; grid-template-columns: 92px minmax(0, 1fr) auto; gap: 10px; align-items: center; width: 100%; padding: 8px 2px; background: none; border: 0; font: inherit; color: var(--text); text-align: left; cursor: pointer; }
.obj-hist-row:hover b { color: var(--accent); }
.obj-hist-row b { font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.obj-hist-pos { font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.obj-hist-body { padding: 2px 2px 10px; display: flex; flex-direction: column; gap: 8px; }
.obj-hist-field span { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); font-weight: 600; margin-bottom: 2px; }
.obj-hist-field p { margin: 0; font-size: 12px; }
.obj-hist-appr { font-size: 11px; color: var(--text-dim); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.obj-rel-row { display: flex; align-items: flex-start; gap: 10px; padding: 7px 0; border-bottom: 1px dashed var(--border); }
.obj-rel-row:last-of-type { border-bottom: 0; }
.obj-rel-chip { flex: none; display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 600; padding: 2px 9px; border-radius: var(--radius-pill); white-space: nowrap; }
.obj-rel-project { background: var(--action-pill-info-bg); color: var(--action-pill-info-fg); }
.obj-rel-task { background: var(--neutral-soft-bg); color: var(--neutral-soft-fg); }
.obj-rel-risk { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.obj-rel-decision { background: var(--violet-soft-bg); color: var(--violet-soft-fg); }
.obj-rel-workforce-demand { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.obj-rel-chip-proposed { background: transparent; border: 1px dashed currentColor; }
.obj-rel-body { flex: 1; min-width: 0; }
.obj-rel-body b { display: block; font-size: 12px; }
.obj-rel-body small { display: block; font-size: 10.5px; color: var(--text-dim); margin-top: 1px; }
.obj-rel-proposedtag { flex: none; font-size: 10px; font-style: italic; color: var(--text-dim); border: 1px dashed var(--border); border-radius: var(--radius-pill); padding: 1px 7px; margin-top: 1px; }
.obj-rel-confirmbtn { flex: none; }
.obj-rel-add { display: grid; grid-template-columns: 150px minmax(0, 1fr) minmax(0, 1.3fr) auto; gap: 8px; align-items: center; margin-top: 8px; padding-top: 8px; border-top: 0.5px solid var(--border); }
.obj-rel-note { font-size: 10.5px; color: var(--text-faint); margin: 6px 0 0; }

/* FIN-11: the mark-paid house modal — body copy + the optional note field. */
.fin-paidconf { margin: 0 0 8px; font-size: 12px; }
.fin-paidnote-l { display: block; margin-top: 8px; font-size: 11px; color: var(--text-dim); }
.fin-paidnote-l .cck-tk-inline { width: 100%; margin-top: 4px; }

/* FIN-13: statuses + supporting-doc sub-rows. Credited = settled without cash
   (ok family); Duplicate = never payable (danger family); sub-rows indent
   under their linked invoice. */
.fin-pill-credited { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.fin-pill-duplicate { background: var(--action-pill-danger-bg); color: var(--action-pill-danger-fg); }
.fin-subrow td:first-child { padding-left: 32px; }
.fin-credited-l input { margin-right: 4px; }

.fin-paidconf-hint { font-size: 10.5px; color: var(--text-faint); }

/* FX-1: the Xero-driven pay run — one clean screen; connect card; run bar. */
.fin-payrun-src { font-size: 11px; color: var(--text-dim); margin: 0 0 8px; }
.fin-runtable .fin-runchk { width: 32px; }
.fin-runrow-on td { background: var(--cck-accent-soft); }
/* FX-5 — the streamlined run: in-Xero mark per row (click = the bill in Xero),
   and the quiet paid-awaiting-bank-feed band under the open bills */
.fin-runrow-wait td { opacity: 0.55; }
/* ── FR — Fundraising: funnel · database · mailshot ─────────────────────── */
.fr-railcard { background: var(--surface-0); border: 0.5px solid var(--border); border-radius: 10px; padding: 8px 12px 6px; display: block; }
.fr-railhead { display: block; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); padding: 2px 0 4px; }
.fr-railrow { display: flex; justify-content: space-between; align-items: baseline; padding: 6px 0; border-bottom: 1px dashed var(--border); font-size: var(--fs-xs); color: var(--text-dim); }
.fr-railrow:last-child { border-bottom: 0; }
.fr-railrow b { font-variant-numeric: tabular-nums; font-weight: 650; color: var(--text); }
.fr-caption, .fr-listdesc { font-size: var(--fs-xs); color: var(--text-dim); margin: 0 0 10px; }
.fr-funnelwrap { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.fr-stage { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px 8px; margin-bottom: 8px; cursor: pointer; background: var(--surface); }
.fr-stage:hover { border-color: var(--border-strong); }
.fr-stage.on { border-color: var(--cck-accent); box-shadow: 0 0 0 1px var(--cck-accent) inset; }
.fr-stage-top { display: flex; justify-content: space-between; align-items: baseline; }
.fr-stage-name { font-weight: 650; }
.fr-stage-n { font-variant-numeric: tabular-nums; font-weight: 650; }
.fr-bar { height: 8px; background: var(--surface-3); border-radius: 4px; margin-top: 6px; }
.fr-bar i { display: block; height: 8px; border-radius: 4px; background: var(--cck-accent); }
.fr-conv { font-size: var(--fs-xs); color: var(--text-faint); margin-top: 4px; }
.fr-declined { color: var(--cck-danger); cursor: pointer; text-decoration: underline; }
.fr-stagelist { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.fr-listhead { margin: 0 0 2px; font-size: var(--fs-md); }
.fr-listn { color: var(--text-dim); font-weight: 500; }
.fr-listscroll { max-height: 56vh; overflow: auto; }
.fr-li { padding: 7px 6px; border-bottom: 1px dashed var(--border); cursor: pointer; display: flex; flex-direction: column; }
.fr-li:hover { background: var(--surface-2); }
.fr-li span { font-size: var(--fs-xs); color: var(--text-dim); }
.fr-dbbar { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }
.fr-count { font-size: var(--fs-xs); color: var(--text-dim); margin-left: auto; }
.fr-table td { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fr-cell { cursor: text; }
.fr-cell:hover { background: var(--surface-2); }
.fr-cellin { width: 100%; font: inherit; border: 1px solid var(--cck-accent); border-radius: 4px; padding: 2px 4px; background: var(--surface); color: inherit; }
.fr-src { font-size: 10px; color: var(--text-faint); }
.fr-web { text-decoration: none; }
.fr-stagesel { font: inherit; font-size: var(--fs-xs); border: 1px solid var(--border); border-radius: 6px; padding: 3px 6px; background: var(--surface); color: inherit; }
.fr-mswrap { display: grid; grid-template-columns: 240px minmax(0, 1fr) minmax(0, 1.1fr); gap: 14px; align-items: start; }
.fr-mscol { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; min-width: 0; }
.fr-msfilters { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.fr-mschk { font-size: var(--fs-xs); color: var(--text-dim); display: flex; gap: 6px; align-items: center; }
.fr-msrec { font-size: var(--fs-xs); margin-bottom: 6px; }
.fr-warn { color: var(--warn-text); }
.fr-noemail { opacity: 0.55; }
.fr-msscroll { max-height: 44vh; }
.fr-msbar { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.fr-mssubj { width: 100%; margin-bottom: 8px; }
.fr-msblock { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; gap: 8px; align-items: start; padding: 6px 0; border-bottom: 1px dashed var(--border); }
.fr-msbt { font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); padding-top: 6px; }
.fr-msta { width: 100%; font: inherit; font-size: var(--fs-sm); border: 1px solid var(--border); border-radius: 6px; padding: 5px 7px; background: var(--surface); color: inherit; resize: vertical; }
.fr-msdiv { color: var(--text-faint); font-size: var(--fs-xs); padding-top: 6px; }
.fr-msops { white-space: nowrap; padding-top: 4px; }
.fr-msadd { font-size: var(--fs-xs); color: var(--text-dim); margin: 10px 0; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.fr-mssend { display: flex; gap: 8px; justify-content: flex-end; border-top: 1px solid var(--border); padding-top: 10px; }
.fr-mspreview { border: 1px solid var(--border); border-radius: 8px; overflow: auto; max-height: 62vh; }

/* ── FR-2b — the live funnel page, built to the approved v9 artefact ────── */
/* Rule 13 + the PO's note: panels WHITE on a toned surround, mockup typography
   (12.5px body · 11px captions · 14px/650 panel heads · soft elevation). */
.fr2-page { background: var(--surface-2); border: 0; border-radius: 0; margin: 12px -22px -20px; padding: 16px 22px 20px; font-size: 12.5px; line-height: 1.5; color: var(--text); }
.fr2-page .fr-caption { font-size: 11px; color: var(--text-faint); margin: 2px 0 12px; }
.fr2-kpi, .fr2-panel { background: var(--surface); box-shadow: var(--elev-1, none); }

.fr2-kpis { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-bottom: 16px; }
.fr2-kpi { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; display: grid; grid-template-rows: subgrid; grid-row: span 3; align-content: start; }
.fr2-kpi span { font-size: 11px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); }
.fr2-kpi b { font-size: 22px; font-weight: 650; font-variant-numeric: tabular-nums; margin-top: 2px; color: var(--text); }
.fr2-kpi i { font-style: normal; font-size: var(--fs-xs); color: var(--text-dim); }
.fr2-grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 16px; align-items: stretch; }
.fr2-right { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.fr2-panel { border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px; min-width: 0; }
.fr2-grow { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.fr2-grow .fr2-scroll { flex: 1; max-height: none; min-height: 0; }
.fr2-h { margin: 0 0 2px; font-size: 14px; font-weight: 650; color: var(--text); }
.fr2-row { display: grid; grid-template-columns: 148px minmax(0, 1fr); gap: 12px; align-items: center; cursor: pointer; margin: 2px 0; }
.fr2-lab { display: grid; grid-template-columns: 15px minmax(0, 1fr); gap: 10px; align-items: center; font-weight: 650; font-size: 12.5px; color: var(--text); }
.fr2-lab svg { width: 15px; height: 15px; stroke: var(--text-faint); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fr2-lab { position: relative; }
.fr2-lab em { font-style: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* stage definition = quiet hover card (the PO: no underline, no ?-cursor, nothing that begs a click) */
/* stage definitions ride the NATIVE title tooltip — the same small grey one
   every other Worx control uses (PO: the custom card read as foreign). */
.fr2-lane { position: relative; height: 32px; display: flex; align-items: center; }
.fr2-bar { height: 32px; border-radius: 6px; display: flex; align-items: center; justify-content: flex-end; padding: 0 12px; color: var(--fr-ink-on); min-width: 64px; }
.fr2-row:hover .fr2-bar { filter: brightness(1.06); }
.fr2-row.on .fr2-bar { outline: 2px solid var(--cck-accent); outline-offset: 2px; }
.fr2-n { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.fr2-m { margin-left: 10px; font-size: var(--fs-xs); color: var(--text-dim); white-space: nowrap; }
.fr2-early { background: var(--fr-early); color: var(--fr-early-ink); }
.fr2-early .fr2-n { color: var(--fr-early-ink); }
.fr2-mid { background: var(--fr-mid); }
.fr2-deep { background: var(--fr-deep); }
.fr2-join { display: grid; grid-template-columns: 148px minmax(0, 1fr); gap: 12px; align-items: center; height: 28px; }
.fr2-j { display: flex; align-items: center; gap: 8px; font-size: var(--fs-xs); color: var(--text-faint); padding-left: 6px; }
.fr2-j b { color: var(--text-dim); }
.fr2-arrow { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid var(--fr-arrow); }
.fr2-lost { color: var(--cck-danger); background: var(--fr-rose-chip); border-radius: 999px; padding: 1px 8px; font-weight: 600; font-size: 10.5px; }
.fr2-mouth { width: 100%; background: var(--surface-2); border: 1px dashed var(--border-strong); color: var(--text-dim); border-radius: 7px; min-height: 40px; position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 2px 12px; padding: 8px 16px; font-size: var(--fs-sm); }
.fr2-mouth b { color: var(--text); font-variant-numeric: tabular-nums; }
.fr2-mouthr { margin-left: auto; white-space: nowrap; }
.fr2-mouthr b { font-size: 14px; font-weight: 700; }
.fr2-decl { display: flex; align-items: center; gap: 10px; border-top: 1px dashed var(--border); margin-top: 12px; padding-top: 10px; font-size: var(--fs-sm); color: var(--text-dim); }
.fr2-declbar { flex: 1; height: 8px; border-radius: 4px; background: var(--surface-3); overflow: hidden; display: flex; }
.fr2-declseg { display: block; height: 8px; }
.fr2-ds0 { background: var(--fr-rose-0); } .fr2-ds1 { background: var(--fr-rose-1); } .fr2-ds2 { background: var(--fr-rose-2); } .fr2-ds3 { background: var(--fr-rose-3); }
.fr2-liw { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.fr2-days { font-size: var(--fs-xs); color: var(--text-faint); white-space: nowrap; }
.fr2-days.stale { color: var(--warn-text); font-weight: 650; }
.fr2-listbar { margin: 6px 0 8px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.fr2-listbar .cck-act { flex: none; }
.fr2-selq { flex: 1 1 150px; min-width: 140px; }
.fr2-scroll { max-height: 46vh; }
.fr2-ag { display: grid; grid-template-columns: 128px 1fr auto; gap: 10px; align-items: center; font-size: var(--fs-xs); color: var(--text-dim); padding: 5px 0; }
.fr2-agbar { position: relative; height: 8px; border-radius: 4px; background: var(--surface-3); }
.fr2-agbar i { display: block; height: 8px; border-radius: 4px; background: var(--fr-agbar); }
.fr2-agbar u { position: absolute; top: -3px; bottom: -3px; width: 2px; border-radius: 1px; background: var(--fr-tick); opacity: 0.55; }
.fr2-agbar em { position: absolute; top: 0; bottom: 0; background: var(--fr-amber); }
.fr2-collect { color: var(--text-faint); font-style: italic; }
.fr2-market { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: 16px; margin-top: 16px; }
.fr2-mtype { display: grid; grid-template-columns: 150px 1fr auto; gap: 10px; align-items: center; font-size: var(--fs-xs); color: var(--text-dim); padding: 4px 0; }
.fr2-mb { height: 8px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.fr2-mb i { display: block; height: 8px; border-radius: 4px; background: var(--fr-mid); }
.fr2-mb-dim { opacity: 0.45; }
.fr2-mtype b { color: var(--text); font-variant-numeric: tabular-nums; }
.fr2-map { height: 360px; width: 100%; max-width: 100%; border-radius: 10px; border: 1px solid var(--border); position: relative; z-index: 0; overflow: hidden; }
.fr2-mapfall { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--text-faint); font-size: var(--fs-xs); text-align: center; padding: 20px; }
.fr2-cl { background: var(--fr-cluster); color: var(--fr-ink-on); border: 2px solid var(--fr-ink-on); border-radius: 50%; display: flex; align-items: center; justify-content: center; font: 600 11px/1 var(--font-ui, sans-serif); }
.fr2-cl-dot { width: 10px; height: 10px; }
.fr2-pop { font-size: var(--fs-xs); min-width: 200px; }
.fr2-poplist { max-height: 170px; overflow: auto; margin-top: 6px; }
.fr2-poprow { display: flex; justify-content: space-between; gap: 16px; padding: 3px 0; border-bottom: 1px dashed var(--border); }

/* FR-6 — the investor drawer + the BRIGHT stage-gate (PO: mockup palette was muddy) */
.fr-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 92vw); background: var(--surface); border-left: 1px solid var(--border); box-shadow: var(--elev-2, var(--shadow-2)); padding: 18px 20px; overflow: auto; z-index: 60; line-height: 1.5; }
.fr-drawer .fr-listdesc { line-height: 1.55; margin: 0 0 12px; }
.fr-drawer-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.fr-drawer-head h3 { margin: 0; flex: 1; min-width: 0; }
.fr-gate { display: flex; gap: 4px; margin: 6px 0 10px; }
.fr-gate-seg { flex: 1; min-width: 0; text-align: center; }
.fr-gate-seg i { display: block; height: 8px; border-radius: 4px; background: var(--surface-3); }
.fr-gate-seg.done i { background: var(--cck-accent); opacity: 0.45; }
.fr-gate-seg.on i { background: var(--cck-accent); opacity: 1; }
.fr-gate-seg span { display: block; font-size: 9px; color: var(--text-faint); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-gate-seg.on span { color: var(--text); font-weight: 650; }
.fr-gate-declined { color: var(--cck-danger); font-weight: 650; font-size: var(--fs-sm); }
.fr-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; margin: 14px 0; }
.fr-fact { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.fr-fact span { font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); }
.fr-fact b { font-size: var(--fs-sm); overflow: hidden; text-overflow: ellipsis; }
.fr-drawer-acts { display: flex; gap: 8px; border-top: 1px solid var(--border); padding-top: 14px; margin-top: 12px; flex-wrap: wrap; }
.fr-name { text-align: left; padding: 0; }
.fr-research { max-height: 54vh; overflow: auto; font-size: var(--fs-sm); }
.fr-research b { display: inline-block; margin-top: 8px; }

/* FR-7 — market research lives ON the record and renders IN the drawer
   (informational, PO 2026-08-05: never a centre pop-up); the page header
   (title + tabs) anchors the scroll per the sticky STANDARD. */
.cck-viewer > .cck-work.fr-work { overflow: visible; }
.fr-sticky { position: sticky; top: -18px; z-index: 30; background: var(--surface-0); margin: -20px -22px 0; padding: 20px 22px 10px; border-radius: 14px 14px 0 0; }
.fr-sticky .fin-tabbar { margin-bottom: 0; }
.fr2-page { border-radius: 0 0 14px 14px; }
.fr-ressec { border: 1px solid var(--border); border-radius: 10px; margin-top: 12px; overflow: hidden; }
.fr-ressec-h { display: flex; align-items: center; gap: 8px; padding: 9px 12px; background: var(--surface-2); cursor: pointer; }
.fr-ressec-h:hover { background: var(--surface-3); }
.fr-ressec.open .fr-ressec-h { border-bottom: 1px solid var(--border); }
.fr-ressec-h h4 { margin: 0; font-size: 12.5px; font-weight: 650; white-space: nowrap; }
.fr-chev { width: 14px; height: 14px; stroke: var(--text-dim); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; transition: transform 0.15s; }
.fr-ressec.open .fr-chev { transform: rotate(90deg); }
.fr-resmeta { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--fs-xs); color: var(--text-faint); }
.fr-ressec .fr-research-inline { padding: 10px 12px; }
.fr-research-inline { max-height: none; overflow: visible; line-height: 1.55; }
.fr-research-inline h1, .fr-research-inline h2, .fr-research-inline h3, .fr-research-inline h4 { font-size: 13px; margin: 12px 0 4px; }
.fr-research-inline p { margin: 0 0 8px; }
.fr-research-inline ul, .fr-research-inline ol { margin: 0 0 8px; padding-left: 18px; }

/* FR-8a — the investor timeline: composer + one merged, attributed feed */
.fr-tl { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.fr-tl-h { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.fr-tl-h h4 { margin: 0; font-size: 13px; font-weight: 650; flex: 1; }
.fr-tl-chip { font: 600 10.5px/1 var(--font-ui, sans-serif); border: 1px solid var(--border); background: var(--surface); border-radius: 999px; padding: 4px 10px; color: var(--text-dim); cursor: pointer; }
.fr-tl-chip.on { background: var(--fr-early); color: var(--fr-early-ink); border-color: var(--fr-early); }
.fr-tl-composer { border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2); padding: 8px 10px; margin-bottom: 12px; }
.fr-tl-ta { width: 100%; border: 0; background: transparent; font: inherit; color: inherit; resize: vertical; min-height: 34px; outline: none; }
.fr-tl-crow { display: flex; gap: 8px; align-items: center; }
.fr-tl-crow > span { flex: 1; font-size: 10.5px; color: var(--text-faint); }
.fr-tl-list { position: relative; margin-left: 5px; }
.fr-tl-list::before { content: ''; position: absolute; left: 5px; top: 6px; bottom: 6px; width: 2px; background: var(--border); }
.fr-ev { position: relative; padding: 0 0 12px 22px; }
.fr-ev::before { content: ''; position: absolute; left: 0; top: 4px; width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--surface); background: var(--border-strong); }
.fr-ev-note::before { background: var(--text-faint); }
.fr-ev-stage::before { background: var(--fr-deep); }
.fr-ev-email::before { background: var(--fr-mid); }
.fr-ev-who { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.fr-ev-who b { font-size: 12px; }
.fr-ev-kind { font-size: 9.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; border-radius: 4px; padding: 1px 6px; background: var(--surface-3); color: var(--text-dim); }
.fr-ev-when { font-size: 10.5px; color: var(--text-faint); }
.fr-ev-open { margin-left: auto; }
.fr-ev-body { margin-top: 1px; overflow-wrap: anywhere; }
.fr-tl-cluster { border: 1px dashed var(--border-strong); border-radius: 8px; background: var(--surface-2); padding: 6px 10px; display: flex; align-items: center; gap: 8px; color: var(--text-dim); font-size: 11.5px; cursor: pointer; }
.fr-tl-cluster b { color: var(--text); }
.fr-tl-cluster span:last-child { margin-left: auto; color: var(--text-faint); }
.fr-tl-mailbox { border: 1px solid var(--border); border-radius: 8px; padding: 2px 10px; margin-top: 4px; }
.fr-mailrow { display: flex; gap: 8px; align-items: baseline; border-bottom: 1px dashed var(--border); padding: 5px 0; }
.fr-mailrow:last-child { border-bottom: 0; }
.fr-mailrow .s { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-ev-meeting::before { background: var(--ok-soft-fg); }
.fr-ev-kind-mtg { background: var(--ok-soft-bg); color: var(--ok-soft-fg); }
.fr-tl-q { width: 100%; margin-bottom: 8px; }
.fr-resbtn { white-space: nowrap; }
/* FR-8c — mockup-true timeline entries: initials avatars, tinted kind chips */
.fr-av { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; font: 700 8px/1 var(--font-ui, sans-serif); letter-spacing: 0; color: var(--fr-ink-on); background: var(--fr-deep); flex: none; transform: translateY(3px); }
.fr-av-alt { background: var(--fr-mid); }
.fr-av-sys { background: var(--text-faint); font-size: 10px; font-weight: 400; }
.fr-ev-kind-stage { background: var(--cck-accent-soft); color: var(--fr-deep); }
.fr-ev-kind-email { background: var(--cck-accent-soft); color: var(--fr-deep); }
.fr-ev-kind-task { background: var(--warning-chip-bg); color: var(--warning-chip-fg); }
.fr-ev-task::before { background: var(--fr-amber); }
/* FR-8c — the task row card (mockup): checkbox · title · due · assignee · open */
.fr-tk { display: flex; gap: 8px; align-items: baseline; margin-top: 3px; border: 1px solid var(--border); border-radius: 8px; padding: 7px 10px; background: var(--surface-2); }
.fr-tk input { flex: none; transform: translateY(1px); }
.fr-tk-t { flex: 1; min-width: 0; }
.fr-tk-done .fr-tk-t { text-decoration: line-through; color: var(--text-faint); }
.fr-tk-due { font-style: normal; font-size: 10.5px; font-weight: 650; color: var(--danger-text); }
.fr-tk-who { font-style: normal; font-size: 10.5px; color: var(--text-dim); }
.fr-tk-fields { display: flex; gap: 8px; margin: 6px 0; }
.fr-tk-fields input { flex: 1; min-width: 0; }
.fr-tk-duewrap { position: relative; flex: 1; min-width: 0; display: flex; }
.fr-tk-duewrap .cck-tk-inline { flex: 1; padding-right: 28px; }
.fr-tk-cal { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); border: 0; background: transparent; cursor: pointer; padding: 3px; border-radius: 6px; display: flex; }
.fr-tk-cal:hover { background: var(--surface-3); }
.fr-tk-cal svg { width: 14px; height: 14px; stroke: var(--text-dim); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fr-tk-dateinp { position: absolute; right: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; border: 0; padding: 0; }
.fr-showmore { display: flex; justify-content: center; padding: 10px 0 4px; border-top: 1px dashed var(--border); }

/* FR-10 — the columns editor */
.fr-colbox { max-height: 40vh; overflow: auto; border: 1px solid var(--border); border-radius: 8px; padding: 4px 10px; margin: 8px 0; }
.fr-colrow { display: flex; gap: 8px; align-items: center; padding: 4px 0; border-bottom: 1px dashed var(--border); }
.fr-colrow:last-child { border-bottom: 0; }
.fr-colrow .fr-colname { flex: 1; }
.fr-colkey { font-size: 10px; color: var(--text-faint); }
.fr-coladdrow { display: flex; gap: 8px; }
.fr-coladdrow input { flex: 1; }

/* FX-ADM — the Settings AI-usage table */
.settings-usage-table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 13px; }
.settings-usage-table th { text-align: left; font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-dim); padding: 6px 8px; border-bottom: 1px solid var(--border); }
.settings-usage-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
.settings-usage-table th.num, .settings-usage-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.settings-usage-table tfoot td { border-bottom: 0; border-top: 1.5px solid var(--border-strong); background: var(--surface-2); }
.settings-usage-scroll { max-height: 340px; overflow: auto; margin-top: 8px; border: 0.5px solid var(--border); border-radius: 8px; }
.settings-usage-scroll .settings-usage-table { margin-top: 0; }
.settings-usage-scroll th { position: sticky; top: 0; background: var(--surface-3); z-index: 1; }
.settings-usage-msub td { background: var(--surface-2); border-top: 1px solid var(--border-strong); }

/* FX-2 — the ledger-gap review card on Needs paying (shares the strays grammar) */
.fin-ledgergap { margin-bottom: 10px; }
.fin-runxero { white-space: nowrap; }
.fin-runtable .fin-brand-xero { height: 14px; vertical-align: middle; }
.fin-xerolink { display: inline-flex; align-items: center; }
.fin-runbar { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 8px 12px; border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); position: sticky; bottom: 0; }
.fin-runbar-sum { font-size: 12px; font-variant-numeric: tabular-nums; }
.fin-form-spacer { flex: 1 1 auto; }
.fin-runhint { font-size: 11px; color: var(--text-faint); margin-top: 8px; }
.fin-runstrays { margin-top: 12px; border: 0.5px solid var(--border); border-radius: 10px; padding: 8px 12px; background: var(--surface-0); }
.fin-runstrays-h { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); margin: 0 0 4px; }
.fin-runstrays-p { font-size: 11px; color: var(--text-dim); margin: 0 0 6px; }
.fin-runstray { font-size: 12px; padding: 2px 0; }
/* FX-1d — Cash in and out rail card (the Xero-dashboard widget, tokened) */
.fin-cio { gap: 10px; }
.fin-cio-nums { display: flex; gap: 14px; }
.fin-cio-num { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fin-cio-num b { font-size: var(--fs-md); font-weight: 650; white-space: nowrap; }
.fin-cio-num i, .fin-cio-m i { color: var(--text-3); font-style: normal; font-size: var(--fs-xs); white-space: nowrap; }
.fin-cio-neg { color: var(--danger); }
.fin-cio-plot { display: flex; gap: 6px; margin-top: 4px; }
.fin-cio-axis { display: flex; flex-direction: column; justify-content: space-between; height: 64px; text-align: right; }
.fin-cio-axis i { color: var(--text-3); font-style: normal; font-size: 9px; line-height: 1; opacity: .85; }
.fin-cio-chart { position: relative; flex: 1; display: flex; align-items: flex-end; gap: 6px; height: 79px; }
/* gridlines pinned to the 64px bar zone: max (0), half (32px), zero (above the 15px month labels) */
.fin-cio-chart::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 32px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); pointer-events: none; }
.fin-cio-chart::after { content: ''; position: absolute; left: 0; right: 0; bottom: 15px; border-bottom: 1px solid var(--border); pointer-events: none; }
.fin-cio-m i { height: 15px; display: flex; align-items: flex-end; }
.fin-cio-m { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; height: 100%; justify-content: flex-end; }
.fin-cio-bars { display: flex; align-items: flex-end; gap: 2px; flex: 1; width: 100%; justify-content: center; }
.fin-cio-bars span { width: 45%; max-width: 10px; border-radius: 2px 2px 0 0; display: block; }
span.fin-cio-in, em.fin-cio-in { background: var(--accent); }
span.fin-cio-out, em.fin-cio-out { background: var(--accent-soft, var(--border)); }
.fin-cio-legend { display: flex; gap: 6px; align-items: center; color: var(--text-3); font-size: var(--fs-xs); }
.fin-cio-legend em { width: 8px; height: 8px; border-radius: 50%; display: inline-block; font-style: normal; }

/* FIN-23b — History: sticky header + tonal depth (PO: "more tones… fixed titles row") */
.fin-histwrap { max-height: 62vh; overflow: auto; }
.fin-histtable tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--accent) 3%, var(--surface)); }
.fin-histtable tbody tr:hover td { background: color-mix(in srgb, var(--accent) 7%, var(--surface)); }
.fin-histtable td.num { font-weight: 600; font-variant-numeric: tabular-nums; }
.fin-histfile { text-align: left; display: inline; }   /* buttons centre their text by default — file names sit left like every other cell */
.fin-histpre td { opacity: .72; }

/* FX-1b — the live Cash tile brand marks (NatWest + Xero, inline SVG) */
.fin-brand { width: 14px; height: 14px; vertical-align: -2px; margin-right: 5px; display: inline-block; }
.fin-tile-l .fin-brand { margin-left: auto; margin-right: 0; }   /* the brand mark sits right-aligned on the tile label, like Xero's own bank card */
.fin-rail-cash span { display: flex; align-items: center; }
.fin-rail-cash .fin-brand-xero { margin-left: auto; height: 20px; width: auto; }   /* PO: a little bigger */
/* FIN-24b — compact rail panels: Top expenses bars + month-on-month variance */
.fin-rtrend { gap: 5px; }
.fin-rtr { display: flex; align-items: center; gap: 6px; min-width: 0; }
.fin-rtr-l { flex: 0 0 88px; font-size: 10.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fin-rtr-track { flex: 1; height: 6px; background: var(--surface-2); border-radius: 3px; overflow: hidden; }
.fin-rtr-bar { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.fin-rtr-amt { margin-left: auto; font-size: 10.5px; font-weight: 650; font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; }   /* PO: bold amounts */
.fin-brand-xero { width: auto; height: 18px; }   /* the real wordmark, sized to read (PO: "make it bigger") */
.fin-tile-live span, .fin-tile-live i { display: flex; align-items: center; gap: 2px; min-width: 0; }
.fin-tile-live i { overflow: hidden; }
.fin-tile-live i button { white-space: nowrap; }
.fin-tile-live i .fin-brand { width: 12px; height: 12px; margin-right: 3px; }
.fin-tile i a { color: inherit; text-decoration: underline; }

.fin-xeroconnect { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-0); padding: 16px; margin-bottom: 12px; }
.fin-xc-title { font-size: 13px; font-weight: 600; margin: 0 0 4px; }
.fin-xc-body { font-size: 12px; color: var(--text-dim); margin: 0 0 10px; max-width: 60ch; }
.fin-xc-hint { font-size: 10.5px; color: var(--text-faint); margin: 8px 0 0; }

.fin-offscreen { position: fixed; top: -9999px; left: 0; }
.fin-runlist-ta { width: 100%; font: 12px/1.5 ui-monospace, monospace; color: var(--text); background: var(--surface-2); border: 0.5px solid var(--border); border-radius: 8px; padding: 8px; }


/* ── R12-1 Tickets (docs/defines/mockup_tickets.html, approved 2026-08-05) ──
   The Fundraising page skeleton: headline → KPI tiles → equal-height list +
   drawer panes whose bodies scroll inside; below 1020px they stack. One
   status idiom (the investor drawer's gate strip); option-C BUG/FEATURE
   markers; approve/hold once, in the drawer. */
.tk2-page { display: flex; flex-direction: column; min-height: 0; height: 100%; }
.tk2-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 12px; }
.tk2-head-grow { flex: 1; min-width: 0; }
.tk2-h1 { font-size: var(--fs-xl, 20px); font-weight: 650; margin: 0; }
.tk2-sub { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); margin-top: 2px; }
.tk2-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 14px; }
.tk2-kpi { background: var(--surface); border: 0.5px solid var(--border); border-radius: 12px; padding: 10px 14px; }
.tk2-kpi-attn { border-color: var(--warning-chip-fg); background: var(--warning-chip-bg); }
.tk2-kpi-attn .tk2-v { color: var(--warning-chip-fg); }
.tk2-k { font-size: 10px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); }
.tk2-v { font-size: 22px; font-weight: 650; margin-top: 2px; font-variant-numeric: tabular-nums; }
.tk2-d { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); }
.tk2-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 0.62fr); gap: 14px; align-items: stretch; flex: 1; min-height: 0; height: calc(100vh - 320px); }
@media (max-width: 1020px) { .tk2-grid { grid-template-columns: 1fr; height: auto; } .tk2-pane { max-height: 70vh; } }
.tk2-pane { background: var(--surface); border: 0.5px solid var(--border); border-radius: 12px; padding: 14px 16px; display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.tk2-h3 { font-size: var(--fs-md, 14px); font-weight: 650; margin: 0; }
.tk2-cap { font-size: var(--fs-xs, 11.5px); color: var(--text-faint); margin: 2px 0 10px; }
.tk2-pbody { flex: 1; overflow: auto; min-height: 0; margin: 0 -6px; padding: 0 6px; }
.tk2-toolrow { display: flex; gap: 8px; align-items: center; margin: 0 0 8px; flex-wrap: wrap; }
.tk2-q { flex: 1; min-width: 140px; font: inherit; font-size: var(--fs-xs, 11.5px); border: 0.5px solid var(--border); border-radius: 999px; padding: 6px 12px; background: var(--surface); color: inherit; }
.tk2-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.tk2-chip { font: 600 10.5px/1 var(--font-ui, sans-serif); border: 0.5px solid var(--border); background: var(--surface); border-radius: 999px; padding: 4px 10px; color: var(--text-dim); cursor: pointer; }
.tk2-chip.on { background: var(--fr-early); border-color: var(--fr-early); color: var(--fr-early-ink); }
.tk2-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 10px; padding: 9px 8px; border-bottom: 1px solid var(--border); cursor: pointer; border-radius: 8px; }
.tk2-row:hover { background: var(--surface-2); }
.tk2-row.on { background: var(--cck-accent-soft); }
.tk2-row:last-child { border-bottom: 0; }
.tk2-row-main b { font-size: var(--fs-sm, 12.5px); }
.tk2-row-sub { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); }
.tk2-row-right { text-align: right; align-self: center; font-size: var(--fs-xs, 11.5px); color: var(--text-faint); }
.tk2-st { display: block; font-weight: 650; color: var(--text-dim); }
.tk2-st.attn { color: var(--warning-chip-fg); }
.tk2-st.ok { color: var(--ok-soft-fg); }
.tk2-st-sub { font-size: 10px; }
.tk2-kind { display: flex; align-items: center; gap: 6px; font: 700 9px/1 var(--font-ui, sans-serif); letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 3px; }
.tk2-kico { width: 15px; height: 15px; fill: none; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.tk2-kico-bug { stroke: var(--tk-bug); }
.tk2-kico-feat { stroke: var(--tk-feat); }
.tk2-empty { font-size: var(--fs-xs, 11.5px); color: var(--text-faint); padding: 18px 6px; }
.tk2-digest { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-2); padding: 9px 12px; font-size: var(--fs-xs, 11.5px); color: var(--text-dim); margin-top: 10px; }
.tk2-railnote { font-size: var(--fs-xs, 11.5px); color: var(--text-faint); padding: 10px 4px 0; line-height: 1.5; }
/* drawer */
.tk2-dtitle { display: block; font-size: var(--fs-md, 14px); font-weight: 650; margin: 2px 0 8px; }
.tk2-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; margin: 0 0 12px; }
.tk2-fact span { display: block; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); }
.tk2-fact b { font-size: var(--fs-xs, 11.5px); }
.tk2-gate { display: flex; gap: 4px; margin: 0 0 12px; }
.tk2-gseg { flex: 1; text-align: center; }
.tk2-gseg i { display: block; height: 7px; border-radius: 4px; background: var(--surface-3); }
.tk2-gseg.done i { background: var(--fr-early); }
.tk2-gseg.on i { background: var(--fr-deep); }
.tk2-gseg span { font-size: 9px; color: var(--text-faint); margin-top: 3px; display: block; }
.tk2-gseg.on span { color: var(--text); font-weight: 650; }
.tk2-ressec { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-2); margin-bottom: 10px; }
.tk2-rh { display: flex; align-items: center; gap: 8px; padding: 8px 12px 0; }
.tk2-rh b { flex: 1; font-size: var(--fs-xs, 11.5px); }
.tk2-meta { font-size: 10px; color: var(--text-faint); }
.tk2-rb { padding: 4px 12px 10px; font-size: var(--fs-xs, 11.5px); color: var(--text-dim); line-height: 1.55; }
.tk2-rb.tk2-mono { font-family: ui-monospace, monospace; font-size: 10.5px; white-space: pre-wrap; }
.tk2-rb.tk2-pending { padding-top: 10px; }
.tk2-rec { background: var(--warning-chip-bg); color: var(--warning-chip-fg); border-radius: 8px; padding: 8px 12px; font-size: var(--fs-xs, 11.5px); margin-bottom: 10px; }
.tk2-rec b { display: block; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; margin-bottom: 1px; }
.tk2-actions { display: flex; gap: 8px; align-items: center; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 8px; }
.tk2-hint { flex: 1; font-size: 10.5px; color: var(--text-faint); }
.tk2-tl { position: relative; margin: 10px 0 2px 5px; }
.tk2-tl::before { content: ''; position: absolute; left: 5px; top: 6px; bottom: 6px; width: 2px; background: var(--border); }
.tk2-ev { position: relative; padding: 0 0 10px 24px; }
.tk2-ev:last-child { padding-bottom: 0; }
.tk2-ev::before { content: ''; position: absolute; left: 0; top: 3px; width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--surface); background: var(--border-strong); }
.tk2-ev.on::before { background: var(--fr-deep); }
.tk2-evw { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); }
.tk2-evw b { color: var(--text); }
.tk2-evd { font-size: 10px; color: var(--text-faint); }
/* composer (opens over ANY screen — rides the cck overlay scrim) */
.tk2-composer { background: var(--surface); border: 0.5px solid var(--border); border-radius: 14px; box-shadow: var(--shadow); width: min(440px, 92vw); padding: 16px 18px; }
.tk2-seg { display: inline-flex; border: 0.5px solid var(--border); border-radius: 999px; overflow: hidden; margin: 6px 0 10px; }
.tk2-seg button { font: 600 11px/1 var(--font-ui, sans-serif); padding: 6px 14px; border: 0; background: transparent; color: var(--text-dim); cursor: pointer; }
.tk2-seg button.on { background: var(--fr-early); color: var(--fr-early-ink); }
.tk2-flabel { display: block; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); margin: 8px 0 3px; }
.tk2-finput { width: 100%; font: inherit; font-size: var(--fs-sm, 12.5px); border: 0.5px solid var(--border); border-radius: 8px; background: var(--surface-2); color: inherit; padding: 7px 10px; resize: none; }
.tk2-auto { border: 1px dashed var(--border-strong); border-radius: 10px; background: var(--surface-2); padding: 8px 12px; font-size: var(--fs-xs, 11.5px); color: var(--text-dim); margin: 10px 0; }
.tk2-auto b { display: block; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 2px; }
.tk2-cb { display: flex; gap: 6px; align-items: center; margin-top: 6px; }
.tk2-crow { display: flex; gap: 8px; align-items: center; }
.tk2-crow .tk2-hint { flex: 1; }

/* ── R12-6 Help: the ? button + the help drawer ─────────────────────────── */
#hlp-fab { position: fixed; right: 16px; bottom: 74px; width: 34px; height: 34px; border-radius: 50%; border: 0.5px solid var(--border-strong); background: var(--surface); color: var(--text-dim); font: 650 15px/1 var(--font-ui, sans-serif); cursor: pointer; box-shadow: var(--shadow); z-index: 900; }
#hlp-fab:hover { background: var(--cck-accent-soft); color: var(--cck-accent); }
#hlp-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(400px, 92vw); background: var(--surface); border-left: 0.5px solid var(--border); box-shadow: var(--shadow); z-index: 901; display: flex; flex-direction: column; padding: 14px 16px; }
.hlp-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.hlp-head > b { font-size: var(--fs-md, 14px); }
.hlp-tabs { display: flex; gap: 4px; flex: 1; }
.hlp-tab { font: 600 10.5px/1 var(--font-ui, sans-serif); border: 0.5px solid var(--border); background: var(--surface); border-radius: 999px; padding: 4px 10px; color: var(--text-dim); cursor: pointer; }
.hlp-tab.on { background: var(--fr-early); border-color: var(--fr-early); color: var(--fr-early-ink); }
.hlp-x { border: 0; background: transparent; color: var(--text-faint); font-size: 14px; cursor: pointer; padding: 4px; }
.hlp-q { font: inherit; font-size: var(--fs-xs, 11.5px); border: 0.5px solid var(--border); border-radius: 999px; padding: 6px 12px; background: var(--surface-2); color: inherit; margin-bottom: 10px; }
.hlp-body { flex: 1; overflow: auto; min-height: 0; }
.hlp-article h3 { font-size: var(--fs-md, 14px); font-weight: 650; margin: 0 0 4px; }
.hlp-blurb { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); margin: 0 0 10px; line-height: 1.55; }
.hlp-article h4 { font-size: var(--fs-xs, 11.5px); font-weight: 650; margin: 12px 0 3px; }
.hlp-article p { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); margin: 0 0 6px; line-height: 1.55; }
.hlp-howdo { display: flex; flex-direction: column; border-left: 2px solid var(--border-strong); padding: 2px 0 2px 10px; margin: 0 0 8px; }
.hlp-howdo b { font-size: var(--fs-xs, 11.5px); }
.hlp-howdo span { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); line-height: 1.5; }
.hlp-hit { display: flex; flex-direction: column; width: 100%; text-align: left; border: 0.5px solid var(--border); background: var(--surface); border-radius: 10px; padding: 8px 12px; margin-bottom: 6px; cursor: pointer; color: inherit; font: inherit; }
.hlp-hit:hover { background: var(--surface-2); }
.hlp-hit b { font-size: var(--fs-xs, 11.5px); }
.hlp-hit span { font-size: 10.5px; color: var(--text-faint); }
.hlp-empty { font-size: var(--fs-xs, 11.5px); color: var(--text-faint); padding: 12px 2px; line-height: 1.5; }
.hlp-build { border-bottom: 1px dashed var(--border); padding: 8px 0; }
.hlp-build:last-child { border-bottom: 0; }
.hlp-build-h { display: flex; gap: 8px; align-items: baseline; margin-bottom: 3px; }
.hlp-build-h b { font-size: var(--fs-xs, 11.5px); }
.hlp-build-h span { font-size: 10px; color: var(--text-faint); }
.hlp-build p { font-size: var(--fs-xs, 11.5px); color: var(--text-dim); margin: 0 0 3px; line-height: 1.5; }
.hlp-build-tk span { color: var(--text-faint); }
.hlp-foot { display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 10px; }
.hlp-ver { flex: 1; font-size: 10.5px; color: var(--text-faint); }
/* the quiet version line under the sidebar */
.an-build { font-size: 10px; color: var(--text-faint); padding: 6px 14px 10px; }

/* ── R12-2 Users & Access (Settings) ─────────────────────────────────────── */
.settings-access-scroll { max-height: 320px; overflow: auto; border: 0.5px solid var(--border); border-radius: 10px; margin: 6px 0 4px; }
.settings-access-table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs, 11.5px); }
.settings-access-table th { position: sticky; top: 0; background: var(--surface); font-size: 9.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); text-align: left; padding: 7px 8px; border-bottom: 1px solid var(--border-strong); }
.settings-access-table th.c, .settings-access-table td.c { text-align: center; }
.settings-access-table td { padding: 7px 8px; border-bottom: 1px solid var(--border); }
.settings-access-table tr:last-child td { border-bottom: 0; }
.settings-access-table select { font: inherit; font-size: var(--fs-xs, 11.5px); border: 0.5px solid var(--border); border-radius: 6px; padding: 3px 6px; background: var(--surface); color: inherit; }


/* ── R12-5 Templates (docs/defines/mockup_template-editor.html) ─────────── */
.tpl-grid { grid-template-columns: minmax(0, 1fr) minmax(340px, 0.78fr); }
.tpl-tools { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 8px; }
.tpl-node { border-left: 2px solid var(--border); margin-left: 8px; padding: 2px 0 2px 14px; position: relative; }
.tpl-node::before { content: ''; position: absolute; left: -2px; top: 15px; width: 10px; height: 2px; background: var(--border); }
.tpl-node.tpl-root { border-left: 0; margin-left: 0; padding-left: 0; }
.tpl-node.tpl-root::before { display: none; }
.tpl-row { display: flex; align-items: baseline; gap: 8px; padding: 4px 8px; border-radius: 7px; cursor: pointer; flex-wrap: wrap; }
.tpl-row:hover { background: var(--surface-2); }
.tpl-row b { font-size: var(--fs-sm, 12.5px); }
.tpl-desc { flex: 1; min-width: 120px; font-size: var(--fs-xs, 11px); color: var(--text-dim); font-style: italic; }
.tpl-rule { font: 600 9.5px/1 var(--font-ui, sans-serif); background: var(--surface-2); border: 0.5px solid var(--border); border-radius: 5px; padding: 2px 6px; color: var(--text-faint); white-space: nowrap; }
.tpl-add { font-size: var(--fs-xs, 11px); color: var(--cck-accent); cursor: pointer; padding: 3px 8px; border: 0; background: transparent; }
.tpl-edit { display: grid; gap: 6px; background: var(--surface-2); border: 0.5px solid var(--border); border-radius: 9px; padding: 9px 10px; margin: 3px 0; }
.tpl-in { font: inherit; font-size: var(--fs-xs, 11.5px); border: 0.5px solid var(--border); border-radius: 7px; padding: 6px 9px; background: var(--surface); color: inherit; }
.tpl-edit-actions { display: flex; gap: 6px; align-items: center; }
.tpl-sp { flex: 1; }
.tpl-chat { display: flex; flex-direction: column; gap: 10px; }
.tpl-msg { max-width: 94%; border-radius: 12px; padding: 9px 13px; font-size: var(--fs-xs, 12px); line-height: 1.5; }
.tpl-user { align-self: flex-end; background: var(--fr-early); color: var(--fr-early-ink); border-bottom-right-radius: 4px; }
.tpl-ai { align-self: flex-start; background: var(--surface-2); border: 0.5px solid var(--border); border-bottom-left-radius: 4px; }
.tpl-who { font: 700 9px/1 var(--font-ui, sans-serif); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-faint); display: block; margin-bottom: 4px; }
.tpl-plan { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface); margin-top: 8px; overflow: hidden; }
.tpl-plan-h { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--border); background: var(--surface-2); }
.tpl-plan-h b { flex: 1; font-size: var(--fs-xs, 12px); }
.tpl-plan-n { font: 600 10px/1 var(--font-ui, sans-serif); background: var(--warning-chip-bg); color: var(--warning-chip-fg); border-radius: 999px; padding: 3px 9px; }
.tpl-plan-body { max-height: 240px; overflow: auto; }
.tpl-mv { display: grid; grid-template-columns: minmax(0, 1fr) 14px minmax(0, 1fr); gap: 2px 6px; padding: 5px 12px; border-bottom: 1px solid var(--border); font-size: 11px; }
.tpl-mv:last-child { border-bottom: 0; }
.tpl-mv i { color: var(--text-faint); font-style: normal; text-align: center; }
.tpl-why { grid-column: 1 / -1; font-size: 10px; color: var(--text-faint); }
.tpl-mv.tpl-skip span:first-child { color: var(--cck-danger); }
.tpl-mv.tpl-more span { color: var(--text-faint); }
.tpl-plan-f { display: flex; gap: 8px; align-items: center; padding: 9px 12px; border-top: 1px solid var(--border); background: var(--surface-2); }
.tpl-hint { flex: 1; font-size: 10px; color: var(--text-faint); line-height: 1.4; }
.tpl-composer { display: flex; gap: 8px; margin-top: 10px; }
.tpl-q { flex: 1; font: inherit; font-size: var(--fs-xs, 12px); border: 0.5px solid var(--border); border-radius: 999px; padding: 8px 14px; background: var(--surface-2); color: inherit; outline: none; }

/* ── R12-4 Settings: Protections / Approval queue additions ─────────────── */
.settings-prot-grp { font: 700 9.5px/1 var(--font-ui, sans-serif); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-faint); padding: 14px 0 2px; }
.settings-prot-num { width: 76px; font: inherit; font-size: var(--fs-xs, 11.5px); border: 0.5px solid var(--border); border-radius: 7px; padding: 5px 8px; background: var(--surface-2); color: inherit; text-align: right; }
.settings-apq { border: 0.5px solid var(--border); border-radius: 10px; background: var(--surface-2); padding: 10px 13px; margin: 8px 0; }
.settings-apq-h b { display: block; font-size: var(--fs-sm, 12.5px); }
.settings-apq-kind { font: 700 9px/1 var(--font-ui, sans-serif); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); }
.settings-apq-prev { background: var(--surface); border: 0.5px solid var(--border); border-radius: 8px; margin: 8px 0; }
.settings-apq-mv { display: grid; grid-template-columns: minmax(0, 1fr) 14px minmax(0, 1fr); gap: 6px; padding: 4px 10px; border-bottom: 1px solid var(--border); font-size: 11px; }
.settings-apq-mv:last-child { border-bottom: 0; }
.settings-apq-mv i { color: var(--text-faint); font-style: normal; text-align: center; }
.settings-apq-actions { display: flex; gap: 12px; justify-content: flex-end; }
.settings-apq-yes { color: var(--cck-accent); }
