/* site.css — TickerMantis site chrome.
   nocturne.css stays the design system; this file holds only what every page
   of *this* site shares: the header and its menu, the page scaffolding
   classes, the long-page wayfinding and the footer. There is no build step,
   so one stylesheet beats pasting the same rules into eight <head>s. */

:root {
  /* Rendered height of the sticky bar. Anchor targets clear it, so a jump
     lands under the header instead of behind it. */
  --nav-h: 61px;
  --page-max: 1200px;
  --page-pad: clamp(20px, 4vw, 48px);
}
@media (max-width: 520px) { :root { --nav-h: 55px; } }

/* Nocturne is dark-only, so the user agent is told as much: scrollbars, native
   form controls and the overscroll canvas follow the declaration instead of
   defaulting to their light styling. The ground is repeated on html because
   only body carried it, and rubber-banding past either end of the page —
   or any area the body does not reach — otherwise flashes white. */
:root { color-scheme: dark; }
html { background: var(--color-bg); }

body { margin: 0; }
a { color: var(--color-accent); }
a:hover { color: var(--color-accent-300); }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
[id] { scroll-margin-top: calc(var(--nav-h) + 20px); }

/* — page scaffolding — */
.wrap { max-width: var(--page-max); margin: 0 auto; padding: 0 var(--page-pad); }
/* Long-form reading measure — the policy page and other running prose. The
   container keeps the site's left rail so headings line up with the wordmark;
   only the column of text is narrowed. */
.wrap-narrow > * { max-width: 860px; }
.kicker { display: block; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-accent); margin: 0; }
.h2 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 28px; line-height: 34px; letter-spacing: -.01em; margin: 14px 0 0; }
/* The Nocturne rule: fades to transparent over 48px at each end. */
.rule { height: 1px; background: linear-gradient(to right, transparent, var(--color-divider) 48px calc(100% - 48px), transparent); }

/* — homepage brand voice — */
.hero-brandline {
  display: flex; align-items: center; gap: 9px; margin: 0 0 18px;
  color: var(--color-accent); font-size: 11px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
}
.hero-brandline::before {
  content: ""; width: 24px; height: 1px; background: var(--color-accent);
  box-shadow: 7px 0 14px color-mix(in srgb, var(--color-accent) 55%, transparent);
}
.hero-title-em {
  color: transparent;
  background: linear-gradient(92deg, var(--color-accent-100), var(--color-accent));
  -webkit-background-clip: text; background-clip: text;
}
.hero-dashboard .table { table-layout: fixed; }
.hero-dashboard .table th,
.hero-dashboard .table td { overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 520px) {
  .hero-dashboard .table th,
  .hero-dashboard .table td { font-size: 10px; letter-spacing: 0; padding-inline: 3px !important; }
  .workflow-steps > div {
    grid-template-columns: 34px minmax(0, 1fr) !important;
    gap: 8px 12px !important;
  }
  .workflow-steps > div > p:last-child { grid-column: 2; }
}

/* — homepage: product-led landing page — */
.icon-sprite { position: absolute; }
.page-shell {
  min-height: 100vh; overflow: hidden;
  background:
    radial-gradient(1050px 680px at 82% -120px, color-mix(in srgb, var(--color-accent-900) 72%, transparent), transparent 62%),
    radial-gradient(760px 520px at -10% 24%, color-mix(in srgb, var(--color-accent-900) 22%, transparent), transparent 66%),
    var(--color-bg);
}
.accent-text { color: var(--color-accent); }
.btn-lg { min-height: 44px; padding-inline: 18px; }
/* Two equal columns that fold to one on their own once either would drop under
   430px — no breakpoint needed, and the copy and the stage get the same width. */
.landing-hero {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 430px), 1fr));
  gap: clamp(44px, 6vw, 88px); align-items: center;
  padding-top: clamp(68px, 9vw, 118px); padding-bottom: clamp(80px, 10vw, 132px);
}
.landing-hero h1 { max-width: 720px; margin: 0; font-size: clamp(46px, 5.8vw, 76px); line-height: 1.01; letter-spacing: -.045em; }
.hero-lede { max-width: 55ch; margin: 26px 0 0; font-size: clamp(17px, 1.7vw, 20px); line-height: 1.6; color: color-mix(in srgb, var(--color-text) 78%, transparent); }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.hero-proof { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.hero-proof span { display: inline-flex; align-items: center; gap: 7px; padding: 6px 9px; border: 1px solid var(--color-divider); border-radius: 999px; background: color-mix(in srgb, var(--color-surface) 68%, transparent); color: color-mix(in srgb, var(--color-text) 72%, transparent); font-size: 10px; }
.hero-proof span::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--color-accent); box-shadow: 0 0 8px color-mix(in srgb, var(--color-accent) 70%, transparent); }
.hero-note { margin: 18px 0 0; font-size: 12.5px; color: color-mix(in srgb, var(--color-text) 48%, transparent); }
.hero-scan,
.product-visual,
.zone-chart,
.hero-stage-chart { background: color-mix(in srgb, var(--color-surface) 94%, black); border: 1px solid var(--color-divider); border-radius: var(--radius-lg); box-shadow: 0 32px 80px rgba(0,0,0,.36), inset 0 1px 0 rgba(255,255,255,.025); }
.terminal-topbar,
.ui-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 48px; padding: 0 18px; border-bottom: 1px solid var(--color-divider); font-size: 12px; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.terminal-brand { display: inline-flex; align-items: center; gap: 9px; color: var(--color-text); font-weight: 600; }
.live-pill,
.ui-status { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; }
.live-pill i,
.ui-status i { width: 6px; height: 6px; border-radius: 50%; background: var(--color-accent); box-shadow: 0 0 10px var(--color-accent); }
.terminal-chart { position: relative; height: 320px; overflow: hidden; background-image: linear-gradient(var(--color-divider) 1px, transparent 1px), linear-gradient(90deg, var(--color-divider) 1px, transparent 1px); background-size: 64px 54px; }
.zone-band { position: absolute; height: 42px; border: 1px solid; z-index: 1; }
.zone-band span { position: absolute; top: 7px; right: 10px; font-size: 9px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; }
.zone-supply { top: 46px; left: 8%; width: 42%; background: color-mix(in srgb, var(--color-neutral-700) 58%, transparent); border-color: var(--color-neutral-600); color: var(--color-neutral-200); }
.zone-demand { right: 5%; bottom: 37px; width: 51%; background: color-mix(in srgb, var(--color-accent-900) 72%, transparent); border-color: var(--color-accent-700); color: var(--color-accent-200); }
.candle-field { position: absolute; inset: 16px 24px; z-index: 2; }
.candle-field i { position: absolute; left: var(--x); top: var(--y); width: 5px; height: var(--b); background: var(--c); transform: translate(-50%,-50%); }
.candle-field i::before { content: ""; position: absolute; left: 2px; top: calc((var(--h) - var(--b)) / -2); width: 1px; height: var(--h); background: var(--c); }
.price-callout { position: absolute; z-index: 3; right: 18px; top: 42%; padding: 5px 8px; border-radius: var(--radius-sm); background: var(--color-accent); color: var(--color-bg); font-size: 11px; font-weight: 600; }
.price-callout span { margin-left: 5px; opacity: .7; }
.terminal-stats { display: grid; grid-template-columns: repeat(4, 1fr); }
.terminal-stats > div { padding: 15px 16px; border-top: 1px solid var(--color-divider); }
.terminal-stats > div + div { border-left: 1px solid var(--color-divider); }
.terminal-stats span { display: block; font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 42%, transparent); }
.terminal-stats strong { display: block; margin-top: 5px; font-size: 13px; font-weight: 600; }

/* — homepage: the hero's floating panel stage —
   Three product surfaces held in one perspective: the chart panel behind, the
   scan card overlapping it from the lower left, and the alerts standing off
   the right edge. The offsets are deliberately outside the column — the panels
   break the hero grid to sit over the gutter — so the stage relies on
   .page-shell's overflow clip as its backstop. */
/* The cap only bites once the grid has folded to one column — in two-column
   layout the track is already narrower than this — and it is what keeps the
   composition from stretching across a full-width single column. The explicit
   width matters: auto margins drop a grid item out of stretch sizing, and
   every child here is absolutely positioned, so the stage would otherwise
   resolve to zero. */
.hero-stage { position: relative; min-width: 0; width: 100%; max-width: 560px; margin-inline: auto; height: 580px; }
.hero-stage-glow { position: absolute; left: 10%; right: 0; top: 6%; bottom: 18%; z-index: 0; background: color-mix(in srgb, var(--color-accent) 15%, transparent); filter: blur(58px); }
.hero-stage-chart {
  position: absolute; top: 0; left: 118px; right: -12px; height: 296px; z-index: 1;
  overflow: hidden;
  transform: perspective(1400px) rotateY(-3deg) rotateX(1.4deg);
  animation: tmFloatA 11s ease-in-out infinite;
}
.hero-stage-plot { position: relative; height: 252px; }
.hero-stage .hero-scan {
  position: absolute; left: -28px; top: 262px; width: 300px; z-index: 3;
  box-shadow: 0 32px 80px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.025);
  transform: perspective(1400px) rotateY(-2deg) rotateX(1deg);
  animation: tmFloatB 13s ease-in-out infinite;
}
.hero-stage-alerts {
  position: absolute; right: -30px; top: 312px; width: 232px; z-index: 4;
  display: flex; flex-direction: column; gap: 9px;
  animation: tmFloatC 9s ease-in-out infinite;
}
.hero-stage-alerts .zone-chart-toast { width: auto; }

/* The alert affordance itself, stood off the chart panel's top-left corner:
   a ringing bell with an unread count, ripple pulsing out of the tile edge. */
