/* ==========================================================
   FONTS: Bookmania and Aktiv Grotesk come from the Adobe Fonts web
   project "Yesterday's Signs website" (kit dtb7jih, in Tim's Adobe
   account at fonts.adobe.com → Web Projects). Each page links it in its
   <head>, before this file. The kit is allowed on yesterdaysigns.com,
   www, *.vercel.app, and localhost; add any new domain there.
   ========================================================== */

/* ==========================================================
   YESTERDAY'S SIGNS — SITE
   Brand tokens live in :root. Yellow never goes on white as
   type; it's a background behind ink, or type on ink.
   The home hero is the one loud thing; everything else stays
   quiet: white pages, hairline dividers, no boxes.
   ========================================================== */

:root {
  --yellow: #ECFF00;
  --ink: #231F20;
  --paper: #FFFFFF;
  --muted: #5C5758;
  --muted-dark: rgba(255, 255, 255, 0.72);
  --line: rgba(35, 31, 32, 0.14);
  --line-dark: rgba(255, 255, 255, 0.18);

  /* Adobe Fonts family names first; the fallbacks only show if the
     kit can't load. */
  --font-display: "bookmania", "Bookman Old Style", "Bookman", "URW Bookman", Georgia, serif;
  --font-body: "aktiv-grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Bookmania tracking from the brand guidelines: Illustrator -40.
     Illustrator tracking is in 1/1000 em, so -40 = -0.04em. */
  --tracking-display: -0.04em;

  /* Subtle rounding for buttons and boxes (not the checklist). */
  --radius: 6px;
  --radius-sm: 4px;

  --wrap: 1120px;
  --gutter: clamp(16px, 4vw, 40px);
  --section: clamp(64px, 8vw, 112px);
  --header-h: 72px;
}

/* ---------- Base ---------- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: var(--header-h); }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  -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: 700;
  line-height: 1.08;
  letter-spacing: var(--tracking-display);
  margin: 0 0 0.5em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.5rem, 5.5vw, 4.25rem); }
h2 { font-size: clamp(1.75rem, 3.2vw, 2.5rem); }
h3 { font-size: 1.25rem; line-height: 1.2; }

p { margin: 0 0 1em; max-width: 62ch; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }

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

.skip {
  position: absolute; left: -999px; top: 12px; z-index: 100;
  background: var(--yellow); color: var(--ink); padding: 10px 14px; font-weight: 700;
}
.skip:focus { left: 12px; }

:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
.site-footer :focus-visible { outline-color: var(--yellow); }

.eyebrow {
  font: 700 0.8125rem/1.3 var(--font-body);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin: 0 0 1rem;
}
.lede { font-size: clamp(1.125rem, 1.5vw, 1.25rem); max-width: 52ch; }
.muted { color: var(--muted); }

/* Placeholder copy — search the project for class="tbd" to find
   everything still to fill. Delete these rules once it's all filled. */
.tbd {
  background: linear-gradient(transparent 58%, rgba(236, 255, 0, 0.9) 58%);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.hero .tbd, .cta-band .tbd, .page-head--yellow .tbd, .site-footer .tbd, .contact-card:hover .tbd, .ready-result .tbd {
  background: none;
  text-decoration: underline dotted;
  text-underline-offset: 0.2em;
}

/* ---------- Buttons & links ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  min-height: 48px;
  padding: 0 1.4em;
  font: 700 1rem/1 var(--font-body);
  text-decoration: none;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--paper);
  cursor: pointer;
  transition: transform 0.15s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn--yellow { background: var(--yellow); color: var(--ink); }
.btn--ghost { background: transparent; color: var(--ink); }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

.text-link { font-weight: 700; text-decoration: none; border-bottom: 2px solid currentColor; padding-bottom: 2px; }
.text-link:hover { border-bottom-color: transparent; }

/* ---------- Header ---------- */

/* Black bar: yellow logo, white links, yellow for the current page
   and the Get a Quote button. */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--ink);
  color: var(--paper);
}
.site-header :focus-visible { outline-color: var(--yellow); }
.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; min-height: var(--header-h);
}
.brand img { height: 44px; width: auto; }

.site-nav { display: flex; align-items: center; gap: 32px; }
.site-nav ul { display: flex; gap: 28px; list-style: none; margin: 0; padding: 0; }
.site-nav ul a {
  text-decoration: none; font-weight: 500;
  padding: 6px 0; border-bottom: 2px solid transparent;
}
.site-nav ul a:hover,
.site-nav ul a[aria-current="page"] { border-bottom-color: var(--yellow); }

.nav-toggle {
  display: none;
  align-items: center; gap: 10px;
  min-height: 44px; padding: 0 14px;
  font: 700 0.9375rem var(--font-body);
  background: transparent; color: var(--paper);
  border: 2px solid var(--paper); border-radius: var(--radius); cursor: pointer;
}
.site-header .btn--yellow { border-color: var(--yellow); }
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
  display: block; width: 18px; height: 2px; background: currentColor; position: relative;
}
.nav-toggle-bars::before, .nav-toggle-bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle-bars::before { top: -6px; }
.nav-toggle-bars::after { top: 6px; }
/* Open: the bars become an X and the label reads "Close". */
.nav-toggle[aria-expanded="true"] .nav-toggle-bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after { top: 0; transform: rotate(-45deg); }

