/* ============================================================
   IQInvest — stylesheet, ported verbatim from the Claude Design
   prototype (IQInvest.dc.html).

   Deliberately ONE file in the original source order. An earlier pass split
   this into tokens/primitives/views for tidiness and broke the cascade: the
   @media overrides ended up in a file that loads before the base rules they
   are meant to override, so .note__body stopped stacking on mobile. Source
   order is load-bearing here — keep it.

   Design tokens are the .app{--…} block near the top; edit colours there.
   Fixes made after porting are marked "ported-fix" with the reason.
   ============================================================ */

*,*::before,*::after{box-sizing:border-box}
*,input,button,select,textarea{font-family:inherit}
html,body{overflow-x:clip;max-width:100%}
body{margin:0;background:#fff}
.app{--bg:#FFFFFF;--surface:#F7F8FA;--surface-2:#F2F4F7;--card:#FFFFFF;--border:#E3E7ED;--border-strong:#CBD3DE;--text:#0F172A;--text-muted:#475569;--text-subtle:#5E6C7F;--brand:#12459E;--brand-hover:#0E3578;--brand-soft:#EAF0FA;--on-brand:#FFFFFF;--positive:#0F7B4F;--negative:#B42318;--warning:#B45309;--font-sans:'IBM Plex Sans',system-ui,sans-serif;--font-mono:'IBM Plex Mono',ui-monospace,monospace;--fs-display:44px;--fs-h1:32px;--fs-h2:24px;--fs-h3:19px;--fs-body:18px;--fs-small:15px;--fs-caption:14px;--lh-tight:1.25;--lh-body:1.55;--s-1:4px;--s-2:8px;--s-3:12px;--s-4:16px;--s-5:24px;--s-6:32px;--s-7:48px;--s-8:64px;--s-9:96px;--r-sm:8px;--r-md:12px;--r-lg:16px;--e-1:0 1px 2px rgba(15,23,42,.06);--e-2:0 4px 12px rgba(15,23,42,.08);--e-3:0 16px 40px rgba(15,23,42,.16);--dur-fast:120ms;--dur:180ms;--ease:cubic-bezier(.4,0,.2,1);--container:1200px;--header-h:64px;--card-pad:var(--s-6);--row-y:13px;--sec:var(--s-9);color-scheme:light;background:var(--bg);color:var(--text);font-family:var(--font-sans);font-size:var(--fs-body);line-height:var(--lh-body);min-height:100vh;-webkit-text-size-adjust:100%}
.app[data-theme="dark"]{--bg:#0B0F17;--surface:#121826;--surface-2:#19202F;--card:#151C2C;--border:#232C3D;--border-strong:#33405A;--text:#E8EDF5;--text-muted:#A9B4C4;--text-subtle:#7D8B9C;--brand:#7FA9F5;--brand-hover:#A3C0FF;--brand-soft:#17243B;--on-brand:#0B0F17;--positive:#3DD68C;--negative:#FF7A6B;--warning:#F0A742;--e-1:0 1px 2px rgba(0,0,0,.4);--e-2:0 4px 12px rgba(0,0,0,.5);--e-3:0 16px 40px rgba(0,0,0,.6);color-scheme:dark}
@media (prefers-color-scheme:dark){.app[data-theme="auto"]{--bg:#0B0F17;--surface:#121826;--surface-2:#19202F;--card:#151C2C;--border:#232C3D;--border-strong:#33405A;--text:#E8EDF5;--text-muted:#A9B4C4;--text-subtle:#7D8B9C;--brand:#7FA9F5;--brand-hover:#A3C0FF;--brand-soft:#17243B;--on-brand:#0B0F17;--positive:#3DD68C;--negative:#FF7A6B;--warning:#F0A742;--e-1:0 1px 2px rgba(0,0,0,.4);--e-2:0 4px 12px rgba(0,0,0,.5);--e-3:0 16px 40px rgba(0,0,0,.6);color-scheme:dark}}
.app[data-density="compact"]{--card-pad:var(--s-5);--row-y:8px;--fs-body:17px}
@media (max-width:899px){.app{--sec:var(--s-7);--card-pad:var(--s-5);--fs-display:31px;--fs-h1:25px;--fs-h2:21px}}
.app :focus{outline:none}
.app :focus-visible{outline:3px solid var(--brand);outline-offset:2px;border-radius:3px}
@media (prefers-reduced-motion:reduce){.app *,.app *::before,.app *::after{animation-duration:.01ms!important;transition-duration:.01ms!important}}
.app button,.app a,.app summary,.app input,.app select{touch-action:manipulation}
.num,.app td,.app th{font-variant-numeric:tabular-nums;font-family:var(--font-mono)}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
[hidden]{display:none!important}
.app p,.app figure{margin:0}
.app h1,.app h2,.app h3{margin:0;font-weight:700;line-height:var(--lh-tight)}
.app a{color:var(--brand);text-underline-offset:3px}
.app a:hover{color:var(--brand-hover)}
.app ul{margin:0;padding:0;list-style:none}
.skip{position:absolute;left:var(--s-4);top:-64px;z-index:60;background:var(--card);color:var(--brand);padding:var(--s-3) var(--s-4);border:1px solid var(--border-strong);border-radius:var(--r-sm);font-size:var(--fs-small);font-weight:600;text-decoration:none;transition:top var(--dur) var(--ease)}
.skip:focus{top:var(--s-3)}
.wrap{max-width:var(--container);margin:0 auto;padding-inline:var(--s-5)}
@media (max-width:899px){.wrap{padding-inline:var(--s-4)}}
.sec{padding-block:var(--sec)}
.sec--sm{padding-block:var(--s-7)}
.sec__hd{margin-bottom:var(--s-6);max-width:70ch}
.sec__h2{font-size:clamp(26px,3vw,34px);font-weight:600;letter-spacing:-.02em}
.sec__lede{margin-top:var(--s-3);color:var(--text-muted);font-size:var(--fs-small);text-wrap:pretty}
.eyebrow{font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--text-subtle)}
.hdr{position:sticky;top:0;z-index:40;height:var(--header-h);background:var(--bg);border-bottom:1px solid var(--border)}
.hdr__in{max-width:var(--container);margin:0 auto;padding-inline:var(--s-5);height:var(--header-h);display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--s-5)}
.brand{display:inline-flex;align-items:center;gap:var(--s-2);min-height:44px;color:var(--text);text-decoration:none;font-weight:700;letter-spacing:-.015em;font-size:var(--fs-body)}
.brand__mark{display:grid;place-items:center;width:30px;height:30px;border-radius:var(--r-sm);background:var(--brand);color:var(--on-brand);font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:600}
.nav{min-width:0;display:flex;gap:var(--s-1)}
.nav__link{position:relative;display:inline-flex;align-items:center;min-height:44px;padding:0 var(--s-3);font-size:var(--fs-small);font-weight:500;color:var(--text-muted);text-decoration:none;transition:color var(--dur) var(--ease),background-color var(--dur) var(--ease)}
.nav__link:hover{color:var(--text);background:var(--surface)}
.nav__link::after{content:"";position:absolute;left:var(--s-3);right:var(--s-3);bottom:0;height:2px;background:var(--border-strong);transform:scaleX(0);transform-origin:left center;transition:transform var(--dur) var(--ease),background-color var(--dur) var(--ease)}
.nav__link:hover::after{transform:scaleX(1)}
.nav__link[aria-current="page"]{color:var(--text);font-weight:600}
.nav__link[aria-current="page"]::after{background:var(--brand);transform:scaleX(1)}
.hdr__right{display:flex;align-items:center;gap:var(--s-2)}
@media (max-width:899px){.hdr__in{grid-template-columns:auto 1fr auto;padding-inline:var(--s-4)}.hdr .nav,.hdr .hdr__hide-m{display:none}}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);min-height:44px;padding:0 var(--s-5);font-size:var(--fs-small);font-weight:600;border-radius:var(--r-sm);border:1px solid transparent;background:none;color:inherit;cursor:pointer;text-decoration:none;transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.btn--primary{background:var(--brand);color:var(--on-brand)}
.btn--primary:hover{background:var(--brand-hover)}
.btn--primary:active{box-shadow:inset 0 2px 5px rgba(0,0,0,.22)}
.btn--secondary{background:var(--card);color:var(--text);border-color:var(--border-strong)}
.btn--secondary:hover{background:var(--surface);border-color:var(--text-subtle)}
.btn--ghost{color:var(--text-muted)}
.btn--ghost:hover{background:var(--surface);color:var(--text)}
.btn--sm{padding:0 var(--s-3);font-size:var(--fs-caption)}
.btn:disabled{opacity:.48;cursor:not-allowed;box-shadow:none}
.btn--primary:disabled:hover{background:var(--brand)}
.ibtn{display:inline-grid;place-items:center;flex:0 0 auto;width:44px;height:44px;border-radius:var(--r-sm);border:1px solid transparent;background:transparent;color:var(--text-muted);cursor:pointer;font-family:var(--font-mono);font-size:var(--fs-small);transition:background-color var(--dur) var(--ease),color var(--dur) var(--ease)}
.ibtn:hover,.ibtn[aria-expanded="true"]{background:var(--surface);color:var(--text)}
.spin{display:inline-block;width:13px;height:13px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:sp .7s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}
@keyframes sk{0%,100%{opacity:.5}50%{opacity:.95}}
@keyframes fu{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes su{from{transform:translateY(100%)}to{transform:none}}
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes gradeIn{from{opacity:0;transform:scale(.94) translateY(6px)}to{opacity:1;transform:none}}
@keyframes drawRule{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.menu{position:relative}
.menu__panel{position:absolute;right:0;top:calc(100% + 6px);width:262px;background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--e-3);padding:var(--s-2);z-index:50}
.menu__grp{padding:var(--s-3) var(--s-3) var(--s-1);font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle);text-transform:uppercase;letter-spacing:.08em}
.menu__sep{border-top:1px solid var(--border);margin:var(--s-2) calc(var(--s-2) * -1)}
.menu__item{display:flex;align-items:center;justify-content:space-between;gap:var(--s-3);width:100%;min-height:44px;padding:0 var(--s-3);border:0;border-radius:var(--r-sm);background:transparent;color:var(--text);font-size:var(--fs-small);font-family:inherit;text-align:left;text-decoration:none;cursor:pointer;transition:background-color var(--dur-fast) var(--ease)}
.menu__item:hover{background:var(--surface)}
.menu__kbd{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle)}
.scrim{position:fixed;inset:0;background:rgba(11,15,23,.5);z-index:55;border:0;padding:0;animation:fu var(--dur) var(--ease)}
.sheet{position:fixed;left:0;right:0;bottom:0;z-index:56;background:var(--card);border-top:1px solid var(--border);border-radius:var(--r-lg) var(--r-lg) 0 0;box-shadow:var(--e-3);padding:var(--s-4) var(--s-4) var(--s-8);max-height:82vh;overflow:auto;overscroll-behavior:contain;animation:su var(--dur) var(--ease)}
.sheet__hd{display:flex;align-items:center;justify-content:space-between;gap:var(--s-3);margin-bottom:var(--s-2)}
.tabbar{display:none}
@media (max-width:899px){.app{padding-bottom:64px}
.tabbar{display:grid;grid-template-columns:repeat(5,1fr);position:fixed;left:0;right:0;bottom:0;z-index:45;height:64px;background:var(--bg);border-top:1px solid var(--border)}
.tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-height:44px;border:0;background:transparent;color:var(--text-subtle);font-family:inherit;font-size:var(--fs-caption);font-weight:600;cursor:pointer;text-decoration:none}
.tab__g{display:block;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.tab__g--dots{fill:currentColor;stroke:none}
.tab[aria-current="page"]{color:var(--brand)}}
.hero{padding-block:var(--s-8) var(--s-7)}
.hero__grid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:64px;align-items:start}
@media (max-width:1024px){.hero__grid{grid-template-columns:minmax(0,1fr);gap:var(--s-7)}}
.hero__h1{font-size:clamp(40px,5vw,56px);font-weight:700;letter-spacing:-.03em;text-wrap:balance;max-width:16ch}
.hero__sub{margin-top:24px;font-size:var(--fs-body);color:var(--text-muted);max-width:46ch;text-wrap:pretty}
.demo{display:inline-flex;align-items:center;gap:var(--s-2);min-height:44px;margin-top:var(--s-1);font-size:var(--fs-small);color:var(--brand);text-decoration:none}
.demo:hover{text-decoration:underline}
.sp{position:relative;background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--e-2);overflow:hidden;max-height:436px}
.sp::after{content:"";position:absolute;left:0;right:0;bottom:0;height:72px;background:linear-gradient(to bottom,transparent,var(--card));pointer-events:none}
.sp__hd{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--s-2);padding:var(--s-3) var(--s-5);border-bottom:1px solid var(--border-strong)}
.sp__co{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle);letter-spacing:.04em}
.sp__body{padding:var(--s-5)}
.sp__top{display:flex;align-items:baseline;gap:var(--s-5)}
.sp__g{font-family:var(--font-mono);font-size:var(--fs-h1);font-weight:600;line-height:1;letter-spacing:-.02em}
.sp__s{font-size:var(--fs-small);color:var(--text-muted)}
.sp__s b{font-family:var(--font-mono);color:var(--text)}
.sp__rule{height:3px;width:34px;background:var(--text);margin-top:var(--s-2)}
.sp__v{margin-top:var(--s-5);font-size:var(--fs-small);line-height:1.55;text-wrap:pretty}
.sp__grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-4) var(--s-5);margin-top:var(--s-5);padding-top:var(--s-4);border-top:1px solid var(--border)}
.sp__k{font-size:var(--fs-caption);color:var(--text-subtle);display:flex;justify-content:space-between;gap:var(--s-2)}
.sp__k b{font-family:var(--font-mono);color:var(--text)}
.sp__b{display:block;height:4px;margin-top:6px;background:var(--surface-2);border-radius:999px;overflow:hidden}
.sp__f{display:block;width:100%;height:100%;background:var(--brand);border-radius:999px;transform-origin:left center}
.sp__f--1{transform:scaleX(.336)}.sp__f--2{transform:scaleX(.655)}.sp__f--3{transform:scaleX(.861)}.sp__f--4{transform:scaleX(.677)}
@media (prefers-reduced-motion:no-preference){
.hero__col>*{animation:heroIn 400ms cubic-bezier(.16,1,.3,1) both}
.hero__col>*:nth-child(2){animation-delay:60ms}
.hero__col>*:nth-child(3){animation-delay:120ms}
.hero__col>*:nth-child(4){animation-delay:180ms}
.hero__col>*:nth-child(5){animation-delay:240ms}
.sp{animation:heroIn 400ms cubic-bezier(.16,1,.3,1) 180ms both}
.sp__f{animation:gw 700ms ease-out 500ms both}}
@keyframes heroIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes gw{from{transform:scaleX(0)}}
.cb{position:relative;margin-top:40px;max-width:560px}
.cb__row{display:flex;align-items:stretch;background:var(--card);border:1px solid var(--border-strong);border-radius:var(--r-sm);transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.cb__row:focus-within{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
.cb__input{flex:1 1 auto;min-width:0;height:54px;border:0;background:transparent;color:var(--text);font-family:var(--font-mono);font-size:var(--fs-h3);font-weight:500;padding-inline:var(--s-4)}
.cb__input::placeholder{color:var(--text-subtle)}
.cb__go{flex:0 0 auto;height:54px;min-height:54px;padding-inline:var(--s-5);border-radius:0 7px 7px 0}
.cb__list{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:30;background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--e-3);padding:var(--s-2);max-height:320px;overflow:auto;overscroll-behavior:contain}
.cb__opt{display:grid;grid-template-columns:98px minmax(0,1fr) auto;align-items:center;gap:var(--s-3);min-height:44px;padding:0 var(--s-3);border-radius:var(--r-sm);cursor:pointer;font-size:var(--fs-small)}
.cb__opt[aria-selected="true"]{background:var(--brand-soft)}
.cb__opt:hover{background:var(--surface)}
.cb__sym{font-family:var(--font-mono);font-weight:600}
.cb__co{color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cb__ex{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle)}
.egs{display:flex;flex-wrap:nowrap;gap:var(--s-5);margin-top:20px;align-items:center;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.egs::-webkit-scrollbar{display:none}
.egs__lbl{flex:0 0 auto;font-size:var(--fs-caption);color:var(--text-subtle)}
.eg{display:inline-flex;align-items:center;flex:0 0 auto;white-space:nowrap;min-height:44px;padding:0;border:0;background:none;color:var(--text-muted);font-family:var(--font-mono);font-size:var(--fs-small);cursor:pointer;text-decoration:none;transition:color var(--dur) var(--ease)}
.eg:hover{color:var(--brand);text-decoration:underline;text-underline-offset:4px}
.chip{display:inline-flex;align-items:center;gap:var(--s-2);min-height:44px;padding:0 var(--s-4);border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--card);color:var(--text);font-family:var(--font-mono);font-size:var(--fs-small);font-weight:500;cursor:pointer;transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease),transform var(--dur) var(--ease)}
.chip:hover{background:var(--brand-soft);border-color:var(--brand);color:var(--brand);transform:translateY(-1px)}
.chip:active{transform:none}
.chip[aria-pressed="true"]{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}
.chip[aria-pressed="true"]:hover{background:var(--brand-hover);border-color:var(--brand-hover);color:var(--on-brand)}
.chip--static{cursor:default;border-style:dashed;color:var(--text-muted);min-height:34px;font-size:var(--fs-caption)}
.chip--static:hover{background:var(--card);border-color:var(--border-strong);color:var(--text-muted)}
.trust{margin-top:32px;font-size:var(--fs-caption);color:var(--text-subtle);max-width:70ch;text-wrap:pretty}
.band{background:var(--surface);border-block:1px solid var(--border)}
.how{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s-5)}
@media (max-width:899px){.how{grid-template-columns:1fr;gap:var(--s-4)}}
.how__i{padding-top:var(--s-4);border-top:2px solid var(--border-strong)}
.how__w{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle)}
.how__h3{font-size:var(--fs-h3);margin-top:var(--s-2)}
.how__p{margin-top:var(--s-2);font-size:var(--fs-small);color:var(--text-muted);text-wrap:pretty}
.note{background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--e-1);overflow:hidden}
.note__dateline{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--s-3);padding:var(--s-4) var(--card-pad);border-bottom:1px solid var(--border-strong)}
.note__date{font-size:var(--fs-caption);color:var(--text-subtle)}
.note__head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s-4) var(--s-5);align-items:start;padding:var(--s-5) var(--card-pad);border-bottom:1px solid var(--border)}
@media (max-width:560px){.note__head{grid-template-columns:1fr}.note__px{text-align:left}}
.note__sym{font-family:var(--font-mono);font-size:var(--fs-h1);font-weight:600;letter-spacing:.01em}
.note__co{font-size:var(--fs-body);font-weight:600;margin-top:var(--s-1)}
.note__meta{font-size:var(--fs-caption);color:var(--text-subtle);margin-top:var(--s-1)}
.note__px{text-align:right}
.note__price{font-family:var(--font-mono);font-size:var(--fs-h1);font-weight:600}
.note__chg{font-family:var(--font-mono);font-size:var(--fs-small);font-weight:500;margin-top:var(--s-1)}
.note__chg[data-dir="up"]{color:var(--positive)}
.note__chg[data-dir="down"]{color:var(--negative)}
.note__delay{font-size:var(--fs-caption);color:var(--text-subtle);margin-top:var(--s-2)}
.note__body{display:grid;grid-template-columns:212px minmax(0,1fr);gap:var(--s-6);padding:var(--s-6) var(--card-pad)}
@media (max-width:760px){.note__body{grid-template-columns:1fr;gap:var(--s-5)}}
.gr__g{font-family:var(--font-mono);font-size:78px;font-weight:600;line-height:.86;letter-spacing:-.03em}
.gr__rule{height:4px;background:var(--text);width:58px;margin-top:var(--s-3);transform-origin:left center}
.pil:nth-child(2){animation-delay:70ms}
.pil:nth-child(3){animation-delay:140ms}
.pil:nth-child(4){animation-delay:210ms}
.gband{display:flex;gap:3px;margin-top:var(--s-4)}
.gband__s{flex:1 1 0;min-width:0;padding:6px 2px;text-align:center;font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:600;color:var(--text-subtle);background:var(--surface-2);border-radius:2px}
.gband__s[data-on="yes"]{background:var(--text);color:var(--bg)}
.gr__score{margin-top:var(--s-4);font-size:var(--fs-caption);color:var(--text-muted);display:flex;justify-content:space-between;gap:var(--s-2)}
.gr__score b{font-family:var(--font-mono);color:var(--text)}
.bar{appearance:none;-webkit-appearance:none;display:block;width:100%;height:6px;margin-top:var(--s-2);border:0;border-radius:999px;background:var(--surface-2);overflow:hidden;accent-color:var(--brand)}
.bar::-webkit-progress-bar{background:var(--surface-2);border-radius:999px}
.bar::-webkit-progress-value{background:var(--brand);border-radius:999px}
.bar::-moz-progress-bar{background:var(--brand);border-radius:999px}
.thesis{font-size:21px;line-height:1.5;letter-spacing:-.006em;text-wrap:pretty;max-width:60ch}
.gr__g--none{color:var(--text-subtle)}
.gr__rule--none{background:var(--border-strong)}
.unsc__lbl{margin-top:var(--s-3);font-family:var(--font-mono);font-size:var(--fs-caption);letter-spacing:.07em;text-transform:uppercase;color:var(--text-subtle)}
.unsc__why{margin-top:var(--s-4);font-size:var(--fs-small);color:var(--text-muted);max-width:62ch;text-wrap:pretty}
.unsc__facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(184px,1fr));gap:var(--s-4) var(--s-5);margin:var(--s-5) 0 0;padding-top:var(--s-4);border-top:1px solid var(--border)}
.unsc__f{min-width:0}
.unsc__k{font-size:var(--fs-caption);color:var(--text-subtle)}
.unsc__v{margin:2px 0 0;font-family:var(--font-mono);font-size:var(--fs-small);font-weight:500;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.thesis__q{color:var(--text-subtle)}
.stance{margin-top:var(--s-5);display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-6);font-size:var(--fs-small);color:var(--text-muted)}
.stance b{font-family:var(--font-mono);color:var(--text);font-weight:600}
.adj{padding:var(--s-4) var(--card-pad);border-top:1px solid var(--border);display:flex;flex-wrap:wrap;gap:var(--s-2);align-items:center}
.adj__lbl{font-family:var(--font-mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;color:var(--text-subtle);margin-right:var(--s-2)}
.note__ft{padding:var(--s-3) var(--card-pad);border-top:1px solid var(--border);background:var(--surface);font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle);display:flex;flex-wrap:wrap;gap:var(--s-1) var(--s-4)}
.est{display:inline-flex;align-items:center;font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--warning);border:1px solid currentColor;border-radius:3px;padding:0 5px;white-space:nowrap}
.load{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3);padding:var(--s-4) var(--card-pad);border-top:1px solid var(--border);background:var(--brand-soft);font-size:var(--fs-small)}
.load__m{flex:1 1 auto;min-width:150px}
.skel{background:var(--surface-2);border-radius:var(--r-sm);animation:sk 1.4s var(--ease) infinite}
.skel--line{height:15px;margin-bottom:var(--s-3)}
.skel--w90{width:90%}.skel--w70{width:70%}.skel--w50{width:50%}.skel--w30{width:30%}
.skel--grade{width:118px;height:76px}
.vs{margin-top:var(--s-7);border-top:1px solid var(--border-strong);padding-top:var(--s-5)}
.vs__rows{margin-top:var(--s-5);border-top:1px solid var(--border-strong)}
.vsr{display:grid;grid-template-columns:minmax(146px,188px) minmax(0,1fr) 92px;align-items:center;gap:var(--s-2) var(--s-4);padding:var(--row-y) 0;border-bottom:1px solid var(--border)}
.vsr__l{font-size:var(--fs-small);color:var(--text-muted);display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap}
.vsr__v{font-family:var(--font-mono);font-size:var(--fs-small);font-variant-numeric:tabular-nums;text-align:right}
.vsr--now{background:var(--surface);border-block:1px solid var(--border-strong)}
.vsr--now .vsr__l{color:var(--text);font-weight:600}
.vsr--now .vsr__v{font-size:var(--fs-h3);font-weight:600}
.vsr__b{height:10px;margin-top:0;accent-color:var(--text-subtle)}
.vsr__b[data-k="dcf"]{accent-color:var(--warning)}
.vsr__b[data-k="tgt"]{accent-color:var(--brand)}
.vsr__b[data-k="now"]{accent-color:var(--text)}
.vsr__b::-webkit-progress-value{background:var(--text-subtle)}
.vsr__b::-moz-progress-bar{background:var(--text-subtle)}
.vsr__b[data-k="dcf"]::-webkit-progress-value{background:var(--warning)}
.vsr__b[data-k="dcf"]::-moz-progress-bar{background:var(--warning)}
.vsr__b[data-k="tgt"]::-webkit-progress-value{background:var(--brand)}
.vsr__b[data-k="tgt"]::-moz-progress-bar{background:var(--brand)}
.vsr__b[data-k="now"]::-webkit-progress-value{background:var(--text)}
.vsr__b[data-k="now"]::-moz-progress-bar{background:var(--text)}
@media (max-width:620px){.vsr{grid-template-columns:minmax(0,1fr) auto}.vsr__b{grid-column:1 / -1}}
.vs__key{display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-5);margin-top:var(--s-4);font-size:var(--fs-caption);color:var(--text-muted)}
.vs__k{display:inline-flex;align-items:center;gap:var(--s-2)}
.vs__sw{width:2px;height:15px;background:var(--text)}
.vs__sw--dcf{background:var(--warning)}
.vs__sw--tgt{background:var(--brand)}
.vs__sw--range{background:var(--text-subtle)}
.pillars{margin-top:var(--s-7);border-top:1px solid var(--border-strong)}
.pil{border-bottom:1px solid var(--border)}
.pil__sum{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--s-3) var(--s-5);padding:var(--s-5) var(--s-2);cursor:pointer;list-style:none;min-height:44px}
.pil__sum::-webkit-details-marker{display:none}
.pil__sum:hover{background:var(--surface)}
.pil__mark{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle);width:20px}
.pil__t{min-width:0}
.pil__h3{font-size:var(--fs-h3);display:block}
.pil__find{margin-top:var(--s-2);font-size:var(--fs-small);color:var(--text-muted);text-wrap:pretty;display:block}
.pil__sc{text-align:right;min-width:126px}
.pil__n{font-family:var(--font-mono);font-size:var(--fs-h3);font-weight:600;display:block}
.pil__w{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle);display:block}
.pil__body{padding:0 var(--s-2) var(--s-6) calc(20px + var(--s-5) + var(--s-2))}
@media (max-width:700px){.pil__sum{grid-template-columns:auto minmax(0,1fr);gap:var(--s-3)}.pil__sc{grid-column:2;text-align:left;min-width:0;display:flex;align-items:baseline;gap:var(--s-3)}.pil__body{padding-left:var(--s-2)}}
.mets{display:grid;grid-template-columns:repeat(auto-fill,minmax(224px,1fr));gap:1px;background:var(--border);border:1px solid var(--border);border-radius:var(--r-sm);overflow:hidden}
.met{background:var(--card);padding:var(--row-y) var(--s-4)}
.met__l{font-size:var(--fs-caption);color:var(--text-subtle);display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap}
.met__v{font-family:var(--font-mono);font-size:var(--fs-body);font-weight:500;margin-top:2px}
.met__h{font-size:var(--fs-caption);color:var(--text-muted);margin-top:var(--s-1);text-wrap:pretty}
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--e-1);padding:var(--card-pad);margin-top:var(--s-6)}
.card__hd{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--s-3);margin-bottom:var(--s-4)}
.card__h3{font-size:var(--fs-h3)}
.tabs{display:flex;gap:var(--s-1);overflow-x:auto}
.tabs__b{min-height:44px;padding:0 var(--s-3);border:0;background:transparent;color:var(--text-muted);font-family:var(--font-mono);font-size:var(--fs-small);cursor:pointer;white-space:nowrap;transition:color var(--dur) var(--ease)}
.tabs__b:hover{color:var(--text)}
.tabs__b[aria-selected="true"]{color:var(--text);font-weight:600;box-shadow:inset 0 -2px 0 var(--brand)}
.chart__svg{display:block;width:100%;height:auto;overflow:visible}
.chart__grid{stroke:var(--border);stroke-width:1}
.chart__px{fill:none;stroke:var(--brand);stroke-width:2;stroke-linejoin:round}
.chart__bm{fill:none;stroke:var(--text-subtle);stroke-width:1.5;stroke-dasharray:5 4}
.chart__lg{display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-5);margin-top:var(--s-4);font-size:var(--fs-caption);color:var(--text-muted)}
.chart__k{display:inline-flex;align-items:center;gap:var(--s-2)}
.chart__sw{width:18px;border-top:2px solid var(--brand)}
.chart__sw--bm{border-top:2px dashed var(--text-subtle)}
.chart__sum{margin-top:var(--s-3);font-size:var(--fs-small);color:var(--text-muted);text-wrap:pretty}
.tw{overflow-x:auto;border-radius:var(--r-sm)}
.tw--framed{border:1px solid var(--border)}
.tbl{width:100%;border-collapse:collapse;font-size:var(--fs-small)}
.tbl caption{text-align:left;padding:var(--s-3) var(--s-4);font-family:var(--font-sans);font-size:var(--fs-caption);color:var(--text-subtle);border-bottom:1px solid var(--border)}
.tbl th{text-align:left;font-family:var(--font-sans);font-size:var(--fs-caption);font-weight:600;color:var(--text-muted);background:var(--surface);border-bottom:1px solid var(--border-strong);padding:0;white-space:nowrap}
.tbl th.tp{padding:var(--row-y) var(--s-4)}
.tbl__sort{display:flex;align-items:center;gap:var(--s-2);width:100%;min-height:44px;padding:0 var(--s-4);border:0;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
.tbl__sort:hover{background:var(--surface-2);color:var(--text)}
.tbl__ar{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle)}
.tbl td{padding:var(--row-y) var(--s-4);border-bottom:1px solid var(--border);white-space:nowrap;transition:background-color var(--dur-fast) var(--ease)}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr:hover td{background:var(--surface)}
.tbl__t{font-family:var(--font-sans);white-space:normal;min-width:180px}
.tbl__r{text-align:right}
.tbl th.tbl__r{text-align:right}
.tbl th.tbl__r .tbl__sort{justify-content:flex-end}
.up{color:var(--positive)}
.down{color:var(--negative)}
.acts{display:flex;flex-wrap:wrap;gap:var(--s-2);margin-top:var(--s-6)}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));gap:1px;background:var(--border);border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden}
.kpi{background:var(--card);padding:var(--s-4) var(--s-5)}
.kpi__l{font-size:var(--fs-caption);color:var(--text-subtle)}
.kpi__v{font-family:var(--font-mono);font-size:var(--fs-h2);font-weight:600;margin-top:var(--s-1)}
.kpi__d{font-family:var(--font-mono);font-size:var(--fs-caption);margin-top:var(--s-1)}
.grid3{display:grid;grid-template-columns:repeat(auto-fit,minmax(268px,1fr));gap:var(--s-4);margin-top:var(--s-4)}
.tool{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-2);text-align:left;padding:var(--s-5);background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--e-1);cursor:pointer;font:inherit;color:inherit;transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),transform var(--dur) var(--ease)}
.tool:hover{border-color:var(--brand);box-shadow:var(--e-2);transform:translateY(-2px)}
.tool:active{transform:none}
.tool:disabled{cursor:not-allowed;opacity:.62;box-shadow:none;background:var(--surface)}
.tool:disabled:hover{border-color:var(--border)}
.tool__n{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle)}
.tool__h3{font-size:var(--fs-h3)}
.tool__p{font-size:var(--fs-small);color:var(--text-muted);text-wrap:pretty}
.tool__why{font-size:var(--fs-caption);color:var(--warning)}
.empty{text-align:center;padding:var(--s-8) var(--s-5);border:1px dashed var(--border-strong);border-radius:var(--r-md);background:var(--surface);margin-top:var(--s-4)}
.empty__g{font-family:var(--font-mono);font-size:var(--fs-h1);color:var(--text-subtle)}
.empty__h3{font-size:var(--fs-h3);margin-top:var(--s-3)}
.empty__p{margin-top:var(--s-2);font-size:var(--fs-small);color:var(--text-muted);max-width:42ch;margin-inline:auto;text-wrap:pretty}
.empty__a{margin-top:var(--s-5);display:flex;gap:var(--s-2);justify-content:center;flex-wrap:wrap}
.toast{position:fixed;left:50%;bottom:var(--s-5);transform:translateX(-50%);z-index:58;display:flex;align-items:center;gap:var(--s-4);width:min(520px,calc(100vw - 32px));padding:var(--s-2) var(--s-2) var(--s-2) var(--s-5);background:var(--text);color:var(--bg);border-radius:var(--r-sm);box-shadow:var(--e-3);font-size:var(--fs-small);animation:fu var(--dur) var(--ease)}
@media (max-width:899px){.toast{bottom:calc(64px + var(--s-4))}}
.toast__m{flex:1 1 auto}
.toast__b{min-height:44px;padding:0 var(--s-3);border:1px solid currentColor;border-radius:var(--r-sm);background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
.toast__b:hover{background:var(--bg);color:var(--text)}
.ftr{border-top:1px solid var(--border);background:var(--surface);padding-block:var(--s-7) var(--s-6);margin-top:var(--sec)}
.ftr__grid{display:grid;grid-template-columns:2fr repeat(3,1fr);gap:var(--s-6)}
@media (max-width:899px){.ftr__grid{grid-template-columns:1fr 1fr}}
.ftr__h3{font-family:var(--font-mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;color:var(--text-subtle);margin-bottom:var(--s-2);font-weight:500}
.ftr__p{font-size:var(--fs-small);color:var(--text-muted);max-width:42ch;text-wrap:pretty}
.ftr__li a{display:inline-flex;align-items:center;min-height:44px;font-size:var(--fs-small);color:var(--text-muted);text-decoration:none}
.ftr__li a:hover{color:var(--brand);text-decoration:underline}
.ftr__dis{margin-top:var(--s-6);padding-top:var(--s-5);border-top:1px solid var(--border);font-size:var(--fs-caption);color:var(--text-muted);max-width:94ch;text-wrap:pretty}
.src{margin-top:var(--s-5);font-size:var(--fs-caption);color:var(--text-subtle);text-wrap:pretty}
.lead{font-size:var(--fs-body);color:var(--text-muted);max-width:64ch;text-wrap:pretty;margin-bottom:var(--s-4)}
.tbl__bar{width:168px;min-width:110px}
.app dd{margin:0}
.gl{border-top:1px solid var(--border-strong)}
.gl__r{display:grid;grid-template-columns:minmax(140px,200px) minmax(0,1fr) minmax(96px,132px);gap:var(--s-1) var(--s-4);padding:var(--row-y) 0;border-bottom:1px solid var(--border);align-items:baseline}
.gl__t{font-size:var(--fs-small);font-weight:600}
.gl__d{font-size:var(--fs-small);color:var(--text-muted);text-wrap:pretty}
.gl__v{font-family:var(--font-mono);font-size:var(--fs-small);font-variant-numeric:tabular-nums;text-align:right}
.wt{margin-top:var(--s-7);background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-md);padding:var(--card-pad)}
.wt__hd{max-width:66ch;margin-bottom:var(--s-5)}
.wt__pre{display:flex;flex-wrap:wrap;gap:var(--s-2);margin-bottom:var(--s-5)}
.wt__grid{display:grid;grid-template-columns:minmax(0,1fr) 268px;gap:var(--s-6)}
@media (max-width:860px){.wt__grid{grid-template-columns:1fr}}
.wt__row{display:grid;grid-template-columns:minmax(118px,1fr) minmax(110px,190px) 52px;align-items:center;gap:0 var(--s-4);border-bottom:1px solid var(--border)}
@media (max-width:520px){.wt__row{grid-template-columns:minmax(0,1fr) 52px}.rng{grid-column:1 / -1}}
.wt__l{font-size:var(--fs-small)}
.wt__v{font-family:var(--font-mono);font-size:var(--fs-small);font-variant-numeric:tabular-nums;text-align:right}
.rng{appearance:none;-webkit-appearance:none;width:100%;height:44px;background:transparent;cursor:pointer;accent-color:var(--brand)}
.rng::-webkit-slider-runnable-track{height:6px;border-radius:999px;background:var(--border-strong);border:1px solid var(--text-subtle)}
.rng::-webkit-slider-thumb{-webkit-appearance:none;width:22px;height:22px;margin-top:-7px;border-radius:50%;background:var(--brand);border:2px solid var(--card);box-shadow:var(--e-1)}
.rng::-moz-range-track{height:6px;border-radius:999px;background:var(--border-strong);border:1px solid var(--text-subtle)}
.rng::-moz-range-thumb{width:20px;height:20px;border-radius:50%;background:var(--brand);border:2px solid var(--card)}
.wt__out{background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s-5);align-self:start}
.wt__g{font-family:var(--font-mono);font-size:var(--fs-h1);font-weight:600;line-height:.9;letter-spacing:-.03em}
.wt__s{font-family:var(--font-mono);font-size:var(--fs-h3);font-weight:600;margin-top:var(--s-3)}
.wt__d{font-size:var(--fs-small);color:var(--text-muted);margin-top:var(--s-3);text-wrap:pretty}
.wt__sum{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle);margin-top:var(--s-4)}
@media (max-width:620px){.gl__r{grid-template-columns:minmax(0,1fr) auto}.gl__d{grid-column:1 / -1}.gl__v{text-align:left;font-weight:600}}
.tbar{appearance:none;-webkit-appearance:none;display:block;width:100%;height:8px;border:0;border-radius:999px;background:var(--surface-2);overflow:hidden;accent-color:var(--brand)}
.tbar[data-k="warn"]{accent-color:var(--warning)}
.tbar[data-k="mute"]{accent-color:var(--text-subtle)}
.tbar[data-k="dark"]{accent-color:var(--text)}
.tbar::-webkit-progress-bar{background:var(--surface-2);border-radius:999px}
.tbar::-webkit-progress-value{background:var(--brand);border-radius:999px}
.tbar::-moz-progress-bar{background:var(--brand);border-radius:999px}
.tbar[data-k="warn"]::-webkit-progress-value{background:var(--warning)}
.tbar[data-k="warn"]::-moz-progress-bar{background:var(--warning)}
.tbar[data-k="mute"]::-webkit-progress-value{background:var(--text-subtle)}
.tbar[data-k="mute"]::-moz-progress-bar{background:var(--text-subtle)}
.tbar[data-k="dark"]::-webkit-progress-value{background:var(--text)}
.tbar[data-k="dark"]::-moz-progress-bar{background:var(--text)}
.tbl tr[data-hl="yes"] td{background:var(--brand-soft)}
.tbl tr[data-hl="yes"] td:first-child{font-weight:600}
@media (max-width:620px){.tbl__bar{display:none}}

