/* ============================================================
   DIVIDENDRUM - twelve months forward from twelve months past
   Palette: deep aubergine ground · amethyst interaction ·
            antique gold reserved for money
   Type:    Cinzel (ceremonial) · Spectral (reading) · Plex Mono (data)

   The token block, page furniture and control styling are shared with
   Triviagon so the two sites read as one hand. Everything below the
   "dividendrum" divider is this tool's own.
   ============================================================ */

:root{
  --bg:#EDEAF2; --surface:#FBFAFD; --surface-2:#E4DFEE; --sunken:#E9E5F1;
  --ink:#1C1526; --ink-soft:#5F5673; --ink-faint:#6D6380;
  --line:#D3CBE0; --line-soft:#E2DCEC;
  --accent:#6D3FBF; --accent-2:#8B62D9; --accent-soft:#EDE4FB; --accent-ink:#FFFFFF;
  --gold:#8F6B18; --gold-2:#B8912F; --gold-soft:#F6EED9;
  --good:#2C7350; --good-bg:#DEEFE6; --bad:#A5364A; --bad-bg:#F8E1E5; --warn:#8E6415; --warn-bg:#F5EAD6;
  --glow:rgba(109,63,191,.10);
  --shadow-sm:0 1px 2px rgba(28,21,38,.06);
  --shadow:0 2px 4px rgba(28,21,38,.05), 0 12px 32px rgba(28,21,38,.10);
  --shadow-lg:0 4px 8px rgba(28,21,38,.06), 0 24px 60px rgba(28,21,38,.16);
  --display:"Cinzel",Georgia,serif;
  --body:"Spectral",Georgia,"Times New Roman",serif;
  --mono:"IBM Plex Mono",ui-monospace,Consolas,monospace;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#120E1A; --surface:#1C1628; --surface-2:#261E36; --sunken:#171223;
    --ink:#EFE9F6; --ink-soft:#A79CBC; --ink-faint:#877C9C;
    --line:#332942; --line-soft:#2A2138;
    --accent:#B48CF7; --accent-2:#C9AAFF; --accent-soft:#291F44; --accent-ink:#150F22;
    --gold:#E2BA5F; --gold-2:#F0D28E; --gold-soft:#2E2413;
    --good:#5DC694; --good-bg:#14301F; --bad:#E7768A; --bad-bg:#2E1720; --warn:#E0B45C; --warn-bg:#2E2413;
    --glow:rgba(180,140,247,.13);
    --shadow-sm:0 1px 2px rgba(0,0,0,.5);
    --shadow:0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.5);
    --shadow-lg:0 4px 8px rgba(0,0,0,.45), 0 24px 60px rgba(0,0,0,.6);
  }
}
:root[data-theme="dark"]{
  --bg:#120E1A; --surface:#1C1628; --surface-2:#261E36; --sunken:#171223;
  --ink:#EFE9F6; --ink-soft:#A79CBC; --ink-faint:#877C9C;
  --line:#332942; --line-soft:#2A2138;
  --accent:#B48CF7; --accent-2:#C9AAFF; --accent-soft:#291F44; --accent-ink:#150F22;
  --gold:#E2BA5F; --gold-2:#F0D28E; --gold-soft:#2E2413;
  --good:#5DC694; --good-bg:#14301F; --bad:#E7768A; --bad-bg:#2E1720; --warn:#E0B45C; --warn-bg:#2E2413;
  --glow:rgba(180,140,247,.13);
  --shadow-sm:0 1px 2px rgba(0,0,0,.5);
  --shadow:0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.5);
  --shadow-lg:0 4px 8px rgba(0,0,0,.45), 0 24px 60px rgba(0,0,0,.6);
}