@media (max-width: 860px) {
  .brand img { height: 36px; }
  .js .nav-toggle { display: inline-flex; }
  /* The open menu covers the screen under the header, with the page
     links set big in Bookmania and Get a Quote below them. The page
     behind doesn't scroll while it's open (html.nav-open, script.js). */
  .site-nav {
    position: absolute; top: 100%; left: 0; right: 0;
    height: calc(100vh - var(--header-h)); overflow-y: auto;
    flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 0;
    background: var(--ink);
    padding: 8px var(--gutter) 32px;
    border-top: 1px solid var(--line-dark);
  }
  @supports (height: 100svh) { .site-nav { height: calc(100svh - var(--header-h)); } }
  .js .site-nav { display: none; }
  .js .site-nav.is-open { display: flex; }
  .site-nav ul { flex-direction: column; gap: 0; }
  .site-nav ul a {
    display: block; padding: 18px 0; border-bottom: 1px solid var(--line-dark);
    font: 700 2rem/1.1 var(--font-display); letter-spacing: var(--tracking-display);
  }
  .site-nav ul a[aria-current="page"] { border-bottom-color: var(--line-dark); color: var(--yellow); }
  .site-nav .btn { margin-top: 28px; min-height: 52px; font-size: 1.0625rem; }
  /* No JS: nav sits in normal flow under the logo. */
  html:not(.js) .header-inner { flex-wrap: wrap; }
  html:not(.js) .site-nav { position: static; height: auto; border: 0; padding: 0 0 16px; width: 100%; }
  html:not(.js) .site-nav ul a { font: 500 1rem var(--font-body); padding: 12px 0; }
}
html.nav-open { overflow: hidden; }

/* ==========================================================
   HOME HERO — the tagline set as a poster in the two brand faces.
   The connector words ("What's", "than") are quiet Bookmania italics;
   the loud words are Aktiv Grotesk: FASTER in black italic caps,
   "today?" in bold. The punchline is the logo's own "Yesterday."
   lettering on the tilted ink strip.
   Every size is in --u, so the composition scales as one piece at
   every window size: the poster, the strip, the gaps, and on desktop
   the description column, its text, and the buttons too. --u is as big
   as the width allows (capped at 12px) and the window height allows.
   ========================================================== */

.hero {
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-wipe: cubic-bezier(0.65, 0, 0.35, 1);
  --col: calc(min(100vw, var(--wrap)) - 2 * var(--gutter));
  /* Phones and tablets (stacked): the poster's top line, "What's
     FASTER" (about 80u), fills the column. The height limit only bites
     on short landscape screens, which scroll instead of shrinking the
     poster to nothing (never below 4px, or the column on tiny phones). */
  --u-fit: calc((100vh - var(--header-h) - 270px) / 60);
  --u: max(min(4px, var(--col) / 84), min(12px, var(--col) / 84, var(--u-fit)));
  /* "Yesterday." is a little wider when stacked, so the strip reaches
     most of the way across a phone. */
  --word: 70;
  min-height: calc(100vh - var(--header-h));
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--yellow);
  padding: 28px 0 32px;
  overflow: hidden;
}
/* Phones: measure against the visible screen, not behind the browser bars. */
@supports (height: 100svh) {
  .hero {
    --u-fit: calc((100svh - var(--header-h) - 270px) / 60);
    min-height: calc(100svh - var(--header-h));
  }
}
.hero-inner { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }
/* Phones and tablets held upright: the hero fills the visible screen
   (the min-height above). The poster is limited by the screen width,
   so instead of floating it in the middle, the spare height is shared
   evenly: above the headline, between the strip and the description,
   and below the buttons. */
@media (max-width: 899px) and (orientation: portrait) {
  .hero { padding: clamp(24px, 5vw, 48px) 0 clamp(28px, 6vw, 56px); }
  /* Prefixed with .hero to win over the base rules further down. */
  .hero .hero-inner { flex: 1; display: flex; flex-direction: column; }
  .hero .poster { margin-top: auto; }
  .hero .hero-yesterday { margin-bottom: calc(var(--u) * 2.7 + 22px); }
  .hero .hero-foot { margin-top: auto; margin-bottom: auto; }
}

/* The poster spans the hero's width, so "today?" always ends at the
   right edge, where the description ends: beside the strip on desktops,
   under it on phones and tablets. */
.poster { margin: 0; font-weight: 400; letter-spacing: 0; line-height: 1; display: flex; flex-direction: column; width: auto; }
.poster-row { display: flex; align-items: baseline; gap: calc(var(--u) * 2); }
.poster-row--2 { justify-content: flex-end; margin-top: calc(var(--u) * 0.5); }

.p-whats {
  font: italic 400 calc(var(--u) * 9.6)/0.9 var(--font-display);
  letter-spacing: -0.02em;
}
/* Italic and kept a step below "Yesterday." so the punchline wins.
   Bold, the same weight as "today?" (Tim: Black read too heavy once the
   real Aktiv Grotesk loaded). */
.p-faster {
  font: italic 700 calc(var(--u) * 13)/0.82 var(--font-body);
  letter-spacing: -0.035em;
  text-transform: uppercase;
  margin-left: calc(var(--u) * 0.4);
}
.p-than { display: inline-block; font: italic 400 calc(var(--u) * 9)/1 var(--font-display); letter-spacing: -0.02em; margin-right: calc(var(--u) * 0.4); }
.p-today { font: 700 calc(var(--u) * 11)/0.9 var(--font-body); letter-spacing: -0.04em; }

/* "Yesterday." tucks up under "than today?": the strip clears "than"
   by about 3.8u, and because it tilts, its left side rises into the
   empty space under "What's". */
.hero-yesterday { margin-top: calc(var(--u) * 1.45); }

/* The ink strip runs off the left edge like tape. Tilted −4° per Tim
   (Illustrator Rotate −4° = CSS rotate(4deg); Illustrator counts
   counterclockwise as positive). The whole strip tilts and the word is
   turned back level inside it, with enough padding that the tilt never
   uncovers it. #rough-edge (in index.html) gives it a hand-cut edge.
   It peels like a vinyl sticker: script.js clips .vinyl-front along
   the fold and draws the lifted flap in .vinyl-flap. */
