/* ═══════════════════════════════════════════════════════════════════════════
   RISKORA MIRROR — the page.

   WHAT THIS REPLACES. mirror.html carried 457 lines of inline <style> written
   when Mirror was a landing page with a 49 rupee paywall underneath it. Both
   of those are gone: the whole report has been free since 2026-08-20, and the
   homepage no longer describes a tradebook reader, it runs one. Mirror is now
   the only page on the site whose entire job is to read the visitor's own
   file, and it should look like what it is.

   THE CATEGORY. Mirror is not a landing page and not a dashboard. It is a
   report: a document a machine produced about a document the reader brought.
   So it is set like one. Rules instead of cards. Columns instead of tiles.
   Mono for every figure, because a machine produced it. One sans. Generous
   measure. Nothing floats, nothing glows, nothing is a capsule.

   WHAT DID NOT CHANGE. The engine. js/mirror/*.js parses, analyses, prices
   and writes the copy, and insights.mts enforces that copy on every build.
   This file styles what those modules emit and nothing else: every class name
   they produce is still here, which is why the selector list below looks
   longer than the page does.

   It loads after css/riskora-shell.css, which owns the header, the wordmark,
   the buttons and the three radii. Mirror does not restate those.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────── 1 · the ground */
:root{
  --bg:var(--rk-bg, #06070A);
  --surface:#0B0D12;
  --border:rgba(255,255,255,.075);
  --border-2:rgba(255,255,255,.14);
  --accent:#D50000;
  --accent-2:#FF6B63;
  --success:#35D9AB;
  --warning:#FF9933;
  --text:#FAFBFC;
  --dim:#A8B1C0;
  --faint:#A2ABB9;

  /* Mirror reads as one column at a report's width. The header frame follows
     it, so the wordmark sits directly above the first word of the page. */
  --m-frame:880px;
}
html.light{
  --bg:#F4F6F9;
  --surface:#FFFFFF;
  --border:rgba(10,14,22,.1);
  --border-2:rgba(10,14,22,.18);
  /* Measured on #F4F6F9: #0B0E14 is 17.4, #424B59 is 8.1, #5A6372 is 6.0.
     The dark-ground accents do not survive the trip: #FF6B63 falls to 2.6
     and #35D9AB to 1.9, so both get their on-paper siblings. */
  --accent-2:#B3001B;
  --success:#0C6B3F;
  --warning:#8A4B0A;
  --text:#0B0E14;
  --dim:#424B59;
  --faint:#5A6372;
}

@font-face{
  font-family:'Ethnocentric Rg'; font-style:normal; font-weight:400;
  font-display:swap;
  src:local('Ethnocentric Rg'), url('/fonts/ethnocentric.woff') format('woff');
}

*{ box-sizing:border-box; margin:0; padding:0; }
html{ overflow-x:hidden; }
body{
  background:var(--bg); color:var(--text);
  font-family:var(--rk-sans,'Inter Tight','Inter',system-ui,sans-serif);
  line-height:1.6; letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;
}
/* The header keeps the site frame; only the page body is this narrow.
   Overriding --rk-frame here moved the wordmark 150px right of where it
   sits on every other page. */
.wrap{ max-width:var(--m-frame); margin:0 auto; padding:0 20px; position:relative; }

/* The ambient layer is gone. The homepage dropped its aurora after measuring
   what a blurred bloom costs, and these three were the same idea: a grain
   texture, a vignette and a pointer-tracked red glow, all painting every
   frame behind a page made of text. The elements stay in the markup so no
   script that touches them can throw. */
.film-grain,.vignette,.bg-glow{ display:none !important; }

a{ color:var(--text); text-decoration:none; }
p a:not([class*="btn"]),li a:not([class*="btn"]){
  text-decoration:underline; text-underline-offset:2px;
  text-decoration-thickness:1px; text-decoration-color:var(--border-2);
}
p a:not([class*="btn"]):hover{ text-decoration-color:currentColor; }

/* ───────────────────────────────────────────── 2 · the first screen */
/*
   WHAT IT WAS. A kicker, a headline, a lede, a green privacy capsule, a
   full-bleed red "Try with sample data" button, a horizontal OR rule, a
   dashed box, and an accordion. Eight blocks before a visitor could act, and
   the one thing they came to do, hand over their own file, was the second
   option, below the sample.

   WHAT IT IS. The file is the subject, so the file target is the first
   object. One sentence above it says what comes back. The sample is still
   there and still one tap, as the quieter of the two doors, because somebody
   who has not found their tradebook yet needs to see the thing before they
   go looking. Nothing is sold above the fold, because the reader is already
   here.
*/
.hero{ padding:clamp(34px,6vh,58px) 0 0; }
.kicker{
  display:flex; align-items:center; gap:11px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10.5px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--faint);
}
.kicker::after{ content:''; flex:1 1 auto; height:1px; background:var(--border-2); }
h1{
  font-size:clamp(2rem,4.6vw,3.1rem); font-weight:600;
  line-height:1.02; letter-spacing:-.042em;
  margin:16px 0 14px; text-wrap:balance;
}
.lede{ color:var(--dim); font-size:clamp(1rem,1.2vw,1.1rem); max-width:40rem; }
/* The privacy promise was a green pill. It is the single most load-bearing
   sentence on the page, so it is a sentence. */
.privacy{
  display:flex; align-items:flex-start; gap:9px;
  margin-top:16px; padding:0; border:0; background:none; border-radius:0;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:12px; line-height:1.6; color:var(--success);
}

.upload-block{ margin:clamp(26px,4vh,40px) 0 0; }
/* Dashed, because this one really is a drop target. It is the only dashed
   outline left on the site. */
.uploader{
  display:block; width:100%; text-align:left;
  border:1px dashed var(--border-2); border-radius:14px;
  background:none; padding:clamp(26px,4vw,40px) clamp(20px,3vw,30px);
  cursor:pointer; transition:border-color .18s ease, background .18s ease;
}
.uploader:hover{ border-color:var(--text); }
.uploader.drag{ border-color:var(--accent-2); background:rgba(255,107,99,.05); }
.uploader:focus-visible{ outline:2px solid var(--text); outline-offset:3px; }
.uploader .icon{ color:var(--faint); line-height:0; margin-bottom:14px; }
.uploader h2,.uploader h3{
  font-size:clamp(1.15rem,2vw,1.4rem); font-weight:600; letter-spacing:-.025em;
  margin:0 0 6px;
}
.uploader p,.up-formats{ color:var(--dim); font-size:13.5px; margin:0; }
.up-hint{
  display:inline-block; margin-top:12px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; letter-spacing:.06em; color:var(--faint);
}

/* THE BUTTONS NEED THEIR OWN SIZE. css/riskora-shell.css owns their shape,
   their colour and their type, but not their padding, because every page it
   serves already had padding of its own. Mirror's came from the inline block
   this file replaced, so without these the primary action rendered as a 20px
   sliver with the label touching all four edges. Caught by looking at the
   rendered page, not by the stylesheet, which was correct in isolation. */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:12px 20px; font-size:14.5px; line-height:1.3; min-height:44px;
  border:0; cursor:pointer;
}
.btn-ghost{ background:none; border:1px solid var(--border-2); color:var(--text); }
.btn-ghost:hover{ border-color:var(--text); }

