@layer reset, tokens, base, layout, components, utilities;

@layer tokens {
  /* Console ist das einzige Thema (Plan 6). Es gibt keinen zweiten Zweig auf die
     Farbschema-Vorliebe des Systems: eine helle Variante waere kein Token-Tausch,
     sondern ein zweiter Entwurf — Lime auf Weiss erreicht 1,3:1 und braeuchte eigenen
     Akzent, eigene Code-Palette, eigene Schatten. Die Angabe color-scheme sagt dem
     Browser, wie er Rollbalken und Formular-Chrome zeichnet. */
  :root {
    color-scheme: dark;

    --c-bg: #0b0e12;
    --c-surface: #0f1319;
    /* Die dritte Flaeche traegt genau fuenf Dinge, und alle fuenf lesen sie auch:
       .site-footer, .tabs__list, .calc, .sample__cell und .docs__body pre. Bis zur
       Schlusswelle stand das hier als Absicht, hielt sich aber nur die Fusszeile daran.
       Sie ist die HELLSTE Flaeche und damit die knappste: --c-control-border erreicht
       darauf genau 3,00:1 (WCAG 1.4.11), --c-text-dim 4,75:1 (Text 14,79, muted 7,69).
       Aufhellen geht nicht — schon #191e26 druecke dim auf 4,38:1, den Rand auf 2,77:1.
       Der Helligkeitsschritt bleibt damit zart: 1,07:1 gegen --c-bg, 1,03:1 gegen
       --c-surface. Wo sie IN einem Panel liegt, traegt ihre Kante deshalb zusaetzlich
       eine --c-line-Trennlinie; die Flaeche allein waere dort zu leise. */
    --c-surface-2: #12161c;
    --c-line: #1c2129;
    --c-line-strong: #262c36;
    /* Raender von Bedienelementen brauchen 3:1 (WCAG 1.4.11). Der Artboard-Wert #2a313c
       erreicht 1,5:1 — er bleibt fuer dekorative Linien, nie fuer ein Bedienelement. */
    --c-control-border: #596377;
    --c-border: var(--c-line);

    --c-text: #e6e8ec;
    --c-text-strong: #ffffff;
    --c-text-muted: #a3a9b5;
    /* Angehoben vom Artboard-Wert #6f7784 (4,28:1) auf 5,06:1 — siehe Kontrolltabelle. */
    --c-text-dim: #7b8391;
    --c-code: #c9cfd8;

    --c-accent: #c6f135;
    --c-accent-hover: #dbff5c;
    /* Flaeche, kein Text: --c-accent-weak traegt ausschliesslich starken oder
       akzentuierten Text (Ruling R9). --c-text-dim erreicht darauf nur 4,22:1 und
       steht deshalb nie auf dieser Flaeche; Weiss, --c-text und der Akzent bestehen. */
    --c-accent-weak: #1a2130;
    --c-on-accent: #0b0e12;
    --c-code-string: #ffd166;
    --c-code-key: #8ab4ff;

    --c-success: #57c98a;
    --c-warning: #e2a34a;
    --c-danger: #ff8a80;

    --s-1: .25rem; --s-2: .5rem; --s-3: .75rem; --s-4: 1rem;
    --s-5: 1.5rem; --s-6: 2rem; --s-7: 3rem; --s-8: 4rem;
    --r-1: 6px; --r-2: 10px; --r-3: 12px;

    /* Die selbst gehosteten Familien (public/assets/fonts/fonts.css, erzeugt von
       `bin/console fonts:fetch`) mit metrisch angepasstem Fallback vor dem System-Stack:
       fehlen die WOFF2-Dateien, greift der Stack still. Eine Familie fuer die
       Oberflaeche, eine fuer Zahlen und Code. --f-display bleibt als Alias bestehen,
       damit bestehende Regeln nicht brechen — Displaywirkung entsteht ueber Groesse,
       Gewicht und Laufweite, nicht ueber eine zweite Familie. */
    --f-ui: "Space Grotesk", "Space Grotesk Fallback", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --f-display: var(--f-ui);
    --f-mono: "JetBrains Mono", "JetBrains Mono Fallback", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --shadow-1: 0 30px 80px rgb(0 0 0 / .5);
    --grid-line: rgb(255 255 255 / .035);
    --tap: 44px;
    /* Ein Token, kein Literal: dieselbe Hoehe steht im sticky-Versatz von allem, was
       unter der Kopfleiste kleben bleibt (FAQ-Kopf, Inhaltsverzeichnis). Sie stand bis
       zur Schlusswelle in einem zweiten :root im Marketing-Blatt. */
    --header-h: 64px;
  }
}

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  body, h1, h2, h3, p, figure, ul, ol, table { margin: 0; }
  ul, ol { padding: 0; list-style: none; }
  img, svg { display: block; max-width: 100%; }
  button, input, select, textarea { font: inherit; color: inherit; }
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  }
}

