/* TLP Base Design System, shared across all interior pages */
/* Self-hosted. Google Fonts was a third-party dependency on the critical
   rendering path: if fonts.googleapis.com is slow, blocked by a trust's
   network, or down, the whole site waits on it. The files are now in
   assets/fonts and this import is local. */
@import url('assets/tlp-fonts.css');

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
  --orange:  #E8531A;
  --amber:   #F5A623;
  --bg:      #060606;
  --bg2:     #0c0c0c;
  --bg3:     #141414;
  --border:  #1c1c1c;
  --border2: #2a2a2a;
  --text:    #FFFFFF;
  --light:   #E5E7EB;
  --muted:   #8A8A8A;
  --faint:   #848484;
  /* Text colours that keep brand orange legible. See 17 Sep 2026 contrast pass. */
  --orange-ink: #E8531A;   /* orange AS TEXT on a pale orange tint */
  --on-orange:  #0A0A0A;   /* text ON a solid orange fill */
  --display: 'Space Grotesk', -apple-system, sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, monospace;

  /* Theme-dependent surfaces. Overridden wholesale in light mode. */
  --surface:      rgba(12,12,12,0.7);    /* cards, panels */
  --surface-solid: rgba(12,12,12,0.97);  /* dropdowns, mobile nav */
  --nav-bg:       rgba(12,12,12,0.55);
  --nav-border:   rgba(255,255,255,0.06);
  --hover-wash:   rgba(255,255,255,0.05);
  --shadow-lg:    0 18px 40px rgba(0,0,0,0.5);
  --table-line:   rgba(28,28,28,0.6);
  --dim-bg:       rgba(74,74,74,0.18);
  --grain-opacity: 0.04;
  --grain-blend:  overlay;
  --canvas-opacity: 1;
  /* "Ink" washes: white in dark mode, near-black in light mode. Used by
     page-level inline styles and inline SVG fills so they invert correctly. */
  --ink-015: rgba(255,255,255,0.015);
  --ink-04:  rgba(255,255,255,0.04);
  --ink-05:  rgba(255,255,255,0.05);
  --ink-06:  rgba(255,255,255,0.06);
  --ink-09:  rgba(255,255,255,0.09);
  --ink-14:  rgba(255,255,255,0.14);
  --ink-22:  rgba(255,255,255,0.22);
  --ink-32:  rgba(255,255,255,0.32);
  --ink-38:  rgba(255,255,255,0.38);
  --ink-45:  rgba(255,255,255,0.45);
  --shadow-color: rgba(0,0,0,0.55);
  --ok: #6FCF97;
  color-scheme: dark;
}

/* ── LIGHT THEME ──
   Brand orange is deepened from #E8531A to #CE440F so that small text
   (eyebrows, meta labels) clears WCAG AA on a near-white background.
   At a glance it reads as the same brand colour. */
:root[data-theme="light"] {
  --orange:  #CE440F;
  --amber:   #B45309;
  --bg:      #FAFAF9;
  --bg2:     #FFFFFF;
  --bg3:     #F2F2F0;
  --border:  #E4E4E1;
  --border2: #D2D2CE;
  --text:    #0A0A0A;
  --light:   #2A2A2A;
  --muted:   #56564F;
  --faint:   #6E6E67;
  --orange-ink: #B83403;
  --on-orange:  #FFFFFF;

  --surface:      rgba(255,255,255,0.78);
  --surface-solid: rgba(255,255,255,0.98);
  --nav-bg:       rgba(255,255,255,0.72);
  --nav-border:   rgba(10,10,10,0.10);
  --hover-wash:   rgba(10,10,10,0.045);
  --shadow-lg:    0 18px 40px rgba(20,20,18,0.14);
  --table-line:   rgba(10,10,10,0.08);
  --dim-bg:       rgba(10,10,10,0.05);
  --grain-opacity: 0.022;
  --grain-blend:  multiply;
  --canvas-opacity: 0.5;
  --ink-015: rgba(10,10,10,0.02);
  --ink-04:  rgba(10,10,10,0.04);
  --ink-05:  rgba(10,10,10,0.05);
  --ink-06:  rgba(10,10,10,0.07);
  --ink-09:  rgba(10,10,10,0.10);
  --ink-14:  rgba(10,10,10,0.15);
  --ink-22:  rgba(10,10,10,0.24);
  --ink-32:  rgba(10,10,10,0.34);
  --ink-38:  rgba(10,10,10,0.42);
  --ink-45:  rgba(10,10,10,0.50);
  --shadow-color: rgba(20,20,18,0.16);
  --ok: #1B7F4B;
  color-scheme: light;
}

html, body, nav.topnav, .tlp-card, .construct-entry, .insight-card,
.sidebar-card, .download-block, footer {
  transition: background-color 0.28s ease, border-color 0.28s ease, color 0.28s ease;
}
@media (prefers-reduced-motion: reduce) {
  html, body, nav.topnav, .tlp-card, .construct-entry, .insight-card,
  .sidebar-card, .download-block, footer { transition: none; }
}
html { scroll-behavior: smooth; }
html, body { background: var(--bg); }
body {
  font-family: var(--display);
  color: var(--text);
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.01em;
}
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: linear-gradient(var(--orange), var(--amber)); border-radius: 3px; }

