
  /* action board */
  .actiongrid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; align-items: start; }
  @media (max-width: 1100px) { .actiongrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  @media (max-width: 900px) { .actiongrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 560px) { .actiongrid { grid-template-columns: minmax(0, 1fr); } }
  /* V2 action board — lane column card, restyled to the china anv2 lane idiom
     (operator request 2026-07-11): panel card, 14px radius, 3px accent bar inside
     the header, colored uppercase lane titles, chips-below-name rows.
     Class names unchanged — fold JS (.actcol/.actbody/.act-fold) and the View-all
     modal (.acth-name/.acth-sub) query them. */
  .actcol { background: var(--panel); border: 1px solid var(--line); min-width: 0;
            border-radius: 14px; padding: 0; overflow: hidden;
            display: flex; flex-direction: column; --act-accent: var(--muted); }
  /* --act-accent stays fill-grade for the lane bar; --act-accent-ink is the
     text-grade twin for .acth-name (violet measured 4.19:1 dark / 3.89 light). */
  .act-buy  { --act-accent: var(--up); --act-accent-ink: var(--ink-up, var(--up)); }
  .act-soon { --act-accent: var(--info); --act-accent-ink: var(--ink-info, var(--info)); }
  .act-run  { --act-accent: #8b5cf6; --act-accent-ink: color-mix(in srgb, #8b5cf6 80%, var(--text)); }   /* neutral violet — NOT green/buy */
  .act-trim { --act-accent: var(--warn); --act-accent-ink: var(--ink-warn, var(--warn)); }
  .act-hold { --act-accent: var(--muted); --act-accent-ink: var(--muted); }
  html[data-theme="light"] .act-run { --act-accent-ink: color-mix(in srgb, #8b5cf6 72%, var(--text)); }
  /* ── Monoline marks (doctrine §5.8 — emoji are not UI icons) ──────────────
     Lane heads, row marks, the legend and the hover-card mark all draw from
     templates/_icons.html.j2 (24×24, stroke=currentColor), so each mark
     inherits its context's ink: the lane icons ride
     --act-accent-ink, which is what carries forward the per-lane colour
     identity the coloured dots used to supply — and the glyph now says what
     the lane DOES, which a coloured dot never did.
     The bottoming-watch strip (_us_bottoming_watch.html.j2, the board's own
     watch surface) reuses .acth-icon / .ai-bdg for its two marks instead of
     shipping a third icon rule, so it is sized from here.
     NO bare `.ic-svg {}` rule here on purpose: sector_central.html.j2 scopes
     its own copy under #si-confluence, and a global rule shipped from a panel
     would fight its host. Explicit selectors only, one size per context.
     .row-pop-mark is deliberately NOT scoped to #action-board — theme.js
     clones the hover card onto document.body, so an id-scoped rule would
     style the hidden source and miss the card the reader actually sees. */
  .ai-bdg .ic-svg, .acth-icon .ic-svg, .row-pop-mark .ic-svg,
  .ab-shock-ic .ic-svg, #action-board .help .tip .ic-svg {
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round; }
  .ai-bdg .ic-svg { width: 13px; height: 13px; display: block; }
  .acth-icon .ic-svg { width: 14px; height: 14px; display: block; }
  .row-pop-mark .ic-svg { width: 17px; height: 17px; display: block; }
  /* inline runs — a mark inside a sentence keeps the text baseline, never block */
  .ab-shock-ic { color: var(--ink-warn, var(--warn)); }
  .ab-shock-ic .ic-svg { width: 14px; height: 14px; display: inline-block; vertical-align: -.17em; }
  #action-board .help .tip .ic-svg { width: 12px; height: 12px; display: inline-block; vertical-align: -.14em; }
  /* Lane header — accent top bar via ::before (anv2-lane-hd idiom) */
  .acth { padding: 10px 13px 8px; border-bottom: 1px solid var(--line); position: relative; }
  .acth::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
                  border-radius: 14px 14px 0 0; background: var(--act-accent); }
  .acth-title-row { display: flex; align-items: center; gap: 5px; }
  .acth-icon { display: flex; line-height: 1; flex: none; color: var(--act-accent-ink, var(--act-accent)); }
  .acth-name { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
               color: var(--act-accent-ink, var(--act-accent)); flex: 0 1 auto; min-width: 0;
               white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .acth-count { flex: none; font-size: 11px; font-weight: 400; color: var(--muted); }
  .acth-count::before { content: "("; } .acth-count::after { content: ")"; }
  .acth-sub { font-size: 10.5px; color: var(--muted); line-height: 1.4; margin-top: 3px; }
  /* Lane body list */
  .actbody { padding: 6px 0; flex: 1; }
  /* V2 row — anv2-row anatomy: name row on top, chips row below, stat line last */
  .actitem { display: block; padding: 7px 13px;
             border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
             font-size: 13px; min-width: 0; overflow: hidden;
             text-decoration: none; color: inherit; cursor: pointer;
             transition: background 0.1s; position: relative; }
  .actitem:last-child { border-bottom: none; }
  /* `outline:none` here is (0,2,0) and theme.css's focus ring is a deliberate
     low-specificity :where() at (0,1,0) — so this line silently removed the ring
     from all 45 rows on us_stocks while the estate believed it was compliant
     (design system §14: a focus-visible ring on EVERY interactive element).
     Hover keeps its wash; the ring is restored for keyboard only. */
  .actitem:hover, .actitem:focus { background: color-mix(in srgb, var(--panel2) 55%, transparent); }
  .actitem:focus:not(:focus-visible) { outline: none; }
  .actitem:focus-visible { outline: 2px solid color-mix(in srgb, var(--link) 78%, transparent); outline-offset: -2px; }
  .actitem.hovered { background: color-mix(in srgb, var(--panel2) 80%, transparent); }
  .act-row-top { display: flex; align-items: center; gap: 6px; min-width: 0; }
  /* Row kind mark. --muted, not text-at-85%: it is a type label (fund vs basket),
     never a signal, so it must stay subordinate to the name in BOTH themes —
     near-black at .85 on white is a heavier mark than the same rule on dark. */
  .ai-bdg { display: flex; flex: none; color: var(--muted); cursor: default; }
  .act-row-name { flex: 1; min-width: 0; font-size: 12.5px; font-weight: 600; color: var(--text);
                  line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* theme composite score — anv2-score idiom (big number, right of the name) */
  .act-row-score { flex: none; font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums;
                   white-space: nowrap; }
  .act-score-hi  { color: var(--ink-up, var(--up)); }
  .act-score-mid { color: var(--ink-warn, var(--warn)); }
  .act-score-lo  { color: var(--ink-down, var(--down)); }
  /* V2 stat line — last line of the row; muted label, china-anv2-style colored value
     (var(--up)/var(--down) so the zh red/green flip rides along); hidden on mobile */
  .act-row-stat { display: block; font-size: 10.5px; color: var(--muted); line-height: 1.35; margin-top: 3px;
                  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .act-row-stat .up { color: var(--ink-up, var(--up)); font-weight: 600; }
  .act-row-stat .dn { color: var(--ink-down, var(--down)); font-weight: 600; }
  @media (max-width: 560px) { .act-row-stat { display: none; } }
  .act-row-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; margin-top: 4px; }
  /* V2 action chip — anv2-chip idiom (uppercase 10px, 4px radius) */
  .ab-chip { font-size: 10px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
             padding: 2px 6px; border-radius: 4px; line-height: 15px; white-space: nowrap; flex: none; }
  .ab-chip--warn { background: color-mix(in srgb, var(--warn) 14%, transparent);
                   color: var(--ink-warn, var(--warn)); border: 1px solid color-mix(in srgb, var(--ink-warn, var(--warn)) 28%, transparent); }
  .ab-chip--pos  { background: color-mix(in srgb, var(--up) 14%, transparent);
                   color: var(--ink-up, var(--up)); border: 1px solid color-mix(in srgb, var(--ink-up, var(--up)) 28%, transparent); }
  .ab-chip--neg  { background: color-mix(in srgb, var(--down) 14%, transparent);
                   color: var(--ink-down, var(--down)); border: 1px solid color-mix(in srgb, var(--ink-down, var(--down)) 28%, transparent); }
  .ab-chip--info { background: color-mix(in srgb, var(--info) 14%, transparent);
                   color: var(--ink-info, var(--info)); border: 1px solid color-mix(in srgb, var(--ink-info, var(--info)) 28%, transparent); }
  .ab-chip--muted { background: color-mix(in srgb, var(--muted) 12%, transparent);
                    color: var(--muted); border: 1px solid color-mix(in srgb, var(--muted) 22%, transparent); }
  /* A chip whose wording is longer than a lane column. .ab-chip is nowrap + flex:none,
     so a long label runs past .actitem's overflow:hidden and is silently CLIPPED —
     measured at 180px inside a 177px row for the graduation-gap chip. Its words ship
     from the engine (bottoming_authority) and must not be shortened on the page, so
     the chip wraps to a second line instead of losing its tail.
     white-space alone is NOT enough: .ab-chip is `flex: none` (= 0 0 auto), so the
     chip keeps its max-content width and wraps nowhere. It has to be allowed to
     shrink as well — flex-shrink + min-width:0 are what actually let the text reflow. */
  .ab-chip--wrap { white-space: normal; line-height: 1.3; flex: 0 1 auto; min-width: 0; max-width: 100%; }
  /* gate-override ✓ pill */
  .ab-chip--gate { background: color-mix(in srgb, var(--up) 10%, transparent);
                   color: var(--ink-up, var(--up)); border: 1px solid color-mix(in srgb, var(--up) 22%, transparent);
                   font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 4px;
                   line-height: 15px; flex: none; cursor: help; }
  /* theme item star/check/lens glyphs */
  .ai-book { flex: none; margin-left: 4px; font-size: 10px; font-weight: 800; cursor: help;
             color: var(--ink-up, var(--up)); white-space: nowrap; }
  .ai-val { flex: none; margin-left: 4px; font-size: 10.5px; font-weight: 800; color: var(--ink-up, var(--up)); cursor: help; }
  .ai-lens { flex: none; margin-left: 4px; font-size: 11px; color: var(--muted); cursor: help; }
  /* theme item name */
  .actitem.ai-theme .act-row-name { font-weight: 700; }
  /* legacy chips kept for non-board uses */
  .ew-chip { display: none; }  /* hidden in V2 board; moved to popover */
  .acttag, .actage, .acteta, .eqmini { display: none; }  /* moved to popover in V2 */
  /* action-board rows opt in to the shared row-pop engine via [data-rpop] */
  /* .notable is its own .panel since 2026-07-11 — panel chrome carries the separation */
  /* keep legacy references alive for non-board code */
  .actitem b { color: var(--text); }
/* page-scoped fold — every V2 action lane shows only its top 3 rows initially */
.actbody.act-fold.is-collapsed > a.actitem:nth-child(n+4),
.actbody.act-fold.is-collapsed > div:nth-child(n+4) { display: none; }
/* Hide the Show-more button when the lane holds fewer rows than its cap.
   All five lanes now share the same top-three contract. */
.actcol:not(:has(.actbody.act-fold > a.actitem:nth-child(4))):not(:has(.actbody.act-fold > div:nth-child(4))):not(:has(.ab-trim-fold > a.actitem:nth-child(4))):not(:has(.ab-trim-fold > div:nth-child(4))) .lst-more.act-more { display: none; }
.ab-trim-fold.is-collapsed > a.actitem:nth-child(n+4),
.ab-trim-fold.is-collapsed > div:nth-child(n+4) { display: none; }
/* Stand-aside keeps its stable id and uses the shared cap-3 fold. */
.lst-collapse.lst-cap3.is-collapsed > a.actitem:nth-child(n+4),
.lst-collapse.lst-cap3.is-collapsed > div:nth-child(n+4) { display: none; }
  /* ── TS-R6: two-reads reconciliation chip ───────────────────────────────── */
  .two-reads-chip { display:inline-flex; align-items:flex-start; gap:4px; padding:2px 8px; border-radius:6px; font-size:10px; font-weight:600;
    /* was white-space:nowrap — the chip is flex:none inside .actitem{overflow:hidden},
       so in the TAKE PROFITS lane the pill ran past the card's rounded corner and the
       label was cut mid-word ('broad sector AC'). The file's own .ab-chip--wrap note
       warns that white-space alone is not enough; the shrink pair is what fixes it.
       DOCTRINE §3: full display names WRAP, never truncate. */
    white-space:normal; line-height:1.35; flex:0 1 auto; min-width:0; max-width:100%; background:color-mix(in srgb,var(--info) 9%,var(--panel2)); border:1px solid color-mix(in srgb,var(--info) 28%,var(--line)); color:var(--ink-info, var(--info,var(--link))); cursor:help; }
  .two-reads-chip .tr-sep { opacity:.45; margin:0 2px; }
  /* ── Legacy help() "?" hover framework — HOST-PORTABILITY COPY ─────────────
     us_stocks gets these rules from dashboard.html.j2's inline page <style>;
     they are NOT in theme.css (theme.css carries only the span.help glyph
     metrics + .help-upgraded popover overrides — see its help-icon comment).
     The SI Overview host has no page-level copy, so without this block the
     board h2's help() tip renders permanently inline next to the heading
     (Tier-2 sentence at the glance tier — doctrine violation, 2026-08-06).
     On us_stocks this is a harmless same-rules duplicate of the page block
     (same precedent as dc.dc_css() above). theme.js upgradeHelpIcons still
     swaps the CSS hover for the LENS popover where it runs; these rules are
     the no-JS floor. */
  /* help-tip-framework:BEGIN — legacy help() "?" hover framework. Byte-identical
     twin in templates/dashboard.html.j2 AND templates/_us_act_now_board.html.j2
     (the shared board include ships it to hosts that have no page-level copy —
     sector_central leaked the whole tip sentence inline without it, 2026-08-06).
     Deliberately NOT in theme.css: editing theme.css re-stamps ~176 pages, and
     its span.help glyph metrics must keep outranking these bare-.help rules.
     Keep both copies in step — pinned by
     tests/test_us_act_now.py::test_help_tip_framework_is_byte_identical_in_both_copies. */
  .help { display: inline-flex; align-items: center; justify-content: center;
          width: 15px; height: 15px; border-radius: 50%; border: 1px solid var(--muted);
          color: var(--muted); font-size: 10px; font-weight: 600; cursor: help;
          position: relative; vertical-align: middle; margin-left: 5px; flex: none; }
  .help .tip { display: none; position: absolute; bottom: 140%; left: 50%;
               transform: translateX(-50%); width: 330px;
               background: var(--panel); border: 1px solid var(--line);
               padding: 10px 13px; border-radius: 8px;
               z-index: 60; font-size: 12px; line-height: 1.5; color: var(--text);
               text-align: left; font-weight: 400; text-transform: none;
               letter-spacing: normal; box-shadow: var(--popover-shadow);
               pointer-events: auto; cursor: auto; white-space: normal;
               max-height: min(60vh, 420px); overflow-y: auto; overscroll-behavior: contain; }
  /* invisible hover pad across the gap between the ? icon and the tip box —
     without it the :hover chain breaks mid-travel and the tip vanishes before
     the cursor can reach (and scroll) it. Lives on .help, not .tip: the tip
     is a scroll container (overflow-y:auto), which clips its own pseudos. */
  .help:hover::before { content: ''; position: absolute; bottom: 100%; left: -30px; right: -30px; height: 10px; }
  .help:hover .tip, .help.tip-open .tip { display: block; }
  th .help .tip, .help.below .tip { bottom: auto; top: 140%; }
  th .help:hover::before, .help.below:hover::before { bottom: auto; top: 100%; }
  /* keep tooltips on-screen near the right/left viewport edges */
  .help.edge-right .tip { left: auto; right: 0; transform: none; }
  .help.edge-left .tip { left: 0; right: auto; transform: none; }
  .help .tip.tip-wide { width: min(430px, calc(100vw - 32px)); }
  @media (max-width: 640px) {
    .help .tip.tip-wide { width: calc(100vw - 28px); font-size: 11.5px; line-height: 1.45; }
  }
  /* help-tip-framework:END */
  