/* Site-specific token overrides (2026-10-02). tokens.css stays a verbatim copy of the design system;
   everything the website direction adds on top of it lives here so a recopy cannot erase it. */
:root {
  /* heading highlight (.hl) on each ground; the deck's two-tone header.
     On light grounds the highlight is --primary (rust #B7410E). */
  --hl-on-rust: #FFE3D9; /* pale rose, inside .splash--rust */
  --hl-on-ink: #E8683A; /* orange, on ink grounds: the close section and the dark theme */

  /* grid: 1200px up to a 1707px viewport, then grows with the viewport to 1800px at 2560px (the 150%-zoom look) */
  --grid-max-width: clamp(1200px, 70.3125vw, 1800px);

  /* icons scale with the fluid root */
  --icon-size-default: 1.25rem;
  --icon-size-inline: 1rem;

  /* focus ring with the 2px offset DESIGN.md specifies: a gap in the page
     background, then the 3px ring. The token's single ring sat flush against
     the control, so on a primary button it was one step off the fill (1.6:1,
     and 1:1 in the dark theme) and on the rust splash it vanished into the
     ground. The gap keeps it legible on every ground. Declared on :root after
     tokens.css, so it wins over both palette blocks; var() resolves per theme. */
  --focus-ring: 0 0 0 var(--focus-ring-offset) var(--background),
    0 0 0 calc(var(--focus-ring-offset) + var(--focus-ring-width)) var(--ring);
}

/* Anything focusable without its own :focus-visible rule (footer links, inline
   source links, the roadmap link) gets the same ring instead of the browser
   default. Zero specificity, so every component rule still wins. */
:where(a[href], button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* Fluid root size (2026-10-02): 16px at 1024px viewport and below, 24px at 2560px
   and above, linear between (about 18.2px at 1440px, 19.6px at 1707px). Slope is
   (24 - 16) / (2560 - 1024) = 0.00521 px per px. Written in rem so a user's own
   browser font-size setting still scales it. All rem tokens above follow this. */
html {
  font-size: clamp(1rem, calc(1rem + (100vw - 1024px) * 0.00521), 1.5rem);
}

/* Critical Point Vision Site: base.css
 * Minimal reset, typography, layout primitives, buttons, tags, and the
 * page-wide custom properties this site adds (--nav-h, --splash-*,
 * --display-*). Owned by structure-builder. Everything here must render
 * sensibly with zero JavaScript.
 */

/* ---------- reset ---------- */

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

html,
body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
ul,
ol,
li,
figure,
blockquote,
dl,
dd {
  margin: 0;
}

html {
  scroll-behavior: auto; /* Lenis (motion.js) drives smooth scroll when active */
}

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

video {
  max-width: 100%;
  display: block;
}

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

ul[class],
ol[class] {
  list-style: none;
  padding: 0;
}

/* ---------- page-wide custom properties ---------- */

:root {
  --nav-h: 72px;

  /* splash bleed: quiet insets the block to a 90% card with 2xl radius;
     medium and loud stay full width. Consumed by .splash below. */
  --splash-bleed: 100%;
  --splash-alpha: 1;

  /* display scale: standard uses the token type scale; oversized clamps
     larger for the hero/close headlines when the tweak is flipped. */
  --display-size: var(--text-display);
  --display-track: -0.01rem;
}

html[data-splash="quiet"] {
  --splash-bleed: 90%;
  --splash-alpha: 0.92;
}

html[data-splash="medium"] {
  --splash-bleed: 100%;
  --splash-alpha: 1;
}

html[data-splash="loud"] {
  --splash-bleed: 100%;
  --splash-alpha: 1;
}

html[data-display="oversized"] {
  --display-size: clamp(4rem, 9vw, 8.5rem);
  --display-track: -0.022rem;
}

/* ---------- body + type ---------- */

html,
body {
  /* off-canvas panels (the mobile nav drawer, demo detail drawers) rest just
     outside the viewport edge before they open; this is the safety net that
     keeps that from creating a horizontal scrollbar on the page itself */
  overflow-x: hidden;
}

body {
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  line-height: var(--leading-heading);
}

/* Two-tone headings (the pitch deck's header treatment): a heading that holds a
   .hl span is Montserrat 500 with the span at 700 in the accent for the ground.
   A heading without .hl keeps 700, so pages not yet rewritten do not go light. */
h1:has(.hl),
h2:has(.hl),
h3:has(.hl) {
  font-weight: 500;
}

.hl {
  font-weight: 700;
  color: var(--primary);
}

.splash--rust .hl {
  color: var(--hl-on-rust);
}

#close .hl,
html[data-theme="dark"] .hl {
  color: var(--hl-on-ink);
}

/* dark theme rust splash is a dark ground too, so it takes the pale rose still */
html[data-theme="dark"] .splash--rust .hl {
  color: var(--hl-on-rust);
}

h1 {
  font-size: var(--display-size);
  line-height: var(--leading-display);
  letter-spacing: var(--display-track);
  text-wrap: balance;
}

h2 {
  font-size: clamp(var(--text-h2), 4vw, var(--text-h1)); /* rem terms: scales with the fluid root; 4vw only binds below ~1000px */
  text-wrap: balance;
}

h3 {
  font-size: var(--text-h3);
}

.lead {
  font-size: var(--text-lead);
  max-width: 62ch;
  color: var(--muted-foreground);
}

.tnum {
  font-variant-numeric: tabular-nums;
}

/* ---------- layout primitives ---------- */

.container {
  max-width: var(--grid-max-width);
  margin-inline: auto;
  padding-inline: var(--grid-gutter-desktop);
}

@media (max-width: 768px) {
  .container {
    padding-inline: var(--grid-margin-mobile);
  }
}

.section-pad {
  padding-block: clamp(4rem, 10vw, 8rem);
}

.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--grid-gutter-desktop);
}