/* Grain overlay */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
  opacity: var(--grain-opacity);
  pointer-events: none;
  z-index: 9999;
  mix-blend-mode: var(--grain-blend);
}

main { position: relative; z-index: 2; }

#bg-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 0;
  pointer-events: none;
  opacity: var(--canvas-opacity);
  transition: opacity 0.28s ease;
}

/* ── THEME TOGGLE ── */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex-shrink: 0;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 100px;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.theme-toggle:hover { color: var(--orange); border-color: var(--orange); }
.theme-toggle:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.theme-toggle svg { width: 16px; height: 16px; display: block; }
/* Show sun in dark mode (click for light), moon in light mode (click for dark) */
.theme-toggle .icon-sun  { display: block; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="light"] .theme-toggle .icon-sun  { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: block; }

/* ── UTILS ── */
.container { max-width: 1200px; margin: 0 auto; padding: 0 2rem; }
.grad-text {
  background: linear-gradient(135deg, var(--orange), var(--amber));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.eyebrow {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--orange);
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.5rem;
}
.eyebrow::before { content: ''; width: 24px; height: 1px; background: var(--orange); }
.section-title {
  font-size: clamp(2rem, 4vw, 3.4rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.035em;
  margin-bottom: 1.5rem;
}
.section-body { color: var(--muted); font-size: 1.05rem; line-height: 1.7; max-width: 580px; font-weight: 400; }
.page-lead { color: var(--muted); font-size: 1.1rem; line-height: 1.75; max-width: 640px; }

/* ── BUTTONS ── */
.btn {
  display: inline-flex; align-items: center; gap: 0.7rem;
  padding: 1rem 1.6rem; border-radius: 999px;
  font-family: var(--display); font-weight: 500; font-size: 0.92rem;
  text-decoration: none; cursor: pointer; border: 1px solid transparent;
  transition: all 0.25s cubic-bezier(.2,.8,.2,1); letter-spacing: -0.01em;
}
.btn-primary { background: var(--text); color: var(--bg); }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 32px rgba(232,83,26,0.25); }
.btn-primary .arr { transition: transform 0.25s; }
.btn-primary:hover .arr { transform: translateX(4px); }
.btn-outline { background: transparent; color: var(--light); border-color: var(--border2); }
.btn-outline:hover { border-color: var(--orange); color: var(--orange); }
.btn-sm { padding: 0.6rem 1.1rem; font-size: 0.82rem; }

/* ── LOGO ── */
.tlp-logo { display: inline-flex; align-items: center; text-decoration: none; flex-shrink: 0; }
.tlp-logo img { display: block; height: 38px; width: auto; }
footer .tlp-logo img { height: 30px; }

