/* MANTIS Forecast Room — ported from Matt Vass's handover package,
   4 September 2026. Generated by build_fr_page.py; edit that, not this.

   Every rule is scoped under .fr-room and every custom property is renamed
   --fr-*, because the original styled bare body/th/td/section/h1-h4/a/button
   and redefined about thirty generically-named :root tokens. Unscoped, it
   restyles Closed Business and every other page in this app. */
.fr-room{
  --ground:#F5F2F1; --surface:#FFFFFF; --surface2:#EDE8E6; --surface3:#E4DDDA;
  --line:#DCD5D2; --line2:#C9C0BC;
  --ink:#141110; --ink2:#4C4340; --ink3:#7D7370;
  --accent:#E30613; --accent2:#B00510; --accentSoft:rgba(227,6,19,.09);
  --good:#1D7B53; --goodSoft:rgba(29,123,83,.10);
  --warn:#9A6B14; --warnSoft:rgba(154,107,20,.12);
  --cool:#4A5C6E; --coolSoft:rgba(74,92,110,.10);
  --shadow:0 1px 2px rgba(20,17,16,.05);
  --logo-light:none; --logo-dark:block;
  --fan:rgba(227,6,19,.13); --fan2:rgba(227,6,19,.22);
  --grid:rgba(20,17,16,.08);
  /* chart fills. The greys step down from black so a stack reads as one thing getting less
     certain from left to right. The reason palette is a data palette, not brand: MANTIS red
     stays reserved for the gap and for the headline percentage. */
  --c-called:#3A3431; --c-run:#6E6663; --c-ups:#A79E9A;
  --c-won:#1D7B53; --c-price:#D9662A; --c-feature:#2A76C4; --c-nobudget:#0F7B87;
  --c-nodecide:#4B37A6; --c-cancelled:#6E6663; --c-none:#9A928E;
}@media (prefers-color-scheme: dark){.fr-room :root:not([data-theme="light"]){
    --ground:#0A0A0A; --surface:#141211; --surface2:#1C1918; --surface3:#262221;
    --line:#302B29; --line2:#413B38;
    --ink:#F4F0EE; --ink2:#B2A9A5; --ink3:#7E7572;
    --accent:#F5202C; --accent2:#FF5A62; --accentSoft:rgba(245,32,44,.13);
    --good:#40C289; --goodSoft:rgba(64,194,137,.13);
    --warn:#D9A33E; --warnSoft:rgba(217,163,62,.14);
    --cool:#8FA3B5; --coolSoft:rgba(143,163,181,.13);
    --shadow:0 1px 2px rgba(0,0,0,.4);
    --logo-light:block; --logo-dark:none;
    --fan:rgba(245,32,44,.16); --fan2:rgba(245,32,44,.28);
    --grid:rgba(244,240,238,.09);
    --c-called:#4A4340; --c-run:#7E7572; --c-ups:#A79E9A;
    --c-won:#2E9A6B; --c-price:#E07A3C; --c-feature:#3D8AD6; --c-nobudget:#1B93A0;
    --c-nodecide:#6B57C9; --c-cancelled:#7E7572; --c-none:#6B6360;
  }
}.fr-room :root[data-theme="dark"]{
  --ground:#0A0A0A; --surface:#141211; --surface2:#1C1918; --surface3:#262221;
  --line:#302B29; --line2:#413B38;
  --ink:#F4F0EE; --ink2:#B2A9A5; --ink3:#7E7572;
  --accent:#F5202C; --accent2:#FF5A62; --accentSoft:rgba(245,32,44,.13);
  --good:#40C289; --goodSoft:rgba(64,194,137,.13);
  --warn:#D9A33E; --warnSoft:rgba(217,163,62,.14);
  --cool:#8FA3B5; --coolSoft:rgba(143,163,181,.13);
  --shadow:0 1px 2px rgba(0,0,0,.4);
  --logo-light:block; --logo-dark:none;
  --fan:rgba(245,32,44,.16); --fan2:rgba(245,32,44,.28);
  --grid:rgba(244,240,238,.09);
  --c-called:#4A4340; --c-run:#7E7572; --c-ups:#A79E9A;
  --c-won:#2E9A6B; --c-price:#E07A3C; --c-feature:#3D8AD6; --c-nobudget:#1B93A0;
  --c-nodecide:#6B57C9; --c-cancelled:#7E7572; --c-none:#6B6360;
}.fr-room, .fr-room *{box-sizing:border-box}.fr-room{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:"IBM Plex Sans","Helvetica Neue",Arial,sans-serif;
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased;
}.fr-room h1, .fr-room h2, .fr-room h3, .fr-room h4{font-family:Montserrat,"Helvetica Neue",Arial,sans-serif; margin:0; text-wrap:balance; letter-spacing:-.01em}.fr-room .mono, .fr-room .num{font-family:"IBM Plex Mono",ui-monospace,monospace; font-variant-numeric:tabular-nums}.fr-room a{color:var(--ink)}.fr-room button{font:inherit; cursor:pointer}.fr-room :focus-visible{outline:2px solid var(--accent); outline-offset:2px}

