/* ============================================================================
   AION DESIGN SYSTEM — v1 (redesign-2026)
   Single source of truth for tokens + components.
   Rule: no page may define a one-off color, size, or spacing. Add it here first.

   Fonts self-hosted in ./fonts/ — no third-party requests, ever.
     Geist          (OFL-1.1) — UI / text
     Geist Mono     (OFL-1.1) — numerals, tickers, all tabular data
     Instrument Serif (OFL-1.1) — editorial display (Direction B)
   ========================================================================== */

/* ---------- 1. FONT FACES ------------------------------------------------ */
@font-face{
  font-family:'Geist';src:url('fonts/geist-var.woff2') format('woff2-variations');
  font-weight:100 900;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Geist Mono';src:url('fonts/geist-mono-var.woff2') format('woff2-variations');
  font-weight:100 900;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Instrument Serif';src:url('fonts/instrument-serif.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Instrument Serif';src:url('fonts/instrument-serif-italic.woff2') format('woff2');
  font-weight:400;font-style:italic;font-display:swap;
}

/* ---------- 2. TOKENS ---------------------------------------------------- */
:root{
  /* -- Neutral ramp. Cool cast, never pure black. Elevation = value + hairline. */
  --n-950:#07080a; --n-900:#0b0d10; --n-850:#101317; --n-800:#15181d;
  --n-750:#1b1f25; --n-700:#23282f; --n-600:#333941; --n-500:#4b535d;
  --n-400:#6b7480; --n-300:#949ca8; --n-200:#c2c8d0; --n-100:#e4e7eb;
  --n-050:#f5f6f8;

  /* -- Surfaces. LOCKED 2026-07-25: Direction B's palette won. Slightly
     cooler and bluer than the neutral ramp's own 950/900/850, which keeps
     Direction A's dense hairline layout from reading as flat charcoal. */
  --bg:#080a0f; --surface:#0d1017; --surface-2:#12161f; --surface-3:#171c26;
  --line:rgba(255,255,255,.07); --line-strong:rgba(255,255,255,.13);

  /* -- Text */
  --fg:var(--n-100); --fg-2:var(--n-300); --fg-3:var(--n-400); --fg-4:var(--n-500);

  /* -- Semantic financial. RESERVED. Never used decoratively. */
  --up:#2ea37b; --up-dim:rgba(46,163,123,.14);
  --down:#e05a5a; --down-dim:rgba(224,90,90,.14);
  --warn:#d9a441;

  /* -- Accent. ONE, system-wide. LOCKED 2026-07-25 to Direction B's azure.
     Distinct from --up/--down so it can never be read as a P&L direction. */
  --accent:#5b8dff; --accent-hi:#7ea5ff; --accent-dim:rgba(91,141,255,.12);
  --accent-line:rgba(91,141,255,.32); --accent-fg:#07080a;
  /* Accent-tinted SURFACES. Reserved for the single highest-intent block on a
     page (the sign-in panel). These are real surface values, not overlays, so
     the block reads as blue at a glance instead of merely outlined. Using more
     than one accent surface per page defeats the point — it is a focal device. */
  --accent-surface:#111a30; --accent-surface-2:#16203a;

  /* -- CTA / ACTION COLOUR — "signal lime". LOCKED 2026-07-25.
     The one deliberate exception to "one accent". Azure carries brand and
     structure (rules, eyebrows, links, focus); it is everywhere, so it cannot
     also mean "click this" — an accent used for everything highlights nothing.

     Why lime, specifically:
       · UNIQUE. Financial data products are uniformly blue, black, or amber.
         Amber-on-black is Bloomberg's signature and was rejected outright for
         that reason. Chartreuse-on-navy is owned by nobody in this category.
       · NOT the old brand. Cyan/purple is what this remodel is replacing.
       · SAFE against the semantic palette. --up is a muted TEAL-green
         (#2ea37b, dark and desaturated); this is a light, high-chroma
         YELLOW-green. Different hue family, ~3x the lightness. They are not
         confusable, and lime never touches a number anyway.
       · READABLE. #cbf24c against --cta-fg clears 15:1 contrast.

     HARD RULE: --cta may only ever colour a primary action. Never a data
     surface, chart series, or metric — inside the terminal it would read as a
     state indicator. Direction/P&L stays exclusively --up / --down. */
  --cta:#cbf24c; --cta-hi:#d8fa6b; --cta-fg:#0b0d10;
  --cta-dim:rgba(203,242,76,.12); --cta-line:rgba(203,242,76,.34);

  /* -- Type families */
  --f-ui:'Geist',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --f-num:'Geist Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --f-display:'Instrument Serif',Georgia,serif;

  /* -- Modular type scale (1.25) — nothing below 10px, nothing ad-hoc */
  --t-3xs:10px; --t-2xs:11px; --t-xs:12px;  --t-sm:13px; --t-base:15px;
  --t-md:17px;  --t-lg:21px;  --t-xl:26px;  --t-2xl:33px; --t-3xl:42px;
  --t-4xl:54px; --t-5xl:68px;

  /* -- Spacing, 4px base */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:20px; --s-6:24px;
  --s-8:32px; --s-10:40px; --s-12:48px; --s-16:64px; --s-20:80px; --s-24:96px;

  /* -- Radius. DE-SMOOTHED 2026-07-25.
     Was 4/8/12. Uniformly soft, evenly-rounded panels are the single loudest
     "generated" tell in a dashboard — every surface reads the same weight and
     nothing looks authored. Instruments are hard-edged: a data surface gets a
     corner, not a pillow. Pills stay round because a pill is a shape, not a
     panel. */
  --r-sm:2px; --r-md:3px; --r-lg:4px; --r-full:999px;

  /* -- Rules. Three weights, not one.
     A single hairline used for every division is the other big tell: it
     flattens structure so the eye finds no hierarchy. Hairline separates rows
     INSIDE a widget; edge bounds a widget; section divides regions of the
     page. Never use two of these to do the same job. */
  --rule-hair:rgba(255,255,255,.055);
  --rule-edge:rgba(255,255,255,.11);
  --rule-section:rgba(255,255,255,.20);

  --e:cubic-bezier(.2,.7,.3,1); --d-fast:120ms; --d:180ms;

  /* -- Content width. 2026-07-27: raised 1180 → 1560 (D-53).
     1180 was inherited from the reading-width of a marketing page and it made
     a 1920 monitor render 740px of empty gutter. A desk instrument is judged on
     how much of the screen it earns: boards, heatmaps and 9-horizon tables all
     want columns, and at 1180 they were being scrolled or crushed. 1560 is a
     cap, not a stretch — full-bleed text is unreadable and reads cheap — but it
     is wide enough that a 15" laptop is filled edge to edge and a 1920 desktop
     keeps a deliberate margin instead of a canyon. */
  --maxw:1560px;
}

/* DIRECTION LOCK, 2026-07-25 — the A/B split is over.
   Shipped system = Direction A's page architecture, information density and
   component layout, wearing Direction B's palette. Both override classes are
   retired: their values are merged into :root above, so there is exactly one
   set of tokens and no page can opt into a losing palette.
   .dir-a / .dir-b are kept as inert no-ops purely so the archived
   /redesign-preview/copy/ comparison page does not break. Do not add rules
   to them, and do not put them on a new page. */
.dir-a,.dir-b{ /* intentionally empty — see DIRECTION LOCK above */ }

/* ---------- 3. RESET ----------------------------------------------------- */
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:hidden}
body{
  background:var(--bg); color:var(--fg);
  font-family:var(--f-ui); font-size:var(--t-base); line-height:1.55;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  font-feature-settings:'ss01' 1;
}
img,svg,canvas{display:block;max-width:100%}
/* The shell hides panels with the `hidden` ATTRIBUTE rather than a class, so
   the attribute has to WIN. The UA sheet only gives it `[hidden]{display:none}`
   at specificity (0,1,0), which any component rule that sets a display beats:
   `.plot>.state` (0,2,0) is display:flex, `.stat-row` is grid, `.chips` is
   flex. Every one of those silently ignored `hidden` — a "Building the outlook"
   placeholder stayed on top of a finished chart, and the blended-mode magnet
   row rendered in outlook mode. !important because the whole point is that no
   component rule may outrank it. */
[hidden]{display:none!important}
a{color:inherit;text-decoration:none}
button,input{font:inherit;color:inherit}
::selection{background:var(--accent);color:var(--accent-fg)}

/* Scrollbar — neutral, not cyan */
*{scrollbar-width:thin;scrollbar-color:var(--n-700) transparent}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--n-700);border-radius:var(--r-full)}
::-webkit-scrollbar-thumb:hover{background:var(--n-600)}

/* ---------- 4. TYPE UTILITIES ------------------------------------------- */
/* Every number on the site goes through .num. Tabular is non-negotiable. */
.num{font-family:var(--f-num);font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1,'zero' 1;letter-spacing:-.01em}
.display{font-family:var(--f-display);font-weight:400;line-height:1.04;letter-spacing:-.015em}
.mono-label{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3)}
.eyebrow{font-size:var(--t-2xs);letter-spacing:.18em;text-transform:uppercase;color:var(--fg-3);font-weight:500}
.h1{font-size:clamp(var(--t-2xl),6vw,var(--t-4xl));font-weight:600;letter-spacing:-.03em;line-height:1.06}
.h2{font-size:var(--t-xl);font-weight:600;letter-spacing:-.02em;line-height:1.2}
.h3{font-size:var(--t-md);font-weight:600;letter-spacing:-.01em}
.lede{font-size:var(--t-md);color:var(--fg-2);line-height:1.6}
.muted{color:var(--fg-3)}
.up{color:var(--up)} .down{color:var(--down)} .warn{color:var(--warn)}

/* ---------- 5. COMPONENTS ------------------------------------------------ */
/* SHELL.md 3 is law: a panel is --surface-2 with a --rule-edge boundary.
   This previously said --surface/--line while the 5f veneer said
   --surface-2/--rule-edge, so a "card" and an aliased panel were visibly
   different surfaces inside one stylesheet. */
/* Padding belongs to the card, not to the page. The dashboard — the
   reference surface — was carrying `.card{padding:var(--s-6)}` in its own
   <style>, so a card built anywhere else had no interior at all. Moved here
   so one card means one card everywhere. */
.card{background:var(--surface-2);border:1px solid var(--rule-edge);
  border-radius:var(--r-lg);padding:var(--s-6)}
.card-pad{padding:var(--s-6)}
@media (max-width:600px){.card{padding:var(--s-4)}}
.hr{height:1px;background:var(--line);border:0}

/* Buttons — solid accent for primary, hairline for secondary. No gradients. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);
  padding:13px var(--s-6);border:1px solid transparent;border-radius:var(--r-md);
  font-size:var(--t-sm);font-weight:600;letter-spacing:.01em;cursor:pointer;
  transition:background var(--d) var(--e),border-color var(--d) var(--e),color var(--d) var(--e)}
/* Primary = a conversion action. Always --cta, never --accent. See token note. */
.btn-primary{background:var(--cta);color:var(--cta-fg);font-weight:650}
.btn-primary:hover{background:var(--cta-hi)}
.btn-secondary{background:transparent;border-color:var(--line-strong);color:var(--fg)}
.btn-secondary:hover{border-color:var(--accent-line);background:var(--accent-dim)}
.btn-block{display:flex;width:100%}
.btn:disabled{opacity:.5;cursor:default}

/* Inputs */
.field{margin-bottom:var(--s-4)}
.field label{display:block;font-family:var(--f-num);font-size:var(--t-3xs);
  letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3);margin-bottom:var(--s-2)}
.input{width:100%;background:var(--bg);border:1px solid var(--line-strong);
  border-radius:var(--r-md);padding:12px var(--s-4);font-size:var(--t-sm);
  transition:border-color var(--d) var(--e)}
.input::placeholder{color:var(--fg-4)}
.input:focus{outline:none;border-color:var(--accent-line)}
.input[aria-invalid="true"]{border-color:var(--down)}

/* Badges — text + rule, never emoji */
.badge{display:inline-flex;align-items:center;gap:var(--s-2);padding:5px 10px;
  border:1px solid var(--line-strong);border-radius:var(--r-full);
  font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.1em;
  text-transform:uppercase;color:var(--fg-2)}
