/* ============================================================
   Rules of Thumb — shared design tokens & theme system
   Loaded by every page. Defines the palette ONCE, with a dark
   default and a re-treated light theme. Tools reference these
   variables; nothing here re-implements tool layout.

   Theme resolution order:
     1. <html data-theme="light|dark">  (explicit override, set by rot.js)
     2. @media (prefers-color-scheme)   (OS/browser preference)
     3. dark                            (designed-for default)
   ============================================================ */

:root{
  /* ---- accents: brand colors, shared across themes ---- */
  --amber:#f6b53f; --amber-dim:#c98a25;
  --cyan:#57c7e8;  --cyan-dim:#2c6f86;
  --violet:#a98bff; --violet-dim:#6e57a8;
  --green:#6fdba0; --green-dim:#4aa578; --red:#ff6b7d;
  --pink:#f77bbd; --pink-dim:#a8527e;
  --indigo:#7f9cf5; --indigo-dim:#4d5fa8;
  --coral:#ff8a5c; --coral-dim:#c85f37;
  --teal:#2dd4bf; --teal-dim:#1f9c8c;
  --azure:#4d94ff; --azure-dim:#2f6bc4;
  --lime:#a3e635; --lime-dim:#6b9a1f;

  /* ---- DARK THEME (default) — the instrument-blueprint look ---- */
  --ink:#0a111e; --ink-2:#0e1830;
  --panel:#122140; --panel-2:#16264a;
  --line:#24365e; --line-soft:#1b2c4f;
  /* --muted-2 was #6b7fa6, tuned against --ink where it passed at 4.69:1. But the token is
     used on panels too, and there it fell to 3.96:1 on --panel and 3.70:1 on --panel-2 —
     below the 4.5:1 AA floor for the small labels and chart axes it is used for. It is now
     aimed at --panel-2, the worst case, so all four surfaces clear 4.5:1 at once
     (ink 5.86, panel 4.94, panel-2 4.62, glyph-bg 5.51).

     --muted moved with it. Raising muted-2 to meet AA closed the lightness gap between the
     two tokens from 9.8 to 3.3 L*, which is nearly imperceptible — the recessive/secondary
     hierarchy would have been lost across 1300+ uses. Lifting --muted restores the original
     step (9.7 L*) and improves its own contrast (6.32:1 worst case, was 5.16). Same hue and
     saturation on both; only lightness changed. */
  --text:#e9f0fb; --muted:#98aac8; --muted-2:#7e90b1;
  --grid:rgba(120,150,200,.10); --grid-bold:rgba(120,150,200,.20);
  --grid-paper:rgba(150,180,230,.10);   /* background graph paper, v1.72 — LIGHTER than the page, see the note by body::before */

  /* atmospheric / structural (previously hardcoded) */
  --glyph-bg:#0d1730;
  /* was #16244a / #d5dff0 - the top-right page glow. Switched OFF (v1.73): on a wide
     monitor a 1200-1300px radial anchored at 75-80% -10% reads as a distinct orb in the
     corner rather than as ambient light. It is referenced by 170 pages across three
     slightly different gradients, so it is killed HERE, at the token - every one of those
     gradients still exists and goes back to work the moment this is given a colour. */
  --bg-rad-1:transparent;
  --bg-rad-2:transparent;   /* off with --bg-rad-1 - despite the old name this one sits
                               TOP-left (-5% 8%), and it is the orb that was left behind
                               when only --bg-rad-1 was switched off. */
  --bg-rad-fin:#1c1a3a; /* finance pages lean violet */
  --banner-a:#1d1733; --banner-b:#141a30;  /* probe/station banner gradient */

  /* accent glow strength — strong on dark, softened on light */
  --glow:1;
  --shadow-card:0 14px 30px -18px #000;

  /* ---- viz / simulator surfaces (SVG hosts, chart plates) ---- */
  --viz-bg:var(--ink);
  --viz-border:var(--line-soft);
  --viz-axis:var(--muted-2);
  --viz-grid-line:var(--grid);
  --viz-label:var(--muted);
}

/* explicit dark override (when rot.js forces it) keeps defaults */
:root[data-theme="dark"]{ color-scheme:dark; }

/* ---- LIGHT THEME ---- */
/* Re-treated rather than inverted: warm off-white instrument
   surfaces, deepened accents, glows traded for soft shadows. */
:root[data-theme="light"]{
  color-scheme:light;
  --amber:#8d5c14; --amber-dim:#6f470f;
  --cyan:#1b6f8e; --cyan-dim:#5aa6c0;
  --violet:#6d4bc4; --violet-dim:#9b85d8;
  --green:#23744e; --green-dim:#1a5a3c; --red:#b8374a;
  --pink:#b2347d; --pink-dim:#d98ab8;
  --indigo:#4a5fc4; --indigo-dim:#8894d6;
  --coral:#a74c27; --coral-dim:#a3491f;
  --teal:#0e7466; --teal-dim:#0a5a4f;
  --azure:#1d5fb8; --azure-dim:#123f7a;
  --lime:#4b7115; --lime-dim:#456b12;

  --ink:#e3e8f1; --ink-2:#eef1f8;
  --panel:#ffffff; --panel-2:#f7f9fd;
  --line:#c4cfe1; --line-soft:#d4dcea;
  --text:#16213a; --muted:#52607c; --muted-2:#5a6884;
  --grid:rgba(70,90,130,.11); --grid-bold:rgba(70,90,130,.20); --grid-paper:rgba(45,70,115,.13);

  --glyph-bg:#eef2f9;
  --bg-rad-1:transparent;   /* off - see the note in the dark block */
  --bg-rad-2:transparent;
  --bg-rad-fin:#ece7f7;
  --banner-a:#efeafb; --banner-b:#eef1fa;

  --glow:0;
  --shadow-card:0 12px 26px -16px rgba(40,60,100,.35);

  --viz-bg:#f4f7fc;
  --viz-border:var(--line);
  --viz-axis:var(--muted-2);
  --viz-grid-line:var(--grid);
  --viz-label:var(--muted);
}

@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]){
    color-scheme:light;
    --amber:#8d5c14; --amber-dim:#6f470f;
    --cyan:#1b6f8e; --cyan-dim:#5aa6c0;
    --violet:#6d4bc4; --violet-dim:#9b85d8;
    --green:#23744e; --green-dim:#1a5a3c; --red:#b8374a;
    --pink:#b2347d; --pink-dim:#d98ab8;
    --indigo:#4a5fc4; --indigo-dim:#8894d6;
  --coral:#a74c27; --coral-dim:#a3491f;
  --teal:#0e7466; --teal-dim:#0a5a4f;
  --azure:#1d5fb8; --azure-dim:#123f7a;
  --lime:#4b7115; --lime-dim:#456b12;

    --ink:#e3e8f1; --ink-2:#eef1f8;
    --panel:#ffffff; --panel-2:#f7f9fd;
    --line:#c4cfe1; --line-soft:#d4dcea;
    --text:#16213a; --muted:#52607c; --muted-2:#5a6884;
    --grid:rgba(70,90,130,.11); --grid-bold:rgba(70,90,130,.20); --grid-paper:rgba(45,70,115,.13);

    --glyph-bg:#eef2f9;
    --bg-rad-1:transparent;   /* off - see the note in the dark block */
    --bg-rad-2:transparent;
    --bg-rad-fin:#ece7f7;
    --banner-a:#efeafb; --banner-b:#eef1fa;

    --glow:0;
    --shadow-card:0 12px 26px -16px rgba(40,60,100,.35);

    --viz-bg:#f4f7fc;
    --viz-border:var(--line);
    --viz-axis:var(--muted-2);
    --viz-grid-line:var(--grid);
    --viz-label:var(--muted);
  }
}

/* Prevent a flash of the wrong theme: rot.js sets data-theme before paint. */
html{ background:var(--ink); }

/* Smooth dark/light theme switching for the page background and every
   shared-chrome component (controls, palette, toasts, related-tools strip).
   Deliberately scoped here rather than applied universally: many tools have
   real-time drag/redraw interactions (dials, sliders, live charts) where a
   blanket transition can't be visually verified safe without a real browser,
   so the toggle stays instant inside individual tools and smooth everywhere
   this stylesheet owns directly. */
html{ transition: background-color .35s ease; }
.rot-controls, .rot-btn, .rot-cmd, .rot-cmd input, .rot-cmd-item, .rot-cmd-hint kbd,
.rot-toast, .rot-skip, .rot-share, .rot-related .rr-item, .rot-content .rc-example,
.rot-content .faq .q{
  transition: background-color .3s ease, border-color .3s ease, color .3s ease, box-shadow .3s ease;
}
@media (prefers-reduced-motion:reduce){
  html, .rot-controls, .rot-btn, .rot-cmd, .rot-cmd input, .rot-cmd-item, .rot-cmd-hint kbd,
  .rot-toast, .rot-skip, .rot-share, .rot-related .rr-item, .rot-content .rc-example,
  .rot-content .faq .q{ transition:none !important; }
}