/* ---- ported-fix: measured at 375px, not eyeballed --------------------- */
/* Scroll wrappers must not themselves exceed the viewport, or the page
   overflows and overflow-x:clip merely hides it. */
.tw{max-width:100%;overscroll-behavior-x:contain}
.tbl{max-width:100%}
/* The stance line is one span per item; at 375px it has to break inside an
   item too, not only between them. */
.stance > span{display:inline-flex;flex-wrap:wrap;align-items:baseline;gap:0 .35em;min-width:0}
.stance .est{flex:0 1 auto;min-width:0}

/* ---- forms: portfolio add, watchlist add ------------------------------
   The prototype had no form component — every view was read-only. These
   follow the same control conventions as .btn: 44px min target, tokenised
   spacing, and the app-wide :focus-visible ring rather than a bespoke one. */
.fm__row{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:var(--s-4)}
.fm__f{display:flex;flex-direction:column;gap:var(--s-2);min-width:0}
.fm__l{font-size:var(--fs-caption);color:var(--text-subtle);font-weight:500}
.fm__i{min-height:44px;width:100%;min-width:0;padding:0 var(--s-3);color:var(--text);background:var(--surface);
  border:1px solid var(--border-strong);border-radius:var(--r-sm);
  font-family:var(--font-mono);font-size:var(--fs-small)}