.badge-accent{border-color:var(--accent-line);color:var(--accent);background:var(--accent-dim)}

/* Live dot — the ONLY sanctioned infinite animation. It means "streaming". */
.dot{width:6px;height:6px;border-radius:50%;background:var(--up);flex:none;
  box-shadow:0 0 0 0 var(--up-dim);animation:live 2.4s var(--e) infinite}
@keyframes live{0%{box-shadow:0 0 0 0 var(--up-dim)}70%{box-shadow:0 0 0 6px transparent}100%{box-shadow:0 0 0 0 transparent}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
}

/* Stat — the atomic data unit: label above, tabular figure below */
.stat{display:flex;flex-direction:column;gap:var(--s-1)}
.stat-k{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.14em;
  text-transform:uppercase;color:var(--fg-3)}
.stat-v{font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-lg);font-weight:500;letter-spacing:-.02em}

/* Data table */
.table{width:100%;border-collapse:collapse;font-size:var(--t-sm)}
.table th{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.12em;
  text-transform:uppercase;color:var(--fg-3);font-weight:500;text-align:left;
  padding:var(--s-2) var(--s-3);border-bottom:1px solid var(--line)}
/* One row rhythm, whatever the cell holds (D-64). A .tag carries a border and
   its own padding, so a tagged row measured 43px against a text row's 41px.
   In a single table nobody notices; with two tables side by side the rules
   drift a couple of pixels per row and by the third row the panel visibly
   loses register. Height on a table cell acts as a minimum, so a genuinely
   tall cell still grows, but every ordinary row now agrees. */
.table td{padding:10px var(--s-3);height:44px;border-bottom:1px solid var(--line);
  font-variant-numeric:tabular-nums}
.table th{height:34px}
.table td.n{font-family:var(--f-num);text-align:right}
/* A header always aligns the way its column's data aligns (D-142): numeric
   columns are right-aligned, so their header labels sit over the numerals.
   .board already pairs th/td alignment; .table now does too. */
.table th.n{text-align:right}

/* In-card group header (D-147) — splits one card body into named sections
   the eye separates instantly: section-head type on the label, the count as
   a quiet numeric suffix, an optional desk-voice subtitle, a hairline rule
   and section-scale breathing room above every group after the first. */
.group-h{margin:var(--s-12) 0 var(--s-3);padding-top:var(--s-6);border-top:1px solid var(--rule-hair)}
.group-h:first-of-type{margin-top:var(--s-2);padding-top:0;border-top:0}
/* two classes on purpose: .card h3 pins in-card h3s to --t-sm and would
   outrank a single class — a group head IS a section head (SHELL §4). */
.group-h .group-h-t{font-size:var(--t-md);font-weight:600;color:var(--fg);margin:0}
.group-h-n{font-family:var(--f-num);font-variant-numeric:tabular-nums;font-weight:500;
  color:var(--fg-3);font-size:var(--t-sm);margin-left:var(--s-2)}
.group-h-s{font-size:var(--t-xs);color:var(--fg-3);margin:2px 0 0}

/* Sparkline box (D-144) — the shared frame for in-card mini charts: the
   Global Liquidity forecast (assets/aion_liq.js), the desk's consensus and
   extremes sparks. One look, wherever a card carries a small series. */
.spark-box{margin:12px 0;position:relative;background:var(--surface-3);border-radius:var(--r-md);padding:8px 10px 20px}
.spark-box-k{color:var(--fg-3);font-size:var(--t-3xs);margin:0 0 4px;text-transform:uppercase;letter-spacing:1px}
.spark-box-x{display:flex;justify-content:space-between;font-size:var(--t-3xs);color:var(--fg-4);margin-top:2px;font-family:var(--f-num);font-variant-numeric:tabular-nums}
.spark-row{display:flex;gap:var(--s-2)}
.spark-row>.spark-box{flex:1;margin:12px 0 0}
.table tbody tr:hover{background:var(--surface-2)}

/* ---------- 5b. CATALOG + OPERATIONS (Rev-1) -----------------------------
   Rendered from brand.config.js by render.js. Both directions share these
   primitives; each direction only re-skins the container. */
.cat-group{padding:var(--s-8) 0;border-top:1px solid var(--line)}
.cat-group:first-child{border-top:0}
.cat-g{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.16em;
  text-transform:uppercase;color:var(--accent);margin-bottom:var(--s-5);font-weight:500}
.cat-items{display:grid;gap:var(--s-5) var(--s-8);
  grid-template-columns:repeat(auto-fit,minmax(268px,1fr))}
.cat-n{font-size:var(--t-sm);font-weight:600;letter-spacing:-.005em;margin-bottom:var(--s-1)}
.cat-d{font-size:var(--t-sm);color:var(--fg-3);line-height:1.6}

/* Explicit column counts, the D-53 lesson: auto-fit derived 4 columns for
   6 tiles, so the grid read as 8 boxes with two holes. 6 divides by 3, 2
   and 1 — every breakpoint renders a complete rectangle. */
.op-grid{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--r-lg);overflow:hidden;
  grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:760px){.op-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:480px){.op-grid{grid-template-columns:minmax(0,1fr)}}
.op-item{background:var(--surface);padding:var(--s-6)}
.op-v{font-size:var(--t-xl);font-weight:500;letter-spacing:-.03em;line-height:1;
  margin-bottom:var(--s-2)}
.op-k{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.13em;
  text-transform:uppercase;color:var(--accent);margin-bottom:var(--s-2)}
.op-d{font-size:var(--t-xs);color:var(--fg-3);line-height:1.55}

/* ---------- 5c. INTERIOR NAV (rendered by nav.js) ------------------------
   One accent, one shape, one hover. Replaces seven per-page copies that each
   used a different colour and inline hover handlers. */
/* THE ONE HEADER. Same furniture on every page: brand mark, section
   buttons, logout. Switching sections must never change the chrome. */
/* UNIFORM BODY GUTTER — prerequisite for a header that does not move.
   The viewport-centring below uses calc(50% - 50vw), and that 50% resolves
   against the PARENT (the body content box). Terminal set '0 var(--s-6)',
   leaderboard '0!important', guide '12px', six pages nothing — so the same
   calc produced a different offset on every page and the logo still jumped.
   Forcing one horizontal gutter site-wide makes the parent width identical
   everywhere, which is what actually pins the chrome. Vertical padding is
   left to each page. */
body{padding-left:var(--s-6)!important;padding-right:var(--s-6)!important}
@media (max-width:600px){
  body{padding-left:var(--s-4)!important;padding-right:var(--s-4)!important}
}

/* THE HEADER MUST NOT SHIFT BETWEEN PAGES.
   Body padding is not uniform across this site — it ranges from 0 to
   '14px 16px' to '12px !important' — so a header that sits inside the body box
   inherits a different horizontal offset on every page, and the logo visibly
   jumps as you navigate. This centres the header on the VIEWPORT instead of
   the body box, so it renders in exactly the same place regardless of what any
   page does to its own padding. html{overflow-x:hidden} contains the
   scrollbar-width overflow that 100vw can otherwise introduce. */
/* FIXED to the viewport. Every previous attempt positioned the header
   relative to its PARENT — negative margins, then calc(50% - 50vw) — and the
   parent's width is whatever each page's body padding happens to make it, so
   the logo kept moving. position:fixed with left/right:0 removes the parent
   from the equation completely: the header cannot be affected by page
   padding, page width, or scrollbar presence. body gets a matching padding-top
   from nav.js so no content hides beneath it. */
.aion-hd{position:fixed;top:0;left:0;right:0;width:auto;margin:0;
  /* z-index 500: above every page-level sticky bar (pages use 100) but below
   modals and dropdowns (1000-1200), which must still overlay the chrome.
   At 90 the header was painted OVER by scanner, simulations and
   fundamentals, so the logo simply disappeared on those pages. */
  z-index:500;background:var(--surface);
  border-bottom:1px solid var(--rule-section);overflow-x:clip}
.hd-bar{max-width:var(--maxw);margin:0 auto;padding:var(--s-3) var(--s-6);
  display:flex;align-items:center;gap:var(--s-4)}
.hd-logo{display:flex;align-items:center;gap:var(--s-3);color:var(--accent);flex:none}
.hd-word{font-size:var(--t-sm);font-weight:600;letter-spacing:.3em;
  text-transform:uppercase;color:var(--fg)}
.hd-acct{margin-left:auto;display:flex;align-items:center;gap:var(--s-2)}
.hd-user{font-family:var(--f-num);font-size:var(--t-3xs);color:var(--fg-3);
  letter-spacing:.06em;max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hd-menu-wrap{position:relative}
.hd-gear{background:transparent;border:1px solid var(--rule-edge);color:var(--fg-3);
  padding:6px 9px;border-radius:var(--r-sm);cursor:pointer;display:flex;align-items:center;
  transition:border-color var(--d) var(--e),color var(--d) var(--e)}
.hd-gear:hover{border-color:var(--accent-line);color:var(--accent)}
.hd-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:190px;
  background:var(--surface-2);border:1px solid var(--rule-edge);border-radius:var(--r-md);
  box-shadow:0 14px 40px rgba(0,0,0,.62);overflow:hidden;display:none;z-index:70}
.hd-menu.is-open{display:block}
/* D-130: shown through the top layer, the UA popover sheet sets inset:0,
   margin:auto, padding and a border — neutralize it so the menu keeps its
   own chrome; nav.js positions it in viewport coordinates. */
.hd-menu[popover]{inset:auto;margin:0;padding:0;width:auto;height:auto;color:inherit}
.hd-menu[popover]:popover-open{display:block}
.hd-menu button{display:block;width:100%;text-align:left;background:transparent;border:0;
  padding:10px 14px;color:var(--fg-2);font-size:var(--t-xs);cursor:pointer;
  transition:background var(--d) var(--e),color var(--d) var(--e)}
.hd-menu button+button{border-top:1px solid var(--rule-hair)}
.hd-menu button:hover{background:var(--surface-3);color:var(--fg)}
.hd-out{background:transparent;border:1px solid var(--rule-edge);
  color:var(--fg-3);padding:6px 13px;border-radius:var(--r-sm);cursor:pointer;
  font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.1em;text-transform:uppercase;
  transition:border-color var(--d) var(--e),color var(--d) var(--e)}
.hd-out:hover{border-color:var(--down);color:var(--down)}
/* SECTIONS ROLL-UP (2026-07-27, D-54). The section cards are two rows of
   furniture on top of every page. They earn their place when you are moving
   between sections and cost real vertical space when you are reading one, so
   the toggle that used to appear only under 900px is now on every width and
   the choice is remembered. Collapsed, the header is one bar. */
.hd-toggle{display:inline-flex;align-items:center;gap:7px;background:transparent;
  border:1px solid var(--rule-edge);
  color:var(--fg-2);padding:6px 13px;border-radius:var(--r-sm);cursor:pointer;
  font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.1em;text-transform:uppercase;
  transition:border-color var(--d) var(--e),color var(--d) var(--e)}
.hd-toggle:hover{border-color:var(--accent-line);color:var(--fg)}
/* Caret points at what the click will do: down = will open, up = will close.
   A transform, not a bounce — the state change is the only motion. */
.hd-caret{flex:none;transition:transform var(--d) var(--e)}
.aion-hd.is-collapsed .hd-caret{transform:rotate(180deg)}
.aion-hd.is-collapsed .nv{display:none}
/* A GRID, NOT A WRAP (2026-07-27, D-53). This was flex-wrap with a 230px cap
   per card, which meant eight cards packed as "as many as fit" — 6+2 at 1180,
   5+3 at 1024. Never an even shape, and the orphan row read as a mistake.
   Four fixed columns give 4+4 at every desktop width: two full rows, equal
   cards, nothing orphaned. The count is explicit because evenness is the
   point — auto-fit would just re-derive the same ragged answer. */
/* 2026-07-28: ten links now (My Desk + Alerts joined). 10 divides by 5, not
   by 4 — five columns keep the D-53 evenness rule: 5+5 on desktop, 2-col
   phones get five full rows, never an orphan. */