/* ============================================================
   Shared chrome — theme toggle + command palette
   (component CSS that every page gets for free)
   ============================================================ */
.rot-controls{
  position:fixed; top:14px; right:16px; z-index:60;
  display:flex; gap:8px; align-items:center;
}
.rot-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  width:36px; height:36px; border-radius:10px; cursor:pointer;
  background:color-mix(in srgb, var(--panel) 82%, transparent);
  border:1px solid var(--line);
  color:var(--muted); backdrop-filter:blur(8px);
  transition:color .15s, border-color .15s, background .15s, transform .12s;
}
.rot-btn:hover{ color:var(--text); border-color:var(--violet); transform:translateY(-1px); }
.rot-btn svg{ width:17px; height:17px; }
/* Currency control is a glyph, not an icon — the symbol itself is the affordance.
   Multi-character symbols (CA$, A$) get squeezed rather than overflowing the 36px button.
   Dimmed while on 'auto' so an explicit override reads as deliberately set. */
.rot-cur-btn{ font-family:'IBM Plex Mono',monospace; font-size:15px; font-weight:600;
  letter-spacing:-.02em; line-height:1; padding:0 2px; }
.rot-cur-btn.is-auto{ color:var(--muted-2); }
.rot-cur-btn:hover{ color:var(--text); }
.rot-btn .lbl{ display:none; }

/* Search bar in the top-right chrome (replaces square search icon) */
.rot-searchbar{
  display:inline-flex; align-items:center; gap:8px;
  height:36px; min-width:168px; max-width:min(260px,42vw); padding:0 10px 0 11px;
  border-radius:10px; cursor:pointer;
  background:color-mix(in srgb, var(--panel) 88%, transparent);
  border:1px solid var(--line);
  color:var(--muted); backdrop-filter:blur(8px);
  font-family:'Inter',system-ui,sans-serif; font-size:12.5px;
  transition:color .15s, border-color .15s, background .15s, transform .12s;
}
.rot-searchbar:hover{ color:var(--text); border-color:var(--violet); transform:translateY(-1px); }
.rot-searchbar svg{ width:15px; height:15px; flex:none; opacity:.85; }
.rot-search-ph{ flex:1; min-width:0; text-align:left; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:var(--muted-2); }
.rot-searchbar:hover .rot-search-ph{ color:var(--muted); }
.rot-search-kbd{
  font-family:'IBM Plex Mono',monospace; font-size:10.5px; color:var(--muted-2);
  background:var(--ink); border:1px solid var(--line); border-radius:5px; padding:1px 6px; flex:none;
}

@media (max-width:560px){
  /* The floating controls are position:fixed at top:10px and 32px tall, so the top 42px of the
     viewport belongs to them. Below 560px the breadcrumb runs straight underneath the search bar
     and becomes unreadable and unclickable — measured: it collides at <=560px and clears from
     600px up, which is exactly this breakpoint. Reserve the space instead.

     `body .wrap` rather than `.wrap` on purpose. The container is redefined by tool.css, by
     index.html and by every area hub, all at (0,0,1,0) and several loaded after this file; the
     descendant selector wins on specificity regardless of source order, so one rule fixes every
     page type and the next page added gets it for free. */
  body .wrap{ padding-top:54px; }

  .rot-controls{ top:10px; right:10px; }
  .rot-btn{ width:32px; height:32px; }
  .rot-searchbar{ min-width:0; max-width:42vw; height:32px; padding:0 8px; font-size:11.5px; }
  .rot-search-kbd{ display:none; }
}

/* Snapshot button: same chrome as the other controls, plus a one-time gentle
   pulse so returning visitors notice the new feature without it becoming a
   permanent distraction. */
.rot-snap-btn{ position:relative; color:var(--amber); }
.rot-snap-btn:hover{ color:var(--text); border-color:var(--amber); background:color-mix(in srgb,var(--amber) 12%,transparent); }
.rot-snap-btn::after{
  content:""; position:absolute; inset:-3px; border-radius:12px;
  border:1.5px solid var(--amber); opacity:0; pointer-events:none;
  animation: rot-snap-pulse 2.4s ease-out 1;
}
@keyframes rot-snap-pulse{
  0%{ opacity:.9; transform:scale(1); }
  100%{ opacity:0; transform:scale(1.35); }
}
@media (prefers-reduced-motion:reduce){ .rot-snap-btn::after{ animation:none; } }
/* Optional in-page CTA: <button type="button" class="rot-snap-cta" data-rot-snap>Snapshot</button> */
.rot-snap-cta{
  display:inline-flex; align-items:center; gap:7px;
  font-family:'IBM Plex Mono',monospace; font-size:12px; font-weight:600;
  color:var(--ink); background:linear-gradient(90deg,var(--amber),color-mix(in srgb,var(--coral) 50%,var(--amber)));
  border:none; border-radius:9px; padding:9px 14px; cursor:pointer;
}
.rot-snap-cta:hover{ filter:brightness(1.06); }

.rot-pin-btn.pinned{ color:var(--amber); border-color:var(--amber); }
/* Favorite = pin star + shared tally count (top chrome) */
.rot-fav-btn{ position:relative; width:auto !important; min-width:36px; padding:0 8px !important; gap:4px; }
.rot-fav-btn .rot-fav-n{
  font-family:'IBM Plex Mono',monospace; font-size:10px; font-weight:600;
  color:var(--muted-2); line-height:1; margin-left:1px;
}
.rot-fav-btn.pinned .rot-fav-n{ color:var(--amber); }
.rot-fav-btn.api-down .rot-fav-n{ opacity:.45; }

