/*
 * Passo Trading landing page, major revision pass.
 *
 * Color tokens are copied verbatim from src/theme/tokens.css for visual continuity with the
 * actual product (accent is magenta now, the final decision after gold, which itself replaced
 * the original spec's violet, see tokens.css's own header comment). A handful of landing-only
 * tokens are derived from those same values (never a new hue) for gradients/glows the
 * dashboard itself has no use for.
 *
 * Type: Inter for both headings and body (Linear's actual stack, verified live), IBM Plex
 * Mono kept for kickers/data-flavored labels only. "Inter" (the literal Google Fonts family
 * name) has to lead the stack, not just "Inter Variable", or the loaded webfont never
 * matches and every browser silently falls through to a system font instead.
 */

:root {
  /* --- Product tokens (verbatim from src/theme/tokens.css) --- */
  --color-bg: #111214;
  --color-surface: #191b1e;
  --color-surface-raised: #23262a;
  --color-border: #33363d;
  --color-accent: #ff0083;
  --color-focus: #ff379e;
  --color-profit: #4ccb83;
  --color-loss: #f06a6a;
  --color-text: #f5f4f7;
  --color-muted: #9ca3af;

  /* --- Landing-only, derived from the tokens above (RGB triplets of --color-accent / --color-
     focus, never an invented hue) --- */
  --color-accent-soft: rgb(255 0 131 / 16%);
  --color-accent-line: rgb(255 0 131 / 40%);
  --color-glow: rgb(255 55 158 / 24%);
  /* Verbatim from src/theme/tokens.css's --color-accent-highlight, reused here for the primary
     button's gradient and hover state so the "premium magenta" comes from the same family as
     the product, not an invented shade. */
  --color-accent-highlight: #ffabd6;
  /* Taken from tokens.css's blue streak ramp (tier4/tier5), never a new hue: the shared lit-edge
     treatment on both showcase panels (.showcase-panel, see the Gap/Streak sections below) uses
     this one blue rather than each panel echoing its own subject's color, which read as
     inconsistent across two adjacent panels rather than intentional. */
  --color-streak-line: #6da5e9;
  --color-streak-glow: rgb(100 152 216 / 22%);

  /* --- Type: Linear's actual stack (verified live), Inter leading, extensive system fallback.
     Same stack for display and body per this revision; only font-weight differs between them. --- */
  --font-sans:
    'Inter', 'Inter Variable', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Open Sans', 'Helvetica Neue', sans-serif;
  --font-display: var(--font-sans);
  --font-body: var(--font-sans);
  --font-mono: 'IBM Plex Mono', ui-monospace, 'Courier New', monospace;

  /* --- Layout --- */
  --content-width: 1160px;
  --gutter: clamp(24px, 5vw, 64px);
  --section-space: clamp(80px, 11vw, 168px);

  /* --- Shared section heading scale (point 7: every section uses this, no exceptions).
     48px/weight ~510/line-height 1/letter-spacing -0.022em is linear.app's own measured section
     h2 (verified live, not estimated), reproduced here almost exactly. --- */
  --heading-size: clamp(1.875rem, 2.6vw + 1rem, 3rem);

  /* Linear's own body/support text sits at 14-15px against 48px headings, a much bigger
     headline-to-detail contrast than a "normal" 17px body page uses. Applied to every
     supporting paragraph on the page (point 2), not just the hero. */
  --body-copy-size: 0.9375rem;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.022em;
  text-wrap: balance;
  margin: 0;
}

p {
  margin: 0;
}

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