/* ── NAV ── */
nav.topnav {
  position: fixed;
  top: 1.25rem; left: 1.25rem; right: 1.25rem;
  z-index: 100; height: 60px;
  display: flex; align-items: center; padding: 0 1.5rem;
  background: var(--nav-bg);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid var(--nav-border);
  border-radius: 100px; justify-content: space-between;
}
.nav-links { display: flex; list-style: none; gap: 1.75rem; align-items: center; }
.nav-links a { color: var(--muted); text-decoration: none; font-size: 0.85rem; font-weight: 400; transition: color 0.2s; }
.nav-links a:hover, .nav-links a.active { color: var(--text); }
.nav-cta { background: var(--orange) !important; color: #fff !important; padding: 0.5rem 1.1rem; border-radius: 100px; font-weight: 500 !important; font-size: 0.82rem !important; }
.nav-cta:hover { background: #d14816 !important; }
/* Grouped navigation (dropdowns) */
.nav-links > li { position: relative; }
.nav-group > a::after { content: ""; display: inline-block; margin-left: 0.4rem; vertical-align: middle; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; opacity: 0.55; }
.nav-sub { display: none; position: absolute; top: calc(100% + 0.55rem); left: 50%; transform: translateX(-50%); flex-direction: column; list-style: none; background: var(--surface-solid); border: 1px solid var(--border2); border-radius: 14px; padding: 0.5rem; min-width: 215px; box-shadow: var(--shadow-lg); z-index: 60; }
.nav-sub::before { content: ""; position: absolute; top: -0.6rem; left: 0; right: 0; height: 0.6rem; }
.nav-group:hover .nav-sub, .nav-group:focus-within .nav-sub { display: flex; }
.nav-sub li a { display: block; padding: 0.6rem 0.95rem; border-radius: 9px; font-size: 0.84rem; }
.nav-sub li a:hover { background: var(--hover-wash); }
.nav-mobile-btn { display: none; background: none; border: none; cursor: pointer; padding: 0.5rem; color: var(--light); }
.nav-actions { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; }

/* ── PAGE HEADER ── */
.page-header {
  padding: 9rem 0 5rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6rem;
}
.page-header .section-title { margin-bottom: 1rem; }

/* ── CARDS ── */
.tlp-card {
  background: var(--surface);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 2rem 1.85rem;
  transition: transform 0.4s cubic-bezier(.2,.8,.2,1), border-color 0.3s;
}
.tlp-card:hover { border-color: rgba(232,83,26,0.25); transform: translateY(-3px); }
.tlp-card h3 { font-size: 1.15rem; font-weight: 500; margin-bottom: 0.75rem; letter-spacing: -0.02em; }
.tlp-card p { color: var(--muted); font-size: 0.9rem; line-height: 1.65; }

/* Construct entry */
.construct-entry {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 2.25rem 2rem;
  transition: border-color 0.3s;
  margin-bottom: 1rem;
}
.construct-entry:hover { border-color: rgba(232,83,26,0.2); }
.construct-tier { font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.12em; text-transform: uppercase; padding: 0.25rem 0.65rem; border-radius: 100px; display: inline-block; margin-bottom: 1rem; }
.tier-1-badge { background: rgba(232,83,26,0.12); color: var(--orange-ink); border: 1px solid rgba(232,83,26,0.25); }
.tier-2-badge { background: rgba(245,166,35,0.1); color: var(--amber); border: 1px solid rgba(245,166,35,0.2); }
.tier-3-badge { background: var(--dim-bg); color: var(--muted); border: 1px solid var(--border2); }
.construct-entry h3 { font-size: 1.3rem; font-weight: 500; letter-spacing: -0.025em; margin-bottom: 0.85rem; }
.construct-entry p { color: var(--muted); font-size: 0.92rem; line-height: 1.7; margin-bottom: 0.75rem; }
.construct-entry p:last-child { margin-bottom: 0; }
.construct-meta { font-family: var(--mono); font-size: 0.68rem; color: var(--faint); letter-spacing: 0.06em; margin-bottom: 0.75rem; }
.diagnostic-q {
  margin-top: 1.25rem;
  padding: 1rem 1.25rem;
  border-left: 2px solid var(--orange);
  background: rgba(232,83,26,0.04);
  border-radius: 0 10px 10px 0;
  font-size: 0.88rem;
  color: var(--muted);
  font-style: italic;
}
.cite-note { font-family: var(--mono); font-size: 0.65rem; color: var(--faint); margin-top: 1rem; letter-spacing: 0.04em; }

/* Download block */
.download-block {
  display: flex; align-items: center; gap: 1.25rem;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 1.25rem 1.5rem;
  text-decoration: none; transition: border-color 0.3s;
}
.download-block:hover { border-color: var(--orange); }
.download-icon { width: 42px; height: 42px; border-radius: 10px; background: rgba(232,83,26,0.1); border: 1px solid rgba(232,83,26,0.2); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.download-info { flex: 1; }
.download-info strong { display: block; font-size: 0.92rem; color: var(--text); font-weight: 500; }
.download-info span { font-family: var(--mono); font-size: 0.68rem; color: var(--faint); letter-spacing: 0.05em; }

/* Split layout */
.split-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 5rem; align-items: start; }
.split-grid-wide { display: grid; grid-template-columns: 1.4fr 1fr; gap: 5rem; align-items: start; }

/* Data table */
.tlp-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.tlp-table th { text-align: left; padding: 0.75rem 1rem; font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); border-bottom: 1px solid var(--border); }
.tlp-table td { padding: 1rem; border-bottom: 1px solid var(--table-line); vertical-align: top; color: var(--muted); font-size: 0.88rem; line-height: 1.6; }
.tlp-table tr:last-child td { border-bottom: none; }
.tlp-table td strong { color: var(--text); font-weight: 500; }
.tlp-table a { color: var(--orange); text-decoration: none; }
.tlp-table a:hover { text-decoration: underline; }

/* Feature list */
.feature-list { list-style: none; display: flex; flex-direction: column; gap: 0.9rem; }
.feature-list li { display: flex; align-items: flex-start; gap: 0.9rem; font-size: 0.92rem; color: var(--light); line-height: 1.6; }
.feature-list li::before { content: '+'; color: var(--orange); font-family: var(--mono); font-weight: 500; flex-shrink: 0; padding-top: 0.1rem; }

/* Step indicator */
.step-num { font-family: var(--mono); font-size: 0.7rem; color: var(--orange); letter-spacing: 0.15em; margin-bottom: 1.25rem; display: flex; align-items: center; gap: 0.6rem; }
.step-num::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, var(--orange), transparent); }

/* Sticky sidebar */
.sidebar-card {
  position: sticky; top: 5.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px; padding: 2rem;
}
.sidebar-card h4 { font-size: 0.78rem; font-family: var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-bottom: 1.5rem; }

/* Info row */
.info-row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.9rem 0; border-bottom: 1px solid var(--border); font-size: 0.88rem; }
.info-row:last-child { border-bottom: none; }
.info-row .label { color: var(--muted); }
.info-row .val { color: var(--text); font-weight: 500; text-align: right; }
.info-row .val.hi { color: var(--orange); }

