
  /* ══════════════════════════════════════════════════════════════════════════
     PORTFOLIO INTELLIGENCE WORKSPACE — implementation of the pinned W2 mockup
     (mockups/refs/psi/workspace/workspace.html + DESIGN_NOTES.md).

     Every colour resolves through templates/theme.css tokens; NOTHING is
     re-declared here. Theme mechanism per DESIGN_NOTES §7(a): dark is the bare
     `:root` plane theme.css already defines, light is `html[data-theme="light"]`.
     There is deliberately no `[data-theme="dark"]` selector in this file — such a
     rule ships DEAD for a first-time visitor (theme.css:252-260).

     Page-local classes are ws- / bk- / seam- / att- / rc- / hold-prefixed so a
     later shared-primitive PR can land without collision.
     ══════════════════════════════════════════════════════════════════════════ */
  * { box-sizing:border-box; }
  html, body { margin:0; padding:0; }
  body { background:var(--bg); color:var(--text); font-family:var(--font-ui);
         font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased; }
  a { color:var(--ink-link); text-decoration:none; }

  /* mono numerals are for FIGURES, never for words (§2) */
  .fig { font-family:var(--font-mono); font-variant-numeric:tabular-nums;
         font-feature-settings:"tnum" 1; letter-spacing:-.01em; }
  .ws .mut { color:var(--muted); }

  .ws { max-width:1240px; margin:0 auto; padding:22px 26px 90px; }
  @media (max-width:640px){ .ws { padding:16px 14px 70px; } }

  /* ── WORKSPACE HEAD — title · mode switch · save-state chip ──────────────── */
  .ws-head { display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:end;
    gap:14px 20px; padding-bottom:13px; border-bottom:1px solid var(--line); margin-bottom:20px; }
  .ws-title { margin:0; font-size:21px; font-weight:750; letter-spacing:-.025em; line-height:1.15; }
  .ws-purpose { margin:3px 0 0; font-size:12.5px; color:var(--muted); }
  .ws-headright { display:flex; flex-direction:column; align-items:flex-end; gap:9px; }

  /* segmented mode control — one control, two jobs, never a third page header */
  .ws-modes { display:inline-flex; padding:3px; gap:3px; border-radius:11px;
    border:1px solid var(--gbtn-brd); background:var(--gbtn-bg);
    -webkit-backdrop-filter:blur(12px) saturate(140%); backdrop-filter:blur(12px) saturate(140%); }
  .ws-mode { appearance:none; border:1px solid transparent; background:transparent;
    color:var(--muted); font-family:inherit; font-size:13px; font-weight:650;
    padding:6px 15px; border-radius:8px; cursor:pointer; line-height:1.2;
    transition:color .16s ease, background .16s ease, border-color .16s ease; }
  .ws-mode:hover { color:var(--text); }
  .ws-mode[aria-selected="true"] { background:var(--panel); color:var(--text);
    border-color:var(--line); box-shadow:var(--card-shadow); }
  .ws-mode:focus-visible { outline:2px solid color-mix(in srgb,var(--link) 70%,transparent);
    outline-offset:2px; }
  .ws-mode .n { margin-left:7px; font-size:11px; font-weight:700; color:var(--muted); }
  .ws-mode[aria-selected="true"] .n { color:var(--ink-link); }
  .ws-mode .n:empty { margin-left:0; }

  /* save-state chip — the ONLY disclosure of sync state (Account Sync panel deleted) */
  .ws-chip { display:inline-flex; align-items:center; gap:7px; padding:4px 11px; border-radius:999px;
    border:1px solid var(--line); background:var(--panel);
    font-size:11.5px; font-weight:650; color:var(--muted); white-space:nowrap; }
  .ws-chip i { width:6px; height:6px; border-radius:50%; background:currentColor; flex:none; }
  .ws-chip.is-saved { color:var(--ink-ok); border-color:color-mix(in srgb,var(--ok) 34%,var(--line)); }
  .ws-chip.is-saving { color:var(--ink-link); border-color:color-mix(in srgb,var(--link) 34%,var(--line)); }
  .ws-chip.is-saving i { animation:ws-chippulse 1.4s ease-in-out infinite; }
  .ws-chip.is-local { color:var(--muted); }
  .ws-chip.is-local i { background:transparent; border:1px solid currentColor; }
  .ws-chip.is-offline { color:var(--ink-warn); border-color:color-mix(in srgb,var(--warn) 34%,var(--line)); }
  .ws-chip.is-offline i { background:transparent; border:1px solid currentColor; }
  /* A1A Part A: `failed` is a Portfolio write that did not land — the danger/down
     token, same family as a real error. `unavailable` is a paused-editing read state,
     not a failure of anything the visitor did — the muted/warn tone `offline` uses. */
  .ws-chip.is-failed { color:var(--ink-down); border-color:color-mix(in srgb,var(--down) 34%,var(--line)); }
  .ws-chip.is-unavailable { color:var(--ink-warn); border-color:color-mix(in srgb,var(--warn) 34%,var(--line)); }
  .ws-chip.is-unavailable i { background:transparent; border:1px solid currentColor; }
  @keyframes ws-chippulse { 0%,100%{ opacity:1 } 50%{ opacity:.35 } }
  @media (prefers-reduced-motion:reduce){ .ws-chip.is-saving i { animation:none; } }

  @media (max-width:720px){
    .ws-head { grid-template-columns:1fr; align-items:start; }
    .ws-headright { align-items:flex-start; width:100%; }
    .ws-modes { width:100%; }
    .ws-mode { flex:1; padding:8px 10px; }
  }

  /* ── SECTION GRAMMAR — eyebrow + one dominant idea ───────────────────────── */
  .sec { margin:0 0 26px; }
  .sec-hd { display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin:0 0 10px; }
  .sec-eyebrow { display:inline-flex; align-items:center; gap:7px; flex:none;
    font-size:10px; font-weight:750; letter-spacing:.09em; text-transform:uppercase;
    color:var(--muted); }
  .sec-eyebrow::before { content:""; width:14px; height:1px; background:var(--line); flex:none; }
  .sec-sub { font-size:12px; color:var(--muted); min-width:0; }
  .sec-asof { margin-left:auto; font-size:10.5px; color:var(--muted); opacity:.72;
    font-variant-numeric:tabular-nums; white-space:nowrap; }
  .ws .panel { background:var(--panel); border:1px solid var(--line); border-radius:14px;
    box-shadow:var(--card-shadow); }

  /* A1A — the temporary basket is labeled everywhere it renders (never confused with
     the canonical, saved Portfolio) and a degraded cloud read is disclosed, not hidden. */
  .basket-badge { display:inline-flex; align-items:center; font-size:9.5px; font-weight:750;
    letter-spacing:.05em; text-transform:none; color:var(--ink-warn);
    border:1px solid color-mix(in srgb,var(--warn) 34%,var(--line)); border-radius:99px;
    padding:2px 9px; margin-left:8px; white-space:nowrap; }
  .pf-readbanner { display:none; margin:0 0 12px; padding:9px 14px; border-radius:10px;
    font-size:12.5px; font-weight:600; color:var(--ink-warn);
    background:color-mix(in srgb,var(--warn) 10%,var(--panel));
    border:1px solid color-mix(in srgb,var(--warn) 34%,var(--line)); }

  /* ══════════════════════════════════════════════════════════════════════════
     ★ SIGNATURE — THE BOOK SEAM (DESIGN_NOTES §1)
     Two aligned hairline rails under a plain-language book read. Top rail =
     share of MONEY (every position). Bottom = share of modeled RISK. Same width,
     same order; where they disagree is the whole product. Direction-NEUTRAL by
     construction (--link / --muted only) so 红涨绿跌 never recolours it.
     ══════════════════════════════════════════════════════════════════════════ */
  .bookread { padding:19px 22px 17px; }
  .bk-meta { display:flex; flex-wrap:wrap; align-items:baseline; gap:5px 14px;
    font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
    color:var(--muted); margin-bottom:11px; }
  .bk-meta .sep { opacity:.4; }
  .bk-say { margin:0; font-size:30px; line-height:1.22; font-weight:600; letter-spacing:-.028em;
    max-width:23ch; text-wrap:balance; }
  .bk-say .fig { font-weight:750; color:var(--text); }
  .bk-because { margin:9px 0 0; font-size:15px; line-height:1.45; color:var(--muted); max-width:46ch; }
  .bk-because b { font-weight:650; color:var(--text); }
  .bk-stance { display:inline-block; margin:13px 0 0; font-size:12.5px; font-weight:700;
    color:var(--text); padding:3px 0;
    border-bottom:2px solid color-mix(in srgb,var(--link) 55%,transparent); }
  @media (max-width:640px){ .bk-say { font-size:23px; max-width:none; } .bk-because { font-size:13.5px; } }

  .seam { margin:24px 0 0; }
  .seam-grid { display:grid; grid-template-columns:auto minmax(0,1fr); gap:0 13px; align-items:center; }
  .seam-lbl { font-size:9.5px; font-weight:750; letter-spacing:.08em; text-transform:uppercase;
    color:var(--muted); text-align:right; white-space:nowrap; }
  .seam-rail { display:flex; gap:2px; height:14px; padding:2px; border-radius:5px;
    border:1px solid var(--line); background:var(--panel2); }
  .seam-seg { border-radius:2px; min-width:2px;
    background:color-mix(in srgb,var(--muted) 40%,var(--panel2)); }
  .seam-seg.is-cluster { background:color-mix(in srgb,var(--link) 62%,var(--panel2)); }
  .seam-seg.is-ballast { background:color-mix(in srgb,var(--muted) 26%,var(--panel2)); }
  /* a position the risk model does not cover: hatched on the money rail, an empty
     slot on the risk rail. The coverage disclosure is DRAWN, not merely written. */
  .seam-seg.is-uncovered { background:repeating-linear-gradient(-45deg,
      color-mix(in srgb,var(--muted) 34%,var(--panel2)) 0 2px, transparent 2px 5px);
    border:1px dashed color-mix(in srgb,var(--muted) 50%,transparent); }
  .seam-seg.is-void { background:transparent;
    border:1px dashed color-mix(in srgb,var(--muted) 34%,transparent); }
  /* the folded tail (see MAX_SEGS in watchlist.js): quieter than a named position,
     because it is a group and must not read as one holding */
  .seam-seg.is-tail { background:repeating-linear-gradient(90deg,
      color-mix(in srgb,var(--muted) 30%,var(--panel2)) 0 3px,
      color-mix(in srgb,var(--muted) 14%,var(--panel2)) 3px 6px); }
  /* the risk rail before a signed-in factor read exists: one locked slot, never a
     fabricated distribution (anonymous ruling A9) */
  .seam-rail.is-locked { background:repeating-linear-gradient(-45deg,
      color-mix(in srgb,#7c5cff 12%,var(--panel2)) 0 3px, var(--panel2) 3px 7px);
    border-style:dashed; border-color:color-mix(in srgb,#7c5cff 40%,var(--line)); }

  .seam-brk { position:relative; height:17px; }
  .seam-brk .span { position:absolute; left:0; width:var(--w);
    border:1px solid color-mix(in srgb,var(--link) 66%,transparent); }
  .seam-brk.is-over .span { bottom:0; height:6px; border-bottom:0; border-radius:4px 4px 0 0; }
  .seam-brk.is-under .span { top:0; height:6px; border-top:0; border-radius:0 0 4px 4px; }
  .seam-brk b { position:absolute; left:0; width:var(--w); text-align:center;
    font-size:10.5px; font-weight:700; color:var(--ink-link); letter-spacing:.01em;
    white-space:nowrap; }
  .seam-brk.is-over b { top:0; } .seam-brk.is-under b { bottom:0; }
  .seam-brk b .fig { font-weight:750; }
  .seam-gap { position:relative; height:13px; }
  .seam-gap .over { position:absolute; top:-3px; bottom:-3px; left:var(--a); width:var(--d);
    background:color-mix(in srgb,var(--link) 17%,transparent);
    border-left:1px dashed color-mix(in srgb,var(--link) 62%,transparent);
    border-right:1px dashed color-mix(in srgb,var(--link) 40%,transparent); }
  .seam-cap { margin:17px 0 0; font-size:12.5px; line-height:1.55; color:var(--muted); max-width:74ch; }
  .seam-cap b { color:var(--text); font-weight:650; }
  .bk-coverage { margin:13px 0 0; padding-top:12px; border-top:1px solid var(--line);
    font-size:11.5px; line-height:1.5; color:var(--muted); display:flex; gap:9px; align-items:flex-start; }
  .bk-coverage:empty { display:none; }
  .bk-coverage .mark { flex:none; width:15px; height:15px; border-radius:4px; margin-top:1px;
    background:repeating-linear-gradient(-45deg,color-mix(in srgb,var(--muted) 34%,var(--panel2)) 0 2px,transparent 2px 5px);
    border:1px dashed color-mix(in srgb,var(--muted) 50%,transparent); }
  .bk-coverage b { color:var(--text); font-weight:650; }
  @media (max-width:640px){
    .seam-grid { grid-template-columns:34px minmax(0,1fr); gap:0 8px; }
    .seam-lbl { font-size:8.5px; letter-spacing:.05em; }
    .seam-brk b { font-size:9.5px; }
  }

  /* ── WHAT NEEDS ATTENTION — composed from the .chg-row grammar ───────────── */
  .att { overflow:hidden; }
  .att-row { display:grid; grid-template-columns:76px minmax(0,1fr) auto 26px;
    align-items:center; gap:12px; padding:11px 18px; border-top:1px solid var(--line);
    cursor:pointer; transition:background .14s ease; }
  .att-row:first-child { border-top:0; }
  .att-row:hover { background:color-mix(in srgb,var(--link) 6%,transparent); }
  .att-sym { font-weight:750; font-size:13.5px; letter-spacing:-.01em; }
  .att-what { font-size:13.5px; line-height:1.4; min-width:0; }
  .att-stance { font-size:11px; font-weight:750; letter-spacing:.05em; text-transform:uppercase;
    white-space:nowrap; padding:3px 10px; border-radius:7px;
    border:1px solid color-mix(in srgb,var(--muted) 26%,var(--line)); color:var(--muted); }
  .att-stance.s-watch { color:var(--ink-warn); border-color:color-mix(in srgb,var(--warn) 40%,var(--line));
    background:color-mix(in srgb,var(--warn) 9%,transparent); }
  .att-stance.s-ready { color:var(--ink-link); border-color:color-mix(in srgb,var(--link) 40%,var(--line));
    background:color-mix(in srgb,var(--link) 9%,transparent); }
  .att-chev { color:var(--muted); text-align:right; font-size:14px; line-height:1; }
  @media (max-width:720px){
    .att-row { grid-template-columns:minmax(0,1fr) auto; grid-template-areas:
      "sym stance" "what what"; row-gap:5px; padding:12px 14px; }
    .att-sym { grid-area:sym; } .att-what { grid-area:what; font-size:13px; }
    .att-stance { grid-area:stance; } .att-chev { display:none; }
  }

  /* ══════════════════════════════════════════════════════════════════════════
     THE DENSE TABLE — the hero. Nothing on this page is denser or taller.
     ══════════════════════════════════════════════════════════════════════════ */
  .tbl-top { display:flex; align-items:center; gap:10px; flex-wrap:wrap;
    padding:10px 16px; border-bottom:1px solid var(--line); }
  .tbl-scope { font-size:11.5px; color:var(--muted); font-weight:600; }
  .tbl-scope b { color:var(--text); }
  .srch { appearance:none; -webkit-appearance:none; flex:0 1 230px; min-width:0;
    padding:6px 11px 6px 30px; border-radius:9px; border:1px solid var(--line);
    background:var(--panel2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238b94a8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E") no-repeat 9px 50%;
    background-size:13px; color:var(--text); font:inherit; font-size:12.5px; outline:none; }
  .srch::placeholder { color:var(--muted); }
  .srch:focus { border-color:var(--link); box-shadow:0 0 0 3px color-mix(in srgb,var(--link) 20%,transparent); }
  .tbl-tools { margin-left:auto; display:flex; gap:7px; align-items:center; }
  /* ONE control block that may run to two lines: search + scope + actions above,
     the market-book filter strip below, a SINGLE hairline under both — a filter
     belongs with the thing it filters, never in its own section (§7d). */
  .tbl-bar { border-bottom:1px solid var(--line); }
  .tbl-bar > .tbl-top { border-bottom:0; }

  .hold { width:100%; border-collapse:collapse; font-size:13px; }
  .hold thead th { position:sticky; top:0; z-index:2; text-align:left;
    padding:8px 10px; font-size:9.5px; font-weight:750; letter-spacing:.08em;
    text-transform:uppercase; color:var(--muted); white-space:nowrap;
    background:var(--panel); border-bottom:1px solid var(--line); }
  .hold thead th.srt { cursor:pointer; user-select:none; }
  .hold thead th.srt:hover { color:var(--text); }
  .hold thead th .ar { opacity:0; margin-left:3px; }
  .hold thead th[aria-sort] .ar { opacity:.75; }
  .hold tbody td { padding:0 10px; height:38px; border-bottom:1px solid
    color-mix(in srgb,var(--line) 55%,transparent); vertical-align:middle; }
  .hold tbody tr:last-child td { border-bottom:0; }
  .hold tbody tr { transition:background .12s ease; }
  .hold tbody tr:hover { background:color-mix(in srgb,var(--link) 6%,transparent); }
  .hold .num { text-align:right; }
  .c-sym b { font-weight:750; font-size:13px; letter-spacing:-.01em; }
  .c-sym .co { display:block; font-size:11px; color:var(--muted); line-height:1.25;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:150px; }
  .c-val .w { display:block; font-size:11px; color:var(--muted); line-height:1.25; }
  .dash { color:var(--muted); opacity:.6; }

  /* stage is encoded by WEIGHT, never by hue — survives the zh direction flip and
     never collides with the --up/--down inks (DESIGN_NOTES §1.2) */
  .stg { display:inline-flex; align-items:center; gap:7px; white-space:nowrap; font-size:12.5px; }
  .stg i { flex:none; width:16px; height:7px; border-radius:2px;
    border:1px solid color-mix(in srgb,var(--muted) 55%,transparent); background:transparent; }
  .stg.s-early i { border-style:dashed; }
  .stg.s-confirming i { background:linear-gradient(90deg,var(--muted) 50%,transparent 50%); }
  .stg.s-confirmed i { background:var(--text); border-color:var(--text); }
  .stg.s-aging i { background:color-mix(in srgb,var(--muted) 70%,transparent); }
  /* "running hot" = the mark OVERSHOOTS its own end cap — the shape says extended
     without a word or a colour */
  .stg.s-extended i { position:relative; background:color-mix(in srgb,var(--muted) 70%,transparent); }
  .stg.s-extended i::after { content:""; position:absolute; right:-5px; top:-2px; bottom:-2px; width:2px;
    background:color-mix(in srgb,var(--muted) 80%,transparent); }
  .stg.s-invalid i { position:relative; background:transparent; opacity:.75; }
  .stg.s-invalid i::after { content:""; position:absolute; left:-1px; right:-1px; top:50%;
    height:1px; background:currentColor; color:var(--muted); }
  .stg.s-none { color:var(--muted); }
  .stg.s-none i { border-style:dotted; opacity:.5; }

  /* risk contribution — hairline share bar, honest shared scale, no magnitude lie */
  .rc { display:flex; align-items:center; gap:7px; justify-content:flex-end; }
  .rc .bar { width:34px; height:4px; border-radius:2px; background:var(--panel2);
    border:1px solid color-mix(in srgb,var(--line) 70%,transparent); overflow:hidden; flex:none; }
  .rc .bar span { display:block; height:100%; background:color-mix(in srgb,var(--link) 58%,var(--panel2)); }
  .rc.is-big .bar span { background:color-mix(in srgb,var(--link) 92%,var(--panel2)); }

  .flag { display:inline-block; font-size:11px; font-weight:700; padding:2px 8px; border-radius:7px;
    white-space:nowrap; border:1px solid color-mix(in srgb,var(--muted) 24%,var(--line));
    color:var(--muted); background:var(--panel2); }
  .flag.f-warn { color:var(--ink-warn); border-color:color-mix(in srgb,var(--warn) 40%,var(--line));
    background:color-mix(in srgb,var(--warn) 10%,var(--panel)); }
  .flag.f-info { color:var(--ink-link); border-color:color-mix(in srgb,var(--link) 40%,var(--line));
    background:color-mix(in srgb,var(--link) 10%,var(--panel)); }
  .evt { font-size:12px; color:var(--muted); white-space:nowrap; }
  .evt b { color:var(--text); font-weight:600; }
  .evt .soon { color:var(--ink-warn); font-weight:700; }
  .exp { appearance:none; border:1px solid transparent; background:transparent; color:var(--muted);
    font-size:13px; line-height:1; padding:5px 6px; border-radius:7px; cursor:pointer; }
  .exp:hover { color:var(--text); background:var(--panel2); border-color:var(--line); }
  .exp:focus-visible { outline:2px solid color-mix(in srgb,var(--link) 70%,transparent); outline-offset:1px; }
  .exp .car { display:inline-block; transition:transform .18s ease; }
  tr[aria-expanded="true"] .exp .car { transform:rotate(180deg); }
  @media (prefers-reduced-motion:reduce){ .exp .car { transition:none; } }

  /* the row drawer — where the 390px demotions live, and the per-name detail */
  tr.row-drawer > td { padding:2px 16px 14px; border-bottom:1px solid var(--line);
    background:color-mix(in srgb,var(--panel2) 45%,transparent); }
  .drw { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px 18px;
    font-size:12.5px; }
  .drw .k { display:block; font-size:10px; font-weight:750; letter-spacing:.08em;
    text-transform:uppercase; color:var(--muted); margin-bottom:2px; }
  /* ── the per-name lane rows, emitted by watchlist_risk.js `laneRows`/`chainRows` ──
     These five classes had NO rule anywhere on this page: they belonged to the WRI
     braid hero W2 deleted, and the drawer that still renders them was left showing
     unstyled spans and a bare "?" where the Tier-2 receipt should be. Styled here
     because this is the template whose drawer emits them — W4 inherits a working
     surface rather than a known defect. The state token paints from the HEALTH tokens
     (--warn/--act), never from --up/--down: a lane state is a severity, not a price
     direction, and health tokens deliberately do not swap under 红涨绿跌. */
  .wri-lrow { grid-column:1/-1; display:grid; grid-template-columns:116px 74px minmax(0,1fr);
    gap:10px; align-items:baseline; padding:4px 0; font-size:12px;
    border-top:1px solid color-mix(in srgb,var(--line) 55%,transparent); }
  .wri-lrow .ln { font-weight:650; color:var(--muted); }
  .wri-lrow .st { font-size:9.5px; font-weight:750; letter-spacing:.07em;
    text-transform:uppercase; color:var(--muted); }
  .wri-lrow .st.watch { color:var(--warn); }
  .wri-lrow .st.elev  { color:var(--act); }
  .wri-lrow .st.info  { color:var(--ink-link); }
  .wri-lrow .st.na    { opacity:.62; }
  /* THREE coverage meanings, three marks (W4 m8). `na` is dimmed because it is an
     ABSENCE — we could not read it. `none` and `n/app` are ANSWERS ("we looked, there is
     none" / "this does not apply here"), so they sit at full muted weight: the
     nulls-printed law is exactly the distinction between not measuring and measuring a
     negative, and one dimmed mark for all three erased it. Muted ramp only — a coverage
     state is not a price direction, so the direction tokens (which swap under
     红涨绿跌) have no business here — the same law as the severity tokens above. */
  .wri-lrow .st.none  { color:var(--muted); }
  .wri-lrow .st.n\/app { color:var(--muted); letter-spacing:0; }
  .wri-lrow .rs { color:var(--text); line-height:1.45; }
  /* the Tier-2 receipt mark: a real affordance, not a stray question mark */
  .wri-q { display:inline-grid; place-items:center; width:13px; height:13px; margin-left:5px;
    border-radius:50%; border:1px solid color-mix(in srgb,var(--muted) 45%,transparent);
    font-size:9px; font-weight:700; line-height:1; color:var(--muted); cursor:help; }
  .wri-q:focus-visible { outline:2px solid color-mix(in srgb,var(--link) 70%,transparent);
    outline-offset:1px; }
  @media (max-width:720px){
    .wri-lrow { grid-template-columns:1fr auto; gap:3px 8px; }
    .wri-lrow .rs { grid-column:1/-1; }
  }

  /* ── W4: the Intelligence Drawer's Tier 1 ────────────────────────────────
     Tier 1 is the GLANCE read and it gets exactly two things: one plain sentence and
     one stance word. The stance chip is `.att-stance` — the same grammar the attention
     stack uses, because it is the same vocabulary (§7(b): Watch · Get ready · No
     action), and a second chip style for one vocabulary is how two surfaces start
     disagreeing about what a word looks like. `.drw-full` exists because the watchlist
     drawer's container IS the `.drw` grid, so a block that must span it says so with a
     class rather than an inline style. */
  .drw-full { grid-column:1/-1; }
  .drw-t1 { grid-column:1/-1; display:flex; gap:12px; align-items:flex-start;
    justify-content:space-between; padding-bottom:2px; }
  .drw-lead { font-size:14px; font-weight:650; color:var(--text); line-height:1.4;
    letter-spacing:-.01em; }
  .drw-t1 .att-stance { flex:none; }
  /* the honest "nothing" — muted, and never dressed up as a finding */
  .drw-quiet { grid-column:1/-1; font-size:12px; color:var(--muted); line-height:1.5;
    padding-bottom:2px; }
  /* a lock shell inside a drawer is a full-width block, never a column */
  .drw .lockshell, tr.row-drawer .lockshell { grid-column:1/-1; margin-top:4px; }
  /* The regime rail's appended cascade sentence. Emitted by `watchlist_risk.js` since
     #3527 and styled NOWHERE — same defect class as the five `.wri-*` classes W3 found,
     and the same remedy: it lands in the template that renders it. Muted, because the
     rail's base read is the sentence that must survive the glance and this rides after
     it (display-only WATCH context, never a signal). */
  .wri-rail-chain { color:var(--muted); }
  .wri-rail-chain a { font-weight:650; white-space:nowrap; }
  @media (max-width:720px){
    .drw-t1 { flex-direction:column; gap:7px; align-items:flex-start; }
  }

  .drw-act { grid-column:1/-1; display:flex; gap:12px; flex-wrap:wrap; align-items:center;
    margin-top:2px; padding-top:9px; border-top:1px solid var(--line); font-size:12px; }
  .drw-act a { font-weight:650; }
  .drw-rm { background:transparent; border:0; color:var(--muted); cursor:pointer;
    font:inherit; font-size:12px; font-weight:650; padding:0; }
  /* --act, not --down. "Remove", "error" and "failed" are HEALTH meanings, not price
     directions; theme.css deliberately does not swap the health tokens, so an error
     stays red in Chinese. Painting them from --down made a failure message turn GREEN
     under 红涨绿跌 — the direction swap doing exactly its job to a caller that had no
     direction to express. */
  .drw-rm:hover { color:var(--act); }
  .drw-honest { grid-column:1/-1; font-size:11.5px; color:var(--muted); line-height:1.5; }

  /* Δ-since-visit — a dot + two plain words, no percentage theatre */
  .delta { display:inline-flex; align-items:center; gap:6px; font-size:12px; white-space:nowrap; }
  .delta i { width:6px; height:6px; border-radius:50%; flex:none; background:var(--muted); opacity:.45; }
  .delta.d-new i { background:var(--ink-link); opacity:1; }
  .delta.d-up i { background:var(--ink-up); opacity:1; }
  .delta.d-down i { background:var(--ink-down); opacity:1; }

  /* the row that is not in the model stays VISIBLE and honest, never hidden */
  .hold tr.is-uncovered .c-sym b { opacity:.92; }
  .hold tr.is-uncovered > td { background:repeating-linear-gradient(-45deg,
    color-mix(in srgb,var(--muted) 4%,transparent) 0 3px, transparent 3px 7px); }

  .tbl-foot { padding:10px 16px; border-top:1px solid var(--line); font-size:11.5px;
    color:var(--muted); display:flex; gap:10px; flex-wrap:wrap; align-items:baseline; }
  .tbl-foot .grow { margin-left:auto; }
  .tbl-empty { padding:22px 16px; font-size:13px; color:var(--muted); line-height:1.55; }

  /* ── 390px reduction: deliberate demotions, no horizontal page scroll (§7c) ──
     Day + Since entry + Risk share + Sector move into the row drawer. */
  @media (max-width:720px){
    .hold thead { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0);
      white-space:nowrap; }
    .hold, .hold tbody, .hold tr, .hold td { display:block; }
    .hold tbody tr { display:grid; grid-template-columns:minmax(0,1fr) auto 30px;
      grid-template-areas:"sym val exp" "sig att exp" "meta meta exp";
      gap:3px 10px; padding:11px 14px; border-bottom:1px solid var(--line); align-items:center; }
    .hold tbody td { padding:0; height:auto; border:0; }
    .hold .c-sym { grid-area:sym; }
    .hold .c-val { grid-area:val; text-align:right; }
    .hold .c-sig { grid-area:sig; }
    .hold .c-att { grid-area:att; text-align:right; }
    .hold .c-evt { grid-area:meta; }
    .hold .c-exp { grid-area:exp; text-align:right; }
    .hold .c-day, .hold .c-since, .hold .c-rc, .hold .c-sect { display:none; }
    .hold .c-sym .co { max-width:none; }
    /* watchlist keeps a fourth slot: what changed since the last visit */
    #tbl_wl tbody tr { grid-template-areas:"sym val exp" "sig att exp" "meta chg exp"; }
    #tbl_wl .c-chg { grid-area:chg; text-align:right; }
    .hold tbody tr.row-drawer { display:block; padding:0; }
    .hold tbody tr.row-drawer > td { display:block; padding:2px 14px 14px; }
    .m-only { display:inline; }
    .tbl-top { padding:10px 14px; }
    .srch { flex:1 1 100%; }
    .entry .gbtn { width:100%; }
  }
  .m-only { display:none; }

  /* ══════════════════════════════════════════════════════════════════════════
     RISK CENTER — tabs, one dominant idea each. Deliberately SHORTER than the
     table: diagnostics explain the book, they never replace it.
     ══════════════════════════════════════════════════════════════════════════ */
  .rc-tabs { display:flex; gap:2px; overflow-x:auto; padding:4px 6px; border-bottom:1px solid var(--line);
    scrollbar-width:none; }
  .rc-tabs::-webkit-scrollbar { display:none; }
  .rc-tab { appearance:none; border:0; background:transparent; color:var(--muted);
    font-family:inherit; font-size:12.5px; font-weight:650; white-space:nowrap;
    padding:8px 13px; border-radius:8px; cursor:pointer; position:relative; }
  .rc-tab:hover { color:var(--text); background:color-mix(in srgb,var(--link) 7%,transparent); }
  .rc-tab[aria-selected="true"] { color:var(--text); }
  .rc-tab[aria-selected="true"]::after { content:""; position:absolute; left:13px; right:13px; bottom:-5px;
    height:2px; border-radius:2px; background:var(--ink-link); }
  .rc-tab:focus-visible { outline:2px solid color-mix(in srgb,var(--link) 70%,transparent); outline-offset:1px; }
  .rc-body { padding:17px 20px 18px; }
  .rc-claim { margin:0; font-size:17px; font-weight:600; line-height:1.35; letter-spacing:-.012em;
    max-width:42ch; text-wrap:balance; }
  .rc-claim .fig { font-weight:750; }
  .rc-note { margin:8px 0 0; font-size:12.5px; color:var(--muted); max-width:52ch; }
  .conc { margin:15px 0 0; display:grid; gap:6px; max-width:430px; }
  .conc-row { display:grid; grid-template-columns:66px minmax(0,1fr) 42px; align-items:center; gap:10px;
    font-size:12.5px; }
  .conc-row .track { height:6px; border-radius:3px; background:var(--panel2);
    border:1px solid color-mix(in srgb,var(--line) 70%,transparent); overflow:hidden; }
  .conc-row .track span { display:block; height:100%; background:color-mix(in srgb,var(--link) 62%,var(--panel2)); }
  .conc-row.is-ballast .track span { background:color-mix(in srgb,var(--muted) 34%,var(--panel2)); }
  .conc-row .who { font-weight:650; }
  .conc-row .pct { text-align:right; color:var(--muted); }
  /* Some ladders are labelled with WORDS rather than tickers — "Growth / Tech",
     "Falling days". Those wrap at the ticker width and break the ladder's rhythm, so
     they get a wider label column. The modifier is named for the label, not for the
     tab, because two different tabs need it for the same reason. */
  .conc.is-worded .conc-row { grid-template-columns:104px minmax(0,1fr) 42px; }
  /* Tier-2 receipt affordance: the LENS popover is wired by theme.js off
     [data-tip-en]; this is only the hint that the sentence has one. */
  .rc-tip { border-bottom:1px dotted color-mix(in srgb,var(--muted) 55%,transparent); }
  /* a tab whose book is too thin for its read says so in plain words — never an
     empty panel, and never another tab's answer standing in for a missing one */
  .rc-soon { font-size:12.5px; color:var(--muted); line-height:1.6; max-width:56ch; }
  .rc-soon b { color:var(--text); font-weight:650; display:block; margin-bottom:3px; font-size:13px; }

  /* ── W3 tab row grammars ───────────────────────────────────────────────────
     Three variants of the ONE ladder the Concentration tab already established:
     same track, same shared-scale law, same read-only nature. They differ only in
     what the left column names (a pair, a date, two columns) — never in geometry.
     Nothing here is the Board's count ladder: no cell is a category, no cell is a
     filter control, and every track is a continuous share rather than a count. */
  .pair-row { display:grid; grid-template-columns:112px minmax(0,1fr) 42px; align-items:center;
    gap:10px; font-size:12.5px; }
  .pair-row .who { font-weight:650; }
  .pair-row .pct { text-align:right; color:var(--muted); }
  .pair-row .track { height:6px; border-radius:3px; background:var(--panel2);
    border:1px solid color-mix(in srgb,var(--line) 70%,transparent); overflow:hidden; }
  /* below the 0.70 line the fill is quiet; at or above it, it is the full accent —
     a threshold read by WEIGHT, never by a second hue */
  .pair-row .track span { display:block; height:100%;
    background:color-mix(in srgb,var(--link) 34%,var(--panel2)); }
  .pair-row.is-twin .track span { background:color-mix(in srgb,var(--link) 72%,var(--panel2)); }
  .pair-row.is-twin .who, .pair-row.is-twin .pct { color:var(--text); }

  .evt-row { display:grid; grid-template-columns:66px minmax(0,1fr) 46px; align-items:baseline;
    gap:10px; font-size:12.5px; }
  .evt-row .who { font-weight:650; }
  .evt-row .when { color:var(--muted); min-width:0; }
  .evt-row .when .sub { opacity:.72; }
  .evt-row .pct { text-align:right; color:var(--muted); }
  .evt-row.is-near .who, .evt-row.is-near .pct { color:var(--text); }

  .wk .wk-hd { display:grid; grid-template-columns:66px minmax(0,1fr) 22px; gap:10px;
    font-size:9.5px; font-weight:750; letter-spacing:.08em; text-transform:uppercase;
    color:var(--muted); margin-bottom:1px; }
  .wk-row { display:grid; grid-template-columns:66px minmax(0,1fr) 22px; align-items:center;
    gap:10px; font-size:12.5px; }
  .wk-row .who { font-weight:650; }
  .wk-row .two, .wk .wk-hd .two { display:grid; grid-template-columns:1fr 1fr; gap:9px;
    align-items:center; min-width:0; }
  .wk-row .track { height:6px; border-radius:3px; background:var(--panel2);
    border:1px solid color-mix(in srgb,var(--line) 70%,transparent); overflow:hidden; }
  .wk-row .track span { display:block; height:100%;
    background:color-mix(in srgb,var(--link) 62%,var(--panel2)); }
  .wk-row.is-ballast .track span { background:color-mix(in srgb,var(--muted) 34%,var(--panel2)); }
  /* a direction glyph, not a figure: no tabular-mono, no --up/--down ink (it marks
     risk-per-dollar, which has no up/down meaning and must not flip under zh) */
  .mark { color:var(--muted); font-weight:650; }
  .wk-row .pct.mark { text-align:right; }

  details.lab { border-top:1px solid var(--line); }
  details.lab summary { list-style:none; cursor:pointer; padding:13px 20px; display:flex;
    align-items:center; gap:10px; font-size:13px; font-weight:650; }
  details.lab summary::-webkit-details-marker { display:none; }
  details.lab summary .car { color:var(--muted); font-size:11px; transition:transform .18s ease; }
  details.lab[open] summary .car { transform:rotate(90deg); }
  details.lab summary .q { font-weight:450; color:var(--muted); font-size:12.5px; }
  details.lab .labbody { padding:0 20px 18px; font-size:12.5px; color:var(--muted); max-width:60ch; }
  @media (prefers-reduced-motion:reduce){ details.lab summary .car { transition:none; } }

  /* ── Scenario Lab body (W3) ────────────────────────────────────────────────
     The pre-trade check, rehomed. Deliberately the plainest surface in the panel:
     it describes a book that does not exist, so it gets no accent fill, no bars
     and no signature — two fields, a button, and sentences. */
  .lab-say { margin:0 0 11px; }
  .lab-form { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
  .lab-in { font-family:inherit; font-size:12.5px; color:var(--text);
    background:var(--panel2); border:1px solid var(--line); border-radius:9px;
    padding:7px 10px; min-width:0; }
  .lab-in:focus-visible { outline:2px solid color-mix(in srgb,var(--link) 70%,transparent);
    outline-offset:1px; }
  .lab-t { width:108px; text-transform:uppercase; }
  .lab-d { display:inline-flex; align-items:center; gap:5px; }
  .lab-cur { font-family:var(--font-mono); font-size:12px; color:var(--muted); }
  .lab-amt { width:104px; font-family:var(--font-mono); font-variant-numeric:tabular-nums; }
  .lab-out { margin-top:12px; }
  .lab-out:empty { margin-top:0; }
  .lab-line { margin:0 0 6px; color:var(--text); line-height:1.5; }
  .lab-line b { font-weight:650; }
  .lab-line .fig { font-family:var(--font-mono); font-variant-numeric:tabular-nums;
    font-weight:700; }
  .lab-lens { color:var(--muted); }
  .lab-note { margin:13px 0 0; color:var(--muted); line-height:1.55; }
  @media (max-width:520px){ .lab-form .gbtn { width:100%; } }

  /* ══════════════════════════════════════════════════════════════════════════
     MARKET BOOKS — chips are VIEWS of the ONE portfolio, never new books.
     In Portfolio mode the strip is docked in the holdings toolbar (§7d).
     ══════════════════════════════════════════════════════════════════════════ */
  .books { display:flex; flex-wrap:wrap; gap:7px; padding:14px 16px; }
  .bookchip { display:inline-flex; align-items:center; gap:8px; padding:6px 13px; border-radius:999px;
    border:1px solid var(--gbtn-brd); background:var(--gbtn-bg); color:var(--text);
    font-family:inherit; font-size:12.5px; font-weight:600; cursor:pointer;
    -webkit-backdrop-filter:blur(12px) saturate(140%); backdrop-filter:blur(12px) saturate(140%);
    transition:border-color .16s ease, background .16s ease; }
  .bookchip:hover { border-color:var(--gbtn-brd-hover); background:var(--gbtn-bg-hover); }
  .bookchip:focus-visible { outline:2px solid var(--link); outline-offset:2px; }
  .bookchip .n { font-family:var(--font-mono); font-size:11px; font-variant-numeric:tabular-nums;
    color:var(--muted); }
  .bookchip[aria-pressed="true"] { border-color:color-mix(in srgb,var(--link) 55%,var(--gbtn-brd));
    background:color-mix(in srgb,var(--link) 12%,var(--gbtn-bg)); }
  .bookchip[aria-pressed="true"] .n { color:var(--ink-link); }
  .bookchip:disabled { opacity:.45; cursor:default; }

  .tbl-books { display:flex; align-items:center; flex-wrap:wrap; gap:8px 11px; padding:0 16px 11px; }
  .tbl-books:empty { display:none; }
  .books-lbl { flex:none; font-size:9.5px; font-weight:750; letter-spacing:.08em;
    text-transform:uppercase; color:var(--muted); }
  .books-strip { display:flex; flex-wrap:wrap; gap:7px; min-width:0; }
  .books-strip .bookchip { padding:5px 12px; font-size:12px; }
  .books-law { margin:0; margin-left:auto; min-width:0; font-size:11.5px; color:var(--muted); }
  @media (max-width:1080px){ .books-law { margin-left:0; flex:1 1 100%; } }
  @media (max-width:720px){
    .tbl-books { padding:0 14px 11px; gap:9px; }
    /* the chips scroll INSIDE their own container — the page itself never scrolls
       sideways. Same technique as .rc-tabs, same result. */
    .books-strip { flex:1 1 0; flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; }
    .books-strip::-webkit-scrollbar { display:none; }
    .books-strip .bookchip { flex:none; }
  }

  /* ══════════════════════════════════════════════════════════════════════════
     ANONYMOUS ENTRY + tier locks (.mx-tier-* come from tier_preview.css)
     ══════════════════════════════════════════════════════════════════════════ */
  .entry { padding:26px 24px 22px; }
  .entry-say { margin:0; font-size:30px; line-height:1.2; font-weight:600; letter-spacing:-.028em;
    max-width:26ch; text-wrap:balance; }
  .entry-sub { margin:11px 0 0; font-size:14.5px; color:var(--muted); max-width:50ch; line-height:1.5; }
  .entry-box { margin:19px 0 0; display:grid; gap:11px; }
  .entry-in { width:100%; min-height:88px; resize:vertical; padding:13px 15px; border-radius:12px;
    border:1px solid var(--line); background:var(--panel2); color:var(--text);
    font-family:var(--font-mono); font-size:14px; line-height:1.6; outline:none; }
  .entry-in::placeholder { color:var(--muted); opacity:.75; }
  .entry-in:focus { border-color:var(--link); box-shadow:0 0 0 3px color-mix(in srgb,var(--link) 18%,transparent); }
  .entry-ctl { display:flex; flex-wrap:wrap; gap:12px; align-items:center; }
  .wmode { display:inline-flex; padding:3px; gap:2px; border-radius:10px; border:1px solid var(--gbtn-brd);
    background:var(--gbtn-bg); }
  .wmode button { appearance:none; border:0; background:transparent; color:var(--muted);
    font-family:inherit; font-size:12px; font-weight:650; padding:5px 11px; border-radius:7px; cursor:pointer; }
  .wmode button[aria-pressed="true"] { background:var(--panel); color:var(--text); box-shadow:var(--card-shadow); }
  .wmode button:focus-visible { outline:2px solid var(--link); outline-offset:2px; }
  .wmode-lbl { font-size:11.5px; color:var(--muted); font-weight:600; }
  .gbtn-cta { border-color:color-mix(in srgb,var(--link) 45%,var(--gbtn-brd));
    background:linear-gradient(180deg,color-mix(in srgb,var(--link) 16%,var(--gbtn-bg)),var(--gbtn-bg)); }
  .entry-why { margin:17px 0 0; padding-top:15px; border-top:1px solid var(--line);
    display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
  .entry-why div { font-size:12.5px; color:var(--muted); line-height:1.5; }
  .entry-why b { display:block; color:var(--text); font-size:13px; font-weight:650; margin-bottom:2px; }
  .empty-why { margin:15px 0 0; font-size:12px; color:var(--muted); }
  .entry-err { margin:9px 0 0; font-size:12.5px; color:var(--ink-warn); }
  .entry-err:empty { display:none; }
  @media (max-width:640px){
    .entry { padding:20px 16px; }
    .entry-say { font-size:23px; max-width:none; }
    .entry-sub { font-size:13.5px; }
    .entry-why { grid-template-columns:1fr; gap:11px; }
    .entry-ctl { gap:9px; }
    .wmode { width:100%; } .wmode button { flex:1; }
  }

  /* locked CELL: a lock glyph where the board-tier signal would sit. Anonymous
     never receives the stage read — not blurred, simply absent. */
  .lockcell { display:inline-flex; align-items:center; gap:6px; font-size:12px; color:var(--muted); }
  .lockcell .lk { width:16px; height:7px; border-radius:2px; flex:none;
    border:1px solid color-mix(in srgb,#7c5cff 45%,var(--line));
    background:repeating-linear-gradient(-45deg,color-mix(in srgb,#7c5cff 22%,transparent) 0 2px,transparent 2px 4px); }
  /* a whole locked read (the Risk Center rails and tabs, anonymously) */
  .lockshell { display:flex; gap:11px; align-items:flex-start; padding:14px 16px; border-radius:12px;
    border:1px dashed color-mix(in srgb,#7c5cff 34%,var(--line));
    background:color-mix(in srgb,#7c5cff 5%,transparent); font-size:12.5px; color:var(--muted);
    line-height:1.5; }
  .lockshell .lk { flex:none; width:22px; height:22px; border-radius:7px; display:grid; place-items:center;
    font-size:11px; color:#7c5cff;
    border:1px solid color-mix(in srgb,#7c5cff 28%,var(--line));
    background:color-mix(in srgb,#7c5cff 13%,var(--panel)); }
  .lockshell b { display:block; color:var(--text); font-weight:650; font-size:13px; margin-bottom:2px; }
  .lockshell .cta { background:transparent; border:0; padding:0; margin-top:5px; cursor:pointer;
    font:inherit; font-size:12px; font-weight:700; color:var(--ink-link); display:block; }

  /* ── watchlist head ──────────────────────────────────────────────────────── */
  .wl-head { display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding:13px 16px;
    border-bottom:1px solid var(--line); }
  .listpick { display:inline-flex; align-items:center; gap:9px; padding:7px 13px; border-radius:10px;
    border:1px solid var(--gbtn-brd); background:var(--gbtn-bg); color:var(--text);
    font-family:inherit; font-size:14px; font-weight:700; cursor:pointer; letter-spacing:-.01em; }
  .listpick .car { color:var(--muted); font-size:10px; }
  .listpick:focus-visible { outline:2px solid var(--link); outline-offset:2px; }
  .wl-facts { display:flex; flex-wrap:wrap; gap:4px 12px; font-size:12px; color:var(--muted);
    align-items:baseline; }
  .wl-facts b { color:var(--text); font-weight:650; }
  .wl-facts .sep { opacity:.4; }
  /* the add-a-name field + its suggestion list (the workspace's only write path
     into a watchlist; the pinned mockup showed no add control because it is a
     static artifact — recorded as delta D3) */
  .wl-add { position:relative; flex:1 1 220px; min-width:180px; max-width:340px; }
  .wl-add .srch { width:100%; flex:none; }
  #wl_sugg { position:absolute; top:104%; left:0; right:0; background:var(--panel);
    border:1px solid var(--line); border-radius:10px; z-index:50; max-height:330px;
    overflow:auto; display:none; box-shadow:var(--popover-shadow); }
  #wl_sugg div { padding:8px 13px; cursor:pointer; display:flex; gap:10px; align-items:center;
    font-size:13px; }
  #wl_sugg div:hover, #wl_sugg div.sel { background:var(--panel2); }
  #wl_sugg b { min-width:58px; flex:none; font-family:var(--font-mono); font-size:12px; }
  #wl_sugg small { color:var(--muted); flex:1 1 auto; min-width:0;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  /* the list menu (W1a `lists` seam) */
  .listmenu { position:absolute; z-index:60; min-width:210px; padding:5px;
    background:var(--panel); border:1px solid var(--line); border-radius:11px;
    box-shadow:var(--popover-shadow); display:none; }
  .listmenu.open { display:block; }
  .listmenu button { display:flex; width:100%; align-items:center; gap:8px; appearance:none;
    border:0; background:transparent; color:var(--text); font:inherit; font-size:13px;
    text-align:left; padding:7px 10px; border-radius:8px; cursor:pointer; }
  .listmenu button:hover { background:var(--panel2); }
  .listmenu button[aria-current="true"] { font-weight:700; }
  .listmenu .n { margin-left:auto; font-family:var(--font-mono); font-size:11px; color:var(--muted); }
  .listmenu hr { border:0; border-top:1px solid var(--line); margin:5px 2px; }

  /* ── modal + toast (carried over; unchanged grammar) ─────────────────────── */
  html.mx5-dlg-lock { overflow:hidden; }
  html.mx5-dlg-lock body { overflow:hidden; position:fixed; width:100%; }
  .mx5-dlg { display:none; position:fixed; inset:0; z-index:200; align-items:center; justify-content:center; }
  .mx5-dlg.open { display:flex; }
  .mx5-dlg-backdrop { position:absolute; inset:0; background:rgba(3,6,10,.58);
    backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
  .mx5-dlg-panel { position:relative; z-index:1; max-width:640px; width:calc(100% - 48px);
    max-height:82vh; background:var(--panel); border:1px solid var(--line); border-radius:18px;
    box-shadow:var(--popover-shadow); overflow-y:auto; display:flex; flex-direction:column; }
  .mx5-dlg-header { display:flex; align-items:center; justify-content:space-between;
    padding:18px 22px 14px; position:sticky; top:0; z-index:2; background:var(--panel);
    border-bottom:1px solid var(--line); }
  .mx5-dlg-title { font-size:12px; font-weight:750; letter-spacing:.08em; text-transform:uppercase;
    color:var(--muted); }
  .mx5-dlg-close { display:flex; align-items:center; justify-content:center; width:32px; height:32px;
    border-radius:50%; background:var(--panel2); border:1px solid var(--line); cursor:pointer;
    color:var(--muted); font-size:16px; line-height:1; font-family:inherit; flex-shrink:0; }
  .mx5-dlg-close:hover { color:var(--text); }
  .mx5-dlg-close:focus-visible { outline:2px solid var(--link); outline-offset:2px; }
  .mx5-dlg-body { padding:20px 22px 24px; flex:1; overflow-y:auto; }
  .pfm-row { margin-bottom:13px; }
  .pfm-row label { display:block; font-size:12px; font-weight:650; color:var(--muted); margin-bottom:4px; }
  .wl-in { width:100%; padding:8px 12px; border-radius:9px; border:1px solid var(--line);
    background:var(--panel2); color:var(--text); font:inherit; font-size:14px; outline:none; }
  .wl-in:focus { border-color:var(--link); }
  #pfm_hint { font-size:11.5px; color:var(--muted); margin-top:3px; display:none; }
  #pfm_sugg { position:absolute; top:104%; left:0; right:0; background:var(--panel);
    border:1px solid var(--line); border-radius:10px; z-index:50; max-height:220px;
    overflow:auto; display:none; box-shadow:var(--popover-shadow); }
  #pfm_sugg div { padding:8px 13px; cursor:pointer; display:flex; gap:10px; align-items:center; }
  #pfm_sugg div:hover, #pfm_sugg div.sel { background:var(--panel2); }
  #pfm_sugg b { min-width:58px; flex:none; }
  #pfm_sugg small { color:var(--muted); flex:1; min-width:0;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .pfm-ticker-wrap { position:relative; }
  #pfm_err { display:none; color:var(--act); font-size:12.5px; margin-top:8px; }
  @media (max-width:700px){
    .mx5-dlg { align-items:flex-end; }
    .mx5-dlg-panel { width:calc(100% - 24px); max-width:none; max-height:85vh;
      border-radius:18px 18px 0 0; margin:0 12px; }
    .mx5-dlg-close { width:44px; height:44px; font-size:20px; }
  }
  .wl-toast { position:fixed; left:50%; bottom:26px; transform:translateX(-50%) translateY(20px);
    background:var(--panel); color:var(--text); border:1px solid var(--line);
    border-radius:10px; padding:10px 16px; font-size:13px; font-weight:600;
    box-shadow:var(--popover-shadow); opacity:0; pointer-events:none; transition:.25s; z-index:90; }
  .wl-toast.show { opacity:1; transform:translateX(-50%) translateY(0); }
  .wl-toast.bad { border-color:var(--act); color:var(--act); }
  @media (prefers-reduced-motion:reduce){ .wl-toast { transition:none; } }
  .wl-banner { display:none; margin:0 0 16px; padding:10px 14px; border-radius:9px; font-size:13px;
    background:color-mix(in srgb,var(--warn) 14%,var(--panel));
    border:1px solid color-mix(in srgb,var(--warn) 35%,transparent); color:var(--text); }

  #fx_panel { display:none !important; }

  /* ── state gating — one attribute drives which sections exist ──────────────
     Scoped to `main.ws >` deliberately: the mode also lives on <html>, so a bare
     `[data-ws-mode]{display:none}` matches the ROOT element and blanks the entire
     page — which is exactly what it did on first paint. */
  main.ws > [data-ws-mode] { display:none; }
  html[data-ws-mode="portfolio"]  main.ws > [data-ws-mode="portfolio"],
  html[data-ws-mode="watchlists"] main.ws > [data-ws-mode="watchlists"] { display:block; }
  /* Portfolio mode, anonymous-with-nothing-entered: only the entry panel exists. */
  html[data-ws-state="anon-empty"] #ws_sec_bookread,
  html[data-ws-state="anon-empty"] #ws_sec_att,
  html[data-ws-state="anon-empty"] #ws_sec_hold,
  html[data-ws-state="anon-empty"] #ws_sec_rc,
  html[data-ws-state="anon-empty"] #ws_gate_signal { display:none; }
  /* Anonymous with a parsed book: entry collapses to a re-edit affordance and the
     real structure analysis renders (packet amendment A9). */
  html[data-ws-state="anon-analyzed"] #ws_sec_entry .entry-why,
  html[data-ws-state="anon-analyzed"] #ws_sec_entry .empty-why,
  html[data-ws-state="anon-analyzed"] #ws_sec_entry .entry-sub,
  html[data-ws-state="anon-analyzed"] #ws_sec_starters { display:none; }
  html[data-ws-state="anon-analyzed"] #ws_sec_entry .entry-say { font-size:17px; max-width:none; }
  html[data-ws-state="anon-analyzed"] #ws_sec_entry { margin-bottom:20px; }
  html[data-ws-state="signed"] #ws_sec_entry,
  html[data-ws-state="signed"] #ws_sec_starters,
  html[data-ws-state="signed"] #ws_gate_signal { display:none; }
  html[data-ws-state="anon-empty"] #ws_sec_starters { display:block; }
  html:not([data-ws-state="anon-empty"]) #ws_sec_starters { display:none; }
