/* ── AppZip · design tokens (global invariants) ──────────────────────────────
   The bones every theme and fontset share: grid, spacing, type scale, radii,
   focus. No colours and no font families live here — those come from theme.css
   and fontset.css, so a single attribute on <html> reskins the whole site
   without touching a component. Load order matters: tokens → theme → fontset →
   site. Values follow the sviluppo-sito handoff (§3, §4.2). */

:root {
  /* Container & grid — 12 columns, 1280px cap (handoff §3). */
  --container-max: 1280px;
  --grid-columns: 12;
  --gutter: 16px;                 /* mobile default; bumped up at ≥sm below */
  --margin-side: 16px;            /* mobile default; grows with breakpoints */

  /* Spacing scale — 4/8 system (handoff §3). Inside components: 1–4;
     between components: 5–7; between sections: 8–10. */
  --space-0: 0;
  --space-1: 0.25rem;   /* 4px  */
  --space-2: 0.5rem;    /* 8px  */
  --space-3: 0.75rem;   /* 12px */
  --space-4: 1rem;      /* 16px */
  --space-5: 1.5rem;    /* 24px */
  --space-6: 2rem;      /* 32px */
  --space-7: 3rem;      /* 48px */
  --space-8: 4rem;      /* 64px */
  --space-9: 6rem;      /* 96px */
  --space-10: 8rem;     /* 128px */

  /* Type scale — base 16px, ratio 1.250 (handoff §4.2). Line-heights paired.
     Families are set per fontset; here we fix sizes, weights and rhythm. */
  --fs-h1: 3.052rem;  --lh-h1: 1.1;
  --fs-h2: 2.441rem;  --lh-h2: 1.15;
  --fs-h3: 1.953rem;  --lh-h3: 1.2;
  --fs-h4: 1.563rem;  --lh-h4: 1.25;
  --fs-h5: 1.25rem;   --lh-h5: 1.3;
  --fs-h6: 1rem;      --lh-h6: 1.4;
  --fs-body-l: 1.125rem;  --lh-body-l: 1.6;
  --fs-body: 1rem;        --lh-body: 1.6;
  --fs-small: 0.875rem;   --lh-small: 1.5;
  --fs-caption: 0.75rem;  --lh-caption: 1.4;

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-bold: 700;

  /* Ideal body measure — 60–75 characters (handoff §4.2). */
  --measure: 68ch;

  /* Radii. */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;

  /* Elevation — soft, theme-neutral (colour comes from theme shadow tint). */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.06), 0 2px 8px rgba(0, 0, 0, 0.06);
  --shadow-2: 0 4px 12px rgba(0, 0, 0, 0.10);

  /* Focus ring — 2px with offset, never colour alone (handoff §7). The colour
     itself is a theme token (--focus-ring), so it stays legible on any theme. */
  --focus-width: 2px;
  --focus-offset: 2px;

  /* Motion — one knob, killed by prefers-reduced-motion below. */
  --motion-fast: 120ms;
  --motion-base: 220ms;
  --easing: cubic-bezier(0.2, 0, 0, 1);
}

/* Breakpoints live in em so zoom and user font size are respected (handoff §3).
   sm 40em · md 48em · lg 64em · xl 80em. We only widen gutters/margins here;
   component layout is handled where the component lives. */
@media (min-width: 40em) {
  :root { --gutter: 24px; --margin-side: 24px; }
}
@media (min-width: 64em) {
  :root { --margin-side: 32px; }
}

/* Respect the user's motion preference everywhere, once and for all. */
@media (prefers-reduced-motion: reduce) {
  :root { --motion-fast: 0ms; --motion-base: 0ms; }
}

/* Shared primitives that read only the tokens above. Colours arrive via theme. */
*, *::before, *::after { box-sizing: border-box; }

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--margin-side);
}

/* A visible focus outline on anything keyboard-reachable. Colour is a theme
   token so it contrasts on both themes; the ring never relies on colour alone
   because it is an outline (shape), per WCAG 2.2 (handoff §7). */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* Screen-reader-only helper for accessible labels on icon-only controls. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