/* Command palette overlay */
.rot-cmd-back{
  position:fixed; inset:0; z-index:200; display:none;
  background:color-mix(in srgb, var(--ink) 62%, transparent); backdrop-filter:blur(8px) saturate(1.15); -webkit-backdrop-filter:blur(8px) saturate(1.15);
  align-items:flex-start; justify-content:center; padding:14vh 16px 0;
}
.rot-cmd-back.open{ display:flex; animation:rot-back-in .16s ease; }
@keyframes rot-back-in{ from{ opacity:0; } to{ opacity:1; } }
.rot-cmd{
  width:100%; max-width:560px;
  background:linear-gradient(180deg,var(--panel),var(--ink-2));
  border:1px solid var(--line); border-radius:14px; overflow:hidden;
  box-shadow:0 30px 80px -30px #000, 0 0 0 1px color-mix(in srgb, var(--amber) 8%, transparent);
  font-family:'Inter',system-ui,sans-serif;
}
.rot-cmd-back.open .rot-cmd{ animation:rot-cmd-in .2s cubic-bezier(.3,1.1,.5,1); }
@keyframes rot-cmd-in{ from{ opacity:0; transform:translateY(10px) scale(.975); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){
  .rot-cmd-back.open, .rot-cmd-back.open .rot-cmd{ animation:none; }
}
.rot-cmd input{
  width:100%; box-sizing:border-box; border:none; outline:none;
  background:transparent; color:var(--text);
  font-family:'Space Grotesk','Inter',sans-serif; font-size:17px;
  padding:16px 18px; border-bottom:1px solid var(--line-soft);
}
.rot-cmd input::placeholder{ color:var(--muted-2); }
.rot-cmd-list{ max-height:48vh; overflow-y:auto; padding:6px; }
.rot-cmd-item{
  display:flex; align-items:center; gap:11px; padding:10px 12px; border-radius:9px;
  cursor:pointer; color:var(--muted); text-decoration:none;
}
.rot-cmd-item .nm{ color:var(--text); font-weight:500; font-size:14px; }
.rot-cmd-item .area{ font-family:'IBM Plex Mono',monospace; font-size:10px;
  text-transform:uppercase; letter-spacing:.1em; color:var(--muted-2); margin-left:auto; }
.rot-cmd-item.sel, .rot-cmd-item:hover{
  background:color-mix(in srgb, var(--acc, var(--violet)) 13%, transparent);
  box-shadow:inset 2.5px 0 0 var(--acc, var(--violet));
}
.rot-cmd-item{ transition:background .1s ease; }
.rot-cmd-item .dot{ width:7px; height:7px; border-radius:50%; flex:none; }
.rot-cmd-empty{ padding:20px; text-align:center; color:var(--muted-2); font-size:13px; }

/* ---- instant answers: the palette doubles as a calculator ---- */
.rot-cmd-answer{ flex-direction:column; align-items:flex-start !important; gap:3px !important;
  border:1px solid var(--line); border-radius:10px; margin:2px 2px 6px;
  background:linear-gradient(135deg, color-mix(in srgb, var(--amber) 9%, transparent), color-mix(in srgb, var(--cyan) 7%, transparent)); }
.rot-cmd-answer .rot-ans-main{ font-family:'IBM Plex Mono',monospace; font-size:19px; font-weight:600;
  color:var(--text); letter-spacing:-.01em; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }
.rot-cmd-answer .rot-ans-sub{ font-size:11px; color:var(--muted-2); }
.rot-cmd-answer.sel, .rot-cmd-answer:hover{ border-color:var(--amber-dim); box-shadow:none;
  background:linear-gradient(135deg, color-mix(in srgb, var(--amber) 15%, transparent), color-mix(in srgb, var(--cyan) 11%, transparent)); }

/* ---- rulebook hits in search ---- */
.rot-cmd-rule{ align-items:flex-start !important; }
.rot-cmd-rule .dot{ margin-top:6px; }
.rot-cmd-rule .rot-rule-body{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.rot-cmd-rule .rot-rule-text{ font-size:11.5px; color:var(--muted); line-height:1.45; }
.rot-cmd-hint .rot-hint-full{ color:var(--cyan); text-decoration:none; margin-left:auto;
  border:1px solid var(--cyan-dim); border-radius:6px; padding:2px 8px; }
.rot-cmd-hint .rot-hint-full:hover{ border-color:var(--cyan); }
.rot-cmd-hint .rot-hint-eq{ margin-left:14px; color:var(--amber); opacity:.85; }
@media (max-width:560px){ .rot-cmd-hint .rot-hint-eq{ display:none; }
  .rot-cmd-hint .rot-hint-full{ margin-left:auto; } }
.rot-cmd-hint{ padding:8px 14px; border-top:1px solid var(--line-soft);
  font-family:'IBM Plex Mono',monospace; font-size:10px; color:var(--muted-2);
  display:flex; gap:14px; flex-wrap:wrap; }
.rot-cmd-hint kbd{ background:var(--ink); border:1px solid var(--line); border-radius:4px;
  padding:1px 5px; color:var(--muted); }

/* Toast (copy confirmation) */
/* Export + recent-calculations panel, opened from the controls bar. Anchored to the same
   corner as the buttons, and capped in height so a full history still fits a phone. */
.rot-export{
  position:fixed; top:58px; right:12px; z-index:1002;
  width:min(340px, calc(100vw - 24px)); max-height:min(70vh, 560px); overflow-y:auto;
  background:var(--panel); border:1px solid var(--line); border-radius:14px;
  box-shadow:0 18px 48px rgba(0,0,0,.42);
  font-family:'IBM Plex Mono',monospace;
}
.rot-export .rx-sec{ padding:12px; border-bottom:1px solid var(--line); }
.rot-export .rx-sec:last-child{ border-bottom:0; }
.rot-export .rx-h{
  display:flex; align-items:center; justify-content:space-between;
  font-size:10px; letter-spacing:.13em; text-transform:uppercase; color:var(--muted-2);
  font-weight:600; margin:0 2px 9px;
}
.rot-export .rx-clear{
  font-family:inherit; font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted-2); background:none; border:0; cursor:pointer; padding:2px 4px;
}
.rot-export .rx-clear:hover{ color:var(--red); }
.rot-export .rx-item{
  display:block; width:100%; text-align:left; font-family:inherit; cursor:pointer;
  background:var(--ink-2); border:1px solid var(--line); border-radius:9px;
  padding:9px 11px; margin-bottom:6px; color:var(--muted);
}
.rot-export .rx-item:last-child{ margin-bottom:0; }
.rot-export .rx-item:hover{ border-color:var(--accent, var(--amber)); color:var(--text); }
.rot-export .rx-item b{ display:block; font-size:12.5px; color:var(--text); font-weight:600; }
.rot-export .rx-item span{ display:block; font-size:10.5px; margin-top:2px; color:var(--muted-2); }
.rot-export .rx-empty{ font-size:11.5px; line-height:1.6; color:var(--muted-2); margin:0 2px; }
.rot-export .rx-list{ display:flex; flex-direction:column; gap:5px; }
.rot-export .rx-rec{
  display:block; text-decoration:none; background:var(--ink-2);
  border:1px solid var(--line); border-radius:9px; padding:8px 11px;
}
.rot-export .rx-rec:hover{ border-color:var(--accent, var(--amber)); }
.rot-export .rx-rn{ display:block; font-size:11px; color:var(--muted-2); }
.rot-export .rx-rh{ display:block; font-size:12.5px; color:var(--text); font-weight:600; margin-top:1px; }
.rot-export .rx-rt{ display:block; font-size:10px; color:var(--muted-2); margin-top:3px; }
@media (max-width:560px){
  .rot-export{ top:52px; right:10px; left:10px; width:auto; }
}

.rot-export .rx-seg{ display:flex; gap:5px; }
.rot-export .rx-sb{
  flex:1; font-family:inherit; font-size:11.5px; cursor:pointer; padding:7px 6px;
  background:var(--ink-2); border:1px solid var(--line); border-radius:8px; color:var(--muted);
}
.rot-export .rx-sb:hover{ color:var(--text); border-color:var(--line-soft); }
.rot-export .rx-sb.on{ background:var(--amber); border-color:var(--amber); color:var(--ink-2); font-weight:600; }

.rot-export .rx-wfname{ font-size:11.5px; color:var(--muted); margin:0 2px 7px; }
.rot-export .rx-wfswitch{ display:flex; flex-wrap:wrap; gap:5px; margin-top:8px; }
.rot-export .rx-tab{
  font-family:inherit; font-size:10.5px; color:var(--muted-2); cursor:pointer;
  background:transparent; border:1px dashed var(--line); border-radius:20px; padding:4px 10px;
}
.rot-export .rx-tab.on{ color:var(--ink-2); background:var(--amber); border-color:var(--amber); border-style:solid; }

/* "next in your workflow", above the related-tools strip on a tool page */
.rot-wfnext{
  max-width:var(--wrap-max, 1180px); margin:26px auto 0; padding:14px 16px;
  background:var(--panel); border:1px solid var(--line); border-left:3px solid var(--amber);
  border-radius:12px; font-family:'IBM Plex Mono',monospace;
}
.rot-wfnext .wf-h{
  font-size:10px; letter-spacing:.13em; text-transform:uppercase; color:var(--muted-2); font-weight:600;
}
.rot-wfnext .wf-p{ color:var(--amber); margin-left:6px; }
.rot-wfnext .wf-go{
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  margin-top:9px; text-decoration:none;
}
.rot-wfnext .wf-lb{ font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:var(--muted-2); }
.rot-wfnext .wf-nm{ font-size:15px; font-weight:600; color:var(--text); }
.rot-wfnext .wf-go:hover .wf-nm{ color:var(--amber); }
.rot-wfnext .wf-hh{ font-size:12px; color:var(--muted); }
.rot-wfnext .wf-end{ font-size:12px; color:var(--muted); margin:8px 0 0; }

/* the import offer for a shared ?w= link */
.rot-wfimport{
  position:fixed; left:50%; bottom:22px; transform:translateX(-50%); z-index:1003;
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  max-width:min(560px, calc(100vw - 24px));
  background:var(--panel); border:1px solid var(--amber); border-radius:12px;
  padding:11px 14px; box-shadow:0 14px 40px rgba(0,0,0,.42);
  font-family:'IBM Plex Mono',monospace; font-size:12px; color:var(--muted);
}
.rot-wfimport b{ color:var(--text); }
.rot-wfimport button{
  font-family:inherit; font-size:11px; cursor:pointer; border-radius:8px; padding:5px 11px;
  background:transparent; border:1px solid var(--line); color:var(--muted);
}
.rot-wfimport button[data-a="add"]{ background:var(--amber); border-color:var(--amber); color:var(--ink-2); font-weight:600; }

/* First-visit tour. A corner card rather than a modal, so the highlighted element stays
   visible and the page stays usable while it is open. */
.rot-tour{
  position:fixed; right:16px; bottom:16px; z-index:1004;
  width:min(360px, calc(100vw - 32px));
  background:var(--panel); border:1px solid var(--amber); border-radius:14px;
  padding:15px 17px; box-shadow:0 20px 52px rgba(0,0,0,.5);
}
.rot-tour .tr-n{
  font-family:'IBM Plex Mono',monospace; font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--amber); font-weight:600;
}
.rot-tour h2{ font-size:16.5px; margin:7px 0 0; color:var(--text); }
.rot-tour p{ font-size:13px; line-height:1.6; color:var(--muted); margin:7px 0 0; }
.rot-tour kbd{
  font-family:'IBM Plex Mono',monospace; font-size:11px; background:var(--ink-2);
  border:1px solid var(--line); border-radius:5px; padding:1px 5px; color:var(--text);
}
.rot-tour .tr-btns{ display:flex; gap:7px; justify-content:flex-end; margin-top:13px; }
.rot-tour button{
  font-family:'IBM Plex Mono',monospace; font-size:11.5px; cursor:pointer;
  background:transparent; border:1px solid var(--line); border-radius:8px;
  padding:6px 13px; color:var(--muted);
}
.rot-tour button:hover{ color:var(--text); border-color:var(--line-soft); }
.rot-tour button.tr-go{ background:var(--amber); border-color:var(--amber); color:var(--ink-2); font-weight:600; }
.rot-tour-spot{
  outline:2px solid var(--amber); outline-offset:5px; border-radius:12px;
  scroll-margin-top:80px;
}
.rot-tour-link{ white-space:nowrap; }
@media (max-width:560px){
  .rot-tour{ left:12px; right:12px; bottom:12px; width:auto; }
}