/* The sample is a second door, not a billboard. */
.or-divider{
  display:flex; align-items:center; gap:14px; margin:20px 0 16px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10.5px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--faint);
}
.or-divider::before,.or-divider::after{ content:''; flex:1; height:1px; background:var(--border); }
.btn-lg{ display:inline-flex; width:auto; padding:12px 20px; font-size:14.5px; }
.sample-note{ color:var(--dim); font-size:13px; margin:10px 0 0; }
.btn-sample{
  background:none; border:1px solid var(--border-2); color:var(--text);
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; padding:10px 16px; border-radius:7px; cursor:pointer;
  margin-top:14px; min-height:40px;
}
.btn-sample:hover{ border-color:var(--text); }

.how-toggle{
  width:100%; margin-top:18px; padding:13px 0; cursor:pointer;
  background:none; border:0; border-top:1px solid var(--border);
  border-bottom:1px solid var(--border); border-radius:0;
  color:var(--text); font-family:inherit; font-weight:500; font-size:14.5px;
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  min-height:48px; text-align:left;
}
.how-toggle:hover{ color:var(--text); }
.how-toggle .chev{ color:var(--faint); transition:transform .2s ease; }
.how-toggle[aria-expanded="true"] .chev{ transform:rotate(180deg); }
.how-panel{
  border:0; border-bottom:1px solid var(--border); border-radius:0;
  padding:16px 0 20px; margin-top:0;
}
.how-tabs{
  display:flex; gap:0; overflow-x:auto; -webkit-overflow-scrolling:touch;
  scrollbar-width:none; border-bottom:1px solid var(--border);
}
.how-tabs::-webkit-scrollbar{ display:none; }
/* A segmented control, not five lozenges: the selected broker is marked by a
   rule under the word, which is how a tab has always worked. */
.how-tab{
  flex:0 0 auto; background:none; border:0; border-radius:0;
  box-shadow:inset 0 -1px 0 transparent;
  color:var(--faint); font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; letter-spacing:.06em; padding:11px 14px; cursor:pointer;
  min-height:44px;
}
.how-tab:hover{ color:var(--text); }
.how-tab.on{ color:var(--text); box-shadow:inset 0 -1px 0 currentColor; }
.how-steps{ margin:14px 0 0; }
.how-steps ol{ margin:0; padding-left:20px; }
.how-steps li{ color:var(--dim); font-size:13.5px; line-height:1.65; margin-bottom:7px; }
.how-steps li strong{ color:var(--text); font-weight:600; }
.how-note{ color:var(--faint); font-size:12.5px; margin-top:12px; }

.err{
  color:var(--accent-2); font-size:13px; margin-top:14px; min-height:1.2em;
  font-family:var(--rk-mono,'JetBrains Mono',monospace); line-height:1.6;
}

/* ──────────────────────────────────────────────────── 3 · the report opens */
.report{ display:none; padding-bottom:40px; }
.report.show{ display:block; }

/* ── THE STAGED OPENING ──────────────────────────────────────────────────
   Measured before this: 89.3 percent of every screen on this page was a
   single colour and seven distinct tones appeared in the whole report.
   The home page, same brand, same reader, measures 46.6 percent and
   fifty. That gap is the difference between a page and a printout, and
   no amount of hairline refinement closes it, because the thing the home
   page has and this did not is a lit ground.

   It had one all along. js/mirror/hold-view.js puts the reader's own
   trades through the same renderer that draws the home page's scenes,
   and it was doing that in a 16:9 box halfway down the report. It opens
   the report now, tall, with the verdict on glass against it. */
/* Surface on the left, verdict over its right. The renderer fits its
   subject to the height of the frame it is given, so a full-bleed band
   leaves the right half empty however tall it is; putting the verdict
   there fills it and makes the two one composition instead of a picture
   with a panel under it. It is the home page's own hero shape, argument
   one side and instrument the other, pointed at the reader's trades. */
.rp-head{ display:grid; }
.rp-head > .hv-host{ grid-area:1/1; margin:0; }
.rp-head > .rp-verdict{
  grid-area:1/1; align-self:end; justify-self:end;
  width:min(470px, 48%); margin:0 0 28px;
}
.rp-head:has(.hv-host:empty) > .rp-verdict{
  grid-area:auto; width:auto; justify-self:stretch; margin:clamp(26px,4vh,38px) 0 0;
}
@media (max-width:980px){
  .rp-head{ display:block; }
  .rp-head > .rp-verdict{ width:auto; margin:clamp(22px,3vh,30px) 0 0; }
}
.report .hv-host{ margin:0; }
.report > .rp-head .hv{ position:relative; margin:clamp(26px,4vh,38px) 0 0; }
/* Full bleed, because the renderer solves its camera from the frame it is
   handed: inside the 880px reading column a 440px box left the surface
   floating in the middle of a large black rectangle, which is more flat
   ground, not less. Across the viewport it fills.

   margin-inline rather than width:100vw, which overflows by the width of
   the scrollbar on every desktop browser that reserves one. */
.report .hv__stage{
  aspect-ratio:auto; height:clamp(340px, 58vh, 560px);
  margin-inline:calc(50% - 50vw); width:auto;
  border-left:0; border-right:0; border-radius:0;
}
/* THE SWITCH MOVES ONTO THE STAGE, ON THE LEFT.
   Caught by elementFromPoint, not by eye: the verdict panel is placed in
   the same grid cell as the whole .hv block, so with the panel 483px tall
   its top edge reached up over the .hv__head row and painted across the
   "By hold time" control. The button was not merely low contrast, it was
   unreachable, and the interaction suite never clicked it so nothing
   failed. It now sits over the stage's top left, where the panel on the
   right cannot reach it, at a z-index above the panel. */
