/* ============================================================
   skeleton.css — structure and mechanism only. NO COLOUR VALUES.
   Every build inherits this file unchanged. Identity lives in a
   separate brand file that defines the token contract below.

   Rule: if you are about to write a hex or an rgba() in this file,
   stop. It belongs in the brand file.

   ---- TOKEN CONTRACT ----------------------------------------
   The brand file MUST define, on :root and on every [data-surface]:
     --surface  --fg  --fg-strong  --fg-body  --fg-quiet
     --line  --line-strong  --acid  --acid-lift  --acid-press
     --on-acid  --focus
     --font-display  --font-ui
   Client brand files may alias these from --brand-* placeholders.
   Nothing in this file may reference a --brand-* name directly.
   ------------------------------------------------------------ */

:root {
  /* --- spacing scale (4px base) --- */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 20px;  --sp-6: 24px;  --sp-8: 32px;  --sp-10: 40px;
  --sp-12: 48px; --sp-16: 64px; --sp-20: 80px; --sp-24: 96px;
  --sp-30: 120px;
  --sp-hero-top: 76px;
  --sp-hero-bottom: 84px;

  /* --- type scale --- */
  --t-hero:    clamp(2.25rem, 1.30rem + 3.9vw, 3.5rem);
  --t-display: clamp(2.00rem, 1.25rem + 3.1vw, 3rem);
  --t-title:   clamp(1.625rem, 1.25rem + 1.6vw, 2.125rem);
  --t-sub:     clamp(1.50rem, 1.22rem + 1.2vw, 1.875rem);
  --t-heading: clamp(1.3125rem, 1.19rem + 0.5vw, 1.5rem);
  --t-section: clamp(1.25rem, 1.19rem + 0.25vw, 1.375rem);
  --t-body: 16px;
  --t-body-lg: 17px;
  --t-small: 14px;
  --t-label: 11px;
  --t-mono: 13px;

  --lh-display: 1.05;
  --lh-heading: 1.12;
  --lh-body: 1.65;
  --lh-mono: 1.9;

  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* --- measure --- */
  --measure: 660px;
  --measure-column: 540px;
  --measure-caption: 320px;

  /* --- container --- */
  --column: 1040px;
  --pad-side: var(--sp-12);
  --pad-top: var(--sp-20);
  --pad-bottom: var(--sp-30);
  --section-gap: var(--sp-24);
  --gutter: var(--sp-5);

  /* --- shape --- */
  --r-control: 2px;
  --r-container: 4px;
  --hairline: 1px;

  /* --- motion: two durations for interaction, one arrival curve --- */
  --dur-interaction: 120ms;
  --ease-interaction: cubic-bezier(0.2, 0, 0.2, 1);
  --dur-rise: 500ms;
  --dur-draw: 600ms;
  --ease-arrival: cubic-bezier(0.16, 1, 0.3, 1);
  --stagger: 70ms;
}

@media (max-width: 1135px) {
  :root { --pad-side: var(--sp-8); }
}
@media (max-width: 719px) {
  :root {
    --pad-side: var(--sp-5);
    --pad-top: var(--sp-12);
    --pad-bottom: var(--sp-20);
    --section-gap: 72px;
    --sp-hero-top: 56px;
    --sp-hero-bottom: 64px;
    --t-mono: 12px;
  }
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--surface, Canvas);
  color: var(--fg, CanvasText);
  font-family: var(--font-ui, system-ui, sans-serif);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display, serif);
  letter-spacing: -0.02em;
  line-height: var(--lh-heading);
  text-wrap: balance;
  margin: 0;
}

p { margin: 0; max-width: var(--measure); text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }

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

a { color: inherit; text-underline-offset: 0.16em; text-decoration-thickness: 1px; }

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

.wrap {
  width: 100%;
  max-width: calc(var(--column) + var(--pad-side) * 2);
  margin-inline: auto;
  padding-inline: var(--pad-side);
}

.band { padding-block: calc(var(--section-gap) / 2); }
.band--first { padding-top: var(--sp-hero-top); padding-bottom: var(--sp-hero-bottom); }
.band--last { padding-bottom: var(--pad-bottom); }

.stack { display: flex; flex-direction: column; }
.stack--2 { gap: var(--sp-2); }
.stack--3 { gap: var(--sp-3); }
.stack--4 { gap: var(--sp-4); }
.stack--6 { gap: var(--sp-6); }
.stack--8 { gap: var(--sp-8); }
.stack--12 { gap: var(--sp-12); }

.grid { display: grid; gap: var(--gutter); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1135px) { .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 719px)  { .grid--3 { grid-template-columns: minmax(0, 1fr); } }

.rule {
  border: 0;
  border-top: var(--hairline) solid var(--line);
  margin: 0;
  width: 100%;
}