.wrap {
  width: 100%;
  max-width: var(--content-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.kicker {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: 16px;
}

/* Point 7: the ONE heading treatment every section uses. No section gets its own bigger/smaller
   variant (The Gap's statement used to run larger than the rest; Pricing/Contact used to fall
   back to the browser's bare default h2 size with no kicker-matched scale at all). */
.section-heading {
  max-width: 700px;
  margin-bottom: 48px;
}

.section-heading h2 {
  font-size: var(--heading-size);
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 8px;
  padding: 13px 26px;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

/* Flat fill: the gradient/gloss treatment from an earlier pass was compensating for gold
   reading as flat and lifeless. Magenta doesn't have that problem, so a plain fill plus a soft
   ambient glow beneath (grounding the button, not simulating a curved lit surface) is enough. */
.btn-primary {
  background: var(--color-accent);
  color: var(--color-text);
  box-shadow: 0 8px 24px -6px var(--color-glow);
}

.btn-primary:hover {
  background: var(--color-focus);
  box-shadow: 0 10px 32px -6px var(--color-glow);
  transform: translateY(-1px);
}

.btn-primary:active {
  background: var(--color-focus);
  transform: translateY(0);
  box-shadow: 0 4px 14px -6px var(--color-glow);
}

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

.btn-ghost:hover {
  border-color: var(--color-accent-line);
  background: var(--color-accent-soft);
}

/* The header's contact button: the brand fill, always on one line, slimmer than the page's other
   buttons, and smaller on narrow phones so it fits beside the logo from 320px up. */
.btn-nav {
  flex-shrink: 0;
  white-space: nowrap;
  padding: 10px 18px;
  font-size: 0.875rem;
  line-height: 1.2;
}

.btn-nav:focus-visible {
  outline: 2px solid var(--color-accent-highlight);
  outline-offset: 3px;
}

@media (max-width: 430px) {
  .btn-nav {
    padding: 8px 14px;
    font-size: 0.8125rem;
  }
}

@media (max-width: 359px) {
  .btn-nav {
    padding: 7px 11px;
    font-size: 0.75rem;
  }
}

/* ---------- Nav ---------- */

/* Sticky lives on the <header> itself, not .site-nav (an earlier pass here put it on .site-nav
   while <nav> was a direct child of <body>, which worked, but broke silently once the semantic
   HTML fix wrapped it in a tightly-fitted <header>: a sticky element is constrained to never
   render outside its containing block, and a <header> sized to exactly its nav's own height
   gives it zero room to stay pinned past the first ~90px of scroll. <header>'s own containing
   block is <body>, spanning the full page, so the sticky behavior has to anchor there instead. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgb(17 18 20 / 82%);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-border);
}

.site-nav .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-block: 18px;
}

.nav-logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.nav-logo img {
  display: block;
  height: 30px;
  width: auto;
}

/* Below 360px (max-width: 359px — the first width that's actually tight; 360 itself still has
   a comfortable 24px margin, confirmed via a real getBoundingClientRect() sweep), the logo's
   fixed 189px rendered width at 30px tall no longer leaves room for the "Get in Touch" button
   on the same row — real overflow found and fixed here, not assumed. Shrinking the logo
   (proportionally, same SVG, just smaller) is the only axis available: .nav-links already
   dropped at 1024px, and the button's own text can't shrink further. */
@media (max-width: 359px) {
  .nav-logo img {
    height: 26px;
  }
}

/* Jump-to-section nav. Plain text links (Inter, not the mono kicker face) at a size between the
   nav's other two elements, muted resting state brightening to full text color on hover, the
   same resting->hover relationship the footer links use. No
   mobile menu: below 1024px the six links plus wordmark and CTA stop fitting on one row, and
   this is a lean marketing page with no existing menu-toggle pattern to extend, so links simply
   drop rather than gaining a hamburger; wordmark and the CTA (this page's one essential action)
   still work at every width. */
.nav-links {
  display: flex;
  align-items: center;
  gap: 24px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease;
}

.nav-links a:hover {
  color: var(--color-text);
}

@media (max-width: 1024px) {
  .nav-links {
    display: none;
  }
}

/* Sticky nav offset: an anchor jump would otherwise land the section heading right under (or
   behind) the fixed nav bar. */
#gap,
#who,
#features,
#instructors,
#pricing,
#contact {
  scroll-margin-top: 24px;
}

/* ---------- Hero ----------
   Modeled directly on linear.app's actual hero (inspected live): generous breathing room
   above the headline (~200px there), a tight line-height display headline, a subhead
   directly beneath, CTA beneath that, then a large full-width product screenshot below the
   whole text block. Left-aligned, flush with the nav logo, matching Linear's own measured
   alignment exactly (an earlier pass here used centered text per a since-reversed request). */

.hero {
  padding-block: clamp(64px, 11vw, 160px) var(--section-space);
  position: relative;
  overflow: hidden;
}

/* Large enough that its falloff reaches down into the headline's own line-box: the glow should
   read as something the text sits partly inside, not a shape fully contained above/behind it. */
.hero::before {
  content: '';
  position: absolute;
  top: -280px;
  left: -160px;
  width: 1300px;
  height: 900px;
  background: radial-gradient(ellipse, var(--color-glow) 0%, transparent 70%);
  pointer-events: none;
}

.hero-inner {
  position: relative;
}

.hero h1 {
  font-size: clamp(2.75rem, 5.2vw + 1rem, 4.5rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
}

/* Originally scoped to .hero h1 .accent only; generalized once the same "highlight one word"
   treatment was needed on other section headings too, so there's one shared rule instead of a
   copy per heading. */
.accent {
  color: var(--color-accent);
}

.hero-sub {
  margin: 28px 0 0;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--color-muted);
  max-width: 560px;
}

.hero-cta {
  margin-top: 36px;
  display: flex;
  justify-content: flex-start;
}

/* The single most important visual on the page (point 2): large, full-width, directly below
   the text block, wider than the page's normal content column for extra presence. A soft
   bottom fade dissolves the screenshot into the page background instead of a hard edge,
   echoing Linear's own treatment, rather than the boxed-card look used for every other
   screenshot on this page (deliberately different: this is the one hero moment). */
.hero-visual-wrap {
  max-width: 1320px;
  margin: clamp(56px, 8vw, 96px) auto 0;
  padding-inline: var(--gutter);
}

.hero-visual {
  position: relative;
  border: 1px solid var(--color-border);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 50px 110px -40px rgb(0 0 0 / 70%);
}

.hero-visual img {
  width: 100%;
  display: block;
}

.hero-visual::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent 65%, var(--color-bg) 100%);
  pointer-events: none;
}