/* contextual correction prompt, under the caveat bar on tool and rule pages */
.rot-fb{
  max-width:var(--wrap-max, 1180px); margin:14px auto 0;
  font-size:12.5px; line-height:1.6; color:var(--muted-2); text-align:center;
}
.rot-fb a{ color:var(--amber); }

.rot-toast{
  position:fixed; left:50%; bottom:28px; transform:translateX(-50%) translateY(20px);
  z-index:120; opacity:0; pointer-events:none;
  background:linear-gradient(180deg,var(--panel-2),var(--ink-2));
  border:1px solid var(--green); color:var(--text);
  font-family:'IBM Plex Mono',monospace; font-size:12.5px;
  padding:10px 16px; border-radius:10px; box-shadow:0 14px 30px -16px #000;
  transition:opacity .2s, transform .2s;
}
.rot-toast.show{ opacity:1; transform:translateX(-50%) translateY(0); pointer-events:auto; }

@media (prefers-reduced-motion:reduce){
  .rot-btn, .rot-toast, .rot-cmd-item{ transition:none; }
}

/* Skip-to-content link (visible only on keyboard focus) */
.rot-skip{
  position:fixed; top:-60px; left:14px; z-index:300;
  background:var(--panel-2); color:var(--text); border:1px solid var(--line);
  border-radius:9px; padding:10px 16px; font-family:'IBM Plex Mono',monospace; font-size:12.5px;
  text-decoration:none; transition:top .15s ease;
}
.rot-skip:focus{ top:14px; }

/* Related tools strip — auto-injected before each tool page's footer.
   Uses tool.css's .rhead/.ey/h2 pattern (every tool page loads tool.css)
   so it reads as a real content section, not a footnote. */
.rot-related{
  margin-top:26px; padding:22px 24px; border-radius:16px;
  background:linear-gradient(180deg, color-mix(in srgb, var(--accent,var(--amber)) 6%, var(--panel)), var(--ink-2));
  border:1px solid var(--line);
}
.rot-related .rr-privacy-note{ font-size:10px; text-transform:none; letter-spacing:0; font-weight:400; color:var(--muted-2); opacity:.85; }
.rot-related .rr-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:10px; }
.rot-related .rr-item{
  position:relative; display:flex; flex-direction:column; gap:3px; font-family:'Inter',sans-serif;
  text-decoration:none; color:var(--text);
  background:linear-gradient(180deg,var(--panel),var(--ink-2)); border:1px solid var(--line);
  border-radius:12px; padding:13px 14px 13px 16px; transition:border-color .14s ease, transform .14s ease;
  overflow:hidden;
}
.rot-related .rr-item:before{ content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--rc,var(--muted-2)); }
.rot-related .rr-item:hover{ border-color:var(--line-soft); transform:translateY(-1px); }
.rot-related .rr-item .rr-name{ font-size:13px; font-weight:600; line-height:1.3; }
.rot-related .rr-item .rr-sub{ font-family:'IBM Plex Mono',monospace; font-size:10px; color:var(--muted-2); }
.rot-related .rr-item.rr-all{ justify-content:center; align-items:center; color:var(--muted-2); border-style:dashed; }
.rot-related .rr-item.rr-all:before{ display:none; }

/* ============================================================
   Shared "copy results / share" button (used inside tool heroes)
   ============================================================ */
.rot-share{
  display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  font-family:'IBM Plex Mono',monospace; font-size:11px; font-weight:500;
  color:var(--muted); background:var(--ink);
  border:1px solid var(--line); border-radius:8px; padding:6px 11px;
  transition:color .14s, border-color .14s, background .14s;
}
.rot-share:hover{ color:var(--text); border-color:var(--violet); background:color-mix(in srgb, var(--violet) 10%, transparent); }
.rot-share svg{ width:13px; height:13px; flex:none; }
.rot-share.amber:hover{ border-color:var(--amber); background:color-mix(in srgb, var(--amber) 10%, transparent); }
.rot-share.cyan:hover{ border-color:var(--cyan); background:color-mix(in srgb, var(--cyan) 10%, transparent); }

/* ============================================================
   Shared below-the-fold content section (intro / example / FAQ)
   Reuses each tool's section heading; these style the prose body.

   Field Notes and "Using this tool" are colour-coded consistently
   across every tool page (not tied to that page's own accent) so the
   two kinds of content stay visually distinct at a glance: amber for
   the quick-reference facts, cyan for the how-it-works walkthrough.
   Both also get more vertical breathing room between and within their
   blocks than the default .rhead/.gloss spacing, since a wall of prose
   reads as denser than the same words with natural page breaks.
   ============================================================ */
/* ============================================================
   Shared below-the-fold content section (intro / example / FAQ)
   Reuses each tool's section heading; these style the prose body.

   Field Notes and "Using this tool" are colour-coded boldly and
   consistently across every tool page (not tied to that page's own
   accent), so the two kinds of content are unmistakable at a glance
   even scrolling fast: amber for the quick-reference facts, cyan for
   the how-it-works walkthrough. Each gets its own accent bar, a
   solid eyebrow badge, a faint full-section wash, and noticeably
   more vertical space than the default .rhead/.gloss spacing, since
   a wall of prose reads as denser than the same words broken up with
   real page breaks.
   ============================================================ */
/* These two sections previously stacked THREE devices to say one thing: a floating
   72x4 glowing bar pinned top-left, a solid pill badge, and a gradient wash — and
   they were the only sections on the page that broke the shared .rhead/.ey
   convention every other section follows. The bar in particular read as a stray
   artifact rather than structure.

   Now they use the site's own eyebrow grammar (10px mono, letterspaced, uppercase)
   and differ only by colour, which is the part that carried real meaning: amber for
   the quick-reference facts, cyan for the walkthrough. A hairline under the heading
   carries the section break, matching how the rest of the page divides content. */
/* Target the CLASS, not the aria-label. These rules used to key off
   section[aria-label="Field notes"], which silently dropped the styling on any page
   that gave the section a more descriptive accessible name — psychrometer
   ("What each metric means") and unit-converter ("Notes") both looked different for
   exactly that reason, despite identical markup and eyebrow. Presentation should
   never depend on human-readable label text; aria-label is free to describe. */
.rot-fieldnotes,
.rot-content{
  position:relative; padding-top:26px; background:none;
}
.rot-fieldnotes:before,
.rot-content:before{ content:none; }

.rot-fieldnotes .rhead,
.rot-content .rhead{
  padding-bottom:13px; margin-bottom:22px; border-bottom:1px solid var(--line-soft);
}
/* colour-coded, but same weight and rhythm as every other eyebrow on the page */
.rot-fieldnotes .rhead .ey{
  color:var(--amber); background:none; padding:0; border-radius:0; font-weight:600;
}
.rot-content .rhead .ey{
  color:var(--cyan); background:none; padding:0; border-radius:0; font-weight:600;
}

.rot-fieldnotes .gloss{ gap:20px; }
.rot-fieldnotes .gcard{
  border-left:3px solid color-mix(in srgb, var(--amber) 55%, transparent);
}
.rot-content .rc-intro{ font-size:13.5px; color:var(--muted); line-height:1.65; max-width:74ch; margin:0 0 22px; }
.rot-content .rc-intro b{ color:var(--text); font-weight:600; }
.rot-content .rc-example{
  background:linear-gradient(180deg,var(--panel),var(--ink-2)); border:1px solid var(--line); border-left:4px solid color-mix(in srgb, var(--cyan) 75%, transparent);
  border-radius:13px; padding:16px 18px; margin:0 0 22px; max-width:760px;
  box-shadow:-1px 0 16px -8px color-mix(in srgb, var(--cyan) 40%, transparent);
}
.rot-content .rc-example h4{
  font-family:'Space Grotesk',sans-serif; font-weight:600; font-size:13.5px; margin:0 0 9px;
  color:var(--text); display:flex; align-items:center; gap:8px;
}
.rot-content .rc-example h4:before{ content:""; width:7px; height:7px; border-radius:50%;
  background:var(--cyan); box-shadow:0 0 8px var(--cyan); }