@layer base {
  body {
    margin: 0;
    background: var(--c-bg);
    color: var(--c-text);
    font-family: var(--f-ui);
    font-size: 16px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    -webkit-text-size-adjust: 100%;
  }
  /* Zusammensetzungen wie "Datenschutzerklaerung" sind bei 42px breiter als ein 342px-Blatt
     und schoben die ganze Seite waagerecht. hyphens trennt sie an der Silbe (das lang-Attribut
     steht am <html>), overflow-wrap ist der Riegel fuer den Fall, dass der Browser keine
     Trennmuster fuer diese Sprache hat. */
  h1, h2, h3 { color: var(--c-text-strong); font-weight: 700; hyphens: auto; overflow-wrap: break-word; }
  h1 { font-size: clamp(2rem, 1.4rem + 2.6vw, 2.75rem); line-height: 1.05; letter-spacing: -.03em; }
  h2 { font-size: clamp(1.25rem, 1.1rem + .6vw, 1.5rem); line-height: 1.2; letter-spacing: -.02em; }
  h3 { font-size: 1.05rem; font-weight: 500; letter-spacing: -.01em; }
  /* Ruling R10: Verweise im Fliesstext tragen dauerhaft eine Unterstreichung — Farbe
     allein darf keine Bedeutung tragen (WCAG 1.4.1). Schaltflaechen und Navigation
     nehmen sie in ihren eigenen Regeln zurueck; die liegen in einer spaeteren
     Kaskadenschicht und gewinnen ohne !important. */
  a { color: var(--c-accent); text-decoration: underline; text-underline-offset: .2em; }
  a:hover { color: var(--c-accent-hover); }
  code, pre, .mono { font-family: var(--f-mono); font-size: .9em; }
  :focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; border-radius: var(--r-1); }
  /* Der Sprungverweis ist unsichtbar, bis er den Fokus hat — dann ist er das erste
     Bedienziel der Seite und traegt dieselbe Mindestgroesse wie jedes andere. */
  .skip-link { position: absolute; left: -9999px; display: inline-flex; align-items: center; min-height: var(--tap); }
  .skip-link:focus { left: var(--s-4); top: var(--s-4); z-index: 10; background: var(--c-surface); color: var(--c-text-strong); padding: var(--s-2) var(--s-3); border-radius: var(--r-2); }
  .muted { color: var(--c-text-muted); }
  .visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

