/* =============================================================
   TinyCorp Signal — shared stylesheet
   Single file. No build step. Tokens → base → components → utils.
   ============================================================= */

/* -------------------- TOKENS -------------------- */
:root {
  --bg:        #0c0e14;
  --bg-2:      #0a0c12;
  --surface:   #13151f;
  --surface-2: #1a1d2a;
  --surface-3: #20243a;
  --border:    #252937;
  --border-2:  #2f3447;
  --text:      #e8ecf3;
  --text-dim:  #8b94a8;
  --text-mute: #8990a0;
  /* --text-faint was referenced by 20 base.html templates but never defined here,
     which made each whole `color:` declaration invalid and silently dropped it.
     Defined 2026-09-04 at a value that clears 4.5:1 on every ground in use. */
  --text-faint: #868e9d;
  /* Aliases from the standalone-page palette. 22 base.html templates use these
     with no fallback; undefined, the whole declaration is invalid and the styling
     is silently dropped - the same fault --text-faint had. Values are the ones the
     55 standalone pages already define, mapped onto this sheet's own tokens.
     Contrast measured 2026-09-04: --teal-2 13.04:1 and --teal 7.66:1 on --bg. */
  --teal:    #0fb5ba;
  --teal-2:  #5eead4;
  --line:    #252937;
  --r-md:    10px;
  --text-2:  #8b94a8;
  --accent:    #0fb5ba;
  --accent-2:  #f59e0b;
  --good:      #22c55e;
  --warn:      #eab308;
  --bad:       #ef4444;

  /* derived (used by chart rails, focus rings, etc.) */
  --accent-soft:   rgba(15, 181, 186, 0.12);
  --accent-stroke: rgba(15, 181, 186, 0.35);
  --good-soft:     rgba(34, 197, 94, 0.14);
  --warn-soft:     rgba(234, 179, 8, 0.14);
  --bad-soft:      rgba(239, 68, 68, 0.14);
  --shadow-lg: 0 18px 50px rgba(0, 0, 0, 0.55);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.35);

  /* spacing 4-base */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;

  --r-tag: 4px; --r-btn: 6px; --r-card: 8px; --r-panel: 10px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --t-fast: 120ms;
  --t-base: 180ms;
  --t-slow: 280ms;

  --container: 1280px;
}

/* -------- light theme (delightful secondary) -------- */
body.light {
  --bg:        #f7f8fa;
  --bg-2:      #eef0f5;
  --surface:   #ffffff;
  --surface-2: #f1f3f8;
  --surface-3: #e6e9f1;
  --border:    #d8dde6;
  --border-2:  #c3c9d4;
  --text:      #14161e;
  --text-dim:  #5a6276;
  --text-mute: #5f667a;
  --text-faint: #62697c;
  --teal:    #086b6f;   /* 2026-09-19 (U): was #0a8a8e = 3.9:1 as link text on the light --bg; now 5.9:1 */
  --teal-2:  #0a7276;
  --line:    #d8dde6;
  --r-md:    10px;
  --text-2:  #5a6276;
  --accent:    #086b6f;  /* 2026-09-19 (U): was #0a8a8e - 3.9:1 as a link, 4.2:1 under the white .btn-primary label; now 5.9:1 / 6.3:1 */
  --accent-2:  #c2740b;
  --good:      #15803d;
  --warn:      #854d0e;  /* 2026-09-19 (U): was #a16207 = 4.3:1 on --surface-2; now 5.4:1 */
  --bad:       #b91c1c;
  --accent-soft:   rgba(10, 138, 142, 0.10);
  --accent-stroke: rgba(10, 138, 142, 0.40);
  --good-soft:     rgba(21, 128, 61, 0.10);
  --warn-soft:     rgba(161, 98, 7, 0.12);
  --bad-soft:      rgba(185, 28, 28, 0.10);
  --shadow-lg: 0 18px 50px rgba(20, 26, 40, 0.10);
  --shadow-md: 0 8px 24px rgba(20, 26, 40, 0.06);
}

/* -------------------- BASE -------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  overflow-x: clip;     /* wide content scrolls in its own box, never the page.
                         clip, not hidden: hidden makes body a scroll container
                         and breaks the sticky .data-table th below. */
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'ss01', 'cv11';
}

/* every number-bearing element opt-in via .num or .mono */
.num, .mono, table, .ticker, .timestamp,
[data-num], input[type="number"] { font-variant-numeric: tabular-nums; }
.mono { font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace; }