.report .hv__head{
  position:absolute; left:0; top:16px; z-index:3;
  margin:0; justify-content:flex-start; gap:12px 16px;
  /* It must not reach under the panel on the right, which starts at 48
     percent plus the column gutter. The centre of the control stayed
     clickable when it did, which is exactly why the first version of the
     test passed: it only probed the middle. */
  max-width:calc(50% - 28px);
}
.report .hv__switch{ background:rgba(8,9,13,.72); border-color:rgba(255,255,255,.22); }
.report .hv__btn{ color:#A2ABB9; }
.report .hv__btn:hover{ color:#FAFBFC; }
.report .hv__btn + .hv__btn{ border-left-color:rgba(255,255,255,.22); }
.report .hv__btn.is-on{ background:#FAFBFC; color:#06070A; }
.report .hv__k{ color:#A2ABB9; }
@media (max-width:980px){
  .report .hv__head{ position:static; margin:0 0 12px; }
  .report .hv__switch{ background:none; border-color:var(--border-2); }
  .report .hv__btn{ color:var(--faint); }
  .report .hv__btn.is-on{ background:var(--text); color:var(--bg); }
  .report .hv__k{ color:var(--faint); }
}

/* THE STAGE IS ALWAYS DARK, IN BOTH THEMES. The canvas clears to its own
   near-black whatever the page is set to, so anything printed on top of
   it has to take dark-ground ink even when the rest of the page is on
   paper. Without this the legend and the note took the light theme's
   #5A6372 onto rgb(9,10,14) and measured 3.0 to 3.3.

   The key belongs on the picture it describes, not in the gap underneath
   where the verdict now sits. */
html.light .report .hv__legend dt,
html.light .report .hv__note{ color:#A2ABB9; }
html.light .report .hv__legend dd{ color:#FAFBFC; }
.report .hv__legend{
  position:absolute; left:0; bottom:74px; z-index:1;
  margin:0; gap:6px 22px; pointer-events:none;
  max-width:48%;
}
.report .hv__note{
  position:absolute; left:0; right:53%; bottom:22px; z-index:1;
  margin:0; font-size:12px;
}
@media (max-width:860px){
  .report > .hv-host .hv__legend,
  .report .hv__note{ position:static; right:auto; margin-top:10px; }
}
/* The verdict is an instrument, so it gets the one treatment instruments
   get. Sentences on this page still get none. It is pulled up into the
   foot of the stage so the two read as one composition rather than two
   blocks that happen to be adjacent. */
.rp-verdict{
  position:relative; z-index:2;
  margin:clamp(26px,4vh,40px) 0 0; padding:clamp(18px,2.4vw,26px) clamp(18px,2.6vw,28px) 0;
  border:1px solid var(--g-edge, rgba(255,255,255,.085));
  border-radius:var(--rk-r-box,14px);
  /* A SOLID BASE UNDER THE GLASS. Measured: with only the translucent
     fill, the panel took its colour from whatever part of the lit
     surface was behind it, and where the surface is bright the ground
     under the summary line went to rgb(134). The amber SAMPLE DATA tag
     measured 1.69 there and the summary line 1.80. The glass gradient
     stays, on top of a ground the surface cannot move. */
  background:
    linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.018)),
    rgba(9,11,16,.93);
  box-shadow:
    var(--g-top, inset 0 1px 0 rgba(255,255,255,.09)),
    0 28px 70px -28px rgba(0,0,0,.92), 0 2px 8px -4px rgba(0,0,0,.6);
  backdrop-filter:blur(18px) saturate(1.3);
  -webkit-backdrop-filter:blur(18px) saturate(1.3);
}
/* MEASURED. At .92/.72 over the always-dark stage this panel blended to
   rgb(210) and rgb(192), not to paper, and the light theme's labels and
   body copy fell to 3.97 and 4.30 on it. The panel is the reader's
   verdict and has to read as a printed card in this theme, so it is
   nearly opaque and the ground under its text is paper again. */
html.light .rp-verdict{
  border-color:rgba(10,14,22,.12);
  background:linear-gradient(180deg, rgba(255,255,255,.985), rgba(255,255,255,.965));
  box-shadow:inset 0 1px 0 #fff, 0 18px 44px -22px rgba(10,14,22,.34);
}
/* No stage means no overlap to make: an export without timestamps, or one
   with too few round trips, gets a verdict that simply starts the page. */
.rp-head:has(.hv-host:empty) .rp-verdict{
  margin-top:clamp(26px,4vh,38px); backdrop-filter:none; -webkit-backdrop-filter:none;
}
/* Inside the overlay the three figures stack. Three columns in a 470px
   panel wrapped "Revenge trades" onto two lines and squeezed the score
   scale to 80px, which is the one element on the page that has to be
   read as a proportion. As rows they each get the full width. */
.rp-head .rp-verdict .cards{
  grid-template-columns:1fr; border-bottom:0;
}
.rp-head .rp-verdict .card{ padding:14px 0; }
.rp-head .rp-verdict .card + .card{
  border-left:0; border-top:1px solid var(--border); padding-left:0;
}
.rp-head .rp-verdict .card .big{ font-size:1.9rem; margin:4px 0 2px; }
.rp-head .rp-verdict .score__n b{ font-size:1.9rem; }
@media (max-width:980px){
  .rp-head .rp-verdict .cards{ grid-template-columns:1fr 1fr 1.25fr; }
  .rp-head .rp-verdict .card + .card{
    border-top:0; border-left:1px solid var(--border); padding-left:clamp(16px,2.4vw,26px);
  }
}
@media (max-width:760px){
  .rp-head .rp-verdict .cards{ grid-template-columns:1fr; }
  .rp-head .rp-verdict .card + .card{ border-left:0; border-top:1px solid var(--border); padding-left:0; }
}
.rp-verdict .summary-line{ padding-top:0; }
.rp-verdict details.how{ border-bottom:0; }
@media (max-width:620px){
  .rp-verdict{ margin-top:-30px; }
  .report .hv__stage{ height:clamp(240px, 38vh, 320px); }
}

/* The file's own line, set like a filename and a count, because that is what
   it is. It is the first thing a reader checks: did it read my file. */
.summary-line{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:12px; line-height:1.75; color:var(--dim);
  padding:clamp(28px,4vh,40px) 0 14px; border-bottom:1px solid var(--border);
}
.summary-line .pos{ color:var(--success); }
.summary-line .neg{ color:var(--accent-2); }
/* The qualification on the P&L figure. "net" alone reads as after costs,
   and this figure is realised P&L before them, so the qualification has to
   travel with the number rather than live in a footnote. Set back so it
   reads as a condition on the figure, not as another figure. */
.summary-line .summary-sub{ color:var(--faint); }

/* ── the date question ──────────────────────────────────────────────────
   Shown in place of the report when a file's dates could be read two
   ways. Deliberately NOT styled as an error: nothing has gone wrong and
   the reader has not made a mistake. It is a question, so it reads like
   the report it is standing in for, at 14px radius because the reader
   acts inside it. */
.date-confirm{
  margin:clamp(20px,3vh,32px) 0 0;
  padding:clamp(20px,3vw,28px);
  border:1px solid var(--border);
  border-left:2px solid var(--warning);
  border-radius:14px;
  background:var(--surface, transparent);
  max-width:var(--rk-frame,1180px);
}
.date-confirm h2{
  font-size:clamp(1.05rem,2.4vw,1.3rem); line-height:1.25;
  letter-spacing:-.02em; margin:0 0 10px;
}
.date-confirm p{ color:var(--dim); font-size:14px; line-height:1.7; max-width:62ch; margin:0 0 16px; }
.date-confirm__choices{ display:flex; flex-wrap:wrap; gap:10px; margin-bottom:14px; }
.date-confirm__choices .btn{ font-size:12px; }
.date-confirm__why{
  color:var(--faint); font-size:12.5px; line-height:1.65; margin:0;
  padding-top:12px; border-top:1px solid var(--border);
}
@media (max-width:620px){
  .date-confirm__choices{ flex-direction:column; align-items:stretch; }
  .date-confirm__choices .btn{ width:100%; }
}
.sample-tag{
  display:inline-block; margin-left:8px; padding:0; border:0; border-radius:0;
  background:none; color:var(--warning);
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10.5px; letter-spacing:.14em;
}
.summary-warn{ display:inline-block; margin-top:4px; color:var(--warning); font-size:12px; }

/* ── the three headline figures ──────────────────────────────────────────
   They were three cards in a row, each with a border, a fill and a radius,
   and the third held a donut gauge. Three columns divided by a rule now, so
   they read as one row of a report rather than three objects that happen to
   be adjacent. */
.cards{
  display:grid; grid-template-columns:1fr 1fr 1.25fr;
  gap:0; margin:0; border-bottom:1px solid var(--border);
}
.card{
  background:none; border:0; border-radius:0; text-align:left;
  padding:22px clamp(16px,2.4vw,26px) 24px 0;
}
.card + .card{ border-left:1px solid var(--border); padding-left:clamp(16px,2.4vw,26px); }
.card .label{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint);
}
.card .big{
  font-size:clamp(1.9rem,3.4vw,2.5rem); font-weight:600;
  letter-spacing:-.04em; line-height:1.05; margin:8px 0 3px;
  font-variant-numeric:tabular-nums;
}
.card .sub{ font-size:12.5px; line-height:1.55; color:var(--dim); }

/* ── the Discipline Score, as a measure ──────────────────────────────────
   It was a donut gauge. A donut cannot show the one thing that matters about
   this number, which is where it sits relative to the threshold ORA-1 locks
   at: the reader has to be told that in words underneath. A scale shows both
   at once, and it is the shape the score actually is, nought to a hundred.
   The threshold is drawn on it. */
.score__n{ display:flex; align-items:baseline; gap:6px; margin:8px 0 10px; }
.score__n b{
  font-size:clamp(1.9rem,3.4vw,2.5rem); font-weight:600;
  letter-spacing:-.04em; line-height:1; font-variant-numeric:tabular-nums;
}
.score__n i{
  font-style:normal; font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11px; letter-spacing:.1em; color:var(--faint);
}
.score__scale{
  position:relative; height:8px; width:100%;
  background:rgba(255,255,255,.08); border-radius:1px; overflow:visible;
}
html.light .score__scale{ background:rgba(10,14,22,.09); }
.score__fill{
  position:absolute; inset:0 auto 0 0; width:0; border-radius:1px;
  background:var(--accent-2); transition:width .5s cubic-bezier(.22,1,.36,1);
}
.score__fill[data-band="ok"]{ background:var(--success); }
.score__fill[data-band="warn"]{ background:var(--warning); }
.score__mark{ position:absolute; top:-5px; bottom:-5px; width:1px; background:var(--text); }
/* The threshold's own number, under the tick that marks it. The scale ran
   0 and 100 under its ends as well, and at 1280 the 70 sat on top of the
   100; they also said nothing the "/ 100" beside the score had not already
   said. */
.score__mark span{
  position:absolute; top:calc(100% + 7px); left:0; white-space:nowrap;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10px; letter-spacing:.08em; color:var(--faint);
  transform:translateX(-50%);
}
.card .score__sub{ margin-top:26px; }
@media (prefers-reduced-motion:reduce){ .score__fill{ transition:none; } }

/* The calculation disclosure. One line, a rule, no icon font tricks. */
details.how{ margin:0; border-bottom:1px solid var(--border); }
details.how > summary{
  cursor:pointer; list-style:none; display:flex; align-items:center;
  min-height:44px; padding:0;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; letter-spacing:.06em; color:var(--faint);
}
details.how > summary::-webkit-details-marker{ display:none; }
details.how > summary::before{ content:'How is this calculated?'; }
details.how[open] > summary::before{ content:'Close'; }
details.how > summary:hover{ color:var(--text); }
details.how p{
  font-size:13.5px; line-height:1.7; color:var(--dim);
  margin:0; padding:0 0 16px;
}

/* ───────────────────────────────────────────────── 4 · previous runs */
.runs{
  background:none; border:0; border-bottom:1px solid var(--border);
  border-radius:0; padding:26px 0; margin:0;
}
.runs-h{ font-size:1.05rem; font-weight:600; letter-spacing:-.025em; margin-bottom:5px; }
.runs-sub{ font-size:13px; color:var(--dim); margin-bottom:14px; line-height:1.65; max-width:60ch; }
.runs-row{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  padding:10px 0; border-top:1px solid var(--border); font-size:13.5px;
}
.runs-row .d{ font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px; color:var(--faint); }
.runs-row .s{ font-weight:600; font-variant-numeric:tabular-nums; }
.runs-delta{ font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px; }
.runs-forget{
  background:none; border:1px solid var(--border-2); color:var(--dim);
  border-radius:7px; padding:9px 14px; min-height:40px; cursor:pointer;
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11px;
  margin-top:14px;
}
.runs-forget:hover{ color:var(--text); border-color:var(--text); }

/* ────────────────────────────────────── 5 · the pilot consent card */
/* A privacy decision, so it reads like one: no promotion treatment, and the
   only colour is on the two lists that say what does and does not leave. */
.pilot-card{
  background:none; border:0; border-left:2px solid var(--accent-2);
  border-radius:0; padding:4px 0 4px 18px; margin:26px 0;
}
.pilot-eyebrow{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10.5px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--faint); margin-bottom:8px;
}
.pilot-card h3{ font-size:1.08rem; font-weight:600; letter-spacing:-.025em; margin:0 0 10px; }
.pilot-card p{ font-size:13.5px; line-height:1.7; color:var(--dim); margin:0 0 10px; max-width:64ch; }
.pilot-card p b{ color:var(--text); font-weight:600; }
.pilot-what{ list-style:none; padding:0; margin:12px 0; }
.pilot-what li{ font-size:13px; line-height:1.65; color:var(--dim); padding-left:22px; position:relative; margin-bottom:5px; }
.pilot-what li::before{ position:absolute; left:0; font-family:var(--rk-mono,'JetBrains Mono',monospace); }
.pilot-what li.yes::before{ content:'\2192'; color:var(--accent-2); }
.pilot-what li.no::before{ content:'\2715'; color:var(--success); }
.pilot-actions{ display:flex; gap:10px; flex-wrap:wrap; margin-top:16px; }
.pilot-btn{
  font-family:inherit; font-weight:600; font-size:14px;
  padding:11px 18px; min-height:48px; border-radius:7px; cursor:pointer;
  border:1px solid var(--border-2); background:none; color:var(--text);
}
.pilot-btn:hover{ border-color:var(--text); }
.pilot-btn.join{
  border-color:transparent; color:#fff;
  background:linear-gradient(180deg,#E02B26 0%,#D01A17 52%,#BE1310 100%);
}
.pilot-btn:disabled{ opacity:.55; cursor:default; }
.pilot-msg{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:12px; margin-top:10px; min-height:1.1em; color:var(--success);
}

/* ─────────────────────────────────────────── 6 · the behavioural findings */
/*
   PATTERN, then EVIDENCE, then what it describes. The four parts stay
   visually distinct so a reader can see where measurement stops and where
   reading-into-it begins, which was right and is kept. What goes is the
   card: eight filled, bordered, rounded boxes stacked down a page is a feed,
   and this is a list of findings in a report.
*/
.ins-note{ font-size:13px; color:var(--dim); margin:18px 0 6px; line-height:1.7; max-width:66ch; }
.ins-list{ margin:0; }
.ins{
  background:none; border:0; border-radius:0;
  border-top:1px solid var(--border);
  border-left:2px solid var(--faint);
  padding:20px 0 20px 18px; margin:0;
}
.ins.observed{ border-left-color:var(--accent-2); }
.ins.clean{ border-left-color:var(--success); }
.ins.unavailable{ border-left-color:var(--border-2); }
.ins-top{ display:flex; align-items:baseline; justify-content:space-between; gap:14px; flex-wrap:wrap; }
.ins-title{ font-size:1.06rem; font-weight:600; letter-spacing:-.025em; line-height:1.3; }
/* The status was a bordered lozenge. It is the word, in the finding's own
   colour, which is the only thing the lozenge was carrying. */
.ins-tag{
  padding:0; border:0; border-radius:0; background:none;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--faint); white-space:nowrap; flex-shrink:0;
}
.ins.observed .ins-tag{ color:var(--accent-2); }
.ins.clean .ins-tag{ color:var(--success); }
.ins-part{ margin-top:12px; }
.ins-k{
  display:block; margin-bottom:3px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint);
}
.ins-part p{ font-size:14px; line-height:1.7; margin:0; max-width:66ch; }
.ins-evidence p{ color:var(--text); }
.ins-interpretation p{ color:var(--dim); }
.ins-reflection{ margin-top:14px; }
.ins-reflection p{ color:var(--dim); font-style:italic; }
/* ── The ledger: every matched leg, and the rows it came from. P4-1 ──
   Behind a closed expander, because most readers will never open it and
   the ones who do are deciding whether to believe the rest of the page.
   The table scrolls inside its own container so the page body never
   scrolls sideways on a phone. */

/* mirror.html loads tokens, mirror, mirror-v4 and shell, NOT riskora-ds,
   so .rk-sr-only is not available here and the table caption would have
   rendered visibly without this. */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

.ledger{ margin-top:14px; }
.ledger > summary{
  cursor:pointer; list-style:none; min-height:36px; display:flex; align-items:center;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; letter-spacing:.06em; color:var(--faint);
}
.ledger > summary::-webkit-details-marker{ display:none; }
.ledger > summary::after{ content:'+'; margin-left:auto; font-size:14px; }
.ledger[open] > summary::after{ content:'\2212'; }
.ledger > summary:hover{ color:var(--text); }
.ledger__body{ margin-top:10px; }
.ledger__note{
  color:var(--faint); font-size:12px; line-height:1.6; margin:0 0 10px; max-width:66ch;
}
/* The only element on the page allowed to scroll sideways, and it does
   so inside itself. */
.ledger__scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch;
  /* contain, so reaching the end does not start scrolling the page,
     matching what the homepage tradebook does. */
  overscroll-behavior-x:contain; }