.vinyl {
  position: relative;
  display: block;
  width: fit-content;
  /* Pivot at the middle of the word, so the word stays where it is. */
  transform-origin: calc(100% - var(--u) * (3.5 + var(--word) / 2)) 50%;
  transform: rotate(4deg);
}
.vinyl-front {
  position: relative;
  isolation: isolate;
  display: block;
  padding: calc(var(--u) * 3.4) calc(var(--u) * 3.5) calc(var(--u) * 3.4) 0;
}
.vinyl-ink {
  position: absolute;
  /* Runs far past the left edge; .hero clips it at the screen edge. */
  inset: 0 0 0 -100vw;
  z-index: -1;
  background: var(--ink);
  filter: url(#rough-edge);
}
.vinyl-word { display: block; width: calc(var(--u) * var(--word)); height: auto; transform: rotate(-4deg); }
/* Once script.js has drawn the hand-cut edge as a fixed outline (the
   strip's clip-path), the live filter comes off: it's costly to redraw
   on every frame of a peel, especially in Safari and on phones. The
   strip also gets its own GPU layer, so a peel only moves its clip
   instead of repainting the whole strip each frame. */
.vinyl.is-cut .vinyl-ink { filter: none; }
.vinyl.is-cut .vinyl-front { will-change: transform; }
.vinyl-flap {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none;
  /* On its own layer, Safari draws the shadow on the GPU. */
  will-change: transform;
  filter: drop-shadow(2px 6px 12px rgba(35, 31, 32, 0.35));
}
/* Grab handles (added by script.js): an invisible square on each of the
   strip's right-hand corners. Only these start a peel; touch drags on
   them don't scroll the page. While a peel is being dragged, the whole
   page shows the grabbing hand and no text gets selected. */
.vinyl-grab {
  position: absolute; right: -8px; z-index: 2;
  width: clamp(44px, calc(var(--u) * 9), 96px); height: clamp(44px, calc(var(--u) * 9), 96px);
  cursor: grab; touch-action: none;
}
.vinyl-grab--top { top: -8px; }
.vinyl-grab--bottom { bottom: -8px; }
html.is-peeling, html.is-peeling * { cursor: grabbing !important; user-select: none; -webkit-user-select: none; }
/* What the peel reveals: the cut line "Yesterday." was made from, traced
   on the wall exactly under the letters, like the path the plotter
   followed. Same padding, width, and turn as the word, so it lines up;
   clipped to the strip, so it only shows where the vinyl is peeled
   back. Other ideas for this spot ("Already done.", Terry) are in
   ../samples/peel-reveals.html. */
/* The box reaches 2u into the bleed on the left, so the stroke around
   the "Y" isn't clipped. The image has 24px of room around the letters
   (at its 2400px width), and the negative margin pulls it back so the
   letters sit exactly under the word. */
.vinyl-under { position: absolute; inset: 0 0 0 calc(var(--u) * -2); overflow: hidden; padding: calc(var(--u) * 3.4) calc(var(--u) * 3.5) calc(var(--u) * 3.4) calc(var(--u) * 2); }
.vinyl-cut {
  display: block; height: auto; max-width: none; transform: rotate(-4deg);
  width: calc(var(--u) * var(--word) * 2448 / 2400);
  margin: calc(var(--u) * var(--word) * -24 / 2400) 0 0 calc(var(--u) * var(--word) * -24 / 2400);
}

/* Description, then buttons under it: the last beat of the animation.
   Phones and tablets stack it under the strip, clear of its lowest
   (right-hand) corner. */
.hero-foot {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 20px;
  margin-top: calc(var(--u) * 2.7 + 22px);
}
.hero-foot .lede { margin: 0; max-width: 58ch; font-size: 1rem; line-height: 1.5; }
.hero-foot .btn-row { margin: 0; }

/* The two hero buttons always sit side by side. If the column is ever
   too narrow they shrink (text and padding together, via cqi) rather
   than stack. */
.hero-foot { container-type: inline-size; }
.hero-foot .btn-row {
  flex-wrap: nowrap;
  gap: 0.75em;
  font-size: 0.875rem;
  font-size: min(1rem, 4.6cqi);
}
.hero-foot .btn-row .btn { font-size: 1em; padding: 0 1.2em; min-height: max(40px, 3em); white-space: nowrap; }

/* Desktops (900px and up): the tagline on top, then the strip with the
   description and buttons beside it. The strip (65.5u), a gap (4u), and
   the description column (34u) share the width, and the description's
   text and buttons are in u as well, so the hero keeps the same
   proportions at every window size. The block is centered, and "today?"
   ends where the description ends. */
@media (min-width: 900px) {
  .hero {
    --word: 62;
    --u-wide: calc(var(--col) / 103.5);
    --u-fit: calc((100vh - var(--header-h) - 80px) / 52);
    --u: max(4px, min(12px, var(--u-wide), var(--u-fit)));
  }
  @supports (height: 100svh) {
    .hero { --u-fit: calc((100svh - var(--header-h) - 80px) / 52); }
  }
  .hero-inner {
    display: grid;
    grid-template-columns: auto calc(var(--u) * 34);
    justify-content: center;
    column-gap: calc(var(--u) * 4);
    row-gap: calc(var(--u) * 2.9);
    align-items: start;
  }
  .poster { grid-column: 1 / -1; width: auto; }
  .hero-yesterday { grid-column: 1; margin-top: calc(var(--u) * -3.05); }
  .hero-foot { grid-column: 2; margin: 0; gap: calc(var(--u) * 1.8); }
  .hero-foot .lede { font-size: clamp(14px, calc(var(--u) * 1.5), 17px); }
  .hero-foot .btn-row { font-size: min(clamp(13px, calc(var(--u) * 1.45), 16px), 4.6cqi); }
}

/* The tagline plays in reading order, like someone saying it: each
   word mostly lands before the next starts, then a beat, then the
   bar goes on like vinyl and "Yesterday." lands as the punchline.
   FASTER arrives fastest. "Yesterday." gets a moment on its own,
   then the description fades up, then the buttons. About 4s. It plays on a fresh visit
   or a reload, and is skipped when someone clicks back to Home from
   another page (the .hero-instant class, set in index.html).
     What's 0.2s · FASTER 0.55s · than 1.0s · today? 1.3s
     (beat) bar 2.05s · Yesterday. 2.25s
     Yesterday. done 2.85s · (pause) · description 3.2s · buttons 3.5s */
@media (prefers-reduced-motion: no-preference) {
  .p-whats { animation: in-left 0.6s var(--ease) 0.2s both; }
  .p-faster { animation: in-right 0.4s var(--ease) 0.55s both; }
  .p-than { animation: in-spin 0.6s var(--ease) 1s both; }
  .p-today { animation: in-drop 0.55s var(--ease) 1.3s both; }
  .vinyl-ink { animation: wipe 0.5s var(--ease-wipe) 2.05s both; }
  /* The cut line only switches on once the strip fully covers it
     (the strip's wipe starts far off-screen, so it can't share it). */
  .vinyl-under { animation: under-in 0s 2.6s both; }
  .vinyl-word { animation: wipe 0.6s var(--ease) 2.25s both; }
  .hero-foot .lede { animation: rise 0.6s var(--ease) 3.2s both; }
  .hero-foot .btn-row { animation: rise 0.5s var(--ease) 3.5s both; }
}
.hero-instant .hero *, .hero-instant .hero *::before { animation: none !important; }
@keyframes in-left { from { opacity: 0; transform: translateX(-0.25em); } }
@keyframes in-right { from { opacity: 0; transform: translateX(0.18em) skewX(-8deg); } }
@keyframes in-spin { from { opacity: 0; transform: rotate(-16deg) scale(0.85); } }
@keyframes in-drop { from { opacity: 0; transform: translateY(-0.2em); } }
@keyframes wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes under-in { from { visibility: hidden; } to { visibility: visible; } }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } }

/* ---------- Inner page header ---------- */

.page-head {
  padding: clamp(56px, 8vw, 104px) 0 clamp(40px, 5vw, 64px);
  border-bottom: 1px solid var(--line);
}
.page-head h1 { max-width: 16ch; }
.page-head .lede { color: var(--muted); margin: 0; }
.page-head--yellow { background: var(--yellow); border-bottom: 0; }
.page-head--yellow .lede { color: var(--ink); }

/* ---------- Sections ---------- */

.section { padding: var(--section) 0; }
.section + .section { border-top: 1px solid var(--line); }

.split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 32px clamp(32px, 6vw, 96px);
  align-items: start;
}
.split > :first-child h2 { margin-bottom: 0.4em; }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; } }


/* ---------- Explorer (Services and Process) ----------
   A short list on the left and one detail panel on the right, so a
   client reads one thing at a time. Clicking an item swaps the panel;
   the panel stays in view while they click. On phones each panel opens
   under its own item. Without JavaScript every panel is just shown.
   --n (set on the element) is the number of items. */

/* Equal room above and below the title; the bottom is trimmed by the
   title's own space under its letters, so it looks equal too. */
.page-head--compact { padding: clamp(32px, 4.5vw, 64px) 0 calc(clamp(32px, 4.5vw, 64px) - 10px); }
/* The nav already marks the page, so the label above the heading goes. */
.page-head--compact .eyebrow { display: none; }
.page-head--compact h1 { max-width: none; font-size: clamp(2.25rem, 4vw, 3rem); margin-bottom: 0.3em; }
/* Desktop: heading left, description right, to keep the explorer in
   the first screen. */
@media (min-width: 860px) {
  .page-head--compact .wrap {
    display: grid; grid-template-columns: auto minmax(0, 36ch);
    justify-content: space-between; align-items: end; column-gap: 48px;
  }
  .page-head--compact h1 { margin: 0; }
  .page-head--compact .lede { padding-bottom: 0.25em; font-size: 1.0625rem; }
}

.explorer {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  /* One row per item, plus a last row that soaks up the panel's extra
     height so the list keeps its natural spacing. */
  grid-template-rows: repeat(var(--n), auto) 1fr;
  column-gap: clamp(32px, 5vw, 80px);
  align-items: start;
}
/* Closes the list with a bottom rule. */
.explorer::after { content: ""; grid-column: 1; align-self: start; border-top: 1px solid var(--line); }