/* Callout */
.callout-box {
  background: rgba(232,83,26,0.05);
  border: 1px solid rgba(232,83,26,0.18);
  border-radius: 14px; padding: 1.5rem 1.75rem;
}
.callout-box .eyebrow { margin-bottom: 0.5rem; }
.callout-box p { color: var(--muted); font-size: 0.9rem; line-height: 1.65; }
.callout-box a { color: var(--orange); text-decoration: none; }

/* Timeline */
.timeline { display: flex; flex-direction: column; gap: 0; }
.tl-item { display: flex; gap: 1.25rem; padding-bottom: 2rem; position: relative; }
.tl-item:last-child { padding-bottom: 0; }
.tl-dot { width: 10px; height: 10px; background: var(--orange); border-radius: 50%; margin-top: 0.35rem; flex-shrink: 0; position: relative; }
.tl-dot::after { content: ''; position: absolute; left: 50%; top: 10px; transform: translateX(-50%); width: 1px; height: calc(100% + 14px); background: var(--border); }
.tl-item:last-child .tl-dot::after { display: none; }
.tl-body { flex: 1; }
.tl-body strong { display: block; font-size: 0.92rem; font-weight: 500; color: var(--text); margin-bottom: 0.3rem; }
.tl-body p { color: var(--muted); font-size: 0.85rem; line-height: 1.6; }

/* Grid helpers */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; }

/* Section spacing */
.page-section { padding: 5rem 0; }
.page-section + .page-section { padding-top: 0; }
hr.tlp-rule { border: none; border-top: 1px solid var(--border); margin: 5rem 0; }

/* Reveal. Superseded by the scroll-motion block at the end of this file.
   The hiding rule used to live here unguarded, which meant a JavaScript
   failure left the marked sections permanently blank. It is now scoped to
   html.tlp-motion, a class only assets/tlp-motion.js sets. */

/* ── FOOTER ── */
footer {
  background: var(--bg);
  border-top: 1px solid var(--border);
  padding: 3rem 2rem;
  position: relative; z-index: 2;
}
.footer-inner {
  max-width: 1200px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 2rem;
}
.footer-top { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1.5rem; }
.footer-nav { display: flex; gap: 1.75rem; list-style: none; flex-wrap: wrap; }
.footer-nav a { font-family: var(--mono); color: var(--faint); text-decoration: none; font-size: 0.78rem; letter-spacing: 0.05em; transition: color 0.2s; }
.footer-nav a:hover { color: var(--light); }
.footer-bottom { border-top: 1px solid var(--border); padding-top: 1.5rem; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem; }
.footer-legal {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.footer-copy { font-family: var(--mono); color: var(--faint); font-size: 0.72rem; letter-spacing: 0.05em; }

/* Insight card */
.insight-card {
  display: block; text-decoration: none;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 18px; padding: 2rem;
  transition: transform 0.4s cubic-bezier(.2,.8,.2,1), border-color 0.3s;
}
.insight-card:hover { border-color: rgba(232,83,26,0.3); transform: translateY(-4px); }
.insight-card .eyebrow { margin-bottom: 0.75rem; font-size: 0.65rem; }
.insight-card h3 { font-size: 1.2rem; font-weight: 500; letter-spacing: -0.02em; margin-bottom: 0.75rem; color: var(--text); line-height: 1.25; }
.insight-card p { color: var(--muted); font-size: 0.88rem; line-height: 1.65; }
.insight-date { font-family: var(--mono); font-size: 0.68rem; color: var(--faint); letter-spacing: 0.06em; margin-bottom: 1rem; }

/* Pill tag */
.pill { display: inline-block; font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase; padding: 0.25rem 0.65rem; border-radius: 100px; }
.pill-orange { background: rgba(232,83,26,0.12); color: var(--orange-ink); border: 1px solid rgba(232,83,26,0.25); }
.pill-amber  { background: rgba(245,166,35,0.1);  color: var(--amber);  border: 1px solid rgba(245,166,35,0.2);  }
.pill-dim    { background: var(--dim-bg);    color: var(--muted);  border: 1px solid var(--border2);         }

/* ── RESPONSIVE ── */
@media (max-width: 1024px) {
  .split-grid, .split-grid-wide { grid-template-columns: 1fr; gap: 3rem; }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .nav-links { display: none; }
  .nav-mobile-btn { display: block; }
  .nav-links.nav-open { display: flex; flex-direction: column; position: absolute; top: 70px; left: 0.75rem; right: 0.75rem; background: var(--surface-solid); border: 1px solid var(--border); border-radius: 18px; padding: 1.5rem; gap: 1.25rem; }
  /* The panel inherits align-items:center from the desktop bar, which gives
     every row a different width and staggers the left edges. That staircase is
     what reads as "indented". A menu is a left-aligned list. */
  .nav-links.nav-open { align-items: stretch; text-align: left; }
  .nav-links.nav-open > li { width: 100%; }
  .nav-links.nav-open > li > a { display: block; width: 100%; text-align: left; }
  .nav-links.nav-open .nav-cta { text-align: center; margin-top: 0.4rem; }

  /* Submenus are closed on a phone and opened by tapping the parent. They used
     to be permanently expanded and indented, which turned the menu into one
     long indented list instead of a menu. */
  .nav-links.nav-open .nav-sub {
    display: none; position: static; transform: none; border: none;
    background: transparent; box-shadow: none; min-width: 0;
    flex-direction: column; gap: 0; padding: 0; margin: 0;
  }
  /* Toggled by display rather than by animating max-height. The animated
     version depended on a transition landing correctly and did not survive
     testing on the phone viewport, and a menu that opens reliably beats a menu
     that slides. The fade is kept because it costs nothing. */
  .nav-links.nav-open .nav-group.open > .nav-sub {
    display: flex; padding: 0.35rem 0 0.15rem;
    animation: navSubIn .22s ease both;
  }
  @keyframes navSubIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
  }
  .nav-links.nav-open .nav-sub li { border-left: 2px solid var(--border); }
  .nav-links.nav-open .nav-sub a {
    display: block; padding: 0.7rem 0 0.7rem 1rem; font-size: 0.95rem;
  }
  .nav-links.nav-open .nav-sub a:hover { border-left-color: var(--accent); }
  .nav-links.nav-open .nav-group:hover > .nav-sub,
  .nav-links.nav-open .nav-group:focus-within > .nav-sub { display: none; }
  .nav-links.nav-open .nav-group.open:hover > .nav-sub,
  .nav-links.nav-open .nav-group.open:focus-within > .nav-sub { display: flex; }

  /* The parent is a toggle, so it says so. */
  .nav-links.nav-open .nav-group > a::after {
    display: inline-block; content: ""; float: right; margin-top: 0.45em;
    width: 0.55em; height: 0.55em; border: 2px solid currentColor;
    border-left: 0; border-top: 0; transform: rotate(45deg);
    opacity: .55; transition: transform .3s cubic-bezier(.4,0,.2,1), opacity .2s;
  }
  .nav-links.nav-open .nav-group.open > a::after {
    transform: rotate(-135deg); opacity: 1;
  }
  .nav-links.nav-open .nav-group > a { display: block; padding: 0.55rem 0; }
  .nav-links.nav-open > li + li { border-top: 1px solid var(--border); }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  nav.topnav { top: 0.75rem; left: 0.75rem; right: 0.75rem; padding: 0 1rem; }
  .page-header { padding: 7rem 0 3.5rem; margin-bottom: 3.5rem; }
  .container { padding: 0 1.25rem; }
}