/* It is focusable so a keyboard reader can scroll it, so the focus has
   to be visible on a dark panel rather than left to a faint default. */
.ledger__scroll:focus-visible{ outline:2px solid var(--accent-2,#FF6B63); outline-offset:2px; }
.ledger__table{
  width:100%; border-collapse:collapse;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; font-variant-numeric:tabular-nums; white-space:nowrap;
}
.ledger__table th{
  text-align:left; font-weight:400; color:var(--faint);
  font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  padding:6px 12px 6px 0; border-bottom:1px solid var(--line,rgba(255,255,255,.1));
}
.ledger__table td{
  padding:6px 12px 6px 0; color:var(--dim);
  border-bottom:1px solid var(--line,rgba(255,255,255,.05));
}
.ledger__win{ color:var(--success); }
.ledger__loss{ color:var(--accent-2); }
/* An unmeasured cell is quiet, never styled as a result. */
.ledger__unknown{ color:var(--faint); font-style:italic; }
/* Two legs that share one entry are one decision, and the row says so
   without a badge that would need explaining in the header. */
.ledger__split td:first-child{ box-shadow:inset 2px 0 0 var(--faint); padding-left:6px; }
.ledger__open{ margin:0; padding-left:18px; color:var(--dim); font-size:13px; line-height:1.8; }

/* Where to check a finding in the reader's own file. P1-4.
   The numbers are monospaced because they are looked up one at a time
   against a spreadsheet, and the qualifier below them is quiet because
   it explains the numbering rather than making a claim. */
.ins-trace p{ color:var(--dim); font-size:13.5px; }
.ins-trace__at{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:13px; color:var(--text);
}
.ins-trace__note{
  display:block; margin-top:4px;
  font-size:12px; line-height:1.6; color:var(--faint);
}
.ins-reason p{ color:var(--dim); font-size:13.5px; }
.ins-explain p{ color:var(--dim); font-size:13.5px; }
.ins-how{ margin-top:10px; }
.ins-how summary{
  cursor:pointer; list-style:none; min-height:30px; display:flex; align-items:center;
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px; color:var(--faint);
}
.ins-how summary::-webkit-details-marker{ display:none; }
.ins-how summary::before{ content:'How is this measured?'; }
.ins-how[open] summary::before{ content:'Close'; }
.ins-how p{ font-size:13px; color:var(--dim); line-height:1.7; margin:6px 0 0; }

.ins-read{ margin-top:14px; border-top:1px solid var(--border); }
.ins-read > summary{
  list-style:none; cursor:pointer; display:flex; align-items:center;
  justify-content:space-between; gap:12px; min-height:44px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; letter-spacing:.06em; color:var(--faint);
}
.ins-read > summary::-webkit-details-marker{ display:none; }
.ins-read > summary::after{ content:'+'; font-size:.95rem; flex:none; }
.ins-read[open] > summary::after{ content:'\2212'; }
.ins-read > summary:hover{ color:var(--text); }
/* An author `display` on a details child overrides the UA rule that hides
   closed content, and something on this page was doing exactly that. */
.ins-read:not([open]) .ins-read__body{ display:none; }
.ins-read__body{ padding-bottom:12px; }

.ins-share{ margin-top:14px; }
.ins-share-btn{
  background:none; border:1px solid var(--border-2); color:var(--dim);
  border-radius:7px; padding:10px 15px; min-height:44px; cursor:pointer;
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11px;
}
.ins-share-btn:hover{ color:var(--text); border-color:var(--text); }
.ins-more{ border-top:1px solid var(--border); }
.ins-more > summary{
  cursor:pointer; list-style:none; min-height:48px;
  display:flex; align-items:center; justify-content:center;
  border:0; border-radius:0; padding:14px 0; text-align:center;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; letter-spacing:.06em; color:var(--faint);
}
.ins-more > summary::-webkit-details-marker{ display:none; }
.ins-more > summary:hover{ color:var(--text); }
.ins-more[open] > summary{ margin-bottom:0; }

/* ───────────────────────────────── 7 · the reader's own book, rendered */
.hv-host:empty{ display:none; }
.hv{ margin:28px 0 4px; }
.hv__head{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:12px; margin-bottom:12px;
}
.hv__k{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--faint); margin:0;
}
.hv__switch{ display:flex; gap:0; border:1px solid var(--border-2); border-radius:7px; overflow:hidden; }
.hv__btn{
  appearance:none; background:none; border:0; cursor:pointer;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11px; letter-spacing:.06em; color:var(--faint);
  padding:9px 14px; min-height:40px; transition:background .18s ease, color .18s ease;
}
.hv__btn + .hv__btn{ border-left:1px solid var(--border-2); }
.hv__btn:hover{ color:var(--text); }
/* A filled ground, not a colour change alone: colour by itself is not a
   state anyone who does not see that hue can read. */
.hv__btn.is-on{ background:var(--text); color:var(--bg); }
.hv__btn:focus-visible{ outline:2px solid var(--text); outline-offset:-2px; }
.hv__stage{
  position:relative; aspect-ratio:16/9; width:100%;
  border:1px solid var(--border); border-radius:14px; overflow:hidden;
  background:#08090D;
}
.hv__canvas{ position:absolute; inset:0; width:100%; height:100%; display:block; }
.hv__legend{ display:flex; flex-wrap:wrap; gap:8px 26px; margin:12px 0 0; }
.hv__legend div{ display:flex; align-items:baseline; gap:7px; }
.hv__legend dt{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint);
}
.hv__legend dd{ margin:0; font-size:13px; color:var(--text); }
.hv__note{ margin:10px 0 0; font-size:13px; line-height:1.7; color:var(--dim); max-width:66ch; }