.fm__i::placeholder{color:var(--text-subtle);opacity:1}
.fm__i:hover{border-color:var(--text-subtle)}
.fm__hint{margin-top:var(--s-3);font-size:var(--fs-caption);color:var(--text-subtle)}
.fm__err{margin-bottom:var(--s-4);padding:var(--s-3) var(--s-4);border-radius:var(--r-sm);
  font-size:var(--fs-small);color:var(--negative);
  background:color-mix(in srgb,var(--negative) 10%,transparent);
  border:1px solid color-mix(in srgb,var(--negative) 35%,transparent)}
.fm__ok{margin-bottom:var(--s-4);padding:var(--s-3) var(--s-4);border-radius:var(--r-sm);
  font-size:var(--fs-small);color:var(--positive);
  background:color-mix(in srgb,var(--positive) 10%,transparent);
  border:1px solid color-mix(in srgb,var(--positive) 35%,transparent)}
.fm__a{margin-top:var(--s-5)}
/* Row-level actions sit inside their own POST form; it must not become a
   block-level box that breaks the table cell's baseline. */
.tbl td > form{display:inline}

/* ---- education: guide pages, breadcrumb, assistant --------------------
   .tool was a <button> in the prototype; guides are now real links, so it
   also has to behave as one (no underline, inherited colour). */
