/* == brand:start pixelpoint-brand v0.2.7 == */
/* ERZEUGT von scripts/build-brand.mjs aus pixelpoint-brand v0.2.7 (tokens.css, fonts.css, base.css). Nicht von Hand
   ändern, sondern neu erzeugen. Eigene Stile stehen unten ab „Statusseite“.
   LIZENZ: Draft B ist lizenzpflichtig und darf nur von pixelpoint-Domains ausgeliefert werden (E44, FONTS.md der Brand).
   status.pixelmap.at gehört dazu. IBM Plex Mono: SIL OFL 1.1, Lizenztext in fonts/brand/IBMPlexMono-OFL.txt. */

/* pixelpoint Design-Tokens — SSOT.
   Gleichzeitig Tailwinds @theme-Block: erzeugt Utilities UND :root-Variablen.
   Quelle: pixelpoint Brandmanual v1.0 + Entwurf Runden 1-5 (S17).
   Die Menge ist ABGESCHLOSSEN. Wer eine Zwischenstufe braucht, muss einen
   arbitrary value schreiben — und scripts/checks/tokens.mjs findet ihn. */
:root {
  /* ---- Farbe: Flaechen ---- */
  /* Genau DREI Flaechen pro Seite. Der zweite Grauton (#F7F7F7) ist in
     Designrunde 3 entfallen, #F2F2F2 wurde nie verwendet. Nicht zurueckholen. */
  --color-surface: #ffffff;    /* pixel.white — Grundflaeche, ~70 % */
  --color-surface-2: #fafafa;  /* der EINE Grauton fuer ruhige Sektionen */
  --color-invert: #221c34;     /* pixel.night — max. eine Vollflaeche pro Seite */

  /* ---- Farbe: Text, Linien, Akzent ---- */
  --color-accent: #e5054e;     /* pixel.red — Akzent, ~10 % Flaeche */
  --color-ink: #221c34;        /* Fliesstext. Gleicher Wert wie --color-invert,
                                  aber eigenes Token: im Dark Mode laufen sie
                                  auseinander (#F2F0F6 vs. #100D18). */
  --color-ink-3: #666666;      /* Sekundaertext */
  --color-ink-invert: #d9d9d9; /* Text auf Nachtblau */
  --color-line: #d9d9d9;       /* Trennlinien auf hellem Grund */
  --color-line-invert: #666666;/* Trennlinien auf Nachtblau */

  /* Der betonte 1-px-Rahmen (Design-Handoff 02): Fensterrahmen des Hero,
     Formular, Kategoriemarke API, Platzhalter-Marke. Er ist NICHT --color-line:
     eine Trennlinie ordnet, dieser Rahmen fasst etwas ein und traegt darum
     denselben Wert wie die Schrift. Im Dark Mode loest er sich vom Text
     (#6E6580), sonst wuerde er die Flaeche zuschneiden. */
  --color-frame: #221c34;

  /* Feldrahmen: gemessene Zusage, keine Geschmacksfrage.
     5,5:1 hell / 6,25:1 dunkel. Die frueheren 1px #D9D9D9 lagen bei 1,4:1
     und fielen fuer Bedienelemente durch (WCAG 1.4.11). */
  --color-field-line: #666666;

  /* Trennzeichen (· und / zwischen Links).
     ACHTUNG: im Dark Mode bewusst schwach (1,88:1), weil die Zeichen
     aria-hidden="true" tragen und Dekoration sind.
     WER --color-sep FUER TEXT VERWENDET, BRICHT DIE WCAG-ZUSAGE. */
  --color-sep: #d9d9d9;

  /* Funktionsfarben — nie Markenrot verwenden (Manual: Fix) */
  --color-error-fg: #d8000c;
  --color-error-bg: #ffbaba;
  --color-info-fg: #2d748f;
  --color-info-bg: #dfeff5;
  --color-warn-fg: #887830;
  --color-warn-bg: #f3efdd;
  --color-ok-fg: #4f7a28;
  --color-ok-bg: #eaf3dd;

  /* ---- Schrift ---- */
  --font-sans: 'Draft B', 'Open Sans', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;

  /* Gewichte: die Manual-Schnitte Light/SemiBold/ExtraBold (Task 1b).
     Light traegt usWeightClass 350 statt Manual-300 — die Tokens nennen,
     was die Datei traegt. Siehe FONTS.md. */
  --font-weight-body: 350;
  --font-weight-heading: 600;
  --font-weight-display: 800;

  /* Groessenleiter: sechs Stufen, Desktop-Werte. Der Entwurf hat sie
     entschieden; pro Screen sind 3-5 davon im Einsatz. Mobile Werte
     ueberschreibt base.css am Breakpoint — keine Zwischengroessen,
     keine clamp()-Interpolation, weil der Entwurf diskrete Werte hat.

     IN rem STATT px SEIT 1ix.24. In Pixeln folgte kein einziger Textwert der
     Schriftgroesseneinstellung des Browsers: von 70 gemessenen Textelementen
     skalierte keines, waehrend die rem-basierten ABSTAENDE mitwuchsen — bei
     html{font-size:32px} wuchs die Seite von 7058 auf 9602 px, und der
     Weissraum um einen Text, der gleich klein blieb. Ganzseitenzoom wirkte,
     die Schriftgroesse nicht (WCAG 1.4.4, E17).

     DIE BEZUGSGROESSE IST 19px UND NICHT 16px: base.css setzt
     html { font-size: 118.75% }, genau damit rem hier traegt. Ein rem ist
     also 19px, --text-body wird dadurch glatt 1rem und die Leiter rechnet
     sich sauber daran. Wer gegen 16 umrechnet, verschiebt die ganze Seite um
     ein Fuenftel.

     Vier Nachkommastellen, weil nur 76 und 19 glatt aufgehen. Zurueckgerechnet
     liegt jede Stufe unter einem Tausendstel Pixel neben ihrem Sollwert:
     4rem=76,000  2,4211rem=46,001  1,2632rem=24,001
     1,1053rem=21,001  1rem=19,000  0,6316rem=12,000 */
  --text-display: 4rem; /* 76px */
  --text-h1: 2.4211rem; /* 46px */
  --text-h2: 1.2632rem; /* 24px */
  --text-lead: 1.1053rem; /* 21px */
  --text-body: 1rem; /* 19px */
  --text-small: 0.6316rem; /* 12px */

  /* Laufweiten der Ueberschriftenstufen (Handoff 02, Spalte "Laufweite").
     Sie haengen an der GROESSENSTUFE, nicht am Element: dieselbe H2 traegt im
     Sektionstitel 46px (-0,025em) und im Lauftext 24px (-0,01em). Deshalb
     stehen sie als Tailwind-Beiwerte der Stufe und nicht als Regel auf h1/h2 —
     jede text-*-Utility bringt ihre Laufweite mit, keine Komponente setzt sie
     einzeln. Mobil verschiebt base.css die Leiter und diese Werte mit ihr. */
  --text-display--letter-spacing: -0.03em;  /* 76px H1 Desktop */
  --text-h1--letter-spacing: -0.025em;      /* 46px Sektionstitel Desktop */
  --text-h2--letter-spacing: -0.01em;       /* 24px H2 im Lauftext */

  --leading-body: 1.56;
  --leading-tight: 1.04;
  --tracking-body: 0.02em;

  /* Monospace-Kleinzeilen (12px: Marken, Metazeilen, Datumsangaben). Der
     Handoff nennt dafuer eine Spanne 0,1-0,14em, keinen Einzelwert. Beide
     Enden sind Tokens, kein Mittelwert dazwischen: die Referenzscreens setzen
     Kicker, Metazeilen und Ordnungszahlen auf 0,14em und die Marken der
     News-Liste auf 0,1em. Wer eine dritte Weite braucht, hat einen Fall, den
     der Entwurf nicht kennt. */
  --tracking-mono: 0.1em;
  --tracking-mono-wide: 0.14em;

  /* ---- Form ---- */
  /* Markenhaftes ist Radius 0 — CSS-Default, deshalb kein Token.
     Genau ZWEI Produktradien, entschieden im Entwurf. Kein dritter Wert:
     das ist die technische Fassung von "Radius folgt Funktion, nicht Ort". */
  --radius-product: 14px;
  --radius-product-sm: 10px;

  /* ---- Schatten (Handoff 02 und 08) ---- */
  /* Genau ZWEI Stufen, und nur in der Karten-UI: schwebende Kartenelemente
     (float) und hervorgehobene Bildcontainer (float-lg). Auf Flaechen,
     Formularen und den Kacheln der Rechtstextseiten gibt es keinen Schatten.
     Beide bauen auf --shadow-rgb, das direkt unter diesem Block steht (die
     Begruendung dort) und im Dunkeltheme neutral wird — der Schatten bleibt
     sichtbar und wird NICHT durch einen Rahmen ersetzt (Handoff 08). */
  --shadow-float: 0 16px 40px rgba(var(--shadow-rgb), 0.14);
  --shadow-float-lg: 0 26px 60px rgba(var(--shadow-rgb), 0.16);

  /* ---- Breiten (Manual: Regel) ---- */
  /* Das sind Layoutbreiten, NICHT die Lesespalte. Fliesstext benutzt
     --measure aus base.css. */
  --container-content: 1680px;
  --container-narrow: 1200px;
  --container-xnarrow: 948px;

  /* ---- Bewegung (Manual: Regel) ---- */
  /* Die Kurve steht hier, die zwei Dauern stehen im :root darunter — sie
     sind kein Utility-Namespace und fielen aus @theme heraus. Begruendung
     dort. */
  --ease-brand: ease;
}

/* Der Farbanteil der beiden Schatten, als RGB-Tripel fuer rgba() (Handoff 02:
   34, 28, 52 ist #221C34, dunkel neutral 0, 0, 0).
   Steht ABSICHTLICH ausserhalb von @theme: Tailwind gibt aus dem @theme-Block
   nur aus, was eine Utility wirklich benutzt, und --shadow-rgb wird nur
   innerhalb der beiden Schattenwerte gelesen — im hellen :root waere es sonst
   weggefallen, waehrend die Dunkelbloecke unten es setzen. Dann traegt der
   Schatten nur im Dunkeltheme eine Farbe. Wie --measure in base.css: ein
   Baustein, kein Utility-Namespace. */
:root {
  --shadow-rgb: 34, 28, 52;

  /* Die Verdunklung hinter einer aufgeklappten Flaeche (Mobilmenue, rmq.20).
     Sie steht aus DEMSELBEN Grund hier draussen wie --shadow-rgb: gelesen
     wird sie nur als var() in einem Komponenten-Stilblock, nie von einer
     Utility — in @theme fiele sie aus dem hellen :root heraus, waehrend die
     Dunkelbloecke sie setzen.
     Der Name beginnt mit --color-, obwohl kein Utility-Namespace daraus
     entsteht: das Token-Gate des Landing-Repos nimmt --color-*-Deklarationen
     von der Farbliteral-Pruefung aus, und genau eine solche Deklaration ist
     das hier.
     Hell traegt sie Nachtblau, dunkel neutrales Schwarz — dieselbe Regel wie
     beim Schatten: auf dunklem Grund traegt eine farbige Verdunklung nicht.
     0,32 statt der ueblichen Modal-Haelfte, weil die Flaeche darunter
     bedienbar bleibt: das hier trennt, es sperrt nicht. */
  --color-scrim: rgba(34, 28, 52, 0.32);

  /* Genau ZWEI Dauern, und sie sind eine Regel statt zweier Zahlen:
     `state` fuer den Zustandswechsel eines Bedienelements, `surface` fuer
     eine Flaeche, die kommt oder geht. Wer eine dritte braucht, hat einen
     Fall, den der Entwurf nicht kennt.
     Sie stehen aus demselben Grund hier wie --shadow-rgb daruber, und das ist
     nachgemessen: in @theme neben --ease-brand tauchten sie im gebauten CSS
     nicht auf (13.08.2026). --ease-* ist ein Tailwind-Namespace und wird
     ausgegeben, --duration-* ist keiner.
     Bis 13.08.2026 gab es keine Dauer — die Kurve stand allein, die Zahlen
     davor schrieb jede Komponente selbst (rmq.20). */
  --duration-state: 140ms;
  --duration-surface: 180ms;
}

/* ---- Dark Mode (Abweichung 4: das Manual kennt keinen) ----
   Gesetzt ueber data-pm-theme am Wurzelelement (S18). Starlight schaltet
   ueber data-theme — beide Selektoren, damit die Docs-Site dieselben
   Dunkelwerte bekommt (up3.5). */
:root[data-pm-theme='dark'],
:root[data-theme='dark'] {
  color-scheme: dark;

  --color-surface: #1a1626;
  --color-surface-2: #211c2e;
  /* Abweichung 11: HELLER als der Seitengrund, nicht dunkler (1ix.18).
     Bis 15.08.2026 stand hier #100D18 — nachtblau weitergedacht, aber im
     Dunkeln funktionslos: gegen den Grund #1A1626 sind das 1,086:1, also
     rund 4 % Unterschied. Die Nachtblau-Vollflaeche ist der einzige
     dramatische Moment der Seitenarchitektur, und im Dunkeltheme war er
     schlicht nicht da. Dunkler geht nicht — #100D18 ist fast schwarz.
     Trennung entsteht nur nach oben.
     Der Wert ist 85 % Alt-Invert + 15 % --color-ink (#F2F0F6), gemessen im
     Browser an allen vier Fundstellen: 1,349:1 gegen den Grund, Weiss
     darauf 13,11:1, --color-ink-invert darauf 7,71:1. Die Stufe darunter
     (90 %) blieb unsichtbar, die darueber (82 %) kostet Textkontrast, ohne
     sichtbar mehr zu trennen. */
  --color-invert: #322f39;

  --color-accent: #ff3d74;      /* Abweichung 5: Markenrot erreicht auf
                                   dunklem Grund keine 4,5:1 */
  --color-ink: #f2f0f6;
  --color-ink-3: #a29cb2;
  --color-ink-invert: #c9c4d6;
  --color-line: #35304a;
  /* 64 % --color-invert + 36 % --color-ink, ausgerechnet (1ix.33).
     DAS KRITERIUM, damit es niemand neu verhandelt: die Linie soll im
     Dunkeln so stark trennen wie im Hellen. Hell trennt #666666 auf #221C34
     mit 2,85:1 — dieser Wert kommt auf #322F39 auf 2,87:1. Beide Zahlen im
     Browser abgelesen, nicht gerechnet. Nicht "sieht gut aus", sondern
     "gleiche Trennkraft in beiden Themes".
     Die Linie sitzt ausschliesslich AUF --color-invert, hat den Wert aber
     bis 15.08.2026 nicht mitbewegt: als 1ix.18 die Flaeche von #100D18 auf
     #322F39 hob, fiel sie von 2,05:1 auf 1,40:1 und war fast weg — genau
     die Linie, die im Ergebnis-Band den Platzhalter vom Live-Beleg trennt.
     WARUM LITERAL UND NICHT color-mix(): als Mischung waere die Kopplung in
     der Kaskade gelandet, und dort liefert sie sie nicht. Lightning CSS
     stellt jeder Mischung in einer Custom Property einen statischen
     Rueckfall voran und rechnet ihn gegen das HELLE :root aus — im
     Dunkelblock landete dadurch #221C34, also 1,25:1 und damit schlechter
     als der Schaden, den 1ix.33 repariert. Die Kopplung haelt jetzt
     tokens.test.ts, die die Mischung nachrechnet: wer --color-invert
     bewegt, bekommt einen roten Test mit dem neuen Sollwert statt einer
     Linie, die still verschwindet.
     (Regulaere Eigenschaften sind davon nicht betroffen — Action.astro
     liefert color-mix ohne Rueckfall aus, dort faellt im Ernstfall nur der
     Hover-Effekt weg. Geprueft am gebauten CSS, 15.08.2026.) */
  --color-line-invert: #77747d;
  --color-frame: #6e6580;       /* loest sich vom Text, s. o. */
  --color-field-line: #a29cb2;  /* gemessen 6,25:1 */
  --color-sep: #4a4358;         /* gemessen 1,88:1 — nur Dekoration, s. o. */

  /* Neutral statt nachtblau: auf dunkler Flaeche traegt ein farbiger Schatten
     nicht, und ein Rahmen ersetzt ihn nicht (Handoff 08). */
  --shadow-rgb: 0, 0, 0;

  /* Ebenfalls neutral, und staerker: nach unten ist auf #1A1626 weniger Luft
     als auf Weiss. 0,5 bringt die Flaeche auf #0D0B13 und damit sichtbar
     unter die Flaeche des Kopfes, die im Dunkeltheme selbst schon #1A1626
     ist. Nachtblau waere hier unsichtbar. */
  --color-scrim: rgba(0, 0, 0, 0.5);

  /* Funktionsfarben im Dark Mode (Abweichung 10: das Manual definiert
     nur Hellwerte). REGEL statt vier Einzelentscheidungen: die Rollen
     tauschen — der helle Hintergrund wird die Schriftfarbe, die
     Schriftfarbe wird zur dunklen Flaeche gezogen. Damit bleiben Hue und
     Herkunft erhalten und es entsteht keine neue Palette.
     Braucht die Kreativfreigabe (E43), bevor tokens.css friert. */
  --color-error-fg: #ffbaba;
  --color-error-bg: #3b0d10;
  --color-info-fg: #dfeff5;
  --color-info-bg: #0f2a33;
  --color-warn-fg: #f3efdd;
  --color-warn-bg: #2e2810;
  --color-ok-fg: #eaf3dd;
  --color-ok-bg: #1a2a0d;
}

/* Derselbe Satz Dunkelwerte, wenn KEIN Theme-Attribut gesetzt ist. Beide
   Attribute oben setzt ausschliesslich JavaScript; ohne JS (oder mit
   gesperrtem localStorage) bliebe die Seite sonst immer hell, obwohl das
   System dunkel steht.
   Der Selektor fragt die ABWESENHEIT der Attribute ab, nicht ihren Wert:
   sobald der Umschalter irgendein Theme gesetzt hat, entscheidet allein das
   Attribut — auch gegen die Systemeinstellung.
   Reine Kopie des Blocks darueber; Werte und ihre Begruendungen stehen dort.
   Zusammengehalten von src/styles/tokens.test.ts im Landing-Repo, der beide
   Bloecke deklarationsgenau vergleicht. */
@media (prefers-color-scheme: dark) {
  :root:not([data-pm-theme]):not([data-theme]) {
    color-scheme: dark;

    --color-surface: #1a1626;
    --color-surface-2: #211c2e;
    --color-invert: #322f39;

    --color-accent: #ff3d74;
    --color-ink: #f2f0f6;
    --color-ink-3: #a29cb2;
    --color-ink-invert: #c9c4d6;
    --color-line: #35304a;
    --color-line-invert: #77747d;
    --color-frame: #6e6580;
    --color-field-line: #a29cb2;
    --color-sep: #4a4358;

    --shadow-rgb: 0, 0, 0;
    --color-scrim: rgba(0, 0, 0, 0.5);

    --color-error-fg: #ffbaba;
    --color-error-bg: #3b0d10;
    --color-info-fg: #dfeff5;
    --color-info-bg: #0f2a33;
    --color-warn-fg: #f3efdd;
    --color-warn-bg: #2e2810;
    --color-ok-fg: #eaf3dd;
    --color-ok-bg: #1a2a0d;
  }
}

:root[data-pm-theme='light'],
:root[data-theme='light'] { color-scheme: light; }

/* Draft B — lizenzpflichtig, nur auf pixelpoint-Domains ausliefern (E44).
   Manual-Schnitte Light/SemiBold/ExtraBold. Light traegt usWeightClass 350
   statt Manual-300 — deklariert wird, was in der Datei steht. Siehe FONTS.md */
@font-face {
  font-family: 'Draft B';
  src: url('./fonts/brand/DraftB-Light.woff2?v=0.2.7') format('woff2');
  font-weight: 350;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Draft B';
  src: url('./fonts/brand/DraftB-SemiBold.woff2?v=0.2.7') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Draft B';
  src: url('./fonts/brand/DraftB-ExtraBold.woff2?v=0.2.7') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

/* IBM Plex Mono — SIL OFL 1.1, selbst gehostet. Nur fuer Codebloecke und
   die wenigen Kleinzeilen, die der Entwurf zulaesst. */
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('./fonts/brand/IBMPlexMono-400-latin.woff2?v=0.2.7') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  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';
  src: url('./fonts/brand/IBMPlexMono-500-latin.woff2?v=0.2.7') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  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;
}

/* Basis-CSS der Marke. Nach tokens.css importieren. */

:root {
  /* Lesespalte. Das Manual nennt zugleich content-extra-narrow 948px und
     60-75 Zeichen pro Zeile — beides zusammen geht nicht auf.
     Nachgemessen an Designrunde 5 ueber echte Zeilenboxen: 773px ergaben
     Median 67 und Maximum 77 Zeichen. 690px bringen den Median auf 62-65
     und das Maximum unter 70. Fester Wert, keine Spanne: sonst legt es
     jeder anders aus. */
  --measure: 690px;
}

html {
  /* Grundgroesse 19px = 118,75 % von 16px (Manual: Fix) */
  font-size: 118.75%;
  color-scheme: light dark;
}

body {
  margin: 0;
  background: var(--color-surface);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-weight: var(--font-weight-body);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-body);
  /* Immer linksbuendig, Flattersatz rechts — kein Blocksatz (Manual: Regel) */
  text-align: left;
}

