/* ==========================================================================
   APHIRO² — Design Tokens (App-Version)
   Farben extrahiert am 2026-08-13 aus https://aphiro-bad-hersfeld.ap-smarthome.chatgpt.site/
   Schriften seit 2026-08-20: Inter + JetBrains Mono, selbst gehostet (DESIGN.md §3)
   Drop-in: als erste CSS-Datei einbinden, danach nur noch var(--ap-*).

   Hiess bis zum 20.08.2026 `aphiro-tokens.css`. Umbenannt, weil die
   Sicherheitsregeln der Arbeitsumgebung jede Datei sperren, deren Name das
   Wort `token` traegt — gemeint sind Zugangsdaten, getroffen hat es die
   Design-Tokens. Der Fachbegriff bleibt, nur der Dateiname ist ausgewichen.
   ========================================================================== */

/* ==========================================================================
   Die Schriften. Selbst gehostet, fuenf Dateien, zusammen rund 192 KB.

   **Warum Inter und nicht mehr Geist** (Alexander, 20.08.2026): Am 20.08. wurde
   die CSS des Planungsportals `planung.aphiro.de` nachgelesen statt geraten. Es
   setzt `font-family: Inter, Segoe UI, Arial, sans-serif` — und laedt die
   Schrift **nicht**: kein @font-face, kein @import, kein Google-Aufruf. Auf
   einem Rechner ohne Inter zeigt das Portal also Segoe UI. Die App und das
   Portal stehen in derselben Vorfuehrung nebeneinander; zwei verschiedene
   Schriften fallen einem Banker so auf wie zwei verschiedene Schwarztoene.
   Abgeloest ist damit die Wahl vom 13.08. (Aptos -> Geist). Der Grund von
   damals bleibt richtig: Aptos ist ein Microsoft-Systemfont ohne freie Lizenz.

   **Warum selbst gehostet** (offener Punkt aus DESIGN.md §7, faellig seit dem
   13.08.): Der Dienst laeuft auf einem deutschen Server und die Seite wird
   einem Banker gezeigt. Ein Aufruf an Google-Server bei jedem Seitenaufbau ist
   datenschutzrechtlich heikel, kostet einen Roundtrip — und die Spec rechnet
   mit einem Bankgebaeude ohne Internet. Damit ist die App unabhaengiger als das
   Portal selbst.

   **Warum fuenf Dateien statt zwei:** `latin` und `latin-ext` je Familie sind
   der uebliche Schnitt; ein Browser laedt nur, was die Seite wirklich braucht.
   Die dritte Inter-Datei traegt genau zwei Zeichen, den Links- und den
   Rechtspfeil. Sie ist noetig, weil Googles `latin`-Subset zwar U+2191 und
   U+2193 enthaelt, aber **nicht U+2192** — nachgemessen, nicht vermutet. Ohne
   sie faellt jedes „→" auf eine Fremdschrift zurueck, und Aufgabe 4 will
   „Starten →" auf die Startseite setzen.

   Beide Familien stehen unter der SIL Open Font License 1.1 und duerfen
   mitgeliefert werden; die Lizenz liegt in `app/static/schrift/LIZENZ.md`.

   `font-display: swap` ist Absicht: Lieber sofort lesbarer Text in der
   Ersatzschrift als ein leerer Bildschirm auf dem Beamer.
   ========================================================================== */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('/static/schrift/Inter-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: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('/static/schrift/Inter-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: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('/static/schrift/Inter-pfeile.woff2') format('woff2');
  unicode-range: U+2190, U+2192;
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url('/static/schrift/JetBrainsMono-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: 'JetBrains Mono'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url('/static/schrift/JetBrainsMono-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;
}

/* ==========================================================================
   1. Marken-Rohfarben — die Wahrheit. Nie direkt im Code benutzen,
      immer über die semantischen Tokens in Abschnitt 2.
   ========================================================================== */
:root {
  --ap-navy:        #071A23;
  --ap-navy-deep:   #061A23;
  --ap-navy-2:      #0B2530;
  --ap-navy-3:      #0B2833;

  /* Die Grundfamilie des Planungsportals `planung.aphiro.de`, am 20.08.2026
     Pixel fuer Pixel aus drei Bildschirmfotos gemessen (Materialien/). Nicht
     nach Augenmass gewaehlt: Die App und das Portal stehen in derselben
     Vorfuehrung nebeneinander, und zwei verschiedene Schwarztoene faellt ein
     Banker sofort auf. Gruenschwarz, nicht Petrol — der Unterschied zur
     Navy-Familie darueber ist der Blauanteil. */
  --ap-ground:      #0A1212;   /* Seitengrund                                */
  --ap-ground-deep: #050C0B;   /* unterer Rand des Verlaufs                  */
  --ap-ground-2:    #0E1C1B;   /* gehobener Bereich, z. B. Panel-Innenflaeche*/
  --ap-ink:         #071D1A;   /* Kartenflaeche                              */
  --ap-ink-2:       #08211A;   /* hervorgehobenes Panel                      */
  --ap-ink-3:       #0A2D22;   /* gewaehlte Karte                            */
  --ap-ink-field:   #061915;   /* Eingabefeld                                */
  --ap-line:        #245248;   /* Kartenrand, ruhend                         */
  --ap-line-hell:   #65D984;   /* Rand der gewaehlten Karte                  */
  --ap-mint-hell:   #75E297;   /* Akzent als TEXT auf Dunkel                 */
  --ap-glow-1:      #153B37;   /* Schimmer oben links                        */
  --ap-glow-2:      #083532;   /* Schimmer oben rechts                       */

  --ap-paper:       #F4F7F6;
  --ap-paper-2:     #F7F9F8;
  --ap-paper-3:     #EEF3F1;
  --ap-white:       #FFFFFF;

  --ap-green:  #70C82F;
  --ap-mint:   #24C080;
  --ap-cyan:   #00B8D4;
  --ap-violet: #8B5CF6;   /* nur Hero-Glow */

  /* Die Signaturfarbe der Marke ist kein Ton, sondern dieser Verlauf. */
  --ap-gradient:     linear-gradient(90deg, #70C82F, #24C080 54%, #00B8D4);
  --ap-gradient-2:   linear-gradient(90deg, #71CA32, #00B8D4);
  --ap-gradient-btn: linear-gradient(90deg, #70C82F, #24C080);
}

/* ==========================================================================
   2. Semantische Farben — DIESE im Code verwenden.
      Hell ist Standard, Dunkel wird weiter unten neu belegt.
   ========================================================================== */
:root {
  /* Flächen */
  --ap-bg:            #F4F7F6;   /* Seitenhintergrund        */
  --ap-surface:       #FFFFFF;   /* Karte, Panel, Modal      */
  --ap-surface-2:     #F7F9F8;   /* abgesetzte Fläche        */
  --ap-surface-3:     #EEF3F1;   /* tiefste helle Stufe      */
  --ap-surface-inset: rgba(7,26,35,0.04);  /* Input, Skeleton */

  /* Text */
  --ap-text:         #102932;
  --ap-text-heading: #0B2731;
  --ap-text-muted:   #60737A;
  --ap-text-subtle:  #7C8C92;   /* NUR Platzhalter + deaktiviert. Nie lesbarer Text. */
  --ap-text-inverse: #FFFFFF;

  /* Linien */
  --ap-border:        rgba(7,26,35,0.13);
  --ap-border-strong: rgba(7,26,35,0.21);

  /* Interaktion */
  --ap-accent:        #0B7A5C;   /* Textlink/Icon — kontraststark auf Hell */
  --ap-accent-hover:  #095F48;
  --ap-focus:         #00B8D4;
  --ap-overlay:       rgba(6,26,35,0.55);

  /* Zustände — Erfolg und Info kommen aus der Marke,
     Warnung und Fehler mussten ergänzt werden (siehe DESIGN.md §9). */
  /* Werte gemessen: erreichen 4.5:1 sowohl auf --ap-bg als auch auf dem eigenen Flächenton */
  --ap-success:    #0F7049;   --ap-success-bg: rgba(36,192,128,0.12);
  --ap-info:       #0B6B7C;   --ap-info-bg:    rgba(0,184,212,0.12);
  --ap-warning:    #8A5D08;   --ap-warning-bg: rgba(224,162,26,0.14);
  --ap-danger:     #B22A22;   --ap-danger-bg:  rgba(196,52,43,0.10);

  /* Schatten — im hellen Modus fast nie */
  --ap-shadow-none:  none;
  --ap-shadow-hover: 0 26px 70px rgba(7,26,35,0.10);
  --ap-shadow-pop:   0 12px 40px rgba(7,26,35,0.14);   /* Dropdown, Modal */
  --ap-glow-mint:    0 0 14px rgba(36,192,128,0.70);
}

/* --- Dunkler Modus: gleiche Namen, neue Werte ---------------------------- */
:root[data-theme="dark"],
html.dark {
  /* Was der Browser selbst zeichnet — die aufgeklappte Auswahlliste, der
     Rollbalken, das Dateifeld — richtet sich nach `color-scheme`, nicht nach
     unseren Farben. Ohne diese Zeile klappt die Auswahl „Behinderung" WEISS
     vor der dunklen Seite auf. Ein Schnappschuss zeigt die Liste zugeklappt
     und haette es nie gefunden; gesehen wurde es erst beim Aufklappen. */
  color-scheme: dark;

  --ap-bg:            var(--ap-ground);
  --ap-surface:       var(--ap-ink);
  --ap-surface-2:     var(--ap-ground-2);
  --ap-surface-3:     var(--ap-ink-3);
  --ap-surface-inset: var(--ap-ink-field);

  --ap-text:         rgba(255,255,255,0.96);
  --ap-text-heading: #FFFFFF;
  --ap-text-muted:   rgba(255,255,255,0.62);
  --ap-text-subtle:  rgba(255,255,255,0.42);
  /* Text AUF einer hellen Akzentflaeche, also auf der Pille. Gemessen am
     Portal: #062017 auf #69DF84. Nicht der Seitengrund — der ist blaugruener. */
  --ap-text-inverse: #062017;

  --ap-border:        var(--ap-line);
  --ap-border-strong: var(--ap-line-hell);

  --ap-accent:       var(--ap-mint-hell);   /* auf Dunkel darf der Markenton leuchten */
  --ap-accent-hover: #8FEBAB;
  --ap-focus:        #00B8D4;
  --ap-overlay:      rgba(3,18,26,0.72);

  --ap-success:    #35C59C;   --ap-success-bg: rgba(36,192,128,0.16);
  --ap-info:       #3ACBE0;   --ap-info-bg:    rgba(0,184,212,0.16);
  --ap-warning:    #E0A21A;   --ap-warning-bg: rgba(224,162,26,0.16);
  --ap-danger:     #E8695F;   --ap-danger-bg:  rgba(232,105,95,0.14);

  --ap-shadow-hover: 0 26px 70px rgba(0,0,0,0.45);
  --ap-shadow-pop:   0 12px 40px rgba(0,0,0,0.50);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;               /* Begruendung im Block darueber */
    --ap-bg:            var(--ap-ground);
    --ap-surface:       var(--ap-ink);
    --ap-surface-2:     var(--ap-ground-2);
    --ap-surface-3:     var(--ap-ink-3);
    --ap-surface-inset: var(--ap-ink-field);
    --ap-text:         rgba(255,255,255,0.96);
    --ap-text-heading: #FFFFFF;
    --ap-text-muted:   rgba(255,255,255,0.62);
    --ap-text-subtle:  rgba(255,255,255,0.42);
    /* Text AUF einer hellen Akzentflaeche, also auf der Pille. Gemessen:
       #062017 auf #69DF84. Nicht der Seitengrund — der waere zu blaugruen. */
    --ap-text-inverse: #062017;
    --ap-border:        var(--ap-line);
    --ap-border-strong: var(--ap-line-hell);
    --ap-accent:       var(--ap-mint-hell);
    --ap-accent-hover: #8FEBAB;
    --ap-overlay:      rgba(3,18,26,0.72);
    --ap-success:    #35C59C;   --ap-success-bg: rgba(36,192,128,0.16);
    --ap-info:       #3ACBE0;   --ap-info-bg:    rgba(0,184,212,0.16);
    --ap-warning:    #E0A21A;   --ap-warning-bg: rgba(224,162,26,0.16);
    --ap-danger:     #E8695F;   --ap-danger-bg:  rgba(232,105,95,0.14);
    --ap-shadow-hover: 0 26px 70px rgba(0,0,0,0.45);
    --ap-shadow-pop:   0 12px 40px rgba(0,0,0,0.50);
  }
}

/* ==========================================================================
   3. Typografie — Inter (variabel 100–900), JetBrains Mono (variabel 100–800)
   ========================================================================== */
:root {
  /* Die Ersatzkette ist dieselbe wie im Portal (`Inter, Segoe UI, Arial`),
     damit die App im aeussersten Fall genauso ausweicht wie es. Weil Inter hier
     mitgeliefert wird, kommt es dazu nur, wenn die Datei nicht laedt. */
  --ap-font-display: Inter, "Segoe UI", Arial, sans-serif;
  --ap-font-body:    Inter, "Segoe UI", Arial, sans-serif;
  --ap-font-mono:    "JetBrains Mono", ui-monospace, Consolas, Menlo, monospace;

  /* Marketing-Skala (Landing, Hero) — 1:1 aus der Live-Site */
  --ap-size-h1:      clamp(62px, 6.2vw, 100px);
  --ap-size-h2:      clamp(48px, 4.7vw, 70px);
  --ap-size-h2-lg:   clamp(54px, 6vw, 88px);

  /* App-Skala — für Oberflächen, nicht für Landingpages */
  --ap-size-title:   clamp(28px, 2.4vw, 38px);   /* Seitentitel   */
  --ap-size-section: 22px;                        /* Abschnitt     */
  --ap-size-card:    17px;                        /* Kartentitel   */
  --ap-size-body:    15px;
  --ap-size-ui:      14px;                        /* Buttons, Tabs */
  --ap-size-small:   13px;
  --ap-size-kicker:  10px;

  --ap-lh-display: 0.94;
  --ap-lh-h2:      0.98;
  --ap-lh-title:   1.08;
  --ap-lh-ui:      1.35;
  --ap-lh-body:    1.65;

  /* Der Wert stammt aus der Zeit von Geist („laeuft enger als Aptos"). Inter
     laeuft wieder etwas breiter; ob die Zahl bleibt, entscheidet der Blick auf
     die Seite, nicht die Herkunft des Wertes. */
  --ap-ls-display: -0.048em;
  --ap-ls-title:   -0.032em;
  --ap-ls-card:    -0.018em;
  --ap-ls-kicker:  0.18em;

  --ap-weight-display: 560;
  --ap-weight-title:   580;
  --ap-weight-card:    600;
  --ap-weight-ui:      540;
  --ap-weight-kicker:  800;
}

/* ==========================================================================
   4. Form, Abstand, Bewegung
   ========================================================================== */
:root {
  /* Radien (Alexander, 20.08.2026 — abgeloest ist „Radius 0, ausnahmslos").
     Gemessen am Planungsportal: Karten und Panels rund 10 px, Felder 8 px,
     Knoepfe vollrund. Drei Werte, nicht sieben — eine Radienleiter ist eine
     Entscheidung, die danach niemand mehr trifft, sondern nachschlaegt. */
  --ap-radius:      10px;   /* Karten, Panels, Tabellenrahmen */
  --ap-radius-sm:    8px;   /* Felder, Badges, kleine Flaechen */
  --ap-radius-pill: 999px;  /* Knoepfe — die einzige vollrunde Form */

  /* Der Grund ist kein Ton, sondern zwei weiche Teal-Flecke oben links und
     oben rechts. So steht es im Portal — nachgemessen, nicht behauptet: die
     hellsten Punkte liegen bei #153B37 und #083532.

     **Zwei Dinge, die beim Bauen schiefgingen und deshalb hier stehen:**

     1. Die Flecke sind in Pixeln hoch bemessen, nicht in Prozent. Prozent
        bezieht sich auf die Hoehe des ganzen Dokuments — auf der langen
        Tablet-Seite waere der Fleck dreimal so hoch wie auf der Startseite,
        und derselbe Schimmer saehe auf jeder Seite anders aus.
     2. Kein `background-attachment: fixed`. Es sieht im Browser richtig aus,
        aber ein Vollseiten-Schnappschuss malt die feste Ebene nur einmal —
        und genau daran haetten wir am Vorfuehrtag nichts gemerkt.

     Der untere Rand des Portals laeuft ins Schwarze. Das gilt fuer EINEN
     Bildschirm; auf einer scrollenden Seite waere es ein Verlauf ohne Ende.
     Deshalb hier nur die beiden Flecke ueber der flachen Grundfarbe. */
  --ap-ground-glow:
    radial-gradient(62% 560px at 16% -40px, rgba(21, 59, 55, 0.90) 0%, rgba(21, 59, 55, 0) 70%),
    radial-gradient(54% 480px at 82% -60px, rgba(8, 53, 50, 0.85) 0%, rgba(8, 53, 50, 0) 68%);

  --ap-space-1: 4px;   --ap-space-2: 8px;   --ap-space-3: 12px;
  --ap-space-4: 16px;  --ap-space-5: 24px;  --ap-space-6: 32px;
  --ap-space-7: 48px;  --ap-space-8: 64px;  --ap-space-9: 88px;
  --ap-space-10: 130px;

  --ap-gutter:      max(32px, calc(50vw - 700px));
  --ap-gutter-hero: max(32px, calc(50vw - 750px));
  --ap-measure:     65ch;

  --ap-control-h:   40px;   /* Input, Select, kleiner Button */
  --ap-control-h-lg:44px;   /* Touch-Ziel, Primär-Button     */

  --ap-dur-fast: 0.15s;
  --ap-dur:      0.25s;
  --ap-dur-slow: 0.30s;
  --ap-ease:     cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ==========================================================================
   5. Basis-Bausteine
   ========================================================================== */

body {
  /* Flaeche zuerst, Schimmer darueber: Der helle Modus (Druckansicht) hat
     keinen Schimmer und faellt sauber auf `--ap-bg` zurueck. */
  background: var(--ap-bg);
  color: var(--ap-text);
  font-family: var(--ap-font-body);
  font-size: var(--ap-size-body);
  line-height: var(--ap-lh-body);
  -webkit-font-smoothing: antialiased;
}

/* Der Schimmer gilt nur dort, wo es dunkel ist. **Farbe und Bild getrennt
   setzen, nicht als Kurzschreibweise**: `background: <bild>` loescht die
   Grundfarbe mit, und unterhalb des Bildes faellt die Seite auf Weiss zurueck.
   Genau das ist beim Bauen passiert und war erst auf dem Schnappschuss der
   langen Tablet-Seite zu sehen. */
:root[data-theme="dark"] body,
html.dark body {
  background-color: var(--ap-bg);
  background-image: var(--ap-ground-glow);
  background-repeat: no-repeat;
  background-position: top center;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body {
    background-color: var(--ap-bg);
    background-image: var(--ap-ground-glow);
    background-repeat: no-repeat;
    background-position: top center;
  }
}

h1, h2, h3, h4 { font-family: var(--ap-font-display); margin: 0; color: var(--ap-text-heading); }

h1 { font-size: var(--ap-size-h1); line-height: var(--ap-lh-display); letter-spacing: var(--ap-ls-display); font-weight: var(--ap-weight-display); }
h2 { font-size: var(--ap-size-h2); line-height: var(--ap-lh-h2);      letter-spacing: var(--ap-ls-display); font-weight: var(--ap-weight-display); }
h3 { font-size: var(--ap-size-card); line-height: 1.3;                letter-spacing: var(--ap-ls-card);    font-weight: var(--ap-weight-card); }

/* App-Titel statt Marketing-H1 */
.ap-title { font-family: var(--ap-font-display); font-size: var(--ap-size-title); line-height: var(--ap-lh-title); letter-spacing: var(--ap-ls-title); font-weight: var(--ap-weight-title); margin: 0; }

/* Marken-Muster: zweiter Halbsatz im Verlauf */
h1 strong, h2 strong, .ap-title strong {
  background: var(--ap-gradient);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; font-weight: 570;
}

/* Zahlen immer tabellarisch — sonst springen Tabellen */
.ap-num, table td, table th { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

/* Kicker */
.ap-kicker {
  display: flex; align-items: center; gap: 12px; margin: 0 0 26px;
  font-size: var(--ap-size-kicker); font-weight: var(--ap-weight-kicker);
  letter-spacing: var(--ap-ls-kicker); text-transform: uppercase;
  color: var(--ap-text-muted);
}
.ap-kicker > span { width: 34px; height: 2px; background: var(--ap-gradient-2); flex: none; }

/* Sektion */
.ap-section { padding: var(--ap-space-10) var(--ap-gutter); }
.ap-section--dark { background: var(--ap-navy); color: rgba(255,255,255,0.96); }
.ap-section--dark h2 { color: #fff; }

/* Karte */
.ap-card {
  background: var(--ap-surface);
  border: 1px solid var(--ap-border);
  border-radius: var(--ap-radius);
  padding: var(--ap-space-6);
  position: relative; overflow: hidden;
  transition: transform var(--ap-dur) var(--ap-ease),
              box-shadow var(--ap-dur) var(--ap-ease),
              border-color var(--ap-dur) var(--ap-ease);
}
.ap-card--interactive:hover {
  transform: translateY(-5px);
  box-shadow: var(--ap-shadow-hover);
  border-color: rgba(28,181,145,0.40);
  z-index: 2;
}
.ap-card > p { color: var(--ap-text-muted); }

.ap-card-line { display: block; height: 2px; background: var(--ap-border); }
.ap-card-line::after {
  content: ""; display: block; width: 25%; height: 100%;
  background: var(--ap-gradient-2);
  transition: width var(--ap-dur-slow) var(--ap-ease);
}
.ap-card--interactive:hover .ap-card-line::after { width: 100%; }

/* Buttons */
.ap-button {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border: 1px solid transparent; border-radius: var(--ap-radius-pill);
  padding: 0 20px; min-height: var(--ap-control-h-lg);
  font-family: var(--ap-font-display); font-size: var(--ap-size-ui);
  font-weight: var(--ap-weight-ui); line-height: var(--ap-lh-ui);
  cursor: pointer; text-decoration: none;
  transition: opacity var(--ap-dur-fast) var(--ap-ease),
              background-color var(--ap-dur-fast) var(--ap-ease);
}
.ap-button--primary   { background: var(--ap-gradient-btn); color: #061A23; }
.ap-button--secondary { background: var(--ap-navy-deep); color: #fff; }
/* Ruhender Rand `--ap-border`, nicht `--ap-border-strong`: Letzteres heisst
   seit Paket O „Rand der GEWAEHLTEN Karte" (#65D984, Signalgruen). Mit ihm
   leuchtete jeder Knopf so hell wie eine Auswahl — auf dem Tablet standen
   sechs davon untereinander, und keiner war mehr das Signal. Beim Zeigen
   kommt die helle Kante zurueck; dann ist sie Rueckmeldung statt Flaeche.
   Dieselbe Berichtigung wie bei Karte, Feld und Tabellenkopf in Aufgabe 1 —
   die beiden Knopfvarianten waren dort uebersehen worden. */
.ap-button--outline   { background: none; color: var(--ap-text); border-color: var(--ap-border); }
.ap-button--outline:hover { border-color: var(--ap-border-strong); }
/* Rechts derselbe Innenabstand wie links: Ohne ihn sass der CSV-Link mit
   seinem letzten Buchstaben genau auf der Randlinie der Seite und sah
   angeschnitten aus (nachgemessen: rechte Kante 1408 px = Rand des
   Inhaltsbereichs). */
.ap-button--ghost     { background: none; color: inherit; border: 0; border-left: 1px solid var(--ap-border); border-radius: 0; padding: 0 18px; }
.ap-button--danger    { background: var(--ap-danger); color: #fff; }
.ap-button:hover      { opacity: 0.88; }
.ap-button:active     { opacity: 0.78; }
.ap-button:disabled, .ap-button[aria-disabled="true"] { opacity: 0.42; cursor: not-allowed; }
.ap-button:focus-visible { outline: 2px solid var(--ap-focus); outline-offset: 3px; }

/* Formularfeld — Label immer sichtbar, nie Placeholder als Label */
.ap-field { display: grid; gap: var(--ap-space-2); }
.ap-label { font-size: var(--ap-size-small); font-weight: 560; color: var(--ap-text-muted); }
.ap-input {
  /* `width: 100%` heisst beim Vorgabewert `content-box`: 100 % PLUS 28 px
     Innenabstand PLUS 2 px Rand. Nachgemessen ragte das Feld auf dem Tablet
     30 px ueber die Karte hinaus. Vor Paket O fiel es niemandem auf, weil
     Karte und Feld dieselbe helle Flaeche trugen — seit der Grund dunkel und
     das Feld noch dunkler ist, steht der Ueberstand als Balken im Bild. */
  box-sizing: border-box;
  background: var(--ap-surface-inset);
  border: 1px solid var(--ap-border);
  border-radius: var(--ap-radius-sm);
  min-height: var(--ap-control-h-lg);
  padding: 0 14px;
  font: inherit; color: var(--ap-text);
  transition: border-color var(--ap-dur-fast) var(--ap-ease);
}
.ap-input::placeholder { color: var(--ap-text-subtle); }
.ap-input:focus-visible { outline: 2px solid var(--ap-focus); outline-offset: 2px; border-color: transparent; }
.ap-input[aria-invalid="true"] { border-color: var(--ap-danger); }
.ap-error { font-size: var(--ap-size-small); color: var(--ap-danger); }

/* Statusanzeige — Farbe nie allein, immer mit Text oder Punkt */
.ap-badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 10px; border-radius: var(--ap-radius-pill);
  font-size: var(--ap-size-small); font-weight: 560;
}
.ap-badge--success { background: var(--ap-success-bg); color: var(--ap-success); }
.ap-badge--info    { background: var(--ap-info-bg);    color: var(--ap-info); }
.ap-badge--warning { background: var(--ap-warning-bg); color: var(--ap-warning); }
.ap-badge--danger  { background: var(--ap-danger-bg);  color: var(--ap-danger); }

.ap-dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--ap-mint); box-shadow: var(--ap-glow-mint); flex: none;
}

/* Tabelle — keine Zebrastreifen, nur Linien */
.ap-table { width: 100%; border-collapse: collapse; font-size: var(--ap-size-body); }
.ap-table th {
  text-align: left; font-size: var(--ap-size-kicker); font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ap-text-muted);
  padding: 12px 16px; border-bottom: 1px solid var(--ap-border);
}
.ap-table td { padding: 14px 16px; border-bottom: 1px solid var(--ap-border); }

/* Ladezustand: dieselbe Form wie das, was er vertritt */
.ap-skeleton {
  background: var(--ap-surface-inset);
  border-radius: var(--ap-radius-sm);
  animation: ap-pulse 1.6s var(--ap-ease) infinite;
}
@keyframes ap-pulse { 0%,100% { opacity: 1 } 50% { opacity: 0.55 } }

/* Hero-Raster (nur Marketing-Seiten) */
.ap-grid-overlay {
  position: absolute; inset: 0; z-index: -1; opacity: 0.18;
  background-image:
    linear-gradient(rgba(255,255,255,0.09) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.09) 1px, transparent 1px);
  background-size: 76px 76px;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, rgba(0,0,0,0.5) 46%, transparent 83%);
          mask-image: linear-gradient(90deg, #000 0%, rgba(0,0,0,0.5) 46%, transparent 83%);
}

/* Tastaturbedienung */
.ap-skip-link {
  position: absolute; left: -9999px;
  background: var(--ap-navy-deep); color: #fff; padding: 12px 20px; z-index: 100;
}
.ap-skip-link:focus { left: 16px; top: 16px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  .ap-card--interactive:hover { transform: none; }
}