/* ---------- Section rhythm ---------- */

.section {
  padding-block: var(--section-space);
}

.section-alt {
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

/* ---------- Showcase panel lighting (Gap, Streak) ----------
   Replaces an earlier pass here: one big soft radial blob centered behind the section read as
   generic "AI-template glow" rather than a deliberate choice. This is a tighter, more literal
   substitute: a thin gradient seam along the panel's own bottom edge (light catching the base
   of a physical object resting on a surface, not an ambient wash filling the whole section),
   paired with a glow that hugs the panel's actual silhouette rather than floating behind it as
   a separate shape. Applied directly to the showcase panels themselves (.gap-media,
   .streak-visual), not the section, so it stays precisely where the object is.
   One shared blue (the streak ramp's own tone, not the page accent) for both panels rather than
   each echoing its own subject's color: two different accent colors across two adjacent
   showcase panels read as inconsistent, not intentional. */
.showcase-panel {
  position: relative;
}

.showcase-panel::before {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--color-streak-line) 50%, transparent);
  opacity: 0.85;
}

.showcase-panel::after {
  content: '';
  position: absolute;
  bottom: -28px;
  left: 22%;
  right: 22%;
  height: 40px;
  background: linear-gradient(to top, var(--color-streak-glow), transparent);
  filter: blur(14px);
  pointer-events: none;
}

/* ---------- The Gap ---------- */

/* Stacked, not side-by-side (point 2 of the visual-feedback pass): this chart IS the section's
   whole argument, so it gets a full-width showcase panel below the copy instead of being
   squeezed into half a column where its tick labels were illegible. */
.gap-block {
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 6vw, 56px);
}

.gap-body {
  max-width: 640px;
  font-size: var(--body-copy-size);
  color: var(--color-muted);
  line-height: 1.7;
}

.gap-media {
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  border-radius: 16px;
  padding: clamp(28px, 4vw, 48px);
  box-shadow: 0 40px 100px -35px rgb(0 0 0 / 60%);
}

.gap-media img {
  width: 100%;
  max-width: 980px;
  margin-inline: auto;
}

/* ---------- Who it's for ---------- */

.audience-intro {
  max-width: 700px;
  font-size: var(--body-copy-size);
  color: var(--color-muted);
  line-height: 1.75;
  margin-bottom: clamp(40px, 6vw, 64px);
}

/* Redesigned (point 5): icon + large statement per audience, separated by vertical rules
   instead of boxed/bordered rows, so it reads as one confident editorial statement in three
   parts rather than a form-like list. */