.rot-content .rc-example p{ font-size:12.5px; color:var(--muted); line-height:1.6; margin:0 0 7px; }
.rot-content .rc-example p:last-child{ margin-bottom:0; }
.rot-content .rc-example b{ color:var(--text); font-weight:600; }
.rot-content .rc-example .num{ font-family:'IBM Plex Mono',monospace; color:var(--cyan); }
.rot-content .faq{ display:grid; grid-template-columns:repeat(2,1fr); gap:16px; }
@media (max-width:760px){ .rot-content .faq{ grid-template-columns:1fr; } }
.rot-content .faq .q{
  background:linear-gradient(180deg,var(--panel),var(--ink-2)); border:1px solid var(--line); border-left:4px solid color-mix(in srgb, var(--cyan) 55%, transparent);
  border-radius:12px; padding:14px 16px;
}
.rot-content .faq .q h4{ font-family:'Space Grotesk',sans-serif; font-weight:600; font-size:13.5px;
  margin:0 0 6px; color:var(--text); }
.rot-content .faq .q p{ font-size:12.5px; color:var(--muted); line-height:1.6; margin:0; }
.rot-content .faq .q p b{ color:var(--text); font-weight:600; }

/* ============================================================
   Global polish layer (v2) — one file, every page benefits.
   Everything below is progressive enhancement: old browsers
   simply ignore what they don't understand.
   ============================================================ */

/* Command palette group headers (Recent / Everything) */
.rot-cmd-group{
  padding:9px 12px 4px; font-family:'IBM Plex Mono',monospace;
  font-size:9.5px; font-weight:600; letter-spacing:.18em; text-transform:uppercase;
  color:var(--muted-2); user-select:none;
}
.rot-cmd-group + .rot-cmd-item{ margin-top:1px; }

/* Text selection carries the brand */
::selection{ background:color-mix(in srgb, var(--amber) 32%, transparent); color:var(--text); }
/* Gradient-clipped headings (.h1-hl on the homepage) paint their glyphs with
   -webkit-text-fill-color:transparent, which OVERRIDES the `color` above — so selecting them
   drew a solid amber band with invisible letters inside it. Restore a real fill while
   selected; the gradient returns the moment the selection clears. */
.h1-hl::selection{ -webkit-text-fill-color:var(--text); color:var(--text); }
.h1-hl::-moz-selection{ -webkit-text-fill-color:var(--text); color:var(--text); }

/* Themed scrollbars — thin, quiet, matching the instrument chrome */
html{ scrollbar-width:thin; scrollbar-color:var(--line) transparent; }
::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-track{ background:transparent; }
::-webkit-scrollbar-thumb{ background:var(--line); border-radius:8px; border:2px solid var(--ink); }
::-webkit-scrollbar-thumb:hover{ background:var(--muted-2); }

/* A default focus ring for anything a page hasn't styled itself.
   :where() keeps specificity at zero so per-page rules always win. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible{
  outline:2px solid var(--amber); outline-offset:2px; border-radius:4px;
}

/* Cross-page view transitions — navigation feels like one continuous
   instrument panel instead of discrete page loads. Chromium-only for
   now; other engines fall back to instant navigation, unharmed. */
@view-transition{ navigation:auto; }
@keyframes rot-vt-out{ to{ opacity:0; } }
@keyframes rot-vt-in{ from{ opacity:0; transform:translateY(5px); } to{ opacity:1; transform:none; } }
::view-transition-old(root){ animation:rot-vt-out .14s ease both; }
::view-transition-new(root){ animation:rot-vt-in .22s ease both; }
@media (prefers-reduced-motion:reduce){
  ::view-transition-old(root), ::view-transition-new(root){ animation:none; }
}

/* Chart data-table fallback (ROT.setTable) */
.rot-datatable{ margin-top:10px; border:1px solid var(--line); border-radius:10px; overflow:hidden; }
.rot-datatable summary{ font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--muted-2);
  padding:9px 13px; cursor:pointer; user-select:none; letter-spacing:.06em; }
.rot-datatable summary:hover{ color:var(--text); }
.rot-datatable[open] summary{ border-bottom:1px solid var(--line); color:var(--muted); }
.rot-dt-scroll{ max-height:280px; overflow:auto; }
.rot-datatable table{ width:100%; border-collapse:collapse; font-family:'IBM Plex Mono',monospace; font-size:11.5px; }
.rot-datatable caption{ text-align:left; padding:8px 13px 2px; color:var(--muted-2); font-size:10.5px; }
.rot-datatable th{ position:sticky; top:0; background:var(--panel); color:var(--muted); font-weight:600;
  text-align:right; padding:7px 13px; border-bottom:1px solid var(--line); }
.rot-datatable th:first-child, .rot-datatable td:first-child{ text-align:left; }
.rot-datatable td{ text-align:right; padding:5px 13px; color:var(--muted); border-bottom:1px solid var(--line-soft); }
.rot-datatable tr:last-child td{ border-bottom:none; }

/* Rule-of-thumb card — auto-mounted on tool pages whose tool has a Rulebook entry */
.rot-rulecard{ margin-top:26px; display:flex; gap:14px; align-items:flex-start;
  background:linear-gradient(180deg,var(--panel),var(--ink-2)); border:1px solid var(--line);
  border-left:3px solid var(--amber); border-radius:13px; padding:15px 17px; }
.rot-rulecard .rc-ico{ flex:none; width:30px; height:30px; margin-top:2px; }
.rot-rulecard .rc-stack{ flex:1; min-width:0; display:flex; flex-direction:column; gap:14px; }
.rot-rulecard .rc-block + .rc-block{ padding-top:14px; border-top:1px solid var(--line-soft); }
.rot-rulecard .rc-ey{ font-size:9.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--amber);
  font-weight:600; font-family:'IBM Plex Mono',monospace; margin-bottom:4px; }
.rot-rulecard h3{ font-family:'Space Grotesk',sans-serif; font-weight:600; font-size:14.5px; margin:0 0 5px; color:var(--text); }
/* Rule title as a permalink to /rule/<slug> — inherits the heading's look so the card
   reads unchanged, and only announces itself on hover/focus. */
.rot-rulecard h3 .rc-perma{ color:inherit; text-decoration:none; }
.rot-rulecard h3 .rc-perma:hover,
.rot-rulecard h3 .rc-perma:focus-visible{ color:var(--amber); text-decoration:underline;
  text-decoration-thickness:1px; text-underline-offset:2px; }
.rot-rulecard .rc-rule{ font-size:13px; color:var(--text); line-height:1.55; margin:0 0 8px; font-weight:500; }
.rot-rulecard .rc-why{ font-size:12px; color:var(--muted); line-height:1.55; margin:0; }
.rot-rulecard .rc-why-lab{ font-family:'IBM Plex Mono',monospace; font-size:9.5px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted-2); margin-right:6px; }
.rot-rulecard .rc-links{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; padding-top:2px; }
.rot-rulecard .rc-links a{ font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--amber); text-decoration:none; font-weight:600; }
.rot-rulecard .rc-links a:hover{ text-decoration:underline; }

/* ============================================================
   Region note — generated from the registry into the page ABOVE the inputs.

   A currency symbol is not a jurisdiction: /finance/mortgage models US PMI and
   property tax and mentions stamp duty nowhere, so showing a UK reader '£' made the
   page imply rules it does not implement. This states the jurisdiction the METHOD
   assumes, before anyone types a number.

   Deliberately quieter than .refbar (the reference-only disclaimer at the foot of the
   page) — it is metadata a reader should register, not a warning that should shout on
   every visit. The amber rule ties the two together as the same family of caveat.
   ============================================================ */
.rot-region{
  display:flex; align-items:flex-start; gap:10px;
  margin:-4px 0 20px; padding:10px 13px;
  background:var(--panel); border:1px solid var(--line-soft);
  border-left:3px solid var(--amber); border-radius:9px;
  font-size:12px; line-height:1.55; color:var(--muted);
}
.rot-region .rr-tag{
  flex:none; font-family:'IBM Plex Mono',monospace; font-size:9.5px; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--amber);
  padding-top:2px;
}
.rot-region .rr-body b{ color:var(--text); font-weight:600; }
@media (max-width:560px){
  .rot-region{ flex-direction:column; gap:5px; }
}

