/* Hallmark · macrostructure: Console · genre: documentation · theme: Vespryx (brand-locked)
 *
 * THE PORTAL, AS A MANUAL.
 *
 * The old portal was thirteen <h2>s on one scroll with a hand-written TOC beside
 * them, and every deep answer lived on guide.html instead — so "why does my chart
 * say 0 OI" was two pages and a scroll away from the page you were already on.
 * This is the same content, in ten numbered chapters, one at a time, with the
 * guide's reference material folded in as chapters 04–08.
 *
 * No colour literals. Every value is a token from ui/tokens.css, for the reason
 * test/uiTokens.test.mjs exists: the chart names its colours out loud, so a
 * surface that drifts to a different amber teaches the wrong one. The four wall
 * colours appear here as swatches in chapter 04 and MUST stay on --tdx-red /
 * --tdx-green / --tdx-amber / --tdx-purple, never on the gold chrome ramp.
 *
 * Load order: ui/tokens.css, then this file. portal.js is unchanged and still
 * owns #planCard, the three account forms, the pd* dress controls and the token
 * reveal; portal-nav.js owns chapter switching and search, and touches nothing
 * portal.js reads.
 */

*, *::before, *::after { box-sizing: border-box; }
/* An author display rule beats the UA's [hidden] regardless of specificity. This
   project has already shipped a strip that was visible in every state for want
   of this line. */
[hidden] { display: none !important; }

html { background: var(--tdx-navy); }
body {
  margin: 0;
  background: var(--tdx-navy);
  color: var(--tdx-white);
  font: 16px/1.65 var(--tdx-font);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--tdx-ui); text-decoration: none; }
a:hover { color: var(--tdx-ui-hi); }
code { font: var(--tdx-text-base) var(--tdx-mono); color: var(--tdx-white-dim); }
em { font-style: italic; }
strong { color: var(--tdx-white); font-weight: 650; }

:where(a, button, input, select, textarea, summary):focus-visible {
  outline: 2px solid rgba(var(--tm-gold-rgb), 0.55);
  outline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════ signed out ═══
 * A first-class state, not an error: the extension and the download are free, so
 * this page has to be useful to someone with no account. */
.out { min-height: 100vh; display: grid; grid-template-rows: auto 1fr auto; }
.out__bar { border-bottom: 1px solid var(--tdx-line-soft); padding: var(--tdx-space-16) 0; }
.out__wrap { width: 100%; max-width: 1000px; margin: 0 auto; padding: 0 var(--tdx-space-24); }
.out__bar .out__wrap { display: flex; align-items: center; gap: var(--tdx-space-16); }
.out__nav { display: flex; flex-wrap: wrap; gap: var(--tdx-space-16); margin-right: auto; font-size: 14px; }
.out__nav a { color: var(--tdx-slate); }
.out__nav a:hover { color: var(--tdx-white); }
.out__body { padding: 64px var(--tdx-space-24) var(--tdx-space-40); }
.out__body > div { max-width: 640px; }
.out h1 {
  margin: 10px 0 0; font-size: 34px; line-height: 1.1; font-weight: 620;
  letter-spacing: -0.028em; text-wrap: pretty;
}
.out__foot { border-top: 1px solid var(--tdx-line-soft); padding: var(--tdx-space-20) 0 36px; }
.out__foot .out__wrap { display: flex; flex-wrap: wrap; gap: var(--tdx-space-16); font-size: 13px; }
.out__foot a { color: var(--tdx-slate); }
.out__foot a:hover { color: var(--tdx-white); }

/* ═══════════════════════════════════════════════════════════════ shell ═══ */
.shell { display: grid; grid-template-columns: 252px minmax(0, 1fr); min-height: 100vh; }

.rail {
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  background: var(--tdx-panel-lo);
  border-right: 1px solid var(--tdx-line-soft);
  padding: var(--tdx-space-20) 14px var(--tdx-space-24);
  display: flex; flex-direction: column; gap: var(--tdx-space-20);
}
.rail__brand { display: flex; align-items: center; gap: 10px; padding: 0 var(--tdx-space-8); color: inherit; }
.rail__brand:hover { color: var(--tdx-white); }
.rail__brand img { display: block; width: 24px; height: 24px; border-radius: 6px; }
.rail__name { font-weight: 650; font-size: var(--tdx-text-md); }
.rail__ver {
  margin-left: auto;
  font: 600 10px var(--tdx-mono); letter-spacing: 0.16em; color: var(--vx-chrome-lo);
}

/* Search. One field over every setting, colour, reaction word and fix, because
 * "find the thing that explains this" was previously a scroll on two pages. */
.find {
  display: flex; align-items: center; gap: var(--tdx-space-8);
  padding: var(--tdx-space-8) 11px; border-radius: 9px;
  background: rgba(var(--tdx-navy-rgb), 0.75);
  border: 1px solid var(--tdx-line);
}
.find__icon { color: var(--tdx-slate-dim); font-size: 13px; }
.find input {
  flex: 1; min-width: 0; background: none; border: 0; outline: none;
  color: var(--tdx-white); font: 13px var(--tdx-font);
}
.find input::placeholder { color: var(--vx-chrome-lo); }
.find__clear {
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--tdx-slate-dim); font-size: 14px;
}