a.tool{text-decoration:none}
a.tool:hover .tool__h3{text-decoration:underline}
.crumb{font-size:var(--fs-caption);color:var(--text-subtle);margin-bottom:var(--s-4)}
.crumb a{color:inherit}
.chips{display:flex;flex-wrap:wrap;gap:var(--s-2)}

/* Long-form article body. Measure is capped for readability, not for looks. */
.doc{max-width:68ch}
.doc__h{margin-top:var(--s-6);margin-bottom:var(--s-3);line-height:var(--lh-tight)}
.doc__h:first-child{margin-top:0}
h2.doc__h{font-size:var(--fs-h2)}
h3.doc__h{font-size:var(--fs-h3)}
h4.doc__h,h5.doc__h,h6.doc__h{font-size:var(--fs-body)}
.doc__p{margin-bottom:var(--s-4);color:var(--text-muted);line-height:var(--lh-body);text-wrap:pretty}
.doc__ul,.doc__ol{margin:0 0 var(--s-4) var(--s-5);color:var(--text-muted);line-height:var(--lh-body)}
.doc__ul{list-style:disc}
.doc__ol{list-style:decimal}
.doc__ul li,.doc__ol li{margin-bottom:var(--s-2);padding-left:var(--s-1)}
.doc__p code,.doc__ul code,.doc__ol code{font-family:var(--font-mono);font-size:.92em;
  padding:1px 4px;border-radius:4px;background:var(--surface-2)}