/* ---------- shell ---------- */.fr-room .wrap{max-width:1240px; margin:0 auto; padding:0 22px}.fr-room header.top{
  position:sticky; top:0; z-index:40; background:var(--surface);
  border-bottom:1px solid var(--line);
}.fr-room .topin{display:flex; align-items:center; gap:20px; padding:12px 0; flex-wrap:wrap}.fr-room .mark{display:flex; align-items:baseline; gap:12px; min-width:0}.fr-room .mark img{height:15px; width:auto; display:block}.fr-room .mark img.l{display:var(--logo-light)}.fr-room .mark img.d{display:var(--logo-dark)}.fr-room .mark .rail{width:1px; height:20px; background:var(--line2)}.fr-room .mark .lab{font-family:Montserrat; font-weight:700; font-size:13px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink)}.fr-room .topmeta{margin-left:auto; display:flex; gap:22px; align-items:center; flex-wrap:wrap}.fr-room .tm{display:flex; flex-direction:column; gap:1px}.fr-room .tm b{font-family:"IBM Plex Mono"; font-variant-numeric:tabular-nums; font-size:15px; font-weight:600; line-height:1.1}.fr-room .tm span{font-size:9.5px; letter-spacing:.11em; text-transform:uppercase; color:var(--ink3)}.fr-room .saveState{font-size:11px; color:var(--ink3); display:flex; align-items:center; gap:7px}.fr-room .dot{width:6px; height:6px; border-radius:50%; background:var(--good); flex:none}.fr-room .dot.dirty{background:var(--accent)}.fr-room .dot.busy{background:var(--warn)}.fr-room .dot.ro{background:var(--ink3)}.fr-room .draftbar{display:flex; gap:12px; align-items:center; flex-wrap:wrap; margin:18px 0 0;
  padding:13px 15px; border:1px solid var(--accent); border-radius:2px; background:var(--accentSoft);
  font-size:13px; color:var(--ink)}.fr-room .draftbar span{flex:1 1 340px}

/* ---------- sections ---------- */.fr-room section{padding:38px 0 6px; border-top:1px solid var(--line)}.fr-room section:first-of-type{border-top:none}.fr-room .eyebrow{display:flex; align-items:center; gap:11px; margin-bottom:8px}.fr-room .eyebrow i{display:block; width:26px; height:2px; background:var(--accent); flex:none}.fr-room .eyebrow span{font-size:10px; font-weight:600; letter-spacing:.15em; text-transform:uppercase; color:var(--ink3)}.fr-room h2.sec{font-size:23px; font-weight:700; margin-bottom:7px}.fr-room p.lede{color:var(--ink2); max-width:74ch; margin:0 0 20px}.fr-room p.lede.tight{margin-bottom:14px}

/* ---------- cards ---------- */.fr-room .grid3{display:grid; grid-template-columns:repeat(3,1fr); gap:14px}.fr-room .grid2{display:grid; grid-template-columns:repeat(2,1fr); gap:14px}.fr-room .grid4{display:grid; grid-template-columns:repeat(4,1fr); gap:12px}
/* four labels of unequal length must not push their numbers onto different baselines */.fr-room .grid4 .k-lab{min-height:2.4em; display:flex; align-items:flex-start}@media (max-width:1080px){.fr-room .grid4{grid-template-columns:repeat(2,1fr)}}@media (max-width:860px){.fr-room .grid3, .fr-room .grid2, .fr-room .grid4{grid-template-columns:1fr}}.fr-room .card{background:var(--surface); border:1px solid var(--line); border-radius:3px; padding:18px; box-shadow:var(--shadow)}.fr-room .card.flush{padding:0; overflow:hidden}.fr-room .kpi .k-lab{font-size:10px; font-weight:600; letter-spacing:.13em; text-transform:uppercase; color:var(--ink3)}.fr-room .kpi .k-big{font-family:"IBM Plex Mono"; font-variant-numeric:tabular-nums; font-size:40px; font-weight:500; line-height:1.05; margin-top:9px; letter-spacing:-.02em}.fr-room .kpi .k-big small{font-size:19px; font-weight:400; color:var(--ink2)}.fr-room .kpi .k-band{font-family:"IBM Plex Mono"; font-size:12.5px; color:var(--ink2); margin-top:7px; font-variant-numeric:tabular-nums}.fr-room .kpi .k-split{margin-top:13px; padding-top:11px; border-top:1px solid var(--line); display:flex; flex-direction:column; gap:5px}.fr-room .kpi .k-row{display:flex; justify-content:space-between; font-size:12.5px; color:var(--ink2)}.fr-room .kpi .k-row b{font-family:"IBM Plex Mono"; font-weight:500; color:var(--ink); font-variant-numeric:tabular-nums}.fr-room .barsplit{display:flex; height:4px; margin-top:11px; gap:2px}.fr-room .barsplit i{display:block; height:100%}.fr-room .barsplit i.a{background:var(--ink2)}.fr-room .barsplit i.b{background:var(--accent)}

