/* ==========================================================================
   base.css — reset, document defaults, typography, global a11y.
   Depends on tokens.css. Declares no component classes.
   ========================================================================== */

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

  * { margin: 0; }

  html {
    -webkit-text-size-adjust: 100%;
    /* Anchor links and hash navigation clear the sticky header. */
    scroll-padding-top: calc(var(--header-h) + var(--space-4));
  }

  body {
    min-height: 100dvh;              /* dvh, so mobile chrome cannot clip it */
    line-height: var(--leading-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
  }

  img, svg, video, canvas, picture {
    display: block;
    max-width: 100%;
    /* Prevents the intrinsic-size jump before an image loads. */
    height: auto;
  }

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

  button { background: none; border: 0; }

  table { border-collapse: collapse; }

  /* Honour the OS-level reduced-transparency preference where the browser
     exposes it, by removing the blur (see .glass-panel in components.css). */
  dialog { padding: 0; border: 0; background: transparent; }
}

@layer base {
  html {
    color-scheme: light;
    scroll-behavior: smooth;
  }

  body {
    background-color: var(--bg-core);
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--step-0);
    /*
      `clip` rather than `hidden`.

      `overflow-x: hidden` creates a scroll container, which silently breaks
      position: sticky for every descendant — including the sticky sidebar and
      top bar. This must live in `@layer base` (which is declared after
      `reset`), and the <body> must NOT also carry Tailwind's
      `overflow-x-hidden` utility, or the utility wins and reintroduces the bug.
    */
    overflow-x: clip;
  }

  /* ── Atmospheric backdrop ────────────────────────────────────────────────
     RETIRED. Three fixed radial gradients — indigo from the upper left, a cool
     slate wash from the right, a violet floor glow — used to paint the room
     here. They are exactly the "made by a machine, lit from nowhere" cue this
     direction removes: light should come from the page, not from coloured light
     behind it. The warm paper fill and its grain now live on `body` in
     artist.css, which is loaded last. This rule is kept (rather than deleted)
     only so a stale cached bundle that still references `body::before` renders
     a flat page instead of a broken one. It can be deleted once no cache holds
     the old stylesheet.

  body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
      radial-gradient(70rem 40rem at 12% -8%,  color-mix(in oklab, var(--accent) 18%, transparent), transparent 62%),
      radial-gradient(55rem 34rem at 92% 8%,   color-mix(in oklab, var(--text) 5%, transparent),  transparent 60%),
      radial-gradient(60rem 40rem at 50% 108%, color-mix(in oklab, var(--accent-violet) 16%, transparent), transparent 65%),
      var(--bg-core);
  }
  */

  /* ── Type ────────────────────────────────────────────────────────────────
     The display face is for headings only. Body text stays DM Sans so long
     passages remain comfortable at small sizes. */
  h1, h2, h3, h4 {
    font-family: var(--font-display);
    /* Set type, not a bolded interface. Fraunces at 400 with its optical size
       dialled up reads as a monograph plate. */
    font-weight: 400;
    font-variation-settings: 'opsz' 144, 'SOFT' 60;
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-display);
    text-transform: none;
    /* Balance short headings so they break into even lines. */
    text-wrap: balance;
  }

  h1 { font-size: var(--step-4); font-style: italic; }
  h2 { font-size: var(--step-3); }
  h3 { font-size: var(--step-1); }

  p {
    max-width: var(--measure);
    /* `pretty` avoids orphans and short last lines; harmless where unsupported. */
    text-wrap: pretty;
  }

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

  strong, b { font-weight: 600; }

  code, kbd, pre { font-family: var(--font-mono); font-size: 0.9em; }

  /* Statistics should not jitter as digits change. */
  .tabular, .stat-value, [data-count-to] {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
  }

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

  /* ── Scrollbars ──────────────────────────────────────────────────────── */
  ::-webkit-scrollbar { width: 10px; height: 10px; }
  ::-webkit-scrollbar-track { background: var(--bg-core); }
  /* Square, like the rest of the page. A pill-shaped thumb is a tech cue. */
  ::-webkit-scrollbar-thumb {
    background: var(--line);
    border-radius: 0;
    border: 2px solid var(--bg-core);
  }
  ::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

  @supports (scrollbar-color: auto) {
    html { scrollbar-color: var(--line) var(--bg-core); scrollbar-width: thin; }
  }

  /* ── Focus ───────────────────────────────────────────────────────────────
     One global ring, keyboard-only. It deliberately does NOT set
     border-radius: doing so reshapes the element (a circle becomes a
     square) the moment it is focused. The ring follows whatever radius the
     element already has. */
  :focus-visible {
    outline: 2px solid var(--accent-ring);
    outline-offset: 3px;
  }

  /* Elements that clip their own overflow need the ring drawn inward, or it
     is cut off by the clip. */
  .art-card:focus-visible,
  .masonry-item:focus-visible,
  .input-drag:focus-visible {
    outline-offset: -2px;
  }

  /* ── Media defaults ──────────────────────────────────────────────────────
     Reserve space from an explicit ratio so images cannot shift layout while
     loading. A component may override --ar per instance. */
  img[loading='lazy'] {
    background-color: var(--bg-sunken);
  }

  /* ── Metadata voice ──────────────────────────────────────────────────────
     The caption card beside a work on a gallery wall: small, letterspaced,
     upper-case. Used for years, media, sizes, tags and every other piece of
     true-but-quiet information. */
  .meta {
    font-family: var(--font-body);
    font-size: var(--label-size);
    font-weight: 500;
    letter-spacing: var(--label-tracking);
    text-transform: uppercase;
    color: var(--text-muted);
  }

  /* One handwritten note, used sparingly — a signature on a canvas. */
  .hand {
    font-family: var(--font-hand);
    font-size: 1.35rem;
    color: var(--accent);
  }
}

@layer utilities {
  /* Visually hidden, still announced. Keyboard/screen-reader users can browse
     the same content a 3D or canvas scene shows visually. */
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* Reveal for keyboard users: focus the wrapper to show the skip link. */
  .sr-only-focusable:focus-visible {
    position: static;
    width: auto;
    height: auto;
    padding: var(--space-2) var(--space-4);
    margin: 0;
    overflow: visible;
    clip-path: none;
    white-space: normal;
  }

  .tabular { font-variant-numeric: tabular-nums; }

  /* Two measures: `--measure` for body copy, `--measure-prose` for README-like
     text that shares a row with other chrome. */
  .measure { max-width: var(--measure); }
  .prose { max-width: var(--measure-prose); }
}