*{box-sizing:border-box}
body{
  margin:0; min-height:100vh; background:var(--bg); color:var(--ink);
  font-family:var(--body); font-size:17px; line-height:1.6;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
body::before{
  content:""; position:fixed; inset:0; z-index:-2; pointer-events:none;
  background:radial-gradient(130% 70% at 50% -8%, var(--glow) 0%, transparent 62%);
}
#app{max-width:41rem; margin:0 auto; padding:1.5rem 1.15rem 4.5rem; position:relative}
a{color:inherit}

/* ---------------- masthead ---------------- */
.masthead{text-align:center; padding:1.1rem 0 1rem; position:relative}
.crest{
  font-family:var(--display); font-weight:700; letter-spacing:.02em;
  font-size:clamp(1.25rem,5.6vw,2rem); line-height:1.12; margin:0; color:var(--ink); text-wrap:balance;
}
.crest a{text-decoration:none}
.crest .glyph{
  display:block; font-size:.62em; color:var(--gold); margin:0 auto .5rem;
  letter-spacing:.3em; text-indent:.3em; line-height:1;
}
/* Wide enough that the subheader sentence still leaves room for the hairlines
   either side of it. At 26rem the text overflowed its own rule and both
   hairlines collapsed to nothing, which reads as a layout accident rather
   than as a rule. */
.rule{display:flex; align-items:center; gap:.7rem; margin:.85rem auto 0; max-width:32rem; color:var(--line)}
.rule::before,.rule::after{content:""; flex:1; height:1px; background:currentColor}
.rule span{
  font-family:var(--mono); font-size:.6rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--ink-faint); white-space:nowrap;
}
/* A sentence rather than a label, so on a narrow screen it is wider than the
   column it sits in. Left as nowrap it pushes both hairlines to nothing and
   runs off the edge; allowed to wrap, it balances onto two lines and the rule
   still reads as a rule. */
@media (max-width:34rem){
  .rule{max-width:none}
  .rule span{white-space:normal; text-align:center; text-wrap:balance}
}
.homebtn{
  position:absolute; top:.9rem; left:0; font-family:var(--mono); font-size:.68rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--ink); text-decoration:none;
  background:var(--surface); border:1px solid var(--line); border-radius:999px;
  padding:.45rem .85rem; line-height:1; display:inline-block; box-shadow:var(--shadow-sm);
}
.homebtn:hover{color:var(--gold); border-color:var(--gold)}
.homebtn:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.hdr-actions{position:absolute; top:.9rem; right:0; display:flex; align-items:center; gap:.35rem}
.themebtn, .patbtn{
  font-family:var(--mono); font-size:.78rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink); background:var(--surface); border:1px solid var(--line); border-radius:999px;
  padding:.4rem .6rem; cursor:pointer; line-height:1; min-width:2rem; text-align:center;
  box-shadow:var(--shadow-sm);
}
.themebtn:hover, .patbtn:hover{color:var(--gold); border-color:var(--gold)}
.themebtn:focus-visible, .patbtn:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

/* ---------------- top nav ---------------- */
.topnav{display:flex; justify-content:center; gap:.4rem; margin:1.1rem 0 .2rem}
.topnav a{
  font-family:var(--display); font-size:.68rem; font-weight:600; letter-spacing:.16em;
  text-transform:uppercase; text-decoration:none; color:var(--ink-faint);
  padding:.42rem .95rem; border:1px solid var(--line); border-radius:999px;
  transition:color .18s ease, border-color .18s ease, background .18s ease;
}
.topnav a:hover{color:var(--ink); border-color:var(--ink-soft)}
.topnav a[aria-current="page"]{color:var(--accent); border-color:var(--accent); background:var(--accent-soft)}
.topnav a:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

/* ---------------- storage consent ----------------
   Sits under the subheader rather than in a footer or behind a modal, because
   it is a claim about the visitor's data made before they have typed any: the
   sentence and the control that acts on it want reading together, once, and
   then never again. Quiet enough to pass over if you do not care. */
.privnote{
  font-family:var(--mono); font-size:.575rem; letter-spacing:.055em; line-height:1.8;
  color:var(--ink-faint); text-align:center; text-wrap:balance;
  max-width:29rem; margin:1rem auto 0;
}
/* The segmented switch, shared by the storage choice here and the
   reinvestment choice on the chart. Two mutually exclusive readings of the
   same page, so a pill pair rather than a checkbox: both options stay named
   and visible, and neither is the "off" state of the other. */