.explorer-item {
  grid-column: 1;
  display: grid; grid-template-columns: 3rem minmax(0, 1fr) auto; align-items: center; gap: 12px;
  width: 100%;
  padding: 14px 16px 14px 12px;
  background: none; border: 0; border-top: 1px solid var(--line);
  font: inherit; color: var(--ink); text-align: left;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.explorer-num { font-family: var(--font-display); letter-spacing: var(--tracking-display); font-size: 1.375rem; line-height: 1; }
.explorer-text { display: grid; gap: 2px; }
.explorer-title { font: 700 clamp(1.125rem, 1.8vw, 1.375rem)/1.2 var(--font-display); letter-spacing: var(--tracking-display); }
.explorer-hint { font-size: 0.875rem; color: var(--muted); }
.explorer-arrow { font-weight: 700; opacity: 0; transform: translateX(-4px); transition: opacity 0.15s ease, transform 0.15s ease; }
.explorer-item:hover .explorer-title { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.explorer-item:hover .explorer-arrow,
.explorer-item[aria-expanded="true"] .explorer-arrow { opacity: 1; transform: none; }
.explorer-item[aria-expanded="true"] { background: var(--yellow); border-radius: var(--radius); border-top-color: transparent; }
.explorer-item[aria-expanded="true"] .explorer-hint { color: var(--ink); }
.explorer-item[aria-expanded="true"] .explorer-title { text-decoration: none; }

.explorer-panel {
  grid-column: 2; grid-row: 1 / -1;
  position: sticky; top: calc(var(--header-h) + 24px);
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  padding: clamp(22px, 2.5vw, 32px);
}
.panel-kicker { font: 700 0.75rem var(--font-body); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin: 0 0 10px; font-variant-numeric: tabular-nums; }
.explorer-panel h2 { font-size: clamp(1.875rem, 3vw, 2.5rem); margin: 0 0 0.25em; }
.panel-lead { font-size: 1.125rem; max-width: 48ch; margin: 0 0 20px; }
.panel-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: 16px 32px; margin: 0; padding-top: 18px; border-top: 1px solid var(--line);
}
/* Services: the chips, then what we need, each full width. Process
   steps have two short facts, so they sit side by side. */
.panel-facts > div { grid-column: 1 / -1; }
.explorer--steps .panel-facts > div { grid-column: auto; }
.panel-facts dt { font: 700 0.75rem var(--font-body); letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 6px; }
.panel-facts dd { margin: 0; color: var(--muted); }
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.chips li { border: 1px solid var(--ink); border-radius: var(--radius-sm); color: var(--ink); padding: 4px 10px; font-size: 0.875rem; }
.explorer-panel .btn-row { margin-top: 24px; }

/* Process: the steps are a connected timeline. Earlier steps fill in
   as you move through, so it reads like progress. */
.explorer--steps .explorer-item { position: relative; border-top: 0; }
/* The last step's own padding would add to the section's room below. */
@media (min-width: 860px) { .explorer--steps { margin-bottom: -14px; } }
.explorer--steps::after { border-top: 0; }
.explorer--steps .explorer-item::before {
  content: ""; position: absolute; left: calc(12px + 1.25rem - 1px); top: 0; bottom: 0;
  width: 2px; background: var(--line);
}
.explorer--steps .explorer-item:first-of-type::before { top: 50%; }
.explorer--steps .explorer-item:last-of-type::before { bottom: 50%; }
.explorer--steps .explorer-num {
  position: relative; z-index: 1;
  width: 2.5rem; height: 2.5rem; border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--ink); background: var(--paper);
  font-size: 0.9375rem;
}
.explorer--steps .explorer-item.is-done .explorer-num,
.explorer--steps .explorer-item[aria-expanded="true"] .explorer-num { background: var(--ink); color: var(--yellow); }

@media (max-width: 859px) {
  .explorer { grid-template-columns: 1fr; grid-template-rows: none; }
  .explorer-panel {
    grid-column: 1; grid-row: auto;
    position: static; top: auto;
    border: 0;
    padding: 4px 12px 28px calc(12px + 3rem + 12px);
  }
  .explorer-panel h2 { display: none; }  /* the item above already names it */
  .panel-kicker { display: none; }
  .explorer--steps .explorer-panel { position: relative; }
  .explorer--steps .explorer-panel::before {
    content: ""; position: absolute; left: calc(12px + 1.25rem - 1px); top: 0; bottom: 0;
    width: 2px; background: var(--line);
  }
  .explorer--steps .explorer-panel:last-of-type::before { display: none; }
}
/* Phones: each open panel hangs off a thin rule under its number (the
   Process timeline already draws one), its two buttons share a line,
   and "Next" drops the step's name (still read out by screen readers). */
@media (max-width: 480px) {
  .explorer-panel { padding-left: calc(12px + 2.5rem + 12px); position: relative; }
  .explorer:not(.explorer--steps) .explorer-panel::before {
    content: ""; position: absolute; left: calc(12px + 0.7rem - 1px); top: 0; bottom: 20px;
    width: 2px; background: var(--line);
  }
  .panel-lead { font-size: 1.0625rem; }
  .explorer-panel .btn-row { flex-wrap: nowrap; gap: 10px; }
  .explorer-panel .btn-row .btn { padding: 0 18px; }
  .next-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

.faq details { border-top: 1px solid var(--line); }
.faq details:last-child { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer; position: relative;
  padding: 20px 48px 20px 0; font: 700 1.0625rem/1.35 var(--font-body);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  font: 400 1.75rem/1 var(--font-body);
}
.faq details[open] summary::after { content: "\2013"; }
.faq details p { color: var(--muted); padding-bottom: 8px; }
.faq details > :last-child { padding-bottom: 20px; }

/* ---------- About ---------- */

/* At a glance: four figures, then a one-roof diagram. Yellow figures
   on ink. The diagram's line runs through every dot; the client's two
   ends (idea, done) are hollow, the four shop steps are filled. */
.glance { background: var(--ink); color: var(--paper); }
.glance .eyebrow { color: var(--yellow); }
.glance :focus-visible { outline-color: var(--yellow); }
.glance + .section { border-top: 0; }
.glance h2 { color: var(--paper); margin-bottom: clamp(24px, 3vw, 36px); }
.stats {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--line-dark);
}
.stats li { display: grid; gap: 4px; align-content: start; padding: 20px 20px 0 0; }
.stats li + li { padding-left: 20px; border-left: 1px solid var(--line-dark); }
.stat-num { font-family: var(--font-display); letter-spacing: var(--tracking-display); font-weight: 700; font-size: clamp(3.25rem, 6.5vw, 5.5rem); line-height: 0.9; color: var(--yellow); }
.stat-label { font: 700 0.8125rem var(--font-body); letter-spacing: 0.12em; text-transform: uppercase; color: var(--paper); margin-top: 6px; }
.stat-note { font-size: 0.9375rem; color: var(--muted-dark); }
@media (max-width: 700px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 24px; }
  .stats li:nth-child(odd) { padding-left: 0; border-left: 0; }
}

