/* =============================================================================
   BASE — the shared skeleton. Structure, rhythm, motion. No committed colour.
   Everything here sits in @layer base, so ANY rule in a variant's style.css
   overrides it regardless of specificity. Variants set tokens; they may also
   restyle or unset anything below.
   ========================================================================== */

@layer base, variant;

@layer base {

  /* --- tokens ------------------------------------------------------------ */
  :root {
    /* colour — neutral defaults, every variant replaces these */
    --bg:              #ffffff;
    --bg-sunk:         #f4f4f4;
    --ink:             #111111;
    --ink-soft:        color-mix(in srgb, var(--ink) 62%, transparent);
    --ink-faint:       color-mix(in srgb, var(--ink) 38%, transparent);
    --rule:            color-mix(in srgb, var(--ink) 14%, transparent);
    --accent:          var(--ink);

    /* hero art — how the diagram is composited onto the background */
    --diagram-blend:   multiply;
    --diagram-opacity: 1;
    --diagram-filter:  none;

    /* atmosphere */
    --grain-opacity:   0.055;
    --grain-blend:     multiply;
    --grid-opacity:    0;
    --grid-size:       88px;
    --glow:            none;

    /* type */
    --font-display: "Cormorant Garamond", "Times New Roman", serif;
    --font-sans:    "Archivo", "Helvetica Neue", Helvetica, sans-serif;
    --font-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", monospace;

    /* cqw = % of the headline column, so the title always fits beside the
       drawing no matter how wide the window gets */
    --title-size:   clamp(2.4rem, 15cqw, 9rem);
    --title-weight: 500;
    --title-track:  -0.042em;
    --title-leading: 0.9;

    /* how far the drawing runs past the right edge, and how far it tucks
       back under the headline column */
    /* Tuned for the current plate, which is cropped tight to the craft
       (content spans ~1.5%-99.5% of the frame). Looser art with dead margins
       needs a bigger bleed and some pull to look the same. */
    --figure-bleed: clamp(40px, 7vw, 120px);
    --figure-pull:  0%;
    --figure-col:   64fr;
    --text-col:     36fr;

    /* metrics */
    --page-max: 1760px;

    --pad:      clamp(22px, 3.4vw, 60px);
    --hairline: 1px;
  }

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

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

  html, body {
    margin: 0;
    overflow-x: clip;
  }

  body {
    background-color: var(--bg);
    background-image: var(--glow);
    background-repeat: no-repeat;
    background-attachment: fixed;
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: clamp(15px, 0.95vw, 17px);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }

  h1, h2, h3, p, figure, ol, ul { margin: 0; padding: 0; }
  ol, ul { list-style: none; }
  img { display: block; max-width: 100%; height: auto; }

  a { color: inherit; text-decoration: none; }

  ::selection { background: var(--ink); color: var(--bg); }

  /* --- atmosphere: grid paper, grain, glow -------------------------------- */
  body::before,
  body::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 9;
  }

  /* engineering grid paper */
  body::before {
    background:
      repeating-linear-gradient(to right,
        var(--rule) 0 var(--hairline),
        transparent var(--hairline) var(--grid-size)),
      repeating-linear-gradient(to bottom,
        var(--rule) 0 var(--hairline),
        transparent var(--hairline) var(--grid-size));
    opacity: var(--grid-opacity);
    z-index: 0;
  }

  /* film grain */
  body::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    opacity: var(--grain-opacity);
    mix-blend-mode: var(--grain-blend);
  }

  /* --- page frame --------------------------------------------------------- */
  .page {
    position: relative;
    z-index: 1;
    max-width: var(--page-max);
    margin-inline: auto;
    padding: var(--pad);
    display: flex;
    flex-direction: column;
    min-height: 100vh;
  }

  /* --- masthead ----------------------------------------------------------- */
  .masthead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
    position: relative;
    z-index: 3;
  }

  .brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6em;
    font-weight: 700;
    font-size: clamp(1.05rem, 1.35vw, 1.4rem);
    letter-spacing: -0.02em;
  }

  /* The lockup is inline SVG so it can be inked by the page. Every path takes
     currentColor; the single knockout path — authored as an opaque cream shape
     rather than a real hole — is singled out by its attribute value and tracks
     the background instead, so it stays a hole in every variant. */
  .brand__logo {
    display: block;
    width: clamp(138px, 12.8vw, 186px);
    flex: 0 0 auto;
    transition: opacity 300ms ease;
  }

  .brand__logo svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
  }

  .brand__logo path { fill: currentColor; }
  .brand__logo path[fill="#FEFCF7" i] { fill: var(--bg); }

  .brand:hover .brand__logo { opacity: 0.62; }

  /* assets/logo.svg unavailable: shrink to the fallback mark and bring the
     wordmark back, since the fallback artwork has no lettering of its own */
  .brand__logo--fallback { width: 1.15em; }
  .brand__logo--fallback path { fill: currentColor; }

  .brand:has(.brand__logo--fallback) .brand__name {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip-path: none;
  }

  /* the lockup already reads "Frontier Lab"; keep the text for screen readers */
  .brand__name {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .masthead__meta {
    display: inline-flex;
    align-items: center;
    gap: 0.9em;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-soft);
  }

  .masthead__sep {
    width: 2.4em;
    height: var(--hairline);
    background: currentColor;
    opacity: 0.5;
  }

  /* --- hero --------------------------------------------------------------- */
  .hero {
    position: relative;
    flex: 1 0 auto;
    display: grid;
    grid-template-columns: minmax(0, var(--text-col)) minmax(0, var(--figure-col));
    align-items: center;
    column-gap: clamp(0.5rem, 1.5vw, 2rem);
    min-height: min(66vh, 720px);
    /* asymmetric on purpose: the drawing sits high, near the masthead */
    padding-block: clamp(0.25rem, 1.2vh, 1.25rem) clamp(2rem, 5vh, 5rem);
  }

  .hero__text {
    grid-column: 1;
    position: relative;
    z-index: 2;
    /* the headline measures itself against this box, via cqw */
    container-type: inline-size;
  }

  .hero__kicker {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: 1.4em;
  }

  .hero__title {
    font-family: var(--font-display);
    font-weight: var(--title-weight);
    font-size: var(--title-size);
    line-height: var(--title-leading);
    letter-spacing: var(--title-track);
  }

  /* content.js supplies the line breaks; don't let them re-wrap */
  .hero__line { display: block; white-space: nowrap; }

  .hero__lede {
    margin-top: clamp(1.6rem, 3vh, 2.6rem);
    max-width: 38ch;
    color: var(--ink-soft);
    font-size: 1rem;
    line-height: 1.62;
    text-wrap: pretty;
  }

  /* the drawing runs off the right edge and tucks a little behind the headline */
  .hero__figure {
    grid-column: 2;
    position: relative;
    z-index: 1;
    /* Bleeds past the PAGE's edge by a fixed, capped amount — never past the
       viewport's. Letting it chase the viewport edge on wide screens meant the
       drawing kept growing after everything else had stopped, which is exactly
       what --page-max exists to prevent. */
    width: calc(100% + var(--pad) + var(--figure-bleed) + var(--figure-pull));
    margin-right: calc(-1 * (var(--pad) + var(--figure-bleed)));
    margin-left: calc(-1 * var(--figure-pull));
    pointer-events: none;
  }

  .hero__diagram {
    width: 100%;
    mix-blend-mode: var(--diagram-blend);
    opacity: var(--diagram-opacity);
    filter: var(--diagram-filter);
  }

  .hero__caption {
    position: absolute;
    right: calc(var(--pad) + var(--figure-bleed));
    bottom: -1.8em;
    font-family: var(--font-mono);
    font-size: 0.64rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-faint);
  }

  /* A variant may declare `video: { src }` in the manifest to swap the planet
     still for footage. Hidden unless the variant positions it. */
  .hero__video { display: none; }

  /* --- annotations ---------------------------------------------------------
     The parts index off the original sheet. Hidden by default — a variant opts
     in — and ALWAYS out of flow: `.hero` is a two-column grid, so leaving this
     in flow auto-places it into a new grid row and blows the hero apart. Keep it
     absolute even when shown. */
  .annotations {
    display: none;
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
  }

  .ann__group,
  .ann__list { margin: 0; padding: 0; }

  .ann__item { list-style: none; }

  /* --- project index ------------------------------------------------------ */
  .index {
    position: relative;
    z-index: 2;
    padding-block: clamp(3rem, 9vh, 7rem) clamp(3rem, 8vh, 6rem);
    border-top: var(--hairline) solid var(--rule);
  }

  .index__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 2rem;
    flex-wrap: wrap;
    margin-bottom: clamp(2rem, 5vh, 3.5rem);
  }

  .index__title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(1.9rem, 3.4vw, 3rem);
    letter-spacing: -0.035em;
    line-height: 1;
  }

  .index__note {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
  }

  .index__list {
    display: grid;
    gap: 0;
  }

  .entry {
    position: relative;
    display: grid;
    grid-template-columns: 4.5rem minmax(0, 21rem) minmax(0, 1fr);
    align-items: baseline;
    gap: 0 clamp(1rem, 3vw, 3rem);
    padding-block: clamp(1.1rem, 2.4vh, 1.7rem);
  }

  .entry__rule {
    position: absolute;
    inset: auto 0 0 0;
    height: var(--hairline);
    background: var(--rule);
    transform-origin: left;
    transition: background 400ms ease;
  }

  .entry:hover .entry__rule { background: var(--accent); }

  .entry__num {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    color: var(--ink-faint);
    transition: color 300ms ease;
  }

  .entry:hover .entry__num { color: var(--accent); }

  .entry__name {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(1.35rem, 2.1vw, 1.95rem);
    line-height: 1.1;
    letter-spacing: -0.028em;
    transition: translate 400ms cubic-bezier(.2,.8,.2,1);
  }

  .entry:hover .entry__name { translate: 0.35rem 0; }

  .entry__desc {
    color: var(--ink-soft);
    font-size: 0.94rem;
    line-height: 1.5;
    text-wrap: pretty;
  }

  /* --- colophon ----------------------------------------------------------- */
  .colophon {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding-top: clamp(1.5rem, 4vh, 2.5rem);
    padding-bottom: 3.5rem;
    border-top: var(--hairline) solid var(--rule);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
  }

  .colophon__links { display: flex; gap: clamp(1rem, 2.5vw, 2.2rem); }

  .colophon__link { transition: color 250ms ease; }
  .colophon__link:hover { color: var(--ink); }

  /* --- load choreography --------------------------------------------------- */
  @keyframes rise {
    from { opacity: 0; translate: 0 1.1rem; }
    to   { opacity: 1; translate: 0 0; }
  }

  /* Fade only — no zoom. A scale here would also desynchronise any variant that
     composites the drawing from more than one layer (see variants/orbit): the
     transform would land on the image and not on its companion plates. */
  @keyframes wash {
    from { opacity: 0; }
    to   { opacity: var(--diagram-opacity); }
  }

  .masthead,
  .hero__kicker,
  .hero__line,
  .hero__lede,
  .index__head,
  .entry {
    animation: rise 900ms cubic-bezier(.16,.84,.28,1) backwards;
  }

  .masthead      { animation-delay: 40ms; }
  .hero__kicker  { animation-delay: 160ms; }
  .hero__line:nth-child(1) { animation-delay: 220ms; }
  .hero__line:nth-child(2) { animation-delay: 320ms; }
  .hero__line:nth-child(3) { animation-delay: 420ms; }
  .hero__lede    { animation-delay: 520ms; }
  .index__head   { animation-delay: 120ms; }
  .entry         { animation-delay: calc(160ms + var(--i) * 55ms); }

  .hero__diagram {
    animation: wash 1500ms cubic-bezier(.16,.84,.28,1) 120ms backwards;
  }

  /* --- responsive ---------------------------------------------------------- */
  @media (max-width: 1080px) {
    .hero {
      grid-template-columns: minmax(0, 1fr);
      align-items: stretch;
      row-gap: clamp(1.5rem, 4vh, 3rem);
      min-height: 0;
    }

    /* headline leads; the drawing follows it rather than burying it */
    .hero__text   { grid-column: 1; grid-row: 1; }
    .hero__figure { grid-column: 1; grid-row: 2; }

    :root { --title-size: clamp(2.4rem, 8.6cqw, 5.5rem); }

    .hero__figure {
      width: calc(100% + var(--pad) * 2);
      margin-inline: calc(-1 * var(--pad));
    }

    .hero__caption {
      position: static;
      display: block;
      margin-top: 0.9em;
      padding-inline: var(--pad);
      text-align: right;
    }
  }

  @media (max-width: 720px) {
    .hero__line { white-space: normal; }

    .masthead__meta > span:first-child,
    .masthead__sep { display: none; }

    .entry {
      grid-template-columns: 2.6rem minmax(0, 1fr);
      gap: 0.35rem clamp(0.8rem, 3vw, 1.4rem);
    }

    .entry__num  { grid-row: 1; }
    .entry__name { grid-row: 1; }
    .entry__desc { grid-column: 2; }
  }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 1ms !important;
      animation-delay: 0ms !important;
      transition-duration: 1ms !important;
    }
  }
}