/* ==========================================================================
   Surface polish. Asked for as "HD and glossy": a specular sheen on the
   raised surfaces, deeper and softer shadows, and crisper images. Everything
   below uses the existing tokens, so both themes stay correct, and every
   effect degrades to a plain surface where it is unsupported.
   ========================================================================== */

/* Sharper rendering on high-density screens, which is most phones. */
img { image-rendering: -webkit-optimize-contrast; }
.tlp-logo img { transform: translateZ(0); backface-visibility: hidden; }

/* The navigation bar reads as a pane of glass rather than a flat strip. */
nav.topnav {
  backdrop-filter: saturate(180%) blur(22px);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  box-shadow: 0 1px 0 rgba(255,255,255,.06) inset,
              0 18px 40px -22px rgba(0,0,0,.65);
}
nav.topnav::after {
  content: ""; position: absolute; inset: 0 0 auto; height: 1px;
  background: linear-gradient(90deg, transparent,
              rgba(255,255,255,.22) 22%, rgba(255,255,255,.22) 78%, transparent);
  pointer-events: none;
}

/* The open mobile panel gets the same treatment, so it is not a flat slab. */
@media (max-width: 720px) {
  .nav-links.nav-open {
    backdrop-filter: saturate(180%) blur(26px);
    -webkit-backdrop-filter: saturate(180%) blur(26px);
    box-shadow: 0 1px 0 rgba(255,255,255,.07) inset,
                0 30px 60px -26px rgba(0,0,0,.75);
  }
}

/* Raised surfaces catch a light from above, which is what makes a surface
   read as glossy rather than merely coloured. */
.tlp-card, .construct-entry, .sidebar-card, .insight-card, .download-block, .callout-box {
  position: relative;
  transition: transform .35s cubic-bezier(.4,0,.2,1),
              box-shadow .35s cubic-bezier(.4,0,.2,1),
              border-color .35s ease;
}
.tlp-card::before, .construct-entry::before, .sidebar-card::before,
.insight-card::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(160deg, rgba(255,255,255,.07), transparent 42%);
  opacity: .9; pointer-events: none;
}
.tlp-card:hover, .construct-entry:hover, .sidebar-card:hover,
.insight-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 26px 50px -28px rgba(0,0,0,.7);
}

