/* RionEA99 showcase.
   Rules taken from measuring linear.app / stripe.com / numer.ai / xtxmarkets.com:
   - separation comes from space and hairlines, not from boxes (their bordered
     block ratio is 4.6–16.7%; boxes were 46.5% here before this pass)
   - hairlines are neutral white at 6–10%, never tinted with the accent colour
   - display type is large, light and tightly leaded (line-height ~1.1, not 1.3)
   - the accent colour appears a handful of times, not on every edge
   - one thing moves on its own (the module); everything else moves on input */

:root {
  /* Not pure black: bright text on #000 produces halation -- the glow that
     makes glyphs bleed -- and it is worse for astigmatic readers. Material's
     dark theme recommends #121212 for the same reason; #0d0d0d keeps more of
     the depth this page wants while taking the edge off. Contrast barely
     moves: body text goes 8.16:1 -> 7.71:1, still well past AA. */
  --ink:       #0d0d0d;
  --paper:     #f5f5f7;
  --paper-2:   #d5d8de;   /* sub-heads: bright, but not as bright as display type */
  --mute:      #a1a1a6;
  --faint:     #86868b;   /* Apple's tertiary grey */
  --rule:      rgba(245, 245, 247, 0.14);
  --rule-soft: rgba(245, 245, 247, 0.08);
  --gold:      #d8b25c;   /* 41° / 62% / 60% — gold without the signal-yellow glare */
  --gold-hi:   #e5c47a;   /* hover: brighter, not paler */
  --gold-soft: #e3cf9f;   /* champagne highlight */
  --down:      #cb7a5e;
  --wrap:      1160px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.47;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* The faint gold wash at the top right used to be the body's own background
   with `background-attachment: fixed`. That property is a known scroll-jank
   source in Chromium: a page containing a fixed-attachment background is
   scrolled on the main thread (kHasBackgroundAttachmentFixedObjects), and the
   main thread here is already running a 60fps canvas -- so every wheel step
   had to queue behind a frame. iOS ignores `fixed` altogether and would have
   stretched the gradient over the whole document. A fixed pseudo-element gets
   its own compositor layer: same picture, scrolled off the main thread. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(70% 48% at 78% 0%, rgba(200, 163, 80, .07), transparent 62%);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition-duration: .001ms !important; }
  .reveal, .stag, .hero-in > * { opacity: 1 !important; transform: none !important; }
}

a { color: inherit; text-decoration: none; }
h1, h2, h3 { margin: 0; font-weight: 400; }
p { margin: 0; }
em { font-style: normal; color: var(--paper-2); }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

/* small monospace labels do the work that boxes used to do */
.kicker {
  font-family: var(--mono); font-size: 11px; font-weight: 400;
  letter-spacing: .2em; text-transform: uppercase; color: var(--faint);
}

/* ---------- status dot and labels (the top bar is gone) ---------- */
.src { font-family: var(--mono); font-size: 11px; letter-spacing: .14em; color: var(--mute); }
/* LIVE is the real thing, so it carries the brand colour; BACKTEST is the
   category most easily mistaken for real, so it is flagged, not celebrated */
.src.is-live { color: var(--gold); }
.src.is-demo { color: var(--mute); }
.src.is-backtest { color: var(--down); }
.lang {
  font-family: var(--mono); font-size: inherit; letter-spacing: .14em;
  color: var(--faint); border-bottom: 1px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.lang:hover { color: var(--gold); border-color: var(--gold); }
.foot-row .lang { margin-left: auto; font-size: 11px; display: inline-block; padding: 4px 0; }
.kicker .lang { color: var(--mute); }
/* An English reader landing on a Chinese page needs this before anything
   else, and at 11px in the faintest grey it sat at the bottom of what can be
   found without searching. One point larger and one tier brighter: still a
   corner detail to everyone who does not need it, findable by the one who does.
   It is in the conventional place, which is most of what discoverability is. */
.lang-row {
  display: flex; justify-content: flex-end; align-items: center;
  height: 24px; font-size: 12px; margin-right: -10px;
}
.lang-row .lang { color: var(--mute); }
.lang-row .lang { display: inline-block; line-height: 24px; padding: 0 10px; }

.dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--faint); vertical-align: middle; margin-left: 2px;
}
.dot.is-online { background: var(--gold); animation: beat 3s ease-out infinite; }
.dot.is-idle { background: var(--mute); }
.dot.is-halted { background: var(--down); }
.dot.is-lost { background: var(--down); box-shadow: 0 0 0 3px rgba(203, 122, 94, .16); }
@keyframes beat {
  0%   { box-shadow: 0 0 0 0 rgba(200, 163, 80, .45); }
  70%  { box-shadow: 0 0 0 7px rgba(200, 163, 80, 0); }
  100% { box-shadow: 0 0 0 0 rgba(200, 163, 80, 0); }
}