.storetoggle, .seg{
  display:flex; justify-content:center; gap:2px; width:max-content;
  padding:2px; background:var(--sunken); border:1px solid var(--line); border-radius:999px;
}
.storetoggle{margin:.6rem auto 0}
.storetoggle button, .seg button{
  font-family:var(--mono); font-weight:500; font-size:.575rem; letter-spacing:.1em;
  text-transform:uppercase; line-height:1.2; padding:.36rem .85rem;
  border:0; border-radius:999px; background:transparent; color:var(--ink-faint);
}
.storetoggle button[aria-pressed="true"], .seg button[aria-pressed="true"]{
  background:var(--accent); color:var(--accent-ink);
}
.storetoggle button:not([aria-pressed="true"]):hover,
.seg button:not([aria-pressed="true"]):hover{color:var(--ink)}
.storetoggle button:focus-visible, .seg button:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
/* Empty until the toggle is used, and occupying nothing while empty, so the
   masthead carries no permanent gap for a message shown once. */
.storesaid{
  font-family:var(--mono); font-size:.55rem; letter-spacing:.08em; text-transform:uppercase;
  color:var(--good); text-align:center; margin:.5rem 0 0;
}
.storesaid:empty{display:none}
@media (max-width:26rem){
  .privnote{font-size:.54rem; line-height:1.75}
  .storetoggle button{padding:.36rem .6rem; letter-spacing:.07em}
}

/* ---------------- controls ---------------- */
input, select, textarea{
  font-family:var(--body); font-size:1.05rem; padding:.72rem .9rem;
  border:1.5px solid var(--line); border-radius:4px; background:var(--surface); color:var(--ink);
  transition:border-color .18s ease, box-shadow .18s ease; min-width:0;
}
input::placeholder, textarea::placeholder{color:var(--ink-faint); font-style:italic}
input:focus, select:focus, textarea:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft)}
button{
  font-family:var(--display); font-weight:700; font-size:.72rem; letter-spacing:.16em;
  text-transform:uppercase; border-radius:4px; padding:.78rem 1.2rem; cursor:pointer;
  border:1.5px solid transparent;
  transition:transform .14s ease, filter .18s ease, border-color .18s ease, color .18s ease, background .18s ease;
}
button:active{transform:translateY(1px)}
button:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.btn-primary{background:var(--accent); color:var(--accent-ink); border-color:var(--accent); box-shadow:0 3px 12px var(--glow)}
.btn-primary:hover:not(:disabled){filter:brightness(1.1)}
.btn-ghost{background:transparent; color:var(--ink-faint); border-color:var(--line)}
.btn-ghost:hover:not(:disabled){color:var(--ink); border-color:var(--ink-soft)}
.btn-sm{font-size:.6rem; padding:.5rem .8rem; letter-spacing:.14em}
button:disabled{cursor:default; opacity:.45}

.feedback{
  font-family:var(--mono); font-size:.72rem; letter-spacing:.03em; line-height:1.65;
  margin-top:.8rem; padding:.6rem .85rem; border-radius:4px; border-left:3px solid currentColor;
}
.feedback.bad{background:var(--bad-bg); color:var(--bad)}
.feedback.warn{background:var(--warn-bg); color:var(--warn)}
.feedback.good{background:var(--good-bg); color:var(--good)}

/* ---------------- notices ---------------- */
.notice{
  text-align:center; background:var(--surface); border:1px solid var(--line); border-radius:6px;
  padding:2.2rem 1.5rem; box-shadow:var(--shadow); margin-top:1.2rem;
}
.notice .sigil{font-family:var(--display); font-size:1.8rem; color:var(--gold); letter-spacing:.2em}
.notice h2{font-family:var(--display); font-weight:600; font-size:1.35rem; margin:.7rem 0 .5rem; text-wrap:balance}
.notice p{color:var(--ink-soft); margin:0 auto; max-width:26rem}
.notice .acts{margin-top:1.5rem; display:flex; gap:.5rem; justify-content:center; flex-wrap:wrap}