h1, h2, h3, h4 {
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 var(--s3);
  line-height: 1.2;
  color: var(--text);
}
h1 { font-size: 32px; letter-spacing: -0.025em; line-height: 1.1; }
h2 { font-size: 22px; }
h3 { font-size: 17px; }
h4 { font-size: 17px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-dim); font-weight: 700; }
p  { margin: 0 0 var(--s3); color: var(--text-dim); }

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}
a:hover { color: var(--text); }

hr { border: none; border-top: 1px solid var(--border); margin: var(--s6) 0; }

::selection { background: var(--accent-soft); color: var(--text); }

/* focus */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* -------- container/grid -------- */
.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--s5); }
.container-wide { max-width: 1440px; margin: 0 auto; padding: 0 var(--s5); }

/* -------------------- NAV -------------------- */
.site-nav {
  position: sticky; top: 0; z-index: 50;
  height: 56px;
  background: rgba(12, 14, 20, 0.85);
  backdrop-filter: blur(10px) saturate(120%);
  border-bottom: 1px solid var(--border);
}
body.light .site-nav { background: rgba(247, 248, 250, 0.85); }
.site-nav-inner {
  height: 100%;
  display: flex;
  align-items: center;
  gap: var(--s5);
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--s5);
}
.brand {
  display: flex; align-items: center; gap: var(--s2);
  color: var(--text); font-weight: 700; font-size: 17px;
  letter-spacing: -0.01em;
  text-decoration: none;
}
.brand .glyph {
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--accent);
}
.brand .glyph::before {
  content: "";
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
}
.brand-mark { color: var(--text); }
.brand-mark .signal { color: var(--text-dim); font-weight: 500; }

.site-nav-links { display: flex; gap: var(--s1); margin-left: var(--s4); flex: 1; }
.site-nav-links a {
  padding: 6px 12px;
  border-radius: var(--r-btn);
  color: var(--text-dim);
  font-size: 17px;
  font-weight: 500;
}
.site-nav-links a:hover { color: var(--text); background: var(--surface); }
.site-nav-links a.active { color: var(--accent); background: var(--accent-soft); }

.site-nav-actions { display: flex; align-items: center; gap: var(--s2); }
.theme-toggle {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-btn);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.theme-toggle:hover { color: var(--text); background: var(--surface); }
.theme-toggle svg { width: 16px; height: 16px; }
.theme-toggle .sun { display: none; }
body.light .theme-toggle .sun { display: inline; }
body.light .theme-toggle .moon { display: none; }

/* mobile menu — hidden by default */
.nav-mobile-toggle { display: none; }

/* -------------------- BUTTONS -------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  height: 36px;
  padding: 0 var(--s4);
  border-radius: var(--r-btn);
  font-size: 17px;
  font-weight: 600;
  font-family: inherit;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
  text-decoration: none;
  letter-spacing: -0.005em;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-2); border-color: var(--border-2); color: var(--text); }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn.is-disabled {
  opacity: 0.5; cursor: not-allowed; pointer-events: none;
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #06222a;
}
body.light .btn-primary { color: #ffffff; }
.btn-primary:hover {
  background: #18c8cd;
  border-color: #18c8cd;
  color: #06222a;
}
body.light .btn-primary:hover { background: #0a7276; border-color: #0a7276; color: #ffffff; }  /* 2026-09-19 (U): was #0b9ea3, 3.3:1 under white */

.btn-ghost {
  background: transparent;
  border-color: var(--border-2);
  color: var(--text);
}
.btn-ghost:hover { background: var(--surface); color: var(--text); }

.btn-link {
  background: transparent;
  border-color: transparent;
  color: var(--accent);
  padding-left: 0; padding-right: 0;
  height: auto;
}
.btn-link:hover { color: var(--text); background: transparent; }

.btn-sm { height: 36px; padding: 0 12px; font-size: 17px; }
.btn-lg { height: 44px; padding: 0 var(--s5); font-size: 17px; }
.btn-block { width: 100%; }
.btn .arrow { transition: transform var(--t-fast) var(--ease); }
.btn:hover .arrow { transform: translateX(2px); }