/* Mobile Groessenleiter. Der Entwurf hat diskrete Werte je Breakpoint,
   keine fluide Interpolation — deshalb Ueberschreibung statt clamp().
   Breakpoint 767px entspricht BREAKPOINT_PX.mobileMax des Produkts. */
@media (max-width: 767px) {
  :root {
    /* In rem wie die Desktop-Leiter (1ix.24), gegen dieselbe Bezugsgroesse
       von 19px. Die BEDINGUNG der Media Query bleibt in Pixeln: dort loest
       rem gegen die Initialgroesse auf und nicht gegen die 118,75-%-Wurzel,
       der Umschaltpunkt wuerde also woanders liegen als gedacht. Die
       Deklarationen darin sind davon nicht betroffen. */
    --text-display: 2.4211rem; /* 46px */
    --text-h1: 2.1053rem; /* 40px */
    --text-h2: 1.5789rem; /* 30px */
    --text-lead: 1.1053rem; /* 21px */
    --text-body: 0.8947rem; /* 17px */
    --text-small: 0.6316rem; /* 12px */

    /* Die Laufweiten wandern mit der Leiter (Handoff 02): auf dieser Stufe
       traegt --text-h1 die 40-px-H1 der Mobilfassung, und die steht im Entwurf
       auf -0,03em statt auf den -0,025em des 46-px-Sektionstitels. --text-h2
       traegt hier die 30-px-Zeile, fuer die der Entwurf keine eigene Laufweite
       nennt — dort gilt die des Fliesstexts. */
    --text-h1--letter-spacing: -0.03em;
    --text-h2--letter-spacing: var(--tracking-body);
  }
}