footer{
  margin-top:3.5rem; padding-top:1.3rem; border-top:1px solid var(--line-soft);
  font-family:var(--mono); font-size:.6rem; color:var(--ink-faint);
  letter-spacing:.07em; text-align:center; line-height:1.9;
}
/* The shared trust-page row sits under the disclaimer, not off on its own. */
footer .tg-sitelinks{margin-top:.9rem; padding-top:0}
footer .legal{
  color:var(--ink-faint); opacity:.85; font-size:.58rem; letter-spacing:.06em;
  max-width:32rem; margin:.4rem auto 0; line-height:1.75;
}

/* ============================================================
   THE ALMANAC ITSELF
   ============================================================ */

/* ---------------- section headings ----------------
   A label, a hairline that takes whatever width is left, and an optional
   note pinned to the right. The hairline is what keeps a long page of
   stacked panels from reading as one undifferentiated column. */
.sect{display:flex; align-items:center; gap:.7rem; margin:2.3rem 0 .85rem; color:var(--line)}
.sect h2{
  font-family:var(--display); font-size:.68rem; font-weight:700; letter-spacing:.18em;
  text-transform:uppercase; color:var(--ink-soft); margin:0; white-space:nowrap;
}
.sect::after{content:""; flex:1; height:1px; background:currentColor}
.sect .hint{
  font-family:var(--mono); font-size:.58rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-faint); white-space:nowrap; flex:0 0 auto;
}

/* ---------------- composer ----------------
   Ticker, quantity, and the unit the quantity is counted in. The unit
   toggle sits inside the quantity field's border rather than beside it,
   because "500" means nothing until you know whether it is shares or
   dollars - the two belong to one another. */
.composer{
  background:var(--surface); border:1px solid var(--line); border-radius:5px;
  padding:1rem 1.1rem 1.05rem; box-shadow:var(--shadow); position:relative;
}
.composer::before{content:""; position:absolute; inset:5px; border-radius:3px; border:1px solid var(--line-soft); pointer-events:none}
.composer .fields{display:flex; gap:.55rem; position:relative}
.f-sym{flex:0 0 7.4rem}
.f-sym input{
  width:100%; font-family:var(--display); font-weight:700; font-size:.98rem;
  letter-spacing:.12em; text-transform:uppercase; text-align:center;
}
.f-sym input::placeholder{letter-spacing:.1em; font-family:var(--mono); font-size:.8rem; font-weight:400}
.f-qty{flex:1 1 auto; position:relative; display:flex}
.f-qty input{
  width:100%; font-family:var(--mono); font-size:1rem; padding-right:4.9rem;
  font-variant-numeric:tabular-nums; text-align:right;
}
.f-qty input::-webkit-outer-spin-button, .f-qty input::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}
.f-qty input[type=number]{-moz-appearance:textfield; appearance:textfield}

/* Segmented unit switch. Absolutely positioned inside the field so the
   input keeps its full hit area and the switch never reflows the row. */
.unit{
  position:absolute; right:.32rem; top:50%; transform:translateY(-50%);
  display:flex; gap:2px; background:var(--sunken); border:1px solid var(--line);
  border-radius:3px; padding:2px;
}
.unit button{
  font-family:var(--mono); font-weight:600; font-size:.6rem; letter-spacing:.06em;
  padding:.24rem .42rem; border-radius:2px; border:0; background:transparent;
  color:var(--ink-faint); text-transform:none; line-height:1.2; min-width:1.8rem;
}
.unit button[aria-pressed="true"]{background:var(--accent); color:var(--accent-ink)}
.unit button:not([aria-pressed="true"]):hover{color:var(--ink)}
.composer .acts{display:flex; gap:.5rem; margin-top:.6rem; align-items:center}
.composer .acts .grow{flex:1}