/* -------------------- CARDS -------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: var(--s5);
}
.card-elev { background: var(--surface-2); }
.card-flat { border: 1px solid var(--border); border-radius: var(--r-card); padding: var(--s5); background: transparent; }
.card-tight { padding: var(--s4); }
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  margin-bottom: var(--s4);
}
.card-head h4 { margin: 0; }
.card-head .head-actions { display: flex; gap: var(--s2); align-items: center; }

/* -------------------- INPUTS -------------------- */
.input,
input[type="text"],
input[type="email"],
input[type="search"],
input[type="number"],
select,
textarea {
  font-family: inherit;
  font-size: 17px;
  height: 40px;
  padding: 0 var(--s3);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--r-btn);
  color: var(--text);
  width: 100%;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
textarea { height: auto; min-height: 84px; padding: 10px var(--s3); line-height: 1.5; resize: vertical; }
.input:focus, input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
}
.input::placeholder, input::placeholder, textarea::placeholder { color: var(--text-mute); }
select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%238b94a8' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 28px;
}

.field { display: flex; flex-direction: column; gap: 6px; }
.field-label {
  font-size: 17px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-mute);
}
.field-help { font-size: 17px; color: var(--text-mute); margin-top: 4px; }

/* checkbox */
.check {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  cursor: pointer;
  font-size: 17px;
  color: var(--text);
  user-select: none;
  padding: 4px 0;
}
.check input { position: absolute; opacity: 0; pointer-events: none; }
.check .box {
  width: 16px; height: 16px;
  border-radius: 4px;
  border: 1.5px solid var(--border-2);
  background: var(--bg-2);
  flex-shrink: 0;
  position: relative;
  transition: all var(--t-fast) var(--ease);
}
.check input:checked + .box {
  background: var(--accent);
  border-color: var(--accent);
}
.check input:checked + .box::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2.5 6l2.5 2.5 4.5-5' stroke='%23061a1c' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-position: center;
  background-repeat: no-repeat;
}
.check:hover .box { border-color: var(--accent); }

/* radio (segmented control style) */
.seg {
  display: inline-flex;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-btn);
  gap: 2px;
}
.seg button, .seg label {
  height: 28px;
  padding: 0 var(--s3);
  border-radius: 4px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  font-size: 17px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit;
  transition: all var(--t-fast) var(--ease);
}
.seg button:hover { color: var(--text); }
.seg button.is-on, .seg label.is-on {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-stroke);
}
.seg input { display: none; }

/* range */
input[type="range"] {
  width: 100%; height: 4px; background: var(--surface-2);
  border-radius: 2px; appearance: none; padding: 0; margin: 8px 0;
}
input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  cursor: pointer;
}

/* -------------------- TAGS -------------------- */
.tag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 17px; font-weight: 700;
  letter-spacing: 0.04em;
  padding: 3px 7px;
  border-radius: var(--r-tag);
  background: var(--surface-2);
  color: var(--text-dim);
  border: 1px solid var(--border);
  font-family: 'JetBrains Mono', monospace;
}
.tag-aplus { background: var(--good-soft); color: var(--good); border-color: rgba(34,197,94,0.3); }
.tag-a     { background: rgba(22,163,74,0.12); color: #16a34a; border-color: rgba(22,163,74,0.3); }
.tag-b     { background: var(--warn-soft); color: var(--warn); border-color: rgba(234,179,8,0.3); }
.tag-warn  { background: var(--warn-soft); color: var(--warn); border-color: rgba(234,179,8,0.3); }
.tag-bad   { background: var(--bad-soft); color: var(--bad); border-color: rgba(239,68,68,0.3); }
.tag-accent { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-stroke); }
.tag-pro    { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-stroke); }
.tag-live   { background: rgba(34,197,94,0.12); color: var(--good); border-color: rgba(34,197,94,0.3); }
.tag-live::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--good); box-shadow: 0 0 6px var(--good);
  animation: pulse-pip 1.6s ease-in-out infinite;
}
@keyframes pulse-pip { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }

/* -------------------- TABLES -------------------- */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.data-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 17px;
}
.data-table th, .data-table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.data-table th {
  position: sticky; top: 0;
  background: var(--surface);
  font-size: 17px;
  font-weight: 600;
  color: var(--text-mute);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--border);
  user-select: none;
  z-index: 1;
}
.data-table th.sortable { cursor: pointer; }
.data-table th.sortable:hover { color: var(--text); }
.data-table th .sort-arrow { opacity: 0; margin-left: 4px; }
.data-table th.is-sorted .sort-arrow { opacity: 1; color: var(--accent); }
.data-table tbody tr { transition: background var(--t-fast) var(--ease); }
.data-table tbody tr:hover { background: var(--surface); cursor: pointer; }
.data-table tbody tr:hover td { color: var(--text); }
.data-table .num, .data-table .ticker { font-variant-numeric: tabular-nums; }
.data-table .ticker { font-family: 'JetBrains Mono', monospace; font-weight: 600; color: var(--text); font-size: 17px; }
.data-table .right { text-align: right; }
.data-table .center { text-align: center; }
.data-table .delta-pos { color: var(--good); }
.data-table .delta-neg { color: var(--bad); }
.data-table .col-fav { width: 32px; text-align: center; }