/* Buttons get a soft highlight along the top edge. */
.btn, .nav-cta, button.cta {
  position: relative; overflow: hidden;
  transition: transform .25s cubic-bezier(.4,0,.2,1),
              box-shadow .25s ease, filter .25s ease;
}
.btn::after, .nav-cta::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(180deg, rgba(255,255,255,.20), transparent 55%);
  pointer-events: none;
}
.btn:hover, .nav-cta:hover { transform: translateY(-1px); filter: brightness(1.06); }
.btn:active, .nav-cta:active { transform: translateY(0); }

/* Keyboard users get a visible ring rather than the browser default, which
   the dark palette was swallowing. */
a:focus-visible, button:focus-visible, .nav-cta:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px;
}

/* Respect a stated preference for less movement. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; transition-duration: .001ms !important;
  }
}


/* Example-report download row. */
.dl-row { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap;
  margin-top: 1.6rem; }
.dl-meta { font-family: var(--mono, monospace); font-size: 0.78rem;
  letter-spacing: 0.06em; text-transform: uppercase; opacity: .7; }

/* ---- plain-language glossary ---------------------------------------------
   Sixteen technical terms, one definition each, from glossary.json. First use
   on a page is explained inline in brackets, because that is the version that
   survives being printed into a board pack. Later uses carry a small (i) that
   opens the full definition on click, which behaves identically on a phone and
   on a desktop. Hover was rejected: it gives no affordance on touch. */
.gl-term { border-bottom: 1px dotted var(--border); }
.gl-inline { color: var(--faint); font-size: 0.92em; }

.gl-i {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; padding: 0; margin-left: 3px;
  /* A hair of space each side so the marker reads as a separate control
     rather than a letter stuck on the end of the word. */
  vertical-align: 3px;
  margin-right: 2px;
  border: 1px solid var(--border); border-radius: 50%;
  background: transparent; cursor: pointer;
  font-family: var(--font-sans, inherit); font-size: 10px; font-style: italic;
  /* --muted, not --faint: at 10px the marker counts as text, and --faint
     falls to 3.95:1 against the dark background, under the 4.5 bar. */
  font-weight: 500; line-height: 1; color: var(--muted);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.gl-i:hover, .gl-i:focus-visible, .gl-i[aria-expanded="true"] {
  background: var(--orange); border-color: var(--orange); color: var(--on-orange);
}
.gl-i:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
/* The circle stays 15px so it does not shout in running text, but the tappable
   area is extended to 44px, which is the minimum a thumb can hit reliably. */
.gl-i { position: relative; }
.gl-i::after { content: ""; position: absolute; top: -15px; right: -15px; bottom: -15px; left: -15px; }

.gl-panel {
  margin: 0.9rem 0 1.1rem;
  padding: 0.85rem 1.1rem;
  /* A faint brand tint rather than a white wash: white on white is invisible
     in light mode, and --card does not exist in this stylesheet. */
  background: rgba(232, 83, 26, 0.06);
  border-left: 3px solid var(--orange);
  border-radius: 0;
}
.gl-panel-t {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  margin: 0 0 0.35rem;
  font-size: 0.82rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--orange);
}
.gl-panel-d { margin: 0; font-size: 0.9rem; line-height: 1.6; color: var(--muted); }
.gl-panel-x {
  border: none; background: none; padding: 0; cursor: pointer;
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--faint);
}
.gl-panel-x:hover { color: var(--orange); }

/* On paper the marker is a dead control and the panel cannot be opened, so the
   inline first use is what carries the meaning. Hide the rest. */
@media print {
  .gl-i, .gl-panel { display: none !important; }
  .gl-term { border-bottom: none; }
}

/* ---- gated report preview ------------------------------------------------
   The cover page is shown clear, the second page sits behind a blur, and the
   full file arrives on one click. A soft gate, deliberately: the site promises
   "no email required" on five pages, and no mail provider is wired, so the
   unlock control IS the download link. Pure HTML and CSS, nothing to fail. */
.pdf-gate { max-width: 440px; margin-top: 2.25rem; }
.pdf-gate .pg-cover { display: block; width: 100%; border: 1px solid var(--border);
                      border-radius: 8px 8px 0 0; }
.pdf-gate .pg-blur { position: relative; overflow: hidden; max-height: 280px;
                     border: 1px solid var(--border); border-top: none;
                     border-radius: 0 0 8px 8px; }
.pdf-gate .pg-blur img { display: block; width: 100%; filter: blur(7px);
                         transform: scale(1.04); opacity: 0.7; }
.pdf-gate .gate-veil { position: absolute; inset: 0; display: flex;
                       flex-direction: column; align-items: center; justify-content: center;
                       gap: 0.9rem; padding: 1.25rem; text-align: center;
                       background: linear-gradient(180deg, rgba(0,0,0,0) 0%, var(--bg) 96%); }
.pdf-gate .gate-note { font-family: var(--mono); font-size: 0.68rem;
                       letter-spacing: 0.08em; color: var(--muted); }


