/* Manimal Group design tokens
 * The single source of every token. tokens.json is generated from this file by
 * scripts/tokens.mjs (npm run tokens); never edit tokens.json by hand.
 * Status: colour and typeface LOCKED 2026-09-14. Palette: Signal.
 * Structural reference: apc-pallets.nl. See EXTRACTION.md.
 */

/* ---------------------------------------------------------------------------
 * LAYER 0, THE FACE
 * Aspekta Variable 2.100, Ivo Dolenc, OFL 1.1. Self-hosted.
 * Provenance, metrics and known gaps: assets/fonts/README.md
 * ------------------------------------------------------------------------ */

@font-face {
  font-family: 'Aspekta Variable';
  src: url('assets/fonts/AspektaVF.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------------------------------------------------------------------------
 * LAYER 1, PRIMITIVES
 * Raw values. Nothing outside layer 2 may read these directly.
 * ------------------------------------------------------------------------ */

:root {
  /* Space. Coarse by design: eight steps, no 4px ladder. */
  --mn-space-0-5: 0.5rem;
  --mn-space-1:   1rem;
  --mn-space-1-5: 1.5rem;
  --mn-space-2:   2rem;
  --mn-space-3:   3rem;
  --mn-space-5:   5rem;
  --mn-space-7-5: 7rem;
  --mn-space-10:  10rem;

  /* Section spacing is its own, larger scale. */
  --mn-section-none:     0rem;
  --mn-section-small:    1.5rem;
  --mn-section-main:     4rem;
  --mn-section-large:    7rem;
  --mn-section-page-top: 6.5rem;

  /* Type scale. Rides the fluid root, so it never changes at a breakpoint. */
  --mn-size-display:    6rem;
  --mn-size-h1:         3.75rem;
  --mn-size-h2:         3rem;
  --mn-size-h3:         2rem;
  --mn-size-h4:         1.375rem;
  --mn-size-h5:         1.25rem;
  --mn-size-h6:         1.125rem;
  --mn-size-text-large: 1.25rem;
  --mn-size-text-main:  1rem;
  --mn-size-text-small: 0.875rem;

  /* Weights. A variable face is required: 350 and 450 are not static weights. */
  --mn-weight-light:   350;
  --mn-weight-regular: 400;
  --mn-weight-medium:  450;
  --mn-weight-bold:    550;

  --mn-lh-1:    1;
  --mn-lh-1-1:  1.1;
  --mn-lh-1-15: 1.15;
  --mn-lh-1-3:  1.3;
  --mn-lh-1-35: 1.35;

  --mn-ls-normal: 0em;
  --mn-ls-tight:  -0.03em;

  /* The face. The fallback is not decoration: Aspekta has no rupee sign and no
   * measurement glyphs, so the next face in the stack is what actually renders
   * ₹, ±, µ and ∆. Pick it deliberately. See assets/fonts/README.md. */
  --mn-font-primary: 'Aspekta Variable', 'Helvetica Neue', Arial, sans-serif;

  /* Cap-height trim. The difference between a laid-out page and a typeset one. */
  --mn-trim-top:    0.33em;
  --mn-trim-bottom: 0.38em;

  --mn-radius-none:  0rem;
  --mn-radius-main:  0.5rem;
  --mn-radius-round: 100vw;

  --mn-border-width: 1px;

  /* Layout. 1440 is the reference width, where 1rem is exactly 16px. */
  --mn-columns: 12;
  --mn-gutter:  2rem;
  --mn-margin:  clamp(1rem, 0.5rem + 1.5vw, 3rem);
  --mn-max-width-main: 100%;
  --mn-column-width: calc(
    (min(var(--mn-max-width-main), 100% - var(--mn-margin) * 2)
     - (var(--mn-gutter) * (var(--mn-columns) - 1))) / var(--mn-columns)
  );
  --mn-max-width-medium: calc(var(--mn-column-width) * 8 + var(--mn-gutter) * 7);
  --mn-max-width-small:  calc(var(--mn-column-width) * 6 + var(--mn-gutter) * 5);
}

/* The fluid root. Matches APC exactly at 1440 and 1920, but floors at 1rem
 * instead of shrinking to ~12.3px at 1000px wide, which is a builder artifact
 * rather than a design decision. */
html { font-size: clamp(1rem, 0.25rem + 0.8333vw, 1.25rem); }

/* ---------------------------------------------------------------------------
 * LAYER 1b, THE PALETTE
 * Signal. LOCKED by Sujay, 2026-09-14.
 * A tonal ramp, not a flat set: each accent carries a `-deep` step, because a
 * mid-tone accent that reads on a dark band fails as text on a light one. The
 * semantic layer below switches between them per band.
 * Validated: zero WCAG AA failures across all four bands.
 * ------------------------------------------------------------------------ */

:root {
  --mn-ground:      #042A22;   /* darkest band, the resting state        */
  --mn-ground-2:    #0C473B;   /* second dark band, surface on ground    */
  --mn-surface:     #14574A;   /* raised card on a dark band             */

  --mn-accent:      #9FE870;   /* headings and fills, dark bands         */
  --mn-accent-deep: #2F6B24;   /* the same role, light bands             */

  --mn-secondary:      #4FA45C;  /* figures and measurement, dark bands  */
  --mn-secondary-deep: #2A6437;  /* the same, light bands                */

  --mn-pale:  #E7F3DF;         /* light band                             */
  --mn-paper: #FFFFFF;         /* lightest band, body text on dark       */
  --mn-ink:   #04231C;         /* body text on light bands               */

  /* Derived, never hand-picked. */
  --mn-ground-muted: color-mix(in srgb, var(--mn-ground) 35%, transparent);
  --mn-paper-muted:  color-mix(in srgb, var(--mn-paper) 35%, transparent);
}

/* ---------------------------------------------------------------------------
 * LAYER 2, SEMANTIC BAND THEMES
 * A page is built by stacking sections, each declaring a theme.
 * The ramp switch lives here: dark bands take the bright accent, light bands
 * take the deep one. No component ever has to know which band it is in.
 * ------------------------------------------------------------------------ */

[data-theme] {
  background-color: var(--mn-theme-background);
  color: var(--mn-theme-text);
}

[data-theme="ground"] {
  --mn-theme-background:     var(--mn-ground);
  --mn-theme-background-2:   var(--mn-ground-2);
  --mn-theme-surface:        var(--mn-ground-2);
  --mn-theme-text:           var(--mn-paper);
  --mn-theme-border:         var(--mn-ground-2);
  --mn-theme-heading-accent: var(--mn-accent);
  --mn-theme-secondary:      var(--mn-secondary);
}

[data-theme="ground-alt"] {
  --mn-theme-background:     var(--mn-ground-2);
  --mn-theme-background-2:   var(--mn-ground);
  --mn-theme-surface:        var(--mn-surface);
  --mn-theme-text:           var(--mn-paper);
  --mn-theme-border:         var(--mn-surface);
  --mn-theme-heading-accent: var(--mn-accent);
  --mn-theme-secondary:      var(--mn-secondary);
}

[data-theme="pale"] {
  --mn-theme-background:     var(--mn-pale);
  --mn-theme-background-2:   var(--mn-paper);
  --mn-theme-surface:        var(--mn-paper);
  --mn-theme-text:           var(--mn-ink);
  --mn-theme-border:         var(--mn-ground-muted);
  --mn-theme-heading-accent: var(--mn-accent-deep);
  --mn-theme-secondary:      var(--mn-secondary-deep);
}

[data-theme="paper"] {
  --mn-theme-background:     var(--mn-paper);
  --mn-theme-background-2:   var(--mn-pale);
  --mn-theme-surface:        var(--mn-pale);
  --mn-theme-text:           var(--mn-ink);
  --mn-theme-border:         var(--mn-ground-muted);
  --mn-theme-heading-accent: var(--mn-accent-deep);
  --mn-theme-secondary:      var(--mn-secondary-deep);
}

::selection {
  background-color: color-mix(in srgb, var(--mn-ground), white 40%);
  color: var(--mn-paper);
}

/* ---------------------------------------------------------------------------
 * LAYER 3, COMPONENTS
 * Components read layer 2 only. They never see a hex.
 * ------------------------------------------------------------------------ */

:root {
  --mn-button-size-medium: 3rem;
  --mn-button-size-large:  5rem;
  --mn-focus-width:        0.125rem;
  --mn-focus-offset-outer: 0.1875rem;
  --mn-focus-offset-inner: calc(var(--mn-focus-width) * -1);
  --mn-nav-height:         4rem;
  --mn-nav-banner-height:  2.4rem;
  --mn-nav-radius:         var(--mn-radius-none);
}

.mn-button {
  --mn-button-background: var(--mn-theme-heading-accent);
  --mn-button-text:       var(--mn-theme-background);
  --mn-button-border:     var(--mn-button-background);
  display: inline-flex;
  align-items: center;
  height: var(--mn-button-size-medium);
  padding: 0 var(--mn-space-1-5);
  border: var(--mn-border-width) solid var(--mn-button-border);
  border-radius: var(--mn-radius-main);
  background-color: var(--mn-button-background);
  color: var(--mn-button-text);
  font: inherit;
  font-weight: var(--mn-weight-medium);
  font-size: var(--mn-size-text-small);
  text-decoration: none;
  cursor: pointer;
}

.mn-button:hover {
  background-color: color-mix(in srgb, var(--mn-button-background), white 10%);
}

.mn-button--secondary {
  --mn-button-background: transparent;
  --mn-button-text:       var(--mn-theme-text);
  --mn-button-border:     var(--mn-theme-text);
}

.mn-button--secondary:hover {
  background-color: transparent;
}

:where(a, button, [tabindex]):focus-visible {
  outline: var(--mn-focus-width) solid var(--mn-theme-heading-accent);
  outline-offset: var(--mn-focus-offset-outer);
}