/* ───────────────────────────────────────────── 8 · what the patterns cost */
/* One rupee total on this page, from cost.js, auditable to the trade. It is
   the figure, a rule under it and the rows that make it up. Nothing is in a
   box, because a number in a box reads as a claim and this one is a sum the
   reader can check. */
.cost-block{ margin:32px 0 4px; }
.cost-head{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin-bottom:12px;
}
.cost-title{ font-size:1.2rem; font-weight:600; letter-spacing:-.03em; }
.cost-scope{ font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px; color:var(--faint); }
.cost-hero{
  background:none; border:0; border-top:1px solid var(--border-2);
  border-radius:0; padding:18px 0 20px;
}
.cost-hero .amount{
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-weight:600;
  font-size:clamp(1.9rem,6vw,2.6rem); line-height:1.1; letter-spacing:-.02em;
  color:var(--accent-2); font-variant-numeric:tabular-nums;
}
.cost-hero .amount.zero{ color:var(--success); }
/* The suppressed state is a sentence explaining why there is no figure, so
   it is set as one. In the mono hero size it was a 17px monospace paragraph
   wrapping across the full width, which read as the headline it is standing
   in for rather than as the note it is. */
.cost-hero .amount.held{
  color:var(--dim); font-family:inherit; font-weight:400;
  font-size:14.5px; line-height:1.7; letter-spacing:-.005em; max-width:62ch;
}
.cost-hero .under{ font-size:13.5px; color:var(--dim); margin-top:7px; max-width:60ch; }
.cost-hero .under b{ color:var(--text); font-family:var(--rk-mono,'JetBrains Mono',monospace); font-weight:600; }