/* ---- scroll motion -------------------------------------------------------
   Sections fade and rise as they come into view; grouped siblings arrive in
   sequence via --rv-delay. Driven by assets/tlp-motion.js.

   Every rule here is behind html.tlp-motion. That class is set by the script
   only after it has confirmed the visitor has not asked for reduced motion,
   so the two failure paths that matter, script broken and motion declined,
   both land on the plain readable page rather than on an empty one. */
html.tlp-motion .reveal,
html.tlp-motion .tlp-rv {
  opacity: 0;
  /* 22px over 0.7s was there but nobody could see it. The rise is now far
     enough to register as movement, with a slight scale so the block settles
     into place rather than only sliding. */
  transform: translateY(40px) scale(0.985);
}
/* The reveal owns the element's transition only until it has landed. Without
   the :not() an element that is both a reveal target and a hover target keeps
   the reveal's 0.7s opacity-and-transform transition for ever, so its hover
   either snaps or crawls. Once tlp-motion.js marks it settled the element goes
   back to whatever transition its own rule specifies. */
html.tlp-motion .reveal:not(.tlp-settled),
html.tlp-motion .tlp-rv:not(.tlp-settled) {
  transition: opacity 0.85s cubic-bezier(.16,1,.3,1),
              transform 0.85s cubic-bezier(.16,1,.3,1);
  transition-delay: var(--rv-delay, 0ms);
}
html.tlp-motion .reveal.in,
html.tlp-motion .reveal.tlp-in,
html.tlp-motion .tlp-rv.tlp-in {
  opacity: 1;
  transform: none;
}

/* Headline figures count up on arrival. Fixing the digits to one width stops
   the number jittering sideways while it climbs. */
html.tlp-motion .fig,
html.tlp-motion [data-countup] {
  font-variant-numeric: tabular-nums;
}


/* ---- page transition -----------------------------------------------------
   A short cross-fade between pages so navigation reads as one continuous
   surface rather than a hard document swap. Two safety rules, both the same
   rule the scroll motion follows: everything is behind html.tlp-motion, which
   only exists when the script is running and the visitor has not asked for
   reduced motion, and the fade-in starts from full opacity so a script that
   never runs leaves a normally visible page. */
/* NEVER put a transform on <body>. #bg-canvas is a fixed-position sibling of
   <nav> and <main>, and any transform on an ancestor makes that ancestor the
   containing block for fixed descendants. The canvas then scrolls with the
   page instead of tracking the viewport, so the lattice shows at the top and
   the rest of the page goes black. That is exactly what happened when this
   rule first animated transform on body. The fade stays on body, where only
   opacity is touched; the rise moved to <main>, which has no fixed children. */