/* ============================================================
   Per-tool version history (AUTO-GENERATED:HISTORY).
   Collapsed by default: it is a trust signal, not something anyone needs while using the tool.
   ============================================================ */
.rot-hist{ margin:26px 0 0; border-top:1px solid var(--line); padding-top:14px; }
.rot-hist summary{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer; list-style:none;
  font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.06em;
  text-transform:uppercase; color:var(--muted-2);
  border:1px solid var(--line); border-radius:8px; padding:6px 11px;
}
.rot-hist summary::-webkit-details-marker{ display:none; }
.rot-hist summary:hover{ color:var(--text); border-color:var(--violet); }
.rot-hist summary .caret{ transition:transform .15s; }
.rot-hist[open] summary .caret{ transform:rotate(90deg); }
.rot-hist ol{ list-style:none; margin:13px 0 0; padding:0; display:flex; flex-direction:column; gap:9px; }
.rot-hist li{ display:grid; grid-template-columns:auto auto 1fr; gap:11px; align-items:baseline;
  font-size:12px; line-height:1.5; color:var(--muted); }
.rot-hist .v{ font-family:'IBM Plex Mono',monospace; font-size:11.5px; color:var(--text); font-weight:600; }
.rot-hist .d{ font-family:'IBM Plex Mono',monospace; font-size:10.5px; color:var(--muted-2); white-space:nowrap; }
.rot-hist .note{ font-size:11px; color:var(--muted-2); margin:11px 0 0; line-height:1.5; }
@media (max-width:560px){
  .rot-hist li{ grid-template-columns:auto 1fr; }
  .rot-hist .d{ grid-column:2; }
}

/* ============================================================
   Financial advice disclaimer — every tool in the Finance area.
   Generated from the registry (AUTO-GENERATED:ADVICE), never hand-written, because four of the
   first ten finance tools had no disclaimer at all and selective disclaiming is worse than none.
   Red rather than the amber used by .rot-region: a region note narrows scope, this one disclaims
   liability, and stacking two identical amber bars on /finance/mortgage read as one caveat.
   ============================================================ */
  /* Was margin-top:-4px, which tucked this under the region banner when it sat above the
     inputs. Since v1.31 it sits below the results, where a negative top margin pulled it into
     the panel above it. */
.rot-advice{
  display:flex; align-items:flex-start; gap:10px;
  margin:22px 0 20px; padding:10px 13px;
  background:var(--panel); border:1px solid var(--line-soft);
  border-left:3px solid var(--red); border-radius:9px;
  font-size:12px; line-height:1.55; color:var(--muted);
}
.rot-advice .ra-tag{
  flex:none; font-family:'IBM Plex Mono',monospace; font-size:9.5px; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--red);
  padding-top:2px;
}
.rot-advice .ra-body b{ color:var(--text); font-weight:600; }
.rot-advice a{ color:var(--text); text-decoration:underline; text-underline-offset:2px; }
@media (max-width:560px){
  .rot-advice{ flex-direction:column; gap:5px; }
}

/* ============================================================
   Reduced motion — site-wide backstop.

   rot.css and home-demos.js honoured the preference, but tool.css never did and 87
   transition/animation declarations live in per-page <style> blocks, three of which
   ran keyframes regardless. Page styles load AFTER this file, so the backstop needs
   !important to reach them; JS-driven motion is handled separately via ROT.motionPaused().

   Transitions are neutralised rather than removed so focus and hover states still
   register — they just arrive instantly.
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* Motion control in the shared chrome — see ROT.motionPaused() */
.rot-motion-btn[aria-pressed="true"]{ color:var(--amber); border-color:var(--amber); }

/* Legal links line — auto-appended to every tool-page footer */
.rot-legal{ margin-top:12px; padding-top:12px; border-top:1px solid var(--line-soft);
  font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--muted-2); }
.rot-legal a{ color:var(--muted); text-decoration:none; }
.rot-legal a:hover{ color:var(--text); }

/* Print: drop the interactive chrome, keep the results */
@media print{
  .rot-controls, .rot-searchbar, .rot-cmd-back, .rot-toast, .rot-skip, .rot-related{ display:none !important; }
}


/* ============================================================
   MOTION SYSTEM
   One set of easings and durations, so every surface on the site
   accelerates and settles the same way. Everything here is off
   under prefers-reduced-motion, at the end of this file.
   ============================================================ */
:root{
  --ease-out:cubic-bezier(.22,.61,.36,1);      /* natural deceleration, the default */
  --ease-pop:cubic-bezier(.34,1.42,.64,1);     /* slight overshoot, for press and pop */
  --t-1:.12s;   /* press, tap, immediate feedback */
  --t-2:.2s;    /* hover, colour, border */
  --t-3:.34s;   /* surfaces settling */
  --t-4:.55s;   /* entrances */
}

/* ---- page entrance: content settles in rather than snapping ----
   Scoped inside no-preference so the animation does not exist at all when motion is
   reduced. That matters because it fills backwards from opacity 0 - if the rule applied
   but the animation never ran, the page would be blank. */
@media (prefers-reduced-motion:no-preference){
  @keyframes rot-rise{ from{ opacity:0; transform:translate3d(0,9px,0); } to{ opacity:1; transform:none; } }
  .wrap > nav.crumb,
  .wrap > header.mast,
  .wrap > .grid,
  .wrap > section.block,
  .wrap > section.rot-fieldnotes,
  .wrap > .refbar,
  .wrap > details.rot-hist,
  .wrap > footer{ animation:rot-rise var(--t-4) var(--ease-out) both; }
  .wrap > header.mast{ animation-delay:.03s; }
  .wrap > .grid{ animation-delay:.07s; }
  .wrap > section.block,
  .wrap > section.rot-fieldnotes{ animation-delay:.11s; }
  .wrap > .refbar,
  .wrap > details.rot-hist,
  .wrap > footer{ animation-delay:.14s; }

  /* a readout that has just changed should register as having landed, not silently
     swap. Applied by rot.js when the text content actually changes. */
  @keyframes rot-tick{
    0%{ opacity:.35; transform:translate3d(0,-2px,0); }
    100%{ opacity:1; transform:none; }
  }
  .rot-tick{ animation:rot-tick .42s var(--ease-out); }

  /* chart lines draw themselves the first time a chart scrolls into view */
  @keyframes rot-draw{ to{ stroke-dashoffset:0; } }
}

/* ---- surfaces respond to the pointer ---- */
.panel, .hero, section.block, .rot-rulecard{
  transition:border-color var(--t-2) var(--ease-out),
             box-shadow var(--t-3) var(--ease-out);
}
.panel:hover, .hero:hover{ border-color:var(--line); box-shadow:var(--shadow-card); }
/* ...except when `.hero` is a MASTHEAD rather than a panel (v1.73). The class does two jobs:
   on a tool page it is the diagram/result panel, but on the homepage and the nine area index
   pages it wraps the logo and the page title. Those have no border and no background, so the
   rule above hung a floating card shadow around the page heading whenever the pointer crossed
   it — reported as "a box around the header, like a shadow".

   The discriminator has to be BOTH parts. Element type alone is wrong: nine tool pages use
   `section.hero` with no `.hero-head` and are still panels, while `diy/paint-coverage` and
   friends use `div.hero` WITH a `.hero-head` and are panels too. Only a <div> with no head bar
   is a masthead. */
div.hero:not(:has(> .hero-head)):hover{ box-shadow:none; }

/* ---- anything clickable gets the same press ---- */
button, .rot-btn, .presets button, .seg button, .seg2 button, .seg3 button, .playbtn{
  transition:background-color var(--t-1) var(--ease-out),
             border-color var(--t-1) var(--ease-out),
             color var(--t-1) var(--ease-out),
             transform var(--t-1) var(--ease-pop),
             box-shadow var(--t-2) var(--ease-out);
}
button:active, .rot-btn:active, .presets button:active,
.seg button:active, .seg2 button:active, .seg3 button:active, .playbtn:active{
  transform:translate3d(0,1px,0) scale(.985);
}

/* ---- focus is a ring in the tool's own accent, everywhere ---- */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible{
  outline:2px solid var(--accent, var(--amber));
  outline-offset:2px;
  border-radius:7px;
}

/* ============================================================
   PLOT NORMALISATION
   A chart drawn in a 320-unit viewBox and shown 700px wide scales
   everything inside it by 2.2x; the same chart in a narrow column
   scales it to 0.35x. Text and strokes are therefore declared
   against the measured scale, which rot.js writes to --ps, so a
   10-unit label always lands at 10 CSS px whatever the container
   or the viewBox is doing.

   CSS rules beat SVG presentation attributes, which is what makes
   this work without editing 147 hand-written charts.
   ============================================================ */