.hero-stage-bell { position: absolute; left: 52px; top: -22px; z-index: 5; animation: tmFloatD 7.5s ease-in-out infinite; }
.hero-stage-bell-face {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; border-radius: 18px;
  background: #1b221d; border: 1px solid var(--color-divider);
  box-shadow: 0 16px 36px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.03);
}
.hero-stage-bell-face::before {
  content: ""; position: absolute; inset: -1px; border-radius: 18px;
  border: 1px solid color-mix(in srgb, var(--color-accent) 50%, transparent);
  animation: tmRipple 2.6s ease-out infinite;
}
.hero-stage-bell-icon {
  width: 24px; height: 24px; stroke-width: 1.6; color: var(--color-accent);
  vertical-align: 0; transform-origin: 50% 22%;
  animation: tmRing 2.6s ease-in-out infinite;
}
.hero-stage-bell-face b {
  position: absolute; top: -6px; right: -6px;
  display: flex; align-items: center; justify-content: center;
  min-width: 19px; height: 19px; padding: 0 5px; border-radius: 999px;
  background: var(--color-accent); color: #12180f;
  font-size: 10.5px; font-weight: 700; line-height: 1;
  box-shadow: 0 0 0 3px #0f1512;
}

/* The panels are two thirds the size they are elsewhere on the page, so the
   shared chrome is stepped down to match rather than duplicated. */
.hero-stage .terminal-topbar { min-height: 44px; padding-inline: 16px; font-size: 11.5px; }
.hero-stage .terminal-brand { gap: 8px; }
.hero-stage .hero-scan .terminal-topbar { min-height: 42px; padding-inline: 15px; }
.hero-stage .scan-progress > div { padding: 11px 15px 10px; }
.hero-stage .scan-progress strong { font-size: 19px; }
.hero-stage .scan-progress div span { margin-top: 4px; font-size: 8px; letter-spacing: .07em; }
.hero-stage .scan-complete { right: 12px; top: 10px; padding: 3px 6px; }
.hero-stage .hero-scan-filter { gap: 6px; padding: 10px 15px; }
.hero-stage .hero-scan-row { gap: 8px; min-height: 42px; padding-inline: 15px; }
.hero-stage .hero-scan-head { min-height: 30px; }
.hero-stage .hero-scan-row:last-child { border-bottom: 0; }

@keyframes tmFloatA {
  0%, 100% { transform: perspective(1400px) rotateY(-3deg) rotateX(1.4deg) translateY(0); }
  50% { transform: perspective(1400px) rotateY(-3deg) rotateX(1.4deg) translateY(-11px); }
}
@keyframes tmFloatB {
  0%, 100% { transform: perspective(1400px) rotateY(-2deg) rotateX(1deg) translateY(0); }
  50% { transform: perspective(1400px) rotateY(-2deg) rotateX(1deg) translateY(9px); }
}
@keyframes tmFloatC {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}
@keyframes tmFloatD {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-9px); }
}
@keyframes tmRing {
  0%, 58%, 100% { transform: rotate(0); }
  62% { transform: rotate(15deg); }
  68% { transform: rotate(-13deg); }
  74% { transform: rotate(9deg); }
  80% { transform: rotate(-6deg); }
  86% { transform: rotate(3deg); }
  92% { transform: rotate(-1deg); }
}
@keyframes tmRipple {
  0% { transform: scale(1); opacity: .5; }
  70%, 100% { transform: scale(1.9); opacity: 0; }
}