.doc strong{color:var(--text);font-weight:600}
.doc__back{margin-top:var(--s-6)}

/* Assistant. The log is a live region, so it must not jump the page: it
   scrolls internally instead of growing without bound. */
.chat{display:flex;flex-direction:column;gap:var(--s-4)}
.chat__log{max-height:340px;overflow-y:auto;display:flex;flex-direction:column;gap:var(--s-3);
  padding:var(--s-4);background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md)}
.chat__empty{color:var(--text-subtle);font-size:var(--fs-small)}
.chat__form{display:flex;gap:var(--s-3);flex-wrap:wrap}
.chat__i{flex:1 1 240px}
.chat__msg{max-width:56ch;font-size:var(--fs-small);line-height:var(--lh-body);white-space:pre-wrap}
.chat__msg--you{align-self:flex-end;text-align:right;color:var(--text)}
.chat__msg--bot{align-self:flex-start;color:var(--text-muted)}
.chat__who{display:block;font-size:var(--fs-caption);color:var(--text-subtle);margin-bottom:var(--s-1)}
.chat__fallback{margin-top:var(--s-4);display:flex;flex-direction:column;gap:var(--s-3)}
.chat__you,.chat__bot{font-size:var(--fs-small);line-height:var(--lh-body);white-space:pre-wrap}
.chat__bot{color:var(--text-muted)}

