:root {
  --atelieria-space-4: 4px;
  --atelieria-space-8: 8px;
  --atelieria-space-12: 12px;
  --atelieria-space-16: 16px;
  --atelieria-space-20: 20px;
  --atelieria-space-24: 24px;
  --atelieria-space-32: 32px;
  --atelieria-space-40: 40px;
  --atelieria-space-48: 48px;
  --atelieria-space-64: 64px;
  /* Shared page grid, used by every learner surface: home, catalog, course
     overview, lesson player and profile, and by the top nav so its logo lands
     on the same line as the page's first word.

     The content measure is the number a reader sees; the gutter is the space
     between it and the viewport edge, and the max is what a box needs to be
     to hold both, since box-sizing is border-box everywhere. Write the two a
     designer would name, derive the third. */
  --atelieria-shell-content: 1200px;
  --atelieria-shell-gutter: var(--atelieria-space-24);
  --atelieria-shell-max: calc(var(--atelieria-shell-content) + 2 * var(--atelieria-shell-gutter));
  /* What the rail and the space beside it reach at the shell's full width.
     .atelieria-grid scales them down on a narrower window rather than taking
     the difference out of the article. */
  --atelieria-shell-gap: 40px;
  --atelieria-shell-rail: 360px;
  /* The measure long-form prose is set in. The page grid above can be wider
     than this; a paragraph should not be. */
  --atelieria-reading-max: 720px;
  /* Sticky rails clear the nav: 10px + 32px control + 10px + 1px border. */
  --atelieria-nav-height: 53px;
  /* Learner type stacks: one definition per role, shared by every surface.
     Admin keeps its own Inter stack and does not read these. */
  --atelieria-font-sans: "Instrument Sans Variable", "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  --atelieria-font-mono: "Geist Mono Variable", "Geist Mono", ui-monospace, monospace;
  /* Learner surface type weights: one value per role, shared by every surface. */
  --atelieria-weight-heading: 650;
  --atelieria-weight-emphasis: 600;
  --atelieria-weight-label: 550;
  /* Shared interaction transition for learner surfaces. */
  --atelieria-surface-transition: background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease, color 120ms ease, opacity 120ms ease;
  --atelieria-text-caption: 12px;
  --atelieria-text-ui: 14px;
  --atelieria-text-body: 16px;
  --atelieria-text-lead: 18px;
  --atelieria-text-heading-3: 20px;
  --atelieria-text-heading-2: 24px;
  --atelieria-text-display-mobile: 28px;
  --atelieria-text-display: 30px;

  /* ------------------------------------------------------------------ */
  /* Colour. Every colour the learner surfaces use is named here and only
     here, as a complete value -- so a token is a colour anywhere it is
     written, inherits from :root into every surface, dialog and fixed
     overlay, and never needs a wrapper to become one.

     The learner palette used to live on a grouped selector as bare HSL
     triplets, because `--background`, `--foreground` and `--muted` were
     already taken at :root by the marketing pages. A triplet is not a
     colour, so it could not be hoisted, so every new fixed overlay had to
     be added to that selector by hand -- and three of them shipped
     invisible before this moved. Prefixed and complete, that whole class
     of bug is gone.

     Alpha comes from color-mix() rather than a fourth slot in the token. */
  --atelieria-color-bg: hsl(0 0% 100%);
  --atelieria-color-fg: hsl(222.2 84% 4.9%);
  --atelieria-color-muted: hsl(210 40% 96.1%);
  --atelieria-color-muted-fg: hsl(215.4 16.3% 46.9%);
  --atelieria-color-border: hsl(214.3 31.8% 91.4%);
  /* Long-form reading ink: softer than the UI foreground, because a whole
     paragraph set in it would be heavier than the interface around it. */
  --atelieria-color-prose: hsl(222 24% 18%);
  --atelieria-color-primary: #334155;
  --atelieria-color-primary-fg: hsl(210 40% 98%);
  /* Emerald and sky, from the design. The plain token is the fill -- bars,
     dots, ticks, tinted badge grounds. The -text pair is the same hue taken
     down far enough to carry small type on white. */
  --atelieria-color-success: hsl(160 84% 39%);
  --atelieria-color-success-text: hsl(160 84% 27%);
  --atelieria-color-info: hsl(199 89% 60%);
  --atelieria-color-info-text: hsl(199 89% 36%);
  /* Rose, from the design's danger colour, with the same darkened pair so it
     can carry a button label on white. */
  --atelieria-color-danger: hsl(351 95% 71%);
  --atelieria-color-danger-text: hsl(351 72% 42%);
  /* A second red, older than the pair above: it carries form and request
     errors. Reconciling the two is a decision for the palette pass. */
  --atelieria-color-critical: #b42318;
  --atelieria-color-focus: #245ea8;
  /* The sweep that crosses a loading skeleton. */
  --atelieria-color-shimmer: rgb(255 255 255 / 65%);
  --atelieria-radius: .7rem;

  /* The shell's own set -- nav, bottom bar, guest chrome, drawer. Its greys
     were chosen separately from the learner palette above and are not the
     same values; folding the two into one ramp is a colour decision, not a
     move, so they sit here side by side until that decision is made. */
  --student-bg: #f8f8f8;
  --student-surface: #fff;
  --student-surface-muted: #f3f3f3;
  --student-hover: #ededed;
  --student-active: #e9e9e9;
  --student-text: #171717;
  --student-subtle: #525252;
  --student-muted: #666;
  --student-border: #e2e2e2;
  --student-border-strong: #d3d3d3;
  --student-accent: #0f7b5b;
}