.fav-star {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent;
  color: var(--text-mute); cursor: pointer;
  transition: color var(--t-fast) var(--ease);
}
.fav-star:hover { color: var(--accent-2); }
.fav-star.is-on { color: var(--accent-2); }
.fav-star svg { width: 14px; height: 14px; }

/* skeleton row */
.skel { background: linear-gradient(90deg, var(--surface) 25%, var(--surface-2) 50%, var(--surface) 75%);
  background-size: 200% 100%; animation: skel-shimmer 1.4s linear infinite; border-radius: 4px; height: 12px; }
@keyframes skel-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* -------------------- MODAL -------------------- */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(5, 6, 12, 0.7);
  backdrop-filter: blur(4px);
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--s5);
}
body.light .modal-backdrop { background: rgba(20, 26, 40, 0.4); }
.modal-backdrop.is-open { display: flex; animation: bd-in 180ms var(--ease); }
@keyframes bd-in { from { opacity: 0; } to { opacity: 1; } }
.modal {
  width: 100%;
  max-width: 620px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--r-panel);
  box-shadow: var(--shadow-lg);
  animation: m-in 220ms var(--ease);
}
@keyframes m-in { from { transform: translateY(12px) scale(0.98); opacity: 0; } to { transform: translateY(0) scale(1); opacity: 1; } }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3);
  padding: var(--s5);
  border-bottom: 1px solid var(--border);
}
.modal-head h3 { margin: 0; font-size: 17px; }
.modal-body { padding: var(--s5); }
.modal-close {
  width: 32px; height: 32px;
  border-radius: var(--r-btn);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  font-size: 18px;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.modal-close:hover { background: var(--surface-2); color: var(--text); }

/* -------------------- TOAST -------------------- */
.toast-host { position: fixed; right: 20px; bottom: 20px; z-index: 300; display: flex; flex-direction: column; gap: 8px; }
.toast {
  background: var(--surface-2);
  border: 1px solid var(--border-2);
  border-left: 3px solid var(--accent);
  padding: 10px 14px;
  border-radius: var(--r-btn);
  font-size: 17px;
  color: var(--text);
  box-shadow: var(--shadow-md);
  animation: t-in 180ms var(--ease);
  max-width: 360px;
}
@keyframes t-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* -------------------- BANNERS / CALLOUTS -------------------- */
.banner {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: 14px var(--s5);
  background: var(--accent-soft);
  border: 1px solid var(--accent-stroke);
  border-radius: var(--r-card);
  color: var(--text);
  font-size: 17px;
}
.banner-warn { background: var(--warn-soft); border-color: rgba(234,179,8,0.35); }
.banner .banner-actions { display: flex; gap: var(--s2); align-items: center; }
.banner-dismiss {
  background: transparent; border: none; color: var(--text-dim); cursor: pointer;
  font-size: 17px; padding: 0 4px;
}

/* -------------------- FOOTER -------------------- */
.site-footer {
  margin-top: var(--s8);
  border-top: 1px solid var(--border);
  background: var(--bg-2);
  padding: var(--s6) 0 var(--s5);
}
.site-footer-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--s5);
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
  gap: var(--s7);
}
.site-footer-brand { color: var(--text); font-weight: 600; margin-bottom: var(--s3); display: flex; align-items: center; gap: 8px; }
.site-footer-brand .glyph::before {
  content: "";
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.site-footer h5 {
  font-size: 17px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-mute);
  margin: 0 0 var(--s3);
  font-weight: 700;
}
.site-footer ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.site-footer ul a { color: var(--text-dim); font-size: 17px; }
.site-footer ul a:hover { color: var(--text); }
.disclaimer {
  margin-top: var(--s6);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
  font-size: 17px;
  line-height: 1.65;
  color: var(--text-dim);
  max-width: 920px;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  padding-left: var(--s5);
  padding-right: var(--s5);
}