.audience-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 0px);
}

.audience-item {
  padding: 0 clamp(0px, 3vw, 32px) 0 0;
  border-left: 1px solid var(--color-border);
  padding-left: clamp(20px, 3vw, 32px);
}

.audience-item:first-child {
  border-left: none;
  padding-left: 0;
}

/* "FIG 0.1" mono caption + a bigger, plainer thin-line icon (technique 3: matches linear.app's
   own pattern of abstract line-art illustrations with a small mono figure label, verified live
   in its "FIG 0.1 / Purpose-built", "FIG 0.2 / Powered by agents" row). No circular badge
   around the icon this time, that read as a generic SaaS icon-bubble; Linear's own icons just
   sit directly on the background. */
.audience-fig {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: 20px;
}

.audience-icon {
  display: block;
  color: var(--color-accent);
  margin-bottom: 24px;
}

.audience-icon svg {
  width: 40px;
  height: 40px;
  stroke-width: 1.5;
}

/* Short bold label above the description (added to match linear.app's own "icon, bold 2-3
   word label, short description" pattern, verified live in its "Purpose-built / Powered by
   agents / Designed for speed" row, not just an icon-plus-paragraph). */
.audience-item h3 {
  font-size: 1.0625rem;
  margin-bottom: 10px;
}

.audience-item p {
  font-size: var(--body-copy-size);
  line-height: 1.6;
  color: var(--color-muted);
}

/* ---------- Streak interstitial ---------- */

/* Stacked, same fix as the Gap chart above: this badge was previously squeezed into half a
   column at roughly half its native resolution and read as illegible. The heading/copy block
   stays left-aligned like every other section on the page (no special centered treatment); only
   the image panel below it is centered as its own showcase, via margin-inline: auto on
   .streak-visual rather than align-items on this flex container. */
.streak-block {
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 6vw, 56px);
}

.streak-copy {
  max-width: 640px;
}

.streak-copy p {
  color: var(--color-muted);
  font-size: var(--body-copy-size);
  line-height: 1.75;
  margin-top: 16px;
}

.streak-visual {
  width: 100%;
  max-width: 900px;
  margin-inline: auto;
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  border-radius: 16px;
  padding: clamp(32px, 5vw, 56px);
  box-shadow: 0 30px 90px -35px rgb(0 0 0 / 60%);
}

.streak-visual img {
  display: block;
  width: auto;
  max-width: 100%;
  margin-inline: auto;
  border-radius: 6px;
}

/* ---------- Features: exactly 2 flagship features, large (point 6) ---------- */

.feature-lede {
  max-width: 480px;
  font-size: var(--body-copy-size);
  color: var(--color-muted);
  line-height: 1.75;
  margin-bottom: clamp(56px, 8vw, 96px);
}

/* Copy column first, media column second: text leads, image trails, for both flagships alike.
   Media gets the larger share (1.15fr) since it's the visually dominant element the copy
   narrates rather than an equal-weight partner. Top-aligned (align-items: start), not centered:
   centering read as the copy "floating" against a taller image with no fixed relationship to
   it; both flagships now start at the same baseline the way two columns in an article would. */
.flagship {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(40px, 6vw, 80px);
  align-items: start;
}

.flagship + .flagship {
  margin-top: clamp(80px, 11vw, 140px);
}

.flagship-copy h3 {
  font-size: clamp(1.5rem, 1.6vw + 1rem, 2rem);
  margin-bottom: 18px;
}

.flagship-copy p {
  color: var(--color-muted);
  font-size: var(--body-copy-size);
  line-height: 1.75;
}

/* Layered "scene" treatment (Linear technique 1+2, verified live on their site: a dimmed/
   blurred wider background panel with a sharp, chrome-topped foreground panel floating over
   it, never a flat single screenshot). .flagship-media is the scene's own bounding box: it
   clips the blurred background to the shared rounded corners and gives the floating
   foreground panel room to sit inside with its own shadow, not touching the outer edge. */
.flagship-media {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 680px;
  padding: clamp(36px, 5vw, 64px);
  border: 1px solid var(--color-border);
  border-radius: 20px;
  overflow: hidden;
  background: var(--color-bg);
  box-shadow: 0 40px 100px -35px rgb(0 0 0 / 70%);
}

