/* ==========================================================================
   Fonts — self-hosted. IBM Plex Mono and Chivo are OFL (from @fontsource,
   latin subset). Bespoke Serif is not supplied; its fallback stack holds.
   ========================================================================== */
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/IBMPlexMono-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/IBMPlexMono-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/IBMPlexMono-600.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/IBMPlexMono-700-italic.woff2') format('woff2');
  font-weight: 700; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'Bespoke Serif';
  src: url('../assets/fonts/BespokeSerif-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Chivo';
  src: url('../assets/fonts/Chivo-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Chivo';
  src: url('../assets/fonts/Chivo-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

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

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

body {
  margin: 0;
  min-block-size: 100vh;
  /* Three stops, not two: the video's falloff is steeper in the lower half
     than a straight interpolation between the ends would give, and a linear
     two-stop version visibly lifts the middle of the page. */
  background: linear-gradient(180deg,
    var(--color-bg-top)    0%,
    var(--color-bg-mid)    52%,
    var(--color-bg-bottom) 100%);
  background-attachment: fixed;
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  font-weight: var(--fw-mono);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* Scrolling belongs to #screen, the post-processing container - see
   css/post.css. The document itself never scrolls, which also keeps the
   filter region pinned to the viewport. */
body { overflow: hidden; }

img { display: block; max-inline-size: 100%; height: auto; }

/* Artwork is not a drag source or a selection: no ghost image to drop on the
   desktop, no long-press save sheet on iOS. js/protect.js covers the browsers
   that ignore these (Firefox drags) and the right-click menu. */
img, video {
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
a { color: inherit; text-decoration: none; }

/* The dot IS the cursor — but only where a fine pointer exists and motion
   is welcome. Everyone else keeps the native cursor. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  html.has-cursor-trail, html.has-cursor-trail a, html.has-cursor-trail button { cursor: none; }
}

:focus-visible {
  outline: 1px solid var(--color-text);
  outline-offset: 4px;
}

/* Focus the script moves for screen readers — the case-study heading after a
   tape is chosen (js/router.js commit) — is not something to click, so it
   gets no ring; the author saw a box round the logo on every open. Real
   controls keep theirs. */
[tabindex='-1']:focus,
[tabindex='-1']:focus-visible { outline: none; }

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

.skip-link {
  position: fixed;
  inset-block-start: 0; inset-inline-start: 0;
  z-index: var(--z-critical);
  padding: 10px 16px;
  background: var(--color-bg-top);
  font-size: var(--fs-body);
  letter-spacing: var(--ls-mono-ui);
  text-transform: uppercase;
  transform: translateY(-150%);
}
.skip-link:focus-visible { transform: translateY(0); }

/* The "Copied!" note from js/contact.js, shown when CONTACT copies the
   address. Lives on <body>, outside #screen and its filter. */
.contact-toast {
  position: fixed;
  inset-block-end: 28px;
  inset-inline-start: 50%;
  z-index: var(--z-critical);
  margin: 0;
  padding: 10px 14px;
  border: 1px solid rgba(241, 237, 228, 0.18);
  border-radius: 3px;
  background: rgba(9, 9, 12, 0.92);
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: var(--ls-mono-ui);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, 6px);
  transition: opacity var(--dur-fade) var(--ease), transform var(--dur-fade) var(--ease);
}
.contact-toast.is-shown { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .contact-toast { transition: none; transform: translate(-50%, 0); }
}