/* --- appended: real-data wiring, session 3 -------------------------------
   APPEND ONLY. Source order in this file is load-bearing — see the header
   comment. New rules go at the end so they cannot displace a base rule that
   an earlier @media block depends on. */

/* Controls rendered as <a> rather than <button>.
   `.app a{color:var(--brand)}` is specificity (0,2,0) and outranks every
   component class (0,1,0), and nothing resets the UA underline. So a chip, a
   .btn or a sort header written as a link silently came out brand-blue and
   underlined — "Compare" (a link) sat beside "Add to watchlist" (a button) in
   two different colours. Restore the component's own treatment at matching
   specificity instead of patching each instance. */
.app a.btn,
.app a.chip,
.app a.tool,
.app a.tbl__sort,
.app a.menu__item{color:inherit;text-decoration:none}
.app a.btn--primary{color:var(--on-brand)}
.app a.chip[aria-current="true"]{color:var(--on-brand)}

/* Chips rendered as links use aria-current, not aria-pressed. The screener's
   active preset has been unhighlighted since it stopped being a button. */
.chip[aria-current="true"]{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}
.chip[aria-current="true"]:hover{background:var(--brand-hover);border-color:var(--brand-hover);color:var(--on-brand)}

/* Weights explorer: submit + reset sit together under the recomputed grade. */
.wt__a{display:flex;flex-wrap:wrap;gap:var(--s-2);margin-top:var(--s-4)}
.wt__a .btn{flex:1 1 auto;justify-content:center}
.rng:disabled{opacity:.45;cursor:not-allowed}

/* Row of actions under the note: some are forms now, so normalise the wrapper
   rather than relying on every child being a bare button. */
.acts form{display:contents}

/* In-page anchors (#weights, #metrics, #addpos) would otherwise land beneath
   the sticky header, hiding the heading the reader just jumped to. */
#weights,#metrics,#addpos,.prefs{scroll-margin-top:calc(var(--s-8) + 56px)}

/* WCAG 1.4.1: the hero's demo link sat in a text block distinguished only by
   colour. Underlined at rest, so it does not rely on hue alone. */
.demo{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:4px}