.rail__groups { display: grid; gap: var(--tdx-space-16); }
.rail__kicker {
  font: 600 10.5px var(--tdx-mono); letter-spacing: 0.16em;
  color: var(--vx-chrome-lo); padding: 0 10px var(--tdx-space-6);
}
/* The chapter buttons. Numbered, because a numbered rail tells someone deep in
 * chapter seven how much is left; the old TOC could not. */
.chap {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: var(--tdx-space-8) 10px; border-radius: var(--tdx-radius-sm);
  border: 0; border-left: 2px solid transparent; background: transparent;
  color: var(--tdx-slate); font: 500 13px var(--tdx-font);
  text-align: left; cursor: pointer;
  transition: background var(--tdx-dur-fast) var(--tdx-ease-out),
              color var(--tdx-dur-fast) var(--tdx-ease-out);
}
.chap:hover { background: rgba(var(--tdx-slate-rgb), 0.07); color: var(--tdx-white); }
.chap[aria-current="true"] {
  border-left-color: var(--tdx-ui);
  background: rgba(var(--tm-gold-rgb), 0.10);
  color: var(--tdx-white); font-weight: 600;
}
.chap__n { flex: none; font: 600 10px var(--tdx-mono); color: #4b5563; }
.chap[aria-current="true"] .chap__n { color: var(--tdx-ui); }
.chap__t { flex: 1; }
.chap__badge {
  flex: none; padding: 1px 6px; border-radius: 4px;
  background: rgba(var(--tm-gold-rgb), 0.14);
  border: 1px solid rgba(var(--tm-gold-rgb), 0.35);
  font: 9px var(--tdx-mono); color: var(--tm-gold-hi);
}

.rail__foot { margin-top: auto; display: grid; gap: 10px; }
.whoami { padding: var(--tdx-space-12); border-radius: var(--tdx-radius); background: var(--tdx-panel); border: 1px solid var(--tdx-line-soft); }
.whoami__on { display: flex; align-items: center; gap: var(--tdx-space-8); font-size: var(--tdx-text-sm); color: var(--tdx-white-dim); }
.whoami__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--tdx-green-text); box-shadow: 0 0 8px var(--tdx-green-text); }
.whoami__who { margin-top: var(--tdx-space-4); font-size: 11.5px; color: var(--tdx-slate-dim); overflow: hidden; text-overflow: ellipsis; }
.link {
  padding: var(--tdx-space-8) 11px; border-radius: 9px; background: transparent;
  border: 1px solid var(--tdx-line); color: var(--tdx-slate);
  font: 550 var(--tdx-text-sm) var(--tdx-font); cursor: pointer; text-align: left;
}
.link:hover { color: var(--tdx-white); }

