/* =============================================================================
 * Basis-Layer. Reset, Grundtypografie, Dichte, Fokus, Bewegung.
 *
 * Keine Komponentenklassen. Zeile, Feld und Blatt entstehen in M12.4; was hier
 * hineinwächst, wird dort zweimal gepflegt.
 *
 * Lädt VOR dem Inline-Stylesheet in views.tsx. Das ist die Reihenfolge, auf die
 * sich beide verlassen: base.css setzt Vorgaben, das Inline-Blatt überschreibt
 * sie bei gleicher Spezifität. Wer das dreht, dreht die Wirkung um.
 *
 * Farbliterale sind hier rot (Guard A). Alles kommt aus tokens.css.
 * ========================================================================== */

/* =============================================================================
 * Schriften — selbst gehostet, keine Anfrage nach außen zur Laufzeit.
 *
 * IBM Plex Sans liegt als VARIABLE Font vor (400–600 in einer Datei), IBM Plex
 * Mono nicht — den gibt es nur als feste Schnitte. Geprüft, nicht angenommen:
 * IBM liefert in keinem seiner npm-Pakete eine Variable-Fassung, und die
 * Google-Fonts-API weist `IBM+Plex+Mono:wght@400..600` mit 400 zurück.
 * Deshalb ist Sans eine Datei pro Subset und Mono drei.
 *
 * Subset auf latin und latin-ext. Umlaute (U+00E4 …) liegen in latin, die
 * deutschen Anführungszeichen („ ") in U+2000–206F, ebenfalls latin. Die
 * unicode-range-Angaben sind die von Google Fonts, unverändert übernommen:
 * sie gehören zur Datei, nicht zur Einbindung, und selbst gekürzt wären sie
 * bloß eine zweite Wahrheit über denselben Bytebestand.
 * ========================================================================== */

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/static/fonts/IBMPlexSans-var-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: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/static/fonts/IBMPlexSans-var-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-400-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-400-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-500-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-500-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-600-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-600-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;
}

/* =============================================================================
 * Reset — so klein wie möglich.
 *
 * Zwei Zeilen. Alles Weitere (Ränder von Überschriften, Listenpunkte,
 * Formularelemente) ist eine Designentscheidung und gehört in die Scheibe, die
 * sie trifft, nicht in einen Reset, der sie vorwegnimmt.
 * ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

/* =============================================================================
 * Grundtypografie und Dichte.
 * ========================================================================== */

:root {
  /* Eine Zahl, an der später jede Zeilenhöhe und jede Trefferfläche hängt.
     Am Zeigegerät, nicht am Viewport: ein Tablet im Querformat ist breit und
     wird trotzdem mit dem Finger bedient. */
  --density: 1;
}

@media (pointer: coarse) {
  :root {
    --density: 1.35;
  }
}

:root {
  /* Die Zeilenhöhe hängt an --density und steht deshalb hier und nicht in
     tokens.css: dort zeigte L1 auf einen Nicht-Token (M12.4 A). 40 statt der 38
     des Entwurfs — die Skala hat 40, und ein Wert daneben ist einer, den niemand
     nachrechnen kann. */
  --row-h: calc(var(--space-40) * var(--density));
}

body {
  background: var(--bg-page);
  color: var(--fg-default);
  font-family: var(--font-body);
  font-size: var(--text-15);
  line-height: 1.5;
  /* Ziffern stehen untereinander. In einer App, die fast nur Daten, Uhrzeiten
     und Zähler zeigt, ist proportionaler Ziffernsatz ein Zittern in jeder
     Spalte. */
  font-variant-numeric: tabular-nums;
}

/* =============================================================================
 * Links.
 *
 * Kein Stylesheet hatte je eine Linkfarbe, also stand das Standardblau des
 * Browsers als einzige Nicht-Token-Farbe in der App (Befund aus M12.1). Die
 * Unterstreichung bleibt: Farbe allein ist kein Signal.
 *
 * Der nackte Typselektor genügt gegen die UA-Regel `a:-webkit-any-link`, weil
 * der Ursprung vor der Spezifität kommt — das gilt auch für :visited, das sonst
 * violett bliebe. Im Browser nachgemessen, nicht aus dem Kopf.
 * ========================================================================== */

a {
  color: var(--brand-accent);
}

/* =============================================================================
 * Hell/Dunkel — manuelle Umschaltung.
 *
 * Die Klassen existieren, der Umschalter nicht — er braucht Cookie und Route
 * und steht im BUILD-PLAN als offener Punkt (M12, nach M12.2). Mehr als das hier
 * braucht er nicht: light-dark() folgt `color-scheme`, also genügt es, die
 * Klasse auf :root zu setzen — kein JavaScript im Stylesheet, kein zweiter
 * Tokenblock, kein Flash beim Laden, solange die Klasse serverseitig gerendert
 * wird.
 * ========================================================================== */

:root.theme-light {
  color-scheme: light;
}

:root.theme-dark {
  color-scheme: dark;
}

/* =============================================================================
 * Fokus.
 *
 * :focus-visible, überall, in der Markenfarbe. Nirgends `outline: none` ohne
 * Ersatz — und weil das eine Regel ist, die man beim nächsten Mal versehentlich
 * bricht: der Ring hängt an --focus-ring, damit ihn niemand "nur hier kurz"
 * wegnimmt, sondern höchstens umfärbt.
 *
 * 2px Versatz, damit der Ring nicht auf der Kante des Elements klebt und auf
 * dunklem Grund noch als Ring lesbar ist.
 * ========================================================================== */

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* =============================================================================
 * Bewegung.
 *
 * Wer Bewegung abbestellt hat, bekommt keine. Nicht "weniger" — keine.
 * Die 0.01ms statt 0 sind Absicht: eine Dauer von exakt 0 verschluckt in
 * manchen Browsern das transitionend-Ereignis, an dem Code hängen kann.
 * ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