/* Two controls in one table cell (pause + remove) sit side by side rather than
   stacking, without the display:contents trick used in .acts — these are inside
   a <td>, where contents would collapse the cell's own box. */
.fm--inline{display:inline-block;margin-right:var(--s-2)}
.fm--inline:last-child{margin-right:0}

/* Comparison table: symbol header carries the company name beneath it, and a
   full-width group row separates the metric families. */
.cmp__co{display:block;font-family:var(--font-sans);font-size:var(--fs-caption);font-weight:400;color:var(--text-subtle);white-space:normal}
.cmp__grp th{background:var(--surface-2);font-family:var(--font-mono);font-size:var(--fs-caption);letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted)}

/* --- select-to-compare -------------------------------------------------- */
/* The checkbox is visually the control, but the <label> supplies the hit area
   so pointer and touch users get a full 44px target (WCAG 2.5.5) without
   inflating the table row. The label text itself is for screen readers. */
.pick{width:44px}
.pick__in{width:18px;height:18px;accent-color:var(--brand);cursor:pointer;margin:0}
.pick__lb{position:absolute;width:44px;height:44px;margin:-13px 0 0 -13px;cursor:pointer;
  overflow:hidden;white-space:nowrap;text-indent:-9999px}
.pick__in:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* A ticked row reads as selected, not just the box — the box is easy to lose
   in a wide table. */
.tbl tbody tr:has(.pick__in:checked) td{background:var(--brand-soft)}

/* The action sits directly under the table it belongs to. It is always
   visible and always enabled: with scripting off the form still submits and
   the server explains the problem. */
.cmpbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--s-3);padding:var(--s-4) var(--card-pad);border-top:1px solid var(--border)}
.cmpbar__t{font-size:var(--fs-small);color:var(--text-muted);margin:0}
@media (max-width:520px){.cmpbar{flex-direction:column;align-items:stretch}
  .cmpbar .btn{width:100%;justify-content:center}}

/* --- the teaching layer -------------------------------------------------
   Every figure can explain itself against its own value. Apple's "simplicity,
   not minimalism": the common path (the number) stays first, the explanation
   is exactly one level deeper — never a wall of prose, never hidden so far
   that nobody finds it.

   A native <details> is deliberate. It works with no JavaScript, it is
   keyboard operable and announced correctly for free, and it cannot desync
   from server-rendered state. */
.why{margin-top:var(--s-3);border-top:1px solid var(--border);padding-top:var(--s-2)}
.why__s{display:flex;align-items:center;gap:var(--s-2);cursor:pointer;list-style:none;
  min-height:32px;font-size:var(--fs-caption);color:var(--text-subtle)}
.why__s::-webkit-details-marker{display:none}
/* The verdict is the payload — it reads before the disclosure is opened, so a
   scanner gets the judgement without a click. */
.why__v{font-family:var(--font-mono);color:var(--text-muted);text-transform:lowercase}
.why__more{margin-left:auto;opacity:.75}
.why__more::after{content:" +"}
.why[open] .why__more::after{content:" \2212"}
.why__s:hover{color:var(--text-muted)}
/* Apple: feedback on press, not on release. */
.why__s:active{opacity:.7}
.why__s:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:var(--r-sm)}
.why__b{padding:var(--s-2) 0 var(--s-1)}
.why__p{font-size:var(--fs-caption);color:var(--text-muted);line-height:var(--lh-body);
  text-wrap:pretty;margin-top:var(--s-2)}
.why__p:first-child{margin-top:0;color:var(--text)}

/* --- press feedback ------------------------------------------------------
   Apple: "Respond on pointer-down, not on release." Only four rules had an
   :active state, so most controls gave nothing back until the click resolved
   and navigation began — which reads as a dead control on a slow connection.

   Deliberately restrained: opacity and a sub-pixel scale, no colour change.
   These fire on every tap, which by the frequency gate means they must be
   invisible-but-felt rather than noticed. No transition is declared, so the
   pressed state is instantaneous; only the release eases back via each
   element's own transition. */
.btn:active,
.ibtn:active,
.menu__item:active,
.tbl__sort:active,
.eg:active,
.demo:active,
.brand:active{opacity:.72}
/* Nav and tab bar move rather than fade — they sit on a solid surface where a
   fade reads as a rendering glitch. */
.nav__link:active,
.tab:active{transform:translateY(1px)}
/* Rows highlight instead: a row is a target you hit, not a button you push. */
.cb__opt:active,
.pick__lb:active{background:var(--surface-2)}

/* Springs are pointless here — nothing is gesture-driven or interruptible —
   but a press must never animate for a keyboard user, who gets no press
   phase at all. */
@media (prefers-reduced-motion:reduce){
.nav__link:active,.tab:active{transform:none}
}

/* --- the other two user preferences -------------------------------------
   prefers-reduced-motion was already honoured; these two were not. */
@media (prefers-reduced-transparency:reduce){
/* Nothing currently uses backdrop-filter, so this is forward cover: any
   translucent surface added later becomes solid rather than frosted. */
.app [style*="backdrop-filter"],.hdr,.menu__panel,.sheet{backdrop-filter:none!important}
.menu__panel,.sheet{background:var(--card)}
}
@media (prefers-contrast:more){
/* Near-solid surfaces with a defined border, and no subtle greys: the
   text-subtle token is the first thing to fail a contrast check. */
.app{--text-subtle:var(--text-muted);--border:var(--border-strong)}
.card,.menu__panel,.cb__list,.wt__out{border-color:var(--text-subtle)}
.btn--secondary,.btn--ghost,.chip{border-width:2px}
}

/* --- appended: empty states, glossary grouping, history — session 4 ------
   APPEND ONLY. Source order in this file is load-bearing — see the header
   comment. New rules go at the end so they cannot displace a base rule that
   an earlier @media block depends on.

   No new motion, transparency or low-contrast colour is introduced below:
   every control added in this pass reuses .btn / plain links, which the
   press-feedback and preference blocks above already cover, and the new
   subheads use tokens that prefers-contrast:more already remaps. */

/* History: the grade is the row's payload, so it reads at table-scanning
   size rather than body size. The cell is already mono via the td rule. */
.tbl__gr{font-size:var(--fs-h3);font-weight:600}

/* Glossary, grouped by difficulty band. h3 selector needed: `.app h1,h2,h3`
   is (0,1,1) and would otherwise keep margin at 0 and weight at 700. */
h3.gl__h{margin-top:var(--s-6);margin-bottom:var(--s-2);font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--text-subtle)}
.gl__n{font-weight:400}
/* Grouped rows drop the third (difficulty) column — the subhead already says
   it — so the definition takes the space. */
.gl--grouped .gl__r{grid-template-columns:minmax(140px,200px) minmax(0,1fr)}
@media (max-width:620px){.gl--grouped .gl__r{grid-template-columns:1fr}}
/* Definitions clamp to two lines so every row scans as the same unit; the
   term's own page carries the full text. */
.gl__d{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}

/* In-page anchors added by the empty states, same treatment as the earlier
   #weights set: without it the target heading lands under the sticky header. */
#addwatch,#addalert,#dcf-form{scroll-margin-top:calc(var(--s-8) + 56px)}

/* --- audit follow-ups: classes emitted with no rule behind them ---------- */
/* _dircls() returns 'flat' for every neutral value; with no rule it inherited
   body colour and neutral states were indistinguishable from labels. Sits with
   .up/.down (positive/negative) as the third state of the family. */
.flat{color:var(--text-subtle)}
/* Card-header metadata ("Prices delayed 15+ min", counts) on ~10 pages —
   rendered at full body size without this. */
.card__meta{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-subtle)}
/* The "Show the numbers" disclosure under the price chart. */
.chart__data{margin-top:var(--s-4)}
.chart__data>summary{cursor:pointer;min-height:44px;display:flex;align-items:center;
  font-size:var(--fs-caption);color:var(--text-subtle)}