/* -------------------- PAGE CHROME -------------------- */
.page-head {
  padding: var(--s7) 0 var(--s5);
  border-bottom: 1px solid var(--border);
}
.page-head-inner {
  display: flex; justify-content: space-between; align-items: flex-end; gap: var(--s5);
}
.page-head h1 { margin: 0 0 var(--s2); }
.page-head .lede { color: var(--text-dim); max-width: 720px; margin: 0; font-size: 17px; }
.page-section { padding: var(--s6) 0; }

/* eyebrow */
.eyebrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 17px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-mute);
}
.eyebrow .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }

/* -------------------- AUTH SHELL -------------------- */
.auth-shell {
  min-height: calc(100vh - 56px);
  display: flex; align-items: center; justify-content: center;
  padding: var(--s5);
  background:
    radial-gradient(ellipse at top right, rgba(15,181,186,0.06), transparent 50%),
    radial-gradient(ellipse at bottom left, rgba(245,158,11,0.04), transparent 45%),
    var(--bg);
}
.auth-card {
  width: 100%;
  max-width: 420px;
  padding: var(--s6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-panel);
  box-shadow: var(--shadow-md);
}
.auth-card h1 { font-size: 22px; margin-bottom: var(--s2); }
.auth-card .lede { color: var(--text-dim); margin-bottom: var(--s5); font-size: 17px; }
.auth-card .auth-foot {
  margin-top: var(--s5);
  padding-top: var(--s5);
  border-top: 1px solid var(--border);
  font-size: 17px;
  color: var(--text-mute);
  line-height: 1.65;
}

/* -------------------- KEYBOARD HINT -------------------- */
kbd {
  font-family: 'JetBrains Mono', monospace;
  font-size: 17px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 2px 5px;
  color: var(--text-dim);
}

/* -------------------- UTILS -------------------- */
.row { display: flex; gap: var(--s3); align-items: center; }
.col { display: flex; flex-direction: column; gap: var(--s3); }
.spread { display: flex; justify-content: space-between; align-items: center; gap: var(--s3); }
.muted { color: var(--text-dim); }
.dim   { color: var(--text-mute); }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.hidden { display: none !important; }
.no-scroll { overflow: hidden; }
.text-good { color: var(--good); }
.text-warn { color: var(--warn); }
.text-bad  { color: var(--bad); }
.text-accent { color: var(--accent); }

.mt-1{margin-top:var(--s1)} .mt-2{margin-top:var(--s2)} .mt-3{margin-top:var(--s3)}
.mt-4{margin-top:var(--s4)} .mt-5{margin-top:var(--s5)} .mt-6{margin-top:var(--s6)}
.mt-7{margin-top:var(--s7)} .mt-8{margin-top:var(--s8)}
.mb-1{margin-bottom:var(--s1)} .mb-2{margin-bottom:var(--s2)} .mb-3{margin-bottom:var(--s3)}
.mb-4{margin-bottom:var(--s4)} .mb-5{margin-bottom:var(--s5)} .mb-6{margin-bottom:var(--s6)}
.gap-1{gap:var(--s1)} .gap-2{gap:var(--s2)} .gap-3{gap:var(--s3)}
.gap-4{gap:var(--s4)} .gap-5{gap:var(--s5)} .gap-6{gap:var(--s6)}

/* -------------------- RESPONSIVE -------------------- */
@media (max-width: 1024px) {
  .site-footer-inner { grid-template-columns: 1fr 1fr; gap: var(--s5); }
}
@media (max-width: 767px) {
  /* a heading may step down for line-breaking; body copy never does */
  h1 { font-size: 28px; }
  .site-nav-links { display: none; }
  .nav-mobile-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px;
    background: transparent; border: 1px solid var(--border);
    border-radius: var(--r-btn); color: var(--text-dim); cursor: pointer;
  }
  .container, .container-wide { padding: 0 var(--s4); }
  .site-footer-inner { grid-template-columns: 1fr; gap: var(--s5); }
  .page-head-inner { flex-direction: column; align-items: flex-start; }
}