.rot-plotwrap{ overflow-x:auto; overflow-y:hidden; margin:0; -webkit-overflow-scrolling:touch; }
.rot-plotwrap > svg{ min-width:var(--pmin,420px); }

.rot-plot text[font-size="6.6"]{ font-size:calc(6.6px / var(--ps,1)); }
.rot-plot text[font-size="7"]{ font-size:calc(7px / var(--ps,1)); }
.rot-plot text[font-size="7.5"]{ font-size:calc(7.5px / var(--ps,1)); }
.rot-plot text[font-size="8"]{ font-size:calc(8px / var(--ps,1)); }
.rot-plot text[font-size="8.5"]{ font-size:calc(8.5px / var(--ps,1)); }
.rot-plot text[font-size="9"]{ font-size:calc(9px / var(--ps,1)); }
.rot-plot text[font-size="9.5"]{ font-size:calc(9.5px / var(--ps,1)); }
.rot-plot text[font-size="10"]{ font-size:calc(10px / var(--ps,1)); }
.rot-plot text[font-size="10.5"]{ font-size:calc(10.5px / var(--ps,1)); }
.rot-plot text[font-size="11"]{ font-size:calc(11px / var(--ps,1)); }
.rot-plot text[font-size="11.5"]{ font-size:calc(11.5px / var(--ps,1)); }
.rot-plot text[font-size="12"]{ font-size:calc(12px / var(--ps,1)); }
.rot-plot text[font-size="12.5"]{ font-size:calc(12.5px / var(--ps,1)); }
.rot-plot text[font-size="13"]{ font-size:calc(13px / var(--ps,1)); }
.rot-plot text[font-size="15"]{ font-size:calc(15px / var(--ps,1)); }
.rot-plot text[font-size="16"]{ font-size:calc(16px / var(--ps,1)); }
.rot-plot text[font-size="18"]{ font-size:calc(18px / var(--ps,1)); }
.rot-plot text[font-size="27"]{ font-size:calc(27px / var(--ps,1)); }
.rot-plot text[font-size="30"]{ font-size:calc(30px / var(--ps,1)); }

/* Strokes stop scaling with the box, so 1.6 means 1.6 CSS pixels on every chart on the
   site rather than "1.6 times whatever this chart's scale happens to be". */
.rot-plot path, .rot-plot line, .rot-plot rect, .rot-plot circle, .rot-plot polyline{
  vector-effect:non-scaling-stroke;
}

/* one plate treatment for every chart, replacing the inline background/border/radius
   that had been repeated per page with small differences */
.rot-plot{
  background:var(--viz-bg);
  border:1px solid var(--viz-border);
  border-radius:12px;
  display:block;
  width:100%;
  height:auto;
}

/* ---- motion off ---- */
@media (prefers-reduced-motion:reduce){
  .panel, .hero, section.block, .rot-rulecard,
  button, .rot-btn, .presets button, .seg button, .seg2 button, .seg3 button, .playbtn{
    transition:none !important;
  }
  button:active, .rot-btn:active, .presets button:active,
  .seg button:active, .seg2 button:active, .seg3 button:active, .playbtn:active{
    transform:none !important;
  }
  .rot-tick{ animation:none !important; }
  .rot-plot path{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; }
}


/* ============================================================
   HOW WRONG IS THE RULE?
   The block that puts a number on the shortcut. It sits between
   "when it fails" and the calculator, so it is styled as the
   pivot between them rather than as another prose section.
   ============================================================ */
.est{
  margin:26px 0 0; padding:18px 20px 16px;
  background:linear-gradient(180deg,var(--panel),var(--ink-2));
  border:1px solid var(--line); border-left:3px solid var(--accent,var(--cyan));
  border-radius:14px;
}
.est h2{ margin:0 0 10px; font-size:15px; letter-spacing:-.01em; }
.est-head{
  margin:0 0 14px; font-size:14.5px; line-height:1.65; color:var(--muted);
}
.est-head b{ color:var(--text); font-family:'IBM Plex Mono',monospace; font-weight:600; }
.est-chart{
  width:100%; height:auto; display:block; border-radius:11px;
  background:var(--viz-bg); border:1px solid var(--viz-border);
}
.est-why{
  margin:13px 0 0; font-size:13px; line-height:1.65; color:var(--muted);
  padding-left:13px; border-left:2px solid var(--line);
}
.est-foot{ margin:11px 0 0; font-size:11.5px; line-height:1.6; color:var(--muted-2); }
@media (max-width:640px){ .est{ padding:15px 15px 13px; } }


/* ============================================================
   PRINT LAYOUT
   A tool page on paper is a worksheet: the numbers you put in,
   the answer, and the limits. Interactive furniture is dropped,
   the dark theme is flattened to ink on white, and nothing is
   allowed to break across a page mid-panel.
   ============================================================ */