/* ---------------- holdings ---------------- */
.holds{list-style:none; margin:0; padding:0}
.holdwrap{margin-bottom:.55rem}
.holdwrap.open .hold{border-bottom-left-radius:0; border-bottom-right-radius:0; border-bottom-color:transparent}
.hold{
  display:grid; align-items:center; gap:.35rem .75rem;
  grid-template-columns:1fr 7.7rem 5.4rem auto;
  grid-template-areas:"main qty inc acts";
  background:var(--surface); border:1px solid var(--line); border-radius:5px;
  padding:.7rem .85rem;
}
.hold.pending{opacity:.6}
.hold.dead{background:var(--sunken)}
.hold.bad{border-color:var(--bad)}
.h-main{grid-area:main; min-width:0}
.h-name{display:flex; align-items:baseline; gap:.45rem; min-width:0}
.h-sym{
  font-family:var(--display); font-weight:700; font-size:.86rem; letter-spacing:.1em;
  color:var(--ink); flex:0 0 auto;
}
.hold.bad .h-sym{color:var(--bad)}
.h-co{
  font-size:.84rem; color:var(--ink-soft); line-height:1.3; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.h-meta{
  font-family:var(--mono); font-size:.575rem; letter-spacing:.045em; color:var(--ink-faint);
  margin-top:.22rem; display:flex; flex-wrap:wrap; gap:.1rem .5rem;
}
.h-meta b{font-weight:600; color:var(--ink-soft)}
.h-meta .up{color:var(--good)} .h-meta .down{color:var(--bad)}
.h-qty{grid-area:qty; position:relative; display:flex}
.h-qty input{
  width:100%; font-family:var(--mono); font-size:.78rem; padding:.42rem 1.5rem .42rem .5rem;
  text-align:right; font-variant-numeric:tabular-nums; border-width:1px; border-radius:3px;
  background:var(--sunken);
}
.h-qty input::-webkit-outer-spin-button, .h-qty input::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}
.h-qty input[type=number]{-moz-appearance:textfield; appearance:textfield}
/* The unit reads as a suffix on the number, and clicking it flips the
   holding between shares and dollars without opening anything. */
.h-unit{
  position:absolute; right:.3rem; top:50%; transform:translateY(-50%);
  font-family:var(--mono); font-size:.6rem; font-weight:600; color:var(--ink-faint);
  background:none; border:0; padding:.1rem .12rem; letter-spacing:0; text-transform:none; line-height:1;
}
.h-unit:hover{color:var(--accent)}
.h-inc{
  grid-area:inc; text-align:right; font-family:var(--mono); font-weight:600; font-size:.86rem;
  color:var(--gold); font-variant-numeric:tabular-nums; white-space:nowrap;
}
.h-inc.nil{color:var(--ink-faint); font-weight:400}
.h-inc small{display:block; font-size:.54rem; font-weight:400; color:var(--ink-faint); letter-spacing:.06em}
.h-acts{grid-area:acts; display:flex; gap:.25rem; align-items:center}
.iconbtn{
  width:1.7rem; height:1.7rem; padding:0; flex:0 0 auto;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  background:var(--sunken); border:1px solid var(--line); border-radius:4px;
  color:var(--ink-faint); font-size:.6rem; font-family:var(--mono); line-height:1; letter-spacing:0;
  transition:transform .2s ease, color .2s ease, background .2s ease, border-color .2s ease;
}
.iconbtn:hover{background:var(--surface); color:var(--ink); border-color:var(--ink-faint)}
.iconbtn.kill:hover{color:var(--bad); border-color:var(--bad); background:var(--bad-bg)}
.iconbtn[aria-expanded="true"]{transform:rotate(180deg); color:var(--accent); border-color:var(--accent-soft)}