/* -------------------- REDUCED MOTION -------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─────────────────────────────────────────────────────────────────────────────
   TYPE FLOOR — 17px minimum, at EVERY width (the 1024px ceiling came off 2026-09-19).

   2026-09-04/05: the first a11y pass put the whole floor inside
   `@media (max-width:560px)`. That is a PHONE query, so everything it fixed
   reverted the moment the viewport hit 561px: an iPad in portrait (768), a phone
   in landscape, an unfolded Fold and a half-width desktop window all dropped back
   to the 13-15px desktop component sizes. Measured 2026-09-05 at 768px: 575
   text elements under 17px on /leaderboard, 109 on /, smallest 13px.

   The floor is therefore split in two:

     ≤1024px  THE FLOOR (this block). Nothing below 17px. It reuses the exact
              values the 560px pass already proved out, so nothing new is being
              guessed at - only the width at which they stop applying changed.
     ≤560px   THE PHONE BUMP (block after this one). Phones get MORE than the
              floor - 18px body, 18-20px on the few things a thumb has to hit.

   Chosen over a fluid clamp() base because the base already sets
   `body{font-size:17px}`: the offenders are ~30 components with a hard-coded
   13-16px, and clamp() on the root does not reach a child that declares its own
   px size. The same ~30 rules would need editing either way, so this way keeps
   integer, already-verified sizes.

   (2026-09-19: no longer true - the block is unconditional now.) It WAS: above 1024px nothing here applied and the desktop layout was byte-for-byte
   what it was.

   Two rules here are more than typography:
     - form controls under 16px make iOS zoom the whole page on focus, on iPad
       exactly as on iPhone;
     - .btn-sm's 28px box cannot hold a 17px word, so the box grows with the
       label (to 36px, which is also .btn's height, so mixed rows still align).
   ───────────────────────────────────────────────────────────────────────────── */
@media all{
  h4{font-size:17px}
  .brand{font-size:17px}
  .site-nav-links a{font-size:17px}
  .btn{font-size:17px}
  .btn-sm{font-size:17px;height:36px;padding:0 12px}
  .btn-lg{font-size:17px}
  /* >=17px here also stops iOS auto-zooming the page when a field takes focus. */
  .input, input[type="text"], input[type="email"], input[type="search"], input[type="number"], select, textarea{font-size:17px;height:40px}
  textarea{height:auto}
  .field-label{font-size:17px}
  .field-help{font-size:17px}
  .check{font-size:17px}
  .seg button, .seg label{font-size:17px}
  .tag{font-size:17px}
  .data-table{font-size:17px}
  .data-table th{font-size:17px}
  .data-table .ticker{font-size:17px}
  .modal-head h3{font-size:17px}
  .modal-close{font-size:18px}
  .toast{font-size:17px}
  .banner{font-size:17px}
  .banner-dismiss{font-size:17px}
  .site-footer h5{font-size:17px}
  .site-footer ul a{font-size:17px}
  .disclaimer{font-size:17px}
  .page-head .lede{font-size:17px}
  .eyebrow{font-size:17px}
  .auth-card .lede{font-size:17px}
  .auth-card .auth-foot{font-size:17px}
  kbd{font-size:17px}
  /* wide content scrolls in its own box so a 17px table cannot push the page */
  .table-wrap, .data-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* INLINE style="font-size:..." - 575 of them across the templates. No
     stylesheet rule beats an inline declaration, which is why the 2026-09-04
     phone pass missed these at 390px as well as at 768px. Matching the
     attribute's own text needs no HTML edit and also catches the ones
     JavaScript writes at runtime. Half-pixel steps: starters.js writes
     font-size:11.5px, and a whole-pixel list walked straight past 32 of them. */
  [style*="font-size:8px"],[style*="font-size: 8px"],
  [style*="font-size:8.5px"],[style*="font-size: 8.5px"],
  [style*="font-size:9px"],[style*="font-size: 9px"],
  [style*="font-size:9.5px"],[style*="font-size: 9.5px"],
  [style*="font-size:10px"],[style*="font-size: 10px"],
  [style*="font-size:10.5px"],[style*="font-size: 10.5px"],
  [style*="font-size:11px"],[style*="font-size: 11px"],
  [style*="font-size:11.5px"],[style*="font-size: 11.5px"],
  [style*="font-size:12px"],[style*="font-size: 12px"],
  [style*="font-size:12.5px"],[style*="font-size: 12.5px"],
  [style*="font-size:13px"],[style*="font-size: 13px"],
  [style*="font-size:13.5px"],[style*="font-size: 13.5px"],
  [style*="font-size:14px"],[style*="font-size: 14px"],
  [style*="font-size:14.5px"],[style*="font-size: 14.5px"],
  [style*="font-size:15px"],[style*="font-size: 15px"],
  [style*="font-size:15.5px"],[style*="font-size: 15.5px"],
  [style*="font-size:16px"],[style*="font-size: 16px"],
  [style*="font-size:16.5px"],[style*="font-size: 16.5px"]{font-size:17px !important}

  /* The `font:` SHORTHAND in a style attribute sets the size just as surely as
     font-size: does, and the match above cannot see it - /marketplace's "Your
     strategy" badge and 36 chips on /signals were hiding exactly here. Both
     spellings, because a style JavaScript assigns through .style.cssText comes
     back normalised with a space after the colon. */
  [style*="font: 13px"],
  [style*="font: 14px"],
  [style*="font: 15px"],
  [style*="font: 400 13px"],
  [style*="font: 500 12.5px"],
  [style*="font: 500 12px"],
  [style*="font: 500 13px"],
  [style*="font: 500 14px"],
  [style*="font: 500 15px"],
  [style*="font: 600 11px"],
  [style*="font: 600 12.5px"],
  [style*="font: 600 12px"],
  [style*="font: 600 13px"],
  [style*="font: 600 14px"],
  [style*="font: 600 15px"],
  [style*="font: 600 16px"],
  [style*="font: 700 13px"],
  [style*="font: 700 14px"],
  [style*="font: 700 15px"],
  [style*="font: 700 16px"],
  [style*="font: 700 9.5px"],
  [style*="font: 800 15px"],
  [style*="font:13px"],
  [style*="font:14px"],
  [style*="font:15px"],
  [style*="font:400 13px"],
  [style*="font:500 12.5px"],
  [style*="font:500 12px"],
  [style*="font:500 13px"],
  [style*="font:500 14px"],
  [style*="font:500 15px"],
  [style*="font:600 11px"],
  [style*="font:600 12.5px"],
  [style*="font:600 12px"],
  [style*="font:600 13px"],
  [style*="font:600 14px"],
  [style*="font:600 15px"],
  [style*="font:600 16px"],
  [style*="font:700 13px"],
  [style*="font:700 14px"],
  [style*="font:700 15px"],
  [style*="font:700 16px"],
  [style*="font:700 9.5px"],
  [style*="font:800 15px"]{font-size:17px !important}

  /* A control with no declared size renders at the UA default (13.3px in
     Chrome) and makes iOS zoom the page on focus. Type selectors, so any page
     rule still wins - and page rules under 17px are floored above. */
  input,select,textarea,button,optgroup,option{font-size:17px}
}