/* ═══════════════════════════════════════════════════════════════ chrome ═══ */
.crumbbar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; gap: 14px;
  padding: 0 var(--tdx-space-32); height: 56px;
  border-bottom: 1px solid var(--tdx-line-soft);
  background: rgba(5, 6, 7, 0.72); backdrop-filter: blur(14px);
}
.crumb {
  font: 600 var(--tdx-text-xs) var(--tdx-mono); letter-spacing: 0.18em;
  color: var(--tdx-slate-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crumbbar__end { margin-left: auto; display: flex; gap: var(--tdx-space-16); font-size: 13px; flex: none; }

/* ══════════════════════════════════════════════════════════════ chapter ═══ */
.doc { padding: var(--tdx-space-40) var(--tdx-space-32) 64px; max-width: 820px; }
.eyebrow {
  display: block;
  font: 600 var(--tdx-text-xs) var(--tdx-mono); letter-spacing: 0.18em;
  color: var(--vx-chrome-lo);
}
.doc h2 {
  margin: var(--tdx-space-8) 0 0; font-size: 31px; line-height: 1.1;
  font-weight: 600; letter-spacing: -0.028em; max-width: 26ch; text-wrap: pretty;
}
.doc h3 {
  margin: 36px 0 0; font-size: 19px; font-weight: 620; letter-spacing: -0.018em;
}
.doc h3:first-child { margin-top: 0; }
.doc h4 { margin: var(--tdx-space-32) 0 0; font-size: 17px; font-weight: 620; }
.lede {
  margin: var(--tdx-space-16) 0 0; font-size: var(--tdx-text-md); line-height: 1.7;
  color: var(--tdx-white-2); max-width: 62ch; text-wrap: pretty;
}
.doc h3 + .lede { margin-top: 10px; font-size: 14px; line-height: 1.75; }

/* An aside: the caveat, the measured detail, the thing that would clutter the
 * body but must not be dropped. Tinted so it reads as an aside rather than as
 * one more paragraph to skim. */
.aside {
  margin-top: var(--tdx-space-20); padding: var(--tdx-space-20) 22px;
  border-radius: 14px; background: rgba(var(--tdx-navy-rgb), 0.45);
  border: 1px solid var(--tdx-line-soft);
  display: grid; gap: var(--tdx-space-12);
}
.aside p { margin: 0; font-size: 13.5px; line-height: 1.75; color: var(--tdx-slate); max-width: 76ch; }
.aside strong { color: var(--tdx-white-dim); }
.fine { font-size: var(--tdx-text-sm); line-height: 1.75; color: var(--tdx-slate); }
.faint { font-size: var(--tdx-text-sm); color: var(--tdx-slate-dim); }

/* A warning that has to look unlike the paragraph above it or it reads as more
 * prose to skim. */
.warn {
  margin-top: var(--tdx-space-16); padding: 13px 15px; border-radius: 12px;
  background: rgba(var(--tdx-amber-rgb), 0.08);
  border: 1px solid rgba(var(--tdx-amber-rgb), 0.3);
  font-size: 13px; line-height: 1.75; color: #f0c274;
}
.warn strong { color: var(--tdx-amber); }
.danger {
  margin: 0; padding: var(--tdx-space-12) 14px; border-radius: 9px;
  background: rgba(var(--tdx-red-rgb), 0.08);
  border: 1px solid rgba(var(--tdx-red-rgb), 0.3);
  font-size: 13px; line-height: 1.65; color: #fca5a5;
}

/* ════════════════════════════════════════════════════════════════ cards ═══
 * A stack of hairline-separated rows inside one rounded frame. One shape for
 * every list in the manual — steps, settings, colours, fixes, plan rows — so a
 * reader learns the layout once. */
.stack {
  display: grid; gap: 1px; margin-top: 26px; padding: 0; list-style: none;
  border-radius: 14px; overflow: hidden;
  background: var(--tdx-line-soft); border: 1px solid var(--tdx-line-soft);
}
.stack > * { background: #0a0c10; }
.row { padding: var(--tdx-space-16) var(--tdx-space-20); }
.row--kv { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: var(--tdx-space-20); }
.row--kv .k { display: grid; gap: var(--tdx-space-8); align-content: start; font-size: 13.5px; font-weight: 640; color: var(--tdx-white); }
.row--kv .v { min-width: 0; display: grid; gap: 9px; }
.row--kv .v p { margin: 0; font-size: 13.5px; line-height: 1.75; color: var(--tdx-white-2); }
.row--kv .v .fine { color: var(--tdx-slate); }

.card { padding: 17px; border-radius: 14px; background: #0a0c10; border: 1px solid var(--tdx-line-soft); }
.card--panel { padding: var(--tdx-space-20) 22px; border-radius: 14px; background: var(--tdx-panel); border: 1px solid var(--tdx-line-soft); }
.card__head { display: flex; align-items: center; gap: 9px; font-size: 14px; font-weight: 650; }
.card__head img { display: block; width: 22px; height: 22px; border-radius: 5px; }
.card p { margin: 10px 0 0; font-size: 13px; line-height: 1.7; color: var(--tdx-slate); }
.kicker { margin-top: 11px; font: 600 10.5px var(--tdx-mono); letter-spacing: 0.1em; color: var(--vx-chrome-lo); }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--tdx-space-12); }
.two--mt { margin-top: var(--tdx-space-20); }

/* The one card on this surface that is an offer rather than information: the annual
 * plan. Gold edge and a top-lit wash, both from --tdx-ui, so it reads as the
 * recommended option without a second accent entering the stylesheet. */
.card--accent {
  border-color: rgba(var(--tdx-ui-rgb), 0.34);
  background:
    radial-gradient(420px 220px at 50% 0%, rgba(var(--tdx-ui-rgb), 0.12), transparent 70%),
    var(--tdx-panel);
}
.card--accent .eyebrow { color: var(--tm-gold-hi); }

/* ════════════════════════════════════════════════════════════════ atoms ═══ */
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: var(--tdx-space-16); }
.btn {
  display: inline-block; padding: 10px 17px; border: 0; border-radius: 9px;
  background: var(--tdx-ui); color: var(--tdx-ui-ink);
  font: 650 13.5px var(--tdx-font); cursor: pointer;
}
.btn:hover { background: var(--tdx-ui-hi); color: var(--tdx-ui-ink); }
.btn:active { background: var(--tdx-ui-press); }
.btn--quiet { background: transparent; border: 1px solid var(--tdx-line-hi); color: var(--tdx-white-dim); }
.btn--quiet:hover { background: rgba(var(--tdx-slate-rgb), 0.08); color: var(--tdx-white); }
.btn--danger { background: transparent; border: 1px solid rgba(var(--tdx-red-rgb), 0.45); color: var(--tdx-red-text); }
.btn--danger:hover { background: rgba(var(--tdx-red-rgb), 0.1); color: var(--tdx-red-text); }
.btn:disabled { opacity: 0.55; cursor: default; }

/* A tag hugs its text. It sits in both flex and grid parents here, so it needs
 * justify-self as well as flex:none — a bare flex:none is inert in a grid and the
 * pill stretches to the whole column. */
.tag {
  flex: none; justify-self: start; width: max-content; max-width: 100%;
  padding: 2px var(--tdx-space-8); border-radius: 5px;
  background: #12151b; border: 1px solid var(--tdx-line);
  font: 9.5px/1.6 var(--tdx-mono); letter-spacing: 0.08em; color: var(--tdx-slate);
}
.tag--ok { background: rgba(var(--tdx-green-rgb), 0.14); border-color: rgba(var(--tdx-green-rgb), 0.34); color: var(--tdx-green-text); }
.tag--warn { background: rgba(var(--tdx-amber-rgb), 0.12); border-color: rgba(var(--tdx-amber-rgb), 0.32); color: var(--tdx-amber); }
.tag--off { color: var(--tdx-slate-dim); }

pre {
  margin: 0; padding: var(--tdx-space-12) 14px; border-radius: 9px; overflow-x: auto;
  background: rgba(var(--tdx-navy-rgb), 0.6); border: 1px solid var(--tdx-line-soft);
  color: var(--tdx-white); font: 11.5px/1.5 var(--tdx-mono);
}

/* ════════════════════════════════════════════════════════════════ steps ═══ */
.step { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: var(--tdx-space-16); align-items: center; }
.step__mark {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center; font: 700 11px var(--tdx-mono);
  background: transparent; border: 1px solid var(--tdx-line-hi); color: var(--tdx-slate);
}
.step--done .step__mark {
  background: rgba(var(--tm-gold-rgb), 0.16);
  border-color: rgba(var(--tm-gold-rgb), 0.4);
  color: var(--tm-gold-hi);
}
.step__body { min-width: 0; display: grid; gap: 3px; }
.step__t { font-size: 14.5px; font-weight: 620; color: var(--tdx-white); }
.step--done .step__t { color: var(--tdx-slate); }
.step__sub { font-size: 13px; line-height: 1.6; color: var(--tdx-slate); }
.step__done { justify-self: end; font: 600 11px var(--tdx-mono); letter-spacing: 0.1em; color: var(--tdx-green-text); }

/* ═════════════════════════════════════════════════════════════ setup card ═══
 * The four-step checklist in chapter 01. portal.js fills the count and hides
 * the whole card once every step reads DONE. */
.setup-card {
  margin-top: var(--tdx-space-20);
  border-radius: 14px;
  border: 1px solid var(--tdx-line-soft);
  overflow: hidden;
}
.setup-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--tdx-space-12) var(--tdx-space-20);
  background: var(--tdx-panel-lo);
  border-bottom: 1px solid var(--tdx-line-soft);
}
.setup-card #setupSteps { margin-top: 0; border-radius: 0; border: 0; }
.setup-card__done { padding: var(--tdx-space-12) var(--tdx-space-20); margin: 0; }
.setup-card__dismiss { font-size: var(--tdx-text-sm); }
.setup-card__dismiss:hover { color: var(--tdx-white-dim); }
.setup-card__restore { margin-top: var(--tdx-space-8); }