.nv{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--s-2);
  max-width:var(--maxw);margin:0 auto;padding:0 var(--s-6) var(--s-4)}
/* Dashboard-style cards — the look Joey signed off on, now the standard on
   every page rather than only the dashboard. */
.nv-a{display:flex;align-items:flex-start;gap:var(--s-3);
  padding:9px var(--s-4);min-width:0;
  background:var(--surface-2);border:1px solid var(--rule-edge);
  border-radius:var(--r-md);color:var(--fg-2);
  transition:border-color var(--d) var(--e),background var(--d) var(--e),color var(--d) var(--e)}
.nv-a:hover{background:var(--surface-3);border-color:var(--accent-line);color:var(--fg)}
/* No font-weight here: the title is already 600 on every card and the
   description inherits the card's weight, so a 600 here fattens ONLY the
   active card's description — wide enough to wrap it (the terminal nav
   read taller than every other page, D-117). Border + background carry
   the state. */
.nv-a.is-active{border-color:var(--accent-line);background:var(--accent-dim);color:var(--fg)}
.nv-i{flex:none;margin-top:2px;color:var(--accent);opacity:.9}
.nv-a:hover .nv-i,.nv-a.is-active .nv-i{opacity:1}

.nv-t{display:flex;flex-direction:column;gap:1px;min-width:0}
.nv-n{font-size:var(--t-xs);font-weight:600;color:inherit;line-height:1.25}
/* Unseen-alert count on the Alerts nav card. Data palette, not the accent:
   the count is a state, not chrome. Painted only from the local cache. */
.nv-badge{display:inline-block;margin-left:6px;padding:0 5px;min-width:14px;
  border-radius:var(--r-full);background:var(--warn);color:var(--bg);
  font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-3xs);font-weight:600;line-height:14px;text-align:center;
  vertical-align:1px}
.nv-s{font-size:var(--t-3xs);color:var(--fg-3);line-height:1.35}
@media (max-width:900px){
  .nv{grid-template-columns:repeat(2,minmax(0,1fr));padding-bottom:var(--s-3)}
}
@media (max-width:520px){
  .nv{grid-template-columns:minmax(0,1fr)}
  .nv-s{display:none}
}
@media (max-width:600px){
  .aion-hd{margin:0}
  .hd-bar,.nv{padding-left:var(--s-4);padding-right:var(--s-4)}
  /* THE BAR HAS TO WRAP BELOW 563px (D-118). .hd-bar is one nowrap flex row
     whose content has a hard min-content width of 563px — logo 90 + Sections
     91 + user 59 + Guide 63 + Community 91 + gear 25 + Log out 64. Under that
     width the row overflowed and .aion-hd's overflow-x:clip silently ate the
     right end: on every phone the gear measured 0 of 25 visible pixels and
     Log out was gone entirely, so Settings could not be opened at all. In the
     narrow band where a sliver of the gear was still tappable (466-490px) the
     menu DID open and was then sliced by the same clip box — a bordered panel
     with its right half missing, which is how this was reported.

     overflow-x:clip is also why no harness caught it: shot.js gates on
     scrollWidth === clientWidth, and clip is exactly what makes that pass.

     Wrapping puts the account cluster on its own full-width row, right
     aligned. The gear then sits ~88px in from the right edge, so the 190px
     menu (anchored right:0 to the gear) lands fully on screen down to 280px.
     .hd-acct wraps again below that rather than overflow. nav.js measures the
     header and sets body padding-top from a ResizeObserver, so the taller
     two-row header reserves its own space with no other change.

     Scoped to <=600px on purpose: 600 sits just above the 563px min-content
     width, so every viewport that was already correct renders identically. */
  .hd-bar{flex-wrap:wrap;row-gap:var(--s-2)}
  .hd-acct{margin-left:0;width:100%;justify-content:flex-end;flex-wrap:wrap;
    row-gap:var(--s-2)}
}

/* ---------- 5d. MARKET INTERNALS — expand in place -----------------------
   Default is the two-panel pill view. Expanding grows the card to the full
   grid width and stacks every breadth series at once. */
.mi-exp-bar{display:flex;justify-content:flex-end;margin-bottom:var(--s-3)}
.mi-exp-btn{background:transparent;border:1px solid var(--rule-edge);color:var(--fg-2);
  padding:5px 12px;border-radius:var(--r-sm);cursor:pointer;
  font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.1em;text-transform:uppercase;
  transition:border-color var(--d) var(--e),color var(--d) var(--e),background var(--d) var(--e)}
.mi-exp-btn:hover{border-color:var(--accent-line);color:var(--fg);background:var(--accent-dim)}
/* Intraday placement (D-139): the internals block shares the RS row and
   takes the wider share — RS keeps one column, internals spans the rest.
   Full row again when the breadth charts are expanded, and on any width
   too narrow for a real multi-column grid (a 2/-1 on a one-column grid
   would mint phantom columns and sideways scroll). 1D never shows this
   host at all, so the daily layout cannot move by a pixel. */
.mi-grid-host{grid-column:1/-1}
@media (min-width:1100px){
  body[data-aion-tf="1h"] .mi-grid-host:not(.is-expanded),
  body[data-aion-tf="4h"] .mi-grid-host:not(.is-expanded){grid-column:2/-1}
}
.mi-grid-host.is-expanded{grid-column:1/-1}
.mi-all-grid{display:none;gap:var(--s-4);
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.mi-all-item{background:var(--surface-3);border:1px solid var(--rule-hair);
  border-radius:var(--r-sm);padding:10px 12px 8px;min-width:0;overflow:hidden}
/* the chart owns a fixed 120px band so nothing can spill past the card */
.mi-all-item svg{width:100%;height:120px;display:block;overflow:hidden}
.mi-all-t{color:var(--fg-3);font-size:var(--t-3xs);margin:0 0 6px;
  text-transform:uppercase;letter-spacing:.1em;font-weight:600}
.mi-all-d{display:flex;justify-content:space-between;font-size:9px;color:var(--fg-4);margin-top:2px;
  font-family:var(--f-num);font-variant-numeric:tabular-nums}
.mi-all-empty{color:var(--fg-3);font-size:var(--t-xs);padding:var(--s-4)}

/* ---------- 5e. SHELL COMPONENTS (SHELL.md §2,§3,§5,§8,§9) ---------------
   Built once here so no page reinvents them. Blockers 1-3 from the
   consistency matrix. */

/* -- Page frame. ONE max-width site-wide. Eleven different values is what
      made the site feel like eleven different products. */
.app{max-width:var(--maxw);margin:0 auto;padding:0 var(--s-6);width:100%}
.app-wide{max-width:1520px}          /* opt-in ONLY for genuine wide tables */
.app-head{padding:var(--s-8) 0 var(--s-5)}
.app-title{font-size:var(--t-xl);font-weight:600;letter-spacing:-.025em;line-height:1.15}
.app-sub{font-size:var(--t-sm);color:var(--fg-3);margin-top:var(--s-2);max-width:70ch;line-height:1.6}
.app-section{margin-top:var(--s-16)}
@media (max-width:600px){
  .app{padding:0 var(--s-4)}
  .app-head{padding:var(--s-6) 0 var(--s-4)}
  .app-section{margin-top:var(--s-10)}
}

/* THE CONTENT WRAPPER.
   AION Index wrapped everything in <main class="main"> with its own
   max-width AND 24px padding, on top of the body gutter — so its content sat
   48px inset and capped narrower than the dashboard, which has no wrapper at
   all. Same header, same title block, but every element below them started at
   a different x. That was the root of "things aren't in the same place".
   The wrapper may cap width, but the gutter belongs to the body alone. */
main,.main{max-width:var(--maxw);margin:0 auto;padding-left:0;padding-right:0;width:100%}

/* ---------- 5g. REBUILD COMPONENTS --------------------------------------
   Used by pages rebuilt from scratch on the shell. Replaces the veneer in 5f,
   which aliased legacy container names onto the card. 5f is deleted as each
   page is rebuilt; when the last one lands, it goes entirely. */
.card-body{min-width:0}
/* The scroller bleeds into the card gutter and PADS the same amount back, so
   the table aligns with the card content while width:100% resolves to exactly
   the container. The old inner-margin version made every table's scroll area
   16px wider than its box — a stray scrollbar under every table on engines
   that paint them (D-142). Genuinely wide tables still scroll in here. */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 calc(-1 * var(--s-2));padding:0 var(--s-2)}
.table-scroll > .table{margin:0}
.table td[data-dir="up"]{color:var(--up)}
.table td[data-dir="down"]{color:var(--down)}
.empty-state{color:var(--fg-3);font-size:var(--t-sm);padding:var(--s-6) 0;text-align:center}
.stat-row{display:grid;gap:var(--s-4);grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
/* A PAGE-LEVEL stat strip sits on the page background, where bare metrics
   read as loose text; panel chrome anchors them. Strips inside a card keep
   the bare form — their card is the anchor. */
.stat-row.is-panel{background:var(--surface-2);border:1px solid var(--rule-edge);
  border-radius:var(--r-lg);padding:var(--s-4) var(--s-6);margin-bottom:var(--s-5)}
.metric{display:flex;flex-direction:column;gap:var(--s-1);min-width:0}
.metric-k{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.13em;
  text-transform:uppercase;color:var(--fg-3)}
.metric-v{font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-lg);font-weight:500;letter-spacing:-.02em;line-height:1.1}
.metric-s{font-family:var(--f-num);font-size:var(--t-3xs);color:var(--fg-3);
  text-transform:uppercase;letter-spacing:.06em}

/* ---------- 5f. PANEL PARITY --------------------------------------------
   Fundamentals, Analogues, Off-Exchange Blocks, Options, Simulations and
   Quant contain ZERO .card elements — they were built from their own
   containers, which is why they read as a different product next to the
   dashboard. Map those container names onto the card so a panel is a panel
   everywhere, without touching a line of their markup. */
.table-wrap,.table-container,.conditions-section,.ticker-picker,.index-toggle,
.summary-card,.panel,.box,.section-box,.stat-box,.data-panel,.chart-wrap,
.wrap > section,.content > section{
  background:var(--surface-2);border:1px solid var(--rule-edge);
  border-radius:var(--r-lg);padding:var(--s-5)}
.table-wrap:hover,.table-container:hover,.panel:hover{border-color:var(--rule-edge)}

/* ONE HEADING SCALE — the fundamental fix.
   Headings were sized in `em` on some pages (terminal .card h2{1.1em} with
   0.95em/0.9em overrides; guide h1{1.6em!important} h2{1.2em!important}) and
   in tokens on others. `em` compounds off whatever the parent happens to be,
   so an identical heading rendered at a different size, weight and case on
   every page. Absolute token sizes, defined once, so a heading level means
   the same thing everywhere. */
h1{font-size:var(--t-xl);font-weight:600;letter-spacing:-.025em;line-height:1.15}
h2{font-size:var(--t-md);font-weight:600;letter-spacing:-.01em;line-height:1.25;text-transform:none}
h3{font-size:var(--t-sm);font-weight:600;letter-spacing:.01em;line-height:1.3;text-transform:none}
.card h2,.card-title,.section-title,.panel-title,.cone-header h2,.mr-header-left h2{
  font-family:var(--f-ui);font-size:var(--t-md);font-weight:600;
  letter-spacing:-.01em;text-transform:none;color:var(--fg)}
.card h3,.table-wrap h3,.quick-ref h3{font-family:var(--f-ui);font-size:var(--t-sm);
  font-weight:600;letter-spacing:.01em;text-transform:none}

/* ONE page title, one subtitle. Every page had its own h1 size and colour. */
.header h1,.page-header h1,.app-head h1,.page-title,h1.page-title{
  font-size:var(--t-xl);font-weight:600;letter-spacing:-.025em;line-height:1.15;color:var(--fg)}
.page-subtitle,.app-sub,.header p,.page-header p{
  font-size:var(--t-sm);color:var(--fg-3);margin-top:var(--s-2);line-height:1.6}
.last-updated{font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-3xs);letter-spacing:.06em;color:var(--fg-3);margin-top:var(--s-2)}