.hero-scan { overflow: hidden; }
.scan-progress { position: relative; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; border-bottom: 1px solid var(--color-divider); background: var(--color-divider); }
.scan-progress > div { padding: 22px 18px 18px; background: color-mix(in srgb, var(--color-surface) 96%, black); }
.scan-progress strong { display: block; font-size: clamp(26px, 3vw, 36px); line-height: 1; letter-spacing: -.04em; color: var(--color-text); }
.scan-progress div:nth-child(2) strong { color: var(--color-accent); }
.scan-progress div span { display: block; margin-top: 7px; font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 42%, transparent); }
.scan-complete { position: absolute; right: 16px; top: 15px; padding: 4px 7px; border-radius: 999px; background: color-mix(in srgb, var(--color-accent) 12%, transparent); color: var(--color-accent); font-size: 8px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.hero-scan-filter { display: flex; flex-wrap: wrap; gap: 7px; padding: 12px 18px; border-bottom: 1px solid var(--color-divider); }
.hero-scan-filter span { padding: 5px 8px; border-radius: var(--radius-sm); background: var(--color-neutral-800); color: var(--color-neutral-300); font-size: 9px; }
.hero-scan-row { display: grid; grid-template-columns: 1.1fr .9fr .75fr .7fr; gap: 10px; align-items: center; min-height: 48px; padding: 0 18px; border-bottom: 1px solid var(--color-divider); color: color-mix(in srgb, var(--color-text) 68%, transparent); font-size: 11px; }
.hero-scan-row strong { color: var(--color-text); font-size: 11px; }
.hero-scan-row b { color: var(--color-accent); font-weight: 600; }
.hero-scan-row em { color: var(--color-text); font-style: normal; font-variant-numeric: tabular-nums; text-align: right; }
.hero-scan-head { min-height: 34px; color: color-mix(in srgb, var(--color-text) 38%, transparent); font-size: 8px; letter-spacing: .08em; text-transform: uppercase; }
.hero-scan-head span:last-child { text-align: right; }
.hero-scan-row.is-leading { background: color-mix(in srgb, var(--color-accent) 6%, transparent); box-shadow: inset 3px 0 var(--color-accent); }

/* — homepage: the animated "Zones as they form" panel —
   Wider than the site's 1200px measure on purpose: it is a chart, and the
   71 bars need the room. Everything inside the plot except the canvas is
   ordinary DOM, so the notification and the timeframe cells stay crisp text
   at any pixel ratio. Drawing lives in js/zone-chart.js. */
.zone-chart-section { max-width: 1360px; margin: 0 auto; padding: 0 var(--page-pad) clamp(80px, 10vw, 132px); }
/* The hero's own bottom padding is sized for a section break, which is too
   much air when the chart is the hero's continuation rather than a new idea. */
.landing-hero:has(+ .zone-chart-section) { padding-bottom: clamp(44px, 5vw, 68px); }
.zone-chart-section .hero-brandline { margin-bottom: 20px; }
.zone-chart { position: relative; overflow: hidden; }
.zone-chart-badge { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 6px; background: var(--color-accent-800); color: var(--color-accent-100); font-size: 10px; font-weight: 600; letter-spacing: .04em; }
/* Scoped rather than put on .live-pill itself: the same pill appears in the
   static product mockups further down the page, where a blinking dot would be
   noise rather than a sign of life. */
.zone-chart .live-pill i,
.hero-stage .live-pill i { animation: tmPulse 2.4s ease-in-out infinite; }
/* Height tracks the viewport but stops where the panel does, so a very wide
   screen gets a wider chart rather than a taller one. */
.zone-chart-plot { position: relative; height: clamp(540px, 42vw, 620px); }
.zone-chart-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.zone-chart-note { margin: 14px 2px 0; font-size: 11px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }

/* Timeframe read-out, bottom right — the Location / Trend / Execution cells
   the indicator itself prints on the chart, in the indicator's own colours
   rather than the site palette. Only Trend and Execution move; js sets their
   background, so the value here is the resting Flat. */
.zone-chart-tfs {
  position: absolute; right: 11px; bottom: 11px; z-index: 2; display: flex;
  border: 1px solid rgba(38,50,61,.5); border-radius: 3px; overflow: hidden;
  font-size: 10px; font-weight: 600; line-height: 1; letter-spacing: .01em;
  font-variant-numeric: tabular-nums;
}
.zone-chart-tfs > span { padding: 5px 9px; color: #26323D; background: #C9D0D6; }
.zone-chart-tfs > span:first-child { background: #8FD0AE; }
.zone-chart-tfs > span + span { border-left: 1px solid rgba(38,50,61,.5); }

/* Alert notification. The card itself is shared — the hero stacks these into a
   column beside the panel, the wide section shows one at a time inside the
   plot — so only the appearance lives here and each placement positions it. */
.zone-chart-toast {
  display: flex; align-items: center; gap: 10px;
  width: 248px; padding: 9px 12px 9px 10px;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
  background: #1b221d; box-shadow: 0 12px 30px rgba(0,0,0,.55);
  animation: tmToastIn .34s cubic-bezier(.2,.7,.3,1) both;
}
.zone-chart-toasts .zone-chart-toast { position: absolute; left: 14px; bottom: 14px; z-index: 2; }
.zone-chart-toast-icon { display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; flex: none; border-radius: 50%; background: color-mix(in srgb, var(--color-accent) 14%, transparent); color: var(--color-accent); }
.zone-chart-toast-icon .ico { width: 14px; height: 14px; vertical-align: 0; }
.zone-chart-toast-body { display: block; min-width: 0; flex: 1; }
.zone-chart-toast-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.zone-chart-toast-name { font-size: 12.5px; font-weight: 600; color: var(--color-text); white-space: nowrap; }
.zone-chart-toast-time { font-size: 10.5px; color: color-mix(in srgb, var(--color-text) 42%, transparent); font-variant-numeric: tabular-nums; }
.zone-chart-toast-msg { display: block; margin-top: 2px; font-size: 11.5px; color: var(--color-accent); white-space: nowrap; }

@keyframes tmToastIn { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes tmPulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) {
  .zone-chart .live-pill i,
  .hero-stage .live-pill i,
  .zone-chart-toast,
  .hero-stage-chart,
  .hero-stage .hero-scan,
  .hero-stage-alerts,
  .hero-stage-bell,
  .hero-stage-bell-face::before,
  .hero-stage-bell-icon { animation: none; }
}

/* Below this the panel is portrait, and the notification and the timeframe
   cells no longer fit on one line together. */
@media (max-width: 620px) {
  .zone-chart-plot { height: 420px; }
  .zone-chart-toasts .zone-chart-toast { left: 11px; right: 11px; bottom: 46px; width: auto; }
}

.product-journey { padding: clamp(76px, 9vw, 120px) 0; background: linear-gradient(180deg, color-mix(in srgb, black 12%, transparent), transparent 30%, transparent 72%, color-mix(in srgb, black 12%, transparent)); border-block: 1px solid var(--color-divider); }
.section-intro { max-width: 720px; }
.section-intro h2 { margin: 14px 0 0; font-size: clamp(32px, 4vw, 48px); line-height: 1.1; letter-spacing: -.03em; }
.section-intro > p:last-child { max-width: 62ch; margin: 20px 0 0; font-size: 16px; line-height: 1.7; color: color-mix(in srgb, var(--color-text) 68%, transparent); }
.compact-intro h2 { font-size: clamp(30px, 3.4vw, 42px); }
/* The illustration side is a fixed-width composition of app chrome, so it takes
   the wider track and a tighter gap than the old flat mockups needed. */
.product-module { display: grid; grid-template-columns: minmax(0, .78fr) minmax(500px, 1.22fr); align-items: center; gap: clamp(40px, 5vw, 72px); padding-top: clamp(88px, 10vw, 136px); }
/* Reversing the module has to swap the track list too, not just the order of
   the items — otherwise the visual lands in the narrow track and step 02's
   window comes out ~160px narrower than the two either side of it. */
.product-module-reverse { grid-template-columns: minmax(500px, 1.22fr) minmax(0, .78fr); }
.product-module-reverse .product-copy { order: 2; }
.product-module-reverse .product-visual { order: 1; }
.step-chip { display: inline-flex; padding: 5px 9px; border: 1px solid color-mix(in srgb, var(--color-accent) 28%, transparent); border-radius: 999px; color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 7%, transparent); font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.product-name { margin: 18px 0 8px; color: var(--color-accent); font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }
.product-copy h2 { max-width: 560px; margin: 0; font-size: clamp(31px, 3.5vw, 46px); line-height: 1.08; letter-spacing: -.035em; }
.product-copy > p:not(.product-name) { max-width: 58ch; margin: 22px 0 0; font-size: 16px; line-height: 1.7; color: color-mix(in srgb, var(--color-text) 72%, transparent); }
.product-points { list-style: none; display: flex; flex-direction: column; gap: 11px; margin: 25px 0 0; padding: 0; font-size: 14px; color: color-mix(in srgb, var(--color-text) 82%, transparent); }
.product-points li { display: grid; grid-template-columns: 18px 1fr; align-items: start; gap: 9px; }
.product-points .ico { margin-top: 3px; color: var(--color-accent); }
.product-visual { overflow: hidden; min-width: 0; }

/* — Step illustrations —
   Each of the three panels is a miniature app window replaying one step of the
   routine under a demo cursor: the screener scans and sorts, the Pro chart runs
   the shared engine from js/zone-chart.js and takes an alert, the alert dialog
   is filled in and created. Timelines live in js/step-demos.js.

   All three are pictures of the product rather than working UI, so the markup
   carries role="img" and nothing in here is meant to be reached or read out.
   The height is a fixed 552px in all three: they are read as a set going down
   the page, and windows that sized to their own content would lose that rhythm.

   States are plain `is-on` classes rather than the `hidden` attribute, because
   every one of these elements sets its own `display` — and because going from
   display:none to shown is what replays the entrance animations on the toasts,
   menus and notification card each time round the loop.

   The markup ships in the state a visitor should be left with if the animation
   never runs (results listed and sorted, alert not yet set, dialog not yet
   submitted), which is also what reduced motion gets. */
.tm-win {
  position: relative; flex: none; height: 552px; display: flex; flex-direction: column;
  border: 1px solid var(--color-divider); border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--color-surface) 94%, black);
  box-shadow: 0 32px 80px rgba(0,0,0,.36), inset 0 1px 0 rgba(255,255,255,.025);
}
.tm-win .ico { vertical-align: 0; }
.tm-gap { flex: 1; }

/* Window title bar — shared by the screener and the alert dialog; the chart
   window uses the same strip with its instrument row instead of tabs. */
.tm-titlebar { display: flex; flex: none; align-items: center; justify-content: space-between; gap: 16px; height: 44px; padding: 0 14px; border-bottom: 1px solid var(--color-divider); background: color-mix(in srgb, var(--color-bg) 40%, transparent); }
.tm-tabs { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.tm-tabs img { flex: none; }
.tm-tab { padding: 5px 10px; font-size: 11.5px; white-space: nowrap; color: color-mix(in srgb, var(--color-text) 42%, transparent); }
.tm-tab.is-on { border-radius: 6px 6px 0 0; background: color-mix(in srgb, var(--color-surface) 94%, black); box-shadow: inset 0 -2px 0 var(--color-accent); font-weight: 600; color: var(--color-text); }
.tm-session { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; white-space: nowrap; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.tm-session i { display: block; width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--color-accent); box-shadow: 0 0 10px var(--color-accent); }
.tm-session b { font-weight: 400; color: color-mix(in srgb, var(--color-text) 42%, transparent); font-variant-numeric: tabular-nums; }

/* Screener toolbar */
.tm-toolbar { display: flex; flex: none; align-items: center; gap: 5px; height: 52px; padding: 0 10px; border-bottom: 1px solid var(--color-divider); overflow: hidden; }
.tm-field { display: inline-flex; align-items: center; gap: 5px; flex: 0 1 auto; min-width: 0; padding: 6px 8px; border: 1px solid var(--color-divider); border-radius: 7px; background: color-mix(in srgb, var(--color-bg) 35%, transparent); font-size: 11px; white-space: nowrap; overflow: hidden; color: color-mix(in srgb, var(--color-text) 46%, transparent); }
.tm-field > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tm-field b { flex: none; font-weight: 600; color: var(--color-text); }
.tm-field .ico { width: 11px; height: 11px; stroke-width: 1.6; }
.tm-field-grow { flex: 1 1 auto; min-width: 38px; padding: 6px 7px; font-weight: 600; color: var(--color-text); }
.tm-field-solid { padding: 6px 7px; border-color: transparent; background: var(--color-neutral-800); color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.tm-scan { display: none; align-items: center; gap: 6px; flex: none; padding: 7px 11px; border: 1px solid color-mix(in srgb, var(--color-accent) 45%, transparent); border-radius: var(--radius-md); background: color-mix(in srgb, var(--color-accent) 6%, transparent); color: var(--color-accent); font-size: 11.5px; font-weight: 600; white-space: nowrap; }
.tm-scan.is-on { display: inline-flex; }
.tm-scan .ico { width: 13px; height: 13px; stroke-width: 1.6; }
.tm-scan-busy { border-color: var(--color-accent); background: var(--color-accent); color: var(--color-bg); box-shadow: 0 8px 22px color-mix(in srgb, var(--color-accent) 18%, transparent); }
.tm-scan-busy i { display: block; animation: tmSpin 1.1s linear infinite; }

/* Scan progress strip */
.tm-progress { display: flex; flex: none; align-items: center; gap: 12px; height: 30px; padding: 0 18px; border-bottom: 1px solid var(--color-divider); background: color-mix(in srgb, var(--color-accent-900) 20%, transparent); }
.tm-progress-stage { font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; color: var(--color-accent); }
.tm-progress-track { position: relative; flex: 1; height: 2px; background: var(--color-neutral-800); overflow: hidden; }
.tm-progress-track i { position: absolute; left: 0; top: 0; height: 100%; background: linear-gradient(90deg, var(--color-accent-700), var(--color-accent)); transition: width .9s linear; }
.tm-progress-count { font-size: 10.5px; white-space: nowrap; color: color-mix(in srgb, var(--color-text) 50%, transparent); font-variant-numeric: tabular-nums; }

/* Results table. Rows share the header's track list so the columns line up. */
.tm-thead,
.tm-row { display: grid; grid-template-columns: 2.85fr .8fr .95fr 1fr 1.2fr .95fr; gap: 10px; align-items: center; padding: 0 18px; }
.tm-thead { flex: none; height: 50px; border-bottom: 1px solid var(--color-divider); font-size: 8.5px; line-height: 1.4; letter-spacing: .05em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 42%, transparent); }
.tm-thead > span:not(:first-child) { text-align: right; }
.tm-thead b { display: block; font-weight: 400; }
.tm-thead > span:first-child b { color: color-mix(in srgb, var(--color-text) 26%, transparent); font-variant-numeric: tabular-nums; }
.tm-sort { color: color-mix(in srgb, var(--color-text) 50%, transparent); }
.tm-sort b { font-weight: 500; }
.tm-sort.is-sorted { color: var(--color-text); }
.tm-sort.is-sorted b { display: flex; align-items: center; justify-content: flex-end; gap: 4px; font-weight: 600; }
.tm-sort-caret { display: none; width: 9px; height: 9px; color: var(--color-accent); stroke-width: 2.2; }
.tm-sort.is-sorted .tm-sort-caret { display: block; }

.tm-tbody { position: relative; display: flex; flex-direction: column; flex: 1; min-height: 0; }
.tm-row { position: relative; flex: 1; min-height: 0; border-bottom: 1px solid color-mix(in srgb, #dce7de 10%, transparent); font-size: 11.5px; color: color-mix(in srgb, var(--color-text) 72%, transparent); font-variant-numeric: tabular-nums; }
.tm-row > span { position: relative; }
.tm-row > span:not(:first-child) { text-align: right; }
.tm-row.is-hot::before { content: ""; position: absolute; inset: 0; background: color-mix(in srgb, var(--color-accent) 7%, transparent); box-shadow: inset 3px 0 var(--color-accent); }
.tm-sym { display: flex; align-items: center; gap: 8px; min-width: 0; overflow: hidden; }
.tm-sym i { display: grid; place-items: center; width: 22px; height: 22px; flex: none; border-radius: 50%; background: color-mix(in srgb, #dce7de 9%, transparent); font-size: 9.5px; font-style: normal; font-weight: 600; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.tm-sym b { flex: none; padding: 3px 7px; border-radius: var(--radius-sm); background: var(--color-neutral-800); font-size: 10.5px; font-weight: 600; color: var(--color-text); }
.tm-sym > span { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 11px; color: color-mix(in srgb, var(--color-text) 50%, transparent); }
.tm-dist { color: var(--color-text); font-weight: 600; }
.tm-dim { color: color-mix(in srgb, var(--color-text) 52%, transparent); }
.tm-zw { display: flex; justify-content: flex-end; align-items: center; color: color-mix(in srgb, var(--color-text) 52%, transparent); }
.tm-zw em { font-style: normal; }
.tm-open { display: none; align-items: center; gap: 4px; padding: 4px 8px; border: 1px solid color-mix(in srgb, var(--color-accent) 45%, transparent); border-radius: 6px; background: color-mix(in srgb, var(--color-accent) 8%, transparent); font-size: 10px; font-weight: 600; white-space: nowrap; color: var(--color-accent); }
.tm-open .ico { width: 11px; height: 11px; stroke-width: 1.7; }
.tm-row.is-hot .tm-zw em { display: none; }
.tm-row.is-hot .tm-open { display: inline-flex; }

/* Pre-scan state. Unlike the design this covers rows that are already in the
   DOM, so it needs its own ground rather than just sitting over empty space. */
.tm-empty { display: none; position: absolute; inset: 0; z-index: 5; flex-direction: column; align-items: center; justify-content: center; gap: 13px; padding: 0 40px; background: color-mix(in srgb, var(--color-surface) 94%, black); font-size: 12px; line-height: 1.6; text-align: center; color: color-mix(in srgb, var(--color-text) 42%, transparent); }
.tm-empty.is-on { display: flex; }
.tm-empty b { font-weight: 600; color: var(--color-accent); }
.tm-empty-mark { display: grid; place-items: center; width: 44px; height: 44px; border: 1px dashed color-mix(in srgb, #dce7de 18%, transparent); border-radius: 50%; color: color-mix(in srgb, var(--color-accent) 55%, transparent); }
.tm-empty-mark .ico { width: 20px; height: 20px; stroke-width: 1.6; }

.tm-foot { display: flex; flex: none; align-items: center; justify-content: space-between; gap: 12px; height: 36px; padding: 0 18px; font-size: 9.5px; color: color-mix(in srgb, var(--color-text) 42%, transparent); }

.tm-toast { display: none; position: absolute; z-index: 30; }
.tm-toast.is-on { display: flex; }
.tm-toast-open { left: 18px; bottom: 52px; }

/* Chart window */
.tm-titlebar-chart { justify-content: flex-start; gap: 10px; }
.tm-titlebar-chart img { flex: none; }
.tm-symbol { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.tm-symbol span { font-size: 10px; font-weight: 500; color: color-mix(in srgb, var(--color-text) 40%, transparent); }
.tm-sep { width: 1px; height: 16px; flex: none; background: var(--color-divider); }
.tm-tfbar { display: inline-flex; gap: 2px; }
.tm-tfbar b { padding: 4px 8px; border-radius: 5px; font-size: 11px; font-weight: 400; color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.tm-tfbar b.is-on { background: color-mix(in srgb, var(--color-accent) 14%, transparent); font-weight: 600; color: var(--color-accent); }
.tm-alert { display: none; align-items: center; gap: 6px; flex: none; padding: 5px 10px; border: 1px solid color-mix(in srgb, var(--color-accent) 45%, transparent); border-radius: 6px; font-size: 10.5px; font-weight: 600; white-space: nowrap; color: var(--color-accent); }
.tm-alert.is-on { display: inline-flex; }
.tm-alert .ico { width: 12px; height: 12px; stroke-width: 1.6; }
.tm-alert-set { border-color: var(--color-accent); background: var(--color-accent); color: var(--color-bg); }
.tm-pro-body { display: flex; flex: 1; min-height: 0; }
.tm-rail { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 38px; flex: none; padding: 8px 0; border-right: 1px solid var(--color-divider); background: color-mix(in srgb, var(--color-bg) 30%, transparent); }
.tm-rail > span:not(.tm-gap) { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 6px; color: color-mix(in srgb, var(--color-text) 38%, transparent); }
.tm-rail > span.is-on { background: color-mix(in srgb, var(--color-accent) 14%, transparent); color: var(--color-accent); }
.tm-rail .ico { width: 14px; height: 14px; }
.tm-plot { position: relative; flex: 1; min-width: 0; min-height: 0; overflow: hidden; }
.tm-plot-toast { position: absolute; right: 72px; top: 12px; z-index: 20; }
.tm-plot-toast .zone-chart-toast { width: 224px; border-radius: 10px; background: color-mix(in srgb, var(--color-surface) 96%, black); box-shadow: 0 16px 40px rgba(0,0,0,.55); }
.tm-plot-toast .zone-chart-toast-name { font-size: 11px; }
.tm-plot-toast .zone-chart-toast-time { font-size: 9.5px; }
.tm-plot-toast .zone-chart-toast-msg { font-size: 11px; }

/* Alert dialog */
.tm-today { display: inline-flex; align-items: center; gap: 8px; font-size: 11px; white-space: nowrap; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.tm-today b { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: var(--color-accent); font-size: 10px; font-weight: 700; color: var(--color-bg); }
.tm-dialog-head { display: flex; flex: none; align-items: center; gap: 10px; height: 52px; padding: 0 16px; border-bottom: 1px solid var(--color-divider); }
.tm-dialog-head strong { font-size: 14.5px; font-weight: 600; letter-spacing: -.01em; white-space: nowrap; }
.tm-dialog-head .tm-field { gap: 6px; padding: 4px 8px; border-radius: 6px; font-size: 11.5px; font-weight: 600; color: var(--color-text); }
.tm-dialog-head .tm-field .ico { width: 12px; height: 12px; }
.tm-dialog-tool { display: grid; place-items: center; width: 24px; height: 24px; flex: none; border-radius: 50%; color: color-mix(in srgb, var(--color-text) 40%, transparent); }
.tm-dialog-tool.is-on { background: color-mix(in srgb, var(--color-accent) 14%, transparent); color: var(--color-accent); }
.tm-dialog-tool .ico { width: 13px; height: 13px; }
.tm-caret { color: color-mix(in srgb, var(--color-text) 50%, transparent); }
.tm-fieldset { position: relative; flex: none; padding: 14px 0 8px; }
.tm-fieldset-tight { padding: 0; }
.tm-formrow { display: grid; grid-template-columns: 120px minmax(0, 1fr); align-items: center; gap: 12px; padding: 0 18px 8px; font-size: 11.5px; }
.tm-fieldset-tight .tm-formrow { height: 34px; padding: 0 18px; }
.tm-formrow > span:first-child { color: color-mix(in srgb, var(--color-text) 42%, transparent); }
.tm-formrow-add { padding: 12px 18px 0; }
.tm-select { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; height: 32px; padding: 0 10px; border: 1px solid color-mix(in srgb, #dce7de 16%, transparent); border-radius: 7px; background: color-mix(in srgb, var(--color-bg) 40%, transparent); }
.tm-select > span:first-child { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tm-select b { flex: none; margin-left: auto; font-weight: 400; color: color-mix(in srgb, var(--color-text) 40%, transparent); }
.tm-select .ico { width: 12px; height: 12px; flex: none; stroke-width: 1.6; }
.tm-plain { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.tm-plain > span { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tm-plain .ico { width: 12px; height: 12px; flex: none; stroke-width: 1.6; }
.tm-add { display: inline-flex; align-items: center; gap: 6px; color: var(--color-accent); }
.tm-add .ico { width: 12px; height: 12px; stroke-width: 1.8; }
.tm-menu { display: none; position: absolute; z-index: 30; padding: 5px; border: 1px solid color-mix(in srgb, #dce7de 18%, transparent); border-radius: 9px; background: #1b221d; box-shadow: 0 22px 50px rgba(0,0,0,.6); animation: tmMenuIn .22s cubic-bezier(.2,.7,.3,1) both; }
.tm-menu.is-on { display: block; }
.tm-menu span { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 11px; overflow: hidden; white-space: nowrap; font-size: 11.5px; color: color-mix(in srgb, var(--color-text) 72%, transparent); }
.tm-menu span.is-on { background: color-mix(in srgb, var(--color-accent) 10%, transparent); color: var(--color-accent-300); }
.tm-menu i { display: block; width: 5px; height: 5px; flex: none; border-radius: 50%; background: color-mix(in srgb, var(--color-text) 20%, transparent); }
.tm-menu span.is-on i { background: var(--color-accent); }
.tm-menu-cond { left: 150px; right: 18px; top: 96px; }
.tm-menu-trig { left: 150px; top: 30px; width: 210px; }
.tm-dialog-rule { flex: none; height: 1px; margin: 8px 18px 10px; background: color-mix(in srgb, #dce7de 13%, transparent); }
.tm-dialog-foot { display: flex; flex: none; align-items: center; gap: 10px; height: 62px; margin-top: 12px; padding: 0 18px; border-top: 1px solid color-mix(in srgb, #dce7de 13%, transparent); }
.tm-btn-ghost { display: inline-flex; align-items: center; justify-content: center; padding: 8px 15px; border: 1px solid color-mix(in srgb, #dce7de 18%, transparent); border-radius: var(--radius-md); font-size: 12px; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.tm-btn-primary,
.tm-btn-done { display: none; align-items: center; justify-content: center; gap: 6px; border-radius: var(--radius-md); font-size: 12px; font-weight: 600; white-space: nowrap; }
.tm-btn-primary.is-on,
.tm-btn-done.is-on { display: inline-flex; }
.tm-btn-primary { padding: 8px 17px; background: var(--color-accent); color: var(--color-bg); box-shadow: 0 8px 24px color-mix(in srgb, var(--color-accent) 14%, transparent); }
.tm-btn-done { padding: 8px 15px; background: var(--color-accent-800); color: var(--color-accent-100); box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 50%, transparent); }
.tm-btn-done .ico { width: 13px; height: 13px; stroke-width: 1.8; }
.tm-statusbar { display: none; flex: 1; align-items: center; gap: 9px; padding: 0 18px; font-size: 9.5px; color: color-mix(in srgb, var(--color-text) 42%, transparent); }
.tm-statusbar.is-on { display: flex; }
.tm-statusbar-live { border-top: 1px solid color-mix(in srgb, var(--color-accent) 22%, transparent); background: color-mix(in srgb, var(--color-accent-900) 28%, transparent); font-size: 11px; color: var(--color-accent-300); animation: tmToastIn .3s ease-out both; }
.tm-statusbar-live .ico { width: 14px; height: 14px; stroke-width: 1.6; }
.tm-push { display: none; position: absolute; right: 16px; bottom: 104px; z-index: 40; align-items: center; gap: 10px; width: 262px; padding: 10px 12px; border: 1px solid var(--color-divider); border-radius: 12px; background: #1b221d; box-shadow: 0 20px 46px rgba(0,0,0,.6); animation: tmPushIn .34s cubic-bezier(.2,.7,.3,1) both; }
.tm-push.is-on { display: flex; }
.tm-push img { flex: none; }
.tm-push-body { min-width: 0; flex: 1; }
.tm-push-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.tm-push-head strong { font-size: 11.5px; font-weight: 600; }
.tm-push-head > span { font-size: 10px; color: color-mix(in srgb, var(--color-text) 40%, transparent); }
.tm-push-msg { display: block; margin-top: 2px; font-size: 11px; color: var(--color-accent); }

/* Demo cursor. Parked off the top-right corner so it is clipped away until the
   timeline moves it; js sets left/top and the transition does the travel. */
.tm-cursor { position: absolute; left: 100%; top: -70px; z-index: 40; pointer-events: none; transition: left .85s cubic-bezier(.4,0,.2,1), top .85s cubic-bezier(.4,0,.2,1); }
.tm-cursor-arrow { display: block; fill: var(--color-bg); stroke: var(--color-text); stroke-width: 1.5; stroke-linejoin: round; filter: drop-shadow(0 5px 12px rgba(0,0,0,.7)); }
.tm-cursor-click { position: absolute; left: -13px; top: -13px; width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid color-mix(in srgb, var(--color-accent) 90%, transparent); background: color-mix(in srgb, var(--color-accent) 16%, transparent); opacity: 0; }
.tm-cursor.is-click .tm-cursor-click { animation: tmClick .55s ease-out both; }

@keyframes tmSpin { to { transform: rotate(360deg); } }
@keyframes tmClick { from { transform: scale(.5); opacity: .95; } to { transform: scale(1.6); opacity: 0; } }
@keyframes tmMenuIn { from { opacity: 0; transform: translateY(6px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes tmPushIn { from { opacity: 0; transform: translate(14px, -8px) scale(.96); } to { opacity: 1; transform: none; } }

/* Below this the six-column table stops holding a price without clipping, so
   the illustration sheds what it can spare: the columns either side of the two
   the copy actually names, the company names, the saved-watchlist chip and the
   result count — the disclaimer beside it stays. The cursor goes too. Its
   targets are written as percentages of the desktop track list, and there is
   no honest way to re-aim a pointer at columns that are no longer there; the
   states it drives still play, so the sequence reads without it. */
@media (max-width: 560px) {
  /* Two groups of nowrap text either side of one title bar collide long before
     they wrap. The background tabs and the clock are the parts that carry no
     meaning, so they go and the open tab keeps its room. */
  .tm-tab:not(.is-on) { display: none; }
  .tm-session b { display: none; }
  /* The chart window is the one panel whose content is not a fixed stack, and
     at this width a 552px box leaves the plot taller than it is wide. */
  .tm-pro { height: 400px; }
  .tm-thead,
  .tm-row { grid-template-columns: 2.4fr .8fr 1fr .95fr; padding: 0 12px; }
  .tm-thead > span:nth-child(4),
  .tm-thead > span:nth-child(5),
  .tm-row > span:nth-child(4),
  .tm-row > span:nth-child(5) { display: none; }
  .tm-sym > span { display: none; }
  .tm-toolbar > .tm-field:first-child { display: none; }
  .tm-progress,
  .tm-foot { padding: 0 12px; }
  .tm-foot [data-foot] { display: none; }
  .tm-toast-open { left: 12px; right: 12px; }
  /* The instrument row runs out of width first. The timeframe tabs go rather
     than the alert button the step is about — the L/T/E read-out at the foot of
     the plot still names all three timeframes. */
  .tm-tfbar,
  .tm-titlebar-chart .tm-sep { display: none; }
  .tm-plot-toast { left: 10px; right: 10px; }
  .tm-plot-toast .zone-chart-toast { width: auto; }
  .tm-formrow { grid-template-columns: 84px minmax(0, 1fr); gap: 10px; }
  .tm-menu-cond,
  .tm-menu-trig { left: 106px; }
  .tm-menu-trig { width: auto; right: 18px; }
  .tm-push { left: 16px; width: auto; }
  .tm-cursor { display: none; }
}

/* js/step-demos.js already stands the timelines down here — this covers the
   entrance animations, which belong to the elements rather than the loop. */
@media (prefers-reduced-motion: reduce) {
  .tm-cursor { display: none; }
  .tm-progress-track i { transition: none; }
  .tm-scan-busy i,
  .tm-menu,
  .tm-push,
  .tm-statusbar-live { animation: none; }
}

.feature-section,
.pricing-section,
.academy-section { padding-top: clamp(84px, 10vw, 132px); padding-bottom: clamp(84px, 10vw, 132px); }
.feature-grid { display: grid; grid-template-columns: repeat(4, 1fr); margin-top: 48px; border-top: 1px solid var(--color-divider); border-left: 1px solid var(--color-divider); }
.feature-grid article { min-height: 180px; padding: 24px; border-right: 1px solid var(--color-divider); border-bottom: 1px solid var(--color-divider); background: color-mix(in srgb, var(--color-surface) 65%, transparent); }
.feature-grid .ico { color: var(--color-accent); }
.feature-grid h3 { margin: 38px 0 0; font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.feature-grid p { margin: 8px 0 0; font-size: 12.5px; line-height: 1.55; color: color-mix(in srgb, var(--color-text) 54%, transparent); }
.private-engine-section { padding-bottom: clamp(84px, 10vw, 132px); }
.private-engine-panel { display: grid; grid-template-columns: .95fr 1.05fr; gap: clamp(44px, 7vw, 100px); align-items: center; padding: clamp(28px, 5vw, 54px); border: 1px solid color-mix(in srgb, var(--color-accent) 26%, transparent); border-radius: var(--radius-lg); background: linear-gradient(135deg, color-mix(in srgb, var(--color-accent-900) 55%, transparent), transparent 54%), var(--color-surface); }
.private-engine-copy h2 { max-width: 620px; margin: 15px 0 0; font-size: clamp(31px, 3.5vw, 45px); line-height: 1.08; letter-spacing: -.035em; }
.private-engine-copy > p:last-child { max-width: 58ch; margin: 20px 0 0; font-size: 15px; line-height: 1.72; color: color-mix(in srgb, var(--color-text) 68%, transparent); }
.private-engine-list { border-top: 1px solid var(--color-divider); }
.private-engine-list > div { display: grid; grid-template-columns: .85fr 1.15fr; gap: 20px; padding: 18px 2px; border-bottom: 1px solid var(--color-divider); }
.private-engine-list span { font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--color-accent); }
.private-engine-list strong { font-size: 13px; line-height: 1.5; font-weight: 500; color: color-mix(in srgb, var(--color-text) 84%, transparent); }
.comparison-section,
.faq-section { padding: clamp(84px, 10vw, 132px) 0; background: color-mix(in srgb, var(--color-surface) 45%, transparent); border-block: 1px solid var(--color-divider); }
.comparison-table-wrap { margin-top: 44px; overflow-x: auto; border: 1px solid var(--color-divider); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--color-bg) 70%, transparent); }
.comparison-table { width: 100%; min-width: 680px; border-collapse: collapse; font-size: 13px; }
.comparison-table th,
.comparison-table td { padding: 17px 20px; border-bottom: 1px solid var(--color-divider); text-align: left; }
.comparison-table th:not(:first-child),
.comparison-table td:not(:first-child) { text-align: center; }
.comparison-table thead th { font-size: 14px; font-weight: 600; color: var(--color-text); background: color-mix(in srgb, var(--color-surface) 82%, transparent); }
.comparison-table thead span { display: block; margin-top: 3px; font-size: 9px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.comparison-table tbody tr:last-child td { border-bottom: 0; }
.comparison-table tbody td:first-child { width: 48%; color: color-mix(in srgb, var(--color-text) 76%, transparent); }
.comparison-table .ico { color: var(--color-accent); }
.comparison-table .is-muted { color: color-mix(in srgb, var(--color-text) 24%, transparent); }
.comparison-table .pro-column { color: var(--color-accent); }
.pricing-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; max-width: 900px; margin-top: 48px; }
.price-card { position: relative; display: flex; flex-direction: column; min-height: 500px; padding: clamp(24px, 4vw, 38px); border: 1px solid var(--color-divider); border-radius: var(--radius-lg); background: var(--color-surface); }
.price-card-featured { border-color: color-mix(in srgb, var(--color-accent) 55%, transparent); box-shadow: 0 26px 70px color-mix(in srgb, var(--color-accent) 7%, transparent); }
.popular-label { position: absolute; right: 18px; top: 18px; padding: 5px 8px; border-radius: 999px; background: var(--color-accent); color: var(--color-bg); font-size: 9px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.price-eyebrow { margin: 0; color: var(--color-accent); font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.price-card h3 { margin: 24px 0 0; font-size: 38px; font-weight: 600; letter-spacing: -.035em; }
.price-card h3 span { font-size: 13px; font-weight: 400; color: color-mix(in srgb, var(--color-text) 52%, transparent); }
.price-offer { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 12px; margin-top: 22px; }
.price-offer del { color: color-mix(in srgb, var(--color-text) 52%, transparent); font-size: 16px; }
.price-offer h3 { margin: 0; }
.price-offer > strong { padding: 4px 7px; border-radius: 999px; background: color-mix(in srgb, var(--color-accent) 12%, transparent); color: var(--color-accent); font-size: 9px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.price-summary { min-height: 52px; margin: 16px 0 0; font-size: 14px; line-height: 1.6; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.price-list { list-style: none; display: flex; flex-direction: column; gap: 12px; margin: 26px 0 30px; padding: 22px 0 0; border-top: 1px solid var(--color-divider); color: color-mix(in srgb, var(--color-text) 78%, transparent); font-size: 13px; }
.price-list li { display: grid; grid-template-columns: 18px 1fr; gap: 8px; }
.price-list .ico { color: var(--color-accent); }
.price-card .btn { margin-top: auto; }
/* The small print under each plan and the disclaimer below the grid are the two
   pieces of pricing text a regulator would read first, so they clear AA rather
   than sitting at the decorative end of the scale. 55% is 5.66:1 on the ground;
   62% is 6.90:1 and matches .price-summary. */
.price-card small { display: block; margin-top: 14px; min-height: 36px; font-size: 10.5px; line-height: 1.55; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.pricing-disclaimer { max-width: 880px; margin: 24px 0 0; font-size: 11.5px; line-height: 1.65; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.faq-layout { display: grid; grid-template-columns: .65fr 1.35fr; gap: clamp(48px, 8vw, 120px); align-items: start; }
.text-link { display: inline-flex; align-items: center; gap: 7px; margin-top: 26px; font-size: 13px; text-decoration: none; }
.faq-list { border-top: 1px solid var(--color-divider); }
.faq-list details { border-bottom: 1px solid var(--color-divider); }
.faq-list summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 22px 2px; cursor: pointer; font-size: 15px; font-weight: 500; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary .ico { color: var(--color-accent); transition: transform .18s ease; }
.faq-list details[open] summary .ico { transform: rotate(180deg); }
.faq-list details p { max-width: 70ch; margin: -4px 40px 22px 2px; font-size: 13.5px; line-height: 1.7; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.academy-panel { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(48px, 8vw, 112px); padding: clamp(30px, 5vw, 56px); border: 1px solid color-mix(in srgb, var(--color-accent) 24%, transparent); border-radius: var(--radius-lg); background: radial-gradient(600px 340px at 0 0, color-mix(in srgb, var(--color-accent-900) 65%, transparent), transparent 70%), var(--color-surface); }
.academy-copy h2 { margin: 16px 0 0; font-size: clamp(31px, 3.6vw, 46px); line-height: 1.08; letter-spacing: -.03em; }
.academy-copy > p:last-of-type { max-width: 55ch; margin: 20px 0 0; font-size: 15px; line-height: 1.7; color: color-mix(in srgb, var(--color-text) 68%, transparent); }
.academy-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 27px; }
.lesson-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--color-divider); }
.lesson-list li { display: grid; grid-template-columns: 34px 1fr; gap: 14px; padding: 18px 4px; border-bottom: 1px solid var(--color-divider); }
.lesson-list li > span { color: var(--color-accent); font-size: 11px; }
.lesson-list strong { display: block; font-size: 14px; font-weight: 600; }
/* 52%, not 48%: this list sits on --color-surface, where 48% lands at 4.46:1 —
   under AA by a hair. 48% only clears on the darker --color-bg ground. */
.lesson-list small { display: block; margin-top: 5px; font-size: 11.5px; color: color-mix(in srgb, var(--color-text) 52%, transparent); }
.footer-rule { margin: 36px 0 24px; }

@media (max-width: 900px) {
  /* .landing-hero is absent on purpose — its auto-fit track folds itself. */
  .product-module,
  .faq-layout,
  .academy-panel,
  .private-engine-panel { grid-template-columns: 1fr; }
  .landing-hero { padding-top: 72px; }
  .product-module-reverse .product-copy,
  .product-module-reverse .product-visual { order: initial; }
  .product-module-reverse .product-copy { order: 1; }
  .product-module-reverse .product-visual { order: 2; }
  .feature-grid { grid-template-columns: repeat(2, 1fr); }
  .faq-layout { gap: 44px; }
  .private-engine-panel { gap: 38px; }
}
/* Below this the stage is narrower than the 560px the overlap is tuned for and
   the chart panel drops under a readable width, so the composition gives up
   and the panels simply stack. The bell and the alert column go with it — both
   are decorative, and the alerts would add half a screen of height for no new
   information. */
@media (max-width: 560px) {
  .hero-stage { height: auto; max-width: none; display: flex; flex-direction: column; gap: 16px; }
  .hero-stage-glow,
  .hero-stage-alerts,
  .hero-stage-bell { display: none; }
  .hero-stage-chart,
  .hero-stage .hero-scan { position: static; width: auto; transform: none; animation: none; }
  .hero-stage-chart { height: auto; }
  .hero-stage-plot { height: 260px; }
}

@media (max-width: 600px) {
  .landing-hero h1 { font-size: clamp(42px, 13vw, 58px); }
  .terminal-chart { height: 260px; }
  .terminal-stats { grid-template-columns: repeat(2, 1fr); }
  .terminal-stats > div:nth-child(3) { border-left: 0; }
  .product-module { grid-template-columns: minmax(0, 1fr); padding-top: 86px; }
  .feature-grid { grid-template-columns: 1fr; }
  .feature-grid article { min-height: 150px; }
  .pricing-grid { grid-template-columns: 1fr; }
  .price-card { min-height: auto; }
  .price-summary { min-height: auto; }
  .faq-list summary { font-size: 14px; }
  .hero-scan-row { grid-template-columns: 1.2fr .75fr .7fr; padding-inline: 12px; }
  .hero-scan-row > :nth-child(2) { display: none; }
  .private-engine-list > div { grid-template-columns: 1fr; gap: 7px; }
}

/* — skip link — */
.skip-link {
  position: fixed; top: 10px; left: 10px; z-index: 200;
  padding: 9px 15px; border-radius: var(--radius-md);
  background: var(--color-surface); box-shadow: var(--shadow-md);
  color: var(--color-text); font-size: 13.5px; text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus-visible { transform: none; }

/* — header —
   Above 1000px the section links sit inline: the three products collapsed
   behind one dropdown, then a hairline, then everything else. Below it they
   move into the menu panel, where they can be grouped and labelled properly. */
.site-nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--color-bg) 82%, transparent);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.site-nav::after {
  content: ""; display: block; height: 1px;
  background: linear-gradient(to right, transparent, var(--color-divider) 48px calc(100% - 48px), transparent);
}
.site-nav nav {
  max-width: var(--page-max); margin: 0 auto;
  display: flex; align-items: center; gap: clamp(14px, 2.2vw, 26px);
  padding: 12px var(--page-pad);
}
.site-nav .nav-brand {
  color: var(--color-text); text-decoration: none; margin-right: auto;
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  font-family: var(--font-heading); font-size: 17px; font-weight: 600;
  letter-spacing: -.035em;
}
.brand-mark {
  width: 30px; height: 30px; flex: none;
  filter: drop-shadow(0 6px 10px color-mix(in srgb, var(--color-accent) 17%, transparent));
}
.brand-name { display: inline-flex; align-items: baseline; }
.brand-name span { color: var(--color-accent); }
.nav-brand:hover .brand-name { color: var(--color-text); }
.nav-brand:hover .brand-mark { filter: drop-shadow(0 6px 12px color-mix(in srgb, var(--color-accent) 32%, transparent)); }
.site-nav-links { display: flex; align-items: center; gap: clamp(14px, 2.2vw, 24px); }
.site-nav-links a {
  font-size: 13.5px; white-space: nowrap; text-decoration: none;
  color: color-mix(in srgb, var(--color-text) 72%, transparent); padding: 6px 0;
}
.site-nav-links a:hover,
.site-nav-links a[aria-current="page"] { color: var(--color-accent); }
.nav-sep { width: 1px; height: 15px; flex: none; background: var(--color-divider); }
.site-nav-cta { white-space: nowrap; font-size: 13.5px; padding: 7px 14px; }

/* — products dropdown —
   The shared navigation script keeps visual, pointer and ARIA state aligned.
   The trigger is a button because Products reveals choices rather than
   navigating to a separate page. */
.nav-drop { position: relative; display: flex; align-items: center; }
.nav-drop-trigger {
  display: inline-flex; align-items: center; gap: 5px;
  font: inherit; font-size: 13.5px; white-space: nowrap;
  background: none; border: 0; margin: 0; padding: 6px 0; cursor: pointer;
  color: color-mix(in srgb, var(--color-text) 72%, transparent);
}
.nav-drop.is-open .nav-drop-trigger { color: var(--color-accent); }
.nav-drop-caret { transition: transform .18s ease; }
.nav-drop.is-open .nav-drop-caret { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .nav-drop-caret { transition: none; } }
.nav-drop-panel {
  position: absolute; top: 100%; left: -18px; z-index: 1;
  width: 290px; margin-top: 10px; padding: 8px;
  background: var(--color-surface);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  visibility: hidden; opacity: 0; transform: translateY(-4px);
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}
.nav-drop-panel::before { content: ""; position: absolute; left: 0; right: 0; top: -10px; height: 10px; }
.nav-drop.is-open .nav-drop-panel {
  visibility: visible; opacity: 1; transform: none;
  transition: opacity .16s ease, transform .16s ease, visibility 0s;
}
@media (prefers-reduced-motion: reduce) { .nav-drop-panel { transition: none; } }
.site-nav-links .nav-drop-panel a {
  display: block; padding: 9px 10px; border-radius: var(--radius-md);
  font-size: 14px; white-space: normal; color: var(--color-text);
}
.site-nav-links .nav-drop-panel a:hover,
.site-nav-links .nav-drop-panel a:focus-visible {
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--color-accent);
}
.nav-drop-panel a span {
  display: block; margin-top: 1px; font-size: 12.5px; line-height: 18px;
  color: color-mix(in srgb, var(--color-text) 52%, transparent);
}
.nav-drop-panel a:hover span,
.nav-drop-panel a:focus-visible span { color: color-mix(in srgb, var(--color-text) 62%, transparent); }

.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
  color: var(--color-text); background: transparent; cursor: pointer;
}
.nav-toggle:hover { border-color: color-mix(in srgb, var(--color-accent) 55%, transparent); color: var(--color-accent); }

/* — accessible mobile menu panel — */
.nav-menu { position: fixed; inset: 0; z-index: 60; overflow: hidden; pointer-events: none; scroll-margin: 0; contain: layout paint; }
.nav-menu.is-open { pointer-events: auto; }
.nav-open { overflow: hidden; }
.nav-menu-scrim {
  position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; opacity: 0; transition: opacity .2s ease;
  background: color-mix(in srgb, #0b0c14 66%, transparent);
}
.nav-menu.is-open .nav-menu-scrim { opacity: 1; }
.nav-menu-panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(330px, 100%);
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--color-bg); border-left: 1px solid var(--color-divider);
  padding: 12px 20px 32px;
  visibility: hidden; transform: translateX(101%);
  transition: transform .22s ease, visibility 0s linear .22s;
}
.nav-menu.is-open .nav-menu-panel { visibility: visible; transform: none; transition: transform .22s ease, visibility 0s; }
@media (prefers-reduced-motion: reduce) { .nav-menu-scrim, .nav-menu-panel { transition: none; } }
.nav-menu-head {
  display: flex; align-items: center; justify-content: space-between;
  height: calc(var(--nav-h) - 25px); margin-bottom: 10px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.nav-menu-close { display: inline-flex; padding: 6px; margin-right: -6px; border: 0; background: transparent; color: var(--color-text); cursor: pointer; }
.nav-menu-close:hover { color: var(--color-accent); }
.nav-menu-label {
  margin: 20px 0 2px; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-accent);
  background: linear-gradient(to right, var(--color-divider), transparent 78%) no-repeat top / 100% 1px;
  padding-top: 16px;
}
.nav-menu-label:first-of-type { margin-top: 4px; background: none; padding-top: 0; }
.nav-menu-panel a.nav-menu-item {
  display: block; padding: 9px 0; text-decoration: none; color: var(--color-text); font-size: 15px;
}
.nav-menu-panel a.nav-menu-item:hover { color: var(--color-accent); }
.nav-menu-item span {
  display: block; margin-top: 1px; font-size: 12.5px; line-height: 18px;
  color: color-mix(in srgb, var(--color-text) 52%, transparent);
}
.nav-menu-item[aria-current="page"] { color: var(--color-accent); }
.nav-menu-cta { margin-top: 22px; width: 100%; }

@media (max-width: 1000px) {
  .site-nav-links { display: none; }
  .nav-toggle { display: inline-flex; }
}
@media (min-width: 1001px) { .nav-menu { display: none; } }
@media (max-width: 520px) {
  .site-nav nav { gap: 12px; padding: 9px 20px; }
  .site-nav .nav-brand { font-size: 15.5px; gap: 8px; }
  .brand-mark { width: 28px; height: 28px; }
  .site-nav-cta { font-size: 13px; padding: 6px 10px; }
}
/* Under ~390px the wordmark, the CTA and the toggle stop fitting on one line;
   the CTA is the one that can go, because the menu carries it too. */
@media (max-width: 389px) { .site-nav-cta { display: none; } }

/* — chapter breaks —
   index.html runs several full sections deep, so the join between two of them
   has to read differently from the hairlines used inside one. This one is
   taller, carries the number and name of the section starting below it, and
   hangs a way back to the top off the same row. */
.chapter-break {
  display: flex; align-items: center; gap: 16px;
  padding: 22px 0 0; margin-top: 64px;
  background: linear-gradient(to right, transparent, var(--color-divider) 48px calc(100% - 48px), transparent) no-repeat top / 100% 1px;
}
.chapter-break-label {
  display: flex; align-items: baseline; gap: 10px; margin: 0; margin-right: auto;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 62%, transparent);
}
.chapter-break-label b { font-weight: inherit; font-feature-settings: 'tnum' 1; color: var(--color-accent); }
.chapter-break-top {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; letter-spacing: .04em; text-decoration: none;
  color: color-mix(in srgb, var(--color-text) 48%, transparent);
}
.chapter-break-top:hover { color: var(--color-accent); }

/* — on this page —
   A directory of the sections below, so the shape of a long page is visible
   before you start scrolling it. */
.toc { list-style: none; margin: 26px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); gap: 0 clamp(28px, 4vw, 56px); }
.toc a {
  display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: baseline;
  gap: 4px 6px; padding: 15px 6px; text-decoration: none; color: inherit;
  background: linear-gradient(to right, transparent, var(--color-neutral-700) 24px calc(100% - 24px), transparent) no-repeat top / 100% 1px;
  border-radius: var(--radius-sm);
}
.toc a:hover { background-color: color-mix(in srgb, var(--color-text) 4%, transparent); }
.toc a:hover .toc-t { color: var(--color-accent); }
.toc-n { font-family: var(--font-heading); font-size: 12px; font-feature-settings: 'tnum' 1; color: var(--color-accent); }
.toc-t { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px; line-height: 24px; }
.toc-d { grid-column: 2; margin: 0; font-size: 13.5px; line-height: 21px; color: color-mix(in srgb, var(--color-text) 62%, transparent); }

/* — footer — */
.site-footer {
  background:
    radial-gradient(760px 260px at 12% 0, color-mix(in srgb, var(--color-accent-900) 48%, transparent), transparent 66%),
    color-mix(in srgb, black 22%, transparent);
  padding: 48px 0 40px; margin-top: 8px;
}
.site-footer-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr)); gap: 32px; }
.site-footer h2 {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; margin: 0 0 12px;
  font-weight: var(--font-heading-weight); line-height: 1.4;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.site-footer nav { display: flex; flex-direction: column; gap: 8px; font-size: 14px; }
.site-footer nav a { color: color-mix(in srgb, var(--color-text) 78%, transparent); text-decoration: none; }
.site-footer nav a:hover { color: var(--color-accent); text-decoration: underline; }
.site-footer-legal { font-size: 13px; line-height: 21px; margin: 0; max-width: 82ch; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.site-footer-copy { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: 13px; margin: 16px 0 0; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.site-footer-copy a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 5px; }
.site-footer-copy a:hover { color: var(--color-accent); }

/* — floating access CTA —
   The same button as the header CTA, turned on its side and fixed to the left
   edge of every page, so the route to checkout survives a long scroll. It
   borrows .btn-primary and only redefines what a floating tab needs: the turn,
   the tab shape, a shadow deep enough to lift it off the content it covers, and
   the hidden state the script toggles. The script decides *when* — past the
   opening screen, and out of the way whenever a page's own primary CTA is on
   show.

   vertical-rl turns the line sideways; the half-turn then sets it reading bottom
   to top, the way a left-edge tab is normally read. That half-turn means the
   button's own frame is a mirror of the screen: what it calls its left edge and
   its forward direction both come out on the opposite side. Every rule below is
   written in the button's frame, so read them through the turn. */
.floating-cta {
  --cta-rest: translateY(-50%) rotate(180deg);
  position: fixed; z-index: 40;
  left: 0; top: 50%;
  writing-mode: vertical-rl;
  padding: 20px 12px;
  /* Rounded on its left corners, which the turn puts on the page-facing edge;
     the two against the window stay square so the tab reads as attached. */
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  font-size: 14.5px; letter-spacing: .01em; white-space: nowrap;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--color-accent) 45%, transparent),
    10px 0 30px color-mix(in srgb, var(--color-accent) 20%, transparent),
    6px 0 20px color-mix(in srgb, black 45%, transparent);
  /* Parked just off the edge until the script calls it in. */
  visibility: hidden; opacity: 0; transform: var(--cta-rest) translateX(26px);
  transition: opacity .2s ease, transform .2s ease, visibility 0s linear .2s;
}
/* Upright in the flow, so the arrow needs turning to travel with the text —
   forward here is down the button's frame, which the half-turn sends up. */
.floating-cta .ico { transform: rotate(90deg); vertical-align: 0; }
/* Nocturne steps .ico-go forward on hover, and does it from a selector that
   outweighs the turn above — left alone, the arrow drops back to its unturned
   bearing the moment the pointer arrives. Restating both keeps the step and
   keeps it pointing the way the text reads. */
.floating-cta:hover .ico { transform: rotate(90deg) translateX(2px); }
.floating-cta.is-visible {
  visibility: visible; opacity: 1; transform: var(--cta-rest);
  transition: opacity .2s ease, transform .2s ease, visibility 0s;
}
/* .btn-primary presses down; a tab against the window presses in. */
.floating-cta.is-visible:active { transform: var(--cta-rest) translateX(2px); }
/* The global focus ring is the accent itself, which disappears against a filled
   accent tab; the text colour is the one that reads here. */
.floating-cta:focus-visible { outline: 2px solid var(--color-text); outline-offset: 3px; }
/* The menu panel covers the page and carries this CTA itself. */
.nav-open .floating-cta.is-visible {
  visibility: hidden; opacity: 0; transform: var(--cta-rest) translateX(26px);
  transition: opacity .2s ease, transform .2s ease, visibility 0s linear .2s;
}
@media (max-width: 520px) { .floating-cta { padding: 17px 11px; font-size: 14px; } }
/* The turn is layout, not motion, so only the slide is dropped. */
@media (prefers-reduced-motion: reduce) {
  .floating-cta, .nav-open .floating-cta.is-visible { transform: var(--cta-rest); transition: none; }
}
@media print { .floating-cta { display: none; } }

/* — quick chat —
   The bottom-right question panel, injected by js/quick-chat.js. The floating
   CTA is a tab on the left edge, so the two never meet; the panel sits under
   the header (50) and under the mobile menu (60) so an open menu covers it,
   which is the same deal the CTA takes.

   Nothing here restyles the form itself: the panel borrows .btn, .field and
   .input from nocturne.css, so it inherits the site's controls rather than
   growing a second set that drifts from them. */
.qc {
  position: fixed; z-index: 45;
  right: clamp(14px, 3vw, 26px); bottom: clamp(14px, 3vw, 26px);
  display: flex; flex-direction: column-reverse; align-items: flex-end; gap: 12px;
  /* The container is wider than its children on small screens, and a
     transparent box still swallows clicks; only the panel and pill take them. */
  pointer-events: none;
}
.qc > * { pointer-events: auto; }
/* Every toggled part of the panel is switched with the hidden attribute. This
   one rule outranks the display each of them sets, so hiding cannot silently
   fail the way it does when a display rule quietly wins. */
.qc [hidden] { display: none; }

.qc-launcher {
  display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
  padding: 11px 16px 11px 14px; border-radius: 999px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1.2; color: var(--color-text);
  /* The accent carries the glyph, not the pill — a filled accent circle would
     be the largest accent area on the page and outshout the real CTA. */
  background: color-mix(in srgb, var(--color-surface) 94%, black);
  border: 1px solid var(--color-divider);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
  transition: border-color .18s ease, background .18s ease, transform .18s ease;
}
.qc-launcher .ico { color: var(--color-accent); }
.qc-launcher:hover {
  transform: translateY(-1px);
  border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
  background: color-mix(in srgb, var(--color-surface) 100%, black);
}
.qc-launcher:active { transform: translateY(0); }

.qc-panel {
  display: flex; flex-direction: column; overflow: hidden;
  width: 360px; max-width: calc(100vw - 28px);
  max-height: min(560px, calc(100vh - var(--nav-h) - 96px));
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .65);
  animation: qcIn .2s cubic-bezier(.2, .7, .3, 1) both;
  transform-origin: 100% 100%;
}
/* The dynamic unit keeps the panel clear of a phone's collapsing browser bar. */
@supports (height: 100dvh) {
  .qc-panel { max-height: min(560px, calc(100dvh - var(--nav-h) - 96px)); }
}
@keyframes qcIn { from { opacity: 0; transform: translateY(8px) scale(.98); } }

.qc-head {
  flex: none; display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; padding: 15px 13px 13px 18px;
  border-bottom: 1px solid var(--color-divider);
}
.qc-kicker {
  display: block; font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--color-accent);
}
/* A paragraph, not a heading: the panel is on all ten pages and a real <h2>
   would inject a stray branch into every one of their outlines. The dialog
   takes its accessible name from it either way. */
.qc-title {
  margin: 4px 0 0; font-family: var(--font-heading);
  font-weight: var(--font-heading-weight); font-size: 17px; line-height: 1.2;
}
.qc-scope {
  margin: 5px 0 0; font-size: 11.5px; line-height: 17px;
  color: color-mix(in srgb, var(--color-text) 58%, transparent);
}
.qc-close { flex: none; color: color-mix(in srgb, var(--color-text) 60%, transparent); }
.qc-close:hover { color: var(--color-text); background: color-mix(in srgb, var(--color-text) 8%, transparent); }

.qc-form, .qc-done { padding: 16px 18px 18px; overflow-y: auto; }
.qc-form .field + .field { margin-top: 12px; }
/* Shorter than nocturne's 90px default so the complete form clears the fold on
   a laptop without making its own scrollbar. */
.qc-form textarea.input { min-height: 74px; }
/* Off-screen rather than display:none — a bot filling every field trips it, a
   reader never sees it, and a screen reader skips it on the aria-hidden. */
.qc-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.qc-consent {
  display: flex; align-items: flex-start; gap: 9px; cursor: pointer;
  margin-top: 12px; font-size: 11.5px; line-height: 17px;
  color: color-mix(in srgb, var(--color-text) 68%, transparent);
}
.qc-consent input {
  width: 15px; height: 15px; flex: none; margin: 1px 0 0;
  accent-color: var(--color-accent);
}
.qc-privacy-link { white-space: nowrap; }
/* Nocturne is lime and teal with no negative tone, and neither accent can be
   made to read as "wrong". One warm colour is scoped to the panel instead —
   8.4:1 on the surface, so it clears AA as body text. */
.qc { --qc-warn: #ff9d84; }
.qc-error { margin: 12px 0 0; font-size: 13px; line-height: 20px; color: var(--qc-warn); }
.qc-submit-row { display: flex; justify-content: flex-end; margin-top: 14px; }
.qc-submit { min-width: 142px; min-height: 38px; }

.qc-status { display: flex; align-items: flex-start; gap: 8px; margin: 0; font-size: 13.5px; line-height: 21px; }
.qc-status .ico { flex: none; margin-top: 3px; }
.qc-status.is-pending { color: color-mix(in srgb, var(--color-text) 68%, transparent); }
.qc-status.is-sent .ico { color: var(--color-accent); }
.qc-status.is-failed { color: var(--qc-warn); }
.qc-status.is-failed a { color: inherit; }

.qc-matches { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--color-divider); }
.qc-matches-head {
  margin: 0 0 4px; font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--color-accent);
}
.qc-match + .qc-match { border-top: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent); }
.qc-match-q {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  list-style: none; cursor: pointer; padding: 11px 0;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 20px;
}
.qc-match-q::-webkit-details-marker { display: none; }
.qc-match-q:hover { color: var(--color-accent); }
.qc-match-q .ico { flex: none; color: var(--color-accent); transition: transform .2s ease; }
.qc-match[open] .qc-match-q .ico { transform: rotate(180deg); }
.qc-match-a {
  padding: 0 0 13px; font-size: 13px; line-height: 21px;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}
.qc-actions { display: flex; align-items: center; gap: 8px; margin-top: 18px; }

/* Below this the pill would crowd the panel it opens, so it becomes a disc and
   the panel spans the width. The button keeps its name through aria-label. */
@media (max-width: 560px) {
  .qc { left: 12px; right: 12px; bottom: 12px; }
  .qc-panel { width: 100%; max-width: none; }
  .qc-launcher { width: 52px; height: 52px; padding: 0; justify-content: center; }
  .qc-launcher-text {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
  }
}
/* The menu panel covers the page and offers Support itself. */
.nav-open .qc { display: none; }
@media (prefers-reduced-motion: reduce) {
  .qc-panel { animation: none; }
  .qc-launcher, .qc-match-q .ico { transition: none; }
}
@media print { .qc { display: none; } }

/* — access request form —
   The Get Access form's JS-injected parts: an error line, the honeypot, and the
   confirmation that replaces the form on success. Same pattern as .qc-* above —
   the markup is built by js/access-request.js rather than pasted into the page,
   so nothing here has a counterpart in get-access.html. */
.ga-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* Same warm tone as the quick-chat panel's, for the same reason: Nocturne's
   lime and teal carry no sense of "wrong". 6.6:1 on --color-bg. */
.ga-error { margin: 0; font-size: 13px; line-height: 20px; color: #ff9d84; }
.ga-error a { color: inherit; }

.ga-done {
  max-width: 520px; padding: 26px 28px;
  border: 1px solid color-mix(in srgb, var(--color-accent) 45%, transparent);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--color-accent-900) 30%, var(--color-surface));
}
.ga-done-title {
  margin: 0; font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 19px; line-height: 26px; color: var(--color-accent-200);
}
.ga-done-body { margin: 12px 0 0; font-size: 14.5px; line-height: 24px; color: color-mix(in srgb, var(--color-text) 82%, transparent); }
/* The two echoed values are the ones the reader most needs to check for typos,
   so they are pulled out of the sentence rather than blending into it. */
.ga-done-email, .ga-done-tv { color: var(--color-text); word-break: break-word; }