/* The wider context shot, always screenshot-all-app.png regardless of which specific feature
   is in the foreground: it's the "bigger scene" every foreground panel is a close-up of, the
   same role Linear's own dimmed background plays for its code-diff/chat-thread callouts.
   Purely decorative (alt="" + aria-hidden, see the HTML), the real content is the sharp panel
   on top. scale(1.1) keeps the blur filter's own soft edge from ever showing at the container
   boundary. */
.scene-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
  /* Light blur (was 10px): enough to read as "background, not content" and separate it from the
     sharp foreground panel, without turning it into unrecognizable mush. The scene should still
     be identifiable as the dashboard, just softened. */
  filter: blur(2px) brightness(0.55) saturate(0.85);
  transform: scale(1.15);
}

/* The sharp foreground panel: real z-index lift (border, shadow, its own rounded corners)
   over the blurred backdrop, plus the window-chrome bar (technique 2) that makes it read as
   a real running window, not a cropped screenshot. Narrower than the scene itself so the
   blurred background visibly peeks out around every edge, the "magnifying glass into a wider
   scene" effect. */
.scene-fg {
  position: relative;
  z-index: 1;
  width: min(100%, 600px);
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  box-shadow:
    0 10px 40px rgb(0 0 0 / 50%),
    0 50px 120px -30px rgb(0 0 0 / 85%);
}

/* Dots only, no path-style label (point 1 of the visual-feedback pass: the "tradelog / x"
   mono label read as confusing app-internal chrome, not a caption, and added nothing a plain
   floating-window affordance doesn't already say on its own). */
.window-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  background: var(--color-surface-raised);
  border-bottom: 1px solid var(--color-border);
}

.window-dots {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

.window-dots span {
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-border);
}

.scene-fg img {
  display: block;
  width: 100%;
  max-height: 600px;
  object-fit: contain;
  background: var(--color-bg);
}

/* Feature 2 (Discipline Score Trend): same side-by-side, top-aligned structure and the same
   0.85fr/1.15fr column ratio as Feature 1, so both media columns render at the same pixel width
   and the shared scene-bg background image (screenshot-all-app.png, identical file in both
   flagships) shows the same crop/zoom in both rather than two different sizes. The columns are
   mirrored (media first/wide, copy second/narrow) and visually reordered so media lands on the
   left instead of the right, intentional alternation rather than two identical-looking rows in
   sequence. Reordered with `order`, not by swapping the HTML: the DOM keeps copy-before-media
   for both flagships (matching Feature 1's actual markup order), so a screen reader still meets
   the heading/paragraph before the image's alt text either way. */
.flagship-full {
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
}

.flagship-full .flagship-copy {
  order: 2;
}

.flagship-full .flagship-media {
  order: 1;
}

/* ---------- Instructors ---------- */

/* Plain paragraph + CTA, matching Pricing/Contact's own pattern (point 6 of the visual-
   feedback pass): this used to be the page's one boxed/accent-striped text callout, a visual
   language nothing else on the page shares, which read as disconnected rather than deliberate. */
.instructor-panel {
  max-width: 700px;
}

.instructor-panel p {
  color: var(--color-muted);
  font-size: var(--body-copy-size);
  line-height: 1.8;
}

.instructor-panel .btn {
  margin-top: 28px;
}

/* ---------- Pricing ---------- */

.pricing-inner {
  max-width: 640px;
}

.pricing-inner p {
  color: var(--color-muted);
  font-size: var(--body-copy-size);
  line-height: 1.8;
}

.pricing-inner .btn {
  margin-top: 28px;
}

/* ---------- Contact / Footer ---------- */

.contact {
  padding-block: var(--section-space) 64px;
}

.contact-inner {
  max-width: 640px;
}

/* Closing bookend (point 2): linear.app gives its final CTA hero-adjacent scale ("Built for
   the future. Available today.", centered, near-hero size), not the standard section-heading
   size everything else on the page uses. This is the one deliberate exception to point 7's
   "every section shares one heading treatment", made for the same reason Linear makes it: the
   last thing on the page is a closing statement, not just another section topic. */
.contact-inner .section-heading h2 {
  font-size: clamp(2rem, 3.2vw + 1rem, 3.25rem);
}