/* THE PAGE TITLE BLOCK — the slot directly under the fixed chrome.
   This was the real inconsistency behind "things aren't in the same place":
   terminal used .header (--maxw, --rule-section underline, --s-6/--s-5
   padding) while leaderboard used .page-header (centred text, a 24px margin,
   nothing else). Same slot, two components, so content below the logo started
   at a different height and the underline appeared on one page only.
   Defined once here; pages may not redefine it. */
.header,.page-header,.app-head{text-align:center;position:relative;
  max-width:var(--maxw);margin:0 auto var(--s-8);
  border-bottom:1px solid var(--rule-section);padding:var(--s-6) 0 var(--s-5)}
@media (max-width:600px){
  .header,.page-header,.app-head{margin-bottom:var(--s-6);padding:var(--s-4) 0 var(--s-3)}
}

/* -- Card header + timestamp slot. Provenance is the interior's trust
      signal: a number with no age is not evidence. */
.card-h{display:flex;align-items:flex-start;gap:var(--s-3);margin-bottom:var(--s-4)}
.card-h-t{min-width:0;flex:1}
.card-title{font-size:var(--t-md);font-weight:600;letter-spacing:-.01em;line-height:1.25;color:var(--accent)}
.card-sub{font-size:var(--t-xs);color:var(--fg-3);margin-top:2px;line-height:1.5}
.card-ts{flex:none;font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-3xs);color:var(--fg-3);letter-spacing:.06em;white-space:nowrap;padding-top:2px}
.card-ts .dot{display:inline-block;margin-right:5px;vertical-align:middle}

/* -- Tooltip / glossary. Terms of art get one sentence, on demand.
      Hover AND focus, so it is reachable by keyboard. */
.tip{position:relative;display:inline-flex;align-items:center;gap:3px;
  border-bottom:1px dotted var(--fg-4);cursor:help}
.tip-i{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:13px;height:13px;border-radius:var(--r-full);border:1px solid var(--rule-edge);
  font-family:var(--f-num);font-size:8px;line-height:1;color:var(--fg-3);flex:none}
/* The badge is what pins the definition open on a pointer device, and it has
   to survive a thumb on a phone. A transparent halo gives it a ~31px target
   without changing a pixel of layout. */
.tip-i::after{content:'';position:absolute;inset:-9px;border-radius:var(--r-full)}
.tip:hover .tip-i,.tip:focus-visible .tip-i{border-color:var(--accent-line);color:var(--accent)}
/* --tip-dx is set by render.js when the bubble would leave the viewport. It
   defaults to 0, so the tooltip is correct with JS disabled and merely
   uncorrected at the extreme edges. */
.tip-b{position:absolute;bottom:calc(100% + 8px);left:50%;
  transform:translateX(calc(-50% + var(--tip-dx,0px)));
  width:max-content;max-width:270px;background:var(--surface-3);
  border:1px solid var(--rule-edge);border-radius:var(--r-md);
  padding:9px 11px;font-family:var(--f-ui);font-size:var(--t-xs);font-weight:400;
  line-height:1.5;color:var(--fg-2);letter-spacing:0;text-transform:none;
  /* A sentence, in a box, wherever the box happens to hang. EVERY inherited
     text property has to be neutralised here, because the bubble lives inside
     whatever it defines: .board th is white-space:nowrap and text-align:right,
     so a definition rendered in a column heading came out as one unwrapped
     line running straight out of its own background. It was invisible only
     while the bubble was being clipped. */
  white-space:normal;text-align:left;overflow-wrap:break-word;
  box-shadow:0 10px 28px rgba(0,0,0,.6);
  opacity:0;visibility:hidden;transition:opacity var(--d) var(--e);z-index:60;pointer-events:none}
.tip:hover .tip-b,.tip:focus-visible .tip-b,.tip.is-open .tip-b{opacity:1;visibility:visible}
@media (max-width:600px){.tip-b{max-width:220px}}
/* Anchored under its mark instead of over it, when the box it lives in would
   otherwise cut the top off (first row of a scrolling board). */
.tip-b.below{bottom:auto;top:calc(100% + 8px)}

/* -- The ⓘ bubble in the TOP LAYER.
      A glossary bubble sits ABOVE its mark, so on the first row of a
      scrolling panel it lands outside that panel's box and gets clipped —
      on the watchlist header, 35 of its 38 pixels, leaving a bare strip
      with no text in it. Sticky <th> cells compound it: z-index:2 on a
      sticky cell opens a stacking context the bubble's z-index:60 cannot
      climb out of. `popover` puts it in the browser's top layer, which no
      ancestor can clip or out-paint, and render.js places it in viewport
      coordinates clamped to the card. Browsers without popover ignore the
      attribute and keep the absolute bubble above.

      Every UA popover default has to be undone: it arrives centred in the
      viewport by `inset:0;margin:auto`, with its own border, padding and
      system colours. It is also display:none while closed, which is a
      bonus — a closed bubble can no longer extend any scroll width. */
.tip-b[popover]{inset:auto;margin:0;overflow:visible;color:var(--fg-2);
  background:var(--surface-3);border:1px solid var(--rule-edge);padding:9px 11px}
.tip-b[popover]:popover-open{opacity:1;visibility:visible}
.tip-b[popover]::backdrop{background:none}

/* -- HOVER READOUT (D-59). Any data mark — a bar, a cell, a marker — can carry
      its own value and show it on hover, focus or tap. It reuses the tooltip
      bubble deliberately: a number and a definition must not look like two
      different systems, and it inherits the viewport clamping for free.

      This replaces native title="", which waits half a second, renders in the
      OS font at the OS size, cannot be styled, and never appears on a phone.

      `:focus` rather than `:focus-visible` here, because a tap on a data mark
      should show its value and a tap does not produce a visible-focus match. */
.hov{position:relative}
.hov:hover>.tip-b,.hov:focus>.tip-b,.hov:focus-within>.tip-b{opacity:1;visibility:visible}
.hov:focus{outline:none}
.hov:focus-visible>.tip-b{outline:none}
.hov:focus-visible{outline:1px solid var(--accent-line);outline-offset:1px}
/* Numeric variant: one figure, optional context line under it. Tabular, mono,
   never wrapped — a value that reflows while you read it reads as unstable. */
.tip-b.n{max-width:none;width:max-content;white-space:nowrap;text-align:center;
  padding:7px 10px;font-family:var(--f-num);font-variant-numeric:tabular-nums}
.tip-b.n b{display:block;font-size:var(--t-xs);font-weight:600;color:var(--fg);
  letter-spacing:.01em}
.tip-b.n i{display:block;margin-top:3px;font-style:normal;font-size:var(--t-3xs);
  color:var(--fg-3);letter-spacing:.05em;text-transform:uppercase}

/* -- Shared footer. Identical on all 14 pages. */
.app-foot{border-top:1px solid var(--rule-section);background:var(--surface);
  margin-top:var(--s-24);padding:var(--s-8) 0 var(--s-10)}
.app-foot-in{max-width:var(--maxw);margin:0 auto;padding:0 var(--s-6);display:grid;gap:var(--s-4)}
.app-foot .foot-links{display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-6);
  align-items:center;font-size:var(--t-xs);color:var(--fg-4)}
.app-foot .foot-links a{color:var(--fg-3);border-bottom:1px solid transparent;
  transition:border-color var(--d) var(--e)}
.app-foot .foot-links a:hover{border-color:var(--accent-line)}
.app-foot .foot-links .sp{margin-left:auto}
@media (max-width:600px){.app-foot-in{padding:0 var(--s-4)}}

#acct-bar{display:none!important}

/* Compliance — legible, never hidden in 8px grey. Legal must be readable. */
/* NOTE: several pages already use .legal for the full legal-disclaimer block,
   so this must NOT constrain width — doing so rendered the disclaimer as a
   narrow left-hand column. Width is owned by .app-foot-in / the page frame. */
.legal{font-size:var(--t-xs);color:var(--fg-3);line-height:1.65}
/* The interior disclaimer block, consistent on every page that carries it. */
.legal-title{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.16em;
  text-transform:uppercase;color:var(--fg-3);margin-bottom:var(--s-3)}
.legal-text{font-size:var(--t-xs);color:var(--fg-3);line-height:1.7;
  max-width:92ch;margin-left:auto;margin-right:auto;text-align:left}
/* THE legal / notice block. One treatment everywhere.
   It exists to protect the business, not to address the user. So it RECEDES:
   no card surface, no border, no radius — a hairline rule and fine print at
   the foot of the page. Nothing is hidden or truncated (it must stay fully
   readable to do its job); it simply stops competing with the product. */
div.legal{max-width:var(--maxw);margin:var(--s-10) auto 0;padding:var(--s-5) 0 0;
  background:none;border:0;border-top:1px solid var(--rule-hair);border-radius:0;
  text-align:left}
div.legal .legal-title{font-family:var(--f-num);font-size:9px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--fg-4);font-weight:500;margin:0 0 var(--s-2)}
div.legal .legal-title:not(:first-child){margin-top:var(--s-4)}
div.legal p,div.legal .legal-text{font-size:var(--t-2xs);line-height:1.55;
  color:var(--fg-4);max-width:none;margin:0;text-align:left;letter-spacing:0}
div.legal p+p{margin-top:var(--s-3)}
/* The copyright line was set as just another paragraph, so 8px of margin left
   it glued to the end of a very long disclaimer. It is a separate statement:
   give it a rule, real space, and centre it away from the legal prose. */
div.legal .copyright{margin-top:var(--s-6);padding-top:var(--s-4);
  border-top:1px solid var(--rule-hair);text-align:center;
  font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.06em;color:var(--fg-4)}
/* Long legal prose needs looser leading than UI text or it reads as a wall. */
div.legal p,div.legal .legal-text{line-height:1.7}
div.legal a{color:var(--fg-3);text-decoration:underline;text-underline-offset:2px}
div.legal a:hover{color:var(--accent)}
@media(max-width:600px){div.legal{margin-top:var(--s-8);padding-top:var(--s-4)}
  div.legal p,div.legal .legal-text{font-size:10px}}
.legal-sm{font-size:var(--t-2xs);color:var(--fg-4);line-height:1.6}

/* Layout */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--s-6)}
.rule{border-top:1px solid var(--line)}
.grid{display:grid;gap:var(--s-4)}

/* Focus visibility — accessibility is part of feeling engineered */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-sm)}

/* ============================================================================
   6. SHARED PAGE MODULES  (rebuild vocabulary — PRIME DIRECTIVE, 2026-07-26)

   Everything an interior page needs beyond §5 lives HERE, once, with a
   generic name — never in a page's own <style>. The rule that produced this
   section: "nothing exists in one place only." Fundamentals was rebuilt
   first, so these were written for it; every later page uses the same
   classes rather than inventing a near-identical one. If a rebuilt page
   needs something new, it is added here and the earlier pages are retrofitted
   in the same commit.
   ========================================================================== */

/* -- 6a. Page thesis + provenance. On EVERY page, directly under the title.
      The thesis says what this page computes and at what scale; the
      provenance strip says how old the data is and how often it lands.
      Both are part of the screenshot: a crop of any page must explain
      itself and date itself without the rest of the page. */
.page-thesis{font-size:var(--t-sm);color:var(--fg-2);line-height:1.6;
  max-width:78ch;margin:var(--s-3) auto 0}
.page-prov{margin-top:var(--s-4);display:flex;justify-content:center;
  align-items:center;flex-wrap:wrap;gap:var(--s-2) var(--s-5);
  font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.1em;
  text-transform:uppercase;color:var(--fg-3)}
.page-prov b{font-weight:500;color:var(--fg-2);font-variant-numeric:tabular-nums}
@media (max-width:600px){.page-prov{gap:var(--s-1) var(--s-3)}}

/* -- 6b. Segmented control. ONE toggle shape site-wide: mode switches,
      basis switches, timeframe-like pickers. Hard-edged, hairline, no
      gradient — the selected segment is a filled surface, not a colour. */
.seg{display:inline-flex;border:1px solid var(--rule-edge);border-radius:var(--r-md);
  overflow:hidden;flex-wrap:wrap}
.seg-btn{padding:8px var(--s-4);background:transparent;border:0;cursor:pointer;
  font-family:var(--f-num);font-size:var(--t-3xs);font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;color:var(--fg-3);white-space:nowrap;
  transition:background var(--d) var(--e),color var(--d) var(--e)}