/* Fliesstext laeuft nie breiter als die Satzregel erlaubt */
p, li, blockquote, dd {
  max-width: var(--measure);
}

/* Fokus: 2px Markenrot, niemals none (Manual: Fix, E17) */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Auf Nachtblau (Handoff 09): weisser Ring statt Akzent — Rot auf Invert
   erreicht den Kontrast nicht. Gilt fuer .bg-invert und Elemente, die selbst
   Invert als Flaeche tragen (Skip-Links). Literal #ffffff, damit der Ring in
   beiden Themes weiss bleibt. */
.bg-invert :focus-visible,
.bg-invert:focus-visible,
.skip-link:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 3px;
}

/* Links im Fliesstext: Unterstreichung bleibt immer sichtbar (E17) */
a {
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
a:hover {
  color: var(--color-accent);
}

/* Skip-Links (Entscheidung Marcus 03.08.2026, Ticket 1f0.16): ueberall
   versteckt bis Fokus — ersetzt die dauerhaft sichtbare Leiste aus Handoff
   01/03. Muster wie vor E1b: position absolute ausserhalb des Bildes, bei
   :focus oben links eingeblendet. Weiss auf Nachtblau mit 4 px Rahmen, in
   beiden Themes (literal #ffffff). Mobil und Desktop gleich. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1rem;
  background: var(--color-invert);
  color: #ffffff;
  text-decoration: none;
  border: 4px solid #ffffff;
}

.skip-link:focus {
  left: 0;
}

img, video {
  max-width: 100%;
  height: auto;
}

@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;
  }
}
/* == brand:end == */

/* == Statusseite == */
/* Handgeschrieben, nur Brand-Tokens per var(). Neu erzeugen mit „pnpm brand“ lässt diesen Abschnitt stehen.
   Flächen: --color-surface (Grund), --color-surface-2 (Störungen), --color-invert (Kopf) – genau drei.
   Zustände nur mit Funktionsfarben, nie Markenrot. */

/* Balkenfarben. Hell = die Funktionsfarben. Im Dunkeln tauscht die Brand die Rollen, dort sind alle -fg-Werte fast
   weiß und ok, eingeschränkt und Wartung als Balken nicht mehr unterscheidbar. Deshalb tragen die Balken im Dunkeln
   die hellen Brand-Werte (Grafik auf dem dunklen Grund jeweils über 3:1, WCAG 1.4.11). Literale nur in --color-*-Deklarationen
   wie im Token-Gate der Brand. */
:root {
  --color-bar-ok: var(--color-ok-fg);
  --color-bar-warn: var(--color-warn-fg);
  --color-bar-error: var(--color-error-fg);
  --color-bar-info: var(--color-info-fg);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-pm-theme]):not([data-theme]) {
    --color-bar-ok: #4f7a28;
    --color-bar-warn: #887830;
    --color-bar-error: #d8000c;
    --color-bar-info: #2d748f;
  }
}