.flow {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 4fr) minmax(0, 1fr);
  align-items: start;
  margin-top: clamp(36px, 5vw, 64px);
}
/* The two client ends drop by the bracket's height (22px + 16px gap) so
   every dot sits on one line, however the labels wrap. */
.flow > .flow-node--you { margin-top: 38px; }
.flow-roof-nodes { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.flow-node {
  position: relative;
  display: grid; justify-items: center; gap: 12px;
  font: 700 clamp(0.75rem, 1.2vw, 0.9375rem)/1.3 var(--font-body);
  color: var(--paper); text-align: center;
}
.flow-node::before {
  content: ""; position: absolute; top: 7px; left: 0; right: 0;
  height: 2px; background: var(--line-dark);
}
.flow > .flow-node:first-child::before { left: 50%; }
.flow > .flow-node:last-child::before { right: 50%; }
.flow-dot { position: relative; width: 16px; height: 16px; border-radius: 50%; background: var(--yellow); }
.flow-node--you .flow-dot { background: var(--ink); border: 2px solid var(--yellow); }
.flow-node--you { color: var(--muted-dark); font-weight: 500; }
.flow-roof-label {
  margin: 0 calc(100% / 8 - 1px) 16px;
  height: 22px;
  border: 2px solid var(--yellow); border-bottom: 0;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  display: flex; justify-content: center;
}
.flow-roof-label span {
  transform: translateY(-50%);
  padding: 0 12px; background: var(--ink); color: var(--yellow);
  font: 700 0.75rem/1 var(--font-body); letter-spacing: 0.12em; text-transform: uppercase;
  height: fit-content;
}


/* About is just the team: the section fills the window under the
   header, content centered. */
.team-page { min-height: calc(100vh - var(--header-h)); display: flex; flex-direction: column; justify-content: center; }
@supports (height: 100svh) { .team-page { min-height: calc(100svh - var(--header-h)); } }
.team-page .wrap { width: 100%; }
.team-page h1 { font-size: clamp(2.25rem, 4vw, 3rem); margin-bottom: 0.3em; }
.team { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 32px; }
.person { border-top: 2px solid var(--ink); padding-top: 20px; }
/* With a portrait, the photo leads instead of the rule. Two-tone, in the
   site's exact yellow and ink (assets/img/team/), all cropped to 4:3. */
.person:has(.person-photo) { border-top: 0; padding-top: 0; }
.person-photo { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; margin-bottom: 20px; background: var(--yellow); }
/* Phones: each person takes about three-quarters of the width, stepping
   left, right, left, with smaller type and more room between them. */
@media (max-width: 600px) {
  .team { gap: 40px; }
  .person:has(.person-photo) { width: 74%; }
  .person:has(.person-photo):nth-child(even) { margin-left: auto; }
  .person-photo { margin-bottom: 14px; }
  .person h2 { font-size: 1.125rem; }
  .person .role { font-size: 0.6875rem; letter-spacing: 0.09em; margin-bottom: 8px; }
  .person p:last-child { font-size: 0.875rem; line-height: 1.5; }
}
/* Names are h2 under the page's h1, sized like the old h3s. */
.person h2 { font-size: 1.25rem; line-height: 1.2; margin-bottom: 4px; }
.role { font: 700 0.8125rem var(--font-body); letter-spacing: 0.1em; text-transform: uppercase; margin: 0 0 10px; }
.person p:last-child { color: var(--muted); margin: 0; }

/* ---------- Quote / contact ---------- */

.contact-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr)); gap: 20px; }
.contact-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: clamp(24px, 4vw, 40px);
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  text-decoration: none;
  transition: background-color 0.15s ease;
}
.contact-card:hover { background: var(--yellow); }
.contact-card .label { font: 700 0.8125rem var(--font-body); letter-spacing: 0.12em; text-transform: uppercase; }
.contact-card .big { font-family: var(--font-display); letter-spacing: var(--tracking-display); font-size: clamp(1.5rem, 3vw, 2.125rem); line-height: 1.1; overflow-wrap: anywhere; }
.contact-card p { margin: 0; color: var(--muted); font-size: 1.125rem; line-height: 1.45; }
.contact-card:hover p { color: var(--ink); }
.contact-card .go { margin-top: 8px; font-weight: 700; }

/* Get a Quote: the same contact section as Home (.contact-band below),
   filling the whole window under the header with the content centered,
   so only the yellow shows until you scroll. */
.quote-hero {
  min-height: calc(100vh - var(--header-h));
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(40px, 6vw, 80px) 0;
}
@supports (height: 100svh) { .quote-hero { min-height: calc(100svh - var(--header-h)); } }
.quote-hero .wrap { width: 100%; }

.info-list { margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 24px; }
.info-list dt { font: 700 0.75rem var(--font-body); letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 4px; }
.info-list dd { margin: 0; }

/* ---------- Readiness checklist ----------
   Desktop: heading and its line side by side, then the items on the
   left and the result panel on the right, so the whole section fits in
   one window. Phones stack everything. */
.ready-head {
  display: grid; grid-template-columns: auto minmax(0, 34ch);
  justify-content: space-between; align-items: end;
  gap: 8px 48px; margin-bottom: clamp(20px, 2.5vw, 32px);
}
.ready-head h2 { margin: 0; }
.ready-head p { margin: 0; }
@media (max-width: 899px) { .ready-head { grid-template-columns: 1fr; } }