.seg-btn+.seg-btn{border-left:1px solid var(--rule-edge)}
.seg-btn:hover:not(.is-on){color:var(--fg);background:var(--surface-3)}
.seg-btn.is-on{background:var(--surface-3);color:var(--fg)}
.seg-btn.is-on::after{content:'';display:block;height:2px;background:var(--accent);
  margin:6px -16px -8px}

/* -- 6c. Control row — the strip of pickers that sits above a view. */
.ctl-row{display:flex;justify-content:center;align-items:center;flex-wrap:wrap;
  gap:var(--s-3);margin:0 0 var(--s-5)}
.ctl-label{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.13em;
  text-transform:uppercase;color:var(--fg-3)}
.select{appearance:none;-webkit-appearance:none;background-color:var(--surface-2);
  border:1px solid var(--rule-edge);border-radius:var(--r-md);color:var(--fg);
  font-family:var(--f-num);font-variant-numeric:tabular-nums;font-size:var(--t-2xs);
  letter-spacing:.06em;padding:9px 32px 9px var(--s-4);cursor:pointer;min-height:38px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%236b7480' stroke-width='1.4' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat:no-repeat;background-position:right 12px center;background-size:11px;
  transition:border-color var(--d) var(--e)}
.select:hover,.select:focus{border-color:var(--accent-line);outline:none}
.select option{background:var(--surface-2);color:var(--fg)}
/* Numeric parameter box. Same surface, border, radius and mono face as
   .select so a row of controls reads as one instrument — but no chevron
   (it is not a dropdown) and only as wide as the number it holds. Any page
   taking a numeric parameter uses this rather than borrowing .select.
   Named .num-box, NOT .num: this rule shipped as a second `.num` and, being
   later in the file, silently turned every class="num" TEXT span site-wide
   into an 88px bordered form control — 11px numerals in the login hero
   prose, the op-grid stat values crushed from --t-xl to 11px chips, the
   price boxes clipping their own figure (D-111). .num is the TYPOGRAPHY
   utility only; a control declares .num-box (D-115). */
.num-box{appearance:none;-webkit-appearance:none;background:var(--surface-2);
  border:1px solid var(--rule-edge);border-radius:var(--r-md);color:var(--fg);
  font-family:var(--f-num);font-variant-numeric:tabular-nums;font-size:var(--t-2xs);
  letter-spacing:.06em;padding:9px var(--s-3);min-height:38px;width:88px;
  transition:border-color var(--d) var(--e)}
.num-box:hover,.num-box:focus{border-color:var(--accent-line);outline:none}
/* A label and its control travel together: without this the row wraps and
   strands a label on one line with its input on the next. */
.ctl-pair{display:inline-flex;align-items:center;gap:var(--s-2)}

/* -- 6d. Symbol picker. Search field + prefix-filtered menu. Used anywhere a
      page selects one name out of a universe. */
.picker{position:relative;display:flex;align-items:center;gap:var(--s-3);
  max-width:460px;margin:0 auto var(--s-4);width:100%}
.picker-in{flex:1;min-width:0;background:var(--surface-2);border:1px solid var(--rule-edge);
  border-radius:var(--r-md);color:var(--fg);font-family:var(--f-num);
  font-size:var(--t-base);letter-spacing:.08em;text-transform:uppercase;
  padding:11px var(--s-4);min-height:44px;transition:border-color var(--d) var(--e)}
.picker-in::placeholder{color:var(--fg-4);letter-spacing:.02em;text-transform:none}
.picker-in:focus{outline:none;border-color:var(--accent-line)}
.picker-now{flex:none;min-width:96px;text-align:center;padding:11px var(--s-3);
  background:var(--surface-3);border:1px solid var(--accent-line);border-radius:var(--r-md);
  font-family:var(--f-num);font-variant-numeric:tabular-nums;font-size:var(--t-sm);
  font-weight:500;letter-spacing:.12em;color:var(--accent)}
.picker-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;max-height:320px;
  overflow-y:auto;background:var(--surface-2);border:1px solid var(--rule-edge);
  border-radius:var(--r-md);box-shadow:0 14px 40px rgba(0,0,0,.62);z-index:80;display:none}
.picker-menu.is-open{display:block}
.picker-opt{padding:9px var(--s-4);font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-xs);letter-spacing:.08em;color:var(--fg-2);cursor:pointer}
.picker-opt+.picker-opt{border-top:1px solid var(--rule-hair)}
.picker-opt:hover{background:var(--surface-3);color:var(--fg)}
@media (max-width:600px){.picker-now{display:none}.picker{max-width:none}}

/* -- 6d-2. Picker option rows carry a value on the right. Flex here rather
      than in the page, so a one-span option (fundamentals) and a
      ticker-plus-price option (options) are the same component. */
.picker-opt{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-4)}
.picker-meta{flex:none;color:var(--fg-3);font-size:var(--t-3xs);letter-spacing:.06em}

/* -- 6e. Note — the paragraph that explains how a board is built. Recedes
      behind the data it describes; it is method, not headline. */
.note{background:var(--surface-2);border:1px solid var(--rule-hair);
  border-left:2px solid var(--accent-line);border-radius:var(--r-md);
  padding:var(--s-4) var(--s-5);font-size:var(--t-xs);line-height:1.7;
  color:var(--fg-2);margin-bottom:var(--s-5)}
.note b{color:var(--fg);font-weight:600}
/* A stale-state banner is a CAUTION, not a method note: the warn edge and
   warn-toned lead say "this is not live data" wherever the reader is. The
   inline action button rides the note so the way back is always one click. */
.note.note-warn{border-left-color:var(--warn)}
.note.note-warn b{color:var(--warn)}
.note .note-act{margin-left:var(--s-3);vertical-align:middle}

/* -- 6f. Board — the dense ranked table. Sticky head so the columns survive
      a long scroll; rank tint on the leading rows; horizontal scroll is
      owned by the wrapper so the page body never scrolls sideways. */
.board-wrap{border:1px solid var(--rule-edge);border-radius:var(--r-lg);
  background:var(--surface-2);max-height:720px;overflow:auto}
.board{width:100%;min-width:760px;border-collapse:collapse;
  font-family:var(--f-num);font-variant-numeric:tabular-nums;font-size:var(--t-xs)}
/* Paired half-width boards fit their pane (D-176, Ryan/Joey reports): the
   760px floor is sized for full-width boards and forced every pair-grid
   board into a sideways scroll that hid its end column (TREND sparklines)
   and stretched dead space between columns. A .board-fit table lays out at
   its natural width; the wrap still scrolls only when content truly
   cannot fit. */
.board-fit{min-width:0}
.board th{background:var(--surface-3);color:var(--fg-3);
  font-weight:500;font-size:var(--t-3xs);letter-spacing:.12em;text-transform:uppercase;
  text-align:right;padding:10px var(--s-3);white-space:nowrap;
  border-bottom:1px solid var(--rule-edge)}
/* Sticky only inside a scroll container of its own — a sticky header in a
   page-scrolled table would ride up under the fixed chrome. */
.board-wrap .board th{position:sticky;top:0;z-index:2}
.board td{text-align:right;padding:9px var(--s-3);color:var(--fg-2);white-space:nowrap;
  border-bottom:1px solid var(--rule-hair)}
.board th.l,.board td.l{text-align:left}
.board td.co{white-space:normal;min-width:190px;color:var(--fg)}
.board tbody tr{border-left:2px solid transparent}
.board tbody tr:hover td{background:var(--surface-3)}
.board tbody tr.t1{border-left-color:var(--accent)}
.board tbody tr.t2{border-left-color:var(--accent-line)}
.board .sub{display:block;color:var(--fg-4);font-size:var(--t-3xs);
  letter-spacing:.04em;text-transform:uppercase;margin-top:2px;white-space:normal}
.board .lnk{color:var(--fg);font-weight:500;cursor:pointer;
  border-bottom:1px solid transparent}
.board .lnk:hover{color:var(--accent);border-bottom-color:var(--accent-line)}
.board .up{color:var(--up)} .board .down{color:var(--down)}
/* Sortable column heads (D-177, the leaderboard grammar): pointer on the
   affordance; the active column and its direction arrow wear accent,
   quietly — the arrow is text in the header's own size. */
.board th[data-sort]{cursor:pointer;user-select:none}
.board th.is-sorted{color:var(--accent)}
.board th .sort-a{margin-left:3px}
/* Drawn cell content obeys its column's alignment (D-142's law extended to
   non-text cells, D-176): the line-147 media reset makes every svg/canvas
   display:block, which pinned table sparklines to the cell's LEFT edge no
   matter what text-align said — under a right-aligned header the drawing
   floated orphaned mid-column. Inline-block follows text-align like the
   glyphs do, one rule for every board on the platform. */
.board td svg,.board td canvas{display:inline-block;vertical-align:middle}
.board-empty{text-align:center;padding:var(--s-12) var(--s-4);color:var(--fg-3);
  font-family:var(--f-ui);font-size:var(--t-sm);white-space:normal}
/* Compact fit-boards tighten their gutters so the TREND column stays on
   screen at phone widths instead of scrolling sideways (D-176). After the
   th/td rules: same specificity, the cascade must land here. */
@media (max-width:600px){
  .board-fit th,.board-fit td{padding-left:var(--s-2);padding-right:var(--s-2)}
}
@media (max-width:480px){
  .board-fit th,.board-fit td{padding-left:var(--s-1);padding-right:var(--s-1)}
}

/* -- 6g. Sub-panel — a panel INSIDE a card. Goes LIGHTER, never darker
      (SHELL.md §3). Every "box within a box" on the site is this. */
.sub-panel{background:var(--surface-3);border:1px solid var(--rule-hair);
  border-radius:var(--r-md);padding:var(--s-4);min-width:0}
.sub-h{font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.13em;
  text-transform:uppercase;color:var(--fg-3);margin-bottom:var(--s-3)}
.pair-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-3)}
@media (max-width:600px){.pair-grid{grid-template-columns:1fr}}
/* A grid item's min-width defaults to AUTO, so a .board (min-width 760px)
   inside a pair-grid column silently widens the track past the page instead
   of scrolling inside its .board-wrap. Zero it once here: the wrap's own
   overflow:auto is the intended containment (found on the AION Index
   rebuild, latent for any page pairing two boards). */
.pair-grid>*{min-width:0}
/* .is-triple — three panels on ONE row, not two-then-an-orphan. Used by the
   cross-timeframe compare (1H/4H/1D). Drops straight to a single column at
   980px: a 2-up fallback would reintroduce the orphan row it exists to fix. */
.pair-grid.is-triple{grid-template-columns:repeat(3,1fr)}
@media (max-width:980px){.pair-grid.is-triple{grid-template-columns:1fr}}
/* At a third of the width the canvas' intrinsic 300x180 ratio renders tall and
   narrow. Pin a wider ratio so the three read as a row of charts, and let the
   4-column board inside drop its 760px floor — it has no wide cells, so it
   fits the track instead of horizontally scrolling in every panel. */
.pair-grid.is-triple .plot.is-auto > canvas{aspect-ratio:16/9}
.pair-grid.is-triple .board{min-width:0}

/* -- 6g-2. Prose — paragraph rhythm for documentation content. The §3 reset
      zeroes every margin, which is right for panels and wrong for reading.
      Scoped: only content that declares itself prose gets rhythm. */
.prose>*+*{margin-top:var(--s-4)}
.prose p+p,.prose p+.kv-list,.prose .kv-list+p{margin-top:var(--s-3)}
.prose p{color:var(--fg-2);font-size:var(--t-sm);line-height:1.7}
.prose strong{color:var(--fg);font-weight:600}
.prose em{color:var(--fg)}

/* -- 6g-3. Key/value rows — a labelled definition list (guide entries,
      glossaries, reference ladders). Lighter than its card, per SHELL §3. */
.kv-list{display:flex;flex-direction:column;gap:var(--s-2)}
.kv-row{display:grid;grid-template-columns:170px 1fr;gap:var(--s-4);
  padding:10px var(--s-4);background:var(--surface-3);border-radius:var(--r-md);
  align-items:start}