/* THE PHONE BUMP - a phone gets more than the floor, not the same as it. */
@media (max-width:560px){
  body{font-size:18px}
  h3{font-size:18px}
  .brand{font-size:18px}
  .btn-lg{font-size:18px}
  .input, input[type="text"], input[type="email"], input[type="search"], input[type="number"], select, textarea{height:42px}
  textarea{height:auto}
  .modal-head h3{font-size:19px}
  .modal-close{font-size:20px}
  .banner-dismiss{font-size:19px}
}

/* ─────────────────────────────────────────────────────────────────────────────
   NAV — the marketing bar (System B, .site-nav-links) becomes the drawer at
   ≤980px, not ≤767px.

   Why: mobile-nav.js rebuilds BOTH navs from one config, and its drawer rules
   (`.nav-drop{position:static;display:flex}`) fire at ≤980px for both. Between
   768 and 980 the marketing bar was still `display:flex` - so every dropdown
   unfolded INLINE inside the bar. Measured on /about at 768px: .site-nav-links
   was 1303px wide inside a 767px viewport and documentElement.scrollWidth read
   1748. 980 here matches the 980 mobile-nav.js already uses, so the two halves
   of the same nav now change mode at the same width.

   The drawer geometry is restated here rather than in mobile-nav.js on purpose:
   tinycorp.css is loaded ONLY by the base.html pages that own .site-nav-links,
   and mobile-nav.js is referenced with eight different ?v= stamps across 120+
   call sites - changing it would have left most of them serving a stale copy.
   mobile-nav.js still declares the same geometry at ≤767px; the two agree.
   ───────────────────────────────────────────────────────────────────────────── */
@media (max-width: 980px) {
  .site-nav-inner { position: relative; flex-wrap: wrap; }
  .site-nav-links {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 0 0 10px 10px;
    padding: 8px 12px 12px; gap: 2px; margin-left: 0;
    box-shadow: 0 14px 28px rgba(0,0,0,.35);
    z-index: 60; max-height: 80vh; overflow: auto;
  }
  .site-nav-links.mnav-open { display: flex !important; }
  .site-nav-links a { padding: 12px; border-radius: 8px; width: 100%; font-size: 17px; }
  .nav-mobile-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px;
    background: transparent; border: 1px solid var(--border);
    border-radius: var(--r-btn); color: var(--text-dim); cursor: pointer;
  }
}