/* ---------- tables ---------- */.fr-room .tw{overflow-x:auto; border:1px solid var(--line); border-radius:3px; background:var(--surface)}.fr-room table{border-collapse:collapse; width:100%; font-size:13px}.fr-room th, .fr-room td{text-align:right; padding:8px 9px; border-bottom:1px solid var(--line); white-space:nowrap}.fr-room th{font-size:9.5px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--ink3); background:var(--surface2); position:sticky; top:0}.fr-room th:first-child, .fr-room td:first-child{text-align:left}.fr-room tbody tr:last-child td{border-bottom:none}.fr-room tbody tr:hover{background:var(--surface2)}.fr-room td.n{font-family:"IBM Plex Mono"; font-variant-numeric:tabular-nums}.fr-room tr.total td{background:var(--surface2); font-weight:600; border-top:1px solid var(--line2)}
/* a quarter subtotal sits between a month and a grand total: heavier than a row, lighter
   than the bottom line, with a rule above it so the quarter reads as a block */.fr-room tr.qtr td{background:var(--surface2); font-weight:600; border-top:1px solid var(--line2);
  border-bottom:1px solid var(--line2)}.fr-room tr.qtr td:first-child b{font-family:Montserrat, sans-serif; font-size:12px; letter-spacing:.01em}.fr-room tr.qtr:hover td{background:var(--surface3)}.fr-room tr.rule td{border-bottom:2px solid var(--line2)}

/* ---------------------------------------------------------------------- vitals -----
   Eight rows, one shape. The repetition is the design: identical geometry down the page is
   what lets an eye compare a win rate against a cycle time without doing any arithmetic.
   Solid black is what we measured, the red hairline is the reference, and a row with no red
   hairline is a number nobody has set a target for. */.fr-room .vit{border-top:1px solid var(--line2)}
/* On the vitals page the region switch is navigation, not reading matter. The buttons stay at
   full size; the Forecast Room's reconciliation prose and the currency evidence table are one
   click away there rather than taking the top third of a page about health. */
/* the view tabs sit in the region row, one hairline away from it, so the row reads as
   "which book" then "which reading of it" rather than as five equal buttons */.fr-room .tabsep{display:inline-block; width:1px; height:22px; background:var(--line2); margin:0 8px}.fr-room .fbtn.tabb{font-family:Montserrat, sans-serif; letter-spacing:.01em}
/* the targets table: an input that looks like the plan inputs, because it behaves like them */.fr-room input.tgt{width:76px; text-align:right; font-family:'IBM Plex Mono', monospace; font-size:12.5px;
  padding:5px 7px; border:1px solid var(--line2); border-radius:5px; background:var(--surface);
  color:var(--ink)}.fr-room input.tgt:focus{outline:none; border-color:var(--ink2)}.fr-room .tgtwrap{display:inline-flex; align-items:center; gap:6px}.fr-room .tu{font-size:11px; color:var(--ink3); width:32px; text-align:left; flex:none}
/* a read-only figure standing in for an input: same 76px slot, centred in it */.fr-room .tgtfix{width:76px; text-align:center; flex:none}.fr-room .vdf{font-size:10px; letter-spacing:.04em; text-transform:uppercase; color:var(--ink3);
  border:1px solid var(--line2); border-radius:3px; padding:1px 4px; margin-left:4px}.fr-room .vrow{display:grid; grid-template-columns:186px 116px 250px 138px 1fr; gap:18px;
  align-items:start; padding:16px 0; border-bottom:1px solid var(--line)}.fr-room .vrow:last-child{border-bottom:none}.fr-room .vname{font-family:Montserrat, sans-serif; font-weight:700; font-size:13px; line-height:1.3;
  letter-spacing:.005em; color:var(--ink)}.fr-room .vsub{font-family:'IBM Plex Sans', sans-serif; font-weight:400; font-size:11.5px;
  color:var(--ink3); margin-top:3px; line-height:1.35}.fr-room .vval{font-family:'IBM Plex Mono', monospace; font-size:26px; font-weight:600; line-height:1;
  color:var(--ink); text-align:right; font-variant-numeric:tabular-nums}.fr-room .vval .vu{font-size:12px; font-weight:500; color:var(--ink3); margin-left:4px}.fr-room .vlb{font-family:'IBM Plex Sans', sans-serif; font-size:10.5px; font-weight:500;
  color:var(--ink3); margin-top:6px; letter-spacing:.02em; text-transform:uppercase}
/* the one-word verdict, right under the number it belongs to */.fr-room .vst{margin-top:9px; display:flex; justify-content:flex-end}.fr-room .vtc, .fr-room .vsc{padding-top:3px}.fr-room .vt, .fr-room .vs{display:block}.fr-room .vref{font-size:11px; color:var(--ink3); margin-top:5px}.fr-room .vnos{font-size:11px; color:var(--ink3); font-style:normal}.fr-room .vfind{font-size:12.5px; line-height:1.55; color:var(--ink2)}.fr-room .vlegend{display:flex; flex-wrap:wrap; gap:18px; align-items:center; font-size:11px;
  color:var(--ink3); padding:10px 0 14px}.fr-room .vlegend span{display:inline-flex; align-items:center; gap:6px}