@media (max-width:600px){.kv-row{grid-template-columns:1fr;gap:2px}}
/* Narrow-card variant. The fixed 170px label column suits a wide definition
   list (the guide); inside a four-across dashboard card it starves the value
   cell, wrapping badges and two-word states onto a second line. The label
   sizes to content and the value right-aligns on the same baseline. */
.kv-row.is-fit{grid-template-columns:auto minmax(0,1fr)}
.kv-row.is-fit>:last-child{justify-self:end;text-align:right}
/* Sparkline variant (velocity rows): label | track | value | change, and the
   TRACK is the only column that flexes. is-fit starved the value cell under
   its widest label and the fixed-width canvas pushed the change figure out
   of the row ("Global liquidity level" +1.3 / 5, D-114). Here a level-style
   value (455.9) or a wide change (+17.2 / 5) takes the width it needs, the
   sparkline gives it up, and the figures never wrap or leave the row; only
   the label may wrap. max-width caps the canvas between repaints so a resize
   can squeeze the drawing but never the row. */
.kv-row.is-spark{grid-template-columns:auto minmax(36px,1fr) auto auto;
  gap:var(--s-3);align-items:center}
.kv-row.is-spark .kv-sp{min-width:0;display:flex;justify-content:flex-end}
.kv-row.is-spark .kv-sp canvas{max-width:100%}
.kv-row.is-spark .kv-v,.kv-row.is-spark .kv-d{white-space:nowrap;justify-self:end;
  font-family:var(--f-num);font-variant-numeric:tabular-nums}
/* A series the profile does not carry: one sentence where the figures would
   be, no sparkline, no dangling "/ 5" (D-116). */
.kv-row.is-spark .kv-na{grid-column:2/-1;justify-self:end;font-size:var(--t-xs)}
.kv-k{font-family:var(--f-num);font-size:var(--t-xs);font-weight:600;color:var(--fg);
  line-height:1.5}
.kv-v{color:var(--fg-2);font-size:var(--t-xs);line-height:1.65;min-width:0}

/* Anchored cards: the shared header is FIXED, so a #fragment jump must land
   the card title below it, not underneath it. Measured heights: 178-205px
   with the nav grid open (>900px viewports), 55px collapsed. Erring tall
   only adds air above the target; erring short hides the title. */
.card[id]{scroll-margin-top:218px}
@media (max-width:900px){.card[id]{scroll-margin-top:68px}}

/* -- 6g-4. Card grid — the dashboard's 3-up card field. 320px min keeps the
      dense widgets (probability bars, model rows, health tables) legible;
      tracks drop to 2, then 1, as the viewport narrows. */
.card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:var(--s-5);align-items:stretch}
.card-grid>*{min-width:0}
/* A card that needs the whole row (boards, ladders, streams) opts in with
   .is-wide; everything else packs the auto-fit columns. */
.card-grid>.is-wide{grid-column:1/-1}
/* The middle size (D-154): two grid tracks, so a pair of .is-mid cards share
   a row on the common 4-track desk. Below 940px the grid may only have one
   track, and a forced span would mint an implicit overflow column — so
   narrow viewports snap .is-mid to the full row instead. Still grid-snap,
   never free pixels (D-128). */
.card-grid>.is-mid{grid-column:1/-1}
@media (min-width:940px){.card-grid>.is-mid{grid-column:span 2}}

/* -- 6u. Star / watchlist affordance (aion_watch.js). Stateful chrome, not
      data: quiet off, --warn on — a bookmark, never a direction. */
.star-btn{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;margin-right:4px;padding:0;vertical-align:-3px;
  background:transparent;border:0;border-radius:var(--r-sm);cursor:pointer;
  color:var(--fg-4)}
.star-btn svg{fill:none;stroke:currentColor;stroke-width:1.3}
.star-btn:hover{color:var(--fg-2);background:var(--surface-3)}
.star-btn.is-on{color:var(--warn)}
.star-btn.is-on svg{fill:currentColor;stroke:none}
@media (max-width:600px){.card-grid{grid-template-columns:1fr;gap:var(--s-3)}}

/* -- 6g-5. Overlay dialog — the shared modal. One scrim, one dialog frame,
      opened with .is-open. The dialog is a card that scrolls its own body;
      the page behind never scrolls sideways. */
.overlay{position:fixed;inset:0;display:none;background:rgba(8,10,15,.88);
  z-index:1000;overflow-y:auto;-webkit-overflow-scrolling:touch}
.overlay.is-open{display:block}
.dialog{max-width:960px;margin:32px auto;background:var(--surface-2);
  border:1px solid var(--rule-edge);border-radius:var(--r-lg);
  padding:var(--s-6);width:calc(100% - 32px)}
.dialog-h{display:flex;justify-content:space-between;align-items:center;
  gap:var(--s-4);margin-bottom:var(--s-4);padding-bottom:var(--s-3);
  border-bottom:1px solid var(--rule-edge)}
.dialog-h h2{font-size:var(--t-md);font-weight:600;color:var(--accent)}
.dialog-body{overflow-x:auto;max-height:70vh}
@media (max-width:600px){.dialog{margin:12px auto;padding:var(--s-4)}}

/* -- 6g-6. Veil — an in-place overlay for a panel whose data is loading or
      absent on the active timeframe. Parent declares [data-tf-aware]. */
[data-tf-aware]{position:relative}
.veil{position:absolute;inset:0;display:none;align-items:center;justify-content:center;
  background:rgba(8,10,15,.92);border-radius:var(--r-md);padding:24px;text-align:center;z-index:5}
.veil.is-on{display:flex}
.veil-msg{color:var(--fg-2);font-size:var(--t-sm);line-height:1.55;max-width:280px}

/* -- 6g-7. Pill stack — a two-line ranked pill (ticker over price). Accent
      frame for the strong side, down frame for the weak side. */
.pill-stack{display:inline-flex;flex-direction:column;align-items:center;
  padding:6px 10px 5px;border-radius:var(--r-full);min-width:64px;cursor:default;
  font-family:var(--f-num);font-variant-numeric:tabular-nums;
  background:var(--accent-dim);border:1px solid var(--accent-line)}
.pill-stack.is-down{background:rgba(224,90,90,.08);border-color:rgba(224,90,90,.25)}

/* -- 6t. Regime composite — the macro-regime / breadth-omen chrome: three
      ratio cards, a composite meter and a methodology fold. Flat fills only;
      the old gradient tracks and glow dots died with the page stylesheet. */
.mr-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;flex-wrap:wrap;gap:10px}
.mr-header-left h2{color:var(--accent);margin:0}
.mr-header-left .mr-sub{font-size:var(--t-2xs);color:var(--fg-2);font-family:var(--f-num);margin-top:2px}
.mr-header-right{display:flex;align-items:center;gap:14px}
.mr-score{font-family:var(--f-num);font-size:var(--t-xl);font-weight:700;line-height:1}
.mr-pill{font-size:var(--t-3xs);font-weight:700;letter-spacing:1.5px;padding:5px 16px;border-radius:var(--r-sm)}
.mr-pill.off{background:var(--down);color:var(--fg)}.mr-pill.on{background:var(--up);color:var(--bg)}
.mr-pill.warn,.mr-badge.warn{background:var(--warn);color:var(--bg)}
.mr-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:14px}
@media (max-width:900px){.mr-grid{grid-template-columns:1fr}.mr-comp-row{flex-wrap:wrap}.mr-spark{width:100%;height:48px;margin-top:8px}}
.mr-card{background:var(--surface-3);border:1px solid var(--rule-hair);border-radius:var(--r-md);padding:12px 14px 6px}
.mr-card-top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:6px}
.mr-card-name{font-size:var(--t-sm);font-weight:700;color:var(--fg)}
.mr-card-desc{font-size:var(--t-3xs);color:var(--fg-2);font-family:var(--f-num);margin-top:1px}
.mr-badge{font-size:var(--t-3xs);font-weight:700;letter-spacing:1.2px;padding:3px 10px;border-radius:var(--r-sm)}
.mr-badge.on{background:var(--up);color:var(--bg)}.mr-badge.off{background:var(--down);color:var(--fg)}
.mr-stats{display:flex;gap:6px;font-family:var(--f-num);font-size:var(--t-3xs);color:var(--fg-2);margin-bottom:8px;align-items:baseline;flex-wrap:wrap}
.mr-stats .v{color:var(--fg);font-weight:700}.mr-stats .pct{font-weight:700;font-size:var(--t-2xs)}.mr-stats .wt{margin-left:auto;font-size:var(--t-3xs);opacity:.5}
.mr-chart-wrap{width:100%;height:150px;position:relative}.mr-chart-wrap canvas{width:100%;height:100%;display:block}
.mr-comp{background:var(--surface-3);border:1px solid var(--rule-hair);border-radius:var(--r-md);padding:14px 18px 12px}
.mr-comp-row{display:flex;align-items:center;gap:18px}
.mr-comp-left{min-width:110px}
.mr-comp-label{font-size:var(--t-3xs);font-weight:700;letter-spacing:1.5px;color:var(--fg-2);margin-bottom:6px}
.mr-dots{display:flex;gap:12px}
.mr-dot-item{display:flex;align-items:center;gap:4px;font-size:var(--t-3xs);font-family:var(--f-num);color:var(--fg-2)}
.mr-dot{width:7px;height:7px;border-radius:50%}
.mr-dot.on{background:var(--up)}.mr-dot.off{background:var(--down)}
.mr-gauge-wrap{flex:1;min-width:0;overflow:hidden}
.mr-gauge-track{width:100%;height:22px;border-radius:2px;position:relative;background:var(--surface-2);border:1px solid var(--rule-hair)}
.mr-gauge-fill{position:absolute;top:0;left:0;height:100%;border-radius:2px}
.mr-gauge-thresh{position:absolute;top:-5px;bottom:-5px;width:2px;border-radius:1px;background:var(--warn);z-index:2}
.mr-gauge-marker{position:absolute;top:50%;transform:translate(-50%,-50%);width:14px;height:14px;background:var(--fg);border-radius:50%;border:2.5px solid var(--bg);z-index:3}
.mr-gauge-labels{display:flex;justify-content:space-between;margin-top:3px;font-size:var(--t-3xs);font-family:var(--f-num);color:var(--fg-2);opacity:.6}
.mr-spark{width:180px;height:48px;flex-shrink:0}.mr-spark canvas{width:100%;height:100%;display:block}
.mr-comp-footer{margin-top:10px;padding-top:8px;border-top:1px solid var(--rule-hair);display:flex;justify-content:space-between;align-items:flex-start;gap:16px}
.mr-interp{font-size:var(--t-3xs);color:var(--fg-2);line-height:1.5;flex:1}
.mr-method-toggle{font-size:var(--t-3xs);color:var(--fg-2);cursor:pointer;font-family:var(--f-num);text-decoration:underline dotted;flex-shrink:0;margin-top:2px}
.mr-method-toggle:hover{color:var(--fg)}
.mr-method-body{display:none;margin-top:12px;padding:14px;background:var(--surface-3);border:1px solid var(--rule-hair);border-radius:var(--r-md);font-size:var(--t-3xs);color:var(--fg-2);font-family:var(--f-num);line-height:1.7}
.mr-method-body.open{display:block}.mr-method-body b{color:var(--fg);font-weight:600}
.cc-readout{display:flex;gap:8px;font-family:var(--f-num);font-size:var(--t-3xs);color:var(--fg-2);margin-bottom:8px;align-items:baseline;flex-wrap:wrap}
.cc-readout .v{font-weight:700}
.cc-lights{display:flex;gap:5px;flex-wrap:wrap;margin-top:8px;margin-bottom:4px}
.cc-light{display:flex;align-items:center;gap:4px;font-size:var(--t-3xs);font-family:var(--f-num);color:var(--fg-3);padding:2px 6px;border-radius:2px;background:var(--surface-3);border:1px solid var(--rule-hair)}
.cc-led{width:6px;height:6px;border-radius:50%}
.cc-led.on{background:var(--up)}
.cc-led.off{background:var(--surface-2)}
.cc-postrack{flex:1;min-width:0;height:22px;border-radius:2px;position:relative;background:var(--surface-2);border:1px solid var(--rule-hair);margin-top:40px}
.cc-pdot{position:absolute;top:50%;transform:translate(-50%,-50%);width:12px;height:12px;border-radius:50%;border:2px solid var(--bg);z-index:3}
.cc-plabel{position:absolute;top:-13px;transform:translateX(-50%);font-size:var(--t-3xs);font-family:var(--f-num);color:var(--fg-2);white-space:nowrap;z-index:4}
.cc-pthresh{position:absolute;top:-5px;bottom:-5px;width:2px;border-radius:1px;background:var(--warn);z-index:2}
.cc-modetog{display:inline-flex;border:1px solid var(--rule-edge);border-radius:var(--r-sm);overflow:hidden;font-family:var(--f-num);font-size:var(--t-3xs);letter-spacing:.6px;margin-right:10px;vertical-align:middle}
.cc-mode-opt{padding:4px 11px;color:var(--fg-3);cursor:pointer;background:var(--surface-3)}
.cc-mode-opt:hover{color:var(--fg-2)}
.cc-mode-opt.active{background:var(--surface-2);color:var(--accent);font-weight:700}
.cc-mode-opt+.cc-mode-opt{border-left:1px solid var(--rule-hair)}
/* Internals: three breadth tables side by side, one column on narrow
   viewports; the sparkline pair stacks the same way. */