@layer layout {
  .plain__main, .auth__card { max-width: 42rem; margin: 0 auto; padding: var(--s-7) var(--s-4); }
  .auth__card { max-width: 26rem; background: var(--c-surface); border: 1px solid var(--c-line); border-radius: var(--r-3); margin-top: var(--s-7); box-shadow: var(--shadow-1); }
  .auth__brand { margin: 0; font-family: var(--f-mono); font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--c-text-dim); }
  .auth__alt { font-size: .9rem; }
  /* Fliessabstand am Container, nicht am Kind: der Reset hat jedem Block sein margin
     genommen. Die Ausnahmen stehen bewusst DANACH — gleiche Spezifitaet, spaetere Regel
     gewinnt. */
  .auth__card > * + * { margin-top: var(--s-4); }
  .auth__brand + .auth__title { margin-top: var(--s-2); }
  .auth__title + * { margin-top: var(--s-5); }
  .auth__alt + .auth__alt { margin-top: var(--s-2); }

  .shell { min-height: 100vh; display: grid; grid-template-rows: auto 1fr; }
  .shell__main { padding: var(--s-5) var(--s-4) var(--s-8); max-width: 76rem; margin: 0 auto; width: 100%; }
  .page__head { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: baseline; justify-content: space-between; }
  /* Karten und Gitter stossen sonst Rahmen an Rahmen aneinander: weder .card noch der
     Reset bringt einen Abstand mit. Mass wie das frueher einzelne margin-bottom der
     Kopfzeile — nur fuer JEDEN Uebergang statt nur den ersten. */
  .shell__main > * + * { margin-top: var(--s-5); }

  .grid { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
  @media (min-width: 768px) { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
  @media (min-width: 1024px) { .grid--3 { grid-template-columns: repeat(3, 1fr); } .shell__main { padding-inline: var(--s-6); } }
  @media (min-width: 1440px) { .shell__main { max-width: 84rem; } }
}

@layer components {
  .topbar { background: var(--c-surface); border-bottom: 1px solid var(--c-line); }
  .topbar__inner { max-width: 76rem; margin: 0 auto; padding: var(--s-3) var(--s-4); display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; justify-content: space-between; }
  /* Die Marke ist ein Verweis nach /app und muss als solcher greifbar sein: 46x25px war
     ein Ziel fuer die Maus, keins fuer den Daumen (WCAG 2.5.5 nennt 44px). Der negative
     Aussenabstand haelt die Leiste dabei genau so hoch wie vorher. */
  .topbar__brand { display: inline-flex; align-items: center; min-height: var(--tap); margin-block: calc(var(--s-2) * -1); padding-inline: var(--s-2); margin-inline-start: calc(var(--s-2) * -1); border-radius: var(--r-1); font-weight: 700; letter-spacing: -.02em; color: var(--c-text-strong); text-decoration: none; }
  .nav { display: flex; flex-wrap: wrap; gap: var(--s-1); }
  .nav__link { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 var(--s-3); border-radius: var(--r-1); color: var(--c-text-muted); text-decoration: none; }
  /* Frueher die zweite Flaeche — die ist im Console-Thema dieselbe wie die der Leiste,
     der Hinweis auf den Zeiger waere damit unsichtbar geworden. */
  .nav__link:hover { background: var(--c-accent-weak); color: var(--c-text); }
  .nav__link[aria-current="page"] { background: var(--c-accent-weak); color: var(--c-accent); font-weight: 600; }

  .card { background: var(--c-surface); border: 1px solid var(--c-line); border-radius: var(--r-3); padding: var(--s-5); container-type: inline-size; }
  .card__title { font-family: var(--f-mono); font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: var(--c-text-dim); }
  /* Dieselbe Regel eine Ebene tiefer: Titel, Kennzahl, Text, Formulare und Tabellen
     stapeln sich in der Karte, alle mit `margin: 0`. Eine Zwischenueberschrift beginnt
     einen neuen Abschnitt und bekommt mehr Luft. */
  .card > * + * { margin-top: var(--s-3); }
  .card > * + :is(h2, h3) { margin-top: var(--s-5); }
  .stat { font-family: var(--f-mono); color: var(--c-text-strong); font-size: 2rem; line-height: 1.1; }
  @container (min-width: 30rem) { .stat { font-size: 2.6rem; } }

  .button { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: var(--tap); padding: 0 var(--s-4); border: 1px solid var(--c-control-border); border-radius: var(--r-1); background: transparent; color: var(--c-text-strong); text-decoration: none; font-weight: 600; cursor: pointer; }
  .button:hover { border-color: var(--c-text-muted); background: var(--c-accent-weak); }
  .button--primary { background: var(--c-accent); border-color: var(--c-accent); color: var(--c-on-accent); font-weight: 700; }
  .button--primary:hover { background: var(--c-accent-hover); border-color: var(--c-accent-hover); color: var(--c-on-accent); }
  .button--danger { color: var(--c-danger); border-color: var(--c-danger); }
  .button[disabled], .button[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }

  .form { display: grid; gap: var(--s-4); }
  .field__label { display: block; font-weight: 600; margin-bottom: var(--s-1); }
  /* Ein Kaestchen von 13px ist auf dem Telefon kaum zu treffen. Die Beschriftung daneben
     schaltet ohnehin mit, aber das Kaestchen selbst muss sichtbar und greifbar sein. */
  input[type="checkbox"], input[type="radio"] { width: 1.15rem; height: 1.15rem; accent-color: var(--c-accent); }
  .field__check { display: flex; align-items: center; gap: var(--s-3); min-height: var(--tap); font-weight: 600; }
  /* Bare `select` statt `.field select`: der Team-Umschalter in der Kopfleiste steht in
     keinem .field und traege sonst das Chrome des Systems. */
  .field__input, select, textarea { min-height: var(--tap); padding: var(--s-2) var(--s-3); border: 1px solid var(--c-control-border); border-radius: var(--r-1); background: var(--c-bg); color: var(--c-text); }
  .field__input, .field select, textarea { width: 100%; }
  /* Wo der Browser den eigenen Klapp-Pfeil hinzeichnet, entscheidet er selbst — in
     Safari sass er auf dem Rahmen. Also zeichnen wir ihn: zwei Farbverlaeufe ergeben das
     Dreieck, `currentColor` nimmt die Textfarbe (keine Farbe literal, keine CSP-Ausnahme),
     `background-position` setzt den Abstand. Der rechte Innenabstand haelt den Text frei.
     `select.field__input` muss mit dabei stehen: `.field__input` (0,1,0) schlaegt ein
     blankes `select` (0,0,1) — sonst kaeme nur `appearance` an. */
  select, select.field__input { -webkit-appearance: none; appearance: none; padding-right: var(--s-6); background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: right 17px top calc(50% - 1px), right 12px top calc(50% - 1px); background-size: 5px 5px; background-repeat: no-repeat; }
  .field__input::placeholder, textarea::placeholder { color: var(--c-text-dim); }
  textarea { min-height: 8rem; font-family: var(--f-mono); }
  .field--invalid .field__input { border-color: var(--c-danger); }
  .field__error { margin-top: var(--s-1); color: var(--c-danger); font-size: .9rem; }
  .field__hint, .form__note { margin-top: var(--s-1); color: var(--c-text-muted); font-size: .9rem; }

  .flashes { display: grid; gap: var(--s-2); }
  .flash { padding: var(--s-3); border-radius: var(--r-2); border: 1px solid var(--c-line-strong); background: var(--c-surface); }
  .flash--success { border-color: var(--c-success); color: var(--c-success); }
  .flash--error { border-color: var(--c-danger); color: var(--c-danger); }
  .notice { background: var(--c-surface); border: 1px solid var(--c-line); border-radius: var(--r-3); padding: var(--s-6); }
  .notice--error { border-color: var(--c-danger); }

  /* Der doppelte Schraegstrich der Augenbraue wird genau EINMAL gebaut: hier, hinter einer
     Modifier-Klasse. Vorher gab es ihn dreimal — als seitenbezogenen Selektor, als Text in
     vier Sprachwerten, und auf /pricing gar nicht. Die Regel steht in app.css, weil die
     Fehlerseite dieselbe Zierde traegt und ohne marketing.css auskommt (Ruling R2).
     Der Alternativtext haelt die Zierde aus dem Baum der Barrierefreiheit heraus; kennt der
     Browser die Schreibweise nicht, bleibt die erste Regel: lieber vorgelesen als weg. */
  .eyebrow--mark::before { content: "// "; }
  @supports (content: "a" / "b") { .eyebrow--mark::before { content: "// " / ""; } }

  /* Ruling R2: EINE Fehlervorlage fuer BEIDE Layouts. Sie steht deshalb hier und nicht in
     marketing.css — unter /app und im Auth-Flow ist jenes Blatt gar nicht geladen, und eine
     Fehlerseite, die im schlanken Layout auf unformatierten Fliesstext zurueckfaellt, ist
     genau dort kaputt, wo sie am noetigsten ist. Das Panel bringt seinen eigenen Rand mit,
     weil das Marketing-Layout kein .wrap um den Inhalt legt. */
  .errorpage { max-width: 44rem; margin-inline: auto; padding: var(--s-7) var(--s-4) var(--s-8); }
  /* Im schlanken Layout liegt das Panel schon in .plain__main — dessen Rand genuegt. */
  .plain__main > .errorpage { padding: 0; }
  .errorpage__eyebrow { font-weight: 500; font-size: .75rem; letter-spacing: .12em; text-transform: uppercase; color: var(--c-accent); margin: 0 0 var(--s-3); }
  .errorpage__title { margin: 0; letter-spacing: -.035em; }
  .errorpage__lede { font-size: 1.125rem; line-height: 1.5; color: var(--c-text-muted); max-width: 35em; margin: var(--s-4) 0 var(--s-5); }
  .errorpage__links { display: grid; gap: var(--s-1); margin-top: var(--s-2); }
  /* Die Unterstreichung bleibt (Ruling R10): das hier ist Fliesstext, keine Navigationsleiste. */
  .errorpage__links a { display: inline-flex; align-items: center; min-width: var(--tap); min-height: var(--tap); }
  .errorpage__id { margin-top: var(--s-6); font-size: .75rem; color: var(--c-text-dim); }

  /* Die Kostenaufstellung der Bestaetigungsseite (Plan 3, Task 10). Zwei Spalten, die
     Betraege rechtsbuendig und mit Tabellenziffern: eine Summe, deren Kommastellen nicht
     untereinander stehen, laedt zum Verlesen ein — und genau das darf hier nicht
     passieren. Die Gesamtzeile ist abgesetzt, damit klar ist, welche Zahl abgeht. */
  .summary { display: grid; grid-template-columns: 1fr auto; gap: var(--s-2) var(--s-4); }
  .summary dd { font-variant-numeric: tabular-nums; text-align: right; }
  .summary__total { padding-top: var(--s-2); border-top: 1px solid var(--c-line-strong); font-weight: 700; color: var(--c-text-strong); }
  /* Der Umrechnungshinweis ist kein Kleingedrucktes: er steht in voller Textfarbe und
     mit einer Kante daneben, weil er die einzige Stelle ist, an der der Kunde den
     wirklich eingezogenen Betrag zu sehen bekommt. */
  .checkout__fx { border-left: 2px solid var(--c-accent); padding-left: var(--s-4); }

  .table { width: 100%; border-collapse: collapse; }
  .table th, .table td { text-align: left; padding: var(--s-3) var(--s-2); border-bottom: 1px solid var(--c-line); }
  .table th { font-family: var(--f-mono); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--c-text-dim); font-weight: 600; }
  @media (max-width: 767px) {
    .table, .table tbody, .table tr, .table td { display: block; }
    .table thead { display: none; }
    .table tr { border: 1px solid var(--c-line); border-radius: var(--r-2); margin-bottom: var(--s-3); padding: var(--s-2); }
    .table td { border: 0; display: flex; justify-content: space-between; gap: var(--s-3); }
    .table td::before { content: attr(data-label); color: var(--c-text-dim); font-family: var(--f-mono); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; }
  }

  .chart { overflow: visible; }
  .chart__bar { fill: var(--c-accent); }
  .chart__label, .chart__empty { fill: var(--c-text-muted); font-size: 11px; font-family: var(--f-ui); }
  /* Die Spur traegt Bedeutung (sie zeigt das Kontingent), also 3:1 statt einer
     dekorativen Linie: --c-line-strong laege auf der Karte bei 1,3:1. */
  .chart__meter-track { fill: var(--c-control-border); }
  .chart__meter-fill { fill: var(--c-accent); }
  .chart__meter--over .chart__meter-fill { fill: var(--c-danger); }

  .key { font-family: var(--f-mono); background: var(--c-bg); border: 1px solid var(--c-line-strong); border-radius: var(--r-2); color: var(--c-code); padding: var(--s-3); word-break: break-all; }
  .badge { display: inline-block; padding: 0 var(--s-2); border-radius: var(--r-1); font-size: .8rem; background: var(--c-accent-weak); border: 1px solid var(--c-line-strong); }
  .badge--revoked { color: var(--c-danger); border-color: var(--c-danger); }
  pre.code { overflow-x: auto; padding: var(--s-3); background: var(--c-bg); border: 1px solid var(--c-line-strong); border-radius: var(--r-2); color: var(--c-code); }

  /* Die vier .hero*-Regeln sind mit Plan 6 in marketing.css umgezogen. Sie standen hier
     falsch: app.css laedt JEDE Seite, .hero gibt es nur auf der Startseite. Zuletzt war
     das ein Fehler und keine Doppelung mehr — seit die Polsterung auf .hero__bg liegt,
     stapelte sich das padding-block von hier mit der Marketing-Regel (oben 144px, davon
     48px ausserhalb des Rasterhintergrunds, unten 48px tote Flaeche vor dem Sprachband).
     .hero__eyebrow und .hero__lead hatte ohnehin kein Template mehr benutzt. */
}

@layer utilities {
  .stack > * + * { margin-top: var(--s-4); }
  .row { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }
  .right { margin-left: auto; }
  .nowrap { white-space: nowrap; }
  .num { font-family: var(--f-mono); font-variant-numeric: tabular-nums; }
  /* Ein Verweis, der allein in seiner Zeile oder als Kartentitel steht, ist ein Bedienziel und
     kein Fliesstext: die Ausnahme fuer Verweise IM Satz (WCAG 2.5.8) gilt fuer ihn nicht. */
  .link--target { display: inline-flex; align-items: center; min-width: var(--tap); min-height: var(--tap); }
}