html.tlp-motion body {
  animation: tlpPageFade 0.42s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes tlpPageFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
html.tlp-motion main {
  animation: tlpPageRise 0.42s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes tlpPageRise {
  from { transform: translateY(8px); }
  to   { transform: none; }
}
/* Set on the outgoing page while the browser fetches the next one. */
html.tlp-motion.tlp-leaving body {
  opacity: 0;
  transition: opacity 0.22s ease;
}
html.tlp-motion.tlp-leaving main {
  transform: translateY(-6px);
  transition: transform 0.22s ease;
}

/* ---- navigation on scroll ------------------------------------------------
   The bar tightens and gains a background once the page has moved, so the
   header stops competing with the hero and starts behaving like a toolbar. */
nav { transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease; }
nav.tlp-stuck {
  background: var(--surface);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom-color: var(--border);
  box-shadow: 0 1px 24px rgba(0,0,0,0.16);
}

/* ---- hover on the surfaces that had none ---------------------------------
   Buttons and cards already responded to the pointer; rows, list items and
   links in running text did not, which is what made the page feel inert. */
.tlp-table tbody tr { transition: background 0.2s ease; }
.tlp-table tbody tr:hover { background: var(--hover-wash, rgba(232,83,26,0.045)); }

.stop-item { transition: border-color 0.25s ease, background 0.25s ease; }
.stop-item:hover { border-color: rgba(232,83,26,0.28); background: rgba(232,83,26,0.04); }

footer a { transition: color 0.2s ease; }
footer a:hover { color: var(--orange); }

/* An underline that grows from the left, rather than one that is simply on.
   Kept off buttons and off the glossary marker. */
.prose a:not(.btn), .page-section p a:not(.btn) {
  color: var(--orange);
  text-decoration: none;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size 0.28s cubic-bezier(.2,.8,.2,1);
  padding-bottom: 1px;
}
.prose a:not(.btn):hover, .page-section p a:not(.btn):hover { background-size: 100% 1px; }

@media (prefers-reduced-motion: reduce) {
  .tlp-table tbody tr, .stop-item, footer a, .prose a, nav { transition: none; }
  .stop-item:hover { transform: none; }
}


/* ---- lists in running text -----------------------------------------------
   These had no styling at all and fell back to browser defaults: tight
   leading, a default disc, and no gap between items, which is why a list of
   named failures read as one grey block. Each item now leads with its label on
   a hanging indent, so the eye can find the five failures without reading. */
.prose ul, .page-section ul:not(.tlp):not(.footer-nav):not(.nav-links):not(.nav-sub):not(.sec-contents) {
  list-style: none;
  margin: 1.25rem 0 1.5rem;
  padding: 0;
}
.prose ul > li,
.page-section ul:not(.tlp):not(.footer-nav):not(.nav-links):not(.nav-sub):not(.sec-contents) > li {
  position: relative;
  padding-left: 1.4rem;
  margin-bottom: 0.95rem;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.72;
}
.prose ul > li::before,
.page-section ul:not(.tlp):not(.footer-nav):not(.nav-links):not(.nav-sub):not(.sec-contents) > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 1px;
  background: var(--orange);
  opacity: 0.85;
}
.prose ul > li > strong:first-child,
.page-section ul > li > strong:first-child {
  color: var(--text);
  font-weight: 500;
}

/* ---- the Validated badge -------------------------------------------------
   A validated diagnostic is the strongest thing on the page, so the badge
   carries a slow pulse rather than sitting flat. Slow and low-contrast on
   purpose: this is a credibility signal, not an alert. */
.tier-1-badge, .pill-orange {
  position: relative;
  box-shadow: 0 0 0 0 rgba(232,83,26,0.30);
}
html.tlp-motion .tier-1-badge {
  animation: tlpValidated 3.2s ease-in-out infinite;
}
@keyframes tlpValidated {
  0%, 100% { box-shadow: 0 0 0 0 rgba(232,83,26,0.00); border-color: rgba(232,83,26,0.25); }
  50%      { box-shadow: 0 0 14px 1px rgba(232,83,26,0.28); border-color: rgba(232,83,26,0.60); }
}

/* ---- gloss ---------------------------------------------------------------
   A single hairline of light along the top edge of raised surfaces, which is
   what makes a dark interface read as glass rather than as flat paint. One
   pseudo-element, no images, no cost. */
.tlp-card, .insight-card, .sidebar-card, .money-box, .warn-box {
  position: relative;
  overflow: hidden;
}
.tlp-card::before, .insight-card::before, .sidebar-card::before {
  content: "";
  position: absolute;
  top: 0; left: 8%; right: 8%;
  height: 1px;
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.28) 50%,
    rgba(255,255,255,0) 100%);
  opacity: 0.7;
  pointer-events: none;
}
:root[data-theme="light"] .tlp-card::before,
:root[data-theme="light"] .insight-card::before,
:root[data-theme="light"] .sidebar-card::before {
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.9) 50%,
    rgba(255,255,255,0) 100%);
}
/* The sheen brightens and widens as the pointer arrives. */
.tlp-card::before, .insight-card::before { transition: opacity 0.35s ease, left 0.35s ease, right 0.35s ease; }
.tlp-card:hover::before, .insight-card:hover::before { opacity: 1; left: 0; right: 0; }

@media (prefers-reduced-motion: reduce) {
  .tier-1-badge { animation: none !important; }
  .tlp-card::before, .insight-card::before { transition: none; }
}

/* ---------------------------------------------------------------------------
   Share row and insights filter. Added 30 August 2026.
   The filter bar carries [hidden] in the markup and is only revealed by script
   once the list is long enough to need it, so a short page never shows an
   empty-looking control.
   --------------------------------------------------------------------------- */
.share-row {
  display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap;
  margin-top: 1.6rem; padding-top: 1.2rem; border-top: 1px solid var(--border);
}
.share-row .share-label {
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--faint);
}
.share-row a, .share-row button {
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); text-decoration: none;
  background: none; border: 0; padding: 0; cursor: pointer;
  transition: color .2s;
}
.share-row a:hover, .share-row button:hover,
.share-row a:focus-visible, .share-row button:focus-visible { color: var(--orange); }

.insight-filters { display: flex; gap: 0.6rem; flex-wrap: wrap; align-items: center; margin: 1.75rem 0 0.5rem; }
.insight-filters button[data-filter] {
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.06em;
  background: none; border: 1px solid var(--border2); border-radius: 999px;
  padding: 0.42rem 0.95rem; color: var(--muted); cursor: pointer;
  transition: color .2s, border-color .2s, background .2s;
}
.insight-filters button[data-filter]:hover { color: var(--orange); border-color: var(--orange); }
.insight-filters button[data-filter][aria-pressed="true"] {
  color: var(--orange-ink); border-color: var(--orange); background: rgba(232,83,26,0.08);
}
.insight-filters input[type="search"] {
  flex: 1; min-width: 180px; background: var(--surface);
  border: 1px solid var(--border2); border-radius: 999px;
  padding: 0.42rem 1rem; color: var(--text);
  font-family: var(--display); font-size: 0.85rem;
}
.insight-filters input[type="search"]:focus { outline: none; border-color: var(--orange); }
.insight-count {
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--faint); display: block; margin-bottom: 1.25rem;
}
