/* ============================================================
   8WARD — SHARED FOUNDATION
   ------------------------------------------------------------
   This file holds ONLY what all three concepts genuinely share:
   brand tokens, a reset, and accessibility primitives.

   It deliberately contains NO components and NO layout.
   Each concept owns its own visual language and must stay free
   to contradict the others. See /brand for the rationale.
   ============================================================ */

/* ---------- 1. BRAND TOKENS ------------------------------- */
:root {
  /* Core palette.
     Evolution of the existing blue + orange equity:
     blue is demoted from "brand colour" to a deep GROUND,
     orange is promoted to a rationed SIGNAL that marks
     direction and action only. Neither is decorative. */
  --ink:        #0e1117;  /* off-black, blue undertone. never #000 */
  --ink-80:     #3a3f47;
  --ink-55:     #5f646c;
  --ink-35:     #686d75;  /* quiet, but still AA at 11px on paper (4.8:1) */

  --navy:       #0c2340;  /* the deep field */
  --navy-lift:  #14355e;

  /* The orange has three jobs and three values. Quiet labels
     need more contrast than a 100px headline does, so small
     type never uses the display value. */
  --signal:      #e0532a;  /* display type, fills, rules, marks */
  --signal-ink:  #a83c14;  /* small type on paper — AA at 11px  */
  --signal-lift: #f4794f;  /* small type on navy  — AA at 11px  */
  --signal-dim:  #c4441f;  /* hover / pressed                   */

  --paper:      #faf8f5;  /* warm off-white. never #fff */
  --paper-2:    #f2eee8;
  --paper-3:    #e8e2d9;

  --rule:       rgba(14, 17, 23, 0.14);
  --rule-soft:  rgba(14, 17, 23, 0.07);
  --rule-inv:   rgba(250, 248, 245, 0.20);

  /* Spacing — an 8 scale, because the brand is built on 8.
     Every dimension in every concept resolves to a multiple. */
  --s1:  8px;
  --s2:  16px;
  --s3:  24px;
  --s4:  32px;
  --s5:  48px;
  --s6:  64px;
  --s7:  96px;
  --s8:  128px;
  --s9:  192px;
  --s10: 256px;

  /* Motion — declared here, applied later. Concepts opt in. */
  --ease-out:  cubic-bezier(0.16, 1, 0.30, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast:  160ms;
  --dur-base:  280ms;
  --dur-slow:  560ms;

  /* Gutter that holds at every width. */
  --gutter: clamp(20px, 5vw, 96px);
}

/* ---------- 2. RESET -------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

/* The browser's own [hidden] rule is weaker than any author rule that sets
   display, so `el.hidden = true` silently does nothing to a flex or grid
   component. Every [hidden] in this codebase relies on it working, so state
   it once, here, at author origin. */
[hidden] { display: none !important; }

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

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

ol[role="list"],
ul[role="list"] { list-style: none; }

body {
  min-height: 100%;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

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

button {
  background: none;
  border: 0;
  cursor: pointer;
}

a { color: inherit; }

/* Headings inherit their concept's display face; never bold by default.
   Weight is a design decision, not a browser default. */
h1, h2, h3, h4, h5, h6 { font-weight: inherit; font-size: inherit; }

/* ---------- 3. ACCESSIBILITY PRIMITIVES ------------------- */

/* Visible focus is non-negotiable and uses the signal colour,
   so the keyboard path is also on-brand. */
:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
  border-radius: 1px;
}
:focus:not(:focus-visible) { outline: none; }

.u-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link — present in every concept, invisible until focused. */
.u-skip {
  position: absolute;
  top: var(--s1);
  left: var(--s1);
  z-index: 999;
  padding: var(--s2) var(--s3);
  background: var(--ink);
  color: var(--paper);
  font-size: 14px;
  letter-spacing: 0.02em;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur-fast) var(--ease-out);
}
.u-skip:focus { transform: translateY(0); }

/* ---------- 4. MOTION SAFETY ------------------------------ */
/* Concepts layer motion on top of a working static page.
   This clause guarantees the static page is what remains. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* Anything revealed by script must be visible regardless. */
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* ---------- 5. REVEAL MECHANICS ---------------------------
   The hidden start state exists ONLY under .js-motion, which
   the reveal script adds after confirming motion is welcome.
   Without JS, or with reduced motion, none of this applies and
   the page is simply visible. Concepts tune distance and
   duration in their own stylesheets. ---------------------- */
.js-motion [data-reveal] {
  opacity: 0;
  transform: translateY(var(--reveal-rise, 14px));
  transition:
    opacity   var(--reveal-dur, 560ms) var(--ease-out) var(--reveal-delay, 0ms),
    transform var(--reveal-dur, 560ms) var(--ease-out) var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
.js-motion [data-reveal].is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* ---------- 6. SELECTION ---------------------------------- */
::selection {
  background: var(--signal);
  color: var(--paper);
}