.wrap {
  max-width: 40rem;
  margin-inline: auto;
  padding-inline: 1rem;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.icon {
  width: 1em;
  height: 1em;
  flex: none;
}

/* Kopf: die eine Nachtblau-Fläche */
.head {
  background: var(--color-invert);
  color: var(--color-ink-invert);
  padding-block: 1.1rem 1.5rem;
}
.head a {
  color: inherit;
  text-decoration: none;
}
.wordmark {
  margin: 0 0 1.5rem;
  font-weight: var(--font-weight-display);
  letter-spacing: var(--tracking-body);
}
.wordmark span {
  font-weight: var(--font-weight-body);
}
.overall {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  font-size: var(--text-h2);
  font-weight: var(--font-weight-heading);
  line-height: var(--leading-tight);
  letter-spacing: var(--text-h2--letter-spacing);
}
.overall-icon {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.5em;
  height: 1.5em;
  border-radius: 50%;
}
.overall-icon .icon {
  width: 0.9em;
  height: 0.9em;
}
.stamp {
  margin: 0.75rem 0 0;
  font-family: var(--font-mono);
  font-size: var(--text-small);
  letter-spacing: var(--tracking-mono);
}

/* Zustandsfarben: Symbol und Text tragen den Zustand, die Farbe unterstützt nur */
.label--ok, .overall-icon--ok { color: var(--color-ok-fg); background: var(--color-ok-bg); }
.label--degraded, .overall-icon--degraded { color: var(--color-warn-fg); background: var(--color-warn-bg); }
.label--outage, .overall-icon--outage { color: var(--color-error-fg); background: var(--color-error-bg); }
.label--maintenance, .overall-icon--maintenance { color: var(--color-info-fg); background: var(--color-info-bg); }
.label--unknown, .overall-icon--unknown { color: var(--color-ink-3); background: var(--color-surface-2); }
.overall-icon--unknown { color: var(--color-ink); }

.label {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  flex: none;
  padding: 0.1rem 0.5rem;
  border-radius: var(--radius-product-sm);
  font-size: var(--text-small);
  font-weight: var(--font-weight-heading);
  line-height: 1.5;
  white-space: nowrap;
}

main.wrap {
  padding-block: 1.5rem 2rem;
}
h2 {
  margin: 0 0 0.75rem;
  font-family: var(--font-mono);
  font-size: var(--text-small);
  font-weight: 500;
  letter-spacing: var(--tracking-mono-wide);
  text-transform: uppercase;
  color: var(--color-ink-3);
}
h3 {
  margin: 0;
  font-size: var(--text-body);
  font-weight: var(--font-weight-heading);
  line-height: 1.3;
}
.meta {
  margin: 0.2rem 0 0;
  font-family: var(--font-mono);
  font-size: var(--text-small);
  letter-spacing: var(--tracking-mono);
  color: var(--color-ink-3);
}

/* Bereiche */
.areas {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--color-line);
}
.area {
  max-width: none;
  padding-block: 1rem;
  border-bottom: 1px solid var(--color-line);
}
.area-row, .incident-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 0.75rem;
}
.bars {
  display: flex;
  gap: 1px;
  height: 1.6rem;
  margin-top: 0.7rem;
}
.bar {
  flex: 1 1 0;
  min-width: 2px;
  border-radius: 1px;
}
.bar--ok { background: var(--color-bar-ok); }
.bar--degraded { background: var(--color-bar-warn); }
.bar--outage { background: var(--color-bar-error); }
.bar--maintenance { background: var(--color-bar-info); }
.bar--none { background: var(--color-line); }
.area-meta {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.35rem;
  font-size: var(--text-small);
  color: var(--color-ink-3);
}
.range--mobile { display: none; }