/* Numbered instructions: the paste steps and the token walkthrough. */
.num { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: var(--tdx-space-16); padding: 18px var(--tdx-space-20); }
.num__n {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(var(--tm-gold-rgb), 0.14); border: 1px solid rgba(var(--tm-gold-rgb), 0.4);
  font: 700 13px var(--tdx-mono); color: var(--tdx-white);
}
.num__t { display: block; font-size: var(--tdx-text-md); font-weight: 620; }
.num__b { display: block; margin-top: 7px; font-size: 13.5px; line-height: 1.75; color: var(--tdx-slate); }

/* ══════════════════════════════════════════════════════════════ colours ═══
 * The four wall colours. These are the SAME values the chart draws in and the
 * regime panel names out loud, so they stay on the semantic tokens. */
.row--colour { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: var(--tdx-space-20); align-items: center; }
.row--colour .swatch { display: grid; gap: 10px; }
.row--colour .name { font-size: 13.5px; font-weight: 650; color: var(--tdx-white); }
.row--colour .desc { font-size: 13.5px; line-height: 1.75; color: var(--tdx-slate); }
.bar { display: block; height: 4px; border-radius: 2px; }
.bar--res  { background: var(--tdx-red);    box-shadow: 0 0 10px rgba(var(--tdx-red-rgb), 0.55); }
.bar--sup  { background: var(--tdx-green);  box-shadow: 0 0 10px rgba(var(--tdx-green-rgb), 0.55); }
.bar--pin  { background: var(--tdx-amber);  box-shadow: 0 0 10px rgba(var(--tdx-amber-rgb), 0.55); }
.bar--flip { background: var(--tdx-purple); box-shadow: 0 0 10px rgba(168, 85, 247, 0.55); }

