/* ==========================================================================
   ViewPort — design tokens
   Transcribed from wisprflow-design.md (binding visual authority).

   Every deviation from that document is marked DEVIATION with its reason.
   Nothing here is changed for taste; the changes are correctness fixes
   (Czech rendering, WCAG AA, and three invalid values in the source doc).
   ========================================================================== */

/* --- Self-hosted faces -----------------------------------------------------
   Served locally rather than from the Google CDN: no visitor IP leaves for a
   US host (an EU/GDPR exposure for a Czech business), and the render-blocking
   third-party connection disappears. Both faces are variable, so one file per
   subset covers every weight the system uses.
   latin-ext is mandatory here — it carries ě š č ř ž ů ď ť ň.
--------------------------------------------------------------------------- */

@font-face {
  font-family: 'EB Garamond';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../assets/fonts/eb-garamond-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'EB Garamond';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../assets/fonts/eb-garamond-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('../assets/fonts/figtree-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('../assets/fonts/figtree-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- Colours — exactly as specified ----------------------------------- */
  --color-lavender-whisper: #f0d7ff;
  --color-forest-ink:       #034f46;
  --color-ember-glow:       #ffa946;
  --color-vast-ink:         #1a1a1a;
  --color-lumen-cream:      #ffffeb;
  --color-lumen-stone:      #e4e4d0;
  --color-fog:              #8a8a80;
  --color-charcoal:         #222222;
  --color-pure-white:       #ffffff;

  /* DEVIATION 1 — accessibility.
     --color-fog on cream measures 3.44:1. The spec assigns it to 14px
     captions and helper text, which fails WCAG AA (4.5:1 for normal text).
     It clears only the 3:1 large-text bar, so:
       --color-fog         stays, restricted to text >=48px (the two-tone
                           display headline), where it is legal and intended.
       --color-fog-muted   is the caption-size substitute. 4.59:1 on cream.
                           Same hue, darkened 15%. */
  --color-fog-muted: #75756d;

  /* DEVIATION 2 — accessibility.
     --color-ember-glow on cream measures 1.88:1, failing both the text floor
     and the 3:1 non-text floor for UI components. It is therefore permitted
     on dark chambers only (9.13:1 on --color-vast-ink), which is where the
     spec's own examples put it. Never on the cream canvas. */

  /* DEVIATION 3 — craft floor: secondary text on a coloured surface is
     tinted from that surface, never gray. Cream-derived muted for use inside
     dark chambers (8.21:1 on ink) instead of reaching for --color-fog. */
  --color-cream-muted: #b3b3a5;

  /* --- Font families ------------------------------------------------------
     FIX: the source doc's Quick Start gives EB Garamond a *sans-serif*
     fallback stack (ui-sans-serif, system-ui, …). That is a typo in the doc —
     if the webfont fails, a serif display face would silently become Arial.
     Corrected to a serif fallback chain. Also 'Eb Garamond' -> 'EB Garamond',
     which is the real family name; the doc's casing would not have matched. */
  --font-eb-garamond: 'EB Garamond', Georgia, 'Times New Roman', Times, serif;
  --font-figtree: 'Figtree', ui-sans-serif, system-ui, -apple-system,
                  BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  /* --- Type scale ---------------------------------------------------------
     The spec gives eight fixed pixel sizes and no breakpoints. A fixed 120px
     headline overflows a 375px phone, so each step is expressed as a clamp()
     that lands on the spec's value at desktop and degrades smoothly below it.
     Spec values are preserved as the upper bound of every step. */
  --text-caption:      0.875rem;                                   /* 14 */
  --text-body-sm:      1rem;                                       /* 16 */
  --text-body:         clamp(1.0625rem, 1rem + 0.30vw, 1.25rem);   /* 17 -> 20 */
  --text-subheading:   clamp(1.25rem, 1.13rem + 0.50vw, 1.5rem);   /* 20 -> 24 */
  --text-heading-sm:   clamp(1.5rem, 1.25rem + 1.10vw, 2rem);      /* 24 -> 32 */
  --text-heading:      clamp(1.875rem, 1.30rem + 2.50vw, 3rem);    /* 30 -> 48 */
  --text-heading-lg:   clamp(2.25rem, 1.35rem + 3.90vw, 4rem);     /* 36 -> 64 */
  --text-display:      clamp(2.75rem, 1.10rem + 7.20vw, 7.5rem);   /* 44 -> 120 */

  /* --- Line heights -------------------------------------------------------
     DEVIATION 4 — Czech rendering. The spec's --leading-display of 0.85 was
     measured on English. Czech stacks diacritics *above* capitals
     (Ř Í Ě Ů Á Ý Č Š Ž); at 0.85 those carons and acutes collide with the
     descenders of the line above. Display leading is opened to 0.95 and
     heading leading to 1.0. The spec's tight tracking is kept, so the
     "single horizontal gesture" the document is after still reads.

     DEVIATION 5 — readability. The spec applies 1.3 to every Figtree size.
     That is right for the UI text it describes (labels, nav, buttons, badges)
     but too tight for multi-line paragraphs at a 65-75ch measure. 1.3 is kept
     for UI; paragraph copy gets --leading-prose. */
  --leading-display:    0.95;   /* spec: 0.85 */
  --leading-heading-lg: 1.0;    /* spec: 0.95 */
  --leading-heading:    1.0;    /* spec: 0.95 */
  --leading-heading-sm: 1.2;
  --leading-ui:         1.3;    /* spec value, kept for labels/nav/buttons */
  --leading-prose:      1.55;

  /* --- Tracking -----------------------------------------------------------
     Spec gives pixel tracking at fixed sizes (-3.6px at 120px, -1.92px at
     64px, -0.96px at 32px). All three are -0.03em, so em units reproduce the
     spec exactly while surviving the fluid scale. Craft floor's -0.04em
     ceiling is respected. */
  --tracking-display: -0.03em;
  --tracking-heading: -0.02em;
  --tracking-ui:       0em;

  /* --- Spacing — 8px base, exactly as specified -------------------------- */
  --spacing-8: 8px;     --spacing-16: 16px;   --spacing-24: 24px;
  --spacing-32: 32px;   --spacing-40: 40px;   --spacing-48: 48px;
  --spacing-56: 56px;   --spacing-64: 64px;   --spacing-80: 80px;
  --spacing-96: 96px;   --spacing-104: 104px; --spacing-128: 128px;
  --spacing-168: 168px;

  /* --- Layout -------------------------------------------------------------
     FIX: the doc ships "--section-gap: 64-96px", "--element-gap: 8-16px" and
     "--radius-sections: 40-80px". Those are not valid CSS values — they are
     ranges written as prose. Split into real min/max tokens. */
  --page-max-width: 1200px;
  --page-gutter: clamp(16px, 4vw, 40px);
  --section-gap-min: 64px;
  --section-gap-max: 96px;
  --section-gap: clamp(var(--section-gap-min), 8vw, var(--section-gap-max));
  --card-padding: 32px;
  --element-gap-min: 8px;
  --element-gap-max: 16px;

  /* --- Radius — exactly as specified ------------------------------------- */
  --radius-badges: 9999px;
  --radius-inputs: 12px;
  --radius-buttons: 12px;
  --radius-square-badge: 8px;   /* the deliberate tight counterpoint */
  --radius-cards: 32px;
  --radius-section-min: 40px;
  --radius-section-max: 80px;
  /* Chambers shrink their radius on small screens or the corner eats the
     content it is supposed to frame. */
  --radius-chamber: clamp(var(--radius-section-min), 6vw, var(--radius-section-max));

  /* --- Surfaces ----------------------------------------------------------- */
  --surface-cream-canvas:   var(--color-lumen-cream);
  --surface-dark-chamber:   var(--color-vast-ink);
  --surface-lavender-accent: var(--color-lavender-whisper);
  --surface-forest-panel:   var(--color-forest-ink);

  /* --- Borders ------------------------------------------------------------
     The 2px ink border is described in the doc as "non-negotiable" and is the
     system's entire separation mechanism, since it is deliberately shadowless. */
  --border-ink: 2px solid var(--color-vast-ink);
  --border-cream: 2px solid var(--color-lumen-cream);
  --border-hairline: 1px solid var(--color-lumen-stone);

  /* --- Motion -------------------------------------------------------------
     One authored moment, exponential ease-out from an already-visible default. */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 140ms;
  --dur-base: 260ms;
  --dur-slow: 620ms;
}

/* Reduced motion: no entrance animation, no waveform, no transitions that
   move things. Content is visible by default, so nothing is lost. */
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 0ms; --dur-base: 0ms; --dur-slow: 0ms; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