.col-5 {
  grid-column: span 5;
}

.col-6 {
  grid-column: span 6;
}

.col-7 {
  grid-column: span 7;
}

.col-1 {
  grid-column: span 1;
}

@media (max-width: 900px) {
  .col-5,
  .col-6,
  .col-7,
  .col-1 {
    grid-column: 1 / -1;
  }
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-target-min);
  padding: var(--space-150) var(--space-300);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-weight: var(--body-bold-weight);
  font-size: var(--text-ui);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-enter), transform var(--duration-fast) var(--ease-enter);
}

.btn:active {
  transform: scale(0.98);
}

.btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.btn--primary {
  background: var(--button-primary-bg);
  color: var(--button-primary-text);
}

.btn--primary:hover {
  background: var(--button-primary-hover);
}

.btn--primary:active {
  background: var(--button-primary-active);
}

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

.btn--ghost:hover {
  background: var(--secondary);
}

/* a ghost button sitting on a splash block (white text) needs its own
   border/hover so it stays legible on the rust/blue fill. #close is not a
   .splash but its content sits on the same kind of dark ground (the video
   plus the ink scrim), so it takes the same treatment */
.splash .btn--ghost,
.close__ctas .btn--ghost {
  color: #fff;
  border-color: rgb(255 255 255 / 0.55);
}

.splash .btn--ghost:hover,
.close__ctas .btn--ghost:hover {
  background: rgb(255 255 255 / 0.12);
}

/* ---------- tags ---------- */

.tag {
  display: inline-flex;
  align-items: center;
  padding: var(--space-050) var(--space-150);
  border-radius: var(--radius-full);
  background: var(--secondary);
  color: var(--secondary-foreground);
  font-size: var(--text-caption);
  line-height: 1;
}

/* ---------- utilities ---------- */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  background: var(--card);
  color: var(--card-foreground);
  padding: var(--space-150) var(--space-300);
  border-radius: 0 0 var(--radius-md) 0;
  font-weight: var(--body-bold-weight);
}

.skip:focus {
  left: 0;
}

/* ---------- splash blocks ---------- */

.splash {
  position: relative;
  width: var(--splash-bleed);
  margin-inline: auto;
  opacity: var(--splash-alpha);
  color: #fff;
}

.splash--rust {
  background: var(--primary);
}

.splash--blue {
  background: var(--chart-2);
}

html[data-splash="quiet"] .splash--rust,
html[data-splash="quiet"] .splash--blue {
  border-radius: var(--radius-2xl);
}

html[data-theme="dark"] .splash--rust {
  /* body copy on a rust splash needs the darker 1000 step for contrast in
     dark mode; display type may still sit directly on --primary */
  background: var(--primary-1000);
}

.splash h2,
.splash p {
  color: inherit;
}

/* ---------- coming-soon dialog ---------- */

.coming-soon {
  border: none;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  padding: var(--space-400);
  max-width: 28rem;
  width: calc(100% - var(--space-400));
  background: var(--card);
  color: var(--card-foreground);
}

.coming-soon::backdrop {
  background: rgb(var(--ink-rgb) / 0.45);
}

.coming-soon h2 {
  font-size: var(--text-h3);
  margin-bottom: var(--space-200);
}

.coming-soon p {
  color: var(--muted-foreground);
  margin-bottom: var(--space-300);
}

/* orchestrator 2026-09-15: hero copy over the video and still variants is pale, so the ghost button follows */
html[data-hero="video"] #hero .btn--ghost,
html[data-hero="still"] #hero .btn--ghost {
  color: #FBFAF9;
  border-color: rgb(251 250 249 / 0.65);
}
html[data-hero="video"] #hero .btn--ghost:hover,
html[data-hero="still"] #hero .btn--ghost:hover {
  background: rgb(251 250 249 / 0.12);
}
@media (max-width: 560px) {
  #hero h1 { font-size: clamp(2.25rem, 11vw, 3rem); }
  /* the field's convergence point sits at a fixed 62% of canvas width at
     every size (js/hero-field.js FRAME_X), so at this width it runs under
     the full-width copy column instead of staying clear of it; fade it
     further behind the text rather than just dimming it slightly */
  #hero .hero__field { opacity: 0.28; }
}