.row--react { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: var(--tdx-space-20); }
.word { font: 700 var(--tdx-text-sm) var(--tdx-mono); letter-spacing: 0.1em; color: var(--tdx-ui); }
.row--react .desc { font-size: 13.5px; line-height: 1.75; color: var(--tdx-slate); }

/* ════════════════════════════════════════════════════════════════ fixes ═══
 * The answer is HERE. It used to be a row that linked to guide.html#trouble,
 * which made the commonest question on the page a navigation. */
.row--fix { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 14px; padding: 18px var(--tdx-space-20); }
.dot { flex: none; width: 8px; height: 8px; margin-top: 7px; border-radius: 50%; }
.dot--a { background: var(--tdx-amber);  box-shadow: 0 0 8px var(--tdx-amber); }
.dot--b { background: var(--tdx-ui);     box-shadow: 0 0 8px var(--tdx-ui); }
.dot--c { background: var(--tdx-purple); box-shadow: 0 0 8px var(--tdx-purple); }
.dot--d { background: var(--tdx-red);    box-shadow: 0 0 8px var(--tdx-red); }
.dot--e { background: var(--tdx-green-text); box-shadow: 0 0 8px var(--tdx-green-text); }
.row--fix .body { min-width: 0; display: grid; gap: 9px; }
.row--fix .q { font-size: var(--tdx-text-md); font-weight: 620; color: var(--tdx-white); }
.row--fix .a { font-size: 13.5px; line-height: 1.75; color: var(--tdx-white-2); }
.row--fix .a2 { font-size: var(--tdx-text-sm); line-height: 1.75; color: var(--tdx-slate); }

/* ═════════════════════════════════════════════════════════════════ flow ═══
 * Chrome paints → TradingView syncs → every other device views. The one idea
 * that covers both the phone and the desktop app. */