/* The modifier names are deliberately ugly. "bar" collided with the global .bar filter-row
   rule, which carries margin-bottom:12px, and that pushed the first swatch off the text
   baseline while every other swatch sat correctly. A swatch is 16px of nothing, so its class
   has to be one nothing else in the page will ever claim. */.fr-room .vlegend .sw{display:inline-block; border-radius:1px; margin:0; align-self:center; flex:none}.fr-room .vlegend .sw.swbar{width:16px; height:8px; background:var(--ink)}.fr-room .vlegend .sw.swref{width:2px; height:12px; background:var(--accent)}.fr-room .vlegend .sw.swgap{width:16px; height:8px; background:var(--accentSoft); border:1px solid var(--accent)}.fr-room .vlegend .sw.swline{width:16px; height:2px; background:var(--ink2)}.fr-room .vlegend > span{min-height:16px}@media (max-width:960px){.fr-room .vrow{grid-template-columns:1fr 1fr; gap:10px 16px}.fr-room .vname{grid-column:1}.fr-room .vval{grid-column:2; text-align:right}.fr-room .vtc{grid-column:1}.fr-room .vsc{grid-column:2}.fr-room .vfind{grid-column:1 / -1}.fr-room .vt{width:100%; max-width:250px}
}
/* a month where nothing closed is still a month: present, readable, and visibly empty */.fr-room tr.zm td{color:var(--ink3)}.fr-room tr.zm td:first-child{color:var(--ink2)}.fr-room .sub{color:var(--ink3); font-size:11.5px}.fr-room .tw.tall{max-height:620px; overflow-y:auto}.fr-room .ribbon.rgbar{display:block}.fr-room .ribbon.rgbar .bar{margin-bottom:9px}.fr-room .ribbon.rgbar .fbtn{font-size:12px; padding:6px 12px}.fr-room tr.thinrow td{background:var(--warnSoft)}.fr-room tr.thinrow td:first-child .sub{color:var(--warn)}.fr-room .draftbar.ok{border-color:var(--good); background:var(--goodSoft)}.fr-room textarea.marksbox{width:100%; font-family:"IBM Plex Mono"; font-size:11px; line-height:1.5;
  background:var(--surface2); border:1px solid var(--line2); color:var(--ink2); border-radius:2px;
  padding:8px 9px; resize:vertical; word-break:break-all}.fr-room textarea.marksbox:focus{border-color:var(--accent); background:var(--surface); color:var(--ink); outline:none}.fr-room tr.resid td{background:var(--surface2); color:var(--ink2)}.fr-room tr.resid td:first-child{font-weight:500}.fr-room .saveState.bad{color:var(--accent)}.fr-room .saveState.bad .dot{background:var(--accent)}.fr-room .btn.sm{padding:5px 10px; font-size:11px}.fr-room td.dropm{color:var(--muted); opacity:.62; text-decoration:line-through; text-decoration-color:var(--accent)}.fr-room td.dropm .sub{text-decoration:none; color:var(--accent); opacity:1}.fr-room .pf select{font-family:"IBM Plex Mono"; font-size:13.5px; background:var(--surface2);
  border:1px solid var(--line2); color:var(--ink); border-radius:2px; padding:6px 9px; width:100%}.fr-room .pf select:focus{border-color:var(--accent); background:var(--surface)}.fr-room td.n.q{color:var(--ink3)}.fr-room tr.msub td{background:var(--surface2); color:var(--ink); font-weight:600; border-top:1px solid var(--line2);
  border-bottom:1px solid var(--line2)}.fr-room tr.msub td:first-child{font-family:Montserrat; font-size:10.5px; letter-spacing:.08em; text-transform:uppercase}.fr-room tr.msub.warnrow td{background:var(--accentSoft); border-top-color:var(--accent); border-bottom-color:var(--accent)}.fr-room tr.msub.warnrow td:first-child{color:var(--accent)}.fr-room td:first-child{max-width:262px}.fr-room td:first-child .sub{white-space:normal}.fr-room .p50{color:var(--ink); font-weight:600}

/* ---------- chips ---------- */.fr-room .chip{display:inline-flex; align-items:center; gap:5px; font-size:10.5px; font-weight:600; letter-spacing:.04em;
  padding:2px 7px; border-radius:2px; border:1px solid var(--line2); color:var(--ink2); text-transform:uppercase; white-space:nowrap}.fr-room .chip.hi{color:var(--good); border-color:var(--good); background:var(--goodSoft)}.fr-room .chip.md{color:var(--warn); border-color:var(--warn); background:var(--warnSoft)}.fr-room .chip.lo{color:var(--cool); border-color:var(--cool); background:var(--coolSoft)}.fr-room .chip.risk{color:var(--accent); border-color:var(--accent); background:var(--accentSoft)}.fr-room .chip.ghost{border-style:dashed; color:var(--ink3)}.fr-room h3.chead{font-family:Montserrat, sans-serif; font-size:12.5px; font-weight:700;
  letter-spacing:.01em; color:var(--ink); margin:0 0 9px}

/* ---------- "how this is calculated": method behind a plus ---------- */
/* The method belongs on the page, not in a separate document, or the forecast and its caveats
   get separated. It does not belong in the way of the numbers either, so it collapses. */.fr-room details.howx{margin:0 0 14px}.fr-room details.howx>summary{cursor:pointer; list-style:none; display:inline-flex; align-items:center;
  gap:8px; font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink3); padding:4px 0; user-select:none}.fr-room details.howx>summary::-webkit-details-marker{display:none}.fr-room details.howx>summary::before{content:"+"; display:inline-flex; align-items:center;
  justify-content:center; width:15px; height:15px; border:1px solid var(--line2); border-radius:2px;
  font-size:12px; font-weight:600; line-height:1; color:var(--ink3); flex:none}.fr-room details[open].howx>summary::before{content:"\2212"}.fr-room details.howx>summary:hover{color:var(--accent)}.fr-room details.howx>summary:hover::before{border-color:var(--accent); color:var(--accent)}.fr-room details.howx>summary:focus-visible{outline:2px solid var(--accent); outline-offset:2px}.fr-room details.howx>*:not(summary){margin-top:8px}