/* --- shells (colour comes from the brand file) -------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 14px 24px;
  border-radius: var(--r-control);
  border: var(--hairline) solid transparent;
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-interaction) var(--ease-interaction),
              color var(--dur-interaction) var(--ease-interaction),
              border-color var(--dur-interaction) var(--ease-interaction);
}

.card {
  padding: var(--sp-8);
  border: var(--hairline) solid var(--line);
  border-radius: var(--r-container);
  transition: border-color var(--dur-interaction) var(--ease-interaction);
}

.label {
  font-family: var(--font-ui);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1.2;
}

.mono {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  line-height: var(--lh-mono);
  font-variant-numeric: tabular-nums;
}

.field-input {
  width: 100%;
  min-height: 44px;
  padding: 12px 14px;
  border: var(--hairline) solid var(--line);
  border-radius: var(--r-container);
  font-family: var(--font-ui);
  font-size: var(--t-body);
  line-height: 1.4;
  transition: border-color var(--dur-interaction) var(--ease-interaction);
}

:where(a, button, input, textarea, select):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
:where(a, button, input, textarea, select):focus {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
:where(a, button, input, textarea, select):focus:not(:focus-visible) {
  outline: none;
}

[disabled] { opacity: 0.4; cursor: not-allowed; }

.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-link {
  position: absolute;
  left: var(--sp-5);
  top: var(--sp-5);
  padding: 10px 16px;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

/* ============================================================
   MOTION PRIMITIVES — three, composed, nothing else permitted.
   Mechanism only. Every value here is colour-agnostic, so this
   travels to every client build at zero marginal cost.

   The finished state is the CSS default. The hidden pre-state is
   scoped to .js only, so a script failure leaves the page fully
   visible rather than blank.
   ============================================================ */

/* rise — opacity 0→1 plus a 24px lift. Fires once. */
.js [data-reveal="rise"] {
  opacity: 0;
  transform: translateY(24px);
}
.js [data-reveal="rise"].is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-rise) var(--ease-arrival),
              transform var(--dur-rise) var(--ease-arrival);
}

/* draw — a hairline scales along its own length. Fires once. */
.js [data-reveal="draw"] {
  transform: scaleX(0);
  transform-origin: left center;
}
.js [data-reveal="draw"].is-in {
  transform: scaleX(1);
  transition: transform var(--dur-draw) var(--ease-arrival);
}

/* Staggered children of a rise or sequence group. */
.js [data-stagger] > * {
  opacity: 0;
  transform: translateY(24px);
}
.js [data-stagger].is-in > * {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-rise) var(--ease-arrival),
              transform var(--dur-rise) var(--ease-arrival);
}
.js [data-stagger].is-in > :nth-child(1) { transition-delay: 0ms; }
.js [data-stagger].is-in > :nth-child(2) { transition-delay: var(--stagger); }
.js [data-stagger].is-in > :nth-child(3) { transition-delay: calc(var(--stagger) * 2); }
.js [data-stagger].is-in > :nth-child(4) { transition-delay: calc(var(--stagger) * 3); }
.js [data-stagger].is-in > :nth-child(5) { transition-delay: calc(var(--stagger) * 4); }
.js [data-stagger].is-in > :nth-child(6) { transition-delay: calc(var(--stagger) * 5); }
.js [data-stagger].is-in > :nth-child(7) { transition-delay: calc(var(--stagger) * 6); }

/* sequence — a group whose number, rule and text arrive together.
   Composed from rise + draw; not a fourth mechanism. */
.js [data-reveal="sequence"] .seq-mark,
.js [data-reveal="sequence"] .seq-body {
  opacity: 0;
  transform: translateY(24px);
}
.js [data-reveal="sequence"] .seq-rule {
  transform: scaleX(0);
  transform-origin: left center;
}
.js [data-reveal="sequence"].is-in .seq-mark,
.js [data-reveal="sequence"].is-in .seq-body {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-rise) var(--ease-arrival),
              transform var(--dur-rise) var(--ease-arrival);
}
.js [data-reveal="sequence"].is-in .seq-rule {
  transform: scaleX(1);
  transition: transform var(--dur-draw) var(--ease-arrival);
}
.js [data-reveal="sequence"].is-in .seq-mark { transition-delay: 0ms; }
.js [data-reveal="sequence"].is-in .seq-rule { transition-delay: var(--stagger); }
.js [data-reveal="sequence"].is-in .seq-body { transition-delay: calc(var(--stagger) * 2); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto !important; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal],
  .js [data-stagger] > *,
  .js [data-reveal="sequence"] .seq-mark,
  .js [data-reveal="sequence"] .seq-body,
  .js [data-reveal="sequence"] .seq-rule {
    opacity: 1 !important;
    transform: none !important;
  }
}
