:root{
  --bg:#fbfaf8; --panel:#fff; --ink:#14161a; --muted:#6b7280; --line:#e4e2dd;
  --buy:#0f7a4d; --buy-bg:#e7f4ed; --sell:#b3261e; --sell-bg:#fceceb;
  --ex:#6b7280; --accent:#1f4ed8; --warn:#a1560a; --warn-bg:#fdf1e3;
  --in:#1f4fd8; --link:#0f7a4d;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
}
@media (prefers-color-scheme:dark){
  :root{ --bg:#111316; --panel:#181b1f; --ink:#e9e8e4; --muted:#9aa1ab; --line:#2a2e34;
         --buy:#4ade80; --buy-bg:#123024; --sell:#f87171; --sell-bg:#3a1a19;
         --accent:#7ea2ff; --warn:#e3a462; --warn-bg:#33240f;
         --in:#7ea2ff; --link:#4ade80; }
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
  font:15px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  -webkit-text-size-adjust:100%}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
code{font-family:var(--mono);font-size:.9em}
h1{font-size:1.65rem;margin:.2em 0 .3em;letter-spacing:-.02em}
h2{font-size:1.05rem;margin:1.8em 0 .6em;letter-spacing:-.01em}
.muted{color:var(--muted)}
.small{font-size:.85em}
.nowrap{white-space:nowrap}

/* ---- chrome ---- */
.topbar{display:flex;gap:1.2rem;align-items:center;flex-wrap:wrap;
  padding:.7rem 1.5rem;border-bottom:1px solid var(--line);background:var(--panel);
  position:sticky;top:0;z-index:20}
.brand{display:flex;align-items:center;gap:.5rem;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.brand-mark{display:inline-grid;place-items:center;width:25px;height:25px;overflow:hidden;border:1px solid color-mix(in srgb,var(--accent) 55%,var(--line));border-radius:7px;background:var(--accent)}
.brand-mark img{display:block;width:100%;height:100%;object-fit:cover}
.topbar nav{display:flex;gap:1rem;flex-wrap:wrap}
.topbar nav a{color:var(--muted);font-size:.92rem}
.topbar nav a:hover{color:var(--ink)}
.topbar .search{margin-left:auto}
.topbar input[type=search]{padding:.4rem .7rem;border:1px solid var(--line);
  border-radius:7px;background:var(--bg);color:var(--ink);min-width:min(240px,45vw)}
main{max-width:1280px;margin:0 auto;padding:1.4rem 1.5rem 3rem}
footer{max-width:1280px;margin:0 auto;padding:1.5rem;border-top:1px solid var(--line);
  color:var(--muted);font-size:.85rem}

/* ---- nav rows (contract §3): row 1 app switcher, row 2 sub-nav ---- */
.chrome{position:sticky;top:0;z-index:20}
.topbar nav.apps{gap:1.15rem;align-items:baseline}
.topbar nav.apps a{font-size:1rem;letter-spacing:-.01em}
.topbar nav.apps a.on{color:var(--accent);font-weight:700}
.topbar nav.apps a.on:hover{text-decoration:none}
.topbar nav.apps a.api{font-size:.86rem}
.subnav{background:var(--panel);border-bottom:1px solid var(--line);
  overflow-x:auto;scrollbar-width:thin;-webkit-overflow-scrolling:touch}
.subnav-inner{display:flex;gap:1.15rem;padding:0 1.5rem;white-space:nowrap}
.subnav a{display:inline-block;padding:.36rem 0;font-size:.86rem;color:var(--muted);
  border-bottom:2px solid transparent}
.subnav a:hover{color:var(--ink);text-decoration:none}
.subnav a.on{color:var(--accent);font-weight:600;border-bottom-color:var(--accent)}
@media(max-width:640px){.subnav-inner{padding:0 1rem;gap:.9rem}}

/* ---- hero / stats ---- */
.hero h1{max-width:24ch}
.lede{max-width:78ch;color:var(--muted)}
.stats{display:flex;flex-wrap:wrap;gap:.6rem;margin:1.2rem 0}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:.6rem .9rem;min-width:118px}
.stat b{display:block;font-size:1.3rem;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.stat span{color:var(--muted);font-size:.78rem;text-transform:uppercase;letter-spacing:.04em}
.stat.warn{background:var(--warn-bg);border-color:transparent}
.stat a{color:inherit}
.runline{margin:.2rem 0 1rem;font-size:.85rem}

.cols{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:2rem;align-items:start}
@media(max-width:960px){.cols{grid-template-columns:1fr}}

/* ---- tables ---- */
.tablewrap{overflow-x:auto;border:1px solid var(--line);border-radius:10px;background:var(--panel)}
table.data{border-collapse:collapse;width:100%;font-size:.88rem}
table.data th,table.data td{padding:.45rem .7rem;text-align:left;border-bottom:1px solid var(--line);vertical-align:top}
table.data th{position:sticky;top:0;background:var(--panel);font-weight:600;font-size:.76rem;
  text-transform:uppercase;letter-spacing:.045em;color:var(--muted);white-space:nowrap;z-index:1}
table.data th[data-sort]{cursor:pointer;user-select:none}
table.data th[data-sort]:hover{color:var(--ink)}
table.data th.asc::after{content:" ▲";font-size:.7em}
table.data th.desc::after{content:" ▼";font-size:.7em}
table.data tbody tr:hover{background:color-mix(in srgb,var(--accent) 5%,transparent)}
table.data tbody tr:last-child td{border-bottom:0}
td.num{text-align:right;font-variant-numeric:tabular-nums}
td.asset{max-width:34ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
td.empty{text-align:center;color:var(--muted);padding:1.6rem}
.late{color:var(--warn);font-weight:600}
.buy{color:var(--buy)} .sell{color:var(--sell)}
.ticker{font-family:var(--mono);font-weight:600}
.ticker.big{font-size:1.5rem}
a.ext{color:var(--muted)}

/* ---- chips ---- */
.chip{display:inline-block;padding:.06rem .38rem;border-radius:5px;font-size:.7rem;
  font-weight:700;letter-spacing:.02em;vertical-align:middle;margin-left:.25rem}
.chip.d{background:#dbe6ff;color:#1c3f9e}
.chip.r{background:#ffdedb;color:#9b1c13}
.chip.i{background:#e6e4df;color:#4b5563}
.chip.buy{background:var(--buy-bg);color:var(--buy);margin-left:0}
.chip.sell{background:var(--sell-bg);color:var(--sell);margin-left:0}
.chip.ex,.chip.un{background:#e6e4df;color:#4b5563;margin-left:0}
.chip.ok{background:var(--buy-bg);color:var(--buy)}
.chip.owner{background:transparent;border:1px solid var(--line);color:var(--muted);font-weight:500}
@media (prefers-color-scheme:dark){
  .chip.d{background:#1b2a52;color:#a9c2ff}.chip.r{background:#4a1e1b;color:#ffb3ac}
  .chip.i,.chip.ex,.chip.un{background:#2a2e34;color:#b6bcc6}
}
ul.chips{list-style:none;display:flex;flex-wrap:wrap;gap:.4rem;padding:0;margin:.4rem 0}
ul.chips li{background:var(--panel);border:1px solid var(--line);border-radius:99px;padding:.2rem .7rem;font-size:.85rem}

/* ---- leaderboard ---- */
ol.lb{list-style:none;padding:0;margin:.4rem 0}
ol.lb li{display:grid;grid-template-columns:auto 1fr auto;gap:.5rem;align-items:center;
  padding:.32rem 0;border-bottom:1px solid var(--line);font-size:.88rem}
ol.lb li span.muted{grid-column:2/4;font-size:.75rem;margin-top:-.2rem}
.bars{display:block;width:100%;height:6px;border-radius:3px;overflow:hidden;background:var(--line);min-width:40px}
.bars rect.b{fill:var(--buy)} .bars rect.s{fill:var(--sell)}

/* ---- forms ---- */
.filters,.chartbar{display:flex;flex-wrap:wrap;gap:.6rem 1rem;align-items:end;
  background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:.7rem .9rem;margin:.8rem 0}
.filters label,.chartbar label{display:flex;flex-direction:column;gap:.2rem;
  font-size:.72rem;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.filters input,.filters select,.chartbar input,.chartbar select{
  padding:.32rem .5rem;border:1px solid var(--line);border-radius:6px;
  background:var(--bg);color:var(--ink);font-size:.88rem}
button,.btn{padding:.38rem .8rem;border:1px solid var(--line);border-radius:7px;
  background:var(--accent);color:#fff;font-size:.85rem;cursor:pointer}
.btn.ghost,button.ghost{background:var(--panel);color:var(--ink)}
.btn.ghost:hover{border-color:var(--accent);text-decoration:none}
.bigsearch{display:flex;gap:.5rem;margin:1rem 0;max-width:560px}
.bigsearch input{flex:1;padding:.6rem .8rem;border:1px solid var(--line);border-radius:8px;
  background:var(--panel);color:var(--ink);font-size:1rem}
.pagehead{display:flex;justify-content:space-between;align-items:start;gap:1rem;flex-wrap:wrap}
.headlinks{display:flex;gap:.4rem;flex-wrap:wrap}
.resultline{margin:.3rem 0 .8rem;font-size:.85rem}
ul.results{list-style:none;padding:0}
ul.results li{padding:.35rem 0;border-bottom:1px solid var(--line)}
.pager{display:flex;gap:1rem;align-items:center;justify-content:center;margin:1rem 0;font-size:.9rem}
.pager .off{color:var(--line)}
.more{font-size:.9rem}

/* ---- chart ---- */
.chartcard{background:var(--panel);border:1px solid var(--line);border-radius:12px;
  padding:.2rem .9rem 1rem;margin:1rem 0}
.chartcard .chartbar{border:0;border-bottom:1px solid var(--line);border-radius:0;
  padding-left:0;padding-right:0;margin-top:0}
.ctrlgroup{display:flex;gap:.6rem 1rem;flex-wrap:wrap;align-items:end}
.ctrlgroup.right{margin-left:auto;align-items:center}
.chart{width:100%;height:520px}
.chart.tape{height:min(760px,max(320px,var(--tape-h,440px)))}
.chartnote{font-size:.85rem;min-height:1.2em;margin:.3rem 0 0}
.chartnote.err{color:var(--warn)}
.rangesel{display:inline-flex;border:1px solid var(--line);border-radius:7px;overflow:hidden}
.rangesel button{background:var(--panel);color:var(--muted);border:0;border-right:1px solid var(--line);
  border-radius:0;padding:.28rem .55rem;font-size:.78rem}
.rangesel button:last-child{border-right:0}
.rangesel button.on{background:var(--accent);color:#fff}
label.tog{flex-direction:row;align-items:center;gap:.3rem;text-transform:none;
  font-size:.8rem;letter-spacing:0}
.legendhint{margin:.5rem 0 0}
.legendhint .k{font-weight:700;margin-left:.6rem}
.legendhint .k.buy{color:var(--buy)}.legendhint .k.sell{color:var(--sell)}.legendhint .k.ex{color:var(--ex)}

/* ==========================================================================
   VALUATION (contract §11) — appended block, nothing above this line changes.

   The house colour rule for this app is Henry's Excel rule, not a decoration:
     blue   (--in)   an input, something a human typed;
     black  (--ink)  a calculated value, something the model derived;
     green  (--link) a cross-reference, something pulled in from elsewhere —
                     a saved beta_estimate, a price out of price_daily, the
                     window a regression actually used.
   Reading a page therefore tells you where every number came from before you
   read a word of it, which is the whole point of colouring a spreadsheet.
   ========================================================================== */

/* --link already exists; --link-bg / --in-bg are the tints the cross-reference
   and input chips sit on.  Defined here rather than edited into :root above so
   this block stays purely additive. */
:root{ --link-bg:#e7f4ed; --in-bg:#eaf0ff; --sens-on:#dbe6ff; }
@media (prefers-color-scheme:dark){
  :root{ --link-bg:#123024; --in-bg:#1b2a52; --sens-on:#22315c; }
}

/* ---- page shell: assumptions left, computation right (contract §11) ---- */
.wacc-cols{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
@media(max-width:1080px){.wacc-cols{grid-template-columns:1fr}}

/* ---- the three number voices ---- */
.in,.calc,.xref{font-family:var(--mono);font-variant-numeric:tabular-nums}
.in{color:var(--in)}
.calc{color:var(--ink)}
.xref{color:var(--link)}
a.xref{color:var(--link);text-decoration:underline;text-decoration-style:dotted}
.xref-chip{display:inline-block;background:var(--link-bg);color:var(--link);
  border-radius:5px;padding:.05rem .4rem;font-size:.76rem;font-family:var(--mono)}

/* ---- assumptions form ---- */
.vform{margin:0}
.vfs{border:1px solid var(--line);border-radius:12px;background:var(--panel);
  padding:.3rem 1rem 1rem;margin:0 0 1rem}
.vfs legend{padding:0 .45rem;font-size:.78rem;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--muted)}
.vfs.subject legend{color:var(--accent)}
.vfield{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.1rem .8rem;
  align-items:baseline;padding:.5rem 0;border-bottom:1px dotted var(--line)}
.vfs .vfield:last-of-type{border-bottom:0;padding-bottom:.1rem}
.vfield .vlabel{font-size:.88rem}
.vfield .vlabel .sym{font-family:var(--mono);color:var(--muted);margin-left:.3rem}
.vfield .vctl{display:flex;align-items:baseline;gap:.4rem;justify-self:end}
.vfield .vhint{grid-column:1/-1;font-size:.79rem;line-height:1.45;color:var(--muted);
  max-width:62ch;margin:.15rem 0 0}
.vfield .unit{font-size:.78rem;color:var(--muted);min-width:2.2em}
.vform input[type=number],.vform input[type=text],.vform input[type=date],
.vform select{padding:.3rem .45rem;border:1px solid var(--line);border-radius:6px;
  background:var(--bg);color:var(--ink);font-size:.9rem}
.vform input.in{width:8.5rem;text-align:right;font-weight:600;background:var(--in-bg);
  border-color:color-mix(in srgb,var(--in) 35%,var(--line))}
.vform input.in:focus{outline:2px solid var(--in);outline-offset:1px}
.vform input.in.wide{width:11rem;text-align:left}
.vform select.in{color:var(--in);font-weight:600;background:var(--in-bg);
  border-color:color-mix(in srgb,var(--in) 35%,var(--line))}
.vform select.xref{color:var(--link);font-weight:600;background:var(--link-bg);
  border-color:color-mix(in srgb,var(--link) 35%,var(--line));max-width:22rem}
.vform input.xref{color:var(--link);background:var(--link-bg);
  border-color:color-mix(in srgb,var(--link) 35%,var(--line))}
/* Amber: a derived value that is an approximation rather than a fact -- a
   market cap off a combined multi-class share count, or off the weighted
   average diluted count when no point-in-time count is filed. Green would
   claim more than we know; blue would claim Henry typed it. */
.vform input.approx{color:var(--warn);background:var(--warn-bg);
  border-color:color-mix(in srgb,var(--warn) 35%,var(--line))}
.vform input.approx.wide{width:11rem;text-align:left}
/* The provenance line under a derived field: what was multiplied by what, and
   as of when. Same colour as the box it explains. */
.vfield .vsrc{grid-column:1/-1;margin:.1rem 0 0;font-size:.76rem;
  font-family:var(--mono);color:var(--muted)}
.vfield .vsrc.xref{color:var(--link)}
.vfield .vsrc.approx{color:var(--warn)}
/* What today's market cap displaced. Muted, not a warning -- the override is
   the intended behaviour; this line only stops it being invisible. */
.vfield .vsrc.replaced{color:var(--muted);font-style:italic}
.vfield .vwarn{grid-column:1/-1;margin:.25rem 0 0;padding:.28rem .5rem;
  border-radius:6px;font-size:.79rem;line-height:1.4;
  background:var(--warn-bg);color:var(--warn)}
.vfield .vwarn::before{content:"⚠ ";font-weight:700}
.vfield.tog{grid-template-columns:1fr}
.vfield.tog .vctl{justify-self:start}
.vfield.tog label{display:flex;gap:.4rem;align-items:center;font-size:.88rem}
.vsub{margin:.1rem 0 .5rem;font-size:.79rem;color:var(--muted)}
.modeswitch{display:inline-flex;border:1px solid var(--line);border-radius:7px;overflow:hidden}
.modeswitch button{background:var(--panel);color:var(--muted);border:0;border-radius:0;
  border-right:1px solid var(--line);padding:.26rem .6rem;font-size:.8rem}
.modeswitch button:last-child{border-right:0}
.modeswitch button.on{background:var(--in);color:#fff}
[hidden]{display:none !important}

/* ---- computation column: formula, substitution, result ---- */
.vcalc{position:sticky;top:5.4rem}
@media(max-width:1080px){.vcalc{position:static}}
.vcalc h2{margin-top:0}
.vstep{border:1px solid var(--line);border-left:3px solid var(--line);border-radius:10px;
  background:var(--panel);padding:.6rem .9rem;margin:0 0 .6rem}
.vstep h3{margin:0 0 .3rem;font-size:.8rem;font-weight:700;letter-spacing:.045em;
  text-transform:uppercase;color:var(--muted)}
.vstep .vformula{margin:0;font-family:var(--mono);font-size:.86rem;color:var(--muted)}
.vstep .vsubst{margin:.15rem 0 .3rem;font-family:var(--mono);font-size:.86rem;
  color:var(--in);word-break:break-word}
.vstep .vres{margin:0;font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:1.15rem;font-weight:700;color:var(--ink)}
.vstep .vres .unit{font-size:.8rem;font-weight:400;color:var(--muted);margin-left:.2rem}
.vstep.on{border-left-color:var(--accent)}

/* the headline number, in large type under the four steps */
.waccbox{border:1px solid var(--line);border-radius:12px;background:var(--panel);
  padding:.9rem 1rem;margin:.9rem 0}
.waccbox .k{font-size:.78rem;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--muted)}
.waccbig{display:block;font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:3rem;line-height:1.05;letter-spacing:-.035em;font-weight:700;color:var(--ink)}
.waccbig .unit{font-size:1.2rem;letter-spacing:0;color:var(--muted)}
.waccbox .recap{margin:.35rem 0 0;font-size:.83rem;color:var(--muted)}
.waccbox .recap b{font-family:var(--mono);color:var(--ink);font-weight:600}

/* ---- notes: warnings render inline and never hide the number ---- */
.vnote{margin:.4rem 0 0;padding:.3rem .55rem;border-radius:7px;font-size:.82rem;
  line-height:1.4;background:var(--warn-bg);color:var(--warn)}
.vnote.hard{background:var(--sell-bg);color:var(--sell)}
.vnote.info{background:transparent;color:var(--muted);padding-left:0}
.vnote::before{content:"⚠ ";font-weight:700}
.vnote.info::before{content:""}
/* An inline caveat that has to sit inside a table cell rather than under a
   step -- the "this security is filed as an option" flag on the Beta page. */
.vnote.inline{display:inline-block;margin:.15rem 0 0;padding:.1rem .35rem;
  font-size:.76rem}

/* The computation column, dimmed and struck while the server is refusing the
   current inputs.  The last good numbers deliberately stay on screen (retyping
   a rate should not blank the page), but a 4-digit WACC must not go on looking
   like the answer to a form the API has just rejected. */
.vcalc.stale{opacity:.42;filter:grayscale(.55)}
.vcalc.stale .waccbig{text-decoration:line-through;
  text-decoration-thickness:.06em;text-decoration-color:var(--sell)}
.vcalc.stale #wacc-status{opacity:1;filter:none}

/* ---- 5x5 sensitivity grid ---- */
.senswrap{overflow-x:auto;border:1px solid var(--line);border-radius:10px;background:var(--panel)}
table.sens{border-collapse:collapse;width:100%;font-size:.84rem;
  font-variant-numeric:tabular-nums;font-family:var(--mono)}
table.sens caption{caption-side:top;text-align:left;padding:.5rem .7rem 0;
  font-family:inherit;font-size:.78rem;font-weight:700;letter-spacing:.045em;
  text-transform:uppercase;color:var(--muted)}
table.sens th,table.sens td{padding:.35rem .6rem;text-align:right;
  border-bottom:1px solid var(--line);white-space:nowrap}
table.sens thead th{font-size:.76rem;color:var(--muted);font-weight:600}
table.sens tbody th{color:var(--muted);font-weight:600}
table.sens tbody tr:last-child th,table.sens tbody tr:last-child td{border-bottom:0}
table.sens td.on{background:var(--sens-on);color:var(--ink);font-weight:700;
  box-shadow:inset 0 0 0 2px var(--accent)}
table.sens .corner{color:var(--muted);text-align:left;font-weight:600}

/* ---- scenarios ---- */
.scenrow{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center;margin:.2rem 0 .6rem}
ul.scenlist{list-style:none;padding:0;margin:.3rem 0 0;font-size:.86rem}
ul.scenlist li{display:flex;gap:.5rem;align-items:baseline;flex-wrap:wrap;
  padding:.35rem 0;border-bottom:1px solid var(--line)}
ul.scenlist li:last-child{border-bottom:0}
ul.scenlist .nm{font-weight:600}
ul.scenlist .sp{margin-left:auto;display:flex;gap:.45rem}
ul.scenlist button{padding:.16rem .5rem;font-size:.78rem}

/* ---- beta page ---- */
.betaform{align-items:end}
.betaform input[type=text]{width:7rem;font-family:var(--mono);text-transform:uppercase}
.betaform input[type=number]{width:5.5rem;text-align:right;font-family:var(--mono)}
.datalimit{border:1px solid var(--line);border-left:3px solid var(--link);
  border-radius:10px;background:var(--panel);padding:.6rem .9rem;margin:.8rem 0;
  font-size:.85rem;line-height:1.5}
.datalimit b{font-family:var(--mono)}
.betagrid{display:grid;grid-template-columns:minmax(0,340px) minmax(0,1fr);gap:1.2rem;
  align-items:start}
@media(max-width:960px){.betagrid{grid-template-columns:1fr}}
table.stats{border-collapse:collapse;width:100%;font-size:.87rem}
table.stats th,table.stats td{padding:.3rem .55rem;border-bottom:1px solid var(--line);
  text-align:left;vertical-align:baseline}
table.stats th{font-weight:500;color:var(--muted);white-space:nowrap}
table.stats td{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
table.stats tr:last-child th,table.stats tr:last-child td{border-bottom:0}
table.stats tr.hi td{font-size:1.05rem;font-weight:700}
.eqline{font-family:var(--mono);font-size:.95rem;background:var(--panel);
  border:1px solid var(--line);border-radius:8px;padding:.45rem .7rem;margin:.2rem 0 .6rem;
  overflow-x:auto;white-space:nowrap}
.chart.scatter{height:460px}
.usewacc{display:flex;gap:.35rem;white-space:nowrap}
.usewacc a{font-size:.78rem;padding:.14rem .45rem;border:1px solid var(--line);
  border-radius:6px;color:var(--link)}
.usewacc a:hover{border-color:var(--link);text-decoration:none}
table.data td button.ghost{font-size:.78rem;padding:.14rem .45rem}

/* An optional, collapsed sub-control inside a fieldset -- today only the
   Hamada re-lever box in Step 1.  Closed by default on purpose: it is the right
   thing to reach for with a regression β and target weights, and the wrong
   thing to imply every WACC needs. */
.vdetails{grid-column:1/-1;margin:.1rem 0 .5rem;border:1px dashed var(--line);
  border-radius:9px;background:var(--panel)}
.vdetails summary{cursor:pointer;padding:.4rem .7rem;font-size:.8rem;
  font-weight:600;color:var(--muted)}
.vdetails[open] summary{border-bottom:1px solid var(--line);color:var(--ink)}
.vdetails .vfield{padding:.5rem .7rem;border-bottom:0}

/* ---- dcf placeholder ---- */
.soon{max-width:76ch}
.soon ul{padding-left:1.1rem}
.soon li{margin:.25rem 0}

/* ==========================================================================
   DCF + FINANCIALS (brief §8) — appended block, nothing above this line changes.

   The three number voices of the Valuation block above (blue input, black
   calculated, green cross-reference) gain the two the statements need, and
   they are Henry's spreadsheet legend, not decoration (brief §3):

     gray   (--hist)  a historical actual, filed with the SEC and not ours to
                      change — every column left of the divider on the
                      Statements panel, and the whole ratio table;
     amber  (--plug)  the one balance-sheet line that absorbs the financing
                      need, and any check that did not tie.

   So a reader who knows only the legend can tell a filed number from a
   projected one from the plug before reading a single label, which is the
   entire reason a case workbook is coloured at all.
   ========================================================================== */

/* --hist is deliberately darker than --muted: --muted is for prose that may
   recede, and a filed number must stay readable while still reading as "not a
   forecast".  --plug reuses the warning hue because a plug and a failed check
   are the same instruction to the reader: look here. */
:root{ --hist:#5b6471; --hist-bg:#f4f3f0; --plug:#a1560a; --plug-bg:#fdf1e3;
       --ok:#0f7a4d; --ok-bg:#e7f4ed; }
@media (prefers-color-scheme:dark){
  :root{ --hist:#9aa1ab; --hist-bg:#1e2126; --plug:#e3a462; --plug-bg:#33240f;
         --ok:#4ade80; --ok-bg:#123024; }
}

/* ---- pill tabs: the DCF's four panels on one page (brief §8) ----
   Buttons, not links, and not four routes: the panels share one computation,
   so switching must not re-POST the model.  role="tablist" is on the row in
   the markup; these rules only carry the look. */
.pills{display:flex;flex-wrap:wrap;gap:.35rem;margin:1rem 0 .2rem;
  border-bottom:1px solid var(--line);padding-bottom:.5rem}
.pills button{background:var(--panel);color:var(--muted);border:1px solid var(--line);
  border-radius:99px;padding:.32rem .95rem;font-size:.86rem;font-weight:600}
.pills button:hover{color:var(--ink);border-color:var(--accent)}
.pills button[aria-selected="true"]{background:var(--accent);color:#fff;
  border-color:var(--accent)}
.pills button .badge{display:inline-block;margin-left:.4rem;padding:0 .35rem;
  border-radius:99px;font-size:.72rem;background:var(--sell-bg);color:var(--sell)}
.pills button[aria-selected="true"] .badge{background:rgba(255,255,255,.22);color:#fff}
.panel{margin-top:.6rem}
.panel > h2:first-child{margin-top:.6rem}

/* ---- the legend, printed on both pages so the colours are never folklore ---- */
.swatches{display:flex;flex-wrap:wrap;gap:.2rem 1rem;margin:.4rem 0 .9rem;
  font-size:.82rem;color:var(--muted)}
.swatches b{font-family:var(--mono);font-weight:700}
/* Named as bare classes, not descendants of .swatches, because the same five
   words are used inline in the panels' prose ("the plug row is marked") and a
   legend whose colours only exist inside the legend teaches nothing. */
.hist{color:var(--hist)} .plug{color:var(--plug)} .ok{color:var(--ok)}

/* ---- financials header: the five facts a statement has to state ---- */
.fhead{display:flex;flex-wrap:wrap;gap:.5rem;align-items:stretch;margin:.9rem 0}
.fhead .f{background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:.5rem .8rem;min-width:9rem}
.fhead .f span{display:block;font-size:.72rem;text-transform:uppercase;
  letter-spacing:.045em;color:var(--muted)}
.fhead .f b{font-family:var(--mono);font-weight:600;font-size:.95rem;
  letter-spacing:-.01em}
.fhead .f.act{display:flex;flex-direction:column;justify-content:center;gap:.35rem;
  align-items:flex-start}
/* The fetch job's status line.  It is a <p>, not a toast: a 4 MB companyfacts
   download takes a while and the page must still say what happened after the
   reader has looked away. */
.jobline{margin:.15rem 0 0;font-size:.8rem;color:var(--muted);
  font-family:var(--mono)}
.jobline.run{color:var(--accent)} .jobline.err{color:var(--sell)}
.jobline.done{color:var(--ok)}

/* ---- statement tables: filed years gray, projected years black ----
   `table.fin` is a data table with a frozen label column, because a five-year
   income statement is wider than a laptop and the row label is the one cell
   that must never scroll away. */
.fintable{overflow-x:auto;border:1px solid var(--line);border-radius:10px;
  background:var(--panel);margin:.5rem 0 1.1rem}
table.fin{border-collapse:separate;border-spacing:0;width:100%;font-size:.85rem}
table.fin th,table.fin td{padding:.3rem .7rem;white-space:nowrap;
  border-bottom:1px solid var(--line)}
table.fin thead th{position:sticky;top:0;z-index:2;background:var(--panel);
  font-size:.74rem;text-transform:uppercase;letter-spacing:.045em;
  color:var(--muted);text-align:right;font-weight:600}
table.fin thead th.lab,table.fin tbody th{text-align:left;font-weight:500}
table.fin tbody th{position:sticky;left:0;z-index:1;background:var(--panel);
  font-weight:400;max-width:26rem;white-space:normal}
table.fin thead th.lab{left:0;z-index:3}
table.fin td{text-align:right;font-family:var(--mono);
  font-variant-numeric:tabular-nums}
table.fin tbody tr:hover th,table.fin tbody tr:hover td{
  background:color-mix(in srgb,var(--accent) 5%,var(--panel))}
/* The three voices, applied per cell so one row can carry both. */
table.fin td.hist,table.fin thead th.hist{color:var(--hist)}
table.fin td.proj{color:var(--ink)}
table.fin td.na{color:var(--muted)}
/* The divider between what was filed and what is forecast — one line, drawn
   once, so the eye finds the boundary without reading the header. */
table.fin .split{border-left:2px solid var(--line)}
table.fin tr.total th,table.fin tr.total td{font-weight:700;
  border-top:1px solid var(--line)}
table.fin tr.sect th{font-size:.72rem;text-transform:uppercase;
  letter-spacing:.05em;color:var(--muted);padding-top:.7rem;font-weight:700;
  background:var(--panel)}
table.fin tr.sect td{background:var(--panel)}
/* The plug (brief §6.2).  Marked on the row, not just noted underneath: it is
   the one line on the balance sheet nobody chose. */
table.fin tr.plug th,table.fin tr.plug td{background:var(--plug-bg);
  color:var(--plug);font-weight:600}
.plugmark{display:inline-block;margin-left:.4rem;padding:0 .35rem;
  border-radius:5px;background:var(--plug);color:#fff;font-size:.66rem;
  font-family:var(--mono);letter-spacing:.04em;vertical-align:middle}
.derivmark{margin-left:.35rem;font-size:.7rem;color:var(--muted);
  font-family:var(--mono)}
.derivmark.missing{color:var(--plug)}
table.fin tr.xrow th,table.fin tr.xrow td{background:var(--hist-bg)}

/* ---- check cells: Match / No match, per year (brief §8 panel 4) ---- */
.chk{display:inline-block;padding:.02rem .4rem;border-radius:5px;
  font-size:.72rem;font-weight:700;letter-spacing:.02em;font-family:var(--mono)}
.chk.ok{background:var(--ok-bg);color:var(--ok)}
.chk.info{background:var(--hist-bg);color:var(--hist)}
.chk.skipped{background:var(--hist-bg);color:var(--muted)}
.chk.warn{background:var(--plug-bg);color:var(--plug)}
.chk.fail{background:var(--sell-bg);color:var(--sell)}
table.fin td .d{display:block;font-size:.74rem;color:var(--muted)}
table.fin td.fail{background:var(--sell-bg)}
table.fin td.warn{background:var(--plug-bg)}
.checksum{margin:.3rem 0 .6rem;font-size:.86rem}
.checksum b{font-family:var(--mono)}
.checknotes{margin:.4rem 0 1rem;padding-left:1.1rem;font-size:.82rem;
  color:var(--muted)}
.checknotes li{margin:.2rem 0}

/* ---- assumptions panel: one row per driver, grouped like Table 5a ---- */
.dgroup{border:1px solid var(--line);border-radius:12px;background:var(--panel);
  padding:.2rem .9rem .7rem;margin:0 0 .9rem}
.dgroup > h3{margin:.7rem 0 .2rem;font-size:.78rem;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.dgroup > p.hint{margin:.1rem 0 .5rem;font-size:.79rem;color:var(--muted);
  max-width:64ch}
.drow{display:grid;grid-template-columns:minmax(9rem,1fr) 10.5rem 7.5rem 2.4rem 1.6rem;
  gap:.3rem .5rem;align-items:center;padding:.28rem 0;
  border-bottom:1px dotted var(--line)}
.drow:last-child{border-bottom:0}
.drow .lab{font-size:.85rem}
.drow .lab .code{font-family:var(--mono);font-size:.74rem;color:var(--muted);
  margin-left:.35rem}
.drow select,.drow input{padding:.24rem .4rem;border:1px solid var(--line);
  border-radius:6px;background:var(--bg);color:var(--ink);font-size:.84rem;
  width:100%;font-family:var(--mono)}
.drow input{text-align:right;font-weight:600}
.drow input.in{color:var(--in);background:var(--in-bg);
  border-color:color-mix(in srgb,var(--in) 35%,var(--line))}
.drow input.xref{color:var(--link);background:var(--link-bg);
  border-color:color-mix(in srgb,var(--link) 35%,var(--line))}
.drow .unit{font-size:.76rem;color:var(--muted)}
.drow .peryear{padding:.1rem .35rem;font-size:.72rem}
.drow .peryear.on{background:var(--in);color:#fff;border-color:var(--in)}
.dseries{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:.3rem;
  padding:.15rem 0 .4rem}
.dseries label{display:flex;flex-direction:column;gap:.1rem;font-size:.7rem;
  color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.dseries input{width:5.4rem}
@media(max-width:720px){.drow{grid-template-columns:1fr 1fr;}
  .drow .lab{grid-column:1/-1}}

/* ---- valuation panel: two methods, side by side, and the bridge ---- */
.twoup{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr));
  gap:1rem;align-items:start}
.methodcard{border:1px solid var(--line);border-radius:12px;background:var(--panel);
  padding:.7rem .95rem}
.methodcard h3{margin:0 0 .3rem;font-size:.8rem;font-weight:700;
  letter-spacing:.045em;text-transform:uppercase;color:var(--muted)}
.methodcard .big{display:block;font-family:var(--mono);
  font-variant-numeric:tabular-nums;font-size:2.1rem;line-height:1.1;
  letter-spacing:-.03em;font-weight:700}
.methodcard .big .unit{font-size:.9rem;letter-spacing:0;color:var(--muted);
  font-weight:400;margin-left:.2rem}
.methodcard .vs{margin:.25rem 0 0;font-size:.84rem;color:var(--muted)}
.methodcard .vs b{font-family:var(--mono);color:var(--ink)}
.methodcard .vs .up{color:var(--buy)} .methodcard .vs .down{color:var(--sell)}
/* "no stored price" is a first-class answer, not an empty cell (contract §1.4).
   ADT is in the universe on purpose and has no row in price_daily at all. */
.noprice{color:var(--plug);font-style:normal;font-family:var(--mono);
  font-size:.82rem}
table.fin td.money::after{content:""}
.gridpair{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,26rem),1fr));
  gap:1rem;align-items:start;margin:.6rem 0}

/* ---- financials/DCF picker row ---- */
.tickerbar{display:flex;flex-wrap:wrap;gap:.6rem 1rem;align-items:end;
  background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:.7rem .9rem;margin:.8rem 0}
.tickerbar label{display:flex;flex-direction:column;gap:.2rem;font-size:.72rem;
  text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.tickerbar select,.tickerbar input{padding:.32rem .5rem;border:1px solid var(--line);
  border-radius:6px;background:var(--bg);color:var(--ink);font-size:.88rem;
  font-family:var(--mono)}
.tickerbar .sp{margin-left:auto;display:flex;gap:.45rem;align-items:center}
.csvlink{font-size:.78rem;font-family:var(--mono)}
.tablehead{display:flex;gap:.6rem;align-items:baseline;flex-wrap:wrap;
  margin:1.4rem 0 .2rem}
.tablehead h2,.tablehead h3{margin:0}
.tablehead .sp{margin-left:auto}

/* A driver row whose kind is `plug`: the value box is disabled because the
   number is solved, not typed, and the row carries the same amber the plug
   line carries on the Statements panel so the two read as one fact. */
.drow.plugrow{background:var(--plug-bg);border-radius:7px;padding-left:.4rem;
  padding-right:.4rem}
.drow.plugrow .lab{color:var(--plug);font-weight:600}
.drow input:disabled{opacity:.55;background:transparent}
/* `pct_of_line` needs to name the line it is a percentage of; a fourth control
   does not fit the five-column row, so it gets its own full-width one. */
.dref{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:.4rem .8rem;
  align-items:center;padding:.15rem 0 .4rem}
.dref label{display:flex;align-items:center;gap:.4rem;font-size:.78rem;
  color:var(--muted)}
.dref input{width:8rem}
/* Shared with the WACC page's Step 3 disclosures; defined here because that
   copy lives in a <style> block inside wacc.html and this file owns neither. */
.rowbtns{display:flex;flex-wrap:wrap;gap:.45rem;align-items:center;
  padding:.35rem 0 .1rem}
.rowbtns .sp{flex:1}
/* A panel dimmed and struck while the server is refusing the current
   assumptions.  Exactly `.vcalc.stale`'s argument: the last good numbers stay
   on screen (retyping a growth rate must not blank four tables) but four black
   tables must not go on looking like the answer to a body the API just rejected. */
.panel.stale{opacity:.42;filter:grayscale(.55)}

/* The driver row gained a sixth control -- brief §5.2's "switch any driver to a
   3-year or 5-year average" -- and a provenance chip.  `.src` is green because
   it says the number was cross-referenced from somewhere (last year's ratio, an
   average of them); it disappears the moment the box is typed into, because it
   would then be false. */
.drow{grid-template-columns:minmax(8rem,1fr) 9.5rem 6.5rem 2.2rem 2rem 2.8rem}
.drow .lab .src{display:inline-block;margin-left:.35rem;padding:0 .35rem;
  border-radius:5px;background:var(--link-bg);color:var(--link);
  font-family:var(--mono);font-size:.7rem}
@media(max-width:720px){.drow{grid-template-columns:1fr 1fr}}

/* ==========================================================================
   BEGINNER DCF (D-047, brief §8.5)
   --------------------------------------------------------------------------
   Two rules and a shape fix, and nothing else: the page is deliberately built
   out of the vocabulary that already exists.  The three-way "Based on" switch
   is `.modeswitch` (blue-filled, because picking a basis is an input); the
   "Add to Fair Value" row is `.vfield.tog`; the two stage cards are
   `.methodcard` inside `.twoup`, which collapses itself at one column with no
   media query; the fair value is `.waccbox`/`.waccbig`; the refusals are
   `.vnote` and `.datalimit`.  Only the +/- stepper had no existing form.

   It cannot be built out of bare `<button>`s: the global rule above fills every
   button with the accent colour, so a naked [-] [+] pair beside a number would
   read as two large blue blobs competing with the value between them.  These
   are panel-coloured and muted until hovered, which is the same weight
   `.modeswitch` gives an unselected segment.
   ========================================================================== */
.vstepper{display:inline-flex;align-items:center;gap:.3rem}
.vstepper button{width:1.7rem;padding:.14rem 0;background:var(--panel);
  color:var(--muted);border:1px solid var(--line);border-radius:6px;
  line-height:1;font-size:.9rem;font-family:var(--mono)}
.vstepper button:hover{color:var(--ink);border-color:var(--in)}
.vstepper button:disabled{opacity:.45;cursor:default}
.vstepper button:disabled:hover{color:var(--muted);border-color:var(--line)}
/* The number keeps its `.in` blue-box treatment but centres between the two
   buttons rather than right-aligning against one of them. */
.vform .vstepper input.in,.vform .vstepper input.xref{width:5rem;text-align:center}

/* Moved out of the <style> block in wacc.html, which has said since D-026 that
   it belongs here: `.in` carries a width, an alignment and a weight while
   `.xref` carries only colours, so a box that turns green also changes shape.
   The Beginner page's base-value box switches between the two on every edit --
   green while it is the figure read off the filing, blue the moment it is typed
   over -- which made a second copy of the patch the alternative to this move. */
.vform input.xref{width:8.5rem;text-align:right;font-weight:600}
.vform input.xref.wide{width:11rem;text-align:left}

/* ==========================================================================
   BEGINNER ⇄ ADVANCED MODEL SWITCH (D-048)
   --------------------------------------------------------------------------
   The same shape as `.modeswitch` -- the reader has already learned that a
   segmented pill means "these are the alternatives, one is current" from the
   Based-on control and the terminal-value tabs -- but built from <a> rather
   than <button>, because the two sides are two pages.  It therefore cannot
   reuse `.modeswitch`'s rules, which are all written against `button`.

   It sits in `.headlinks` beside the ghost buttons, so it has to match their
   height rather than the taller in-form segments: hence the smaller padding
   here than in `.modeswitch button`.
   ========================================================================== */
.modelswitch{display:inline-flex;border:1px solid var(--line);border-radius:7px;
  overflow:hidden;vertical-align:middle}
.modelswitch a{display:inline-block;padding:.3rem .7rem;background:var(--panel);
  color:var(--muted);font-size:.82rem;font-weight:600;text-decoration:none;
  border-right:1px solid var(--line);line-height:1.35}
.modelswitch a:last-child{border-right:0}
.modelswitch a:hover{color:var(--ink)}
.modelswitch a.on{background:var(--in);color:#fff}
.modelswitch a.on:hover{color:#fff}

/* ================================================================= stock page
   The company page (D-054) and the relative-valuation tool (D-055).

   Nothing here invents a token: every colour is one of the six declared at the
   top of this file, so both pages follow the light/dark switch with the rest of
   the site and a theme change is still one edit in one place. */

/* The quote line under the ticker. `.up`/`.down` reuse the buy/sell pair rather
   than a third green and a third red -- a rising price and a disclosed purchase
   are the same colour everywhere else on this site. */
.quoteline{margin:.15rem 0 0;display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap}
.quoteline .px{font-family:var(--mono);font-size:1.35rem;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums}
.quoteline .chg{font-family:var(--mono);font-size:.95rem;font-variant-numeric:tabular-nums}
.quoteline .chg.up{color:var(--buy)}
.quoteline .chg.down{color:var(--sell)}

/* The key-statistics dashboard: three columns of label/value rows, the shape of
   the screenshot this was built from.  Three separate <dl>s rather than one
   grid, because the hairline belongs *between rows of a column* and a single
   grid in column-major order cannot express "last row of each column has no
   rule" without knowing the row count. */
.keystats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:0 1.8rem;margin:.2rem 0 .8rem;padding:.1rem 1.1rem;
  border:1px solid var(--line);border-radius:12px;background:var(--panel)}
.kcol{margin:0}
.kcell{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  padding:.66rem 0;border-bottom:1px solid var(--line)}
.kcol .kcell:last-child{border-bottom:0}
.kcell dt{color:var(--muted);font-size:.88rem}
.kcell dd{margin:0;font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:.95rem;letter-spacing:-.01em;white-space:nowrap}
.kcell .v.none{color:var(--muted);font-weight:400;cursor:help}
/* The asterisk marks a figure that is real but would be misread without its
   caveat -- an average-quarter dividend, an amber share count.  It is a link to
   the sentence, not decoration, so it gets a cursor and a title. */
.kcell abbr{margin-left:.15rem;color:var(--warn);text-decoration:none;cursor:help}
.statnotes{margin:.2rem 0 1.2rem;padding-left:1.1rem}
.statnotes li{margin:.22rem 0}
@media(max-width:900px){.keystats{grid-template-columns:1fr;gap:0}
  .kcol .kcell:last-child{border-bottom:1px solid var(--line)}
  .keystats .kcol:last-child .kcell:last-child{border-bottom:0}}

/* The tools rail.  An unavailable tool keeps its place and loses its link --
   greying it out and saying why is the whole point, so `.off` must stay
   legible rather than being dimmed into unreadability. */
.stockcols{margin-top:1rem}
.toolrail h2{margin-top:0}
.toollist{list-style:none;margin:.4rem 0 .8rem;padding:0;display:grid;gap:.45rem}
.toollist .tool a,.toollist .tool>div{display:block;padding:.6rem .75rem;
  border:1px solid var(--line);border-radius:10px;background:var(--panel)}
.toollist .tool a{color:inherit}
.toollist .tool a:hover{border-color:var(--accent);text-decoration:none}
.toollist .tool b{display:block;font-size:.92rem;margin-bottom:.15rem}
.toollist .tool span{display:block;line-height:1.35}
.toollist .tool.off>div{background:transparent;border-style:dashed}
.toollist .tool.off b{color:var(--muted)}
.toollist .tool .why{margin-top:.4rem;color:var(--warn);font-size:.78rem;line-height:1.35}

/* A chart note that carries a clipping warning rather than an error: amber, not
   red -- the window was served, it was just narrower than asked for. */
.chartnote.warnline{color:var(--warn)}

.bigsearch{display:flex;gap:.5rem;margin:.8rem 0 .4rem;max-width:46rem}
.bigsearch input{flex:1;min-width:0;padding:.5rem .7rem;border:1px solid var(--line);
  border-radius:8px;background:var(--panel);color:var(--ink);font-size:1rem}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* The relative-valuation table.  The live column and the two projected ones are
   tinted apart from the measured fiscal years, because "what the market pays
   today" and "what this model thinks it will earn" are different kinds of claim
   from "what the filing said", and a reader scanning a row must not have to
   remember which columns are which. */
.reltable th[scope=row]{font-weight:500;white-space:nowrap}
.reltable td.live,.reltable th.live{background:color-mix(in srgb,var(--accent) 7%,transparent)}
.reltable td.fwd,.reltable th.fwd{background:var(--warn-bg);
  border-left:1px solid color-mix(in srgb,var(--warn) 35%,var(--line))}
.reltable th .muted{display:block;font-weight:400;text-transform:none;letter-spacing:0}
.reltable .grouprow th{background:var(--bg);color:var(--muted);font-size:.72rem;
  text-transform:uppercase;letter-spacing:.06em;padding-top:.6rem}
.reltable .none{color:var(--muted);cursor:help}