/* Checked boxes set the level; the ink panel shows the matching next
   step. The meter fills one, two, or three segments. */

.ready { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 24px clamp(28px, 4vw, 56px); align-items: start; }
@media (max-width: 759px) { .ready { grid-template-columns: 1fr; } }
.ready fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.ready-item {
  display: grid; grid-template-columns: 22px 1fr; gap: 14px; align-items: start;
  padding: 12px 0; border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.ready-item:first-of-type { border-top: 1px solid var(--line); }
.ready-item input {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; margin: 1px 0 0;
  border: 2px solid var(--ink); background: var(--paper);
  display: grid; place-content: center;
  cursor: pointer;
}
.ready-item input::before {
  content: ""; width: 11px; height: 6px;
  border: solid var(--yellow); border-width: 0 0 3px 3px;
  transform: translateY(-1px) rotate(-45deg);
  opacity: 0;
}
.ready-item input:checked { background: var(--ink); }
.ready-item input:checked::before { opacity: 1; }
.ready-item span { font-weight: 500; }
.ready-item small { display: block; font-weight: 400; color: var(--muted); font-size: 0.875rem; }

.ready-result { background: var(--ink); color: var(--paper); padding: clamp(24px, 3vw, 32px); }
.ready-meter { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-bottom: 14px; }
.ready-meter span { height: 6px; background: var(--line-dark); transition: background-color 0.2s ease; }
.ready-result[data-level="1"] .ready-meter span:first-child,
.ready-result[data-level="2"] .ready-meter span:nth-child(-n+2),
.ready-result[data-level="3"] .ready-meter span { background: var(--yellow); }
.ready-count { font: 700 0.75rem var(--font-body); letter-spacing: 0.12em; text-transform: uppercase; color: var(--yellow); margin: 0 0 14px; }
.ready-result h3 { font-size: clamp(1.5rem, 2.4vw, 1.875rem); color: var(--paper); margin: 0 0 8px; }
.ready-result p { color: var(--muted-dark); margin: 0; }
.ready-result .btn-row { margin-top: 20px; }
/* Phones: the next-step buttons run full width, one per line. */
@media (max-width: 480px) { .ready-result .btn-row .btn { flex: 1 1 100%; } }
.ready-result .btn { background: var(--yellow); color: var(--ink); border-color: var(--yellow); }
.ready-result .btn--ghost { background: transparent; color: var(--paper); border-color: var(--paper); }
.ready-result :focus-visible { outline-color: var(--yellow); }

/* ---------- CTA band ---------- */

.cta-band { background: var(--yellow); padding: var(--section) 0; }
.cta-band h2 { font-size: clamp(2.25rem, 5vw, 3.75rem); max-width: 14ch; }
.cta-band p { font-size: 1.125rem; }

/* Home contact: heading and studio details left, the two contact
   cards stacked right. On yellow the cards are white and turn ink on
   hover. */
.cta-band .contact-title {
  max-width: none;
  white-space: nowrap;
  font-size: min(clamp(2.25rem, 5vw, 3.75rem), calc((100vw - 2 * var(--gutter)) / 8.7));
  margin-bottom: clamp(12px, 1.5vw, 20px);
}
.title-word { display: inline-block; height: 1em; width: auto; vertical-align: -0.254em; margin: 0 0.03em 0 0.02em; }
.nowrap { white-space: nowrap; }

/* The contact section (Home and Get a Quote): heading and reply line on
   top, the two cards side by side, the details along the bottom. */
.contact-band { padding: var(--section) 0; }
.contact-band .contact-lede { margin: 0; font-size: 1.125rem; }
.contact-cards--band { margin-top: clamp(20px, 2.4vw, 28px); grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 16px; }
.contact-cards--band .contact-card { padding: clamp(26px, 3.4vw, 44px); gap: 10px; }
.contact-cards--band .big { font-size: clamp(1.5rem, 2.6vw, 2.125rem); }
.contact-cards--band p { font-size: clamp(1.125rem, 1.5vw, 1.25rem); }
.contact-band .info-list {
  margin-top: clamp(20px, 2.4vw, 28px); padding-top: 18px;
  border-top: 1px solid rgba(35, 31, 32, 0.25);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr));
}
.cta-band .contact-card { background: var(--paper); }
.cta-band .contact-card:hover { background: var(--ink); color: var(--paper); }
.cta-band .contact-card:hover p { color: var(--muted-dark); }

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

/* overflow-x: clip keeps the tagline's blur room (its padding reaches
   past the column) from widening the page on phones. */
.site-footer { background: var(--ink); color: var(--muted-dark); font-size: 0.9375rem; overflow-x: clip; }
/* The tagline (then the logo), centered, with the same room above and
   below it. */
.footer-top { display: flex; justify-content: center; padding: clamp(48px, 6vw, 80px) 0; }

/* Footer tagline: "What's faster / than today?" set big on two lines
   (script.js fits them inside the logo's box: its full width, or its
   full height, whichever comes first), then the logo takes the same
   space. The tagline and the logo share one grid cell.
     words blur up into place 0–1.3s · (read) · soft wipe 2.4–3.8s
   Nothing is ever cut in half: each word fades and sharpens as it
   rises (no mask, so no letter tops peek out beforehand), and the wipe
   is a feathered band rather than a hard edge, with the tagline
   blurring away ahead of it while the logo sharpens in behind it.
   The logo stays.
   With JavaScript (html.js) the footer starts armed, with the words
   and the logo hidden, so nothing flashes before it plays. script.js
   plays it once it's in view and the fonts and logo are ready, or adds
   .is-static (just the logo) if the browser can't watch for it.
   Without JavaScript the footer simply shows the logo. */