.chart__data>summary:hover{color:var(--text-muted)}
.chart__data>summary:active{opacity:.72}
/* The assumptions form inside the "Adjusted for" disclosure. */
.prefs__f{margin-top:var(--s-4);padding-top:var(--s-4);border-top:1px solid var(--border)}
.prefs__t{margin-left:auto}

/* --- pre-paint theme: honour the stored choice before iq-app.js runs -----
   The boot script in base.html sets data-boot-theme on <html> from
   localStorage BEFORE first paint, but nothing here read it — so a light-OS
   user who chose dark (or the reverse) got a full flash of the wrong theme on
   every load while the deferred script caught up. These two rules bridge the
   gap for the server-rendered data-theme="auto" shell only; once iq-app.js
   sets the real data-theme, the original rules above take over unchanged.
   Token values are copies of .app (light) and .app[data-theme="dark"] — if
   the palette ever changes, change it there and re-copy here. */
html[data-boot-theme="dark"] .app[data-theme="auto"]{--bg:#0B0F17;--surface:#121826;--surface-2:#19202F;--card:#151C2C;--border:#232C3D;--border-strong:#33405A;--text:#E8EDF5;--text-muted:#A9B4C4;--text-subtle:#7D8B9C;--brand:#7FA9F5;--brand-hover:#A3C0FF;--brand-soft:#17243B;--on-brand:#0B0F17;--positive:#3DD68C;--negative:#FF7A6B;--warning:#F0A742;--e-1:0 1px 2px rgba(0,0,0,.4);--e-2:0 4px 12px rgba(0,0,0,.5);--e-3:0 16px 40px rgba(0,0,0,.6);color-scheme:dark}
@media (prefers-color-scheme:dark){
html[data-boot-theme="light"] .app[data-theme="auto"]{--bg:#FFFFFF;--surface:#F7F8FA;--surface-2:#F2F4F7;--card:#FFFFFF;--border:#E3E7ED;--border-strong:#CBD3DE;--text:#0F172A;--text-muted:#475569;--text-subtle:#5E6C7F;--brand:#12459E;--brand-hover:#0E3578;--brand-soft:#EAF0FA;--on-brand:#FFFFFF;--positive:#0F7B4F;--negative:#B42318;--warning:#B45309;--e-1:0 1px 2px rgba(15,23,42,.06);--e-2:0 4px 12px rgba(15,23,42,.08);--e-3:0 16px 40px rgba(15,23,42,.12);color-scheme:light}
}

/* Informational note that is not an error: the alerts caveat ("nothing is
   emailed to you") rendered in the error-red .fm__err box, which made honest
   scope-setting read as a fault. */
.fm__note{margin-bottom:var(--s-5);padding:var(--s-3) var(--s-4);border-radius:var(--r-sm);
  border:1px solid var(--border-strong);background:var(--surface);
  font-size:var(--fs-small);color:var(--text-muted);line-height:var(--lh-body);text-wrap:pretty}

/* Comparison cells carry the same verdict word the analysis page teaches,
   under the figure, so a row reads as a comparison of meanings. Muted and
   small: the number stays the payload, the word is the gloss. */
.cmp__vw{display:block;font-family:var(--font-sans);font-size:var(--fs-caption);
  color:var(--text-subtle);text-transform:lowercase}

/* Symbol autocomplete on form fields. The dropdown reuses the hero combobox's
   .cb__list/.cb__opt styling; the field wrapper just needs to be the
   positioning context. Additive — flex layout of .fm__f is unchanged. */
.fm__f{position:relative}

/* ============================ APPEND ONLY ============================
   Source order in this file is load-bearing. Everything below overrides
   an earlier rule by coming later at equal-or-greater specificity. Never
   reorder, never edit the originals in place.
   ==================================================================== */

/* --- WCAG 2.1 SC 1.4.11 (non-text contrast) --------------------------
   --border-strong draws the boundary of every .fm__i input and every
   .btn--secondary. Measured against its own backgrounds it was:
       light  #CBD3DE  1.51:1 vs --bg/--card, 1.42 vs --surface, 1.34 vs --surface-2
       dark   #33405A  1.85:1 vs --bg,        1.64 vs --card,     1.57 vs --surface-2
   The minimum for a UI component boundary is 3:1, so the visible edge of
   most interactive controls on this site failed the standard.

   This was invisible to the axe run the project relies on: axe-core checks
   TEXT contrast thoroughly but covers 1.4.11 for arbitrary borders only
   partially, which is how "0 axe violations" and this defect were both true
   at once. The replacements keep the original hue and shift only lightness,
   to the smallest step that clears 3:1 against bg, card, surface AND
   surface-2 in each theme:
       light  #848C97  3.40 / 3.40 / 3.20 / 3.03
       dark   #5E6B85  3.58 / 3.17 / 3.31 / 3.04
   The token is redefined once per palette copy — the same five copies the
   boot bridges warn about below — because a bare .app override cannot beat
   the boot bridges' higher specificity. */
.app{--border-strong:#848C97}
.app[data-theme="dark"]{--border-strong:#5E6B85}
@media (prefers-color-scheme:dark){
.app[data-theme="auto"]{--border-strong:#5E6B85}
}
html[data-boot-theme="dark"] .app[data-theme="auto"]{--border-strong:#5E6B85}
@media (prefers-color-scheme:dark){
html[data-boot-theme="light"] .app[data-theme="auto"]{--border-strong:#848C97}
}

/* --- the palette-copy convention has already drifted -----------------
   The comment above the boot bridges says the token values are hand-copied
   and must be re-copied when the palette changes. That has already failed
   silently: --e-3 is rgba(15,23,42,.16) in the canonical .app block (line
   19) but rgba(15,23,42,.12) in the boot-light bridge (line 664), so the
   largest shadow was measurably lighter during the pre-paint window than
   after. Corrected here rather than in place, per append-only.

   Six copies of ~16 colours are now maintained by hand: .app,
   .app[data-theme="dark"], the auto-dark media block, the two boot bridges,
   and the <meta name="theme-color"> pair in base.html. Deduplicating them
   properly needs a reorder, which this file forbids — so the risk is
   recorded here instead. Anyone changing a colour must change all six. */
@media (prefers-color-scheme:dark){
html[data-boot-theme="light"] .app[data-theme="auto"]{--e-3:0 16px 40px rgba(15,23,42,.16)}
}

/* --- pre-paint density: the other half of the boot bridge -------------
   base.html's inline script sets data-boot-density on <html> before first
   paint, and iq-app.js keeps it in sync — exactly mirroring the theme boot
   plumbing above. But nothing in this file ever read it, so the bridge was
   only ever half-built: a reader who chose "compact" got a flash of
   comfortable padding, row height and body size on every single page load
   until the deferred script ran. Same bug the theme bridge exists to
   prevent, same fix. Values are copied from .app[data-density="compact"]
   (line 22) and must be kept in step with it. */
html[data-boot-density="compact"] .app{--card-pad:var(--s-5);--row-y:8px;--fs-body:17px}

/* --- dead rules, kept for source-order safety ------------------------
   These match no markup the app can produce. They are documented rather
   than deleted because removing lines from the middle of this file is what
   the append-only rule exists to prevent; a future rewrite can drop them.
     .tabs / .tabs__b        - the shipped tab UI uses .chip[aria-current]
                               links instead, so this ARIA tab component was
                               orphaned before it was ever used.
     .tw--framed             - never applied to any element.
     .chip[aria-pressed]     - chips became <a> links; nothing sets
                               aria-pressed anywhere in the templates.
     .tool:disabled          - .tool is always rendered as <a>, and :disabled
                               cannot match an anchor.
     .fm__ok                 - the success counterpart to .fm__err, which is
                               used in six templates; this one in none.
     .vs__sw--dcf,
     .vsr__b[data-k="dcf"]   - _ranges() only ever emits "", "tgt" or "now";
                               the dcf marker came from the prototype's
                               hardcoded specimen and has no data behind it. */