/* ---------------- the drawer under a holding ---------------- */
.drawer{
  border:1px solid var(--line); border-top:0; border-radius:0 0 5px 5px;
  background:var(--sunken); padding:.75rem .9rem .85rem;
}
.drawer .dh{
  font-family:var(--mono); font-size:.56rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-faint); margin:0 0 .45rem;
}
.drawer .dh + .dh{margin-top:.95rem}
.paytable{width:100%; border-collapse:collapse; font-family:var(--mono); font-size:.62rem}
.paytable td{padding:.26rem 0; border-top:1px solid var(--line-soft); color:var(--ink-soft)}
.paytable tr:first-child td{border-top:0}
.paytable .dt{color:var(--ink-faint); white-space:nowrap}
.paytable .amt{text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap}
.paytable .tot{text-align:right; font-variant-numeric:tabular-nums; color:var(--ink); font-weight:600; white-space:nowrap}
.paytable .sp{color:var(--warn)}
.paytable tr.sum td{border-top:1px solid var(--line); color:var(--ink); font-weight:600; padding-top:.36rem}

/* ---------------- the headline ----------------
   The one number the whole page exists to produce, set the way Triviagon
   sets a final score: Cinzel, gold, and given room to breathe. */
.verdict{text-align:center; padding-top:.6rem}
.verdict .crown{
  font-family:var(--display); font-size:.64rem; font-weight:600; letter-spacing:.24em;
  text-transform:uppercase; color:var(--ink-faint); margin:0;
}
.verdict .total{
  font-family:var(--display); font-weight:700; font-size:clamp(2.6rem,12vw,4rem); line-height:1;
  margin:.55rem 0 .2rem; color:var(--gold); font-variant-numeric:tabular-nums; letter-spacing:-.01em;
}
.verdict .total .cur{color:var(--ink-faint); font-size:.42em; vertical-align:.32em; margin-right:.06em}
.verdict .grade{font-family:var(--body); font-style:italic; font-size:1.05rem; color:var(--ink-soft); margin:.2rem 0 0}

.statgrid{display:grid; grid-template-columns:repeat(4,1fr); gap:.5rem; margin-top:1.5rem}
.stat{
  background:var(--surface); border:1px solid var(--line); border-radius:5px;
  padding:.62rem .4rem .68rem; text-align:center; position:relative;
}
.stat .k{
  font-family:var(--mono); font-size:.5rem; letter-spacing:.11em; text-transform:uppercase;
  color:var(--ink-faint); display:block; line-height:1.4;
}
.stat .v{
  font-family:var(--display); font-weight:700; font-size:1rem; color:var(--ink);
  display:block; margin-top:.28rem; font-variant-numeric:tabular-nums; line-height:1.15;
}
.stat .v.up{color:var(--good)} .stat .v.down{color:var(--bad)} .stat .v.nil{color:var(--ink-faint)}

/* ---------------- the year ahead ----------------
   Bars, not a line: each month is a discrete count of payments that either
   land or do not, and a line would imply a continuity dividends never have.
   Empty months are drawn as a hairline rather than nothing, so a lumpy
   schedule looks lumpy instead of looking like missing data. */
.chart{
  background:var(--surface); border:1px solid var(--line); border-radius:5px;
  padding:1rem .9rem .75rem; box-shadow:var(--shadow-sm);
}
/* Switch on the left, its consequence on the right. They wrap onto separate
   lines on a phone rather than the note being squeezed to nothing, since the
   number is the reason the switch is worth touching. */
.driprow{
  display:flex; align-items:center; justify-content:space-between;
  gap:.5rem .75rem; flex-wrap:wrap; margin-bottom:.95rem;
}
.dripnote{
  font-family:var(--mono); font-size:.545rem; letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink-faint); line-height:1.5;
}
.dripnote b{color:var(--gold); font-weight:600}
@media (max-width:26rem){
  .driprow{justify-content:center; text-align:center}
  .seg button{padding:.36rem .6rem; letter-spacing:.06em}
}

