/* ============================================================
   BASE: reset, fonts, type defaults, focus, motion policy
   ============================================================ */

/* ── Fonts (self-hosted, latin subset) ─────────────────────── */
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("../fonts/bricolage-grotesque.woff2") format("woff2-variations");
  font-weight: 200 800;
  font-stretch: 75% 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
                 U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Switzer";
  src: url("../fonts/switzer.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono.woff2") format("woff2-variations");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
                 U+2215, U+FEFF, U+FFFD;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
    scroll-padding-top: calc(var(--nav-h) + var(--p-space-5));
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* clip, not hidden: `hidden` would turn the body into its own scroll
     container, which breaks the sticky header and the scroll-driven
     progress bar. `clip` stops sideways overflow without doing that. */
  overflow-x: clip;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd, ol, ul {
  margin: 0;
  padding: 0;
}
ol, ul { list-style: none; }

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

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

button, input, select, textarea {
  font: inherit;
  color: inherit;
}
button {
  background: none;
  border: 0;
  cursor: pointer;
}

b, strong { font-weight: 600; }

/* ── Type roles ────────────────────────────────────────────────
   Bricolage carries an optical-size axis, so the face is allowed to
   redraw itself between the masthead and a project title instead of
   being scaled uniformly. That axis is the reason this face is here. */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  text-wrap: balance;
  font-optical-sizing: auto;
}

/* ── Skip link ─────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: var(--p-z-toast);
  transform: translateY(-120%);
  background: var(--color-accent);
  color: var(--color-accent-on);
  padding: var(--p-space-3) var(--p-space-5);
  border-radius: 0 0 var(--p-radius-2) 0;
  font-family: var(--font-mono);
  font-size: var(--t-body-sm);
}
.skip-link:focus-visible { transform: translateY(0); }

/* ── Focus ─────────────────────────────────────────────────── */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: var(--p-radius-1);
}
/* Never leave a focus ring invisible over imagery. */
.work-row:focus-visible,
.case__gallery a:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  box-shadow: 0 0 0 5px var(--color-focus-halo);
}

::selection {
  background: var(--color-accent);
  color: var(--color-accent-on);
}

/* ── Motion policy ─────────────────────────────────────────────
   Every animated thing on this page collapses to its finished state.
   The stitch geometry stays; only the movement goes. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── The theme wipe ────────────────────────────────────────────
   scripts/theme.js opens a circle from the switch itself across the
   new theme. Two things have to be cleared out of its way.

   First the browser's own crossfade. Left alone it runs a quarter of
   a second of opacity over both snapshots, so the edge of the circle
   arrives soft and the old theme shows through it. The circle is the
   whole gesture, so the fade is simply stood down and the new page is
   put on top to be clipped against the old one.

   Second the site's own colour transitions. A dozen controls carry a
   short colour transition for hover, and a change of theme fires all
   of them at once, so the ground the circle has just uncovered spends
   the next fifth of a second catching up with itself. The class is
   held for the length of the wipe only. */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-new(root) { z-index: 1; }

.theme-switching *,
.theme-switching *::before,
.theme-switching *::after {
  transition-property: none !important;
}