.cost-rows{ margin-top:4px; }
.cost-row{ border-bottom:1px solid var(--border); }
.cost-row > summary{
  cursor:pointer; list-style:none; display:flex; align-items:baseline;
  justify-content:space-between; gap:14px; padding:14px 0; min-height:48px;
}
.cost-row > summary::-webkit-details-marker{ display:none; }
.cost-row > summary:hover .cost-what{ color:var(--text); }
.cost-row[open] > summary .chev-c{ transform:rotate(180deg); }
.chev-c{ font-size:.7rem; color:var(--faint); transition:transform .2s ease; display:inline-block; margin-left:6px; }
.cost-what{ font-size:14px; flex:1; min-width:0; color:var(--dim); transition:color .2s ease; }
.cost-what small{ display:block; color:var(--faint); font-size:12.5px; margin-top:2px; }
.cost-val{
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-weight:600;
  font-size:13.5px; text-align:right; white-space:nowrap; font-variant-numeric:tabular-nums;
}
.cost-val .n{ color:var(--text); }
.cost-val .muted{ color:var(--faint); font-weight:400; font-size:12.5px; }
.cost-val .ok{ color:var(--success); font-weight:400; font-size:12.5px; }
.cost-body{ padding:2px 0 18px; }
.cost-body p{ font-size:13.5px; line-height:1.7; color:var(--dim); margin-bottom:10px; max-width:66ch; }
.cost-na{ color:var(--dim); font-size:13.5px; padding:2px 0 16px; }
.cost-stats{ display:flex; flex-wrap:wrap; gap:10px 28px; margin-bottom:14px; }
.cost-stat{ font-size:12.5px; color:var(--faint); }
.cost-stat b{
  display:block; font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:15px; color:var(--text); font-weight:600; font-variant-numeric:tabular-nums;
}
/* max-width and min-width:0 both matter. The table inside carries
   min-width:420px so its columns stay legible, and without these the
   scroll box simply grew to fit it: measured at 320 the document went
   117px wide of the viewport instead of the table scrolling inside its
   own container. */
.cost-audit{
  overflow-x:auto; -webkit-overflow-scrolling:touch;
  max-width:100%; min-width:0;
  border:1px solid var(--border); border-radius:10px;
}
.cost-body,.cost-row,.cost-rows,.cost-block{ min-width:0; }
.cost-audit table{
  border-collapse:collapse; width:100%; min-width:420px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:12px; font-variant-numeric:tabular-nums;
}
.cost-audit th,.cost-audit td{ text-align:left; padding:9px 12px; border-bottom:1px solid var(--border); white-space:nowrap; }
.cost-audit tr:last-child td{ border-bottom:none; }
.cost-audit th{ font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint); font-weight:600; }
.cost-audit td{ color:var(--dim); }
.cost-audit td.sym{ color:var(--text); }
.cost-audit td.r{ text-align:right; }
.cost-audit td.l{ color:var(--accent-2); }
.cost-audit td.w{ color:var(--success); }
.cost-more{ font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px; color:var(--faint); padding:9px 12px; }
.cost-nwin{
  display:inline-flex; align-items:center; gap:7px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px; color:var(--faint);
}
.cost-nwin select{
  background:var(--bg); color:var(--text); border:1px solid var(--border-2);
  border-radius:7px; padding:6px 8px; font-family:inherit; font-size:12.5px; min-height:44px;
}
.cost-note{
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:11.5px; color:var(--faint); line-height:1.75; margin-top:14px; max-width:70ch;
}