.bars{display:flex; align-items:flex-end; gap:.3rem; height:8.5rem}
.bar{flex:1 1 0; height:100%; display:flex; flex-direction:column; justify-content:flex-end; min-width:0}
.bar .fill{
  border-radius:2px 2px 0 0; min-height:2px;
  background:linear-gradient(180deg, var(--accent-2), var(--accent));
  transition:height .45s cubic-bezier(.22,.72,.28,1);
}
.bar.zero .fill{background:var(--line); min-height:1px}
.bar.peak .fill{background:linear-gradient(180deg, var(--gold-2), var(--gold))}
.bar .cap{
  font-family:var(--mono); font-size:.5rem; color:var(--ink-faint); text-align:center;
  margin-bottom:.2rem; white-space:nowrap; overflow:hidden;
}
.bar.peak .cap{color:var(--gold); font-weight:600}
.mlabels{display:flex; gap:.3rem; margin-top:.45rem; border-top:1px solid var(--line-soft); padding-top:.4rem}
.ml{
  flex:1 1 0; text-align:center; font-family:var(--mono); font-size:.5rem; letter-spacing:.04em;
  text-transform:uppercase; color:var(--ink-faint); min-width:0; overflow:hidden;
}
.ml b{display:block; font-weight:600; color:var(--ink-soft)}
.ml .yr{display:block; font-size:.44rem; opacity:.7}