.mi-th{text-align:center;font-size:var(--t-3xs);color:var(--fg-3);font-weight:500;
  padding:2px 4px;text-transform:uppercase;letter-spacing:.5px}
.mi-cell{text-align:center;padding:8px 4px;border-radius:3px;font-size:var(--t-sm);
  font-weight:700;font-family:var(--f-num);font-variant-numeric:tabular-nums;min-width:40px}
.mi-tables{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.mi-pair{display:flex;gap:16px}
@media (max-width:900px){.mi-tables{grid-template-columns:1fr}.mi-pair{flex-direction:column}}

/* -- 6h. Tag — a small state label. Text and a hairline, never an emoji,
      never a filled pill of brand colour. Tones are semantic only. */
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:var(--r-full);
  border:1px solid var(--rule-edge);font-family:var(--f-num);font-size:var(--t-3xs);
  letter-spacing:.1em;text-transform:uppercase;color:var(--fg-3);white-space:nowrap}
/* A tag riding a title (the DAILY / 1D cadence badges) gets air and sits on
   the title's optical midline instead of gluing to the last glyph. */
.card-title .tag,h2 .tag,h3 .tag{margin-left:10px;vertical-align:middle;
  position:relative;top:-2px}
.tag-up{border-color:rgba(46,163,123,.42);color:var(--up)}
.tag-down{border-color:rgba(224,90,90,.42);color:var(--down)}
.tag-warn{border-color:rgba(217,164,65,.42);color:var(--warn)}
.tag-accent{border-color:var(--accent-line);color:var(--accent)}

/* -- 6h-2. Chips — a SELECTABLE list of variable length. Distinct from .seg,
      which is a segmented control for 2–4 fixed, mutually-exclusive views and
      is uppercase by design. A chip list is data: it can hold one item or
      twenty, its labels are sentence case (SHELL.md §4 — caps are for state
      flags only), and it wraps. Written for the setups Analogues detects on
      today's bar; every page with a variable pick-list uses THIS, not a
      near-identical private one (D-32). */
.chips{display:flex;flex-wrap:wrap;gap:var(--s-2);justify-content:center}
.chip{display:inline-flex;align-items:center;gap:var(--s-2);
  padding:7px var(--s-3);background:var(--surface-2);
  border:1px solid var(--rule-edge);border-radius:var(--r-lg);
  color:var(--fg-2);font-family:var(--f-ui);font-size:var(--t-xs);
  line-height:1.2;cursor:pointer;white-space:nowrap;
  transition:background .12s,border-color .12s,color .12s}
.chip:hover{background:var(--surface-3);color:var(--fg)}
.chip.is-on{background:var(--surface-3);color:var(--fg);border-color:var(--accent-line)}
.chip.is-on::before{content:'';width:2px;align-self:stretch;margin:-1px 2px -1px -2px;
  background:var(--accent);border-radius:1px}
@media (max-width:600px){.chip{font-size:var(--t-2xs)}}

/* -- 6i. Feed — a list of dated external items (headlines, filings, prints). */
.feed{display:flex;flex-direction:column}
.feed-item{padding:var(--s-4) 0;border-top:1px solid var(--rule-hair)}
.feed-item:first-child{border-top:0;padding-top:0}
.feed-t{display:block;font-size:var(--t-sm);font-weight:500;line-height:1.45;
  color:var(--fg);border-bottom:1px solid transparent}
a.feed-t:hover{color:var(--accent);border-bottom-color:var(--accent-line)}
.feed-m{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2) var(--s-3);
  margin-top:var(--s-2);font-family:var(--f-num);font-size:var(--t-3xs);
  letter-spacing:.06em;color:var(--fg-4)}
.feed-d{margin-top:var(--s-2);font-size:var(--t-xs);line-height:1.6;color:var(--fg-3)}

/* -- 6j. Trend strip — a quarterly/periodic bar trajectory with a real zero
      baseline, so a loss reads as a bar below the line rather than a short
      one. Values live in the table above it; the strip carries shape only. */
.trend-grid{display:grid;gap:var(--s-3);grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.trend-row{display:flex;align-items:stretch;gap:2px;height:104px}
.trend-cell{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:space-between}
.trend-bar-wrap{position:relative;height:80px}
.trend-base{position:absolute;left:0;right:0;height:1px;background:var(--rule-edge)}
.trend-bar{position:absolute;left:12%;right:12%;background:var(--accent);border-radius:1px}
.trend-bar.down{background:var(--down)}
.trend-cell:hover .trend-bar{outline:1px solid var(--fg-3)}
.trend-p{height:14px;text-align:center;overflow:hidden;white-space:nowrap;
  font-family:var(--f-num);font-variant-numeric:tabular-nums;font-size:var(--t-3xs);
  color:var(--fg-4);letter-spacing:.02em}
@media (max-width:600px){.trend-row{height:92px}.trend-bar-wrap{height:70px}}

/* -- 6k. Meta block — the identity footer of a detail view (who this
      company/instrument is). Prose, not data: UI font, no tabular figures. */
.meta-row{display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-5);align-items:baseline;
  font-size:var(--t-xs);color:var(--fg-3)}
.meta-name{font-size:var(--t-base);font-weight:600;color:var(--fg)}
.meta-row a{color:var(--fg-2);border-bottom:1px solid var(--rule-edge)}
.meta-row a:hover{color:var(--accent);border-bottom-color:var(--accent-line)}
.meta-d{margin-top:var(--s-3);font-size:var(--t-xs);line-height:1.7;color:var(--fg-3)}

/* -- 6l. States. Written like a person, never like a stack trace. */
.state{text-align:center;padding:var(--s-16) var(--s-4);color:var(--fg-3);font-size:var(--t-sm)}
.state-err{color:var(--fg-2)}
.state-err b{display:block;color:var(--fg);font-weight:600;margin-bottom:var(--s-2)}

/* -- 6l-2. A card header may carry a control. The title block takes the space
      it needs and the control sits at the far end, so a scope switch that
      governs the whole card lives in its header instead of eating a row of
      body. Wraps to its own line under 600px. */
.card-h>.seg{flex:none;align-self:flex-start}
@media (max-width:600px){
  .card-h{flex-wrap:wrap}
  .card-h>.seg{width:100%}
  /* A header carrying a CONTROL PAIR stacks on phones: .card-h-t is
     min-width:0/flex:1, so two ~140px selects starved the title column to
     ~65px and 'Blended magnets' + its subtitle rendered one word per line
     (390px audit, 2026-08-08) — hundreds of px of dead height. Scoped with
     :has to headers that hold a .ctl-pair; a plain timestamp slot keeps
     today's single-row header. Engines without :has keep current behavior,
     which renders, just narrow. */
  .card-h:has(>.ctl-pair) .card-h-t{flex:1 1 100%}
  .card-h>.ctl-pair{flex-wrap:wrap}
  .card-h>.ctl-pair .select{flex:1;min-width:0}
  /* The timestamp slot is nowrap by design; on phones a long provenance
     string ("Positioning as of …") starved the title column the same way
     the control pair did (options velocity card, 109px title, 225px tall).
     At phone widths every card timestamp takes its own quiet line under
     the title instead of competing with it for a 390px row. */
  .card-h .card-ts{flex:1 1 100%;order:2;white-space:normal;padding-top:0}
}

/* -- 6m. Canvas scrollport. A chart that is genuinely wider than the page
      (a strike ladder against an expiry ladder) scrolls INSIDE its own box.
      The page itself must never scroll sideways, so this is the boundary.
      Both axes pan, with momentum on touch and the scroll chain stopped so a
      pan inside the matrix does not drag the page behind it. */
/* overscroll-behavior is per-axis on purpose (D-62). `contain` on BOTH axes
   made the box a scroll trap: a wheel gesture inside it could never chain back
   to the page, so once the pointer was over the matrix the page stopped
   scrolling. Horizontal stays contained, because a sideways pan across strikes
   should not drag the page; vertical chains normally once the box hits its
   end, which is what a reader expects from a tall panel. */
.canvas-wrap{width:100%;overflow:auto;max-height:calc(100svh - 220px);
  -webkit-overflow-scrolling:touch;touch-action:pan-x pan-y;
  overscroll-behavior-x:contain;overscroll-behavior-y:auto;
  border:1px solid var(--rule-edge);border-radius:var(--r-md);background:var(--bg)}
/* The §3 reset puts max-width:100% on every canvas, which is right for a
   figure and wrong for a matrix: it squeezed a 2004px heatmap into the 1340px
   container, so the drawing ran out before the last expiry and the sticky
   overlays blitted from coordinates that no longer matched. Inside a
   scrollport the canvas keeps its true width and the BOX scrolls. */
.canvas-wrap canvas{display:block;max-width:none;background:var(--bg)}
/* ECharts measures its container, so a height has to exist before it draws.
   A zero-height div renders a chart with no pixels and no error. */
#gp-chart{width:100%;height:340px}
@media (max-width:600px){#gp-chart{height:260px}}
/* A second scrollbar pinned to the TOP of the scrollport, synced to the real
   one. Without it the only way to pan a tall matrix sideways is to scroll to
   the bottom of it first. Injected by the page, styled once here. */
.canvas-topscroll{position:sticky;top:0;z-index:5;background:var(--bg)}
/* The sticky header and strike-column overlays blit out of the heatmap canvas,
   so they are pixel-identical to it by construction and can never drift.
   z-index orders them: the header owns the corner. */
#hm-header-overlay{position:sticky;top:0;left:0;z-index:4;display:block;
  pointer-events:none;background:var(--bg)}
#hm-strike-overlay{position:sticky;left:0;z-index:3;display:block;
  pointer-events:none;background:var(--bg)}
@media (max-width:600px){.canvas-wrap{max-height:calc(100svh - 150px)}}

/* -- 6n. A chip row that scrolls rather than wraps, for a strip that is
      chronological: wrapping a date sequence onto three lines destroys the
      one thing it encodes. */
.chips-scroll{flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;
  padding-bottom:var(--s-2);-webkit-overflow-scrolling:touch;touch-action:pan-x}
.chips-scroll .chip{flex:none}
/* Direction glyph inside a table label. Sized down: it is a marker, not a
   value, and at full size it competes with the number beside it. */
.lv-dir{font-size:var(--t-3xs);color:var(--fg-4)}

/* -- 6o. Plot — a chart that SIZES TO ITS CONTAINER, as opposed to §6m's
      scrollport, which is for a canvas genuinely wider than the page. The
      distinction matters: a heatmap has a true pixel width and the box
      scrolls; a projection cone has no natural width and must redraw at
      whatever width it is given.

      The frame owns the height so the canvas has something to measure before
      it draws — a canvas in an auto-height parent reports clientHeight 0 and
      renders nothing, with no error. Three children stack in one grid cell:
      the base canvas, an overlay canvas for hover (so a mousemove never
      re-runs the simulation underneath), and a floating readout. */