/* ───────────────────────────────────────────────── 9 · the rest of it */
.full{ display:none; }
.full.show{ display:block; }
.section-h{
  display:flex; align-items:center; gap:11px;
  font-size:1.2rem; font-weight:600; letter-spacing:-.03em;
  margin:36px 0 10px; padding-bottom:10px; border-bottom:1px solid var(--border-2);
}
.section-h::before{ content:''; width:22px; height:1px; background:currentColor; opacity:.5; flex:none; }
.row{
  display:flex; justify-content:space-between; align-items:baseline; gap:14px;
  padding:13px 0; border-bottom:1px solid var(--border);
}
.row .k{ color:var(--dim); font-size:13.5px; }
.row .v{
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-weight:600;
  text-align:right; font-variant-numeric:tabular-nums;
}
/* A row whose value could not be measured. The row keeps its place, so the
   reader can see the finding was looked for, but the value is set back in
   running type rather than dressed as a figure: a monospace 600 "not
   measurable" sitting in the numbers column reads like a result. `.muted`
   existed only under .cost-val, so this class was inert here. */
.row .v .muted{
  font-family:var(--rk-sans,'Inter Tight',system-ui,sans-serif);
  color:var(--faint); font-weight:400; font-size:12.5px;
}
.neg{ color:var(--accent-2); }
.pos{ color:var(--success); }
.rec{
  background:none; border:0; border-left:2px solid var(--accent-2); border-radius:0;
  padding:4px 0 4px 16px; margin-bottom:14px; font-size:14px; line-height:1.7; max-width:66ch;
}
.hours{ display:grid; grid-template-columns:repeat(7,1fr); gap:6px; margin-top:8px; }
.hours .h{ text-align:center; font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:10px; color:var(--faint); }
.hours .bar{ height:46px; display:flex; align-items:flex-end; justify-content:center; border-bottom:1px solid var(--border); }
.hours .bar span{ width:64%; border-radius:1px 1px 0 0; min-height:2px; }

.btn-share-card{
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px;
  background:none; border:1px solid var(--border-2); color:var(--text);
  padding:11px 20px; border-radius:7px; cursor:pointer; margin:20px 0 4px;
  min-height:44px;
}
.btn-share-card:hover{ border-color:var(--text); }

.warn-banner{
  background:none; border:0; border-left:2px solid var(--warning); border-radius:0;
  padding:4px 0 4px 16px; font-size:14px; color:var(--text); margin-bottom:20px;
  line-height:1.7; max-width:66ch;
}
.warn-banner strong{ color:var(--warning); font-weight:600; }
#limitedReport .cards{ margin-bottom:6px; }

/* ── the 49 rupee teaser, dormant ─────────────────────────────────────────
   UI_CONFIG.PAYWALL_ENABLED is false and this never renders. It is styled
   anyway, and the markup is still in the page, because api/mirror.ts was
   deliberately left live: flipping one boolean has to restore the paid flow
   with no server work, and that promise is only true if the markup and the
   styles are both still here. */
.teaser{
  margin:28px 0; background:none; border:0; border-top:1px solid var(--border-2);
  border-radius:0; padding:24px 0; text-align:left;
}
.teaser .ctx{ font-size:1rem; line-height:1.7; max-width:56ch; margin:0 0 14px; color:var(--dim); }
.teaser .ctx b{ color:var(--text); font-weight:600; }
.locked-num{
  font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:2.2rem;
  font-weight:600; letter-spacing:.14em; color:var(--accent-2); user-select:none;
}
.teaser .unlock-row{ margin-top:18px; }
.teaser .price-note{ font-family:var(--rk-mono,'JetBrains Mono',monospace); font-size:11.5px; color:var(--faint); margin-top:10px; }
.sticky-cta{
  position:fixed; left:0; right:0; bottom:0; z-index:60; display:none;
  padding:12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background:color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter:blur(14px); border-top:1px solid var(--border-2);
}
.sticky-cta .btn{ width:100%; }

/* ── the monthly re-check opt-in ─────────────────────────────────────────
   The only thing on this page that asks for something. It stays quiet: a
   rule, the ask, the field. The sentence about what is and is not sent is
   the point of the block, so it is not small print. */
.optin{
  margin:30px 0 4px; padding:24px 0 0;
  border-top:1px solid var(--border-2); text-align:left;
}
.optin h3{ font-size:1.08rem; font-weight:600; letter-spacing:-.025em; margin:0 0 8px; }
.optin p{ font-size:13.5px; line-height:1.7; color:var(--dim); margin:0 0 14px; max-width:62ch; }
.optin p b{ color:var(--text); font-weight:600; }
.optin form{ display:flex; gap:8px; flex-wrap:wrap; max-width:440px; }
.optin input[type="email"]{
  flex:1; min-width:190px; background:none; color:var(--text);
  border:1px solid var(--border-2); border-radius:7px; padding:11px 12px;
  font-family:inherit; font-size:14.5px; min-height:44px;
}
.optin input[type="email"]:focus{ outline:2px solid var(--text); outline-offset:1px; border-color:transparent; }
.optin-msg{
  min-height:1.1em; margin-top:10px; font-size:12px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace); color:var(--success);
}
#shareCardWrap{ text-align:left !important; }

/* ─────────────────────────────────────────────────── 10 · the close */
.cta-final{
  margin:44px 0 10px; background:none; border:0;
  border-top:1px solid var(--border-2); border-radius:0;
  padding:30px 0 0; text-align:left;
}
.cta-final h2{ font-size:1.5rem; font-weight:600; letter-spacing:-.03em; margin-bottom:10px; }
.cta-final p{ color:var(--dim); font-size:14.5px; line-height:1.7; max-width:58ch; margin:0 0 18px; }
.disclaimer{
  color:var(--faint); font-size:11.5px; line-height:1.75; text-align:left;
  max-width:70ch; margin:44px 0 50px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  border-top:1px solid var(--border); padding-top:20px;
}
.legal-link-btn{ color:var(--dim); }

/* ─────────────────────────────── 11 · the reading matter underneath */
/* Quieter than the report above it, and narrower: this is prose, and prose
   reads at about 68 characters however wide the page is. */
.seo-block{ margin:54px 0 0; padding-top:34px; border-top:1px solid var(--border); }
.seo-block h2{ font-size:1.5rem; font-weight:600; letter-spacing:-.032em; line-height:1.2; margin:0 0 12px; }
.seo-block h3{ font-size:1.06rem; font-weight:600; letter-spacing:-.025em; margin:30px 0 8px; }
.seo-block p{ font-size:15px; line-height:1.75; color:var(--dim); max-width:68ch; margin:0 0 12px; }
.seo-block p strong,.seo-block li strong{ color:var(--text); font-weight:600; }
.seo-block .lede-2{ font-size:16px; color:var(--text); }
.seo-block ul,.seo-block ol{ max-width:68ch; padding-left:20px; margin:0 0 14px; }
.seo-block li{ font-size:15px; line-height:1.75; color:var(--dim); margin-bottom:9px; }
.seo-block ol.pipe li{ margin-bottom:11px; }