.flow { display: flex; align-items: center; gap: var(--tdx-space-12); flex-wrap: wrap; }
.flow__box {
  padding: 14px 18px; border-radius: 9px; text-align: center;
  background: rgba(var(--tdx-navy-rgb), 0.75); border: 1px solid var(--tdx-line);
}
.flow__box--lit { background: #12151b; border-color: var(--tdx-line-hi); }
.flow__box b { display: block; font-size: 13.5px; font-weight: 650; color: var(--tdx-white); }
.flow__box span { display: block; font-size: 11.5px; color: var(--tdx-slate); }
.flow__arrow { color: var(--tdx-slate-dim); font-size: 18px; }
.flow__ends { display: grid; gap: var(--tdx-space-8); flex: 1; min-width: 130px; }
.flow__end {
  padding: 9px 14px; border-radius: 9px; font-size: 13px; color: var(--tdx-white-dim);
  background: rgba(var(--tdx-navy-rgb), 0.75); border: 1px solid var(--tdx-line);
}
.dates { display: grid; gap: 5px; }
.dates span {
  padding: var(--tdx-space-6) 13px; border-radius: 6px;
  background: rgba(var(--tdx-navy-rgb), 0.75); border: 1px solid var(--tdx-line);
  font: var(--tdx-text-sm) var(--tdx-mono); color: var(--tdx-white-2);
}
.levels { display: grid; gap: 11px; flex: 1; min-width: 130px; }
.levels .bar { height: 3px; }

/* ══════════════════════════════════════════════════════════════ videos ═══ */
.vcard { display: block; border-radius: 14px; overflow: hidden; background: #0a0c10; border: 1px solid var(--tdx-line-soft); color: var(--tdx-white); }
.vcard:hover { border-color: var(--tdx-line-hi); color: var(--tdx-white); }
.vcard__shot {
  display: grid; place-items: center; aspect-ratio: 16/9;
  background: var(--tdx-navy); border-bottom: 1px solid var(--tdx-line-soft);
}
.play {
  width: 38px; height: 38px; border-radius: 50%; border: 1px solid #333a45;
  background: rgba(var(--tm-gold-rgb), 0.07); display: grid; place-items: center;
}
.play::after {
  content: ""; width: 0; height: 0; margin-left: 3px;
  border-left: 11px solid rgba(251, 205, 96, 0.72);
  border-top: 7px solid transparent; border-bottom: 7px solid transparent;
}
.vcard__meta { display: block; padding: 14px var(--tdx-space-16); }
.vcard__t { display: block; font-size: 14.5px; font-weight: 650; }
.vcard__s { display: block; margin-top: var(--tdx-space-4); font-size: 13px; line-height: 1.6; color: var(--tdx-slate); }

/* The walkthrough placeholder. Empty reads as "coming", not as broken. */
.frame {
  margin-top: var(--tdx-space-20); border-radius: 14px; overflow: hidden;
  border: 1px dashed #2b313b;
  background: repeating-linear-gradient(135deg, var(--tdx-panel) 0 12px, #0a1120 12px 24px);
  aspect-ratio: 16/7; display: grid; place-items: center;
}
.frame__note {
  font: 600 var(--tdx-text-xs) var(--tdx-mono); letter-spacing: 0.2em;
  color: var(--tdx-slate-dim); text-align: center; padding: 0 var(--tdx-space-20);
}

/* ═════════════════════════════════════════════════════════ dress / forms ═══ */
.pd { margin-top: var(--tdx-space-16); display: grid; gap: var(--tdx-space-16); }
.pd__row { display: flex; align-items: center; gap: var(--tdx-space-12); font-size: 13.5px; color: var(--tdx-white-2); flex-wrap: wrap; }
.pd__row--col { display: grid; gap: 7px; }
.pd__row > span:first-child { min-width: 88px; }
.pd label { margin: 0; }
.pd input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--tdx-ui); }
.pd :disabled { opacity: 0.55; }

select, textarea, input[type="email"], input[type="password"], input[type="text"] {
  font: 13px var(--tdx-font); color: var(--tdx-white);
  background: var(--tdx-navy); border: 1px solid var(--tdx-line);
  border-radius: var(--tdx-radius-sm); padding: 10px 12px;
}
textarea { resize: vertical; text-transform: uppercase; }
label { display: block; margin-top: 14px; font-size: var(--tdx-text-sm); color: var(--tdx-white-2); }
.acc__body input { width: 100%; margin-top: var(--tdx-space-6); background: #0a1426; font-size: 14px; }

/* Feedback sits with the button that causes it. The settings page once shipped a
   confirmation rendered at the bottom of a long scroll, correct and invisible. */
.msg { margin-top: var(--tdx-space-12); padding: 9px var(--tdx-space-12); border-radius: 9px; font-size: 14px; }
.msg[data-tone="ok"]  { background: rgba(var(--tdx-green-rgb), 0.1); border: 1px solid rgba(var(--tdx-green-rgb), 0.32); color: #86efac; }
.msg[data-tone="err"] { background: rgba(var(--tdx-red-rgb), 0.1);   border: 1px solid rgba(var(--tdx-red-rgb), 0.34);   color: #fca5a5; }

/* The account accordion. <details name> gives exclusive open/close natively, so
   there is no script to get wrong and a <summary> is keyboard-operable for free. */
.acc { margin-top: 26px; display: grid; gap: 1px; border-radius: 14px; overflow: hidden; background: var(--tdx-line-soft); border: 1px solid var(--tdx-line-soft); }
.acc details { background: var(--tdx-panel); }
.acc summary { display: flex; align-items: center; gap: 14px; padding: 17px var(--tdx-space-20); cursor: pointer; list-style: none; }
.acc summary::-webkit-details-marker { display: none; }
.acc__t { flex: 1; font-size: var(--tdx-text-md); font-weight: 640; }
.acc__t--danger { color: var(--tdx-red-text); }
.acc__meta { flex: none; font-size: 13px; color: var(--tdx-slate-dim); }
.acc__plus { flex: none; font-size: var(--tdx-text-md); color: var(--tdx-slate-dim); transition: transform var(--tdx-dur) var(--tdx-ease-out); }
.acc details[open] .acc__plus { transform: rotate(45deg); }
.acc__body { padding: 0 var(--tdx-space-20) var(--tdx-space-20); }
.acc__body > p:first-child { margin-top: 0; }

/* A disclosure inside a chapter, for the long tail nobody reads until they need
   it: the installer's five steps, the by-hand route. */
.more { margin-top: var(--tdx-space-16); padding: var(--tdx-space-16) 18px; border-radius: 14px; background: #0a0c10; border: 1px solid var(--tdx-line-soft); }
.more > summary { display: flex; align-items: center; gap: 10px; font-size: 13.5px; font-weight: 600; color: var(--tdx-white-dim); cursor: pointer; list-style: none; }
.more > summary::-webkit-details-marker { display: none; }
.more > summary::before { content: "+"; color: var(--tdx-slate-dim); }
.more[open] > summary::before { content: "\2013"; }
.more ol { margin: 14px 0 0; padding-left: var(--tdx-space-20); font-size: var(--tdx-text-sm); line-height: 1.85; color: var(--tdx-slate); }
.more p { margin: 14px 0 0; font-size: var(--tdx-text-sm); line-height: 1.8; color: var(--tdx-slate); }

/* ═══════════════════════════════════════════════════════════════ search ═══ */
.hit {
  display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: var(--tdx-space-16);
  width: 100%; text-align: left; padding: var(--tdx-space-16) 18px;
  border: 0; background: #0a0c10; cursor: pointer; font: inherit; color: inherit;
}
.hit:hover { background: var(--tdx-panel); }
.hit__where { justify-self: start; width: max-content; }
.hit__body { min-width: 0; display: grid; gap: 5px; }
.hit__k { font-size: 14px; font-weight: 640; color: var(--tdx-white); }
.hit__v { font-size: var(--tdx-text-sm); line-height: 1.65; color: var(--tdx-slate); }

/* ═══════════════════════════════════════════════════════════════ footer ═══ */
.pager {
  margin-top: 48px; padding-top: 22px; border-top: 1px solid var(--tdx-line-soft);
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
}
.pager__by { font-size: var(--tdx-text-sm); color: var(--vx-chrome-lo); flex: 1; min-width: 220px; }

/* The way out of a chapter. It takes the slot the "never an API key" line used to
 * hold, because a reader at the foot of a chapter wants somewhere to go more than
 * they want a reassurance they already read at the top. */
.pager__docs {
  flex: 1; min-width: 220px;
  display: inline-flex; align-items: center; gap: 9px;
  font-size: var(--tdx-text-sm); color: var(--tdx-slate); text-decoration: none;
}
.pager__docs:hover { color: var(--tdx-white); }
.pager__dot { flex: none; width: 5px; height: 5px; border-radius: 50%; background: var(--tdx-ui); }
.pager__arrow { color: var(--vx-chrome-lo); }
.pager__docs:hover .pager__arrow { color: var(--tdx-ui); }
.pager button { padding: 9px var(--tdx-space-16); border-radius: 9px; background: transparent; border: 1px solid var(--tdx-line); color: var(--tdx-slate); font: 600 var(--tdx-text-sm) var(--tdx-font); cursor: pointer; }
.pager button:hover { border-color: var(--tdx-line-hi); color: var(--tdx-white); }

/* ═══════════════════════════════════════════════════════════════ narrow ═══
 * The rail folds into a chip row above the content. Same collapse the old TOC
 * had, but it keeps the grouping and the numbers. */
@media (max-width: 900px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .rail { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--tdx-line-soft); }
  .rail__groups { display: flex; flex-wrap: wrap; gap: var(--tdx-space-12); }
  .rail__foot { margin-top: var(--tdx-space-12); }
  .doc { padding: var(--tdx-space-24) var(--tdx-space-20) var(--tdx-space-40); }
  .doc h2 { font-size: 25px; }
  .two, .row--kv, .row--colour, .row--react { grid-template-columns: minmax(0, 1fr); }
  .flow { flex-direction: column; align-items: stretch; }
  .flow__arrow { transform: rotate(90deg); }
  .crumbbar { padding: 0 var(--tdx-space-20); }
}

/* portal.js still emits .muted in a few places; it means what .fine means. */
.muted { font-size: var(--tdx-text-sm); color: var(--tdx-slate); }

/* ═══════════════════════════════════════════════════════════════ sign in ═══
 * The form that used to be /login.html, inside the signed-out state. */
.out .signin { max-width: 400px; }
.out .signin h1 { margin: 10px 0 6px; font-size: 26px; font-weight: 680; letter-spacing: -0.02em; }
.out .signin .sub { margin: 0 0 20px; color: var(--tdx-slate); font-size: 14.5px; }
.out .signin label { display: block; margin-top: 14px; font-size: 13px; color: var(--tdx-white-2); }
.out .signin input {
  width: 100%; margin-top: 6px; padding: 11px 13px; border-radius: 9px;
  border: 1px solid #22304e; background: #0a1426; color: var(--tdx-white); font-size: 15px;
}
.out .signin input:focus { outline: 2px solid rgba(var(--tm-gold-rgb), 0.5); outline-offset: 1px; }
.out .signin button[type="submit"] { width: 100%; margin-top: 20px; padding: 12px; font-size: 15px; }
.out .signin button:disabled { opacity: 0.6; cursor: default; }
.out .signin .alt { margin-top: 18px; text-align: center; font-size: 14px; color: var(--tdx-slate); }
.out .signin .alt a { color: var(--tdx-ui); }
/* The two explainer blocks. Same shell so neither reads as more official than
   the other, and toned gold rather than red: neither is a fault. */
.out .signin .panel {
  margin: 0 0 20px; padding: 13px 15px; border-radius: 10px;
  background: rgba(var(--tm-gold-rgb), 0.08); border: 1px solid rgba(var(--tm-gold-rgb), 0.26);
  font-size: 14px; line-height: 1.55;
}
.out .signin .panel p { margin: 0; }
.out .signin .panel p + p { margin-top: 9px; }
.out .signin .panel .fine { color: var(--tdx-slate); font-size: 13px; }
/* Google's button, in this page's clothes. White-on-dark rather than Google's
   own white pill, because a single foreign-looking control on a dark form reads
   as an embed from somewhere else. The mark stays exactly as Google draws it. */
.out .signin .gbtn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 20px; padding: 12px; border-radius: 10px;
  border: 1px solid var(--tdx-line-hi); background: #12151b;
  color: var(--tdx-white); font-size: 15px; font-weight: 600;
}
.out .signin .gbtn:hover { background: #1a1e26; border-color: #3a4a6b; color: var(--tdx-white); }
.out .signin .gbtn svg { flex: none; }
.out .signin .or {
  display: flex; align-items: center; gap: 12px;
  margin: 20px 0 4px; color: var(--tdx-slate-dim);
  font: 11px var(--tdx-mono); letter-spacing: 0.1em;
}
.out .signin .or::before, .out .signin .or::after { content: ""; flex: 1; height: 1px; background: var(--tdx-line-soft); }

/* ═════════════════════════════════════════════ the daily levels, lifted ═══
 * The levels chapter fetches /levels/<root>.html and adopts its <main>. That
 * page styles itself with bare element rules (table, h1, h2) and short class
 * names (.meta, .pill, .tag) this page also uses, so its stylesheet cannot be
 * linked here. These are the same rules, scoped. Keep in step with the <style>
 * block in tools/daily-levels.mjs.
 */
.levels-embed { margin-top: var(--tdx-space-16); }
.levels-embed .eyebrow { display: none; }
.levels-embed .sym-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.levels-embed h1 { font-size: 26px; line-height: 1.1; letter-spacing: -.02em; color: var(--tdx-white); margin: 0; }
.levels-embed .pill {
  font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  padding: 4px 12px; border-radius: 20px; border: 1px solid currentColor; white-space: nowrap;
}
.levels-embed .regime--pos { color: var(--tdx-green); }
.levels-embed .regime--neg { color: var(--tdx-red); }
.levels-embed .regime--unk { color: var(--tdx-slate); }
.levels-embed .meta { font-size: 13px; color: var(--tdx-slate-dim); margin: 8px 0 12px; display: flex; gap: 16px; flex-wrap: wrap; }
.levels-embed .meta strong { color: var(--tdx-white-dim); }
.levels-embed .proxy { font-size: 12.5px; color: var(--tdx-slate-dim); margin: 0 0 20px; }
.levels-embed .fixture-note {
  font-size: 13px; color: var(--tdx-amber); border: 1px solid var(--tdx-amber);
  border-radius: 6px; padding: 10px 14px; margin-bottom: 20px;
}
.levels-embed h2 {
  font-size: 15px; font-weight: 600; color: var(--tdx-white); margin: 28px 0 12px;
  border-top: 1px solid var(--tdx-line); padding-top: 22px;
}
.levels-embed .levels-wrap { overflow-x: auto; margin-bottom: 8px; }
.levels-embed table { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 420px; }
.levels-embed thead th {
  text-align: left; padding: 8px 12px; font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--tdx-slate-dim); border-bottom: 1px solid var(--tdx-line);
}
.levels-embed thead th.num { text-align: right; }
/* The page puts .num on its price cells; here .num is the numbered-step grid. */
.levels-embed th.num { display: table-cell; padding: 8px 12px; }
.levels-embed td.num { display: table-cell; padding: 10px 12px; }
.levels-embed tbody tr { border-bottom: 1px solid var(--tdx-line-soft); }
.levels-embed tbody td { padding: 10px 12px; }
.levels-embed td.num { text-align: right; font-variant-numeric: tabular-nums; color: var(--tdx-white-dim); }
.levels-embed td.dist { color: var(--tdx-slate); }
.levels-embed td.dist.up { color: var(--tdx-red); }
.levels-embed td.dist.down { color: var(--tdx-green); }
.levels-embed .lvl { font-weight: 600; color: var(--tdx-white); }
.levels-embed .lvl--callWall, .levels-embed .lvl--putWall, .levels-embed .lvl--maxPain { color: var(--tdx-white-dim); }
.levels-embed .lvl--flip { color: var(--tdx-purple); }
.levels-embed .lvl--focus1 { color: var(--tdx-amber); }
.levels-embed .tag {
  font-size: 10px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--tdx-slate-dim); border: 1px solid var(--tdx-line); border-radius: 4px;
  padding: 1px 6px; vertical-align: middle; margin-left: 8px;
}
.levels-embed .sentences { list-style: none; padding: 0; margin: 0 0 8px; }
.levels-embed .sentences li {
  display: grid; grid-template-columns: 130px 1fr; gap: 8px 16px; padding: 10px 0;
  border-bottom: 1px solid var(--tdx-line-soft); font-size: 14px;
}
.levels-embed .sentences li:last-child { border-bottom: none; }
.levels-embed .sent-label { font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--tdx-slate-dim); padding-top: 2px; }
.levels-embed .sent-body { color: var(--tdx-white-dim); line-height: 1.55; }
.levels-embed .disclaimer { margin-top: 16px; font-size: 12px; color: var(--tdx-slate-dim); }