.contact-inner p {
  color: var(--color-muted);
  font-size: var(--body-copy-size);
  line-height: 1.8;
}

.contact-inner .btn {
  margin-top: 28px;
}

.site-footer {
  border-top: 1px solid var(--color-border);
  padding-block: 32px;
}

.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
}

.footer-line {
  font-size: 0.875rem;
  color: var(--color-muted);
}

/* align-items: flex-start, not center: the sentence after the logo can wrap to a second line
   at narrow widths (confirmed at 390px), and center-aligning against the full wrapped-text
   block height looked visually off (the logo floated mid-block instead of sitting with the
   first line). flex-start keeps the logo aligned with the first line regardless of how many
   lines the text wraps to. */
.footer-brand-line {
  display: flex;
  align-items: flex-start;
}

.footer-brand-line img {
  display: block;
  height: 26px;
  width: auto;
  margin-right: 2px;
  /* Nudge down to roughly match the cap-height baseline of the adjacent text at this size,
     confirmed visually, not computed. */
  margin-top: 2px;
}

.footer-privacy {
  max-width: 460px;
}

/* Regulatory disclosures + partner links/trademark notice. Deliberately the same size/weight
   as .footer-line above, not the smaller/italic/reduced-opacity treatment the old single-line
   sample-data note used — these need to read as legible disclosures, not fine print.
   `align-items: stretch` (the flex default, stated explicitly here) lets .footer-partners,
   .footer-legal-trademark and .footer-legal-columns each claim the full width below rather than
   shrinking to their own content width — that shrink-to-fit was what left the old single-column
   disclosure text stranded on the left half of the footer with the right half empty. */
.site-footer .footer-legal {
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--color-border);
}

.footer-legal-text {
  margin: 0;
  /* The same size, line height and color as the page's own body copy (.flagship-copy p and the
     other supporting paragraphs), so the disclosures read as body text, not as footer fine print.
     Overrides .footer-line's smaller 0.875rem for these paragraphs only. */
  font-size: var(--body-copy-size);
  line-height: 1.75;
  color: var(--color-muted);
}

.footer-legal-text strong {
  color: var(--color-text);
}

/* Risk Disclosure + Hypothetical Performance Disclosure, side by side across the footer's full
   width. Each column's own line length (roughly half of --content-width) is what keeps the text
   comfortable to read, so .footer-legal-text needs no max-width of its own in here. */
.footer-legal-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 32px;
}

/* Spans the full footer width on its own row below .footer-partners and above
   .footer-legal-columns, same text styling as every other .footer-legal-text, just not
   column-constrained. */
.footer-legal-trademark {
  max-width: none;
}

/* Live tracking logos, replacing the old plain-text "Label: https://..." reference lines now
   that this page is ready for compliance submission. Leads the footer-legal block (above the
   trademark notice and the two disclosure paragraphs) so the compliance-mandated brand
   attribution reads first, not buried under a wall of disclosure text. Vendor Guidelines require
   >= 0.25in/18px of clear space on every side of each logo (no other content, text, or the other
   logo closer than that): padding-block covers the top/bottom clearance against the footer's own
   top-row wrap above and the trademark paragraph below independently of .footer-legal's own 16px
   inter-child gap (which alone wouldn't clear 18px), and column-gap (40px) covers each logo's own
   18px requirement plus the other logo's 18px for the horizontal case between them. row-gap
   matches column-gap so the same math holds if they wrap to a stacked layout at narrow widths
   instead. */
.footer-partners {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 40px;
  row-gap: 40px;
  padding-block: 20px;
}

.footer-partner-link {
  display: inline-flex;
  line-height: 0;
}

/* Heights picked for visual balance only (each wordmark's own aspect ratio is preserved via
   width: auto, never distorted or recolored, per the Vendor Guidelines — these are the unedited
   files from the media kit). Kinetick's source file carries more vertical padding of its own
   (a tagline above and below the wordmark) than NinjaTrader's bare wordmark does, so it needs a
   taller box to read as the same visual weight. */
.footer-partner-logo {
  display: block;
  width: auto;
}

.footer-partner-logo-ninjatrader {
  height: 20px;
}

.footer-partner-logo-kinetick {
  height: 34px;
}

