/* CLIXHOUSE design system — modern typography primitives
   ─────────────────────────────────────────────────────────────────
   Variable-font axis utilities and OpenType feature toggles. The
   2020s' typographic toolkit — variable fonts let one file express
   the whole Bold/Light/Italic/Condensed matrix; OpenType features
   unlock small-caps, lining numerals, contextual alternates, and
   the subtleties that distinguish careful type from default type.

   Imported via:  @import url("/static/design/typography.css") layer(base);

   Sites should declare the variable-font axes their fonts support
   via @font-face, then reach for these utility classes.

   Axes mapped here (most common):
     wght    100..900     weight
     wdth     50..200     width (condensed..extended)
     opsz      6..144     optical size (display vs caption)
     slnt    -15..0       slant (oblique italic alternative)
     ital      0|1        italic toggle (for fonts with both)
     GRAD   -200..150     grade (Roboto Flex / display tuning)
     ROND      0..100     roundness (Recursive)

   Refs:
     Mandy Michael    — variable fonts pioneer
     Andy Bell        — Piccalilli typography lessons
     Robin Rendle     — typography essays
     Microsoft / VFs  — https://variablefonts.io/
*/

@layer base {

  /* ── BASE — sensible defaults across the document ──────────────── */
  /* Apply on the body so all type inherits these unless overridden.
     OpenType features are subtle but consistent — kerning on,
     contextual alternates on, common ligatures on, tabular numerals
     OFF (use class .nums-tabular for data tables). */
  body {
    font-kerning: normal;
    font-feature-settings:
      "kern" 1,            /* kerning pairs */
      "liga" 1,            /* common ligatures */
      "clig" 1,            /* contextual ligatures */
      "calt" 1;            /* contextual alternates */
    font-variant-ligatures: common-ligatures contextual;
    font-optical-sizing: auto;          /* let the font choose opsz from size */
    /* Opinionated subpixel-AA override — opt OUT via tokens: set
       --font-smooth: auto (and --font-smooth-moz: auto on Firefox/macOS). */
    -webkit-font-smoothing: var(--font-smooth, antialiased);
    -moz-osx-font-smoothing: var(--font-smooth-moz, grayscale);
  }

  /* Headings — opt into discretionary ligatures (swashes, fancy ff).
     If the font has them; otherwise the rule is harmless. */
  :where(h1, h2, h3, h4, h5, h6) {
    font-feature-settings:
      "kern" 1, "liga" 1, "clig" 1, "calt" 1,
      "dlig" 1,            /* discretionary ligatures */
      "ss01" 1;            /* stylistic set 1 (font-dependent) */
  }

  /* ── NUMERIC VARIANTS — utility classes ────────────────────────── */
  /* Use .nums-tabular on data tables / numeric columns; .nums-lining
      for headlines; .nums-oldstyle for body prose (looks like text);
      .nums-slashed-zero where a slashed zero matters (currency, IDs). */
  .nums-tabular {
    font-variant-numeric: tabular-nums;
  }
  .nums-proportional {
    font-variant-numeric: proportional-nums;
  }
  .nums-lining {
    font-variant-numeric: lining-nums;
  }
  .nums-oldstyle {
    font-variant-numeric: oldstyle-nums;
  }
  .nums-slashed-zero {
    font-variant-numeric: slashed-zero;
  }
  /* Combined: tabular + slashed-zero — financial / data display. */
  .nums-data {
    font-variant-numeric: tabular-nums slashed-zero lining-nums;
  }

  /* ── SMALL-CAPS / CAPS variants ────────────────────────────────── */
  /* Use real OpenType small-caps when the font has them. Falls back
      to synthesized when not — sites set explicit `text-transform`
      to opt out of synthesis. */
  .smallcaps {
    font-variant-caps: small-caps;
    letter-spacing: 0.04em;
  }
  .all-smallcaps {
    font-variant-caps: all-small-caps;
    letter-spacing: 0.04em;
  }

  /* ── STYLISTIC SETS — font-specific alternates ─────────────────── */
  /* Many variable fonts ship stylistic sets (ss01..ss20). Useful for
      swashes, alternate a/g, single-story g, etc. Use sparingly.

      font-feature-settings is NON-additive — it REPLACES the whole
      property, so a stylistic-set utility must re-include the base
      features (kern/liga/clig/calt) or it silently wipes them off the
      element. (font-variant-alternates: styleset() would be additive but
      requires per-font @font-feature-values declarations that a
      font-agnostic framework utility cannot provide.) */
  .ss01 { font-feature-settings: "kern" 1, "liga" 1, "clig" 1, "calt" 1, "ss01" 1; }
  .ss02 { font-feature-settings: "kern" 1, "liga" 1, "clig" 1, "calt" 1, "ss02" 1; }
  .ss03 { font-feature-settings: "kern" 1, "liga" 1, "clig" 1, "calt" 1, "ss03" 1; }

  /* ── VARIABLE-FONT AXIS PRESETS ────────────────────────────────── */
  /* Common weight + width + optical-size combos as classes. Site
      should `@font-face` declare the axis ranges; these utilities
      assume Inter/Recursive/Bricolage Grotesque-class fonts that
      expose wght, wdth, opsz. Override with --vf-* custom properties
      on the element when you need finer control. */
  /* Base .vf sets weight + width only and leaves OPTICAL SIZE to
     `font-optical-sizing: auto` (inherited from body) — pinning opsz here
     would override auto on every .vf element, forcing one optical grade
     regardless of font-size. Presets that want a deliberate grade pin it
     explicitly below. */
  .vf {
    font-variation-settings:
      "wght" var(--vf-wght, 400),
      "wdth" var(--vf-wdth, 100);
    font-optical-sizing: auto;
  }
  .vf-display {
    --vf-wght: 700;
    --vf-wdth: 95;
    --vf-opsz: 96;
  }
  .vf-headline {
    --vf-wght: 650;
    --vf-wdth: 100;
    --vf-opsz: 48;
  }
  .vf-body {
    --vf-wght: 420;
    --vf-wdth: 100;
    --vf-opsz: 14;
  }
  .vf-caption {
    --vf-wght: 500;
    --vf-wdth: 100;
    --vf-opsz: 10;
  }
  .vf-condensed {
    --vf-wdth: 80;
  }
  .vf-extended {
    --vf-wdth: 120;
  }
  /* Presets with an explicit optical size pin opsz deliberately (display
     and caption type want a fixed grade); they opt out of auto only here,
     never on the plain .vf base. */
  .vf-display, .vf-headline, .vf-caption {
    font-optical-sizing: none;
    font-variation-settings:
      "wght" var(--vf-wght, 400),
      "wdth" var(--vf-wdth, 100),
      "opsz" var(--vf-opsz, 14);
  }

  /* ── HYPHENATION + WORD-BREAK ──────────────────────────────────── */
  /* Auto-hyphenation requires the font + browser language support.
      Apply to prose; long technical terms benefit from break-word. */
  .hyphens-auto {
    hyphens: auto;
    -webkit-hyphens: auto;
  }
  .hyphens-none {
    hyphens: none;
  }

  /* ── TEXT RENDERING modes ──────────────────────────────────────── */
  /* `optimizeLegibility` enables kerning + ligatures by default but
      can be slow on huge documents. `geometricPrecision` is best for
      display type at large sizes (no font metric hinting). */
  .text-legible {
    text-rendering: optimizeLegibility;
  }
  .text-geometric {
    text-rendering: geometricPrecision;
  }
  .text-speed {
    text-rendering: optimizeSpeed;
  }

  /* ── INITIAL LETTER / DROP-CAP ─────────────────────────────────── */
  /* Native CSS drop-cap. `initial-letter: 3 2` = the first letter
      drops 3 lines and sinks 2 lines down. Per Robin Rendle's
      typography essays. Support: Safari 9+ and Chrome 110+ (the -webkit-
      prefix is still required on both); Firefox unimplemented, so NOT
      Baseline. Purely decorative — falls back to a regular first letter
      where unsupported. */
  .dropcap::first-letter {
    initial-letter: 3 2;
    -webkit-initial-letter: 3 2;
    margin-inline-end: 0.5rem;
    color: var(--accent, currentColor);
    font-weight: 700;
  }

  /* ── LEADING-TRIM — optical cap/baseline alignment ─────────────── */
  /* text-box-trim removes the half-leading above the cap height and
      below the alphabetic baseline, so a heading aligns optically to its
      glyphs (kills the "too much space above the heading" gap). Chrome
      133+ / Safari 18.2+; Firefox not yet — @supports-gated, degrades to
      normal leading. Apply .trim-both in tight vertical rhythm;
      .trim-start trims only the top half-leading. */
  @supports (text-box-trim: trim-both) {
    .trim-both {
      text-box-trim: trim-both;
      text-box-edge: cap alphabetic;
    }
    .trim-start {
      text-box-trim: trim-start;
      text-box-edge: cap alphabetic;
    }
  }

  /* ── PROSE — reset variant features for body copy ──────────────── */
  /* Long-form reading: oldstyle numerals (less shouty), text-wrap
      pretty (avoid orphans), hyphenation on. */
  :where(.prose) {
    font-variant-numeric: oldstyle-nums proportional-nums;
    text-wrap: pretty;
    hyphens: auto;
  }
}