/* the intro paragraph keeps its own type once it is open */.fr-room details.howx p.lede{margin:8px 0 0}

/* ---------- charts ---------- */
/* an SVG chart scales with the column, so the only job here is the furniture around it: the
   legend strip and the one-line finding, both matching the board pack */.fr-room .chartbox{background:var(--surface); border:1px solid var(--line); border-radius:3px;
  padding:16px 18px 12px; overflow-x:auto}.fr-room .chartbox svg{min-width:660px}.fr-room .chartlegend{display:flex; flex-wrap:wrap; gap:6px 20px; align-items:center;
  border-top:1px solid var(--line); margin-top:10px; padding-top:10px}.fr-room .chartlegend span{display:inline-flex; align-items:center; gap:7px; font-size:11px;
  font-weight:600; color:var(--ink2); white-space:nowrap}.fr-room .chartlegend i.sw{width:12px; height:12px; border-radius:2px; display:inline-block; flex:none}.fr-room .chartlegend i.sw.hollow{background:none; border:1.6px solid var(--accent)}
/* a dashed swatch for the third state: a deal nobody has judged yet */.fr-room .chartlegend i.sw.hollow[style*='ink3']{border-style:dashed}.fr-room .chartlegend i.sw.arrow{width:auto; height:auto; font-size:9px; line-height:1; font-style:normal}.fr-room .chartfind{margin-top:10px; font-size:12.5px; line-height:1.55; color:var(--ink2)}.fr-room .chartfind b{color:var(--ink)}

/* ---------- disclosure: working that should be available, not in the way ---------- */.fr-room details.defsx{margin-top:10px}.fr-room details.defsx>summary{cursor:pointer; list-style:none; display:inline-flex; align-items:center; gap:7px;
  font-size:11.5px; font-weight:600; letter-spacing:.02em; color:var(--ink2);
  padding:5px 11px; border:1px solid var(--line2); border-radius:2px; background:var(--surface)}.fr-room details.defsx>summary::-webkit-details-marker{display:none}
/* the same plus as every other disclosure on the page, so one idiom rather than two */.fr-room details.defsx>summary::before{content:"+"; display:inline-flex; align-items:center;
  justify-content:center; width:14px; height:14px; border:1px solid var(--line2); border-radius:2px;
  font-size:11px; font-weight:600; line-height:1; color:var(--ink3); flex:none}.fr-room details[open].defsx>summary::before{content:"\2212"}.fr-room details.defsx>summary:hover::before{border-color:var(--accent); color:var(--accent)}.fr-room details.defsx>summary:hover{border-color:var(--accent); color:var(--accent)}.fr-room details.defsx>.tw{margin-top:9px}.fr-room details.defsx tr.unc td{background:var(--accentSoft)}

/* ---------- note row on the review board ---------- */.fr-room tr.noterow td{padding:0 9px 6px; border-bottom:1px solid var(--line2); background:var(--surface);
  white-space:normal; max-width:none}.fr-room tr.noterow:hover td{background:var(--surface)}.fr-room tr.dealrow td{border-bottom:none}.fr-room tr.dealrow:hover td{background:var(--surface2)}
/* The note collapses to one line so the table stays readable at a glance, and opens to full
   height the moment it is clicked. The label sits inline rather than on its own row. */.fr-room .notewrap{display:flex; align-items:flex-start; gap:9px; max-width:none;
  border-left:2px solid var(--line2); padding:0 0 0 10px; margin-left:2px}.fr-room .notewrap label{flex:0 0 auto; font-size:9.5px; font-weight:600; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink3); padding-top:7px}.fr-room .notewrap textarea{flex:1 1 auto; width:100%; height:26px; min-height:26px; resize:none; overflow:hidden;
  font-family:"IBM Plex Sans","Helvetica Neue",Arial,sans-serif; font-size:12.5px; line-height:1.45;
  background:transparent; border:1px solid transparent; border-radius:2px; color:var(--ink2);
  padding:4px 7px; white-space:pre; text-overflow:ellipsis}.fr-room .notewrap textarea:hover{border-color:var(--line2); background:var(--surface2)}.fr-room .notewrap textarea:focus{border-color:var(--accent); background:var(--surface); color:var(--ink);
  min-height:76px; resize:vertical; white-space:pre-wrap; font-size:13.5px; padding:8px 10px; outline:none}.fr-room .notewrap textarea::placeholder{color:var(--ink3)}.fr-room tr.noterow.has td{background:var(--surface)}.fr-room td.whycell{width:1%; white-space:nowrap; text-align:center}.fr-room .chip.note{cursor:pointer; font-family:inherit; border-style:dashed; color:var(--ink3);
  background:transparent; padding:2px 7px; min-width:30px}.fr-room .chip.note:hover{border-color:var(--accent); color:var(--accent)}.fr-room .chip.note.has{border-style:solid; border-color:var(--ink3); color:var(--ink2); font-weight:600}.fr-room .chip.note.has:hover{border-color:var(--accent); color:var(--accent)}