/* ---- runtime-injected classes -------------------------------------------
   static/starters.js, builder-signals.js, live-backtest.js, js/hot.js and
   js/dashboard.js build a stylesheet as a JavaScript string and append it to
   the document head after load, at 9.5-15px. Those classes are in no template,
   so nothing that reads the HTML can find them: /builder was 299 elements under
   the floor for exactly this reason, and builder_v2.html, onboarding.html and
   starters.html have no style element of their own to carry a page floor.

   !important because the injected sheet lands after this file in the cascade.
   One rule each: an invalid selector inside a comma list takes the whole list
   down with it. Only sizes measured under 17px are listed.
   ------------------------------------------------------------------------- */
@media all{
  .add-sig{font-size:17px !important}
  .cat-pill{font-size:17px !important}
  .lbt-chip .ck{font-size:17px !important}
  .lbt-chip .cv{font-size:17px !important}
  .lbt-clab{font-size:17px !important}
  .lbt-clab .win{font-size:17px !important}
  .lbt-ctx{font-size:17px !important}
  .lbt-msg{font-size:17px !important}
  .lbt-note{font-size:17px !important}
  .nav-cat-btn .caret{font-size:17px !important}
  .sbadd-btn{font-size:17px !important}
  .sbadd-caret{font-size:17px !important}
  .sbadd-opt{font-size:17px !important}
  .sbk .kl{font-size:17px !important}
  .sbk-h{font-size:17px !important}
  .sbsig-eng{font-size:17px !important}
  .sbsig-fields label{font-size:17px !important}
  .sbsig-fields select{font-size:17px !important}
  .sbsig-h{font-size:17px !important}
  .sbsig-top b{font-size:17px !important}
  .sig-input{font-size:17px !important}
  .st-card .st-blurb{font-size:17px !important}
  .st-card .st-btn{font-size:17px !important}
  .st-card .st-eng{font-size:17px !important}
  .st-card .st-next{font-size:17px !important}
  .st-card .st-nm{font-size:17px !important}
  .st-card .st-side{font-size:17px !important}
}

/* ─────────────────────────────────────────────────────────────────────────────
   2026-09-19 (Worker U): THE CEILING CAME OFF.
   Dave's rule is 17px everywhere and 4.5:1 everywhere; the floor above stopped
   at 1024px, so a 1280px desktop render measured /dictionary 187, /methodology
   193, /options/build 236 elements under 17px while every phone measured 0.
   The two `@media all{` blocks were `@media (max-width:1024px){`; the base
   component sizes above were raised to 17px so the file says what it does.

   Below: a generic net for base.html pages that carry NO page floor of their
   own (about, billing, the nine guides, starters, onboarding, verify ...).
   `max(1em, 17px)` means "inherit, but never below 17px" - it can only ever
   make text LARGER, never smaller, so it is safe on a tag selector. The `html`
   prefix out-ranks a bare tag rule in a page's own <style>; a page CLASS rule
   still wins, and those are floored by the page's own block where it has one.
   ───────────────────────────────────────────────────────────────────────────── */
html td, html th, html small, html code, html kbd, html label, html dd, html dt,
html figcaption, html caption, html li, html p, html summary, html legend,
html strong, html em, html b, html i, html a, html time, html abbr, html cite,
html span:not([class]) { font-size: max(1em, 17px); }

/* 2026-09-19 (U): the light theme is the one place the nav script's hard-coded dark palette shows through:
   the Lab link stayed lavender #d8b4fe on a near-white bar = 1.7:1. Light gets a dark purple (6.7:1). The
   Graveyard's loss-red #ff8a8a on light ground was 2.0:1; same fix, same reason (not the .pill.dead badge - it keeps its dark ground). */
body.light .nav-link.mnav-lab { color: #6d28d9; }
body.light .nav-link.mnav-lab:hover { color: #4c1d95; background: rgba(109,40,217,.10); }
body.light .stats .st.red b, body.light .neg { color: #b91c1c; }
/* /datasets and /forward-tests paint dark ink on the accent ground (a dark-theme design); on the darker light accent that is 3.1:1. White is 6.3:1. */
body.light .fam .tag, body.light a.dl { color: #ffffff; }  /* .pill.dead keeps its own dark pill ground, 7:1 as it was */