/* The worked example echoes a real finding so it reads as a genuine preview,
   with a tag that never lets it pass for the reader's own data. */
.ex-card{
  background:none; border:0; border-top:1px solid var(--border);
  border-left:2px solid var(--accent-2); border-radius:0;
  padding:16px 0 16px 18px; margin:0;
}
.ex-head{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:10px; }
.ex-title{ font-size:1.02rem; font-weight:600; letter-spacing:-.025em; }
.ex-tag{
  padding:0; border:0; border-radius:0; background:none; white-space:nowrap;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--warning);
}
.ex-card p{ margin:0 0 9px; font-size:14px; }
.ex-card p:last-child{ margin-bottom:0; }
.ex-k{
  display:block; margin-bottom:2px;
  font-family:var(--rk-mono,'JetBrains Mono',monospace);
  font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint);
}
.ex-note{ font-size:13.5px !important; font-style:italic; margin-top:14px !important; }

.seo-cta{ text-align:left; }
.seo-cta p{ margin-left:0; margin-right:0; }
.seo-cta-btn{
  display:inline-block; color:#fff !important; text-decoration:none !important;
  background:linear-gradient(180deg,#E02B26 0%,#D01A17 52%,#BE1310 100%);
  font-family:inherit; font-weight:600; font-size:14.5px; letter-spacing:-.008em;
  padding:12px 22px; border-radius:7px; min-height:48px; line-height:1.6;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26), inset 0 -1px 0 rgba(0,0,0,.24), 0 1px 2px rgba(0,0,0,.4);
}
.seo-cta-links{ margin:18px 0 12px !important; }
.seo-cta-sub{ font-size:13.5px !important; }

/* ───────────────────────────────────────────────────────── 12 · narrow */
@media (max-width:760px){
  .cards{ grid-template-columns:1fr; }
  .card{ padding:20px 0; }
  .card + .card{ border-left:0; border-top:1px solid var(--border); padding-left:0; }
  .score__ends{ margin-top:24px; }
}
@media (max-width:640px){
  .hv__stage{ aspect-ratio:4/3; }
  .hv__switch{ width:100%; }
  .hv__btn{ flex:1; }
}
@media (max-width:620px){
  .wrap{ padding:0 16px; }
  .hero{ padding-top:28px; }
  .btn-lg{ display:block; width:100%; }
  .btn,.btn-share-card,.how-tab,.how-toggle,.unlock-row .btn{ min-height:48px; }
  details.how > summary,.ins-how > summary,.ins-more > summary{ min-height:44px; }
  input,select,textarea{ font-size:16px; }   /* iOS will not zoom at 16 */
  body.has-sticky main{ padding-bottom:88px; }
  .sticky-cta.show{ display:block; }
}
@media (prefers-reduced-motion:reduce){
  .hv__btn,.cost-what,.chev-c,.how-toggle .chev{ transition:none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   13 · RHYTHM, BECAUSE ONE LIT BAND DID NOT DO IT

   Measured after the staged opening went in: 88.2 percent of a screen is
   still one colour, against 89.3 before and 46.6 on the home page. The
   stage fixed one screen of thirteen. The home page's ground is lit
   because its WebGL stage is fixed behind the whole document; a report is
   not a scene and cannot have the reader's own trades moving behind every
   paragraph of it.

   What a long document has instead is rhythm: bands that tell you where
   you are. Six major sections, alternating between the page ground and a
   raised surface, full bleed so the change is unmistakable at the edge of
   the screen rather than a rounded rectangle in the middle of it. The
   same device the home page uses between its scenes, in print's idiom
   rather than the scene renderer's.
   ═══════════════════════════════════════════════════════════════════════ */
.band{
  position:relative;
  padding:clamp(30px,4.5vh,52px) 0;
  margin-block:clamp(26px,3.5vh,40px) 0;
}
.band::before{
  content:''; position:absolute; z-index:-1; inset:0;
  margin-inline:calc(50% - 50vw);
  background:var(--surface);
  border-top:1px solid var(--border); border-bottom:1px solid var(--border);
}
html.light .band::before{ background:#FFFFFF; }
/* A band that opens with its own heading does not need the heading's rule
   as well, or the two sit two pixels apart. */
.band > :first-child.section-h,
.band > .cost-head{ margin-top:0; }
.band .seo-block:first-child{ margin-top:0; padding-top:0; border-top:0; }

/* The report's own bands. The cost block and the closing section are the
   two places a reader stops, so they are the two that are raised. */
#costBlock.band{ margin-top:clamp(30px,4vh,44px); }

/* The reading matter underneath alternates from the first block, so the
   boundary between the report and the reference material is itself a
   change of ground rather than one more hairline. */
.seo-block.band{ margin-top:0; border-top:0; padding-top:clamp(34px,4.5vh,54px); }
.seo-block.band + .seo-block{ margin-top:0; padding-top:clamp(34px,4.5vh,54px); }

/* ═══════════════════════════════════════════════════════════════════════
   14 · THE REPORT ARRIVES

   Measured: zero mutations in the report after it rendered, and sixteen
   elements on the page carrying a transition against the home page's one
   hundred and seventy five. The report appeared all at once and then sat
   there, which is the other half of reading like a printout.

   The home page's signature is that the read happens in front of you:
   sixteen rows at 95ms and each flag landing 420ms behind its row,
   because a reader sees a line and then notices what is wrong with it.
   Mirror does the actual reading and did not show any of it. So the
   findings arrive strongest first, and each one's evidence lands a beat
   behind its title. Same gap, same reason.

   Nothing here is hidden by this stylesheet. js/mirror adds .is-waiting
   and takes it away again, so a page whose script fails shows every
   finding, which is the rule the rest of this site is built on.
   ═══════════════════════════════════════════════════════════════════════ */
.ins.is-waiting{ opacity:0; }
.ins.is-in{ animation:ins-land .42s cubic-bezier(.22,1,.36,1) both; }
@keyframes ins-land{
  from{ opacity:0; transform:translateY(9px); }
  to{ opacity:1; transform:none; }
}
.ins.is-in .ins-evidence{ opacity:0; }
.ins.is-lit .ins-evidence{ opacity:1; transition:opacity .36s ease; }

/* The verdict settles once, as the panel it sits on comes up. */
.report.show .rp-verdict{ animation:vd-land .5s cubic-bezier(.22,1,.36,1) both; }
@keyframes vd-land{
  from{ opacity:0; transform:translateY(14px); }
  to{ opacity:1; transform:none; }
}
@media (prefers-reduced-motion:reduce){
  .ins.is-in{ animation:none; }
  .ins.is-in .ins-evidence{ opacity:1; transition:none; }
  .report.show .rp-verdict{ animation:none; }
  .score__fill{ transition:none; }
}