/* ---------- confidence control ---------- */.fr-room .conf{display:inline-flex; border:1px solid var(--line2); border-radius:2px; overflow:hidden}.fr-room .conf button{background:var(--surface); border:none; color:var(--ink3); padding:3px 8px; font-size:10.5px; font-weight:600;
  letter-spacing:.05em; border-right:1px solid var(--line2); font-family:"IBM Plex Sans"}.fr-room .conf button:last-child{border-right:none}.fr-room .conf button:hover{background:var(--surface3); color:var(--ink)}.fr-room .conf button[aria-pressed="true"]{color:var(--surface); background:var(--ink)}.fr-room .conf button.h[aria-pressed="true"]{background:var(--good); color:#fff}.fr-room .conf button.m[aria-pressed="true"]{background:var(--warn); color:#fff}.fr-room .conf button.l[aria-pressed="true"]{background:var(--cool); color:#fff}

/* ---------- filters / buttons ---------- */.fr-room .bar{display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:12px}.fr-room .fbtn{background:var(--surface); border:1px solid var(--line2); color:var(--ink2); border-radius:2px; padding:4px 10px;
  font-size:11.5px; font-weight:500}.fr-room .fbtn:hover{color:var(--ink); border-color:var(--ink3)}.fr-room .fbtn[aria-pressed="true"]{background:var(--ink); color:var(--surface); border-color:var(--ink)}.fr-room .btn{background:var(--ink); color:var(--surface); border:1px solid var(--ink); border-radius:2px; padding:8px 15px;
  font-size:12.5px; font-weight:600; letter-spacing:.02em}.fr-room .btn:hover{background:var(--accent); border-color:var(--accent); color:#fff}.fr-room .btn[disabled]{opacity:.4; cursor:not-allowed}.fr-room .btn.ghost{background:transparent; color:var(--ink); border-color:var(--line2)}.fr-room .btn.ghost:hover{border-color:var(--accent); color:var(--accent); background:transparent}.fr-room .hint{font-size:11.5px; color:var(--ink3)}

/* ---------- chart ---------- */.fr-room .chart{background:var(--surface); border:1px solid var(--line); border-radius:3px; padding:16px 14px 10px}.fr-room .chart svg{width:100%; height:auto; display:block; overflow:visible}.fr-room .legend{display:flex; gap:16px; flex-wrap:wrap; margin-top:10px; padding-top:11px; border-top:1px solid var(--line)}.fr-room .legend div{display:flex; align-items:center; gap:6px; font-size:11px; color:var(--ink2)}.fr-room .legend i{width:15px; height:7px; display:block; border-radius:1px}

/* ---------- params ---------- */.fr-room .pgrid{display:grid; grid-template-columns:repeat(auto-fill,minmax(215px,1fr)); gap:12px}.fr-room .pf{display:flex; flex-direction:column; gap:4px}.fr-room .pf label{font-size:10px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color:var(--ink3)}.fr-room .pf input{font-family:"IBM Plex Mono"; font-variant-numeric:tabular-nums; font-size:13.5px; background:var(--surface2);
  border:1px solid var(--line2); color:var(--ink); border-radius:2px; padding:7px 9px; width:100%}.fr-room .pf input:focus{border-color:var(--accent); background:var(--surface)}.fr-room .pf .note{font-size:10.5px; color:var(--ink3)}

/* ---------- health ---------- */.fr-room .hl{display:flex; flex-direction:column; gap:0; border:1px solid var(--line); border-radius:3px; background:var(--surface)}.fr-room .hitem{display:grid; grid-template-columns:74px 1fr; gap:14px; padding:14px 16px; border-bottom:1px solid var(--line)}.fr-room .hitem:last-child{border-bottom:none}.fr-room .hitem h4{font-size:14px; font-weight:700; margin-bottom:3px}.fr-room .hitem p{margin:0; font-size:13px; color:var(--ink2)}.fr-room .hitem .fix{margin-top:6px; font-size:12.5px; color:var(--ink2)}.fr-room .hitem .fix b{color:var(--ink); font-weight:600}.fr-room .sev{align-self:start; font-size:9.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; padding:3px 6px;
  border-radius:2px; text-align:center}.fr-room .sev.blocks{background:var(--accent); color:#fff}.fr-room .sev.limits{background:var(--warnSoft); color:var(--warn); border:1px solid var(--warn)}.fr-room .sev.watch{background:var(--coolSoft); color:var(--cool); border:1px solid var(--cool)}.fr-room .sev.ok{background:var(--goodSoft); color:var(--good); border:1px solid var(--good)}

/* ---------- upload ---------- */.fr-room .drop{border:1px dashed var(--line2); border-radius:3px; padding:20px; text-align:center; background:var(--surface);
  transition:border-color .12s, background .12s}.fr-room .drop.over{border-color:var(--accent); background:var(--accentSoft)}.fr-room .drop h4{font-size:13.5px; margin-bottom:4px}.fr-room .drop p{margin:0; font-size:12px; color:var(--ink3)}.fr-room .drop input{display:none}.fr-room .log{margin-top:12px; font-family:"IBM Plex Mono"; font-size:11.5px; color:var(--ink2); white-space:pre-wrap;
  max-height:190px; overflow:auto; background:var(--surface2); border:1px solid var(--line); border-radius:2px; padding:10px}.fr-room .log:empty{display:none}

/* ---------- driver mix bar ---------- */.fr-room .mix{display:inline-flex; width:104px; height:7px; border-radius:1px; overflow:hidden; vertical-align:middle;
  background:var(--surface3)}.fr-room .mix i{display:block; height:100%}.fr-room .mix i.p{background:var(--accent)}.fr-room .mix i.b{background:var(--ink2)}.fr-room .mix i.n{background:var(--cool)}.fr-room .mixkey{display:flex; gap:20px; flex-wrap:wrap; margin-top:11px; font-size:11.5px; color:var(--ink2)}.fr-room .mixkey span{display:flex; align-items:center; gap:7px}.fr-room .mixkey i{display:block; width:14px; height:7px; border-radius:1px}.fr-room .mixkey i.p{background:var(--accent)}.fr-room .mixkey i.b{background:var(--ink2)}.fr-room .mixkey i.n{background:var(--cool)}.fr-room input.bud{width:74px; font-family:"IBM Plex Mono"; font-variant-numeric:tabular-nums; font-size:12.5px;
  background:var(--surface2); border:1px solid var(--line); color:var(--ink); border-radius:2px;
  padding:4px 6px; text-align:right}.fr-room input.bud:focus{border-color:var(--accent); background:var(--surface)}

/* ---------- month build-up ---------- */.fr-room .lnk{background:none; border:none; color:var(--accent); font-size:12.5px; font-weight:600;
  padding:0; text-decoration:underline; text-underline-offset:2px; font-family:inherit}.fr-room .lnk:hover{color:var(--ink)}.fr-room tr.exp td{background:var(--surface2); padding:0}.fr-room tr.exp:hover td{background:var(--surface2)}.fr-room .expwrap{padding:14px 16px; display:flex; flex-direction:column; gap:0;
  border-left:2px solid var(--accent); margin:2px 0 2px 8px}.fr-room .expttl{font-family:Montserrat; font-size:10px; font-weight:700; letter-spacing:.11em;
  text-transform:uppercase; color:var(--ink3); margin-bottom:8px}.fr-room .expline{display:flex; justify-content:space-between; gap:18px; align-items:baseline;
  padding:6px 0; border-bottom:1px solid var(--line); font-size:13px; white-space:normal}.fr-room .expline b{font-family:"IBM Plex Mono"; font-variant-numeric:tabular-nums; font-weight:500; flex:none}.fr-room .expline.up{color:var(--cool)}.fr-room .expline.up b{color:var(--cool)}.fr-room .expline.tot{border-bottom:none; border-top:1px solid var(--line2); margin-top:5px; font-weight:600}.fr-room .expline.tot b{font-weight:600}

/* ---------- wide segmented control ---------- */.fr-room .conf.wide button{padding:6px 13px; font-size:11px}
/* a mis-hit on the clear button reads as the page undoing the call, so give it a wider
   target and make it visibly the odd one out */.fr-room .conf button:last-child{padding-left:10px; padding-right:10px; color:var(--ink3)}.fr-room .conf button:last-child[aria-pressed="true"]{background:var(--surface3); color:var(--ink2)}.fr-room tr.dealrow.unc td{background:var(--accentSoft)}.fr-room tr.dealrow.unc:hover td{background:var(--accentSoft)}
/* rows below the review threshold are shown for completeness, not to be called: no control,
   and the whole row sits back so the eye still lands on the deals that need a decision */.fr-room tr.dealrow.small td{color:var(--ink2)}.fr-room tr.dealrow.small td:nth-child(2) div:first-child{font-weight:500!important}.fr-room .inrr{display:inline-block; font-size:11px; color:var(--ink3); letter-spacing:.02em;
      padding:5px 0; white-space:nowrap}

/* ---------- definition strip ---------- */
/* separators are drawn on the cards, not by letting a gap-coloured container show through:
   an incomplete last row then reads as blank space rather than a grey slab */.fr-room .defs{display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:0; margin-top:14px;
  background:var(--surface); border:1px solid var(--line); border-radius:3px; overflow:hidden}.fr-room .defs div{padding:13px 15px; display:flex; flex-direction:column; gap:5px;
  border-right:1px solid var(--line); border-bottom:1px solid var(--line)}.fr-room .defs b{font-family:Montserrat; font-size:11px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--ink)}.fr-room .defs b::before{content:''; display:inline-block; width:14px; height:2px; background:var(--accent);
  vertical-align:middle; margin-right:8px; margin-bottom:3px}.fr-room .defs span{font-size:12.5px; color:var(--ink2); line-height:1.45}

/* ---------- region ribbon ---------- */.fr-room .ribbon{display:flex; gap:12px; align-items:baseline; flex-wrap:wrap; margin:18px 0 0;
  padding:11px 14px; border:1px solid var(--line); border-left:2px solid var(--accent);
  border-radius:2px; background:var(--surface); font-size:12.5px; color:var(--ink2)}.fr-room .ribbon span:last-child{max-width:96ch}

/* ---------- misc ---------- */.fr-room .callout{border-left:2px solid var(--accent); padding:2px 0 2px 14px; margin:16px 0; color:var(--ink2); font-size:13.5px; max-width:80ch}.fr-room .callout b{color:var(--ink)}.fr-room footer{border-top:1px solid var(--line); margin-top:40px; padding:26px 0 46px; color:var(--ink3); font-size:12px}.fr-room footer p{margin:0 0 7px; max-width:82ch}.fr-room .spark{display:block; height:26px; width:100%}@media (prefers-reduced-motion:reduce){.fr-room, .fr-room *{transition:none!important; animation:none!important}}

/* ---- port-only: fitting the room inside the app shell ------------------ */
/* Matt's page owned the whole viewport and centred itself with .wrap. Here
   it lives to the right of the sidebar, so .wrap's max-width stays but the
   auto margins are what keep it centred in the space that is left. */
.fr-room{ background:var(--ground); color:var(--ink); min-height:calc(100vh - 46px); }
.fr-room .wrap{ margin-left:auto; margin-right:auto; }
.fr-boot-error{ padding:48px 32px; max-width:60ch; }
.fr-boot-error h2{ font-size:19px; font-weight:600; margin-bottom:6px; }
/* Replaces Matt's brand header. Keeps his two data-render slots and drops
   the wordmark, which the sidebar already carries. */
.fr-room .fr-pagehead{ padding:26px 0 4px; }
.fr-room .fr-pagehead .wrap{ display:flex; align-items:baseline;
  justify-content:space-between; gap:18px; flex-wrap:wrap; }
.fr-room .fr-pagehead h1{ font-family:Montserrat, system-ui, sans-serif;
  font-size:25px; font-weight:700; letter-spacing:-.01em;
  display:flex; align-items:center; gap:10px; }
.fr-room .fr-pagehead .topmeta{ display:flex; align-items:center; gap:18px;
  flex-wrap:wrap; font-size:12px; color:var(--ink3); }
/* The engine measures containers on load; if the tab were display:none until
   ready every chart would size itself to zero. It renders in place instead. */

/* ---- port-only: the section rail -------------------------------------- */
/* A thin strip that opens over the page on hover. The first cut took a full
   236px column; beside the app's own 232px nav that left the charts a fifth
   narrower than the page Matt shares, which is most of why it stopped looking
   like his. Collapsed it costs 46px, and because the open panel is positioned
   rather than in flow, opening it moves nothing. */
.fr-room .fr-shell{ display:flex; align-items:flex-start; }
.fr-room .fr-shell > main{ flex:1; min-width:0; }
.fr-room .fr-rail{
  width:46px; flex:none; align-self:stretch;
  position:relative; margin:26px 0 0 14px;
}
.fr-room .fr-rail-panel{
  position:sticky; top:60px; width:46px; max-height:calc(100vh - 84px);
  overflow:hidden; background:var(--surface); border:1px solid var(--line);
  border-radius:3px; padding:10px 0 6px;
  transition:width .13s ease, box-shadow .13s ease;
}
.fr-room .fr-rail:hover .fr-rail-panel,
.fr-room .fr-rail:focus-within .fr-rail-panel{
  width:238px; overflow-y:auto; box-shadow:0 6px 26px rgba(20,17,16,.14); z-index:6;
}
.fr-room .fr-rail-head{
  font-size:9.5px; font-weight:700; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink3); padding:0 15px 9px; white-space:nowrap; opacity:0;
  transition:opacity .13s ease;
}
.fr-room .fr-rail:hover .fr-rail-head,
.fr-room .fr-rail:focus-within .fr-rail-head{ opacity:1; }
.fr-room .fr-rail-list{ display:flex; flex-direction:column; }
.fr-room .fr-rail-item{
  all:unset; box-sizing:border-box; cursor:pointer; display:flex; align-items:flex-start;
  gap:10px; width:100%; padding:7px 15px; font-family:inherit;
  border-left:2px solid transparent;
}
.fr-room .fr-rail-item:hover{ background:var(--surface2); }
.fr-room .fr-rail-item:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
.fr-room .fr-rail-item.on{ background:var(--surface2); border-left-color:var(--accent); }
.fr-room .fr-rail-num{
  font-family:"IBM Plex Mono", ui-monospace, monospace; font-size:11px; line-height:1.5;
  width:14px; flex:none; text-align:right; color:var(--ink3);
}
.fr-room .fr-rail-item.on .fr-rail-num{ color:var(--accent); }
/* the collapsed marker for a tab whose sections carry no number of their own */
.fr-room .fr-rail-tick{
  display:block; width:12px; height:2px; flex:none; margin-top:7px; border-radius:1px;
  background:var(--line2);
}
.fr-room .fr-rail-item.on .fr-rail-tick{ background:var(--accent); width:14px; }
.fr-room .fr-rail-text{
  font-size:12.5px; line-height:1.35; color:var(--ink2); font-weight:500;
  white-space:normal; opacity:0; transition:opacity .13s ease;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.fr-room .fr-rail:hover .fr-rail-text,
.fr-room .fr-rail:focus-within .fr-rail-text{ opacity:1; }
.fr-room .fr-rail-item.on .fr-rail-text{ color:var(--ink); font-weight:600; }
/* the jump lands the heading below the sticky topbar, not under it */
.fr-room main > section{ scroll-margin-top:96px; }
/* Narrow enough that even 46px is worth more as chart. */
@media (max-width:1080px){ .fr-room .fr-rail{ display:none; } }