@media print{
  /* the dark theme costs a cartridge and reads worse on paper */
  :root, :root[data-theme="dark"], :root[data-theme="light"]{
    --ink:#fff; --ink-2:#fff; --panel:#fff; --panel-2:#fff;
    --line:#bbb; --line-soft:#ddd; --glyph-bg:#fff;
    --text:#000; --muted:#333; --muted-2:#555;
    --grid:#e5e5e5; --grid-bold:#ccc;
    --viz-bg:#fff; --viz-border:#bbb; --viz-axis:#555; --viz-grid-line:#e5e5e5; --viz-label:#333;
    --bg-rad-1:#fff; --bg-rad-2:#fff; --bg-rad-fin:#fff; --banner-a:#fff; --banner-b:#fff;
    --shadow-card:none; --glow:0;
  }
  html, body{ background:#fff !important; color:#000 !important; }
  body::before, body::after, .wrap::before{ display:none !important; }

  /* anything that only works by being clicked */
  .rot-controls, .rot-searchbar, .rot-cmd, .rot-cmd-back, .rot-toast, .rot-skip,
  .rot-related, .rot-tour, .rot-wfnext, .rot-wfimport, .rot-fb, .rot-export,
  .rot-snap-btn, .rot-share, .rot-hist, .scenario-demos, .rot-rulecard,
  nav.crumb, .controls, .playbtn, .speed, button{
    display:none !important;
  }
  /* except the ones showing which option is selected - that IS the input */
  .presets button.on, .seg button.on, .seg2 button.on, .seg3 button.on{
    display:inline-block !important;
    border:1px solid #000 !important; background:#fff !important; color:#000 !important;
    font-weight:700 !important;
  }

  /* sliders print as their value, which the tools already show next to the label */
  input[type="range"]{ display:none !important; }
  input, select{
    border:0 !important; border-bottom:1px solid #000 !important; border-radius:0 !important;
    background:none !important; color:#000 !important; padding:0 !important;
    -webkit-appearance:none; appearance:none;
  }

  .wrap{ max-width:none !important; padding:0 !important; margin:0 !important; }
  .grid{ display:block !important; }
  .panel, .hero, section.block, .refbar, .est{
    background:#fff !important; box-shadow:none !important;
    border:1px solid #bbb !important; border-radius:6px !important;
    break-inside:avoid; page-break-inside:avoid; margin:0 0 10px !important;
  }
  header.mast{ border-bottom:2px solid #000 !important; padding-bottom:8px; margin-bottom:12px; }
  h1{ font-size:19pt !important; }
  h2{ font-size:12pt !important; break-after:avoid; page-break-after:avoid; }
  body{ font-size:10pt !important; }

  /* the answer is the reason the page was printed */
  .hero .big, .infbig .v, .bigcell .bv{ font-size:20pt !important; color:#000 !important; }

  /* charts print, but not at half a page each */
  svg{ max-height:8cm !important; break-inside:avoid; page-break-inside:avoid; }
  .rot-plotwrap{ overflow:visible !important; }
  .rot-plotwrap > svg{ min-width:0 !important; }

  /* the limits are the part you most want on the paper */
  .refbar{ border:2px solid #000 !important; }
  .refbar svg{ display:none !important; }

  /* prose that is only useful on screen */
  .rot-content .faq, .rot-fieldnotes{ break-inside:auto; }

  a{ color:#000 !important; text-decoration:none !important; }
  /* a printout with no way back to the source is a worse document */
  footer::after{
    content:"Printed from " attr(data-print-url);
    display:block; margin-top:8px; padding-top:6px;
    border-top:1px solid #bbb; font-size:8pt; color:#555;
  }
  @page{ margin:14mm; }
}


/* ---- how sure is this answer? ---- */
.unc .unc-go{
  font-family:'IBM Plex Mono',monospace; font-size:12.5px; color:var(--accent,var(--amber));
  background:var(--ink); border:1px solid var(--accent,var(--amber)); border-radius:9px;
  padding:9px 16px; cursor:pointer;
}
.unc .unc-go:hover{ background:var(--ink-2); }
.unc-head{ margin:0 0 12px; font-size:14.5px; line-height:1.65; color:var(--muted); }
.unc-head b{ color:var(--text); font-family:'IBM Plex Mono',monospace; }
.unc-sub{ margin:0 0 8px; font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted-2); font-weight:600; }
.unc-row{ display:flex; align-items:center; gap:10px; margin-bottom:6px; font-size:12.5px; }
.unc-lab{ flex:0 0 34%; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.unc-bar{ flex:1; height:9px; background:var(--ink); border:1px solid var(--line); border-radius:5px;
  overflow:hidden; }
.unc-bar i{ display:block; height:100%; background:var(--accent,var(--amber)); }
.unc-pc{ flex:0 0 40px; text-align:right; font-family:'IBM Plex Mono',monospace;
  font-size:11.5px; color:var(--text); }
.unc-foot{ margin:13px 0 0; font-size:11.5px; line-height:1.65; color:var(--muted-2); }
.unc-foot b{ color:var(--text); }
.unc-none{ margin:0; font-size:12.5px; color:var(--muted-2); }
@media print{ .unc .unc-go{ display:none !important; } }



/* ---------- the grid (v1.72) ----------
   Graph paper, which is the right metaphor for this site, and until now it existed on exactly
   one page of 273 — defined inline in index.html and switched off entirely below 560px.
   Defined once here instead, so it is the site's visual identity rather than the homepage's
   decoration.

   STACKING. This has to be a child of BODY, not html: body carries an opaque background
   (var(--ink)), so anything painted in html's context is buried under it. A first attempt used
   html::before and was invisible while animating perfectly.

   And body needs `isolation:isolate`. A negative z-index child escapes to the nearest ancestor
   STACKING CONTEXT, and `position:relative` alone does not create one — so without isolate the
   layer lands back behind the body background. With it, z-index:-1 paints after body's
   background and before all content, so no page has to touch its own stacking.

   COLOUR. The lines must be LIGHTER than the page, not a darker navy. The first version used
   a dark line (#1b2c4f at .22) and was invisible — not subtle, invisible. It resolved to
   rgb(23,38,75) over a background of rgb(22,36,74): a difference of 1/2/1 per channel. A light
   line at low alpha brightens whatever it is over, which is what makes it hold up regardless of
   what the page background is doing underneath it.

   MOTION. It does not drift on its own; it tilts with the pointer, and the tilt is why it is a
   PERSPECTIVE rather than a translate. Sliding a uniform lattice is close to imperceptible —
   every cell looks like every other cell, so there is no landmark to see move, which is why
   the first attempt read as a still image even though the transform was provably updating.
   Rotating it under perspective changes the SPACING across the screen: lines converge on one
   side and open out on the other, and that is a difference the eye picks up immediately.

   The movement is user-initiated, so WCAG 2.2.2 does not apply and no page needs a Pause
   control it would not otherwise have. Transform is compositor-only; the old homepage version
   animated background-position, repainting a full-viewport grid every frame, which is why it
   had to be disabled on small screens. This one can stay on everywhere.

   `inset:-8%` oversizes the layer so the tilt never pulls its edges into view. */
body{ isolation:isolate; }
body::before{
  content:''; position:fixed; inset:-120px -10%; z-index:-1; pointer-events:none;
  background-image:
    linear-gradient(var(--grid-paper) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-paper) 1px, transparent 1px);
  background-size:64px 64px;
  /* Clear of the masthead, and the clearance is in PIXELS. An earlier version used percentages
     on the reasoning that a fixed layer should be sized to the viewport. That is backwards: the
     masthead (heading, ask bar, stat strip) is ~390px of roughly FIXED height, so a percentage
     clearance lands on it at every window size — 20% of even a 1400px-tall window is 280px, and
     the grid faded in across the search bar. Moving the pointer then shifted lines around the
     header, which reads as an outline appearing on hover. Reported three times; measured against
     the h1 alone (128px) the first time, which is why it looked fixed and was not.

     This is also why the block is inset -120px vertically but -10% horizontally: the vertical
     inset has to be a known number of pixels for the mask offsets below to mean anything, while
     the horizontal oversize only needs to outrun the tilt, which scales with the viewport. */
  /* --grid-clear is MEASURED from the page's own masthead by rot.js and is a document offset,
     so it adapts when a narrow window wraps the heading onto more lines. The +120px converts
     viewport coordinates into this element's, since it starts 120px above the viewport. The
     fallback matches the homepage at a typical desktop width, for the moment before the
     deferred script runs and if it never does. */
  -webkit-mask-image:linear-gradient(transparent 0px,
    transparent calc(120px + var(--grid-clear, 430px)),
    rgba(0,0,0,.5)  calc(300px + var(--grid-clear, 430px)),
    rgba(0,0,0,.7)  calc(480px + var(--grid-clear, 430px)),
    rgba(0,0,0,.7) 100%);
          mask-image:linear-gradient(transparent 0px,
    transparent calc(120px + var(--grid-clear, 430px)),
    rgba(0,0,0,.5)  calc(300px + var(--grid-clear, 430px)),
    rgba(0,0,0,.7)  calc(480px + var(--grid-clear, 430px)),
    rgba(0,0,0,.7) 100%);
  transform:perspective(900px) rotateX(var(--grid-rx, 0deg)) rotateY(var(--grid-ry, 0deg));
  /* Spans longer than the ~150 ms between writes, and LINEAR so consecutive steps join instead of
     each one easing out and stalling. The slowness now lives in the JS easing; this transition is
     only here to hide the sample rate. */
  transition:transform .5s linear;
  will-change:transform;
}
@media (max-width:560px){
  body::before{ background-size:44px 44px; }
}
/* Both mechanisms, which §4d is explicit are not interchangeable. The tilt stops; the paper
   itself stays, because it is texture rather than motion. */
@media (prefers-reduced-motion:reduce){
  body::before{ transition:none; transform:none; }
}
html[data-motion-pref="paused"] body::before{ transition:none; transform:none; }

/* ---------- /rule/ page components ----------
   Lifted out of the rule-page template in v3.7. EIGHT rules, not the twenty that were identical:
   the other twelve used class names (.ey, .cta, .rel, .crumb a) that OTHER pages also use -
   .ey alone appears on 92 non-rule pages. Those pages set their own values for the properties
   they declare, but a global rule also supplies the ones they DON'T, and the mortgage page's
   .ey picked up a margin-bottom it never had. Measured, caught, reverted. Only selectors that
   appear on rule pages and nowhere else are here.

   They are here and the rest of that template is not, for one reason: none of these selectors
   appear anywhere in rot.css or tool.css. A page loads rot.css, then tool.css, then its own
   inline <style>, so an inline rule beats both at equal specificity. Move a rule that the shared
   sheets ALSO define and it silently starts losing to tool.css. That is how the v1.04
   deduplicator broke two panels. `body`, `.wrap`, `h1`, `h2`, `p` and `footer` stay inline on the
   rule pages for exactly that reason - the byte count is not worth the cascade.

   Placed at the end of this file so they still beat rot.css's own rules, and still lose to any
   page's inline <style>, which is the order they had before. */
.ruleline{ font-size:17px; color:var(--text); line-height:1.55; margin:0 0 22px; padding:16px 18px; border-radius:12px; border:1px solid var(--line); border-left:3px solid var(--accent); background:linear-gradient(180deg,var(--panel),var(--ink-2)); }
/* --muted on --panel, not --muted-2: muted-2 on a panel is only 3.96:1 in dark theme, which
   fails AA at this size. --muted is 5.52:1. */
.seq{ display:flex; gap:10px; justify-content:space-between; margin-top:30px; padding-top:18px; border-top:1px solid var(--line); }
.seq a{ font-family:'IBM Plex Mono',monospace; font-size:11.5px; color:var(--muted); text-decoration:none; max-width:46%; }
.seq a:hover{ color:var(--text); }
.seq .lbl{ display:block; color:var(--muted-2); font-size:10px; letter-spacing:.1em; text-transform:uppercase; margin-bottom:3px; }
.fails{ margin:22px 0 0; padding:14px 16px; border-radius:11px; background:var(--panel); border:1px solid var(--line); border-left:3px solid var(--amber); }
.fails h2{ margin:0 0 7px; font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:var(--amber); }
.fails p{ margin:0; }