/* ---------------- the next payments ---------------- */
.sched{list-style:none; margin:0; padding:0}
.sched li{
  display:flex; align-items:baseline; gap:.7rem; padding:.5rem .1rem;
  border-top:1px solid var(--line-soft);
}
.sched li:first-child{border-top:0}
.sched .d{
  font-family:var(--mono); font-size:.6rem; letter-spacing:.05em; color:var(--ink-faint);
  flex:0 0 4.4rem; text-transform:uppercase;
}
.sched .s{font-family:var(--display); font-weight:700; font-size:.78rem; letter-spacing:.1em; flex:0 0 auto}
.sched .n{
  font-size:.78rem; color:var(--ink-faint); flex:1 1 auto; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.sched .a{
  font-family:var(--mono); font-size:.75rem; font-weight:600; color:var(--gold);
  font-variant-numeric:tabular-nums; flex:0 0 auto;
}

/* ---------------- share block ---------------- */
.sharebox{
  font-family:var(--mono); font-size:.72rem; line-height:1.75; text-align:left; white-space:pre;
  background:var(--sunken); border:1px dashed var(--line); border-radius:5px;
  padding:.95rem 1.15rem; margin:0 auto .8rem; overflow-x:auto; color:var(--ink-soft);
}
.shareacts{display:flex; gap:.5rem; justify-content:center; flex-wrap:wrap}

/* ---------------- bulk paste ---------------- */
.paste{margin-top:.6rem}
.paste textarea{
  width:100%; font-family:var(--mono); font-size:.8rem; line-height:1.7; min-height:7.5rem; resize:vertical;
}
.paste .hintline{
  font-family:var(--mono); font-size:.56rem; letter-spacing:.06em; color:var(--ink-faint);
  margin:.45rem 0 .6rem; line-height:1.8;
}

/* ---------------- method page ---------------- */
.prose{
  background:var(--surface); border:1px solid var(--line); border-radius:5px;
  padding:1.4rem 1.5rem 1.5rem; box-shadow:var(--shadow); margin-top:1.2rem; position:relative;
}
.prose::before{content:""; position:absolute; inset:5px; border-radius:3px; border:1px solid var(--line-soft); pointer-events:none}
.prose h3{
  font-family:var(--display); font-size:.7rem; font-weight:700; letter-spacing:.18em;
  text-transform:uppercase; color:var(--ink-soft); margin:1.7rem 0 .5rem;
}
.prose h3:first-child{margin-top:0}
.prose p{margin:0 0 .85rem; color:var(--ink-soft); font-size:.96rem; line-height:1.72}
.prose p:last-child{margin-bottom:0}
.prose code{
  font-family:var(--mono); font-size:.82em; background:var(--sunken); color:var(--ink);
  padding:.1em .35em; border-radius:3px; border:1px solid var(--line-soft);
}
.prose ul{margin:0 0 .9rem; padding-left:1.15rem; color:var(--ink-soft); font-size:.96rem; line-height:1.72}
.prose li{margin-bottom:.4rem}
.prose li b{color:var(--ink); font-weight:600}
.formula{
  font-family:var(--mono); font-size:.78rem; line-height:1.9; background:var(--sunken);
  border:1px dashed var(--line); border-radius:5px; padding:.85rem 1.05rem; color:var(--ink-soft);
  margin:0 0 .95rem; overflow-x:auto; white-space:pre;
}

/* ---------------- odds and ends ---------------- */
.toolbar{display:flex; align-items:center; gap:.4rem; flex-wrap:wrap; margin-bottom:.7rem}
.toolbar .grow{flex:1}
.toolbar select{
  font-family:var(--mono); font-size:.6rem; letter-spacing:.08em; text-transform:uppercase;
  padding:.5rem .55rem; border-radius:4px; border-width:1px; background:var(--surface);
  color:var(--ink-faint); cursor:pointer;
}
.toolbar select:hover{color:var(--ink)}
.dots{display:inline-block; letter-spacing:.15em; color:var(--ink-faint)}
.tag{
  display:inline-block; font-family:var(--mono); font-size:.5rem; font-weight:600; letter-spacing:.09em;
  text-transform:uppercase; padding:.1rem .3rem; border-radius:2px; vertical-align:.08em;
}
.tag.warn{background:var(--warn-bg); color:var(--warn)}
.tag.bad{background:var(--bad-bg); color:var(--bad)}
.tag.new{background:var(--accent-soft); color:var(--accent)}
.sronly{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ---------------- narrow ----------------
   Below 30rem the holding row stops trying to be a table. The name takes
   the full width and the controls fall to a second line, which keeps
   company names readable instead of clipping them to four characters. */
@media (max-width:30rem){
  #app{padding-left:.85rem; padding-right:.85rem}
  .hold{
    grid-template-columns:1fr auto auto;
    grid-template-areas:
      "main main acts"
      "qty  inc  inc";
    gap:.55rem .55rem;
  }
  .h-qty{max-width:7.6rem}
  .h-inc{font-size:.92rem}
  .statgrid{grid-template-columns:repeat(2,1fr)}
  .f-sym{flex:0 0 6.2rem}
  .f-sym input{font-size:.86rem; letter-spacing:.08em; padding-left:.4rem; padding-right:.4rem}
  .bars{height:7rem}
  .bar .cap{display:none}
  .sched .n{display:none}
  .prose{padding:1.2rem 1.1rem 1.25rem}
}
@media (max-width:22rem){
  .ml{font-size:.44rem}
}

/* ---------------- motion ---------------- */
@media (prefers-reduced-motion: no-preference){
  .holdwrap{animation:riseIn .38s cubic-bezier(.22,.72,.28,1) both}
  .verdict .total{animation:riseIn .55s cubic-bezier(.22,.72,.28,1) both}
  /* Rebuilt in place rather than arriving, so it holds still. */
  .verdict.quiet .total{animation:none}
  .panel-in{animation:riseIn .4s cubic-bezier(.22,.72,.28,1) both}
  @keyframes riseIn{from{opacity:0; transform:translateY(12px) scale(.99)} to{opacity:1; transform:none}}
  .dots{animation:blink 1.4s steps(4,end) infinite}
  @keyframes blink{0%{opacity:.25}50%{opacity:1}100%{opacity:.25}}
  .shake{animation:shakeX .34s cubic-bezier(.36,.07,.19,.97)}
  @keyframes shakeX{10%,90%{transform:translateX(-2px)}20%,80%{transform:translateX(4px)}30%,50%,70%{transform:translateX(-6px)}40%,60%{transform:translateX(6px)}}
}
@media (prefers-reduced-motion: reduce){
  .bar .fill{transition:none}
}