.plot{position:relative;width:100%;height:420px;
  border:1px solid var(--rule-edge);border-radius:var(--r-md);background:var(--bg)}
.plot > canvas{position:absolute;inset:0;display:block;width:100%;height:100%}
.plot > canvas + canvas{pointer-events:none}
.plot > .state{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;text-align:center;padding:var(--s-6)}
@media (max-width:980px){.plot{height:360px}}
@media (max-width:600px){.plot{height:300px}}
/* -- 6u. Level map — a vertical price ladder of NAMED levels (D-127).
      Rungs are evenly spaced and sorted by price; the distance column
      carries the geometry, because a to-scale ladder would spend most of
      its height on empty price ranges. One rung per strike; roles merge. */
.lvl-list{border:1px solid var(--rule-edge);border-radius:var(--r-md);overflow:hidden}
.lvl-row{display:grid;grid-template-columns:96px minmax(0,1fr) auto 76px;gap:var(--s-3);
  align-items:center;padding:9px var(--s-3);border-bottom:1px solid var(--rule-hair);
  font-family:var(--f-num);font-variant-numeric:tabular-nums}
.lvl-row:last-child{border-bottom:0}
.lvl-price{font-size:var(--t-sm);font-weight:600;text-align:right;color:var(--fg)}
.lvl-roles{display:flex;gap:6px;flex-wrap:wrap;align-items:center;min-width:0}
.lvl-fig{font-size:var(--t-xs);text-align:right;white-space:nowrap}
.lvl-dist{font-size:var(--t-3xs);color:var(--fg-3);text-align:right;white-space:nowrap}
.lvl-row.is-spot{background:var(--accent-surface)}
.lvl-row.is-spot .lvl-price{color:var(--accent)}

/* -- 6w. Compare grid (D-131): 2-4 ladder columns, each on its OWN price
      scale, its own timestamp. Stacks on phones — never crush (D-123). */
.cmp-grid{display:grid;grid-template-columns:repeat(var(--cmp-n,3),minmax(0,1fr));gap:var(--s-4)}
@media (max-width:980px){.cmp-grid{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}}
@media (max-width:600px){.cmp-grid{grid-template-columns:1fr}}
.cmp-h{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s-2);
  margin-bottom:var(--s-2)}
.cmp-h b{font-size:var(--t-sm);font-weight:600}
.cmp-ts{font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-3xs);color:var(--fg-3);white-space:nowrap}
.cmp-meta{margin-top:var(--s-2);font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-3xs);color:var(--fg-3);display:flex;gap:var(--s-3);flex-wrap:wrap}
.cmp-pickers{position:relative}
/* The mini positioning map: a DOM strike x expiry grid, one per column.
   Small boxes by design — Joey's words — with the big map's rules in
   miniature: per-column colour scale, star on the column max, spot row
   ringed, D-93 signal dimming. */
.cmpx{display:grid;gap:1px;font-family:var(--f-num);font-variant-numeric:tabular-nums;
  font-size:var(--t-3xs)}
.cmpx-h{color:var(--fg-3);text-align:center;padding:2px 0 4px;font-weight:600;
  letter-spacing:.04em}
.cmpx-s{color:var(--fg-2);text-align:right;padding:3px 6px 3px 0}
.cmpx-s.is-spot{color:var(--accent);font-weight:600}
.cmpx-c{text-align:right;padding:3px 4px;border-radius:2px;white-space:nowrap;
  overflow:hidden;color:var(--fg);background:var(--surface-3)}
.cmpx-c.is-spot{box-shadow:inset 0 0 0 1px var(--accent-line)}
.cmpx-c i{font-style:normal;margin-left:2px}
.cmpx-c.cmpx-dim{color:var(--fg-2);opacity:.45;background:transparent}

/* -- 6v. Drag drop target (D-128) — an accent INSERTION EDGE on the hovered
      card, not a highlight box: it says "the card will land on this side". */
.card-grid>.drop-before{box-shadow:-3px 0 0 0 var(--accent)}
.card-grid>.drop-after{box-shadow:3px 0 0 0 var(--accent)}
.card-grid>.is-wide.drop-before{box-shadow:0 -3px 0 0 var(--accent)}
.card-grid>.is-wide.drop-after{box-shadow:0 3px 0 0 var(--accent)}
@media (max-width:600px){
  .card-grid>.drop-before{box-shadow:0 -3px 0 0 var(--accent)}
  .card-grid>.drop-after{box-shadow:0 3px 0 0 var(--accent)}
}
@media (max-width:600px){
  .lvl-row{grid-template-columns:72px minmax(0,1fr) auto;gap:var(--s-2)}
  .lvl-row .lvl-dist{display:none}
}

/* -- Plot scrollport. On phones a 210-day timeline crushed into ~320px is
      unreadable; the timeline SCROLLS sideways instead (the D-62 rule: the
      page never scrolls, the box does). Wrap a .plot in .plot-scroll and on
      phones the plot keeps a real drawing width and gains height; render
      code reads clientWidth as usual and simply draws wider. Desktop is
      untouched: the wrapper is inert above 600px. */
@media (max-width:600px){
  .plot-scroll{overflow-x:auto;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch}
  .plot-scroll>.plot{min-width:560px;height:400px}
}
/* Some renderers compute their own height from the data (a 252-step series
   needs more room than a 63-step one). Those own the height; the frame just
   supplies the width and the border. */
.plot.is-auto{height:auto}
.plot.is-auto > canvas{position:static;width:100%;height:auto}
/* Floating readout pinned inside the plot. Same vocabulary as .tip-b, but
   positioned by script from a cursor coordinate rather than by CSS from an
   anchor, which is why it cannot reuse it. */
.plot-tip{position:absolute;z-index:3;pointer-events:none;display:none;
  background:var(--surface-3);border:1px solid var(--rule-edge);
  border-radius:var(--r-md);padding:var(--s-2) var(--s-3);
  font-family:var(--f-num);font-size:var(--t-2xs);line-height:1.4;
  color:var(--fg-2);white-space:nowrap}
.plot-tip b{display:block;color:var(--fg);font-weight:600}

/* -- 6p. Chips pane — a bounded, scrolling region for a chip list too long
      to lay flat. A profile of 1,338 names is still every name; it just
      stops being a wall that buries the panel underneath it. */
.chips-pane{max-height:132px;overflow-y:auto;overscroll-behavior-y:contain;
  padding:var(--s-3);border:1px solid var(--rule-hair);
  border-radius:var(--r-md);background:var(--bg)}
@media (max-width:600px){.chips-pane{max-height:112px}}

/* -- 6q. Card export — the Copy Image affordance (aion_copy.js). One button
      per data card, seated in the header beside the timestamp slot. The
      exported PNG is the product's ad (pillar 3): the module draws the brand
      band, page · widget line, capture stamp and compliance line around the
      card. Quiet at rest, accent on approach, --up when done — the same
      grammar as every other control. */
.card-copy{flex:none;margin-left:auto;display:inline-flex;align-items:center;
  justify-content:center;width:26px;height:26px;padding:0;background:none;
  border:1px solid var(--rule-edge);border-radius:var(--r-lg);color:var(--fg-3);
  cursor:pointer;transition:color var(--d) var(--e),border-color var(--d) var(--e),
  background var(--d) var(--e)}
.card-copy:hover,.card-copy:focus-visible{color:var(--accent);
  border-color:var(--accent-line);background:var(--accent-surface)}
.card-copy.is-busy{color:var(--fg-3);pointer-events:none}
.card-copy.is-done{color:var(--up)}
.card-copy.is-fail{color:var(--down)}
.card-copy svg{width:15px;height:15px;display:block}
/* Cards whose header is bespoke chrome (terminal macro/internals) have no
   .card-h; the button floats to the same visual seat instead. The relative
   is scoped to opted-in cards so no other card's stacking changes. */
.card[data-copy]{position:relative}
.card-copy.is-float{position:absolute;top:var(--s-4);right:var(--s-4);z-index:5}
html.aion-copy-hidden .card-copy{display:none!important}

/* -- 6r. Labelled chip group — a micro-label above a wrapping row of ticker
      chips, left-aligned under its label (the default .chips centering is
      for pick-lists under a centered picker). The turnover/entrants shape. */
.chip-group{margin-bottom:var(--s-5)}
.chip-group:last-child{margin-bottom:0}
.chip-group .metric-k{margin-bottom:var(--s-2)}
.chip-group .chips{justify-content:flex-start}

/* ==========================================================================
   §8. NEON MODE — an opt-in theme (D-89). The default look stays the locked
   premium-restraint palette; this block only exists behind an attribute the
   user sets from the terminal's Account menu. It re-tints the TOKENS, so
   every component, chart and canvas follows (canvases resolve tokens at
   load; the toggle reloads). Electric cyan/green/pink, bluer surfaces, and
   a measured glow layer — the pre-redesign voltage, by choice not default.
   ========================================================================== */
html[data-aion-theme="neon"]{
  --bg:#05070d; --surface:#0a0f1a; --surface-2:#0e1524; --surface-3:#141c30;
  --line:rgba(0,229,255,.10); --line-strong:rgba(0,229,255,.22);
  --rule-hair:rgba(0,229,255,.09); --rule-edge:rgba(0,229,255,.20);
  --fg-2:var(--n-200); --fg-3:var(--n-300);
  --up:#00e676; --up-dim:rgba(0,230,118,.16);
  --down:#ff4d6d; --down-dim:rgba(255,77,109,.16);
  --warn:#ffd740;
  --accent:#00e5ff; --accent-hi:#5ff3ff;
  --accent-dim:rgba(0,229,255,.14); --accent-line:rgba(0,229,255,.5);
  --accent-surface:#0a2233; --accent-surface-2:#0e2c42;
}
/* The glow layer: only where a state or a number already carries meaning. */
html[data-aion-theme="neon"] .up{text-shadow:0 0 12px rgba(0,230,118,.35)}
html[data-aion-theme="neon"] .down{text-shadow:0 0 12px rgba(255,77,109,.35)}
html[data-aion-theme="neon"] .warn{text-shadow:0 0 12px rgba(255,215,64,.30)}
html[data-aion-theme="neon"] .metric-v{text-shadow:0 0 16px rgba(0,229,255,.16)}
html[data-aion-theme="neon"] .page-title{text-shadow:0 0 28px rgba(0,229,255,.22)}
html[data-aion-theme="neon"] .card-title{text-shadow:0 0 14px rgba(0,229,255,.20)}
html[data-aion-theme="neon"] .tag-up{box-shadow:0 0 10px rgba(0,230,118,.22)}
html[data-aion-theme="neon"] .tag-down{box-shadow:0 0 10px rgba(255,77,109,.22)}
html[data-aion-theme="neon"] .tag-warn{box-shadow:0 0 10px rgba(255,215,64,.20)}
html[data-aion-theme="neon"] .tag-accent{box-shadow:0 0 10px rgba(0,229,255,.22)}
html[data-aion-theme="neon"] .seg-btn.is-on{box-shadow:0 0 12px rgba(0,229,255,.30)}
html[data-aion-theme="neon"] .chip.is-on{box-shadow:0 0 10px rgba(0,229,255,.25)}
html[data-aion-theme="neon"] .card:hover{box-shadow:0 0 26px rgba(0,229,255,.09)}
html[data-aion-theme="neon"] .mr-pill.on,html[data-aion-theme="neon"] .mr-badge.on{box-shadow:0 0 12px rgba(0,230,118,.35)}
html[data-aion-theme="neon"] .mr-pill.off,html[data-aion-theme="neon"] .mr-badge.off{box-shadow:0 0 12px rgba(255,77,109,.35)}
html[data-aion-theme="neon"] .mr-pill.warn,html[data-aion-theme="neon"] .mr-badge.warn{box-shadow:0 0 12px rgba(255,215,64,.30)}
html[data-aion-theme="neon"] .cc-led.on{box-shadow:0 0 6px rgba(0,230,118,.6)}
html[data-aion-theme="neon"] .pill-stack{box-shadow:0 0 10px rgba(0,229,255,.14)}
html[data-aion-theme="neon"] .pill-stack.is-down{box-shadow:0 0 10px rgba(255,77,109,.16)}