/* Kept modest so it sits quietly over the bottom line: about a quarter
   of the screen on desktop (380px at most), two-thirds of a phone. */
.footer-tag { display: grid; width: min(100%, clamp(260px, 28vw, 380px)); }
/* Both share one cell, centered on each other. */
.footer-tag > * { grid-area: 1 / 1; align-self: center; }
.ft-line {
  font-family: var(--font-display); letter-spacing: var(--tracking-display);
  font-size: clamp(2.5rem, 6.4vw, 6rem); line-height: 0.86;
  color: rgba(255, 255, 255, 0.86); /* off-white: a touch quieter than the logo */
  /* Room all round so the wipe's mask never trims ascenders,
     descenders, or the blur; the negative margin keeps the layout the
     same. Its sides match the logo's, so the two masks line up. */
  padding: 0.15em 32px 0.3em; margin: -0.15em -32px -0.3em;
  /* Resting state: just the logo (still read by screen readers). */
  opacity: 0;
}
.ft-row { display: block; width: max-content; margin-inline: auto; }
.ft-w, .ft-w > span { display: inline-block; }
/* Same idea for the logo: invisible room around it so its blur fades
   out fully instead of stopping at the image's edges. */
.ft-logo { display: block; width: 100%; height: auto; box-sizing: content-box; padding: 24px 32px; margin: -24px -32px; }

/* The soft wipe: each piece wears a mask 2.5x its width with a
   feathered band (about 30% of the footer wide) that slides across.
   The two masks are mirror images, so wherever the tagline fades out
   the logo fades in. */
.js .footer-tag:not(.is-static) .ft-line,
.js .footer-tag:not(.is-static) .ft-logo {
  -webkit-mask-size: 250% 100%; mask-size: 250% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 100% 0; mask-position: 100% 0;
}
.js .footer-tag:not(.is-static) .ft-line {
  opacity: 1;
  -webkit-mask-image: linear-gradient(90deg, transparent 44%, #000 56%);
  mask-image: linear-gradient(90deg, transparent 44%, #000 56%);
}
.js .footer-tag:not(.is-static) .ft-logo {
  -webkit-mask-image: linear-gradient(90deg, #000 44%, transparent 56%);
  mask-image: linear-gradient(90deg, #000 44%, transparent 56%);
}
.js .footer-tag:not(.is-static) .ft-w > span { opacity: 0; }
.footer-tag.is-playing .ft-w > span { animation: ft-rise 0.9s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--i) * 140ms) both; }
.footer-tag.is-playing .ft-line { animation: ft-clear 1.4s cubic-bezier(0.45, 0, 0.25, 1) 2.4s both; }
.footer-tag.is-playing .ft-logo { animation: ft-wipe 1.4s cubic-bezier(0.45, 0, 0.25, 1) 2.4s both; }
@keyframes ft-rise {
  from { opacity: 0; transform: translateY(0.3em); filter: blur(0.08em); }
  to { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes ft-clear {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; filter: blur(0); }
  to { -webkit-mask-position: 0% 0; mask-position: 0% 0; filter: blur(0.06em); }
}
@keyframes ft-wipe {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; filter: blur(8px); }
  to { -webkit-mask-position: 0% 0; mask-position: 0% 0; filter: blur(0); }
}
/* Reduced motion: no rising, blurring, or wiping; the words fade in,
   then the tagline crossfades to the logo. */
@media (prefers-reduced-motion: reduce) {
  .js .footer-tag:not(.is-static) .ft-line,
  .js .footer-tag:not(.is-static) .ft-logo { -webkit-mask-image: none; mask-image: none; }
  .js .footer-tag:not(.is-static) .ft-logo { opacity: 0; }
  .footer-tag.is-playing .ft-w > span { animation: ft-fade-in 0.6s ease calc(var(--i) * 140ms) both; }
  .footer-tag.is-playing .ft-line { animation: ft-fade-out 0.6s ease 2.4s both; }
  .footer-tag.is-playing .ft-logo { animation: ft-fade-in 0.6s ease 2.4s both; }
}
@keyframes ft-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes ft-fade-in { from { opacity: 0; } to { opacity: 1; } }
/* The bottom line: the copyright on the left, the contact details on the
   right, all set the same (small, muted). Links light up on hover. */
.footer-base {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 8px 32px;
  padding: 20px 0 22px; border-top: 1px solid var(--line-dark);
  font-size: 0.8125rem; line-height: 1.4;
}
.footer-base p { margin: 0; }
.footer-contact { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: nowrap; gap: 8px 28px; white-space: nowrap; }
/* Phones: the copyright on its own line, then the details on one line
   across the full width, sized to fit (13px at most), with the
   copyright matching. --line-em is the details' width in em plus 0.9em
   per gap: 28.3 for email, Instagram, and city; 36.3 once the phone
   number is back. */
@media (max-width: 759px) {
  .footer-base { --line-em: 28.3; display: block; font-size: min(0.8125rem, calc((100vw - 2 * var(--gutter) - 2px) / var(--line-em))); padding: 18px 0 20px; }
  .footer-base p { margin-bottom: 0.7em; }
  .footer-contact { justify-content: space-between; gap: 0.9em; }
}
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { color: var(--paper); text-decoration: underline; }

/* ---------- 404 ---------- */

.not-found { min-height: calc(100vh - var(--header-h)); display: grid; align-items: center; background: var(--yellow); padding: var(--section) 0; }
.not-found img { width: clamp(120px, 18vw, 180px); margin-bottom: 32px; }

/* ---------- Motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; }
}