/* ---------- hero ---------- */
.hero {
  position: relative; display: flex; flex-direction: column;
  padding-top: 26px;
}
/* the net is the page's background, fixed behind everything */
.net { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
/* Hidden only while JS is running, because JS is what will reveal it: core.js
   adds .is-lit once it knows the real state, or after 1.2s regardless. Without
   the .js gate a browser with scripting off would get a permanently blank hero. */
.js .net { opacity: 0; transition: opacity .4s ease; }
.js .net.is-lit { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .js .net { transition: none; } }
/* everything else sits above it; the top bar keeps its own sticky stacking */
main, .foot { position: relative; z-index: 1; }
.hero-in { position: relative; z-index: 2; text-align: center; padding-bottom: 372px; }
.hero-in > * { opacity: 0; animation: rise .95s cubic-bezier(.2, .7, .2, 1) forwards; }
.hero-in > *:nth-child(1) { animation-delay: .06s; }
.hero-in > *:nth-child(2) { animation-delay: .16s; }
.hero-in > *:nth-child(3) { animation-delay: .30s; }
.hero-in > *:nth-child(4) { animation-delay: .44s; }
.hero-in > *:nth-child(5) { animation-delay: .54s; }
.hero-in > *:nth-child(6) { animation-delay: .64s; }
@keyframes rise { from { opacity: 0; transform: translate3d(0, 18px, 0); } to { opacity: 1; transform: none; } }

h1 {
  margin: 0 0 14px;
  font-size: clamp(38px, 6.6vw, 64px);
  font-weight: 600;
  line-height: 1.07;
  letter-spacing: -0.009em;
  text-wrap: balance;
  /* not flat white: a shallow top-to-bottom fall from white to silver, and a
     dark halo that pushes the net's traces away from the glyph edges */
  background: linear-gradient(177deg, #ffffff 0%, #eceef2 42%, #b3b7c0 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 9px rgba(0, 0, 0, .9))
          drop-shadow(0 0 34px rgba(0, 0, 0, .7))
          drop-shadow(0 0 60px rgba(200, 163, 80, .12));
}
@supports not (background-clip: text) { h1 { color: #f0f1f4; } }
/* measured on apple.com.cn: CJK display type is 600 weight, line-height 1.09,
   letter-spacing 0 — the negative tracking Latin wants would crowd it */
html[lang^="zh"] h1 { letter-spacing: 0; line-height: 1.09; }
html[lang^="zh"] .risks li,
html[lang^="zh"] .col p,
html[lang^="zh"] .steps p,
html[lang^="zh"] .chain p,
html[lang^="zh"] .note,
html[lang^="zh"] .bind { line-height: 1.72; }
.quiet { color: var(--mute); }
.sub {
  font-size: clamp(19px, 2.1vw, 21px); line-height: 1.43; color: var(--mute);
  max-width: 30em; margin: 0 auto 32px;
  text-shadow: 0 1px 10px rgba(0, 0, 0, .95), 0 0 26px rgba(0, 0, 0, .7);
}

/* Measured against the rest of the page, this line came last: 12px in the
   faintest grey gave it a visual weight (luminance x size) of 2.9, against 4.7
   for body copy and 34.7 for the headline -- the lowest of anything on the
   first screen, for the only early risk signal there is. 15px in --mute puts
   it at 5.4, just above body copy, where a leveraged-trading warning belongs.
   Contrast goes from 5.80:1 to 8.16:1 at the same time. */
.warn { margin-top: 22px; font-size: 14px; color: var(--mute); }
.lede-sm { color: var(--mute); font-size: 15px; max-width: 44em; }
.acts { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 14px 24px; margin-top: 30px; }
.acts .link { color: var(--mute); }
.acts .link:hover { color: var(--paper); }
/* the one mid-page path to the action; a link so the primary button stays
   the only button */
.next { margin-top: 36px; font-size: 15px; }
.next .link { color: var(--mute); }
.next .link:hover { color: var(--paper); }
/* the closing beat, before the legal footer: same strip as the hero, so the
   last impression is the same live readout the page opened with */
.strip-end { border-bottom: 1px solid var(--rule-soft); }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 48px; padding: 0 24px;
  border-radius: 999px; color: var(--paper);
  /* 48px height matches Stripe's primary CTA exactly, so the size is not the
     problem; weight and padding were. Measured: Apple 14px/400 with 21px
     padding, Stripe 16px/400 with 24px. At 500 this was the heaviest of the
     three on both counts. */
  font-size: 15px; font-weight: 400;
  /* Outlined, not filled. The off-white fill was the brightest object on the
     first screen -- brighter than the heart it sits above, which is the thing
     the screen is for. Apple's buttons on a dark product page are a line of
     text; the product owns the light. This keeps the pill (still unmistakably
     the one button) and gives the brightness back to the heart. Border at
     40% white: 3.4:1 against the page, over the 3:1 a control boundary needs. */
  background: transparent;
  border: 1px solid rgba(245, 245, 247, .40);
  transition: border-color .2s ease, background .2s ease, transform .2s ease;
}
.btn:hover {
  border-color: rgba(245, 245, 247, .75);
  background: rgba(245, 245, 247, .05);
  transform: translateY(-1px);
}
.btn:active { transform: translateY(0); }
.btn[aria-disabled="true"] {
  border-color: var(--rule-soft); color: var(--faint); background: transparent; cursor: not-allowed;
}
.btn[aria-disabled="true"]:hover { transform: none; border-color: var(--rule-soft); background: transparent; }
.link {
  display: inline-block; color: var(--paper-2); font-size: 15px;
  border-bottom: 1px solid var(--rule); padding: 3px 0;
  transition: color .2s ease, border-color .2s ease;
}
.link:hover { color: var(--gold); border-color: var(--gold); }

/* the status strip: hairlines, no container */
.strip {
  position: relative; z-index: 2; margin-top: 0;
  border-top: 1px solid var(--rule-soft);
  /* the net runs behind this band; fade it out so the labels stay readable */
  background: linear-gradient(180deg, rgba(13, 13, 13, 0), rgba(13, 13, 13, .88) 30%, rgba(13, 13, 13, .88));
}
.strip-in { display: grid; grid-template-columns: repeat(3, 1fr); }
.strip-in > div {
  padding: 15px 18px; border-bottom: 1px solid var(--rule-soft);
  display: flex; flex-direction: column; gap: 1px; min-width: 0;
}
.strip-in > div:first-child { padding-left: 0; }
.strip-in > div + div { border-left: 1px solid var(--rule-soft); }
.strip-in span {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.strip-in b {
  font-family: var(--mono); font-size: 13px; font-weight: 400; color: var(--paper-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color .4s ease;
}
.strip-in b.is-upd { color: var(--gold); }

/* ---------- sections ---------- */
.s { padding: 92px 0; border-top: 1px solid var(--rule-soft); }
#performance { padding-top: 64px; }
/* Apple's opener (small eyebrow, large title) but left-ranged: the content
   below is tables and figures, and scanning them needs a left rail */
.s-head { margin-bottom: 44px; }
.eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: .2em;
  color: var(--faint); margin-bottom: 14px;
}
.s-title {
  font-size: clamp(28px, 3.6vw, 40px); font-weight: 600;
  line-height: 1.1; letter-spacing: -0.006em;
  background: linear-gradient(180deg, #ffffff 0%, #e4e6ea 46%, #bfc3cb 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  filter: drop-shadow(0 1px 6px rgba(0, 0, 0, .85)) drop-shadow(0 0 22px rgba(0, 0, 0, .6));
}
@supports not (background-clip: text) { .s-title { color: #eceef2; } }
html[lang^="zh"] .s-title { letter-spacing: 0; line-height: 1.16; }
.s-meta {
  display: flex; align-items: baseline; gap: 14px;
  margin-top: 14px; font-family: var(--mono); font-size: 11px; color: var(--faint);
}
/* The explanatory copy -- where the figures come from, what the system will
   and will not do, how copying works -- was 13px on a desktop: one pixel above
   the legal footer, three below the headings. Text set at fine-print size is
   read as fine print, which is the exact opposite of what this copy is for.
   15px is a clear step above the footer and matches what a phone already gets.
   Line lengths stay in the CJK comfort band (~40 characters). */
.note { margin-top: 42px; max-width: 40em; font-size: 15px; line-height: 1.7; color: var(--mute); }

/* the drawdown restated inside a sentence, so the two numbers cannot be
   mentally separated; and a demo marker sitting with the numbers, not only
   in a banner people have learned to skip */
.bind {
  margin-top: 26px; max-width: 42em; font-size: 15px; color: var(--mute); line-height: 1.72;
}
.bind em { color: var(--down); font-family: var(--mono); font-size: 15px; }
.verify { margin-top: 16px; max-width: 42em; font-size: 13px; color: var(--mute); }
.demo-inline {
  margin-bottom: 22px; font-size: 15px; color: var(--mute);
  padding-left: 13px; border-left: 2px solid rgba(200, 163, 80, .55);
}
.demo-inline[hidden] { display: none; }
.note-inline { font-size: 13px; color: var(--faint); }

/* how the numbers are counted, stated before the numbers */
.scope {
  margin: 14px 0 0; font-family: var(--mono); font-size: 11px;
  letter-spacing: .04em; color: var(--faint);
}

.js .reveal { opacity: 0; transition: opacity .5s ease; }
.reveal.is-in { opacity: 1; }
.js .stag { opacity: 0; transform: translate3d(0, 14px, 0); transition: opacity .8s ease, transform .8s cubic-bezier(.2, .7, .2, 1); }
/* if the reveal machinery never started, show everything rather than nothing */
.reveal-all .reveal, .reveal-all .stag { opacity: 1 !important; transform: none !important; }
.is-in .stag { opacity: 1; transform: none; }
.is-in .stag:nth-child(1) { transition-delay: .04s; }
.is-in .stag:nth-child(2) { transition-delay: .12s; }
.is-in .stag:nth-child(3) { transition-delay: .20s; }
.is-in .stag:nth-child(4) { transition-delay: .28s; }
.is-in .stag:nth-child(5) { transition-delay: .36s; }
.is-in .stag:nth-child(6) { transition-delay: .44s; }

/* ---------- the two numbers ---------- */
.figures { display: grid; grid-template-columns: 1fr; gap: 34px 0; }
.fig { display: flex; flex-direction: column; gap: 8px; }
.fig-k { font-size: 13px; color: var(--mute); }
.fig-v {
  font-family: var(--mono); font-size: clamp(40px, 8.4vw, 76px); font-weight: 400;
  line-height: 1; letter-spacing: -0.035em; font-variant-numeric: tabular-nums;
}
.fig-v.gold { color: var(--gold); }
.fig-v.down { color: var(--down); }

/* ---------- chart ---------- */
.chart { margin-top: 88px; }
.chart-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px; padding-bottom: 14px; border-bottom: 1px solid var(--rule-soft);
}
/* Tinted pills were the one component that looked borrowed from a dashboard.
   Everything else on this page marks state with a hairline, not a fill -- the
   language link, the focus ring, the rules between rows -- so the switcher
   does the same: text, and a one-pixel underline under the active one. Gold
   stays: the current range is one of the three things gold is allowed to mean. */
.seg { display: inline-flex; gap: 18px; }
.seg button {
  appearance: none; -webkit-appearance: none; background: none; border: 0; cursor: pointer;
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  color: var(--faint); padding: 6px 2px;
  text-decoration: underline; text-decoration-color: transparent;
  text-decoration-thickness: 1px; text-underline-offset: 7px;
  transition: color .2s ease, text-decoration-color .2s ease;
}
.seg button:hover { color: var(--mute); }
.seg button.is-on { color: var(--gold); text-decoration-color: var(--gold); }
/* pan-y, not auto: the crosshair is driven by pointermove, and with `auto` a
   finger dragging sideways across the curve is swallowed by the browser's own
   scroll gesture -- so on a phone the readout that a desktop gets on hover
   simply never appeared. Vertical drags still scroll the page. */
.chart-wrap {
  position: relative; height: 240px; margin-top: 18px;
  touch-action: pan-y; -webkit-user-select: none; user-select: none;
}
/* hold the background net back behind the curve, with no hard edge */
.chart-wrap::before {
  content: ""; position: absolute; inset: -20px -26px -26px -26px; pointer-events: none;
  background: radial-gradient(88% 104% at 50% 52%,
    rgba(13, 13, 13, .95) 42%, rgba(13, 13, 13, .62) 76%, rgba(13, 13, 13, 0) 100%);
}
#equityChart { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 1; }
.chart-foot {
  display: flex; justify-content: space-between; margin-top: 10px;
  font-family: var(--mono); font-size: 11px; color: var(--faint);
}
.chart-tip[hidden] { display: none; }
.chart-tip {
  position: absolute; z-index: 3; pointer-events: none;
  display: flex; flex-direction: column;
  padding: 8px 11px; background: #212124; border-left: 2px solid var(--gold);
  font-family: var(--mono); font-size: 11px; line-height: 1.55; white-space: nowrap;
}
.tip-d { color: var(--faint); }
.tip-v { color: var(--gold-soft); }
.tip-dd { color: var(--down); }

/* ---------- secondary numbers ---------- */
.row {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 30px 20px;
  margin-top: 64px; padding: 30px 0 34px;
  border-top: 1px solid var(--rule-soft); border-bottom: 1px solid var(--rule-soft);
}
.row > div { display: flex; flex-direction: column; gap: 3px; }
.row > div span { font-size: 13px; color: var(--mute); }
.row > div b {
  font-family: var(--mono); font-size: 21px; font-weight: 400;
  letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
}

/* ---------- ledger ---------- */
.ledger { margin-top: 72px; }
.trades { width: 100%; border-collapse: collapse; margin-top: 4px; }
.trades th {
  font-family: var(--mono); font-size: 11px; font-weight: 400;
  letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  text-align: left; padding: 16px 0 12px;
}
.trades td {
  font-family: var(--mono); font-size: 13px; color: var(--mute);
  padding: 13px 0; border-top: 1px solid var(--rule-soft);
}
.trades tbody tr { opacity: 0; animation: rise .5s cubic-bezier(.2, .7, .2, 1) forwards; animation-delay: calc(var(--i, 0) * 45ms); }
.trades tbody tr:hover td { color: var(--paper-2); }
.r { text-align: right; }
.buy { color: var(--paper-2); }
.sell { color: var(--mute); }
.pos { color: var(--gold-soft); }
.neg { color: var(--down); }

/* ---------- columns, steps, risks, contacts ---------- */
.cols { display: grid; grid-template-columns: 1fr; }
.col { padding: 26px 0; border-top: 1px solid var(--rule-soft); }
.col b { display: block; font-size: 15px; font-weight: 500; margin-bottom: 8px; color: var(--paper-2); }
.col p { font-size: 15px; line-height: 1.7; color: var(--mute); max-width: 26em; }

.steps, .chain { list-style: none; margin: 0; padding: 0; }
.steps li, .chain li { display: flex; gap: 22px; padding: 28px 0; border-top: 1px solid var(--rule-soft); }
.steps li > span, .chain li > span {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  color: var(--faint); padding-top: 5px; flex: none;
}
.steps b, .chain b { display: block; font-size: 15px; font-weight: 500; color: var(--paper-2); }
.steps p, .chain p { font-size: 15px; line-height: 1.7; color: var(--mute); max-width: 40em; }

.risks { list-style: none; margin: 0; padding: 0; max-width: 48em; }
.risks li {
  position: relative; padding: 0 0 22px 26px;
  font-size: 15px; color: var(--mute);
}
.risks li::before {
  content: ""; position: absolute; left: 0; top: 13px;
  width: 9px; height: 1px; background: var(--mute);
}

.chips { display: flex; flex-wrap: wrap; gap: 10px 28px; margin-top: 30px; font-size: 15px; }
.chips a { border-bottom: 1px solid var(--rule); padding-bottom: 3px; transition: color .2s ease, border-color .2s ease; }
.chips a:hover { color: var(--gold); border-color: var(--gold); }
.chips .pending { color: var(--faint); border-bottom: 1px dashed var(--rule); padding-bottom: 3px; }

/* ---------- foot ---------- */
.foot { padding: 40px 0 72px; border-top: 1px solid var(--rule-soft); }
.foot-row {
  display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 16px;
  font-family: var(--mono); font-size: 11px; color: var(--faint);
}
.foot-legal { font-size: 12px; color: var(--faint); max-width: 56em; line-height: 1.72; }

/* ---------- wider screens ---------- */
@media (min-width: 720px) {
  .row { grid-template-columns: repeat(3, 1fr); gap: 34px 24px; }
  .cols { grid-template-columns: repeat(2, 1fr); column-gap: 40px; }
  .col { padding: 28px 0 30px; }
  .chart-wrap { height: 300px; }
  .figures { grid-template-columns: repeat(2, 1fr); align-items: end; }
  .fig + .fig { padding-left: 46px; border-left: 1px solid var(--rule-soft); }
  .fig-note { grid-column: 1 / -1; margin-top: 12px; }
}
@media (min-width: 1000px) {
  .row { grid-template-columns: repeat(6, 1fr); gap: 0 24px; }
  .cols { grid-template-columns: repeat(4, 1fr); column-gap: 44px; }
  .chart-wrap { height: 360px; }
  .figures { grid-template-columns: 1fr 1fr 1fr; }
  .fig-note { grid-column: 3; margin-top: 0; padding-left: 46px; }
}

/* ---------- phones (kept last: these override the base rules) ---------- */
/* ---------- scroll snap ----------
   A flick should come to rest on a section rather than halfway between two.

   `proximity`, never `mandatory`: section 02 is 1.86 screens on a desktop and
   2.49 on a phone, and mandatory snapping would drag the reader around while
   they are trying to read the figures -- the one screen where that is least
   forgivable. Proximity only engages when the scroll settles near a boundary,
   so a long section still scrolls freely.

   The scroll is never hijacked in JS. Intercepting the wheel breaks keyboard
   paging, find-in-page and dragging the scrollbar, and it makes some people
   motion sick; no amount of polish is worth that. */
/* Which blocks become pages is decided at runtime (see pageSnap in app.js):
   the blocks are not all one height and they reflow with the viewport, so a
   hand-picked list is wrong on some screen somewhere. Until JS has chosen,
   and whenever it cannot find a safe set, this stays `proximity`. */
/* No scrollbar. It also reclaims the gutter, which is why the page used to
   report a scrollWidth 6px wider than its clientWidth. Scrolling itself is
   untouched: wheel, trackpad, touch, keyboard and find-in-page all work, and
   the snap points below are the wayfinding the bar used to provide. */
/* The progress rail that replaces it. Hiding the scrollbar took away the one
   thing telling a reader how far through a 5700px page they are, and with the
   scroll damped and nothing snapping there is no other cue left.

   A bare bar would give the position back and nothing else. The page is
   already built as numbered sections, so the rail carries that structure: a
   hairline the whole document sits on, a tick where each section begins, and
   the number of the section being read. It answers "how far" and "how much is
   left" and "which part is this" with one glance, and it is gone a second
   after the scrolling stops.

   Neutral throughout. Gold on this page means live, actionable or positive --
   wayfinding is none of those, and a fourth use would start to dilute it. */
.rail {
  position: fixed; top: 0; right: 0; width: 52px; height: 100vh;
  z-index: 3; pointer-events: none;
  opacity: 0; transition: opacity .5s ease;
}
.rail.is-on { opacity: 1; transition-duration: .18s; }

.rail-line {                                  /* the whole document */
  position: absolute; top: 0; right: 15px; width: 1px; height: 100%;
  background: var(--rule-soft);
}
.rail-tick {                                  /* where each section begins */
  position: absolute; right: 11px; width: 9px; height: 1px;
  background: var(--rule);
}
.rail-thumb {                                 /* the part on screen */
  position: absolute; top: 0; right: 14px; width: 3px; height: 100vh;
  background: var(--paper); opacity: .34;
  transform-origin: top; will-change: transform;
}
.rail-at {                                    /* the section being read */
  position: absolute; top: 0; right: 26px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  line-height: 14px; color: var(--faint);
  white-space: nowrap; will-change: transform;
}

@media (prefers-reduced-motion: reduce) { .rail { transition: none; } }
/* a phone has no room beside the column, and no cursor to explain the rail */
@media (max-width: 640px) {
  .rail { width: 10px; }
  .rail-line, .rail-tick, .rail-at { display: none; }
  .rail-thumb { right: 3px; width: 2px; }
}

html { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar { width: 0; height: 0; display: none; }

html { scroll-snap-type: y proximity; }
html.snap-pages { scroll-snap-type: y mandatory; }
.snap { scroll-snap-align: start; }
/* No `scroll-snap-stop: always`. With 12 pages on a phone it forced a stop on
   every flick, so the page jumped constantly and there is no CSS property that
   slows a snap down -- the duration is the browser's. Without it a gentle
   flick still lands on the next page and a firmer one can travel. */
@media (prefers-reduced-motion: reduce) {
  html, html.snap-pages { scroll-snap-type: none; }
}

/* ---------- loading state ----------
   Before the summary lands every figure reads "—". That is the page's honest
   "no data" mark, and it is right for a browser with no scripts -- but on a
   slow connection it is also the first thing anyone sees, for a second or
   two, and it reads as broken rather than arriving. While the first fetch is
   in flight the fields hold their shape as faint blocks instead, sized in em
   to roughly what will land in them, so nothing jumps when it does. They
   breathe on the same slow rhythm as everything else here; under reduced
   motion they hold still. Gated on .js: no scripts, no skeletons, just the
   honest dashes. app.js drops the class on the first render, on the cached
   path, on total failure, and by a timer if none of those ever happen. */
.js.is-loading #ret12,        .js.is-loading #maxdd,
.js.is-loading #teleState,    .js.is-loading #teleBeat,   .js.is-loading #teleToday,
.js.is-loading [data-mirror], .js.is-loading .row b,      .js.is-loading #bindDD,
.js.is-loading #updatedAgo,   .js.is-loading #sourceBadge2,
.js.is-loading #axisStart,    .js.is-loading #axisEnd,
.js.is-loading #footVersion,  .js.is-loading #footGenerated,
.js.is-loading .sk {
  display: inline-block; vertical-align: middle;
  color: transparent !important; background: var(--rule);
  border-radius: 3px; min-width: 4.5em; height: 1em;
  animation: breathe 2.4s ease-in-out infinite;
}
.js.is-loading #ret12, .js.is-loading #maxdd { min-width: 4.4em; height: .82em; }
.js.is-loading .row b { min-width: 4em; height: .9em; }
.js.is-loading #bindDD { min-width: 3.6em; height: .95em; }
.js.is-loading #updatedAgo, .js.is-loading #sourceBadge2 { min-width: 6em; }
.js.is-loading #axisStart, .js.is-loading #axisEnd { min-width: 6.5em; }
.js.is-loading #footVersion, .js.is-loading #footGenerated { min-width: 9em; }
.js.is-loading .sk { min-width: 5em; }
.js.is-loading td:nth-child(2) .sk { min-width: 3em; }
.js.is-loading td:nth-child(3) .sk { min-width: 6em; }
/* the curve's absence gets one hairline where it will run, not a hole */
.js.is-loading .chart-wrap::after {
  content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  background: var(--rule-soft);
}
@keyframes breathe { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .js.is-loading * { animation: none !important; } }

/* ---------- reading measure for the prose sections ----------
   The column is 1160px so the figures, the chart and the ledger have room.
   The prose sections do not need it: on a wide screen a card grid or a step
   list spanning the full width ran past a comfortable measure, and it ran
   into the sphere that settles on the right from section 04 on -- the one
   place effect sat on top of content. The section heads keep the full width
   so titles stay aligned down the page; only the bodies come in. */
@media (min-width: 1200px) {
  #chain .chain, #chain .note, #how .cols, #how .next,
  #risk .risks, #follow .steps, #follow .acts { max-width: 960px; }
}

/* ---------- keyboard focus ----------
   There was no authored focus style at all, so every browser fell back to its
   own default ring -- visible, but different everywhere and foreign to a page
   this deliberate. One gold ring, sitting outside the control so it never
   fights the off-white button underneath it. */
a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  /* deliberately no border-radius here: setting it would square off the pill
     button while it has focus. Browsers already curve the outline to match. */
}
.btn:focus-visible, .seg button:focus-visible { outline-offset: 4px; }
.net:focus-visible { outline: none; }

/* readable by assistive tech, no box on screen */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

.noscript-note {
  margin: 0 0 28px; padding: 14px 16px;
  border-left: 2px solid var(--gold);
  color: var(--paper); font-size: 15px; line-height: 1.7;
  background: rgba(216, 178, 92, .06);
}

/* ---------- print ----------
   The page is near-white text on black, and browsers do not print background
   colours: a printed copy, or "save as PDF", came out as blank paper. This is
   a performance summary, so someone will want to keep one. Inverted here, with
   the interactive furniture dropped -- and the two placeholder markings kept,
   because those are the ones that must survive onto paper. */
@media print {
  :root {
    --paper: #111111; --paper-2: #333333;
    --mute: #565656; --faint: #4a4a4a;
    --rule: rgba(0, 0, 0, .28); --rule-soft: rgba(0, 0, 0, .14);
    --gold: #7a5c18; --gold-hi: #7a5c18; --gold-soft: #7a5c18;
    --down: #9a3412;
  }
  @page { margin: 16mm; }
  html, body { background: #fff !important; color: #111 !important; }
  body::before { display: none !important; }      /* the gold wash */
  .net, .seg, .chart-tip, .lang-row, .lang, #eqCross { display: none !important; }
  /* the scroll reveal must never leave printed sections invisible */
  .reveal, .stag, .hero-in > * {
    opacity: 1 !important; transform: none !important; animation: none !important;
  }
  .hero-in { padding-bottom: 20px !important; }
  /* the display type paints itself through a gradient; undo that on paper */
  h1, h2, .s-title {
    background: none !important; -webkit-text-fill-color: #111 !important;
    color: #111 !important; filter: none !important;
  }
  a { color: #111 !important; text-decoration: underline; }
  a[href^="http"]::after { content: " <" attr(href) ">"; font-size: 11px; color: #555; }
  .btn {
    background: none !important; color: #111 !important;
    border: 1px solid #111 !important; box-shadow: none !important;
  }
  /* two dark washes exist only to hold the background net back; the net is
     hidden on paper, so they are pure black bands with nothing behind them */
  .strip, .seg button.is-on, .noscript-note { background: none !important; }
  .chart-wrap::before { display: none !important; }
  .btn[aria-disabled="true"] {
    background: none !important; color: #555 !important; border-color: #888 !important;
  }
  .dot { animation: none !important; }
  /* screen spacing is generous on purpose; on paper it is just wasted sheets */
  .s { padding: 34px 0 !important; }
  .chart { margin-top: 30px !important; }
  #equityChart path[stroke] { stroke: #7a5c18 !important; }
  #equityChart circle { fill: #7a5c18 !important; }
  #equityChart line { stroke: rgba(0, 0, 0, .3) !important; }
  .fig, .chart, .ledger, .col, .chain li, .steps li, .risks li { break-inside: avoid; }
  .s { break-before: auto; }
}

@media (max-width: 640px) {
  .wrap { padding: 0 20px; }
  .s { padding: 66px 0; }
  #performance { padding-top: 46px; }
  .s-head { margin-bottom: 40px; }

  h1 { margin: 22px 0 26px; }
  /* A full-width bar is the usual mobile pattern, but in flat off-white it was
     88% of the viewport and became the loudest thing on the first screen --
     competing with the heart, which is meant to carry it. Sized to its label
     and centred instead; still 48px tall, so the tap target is unchanged. */
  .acts { flex-direction: column; gap: 14px; margin-top: 30px; }
  .acts .btn { width: auto; max-width: 100%; }
  .acts .link, .next .link { display: inline-block; padding: 12px 0; }   /* 44px tap height */
  .lang-row .lang { line-height: 44px; }

  .seg button {                               /* 44px tap height */
    display: inline-flex; align-items: center;
    min-height: 44px; padding: 0 14px;
  }

  /* the tap area is 44px, but it must not add 44px of visible space */
  .lang-row { height: 44px; margin-top: -12px; margin-bottom: -10px; }

  .strip { margin-top: 0; }
  .hero-in { padding-bottom: 300px; }
  .strip-in > div { padding: 13px 10px; }
  .strip-in b { font-size: 13px; }

  .figures { gap: 26px 0; }
  .row { gap: 26px 16px; padding: 26px 0 28px; }
  .trades td { font-size: 13px; padding: 12px 0; }
  .chain li, .steps li { gap: 16px; padding: 24px 0; }
  /* the four-column ledger collapses on a phone: time and result on one line,
     side and holding time underneath */
  .trades thead { display: none; }   /* the values read on their own here */
  .trades, .trades tbody, .trades tr, .trades td { display: block; width: 100%; }
  .trades tbody tr {
    position: relative; padding: 13px 0;
    border-top: 1px solid var(--rule-soft);
  }
  .trades td { padding: 0; border: 0; }
  .trades td:nth-child(1) { font-size: 13px; color: var(--mute); }
  .trades td:nth-child(2), .trades td:nth-child(3) {
    display: inline-block; width: auto; font-size: 13px; color: var(--mute); margin-top: 5px;
  }
  .trades td:nth-child(2) { margin-right: 12px; }
  .trades td:nth-child(4) { position: absolute; top: 11px; right: 0; width: auto; font-size: 14px; }
  /* The switcher wrapped to its own line and then left-aligned, leaving it
     looking orphaned under the label. Stacked on purpose instead, with the
     switcher on the right where a wide screen puts it. */
  .chart-head { flex-direction: column; align-items: stretch; gap: 10px; }
  .chart-head .seg { align-self: flex-end; }
  .chart-head .s-meta { text-align: right; }

  /* More height for the curve -- there is room on a phone -- and the axis dates
     were sitting inside the wash that reaches 26px below the plot, which is
     what made them look half-erased. */
  .chart-wrap { height: 280px; }
  .chart-foot { margin-top: 26px; }

  /* the section head stacks instead of wrapping into itself */
  .s-head { flex-direction: column; align-items: flex-start; gap: 8px; }
  .s-meta { gap: 12px; }

  .sub { font-size: 19px; }
  .warn { font-size: 15px; }
  .bind { font-size: 14.5px; margin-top: 22px; }
  .verify { font-size: 13px; }
  .scope { font-size: 11px; line-height: 1.7; }

  /* Reading copy was 13px here -- under Material's 16sp body and well under
     Apple's 17pt. These are the paragraphs carrying the trust (where the
     figures come from, what the system will and will not do, how copying
     works), and they were set smaller than any guideline's body size. */
  .chain p, .steps p, .col p, .note { font-size: 15px; line-height: 1.75; }
  .demo-inline { font-size: 15px; }
  .foot-legal { font-size: 13px; }

}