@media (max-width: 860px) {
  .footer-legal-columns {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

/* ---------- Footer links (Privacy Policy, Terms of Service) ---------- */

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
}

.footer-links a {
  color: var(--color-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer-links a:hover,
.footer-links a:focus-visible {
  color: var(--color-text);
}

/* ---------- Legal pages (/privacy, /terms), generated by scripts/build-legal-pages.mjs ---------- */

.legal-page {
  padding-block: 56px 72px;
}

.legal-wrap {
  max-width: 760px;
}

.legal-page h1 {
  font-size: var(--heading-size);
  margin-bottom: 24px;
}

.legal-page h2 {
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  margin: 40px 0 12px;
}

.legal-page p,
.legal-page li,
.legal-page td,
.legal-page th {
  font-size: var(--body-copy-size);
  line-height: 1.75;
  color: var(--color-muted);
}

.legal-page p + p,
.legal-page ul + p,
.legal-page .legal-table-wrap + p {
  margin-top: 12px;
}

.legal-page strong {
  color: var(--color-text);
}

.legal-page ul {
  margin: 0;
  padding-left: 22px;
  display: grid;
  gap: 8px;
}

/* A "> " blockquote in docs/legal/ renders as this banner. The approved text has none, and
   npm run check:legal refuses a deployment that shows a DRAFT banner. */
.legal-draft-banner {
  margin: 0 0 28px;
  padding: 14px 18px;
  border: 1px solid var(--color-accent-line);
  border-left: 4px solid var(--color-accent);
  border-radius: 8px;
  background: var(--color-accent-soft);
}

.legal-draft-banner p {
  color: var(--color-text);
  font-weight: 600;
}

.legal-placeholder {
  color: var(--color-accent-highlight);
  font-family: var(--font-mono, monospace);
  font-size: 0.92em;
}

.legal-table-wrap {
  overflow-x: auto;
  margin-top: 12px;
}

.legal-page table {
  width: 100%;
  border-collapse: collapse;
}

.legal-page th,
.legal-page td {
  text-align: left;
  vertical-align: top;
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-border);
}

.legal-page th {
  color: var(--color-text);
  font-weight: 600;
}

/* ---------- Responsive ---------- */

@media (max-width: 960px) {
  .flagship {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  /* The desktop-only left/right alternation between the two flagships (see .flagship-full
     above) has no "side" left to alternate once both stack into one column; reset to natural
     DOM order (copy, then media) so both flagships stack identically. */
  .flagship-full .flagship-copy,
  .flagship-full .flagship-media {
    order: 0;
  }
}

@media (max-width: 860px) {
  .audience-grid {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  .audience-item,
  .audience-item:first-child {
    border-left: none;
    padding-left: 0;
    padding-top: 24px;
    border-top: 1px solid var(--color-border);
  }

  .audience-grid .audience-item:first-child {
    padding-top: 0;
    border-top: none;
  }
}

@media (max-width: 600px) {
  body {
    font-size: 16px;
  }

  .site-footer .wrap {
    flex-direction: column;
  }
}

/* ---------- Contact page and 404 page ---------- */

.contact-form {
  display: grid;
  gap: 18px;
  max-width: 560px;
  margin-top: 28px;
}

.contact-form .field {
  display: grid;
  gap: 6px;
}

.contact-form label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text);
}

.contact-form input,
.contact-form select,
.contact-form textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 11px 12px;
}

.contact-form textarea {
  resize: vertical;
  min-height: 140px;
}

.contact-form input:focus-visible,
.contact-form select:focus-visible,
.contact-form textarea:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 1px;
  border-color: var(--color-accent-line);
}

/* The honeypot: off screen for people, still in the form for bots. */
.contact-honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-turnstile {
  min-height: 65px;
  max-width: 100%;
}

.legal-page .contact-privacy {
  margin: 0;
  font-size: 0.875rem;
  color: var(--color-muted);
}

.contact-privacy a {
  color: var(--color-text);
}

.contact-form .btn {
  justify-self: start;
}

.legal-page .contact-status {
  margin: 0;
  min-height: 1.5em;
  font-size: 0.9375rem;
}

.contact-status.is-success {
  color: var(--color-profit);
}

.contact-status.is-error {
  color: var(--color-loss);
}

.notfound-page .btn {
  margin-top: 8px;
}