/* Störungen: der eine Grauton */
.block {
  margin-bottom: 1.75rem;
}
.block--incidents {
  padding: 1rem 1rem 0.25rem;
  background: var(--color-surface-2);
  border: 1px solid var(--color-line);
}
.incident {
  padding-bottom: 1rem;
}
.incident + .incident {
  padding-top: 1rem;
  border-top: 1px solid var(--color-line);
}
.incident--resolved h3,
.incident--resolved .update-text {
  color: var(--color-ink-3);
}
.timeline {
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
}
.timeline li,
.maintenance li {
  max-width: none;
}
.timeline li {
  padding-left: 0.75rem;
  border-left: 2px solid var(--color-line);
}
.timeline li + li {
  margin-top: 0.6rem;
}
.update-text {
  margin: 0.15rem 0 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* Wartung */
.maintenance {
  margin: 0;
  padding: 0;
  list-style: none;
}
.maintenance li {
  padding-block: 0.75rem;
  border-top: 1px solid var(--color-line);
}

/* Archiv */
main > .incident {
  padding-block: 1rem;
  border-bottom: 1px solid var(--color-line);
}
main > .incident + .incident {
  border-top: 0;
}
.empty {
  color: var(--color-ink-3);
}
.pager {
  display: flex;
  justify-content: space-between;
  margin-top: 1.5rem;
}

/* Fuß */
.foot {
  border-top: 1px solid var(--color-line);
  padding-block: 1.25rem 2rem;
  font-size: var(--text-small);
  color: var(--color-ink-3);
}
.foot p {
  margin: 0.3rem 0;
}
.sep {
  color: var(--color-sep);
}
.foot-brand {
  font-family: var(--font-mono);
  letter-spacing: var(--tracking-mono-wide);
  text-transform: uppercase;
}

/* Mobil (Breakpoint der Brand): die letzten 30 Tage */
@media (max-width: 767px) {
  .bar:nth-child(-n+60) { display: none; }
  .range--all { display: none; }
  .range--mobile { display: inline; }
}
