/* design-components.css — Designsystem Handoff v1, Bausteine (Block 2).
   ==================================================================
   Setzt voraus: design-tokens.css (Block 0) und design-base.css (Block 1).

   REGEL DIESER DATEI
   Kein eigener Farbwert, kein eigener Radius, kein eigener Schatten, kein
   eigener Abstand. Alles kommt aus --ak-*. Ein Test erzwingt das. Sonst
   entstuende eine zweite Wahrheit neben der Tokenebene, und genau daran
   zerfallen Designsysteme.

   Ausnahme: die Strichzeichnungen der Icons stehen als SVG in
   mask-image-Angaben. Das `black` darin ist keine Farbe, sondern eine
   Schablone — die sichtbare Farbe kommt aus background-color und damit
   aus den Tokens.

   ZWEI GRUNDSAETZE DES HANDOFFS, DIE HIER DURCHGEZOGEN WERDEN

   1. Farbe traegt NIE allein die Bedeutung. Jeder Zustand hat zusaetzlich
      ein Icon und ein Textlabel. Wer nur die Farbe setzt, hat den Zustand
      nicht gebaut. Das ist keine Empfehlung, sondern die
      Barrierefreiheitszusicherung des Designs.

   2. Auswahl und Ergebnis teilen sich nie einen Stil. „Ich habe das
      angeklickt" und „das war richtig" muessen unterscheidbar bleiben,
      auch fuer jemanden, der die Farben nicht unterscheiden kann.

   GELTUNGSBEREICH
   Alle Klassen tragen das Praefix .ak-. Es gibt keinen globalen Selektor,
   der bestehende Seiten veraendern koennte. Diese Datei ist wie Block 0
   und 1 noch von KEINER Vorlage eingebunden.

   NAMENSSCHEMA
     .ak-btn              Baustein
     .ak-btn--primary     Variante
     .ak-btn.is-loading   Zustand (kommt vom Server oder vom Nutzer) */


/* ══ 1 · ICONS ══════════════════════════════════════════════════════════
   Ikonografie des Handoffs: 24x24-Feld, Strichstaerke 1.9 (2.4 bei Haken
   und Kreuz), runde Enden und Ecken, fill="none".

   Technik: CSS-Masken mit inline-SVG als data-URI — dasselbe Verfahren,
   das schon die fruehere App-Huelle nutzte. Vorteile gegenueber <img>: das Icon
   erbt die Textfarbe ueber background-color und braucht keine zweite
   Datei. CSP-konform (img-src 'self' data:).

   Groessen nach Handoff: 13px inline in Navigation, 15-17px in Knoepfen
   und Listenzeilen, 19-22px in Icon-Plaettchen, 24-27px in Abzeichen. */

.ak-ic {
  display: inline-block;
  width: 1em; height: 1em;
  flex: none;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  vertical-align: -0.125em;
}
.ak-ic--sm { width: 15px; height: 15px; }
.ak-ic--md { width: 17px; height: 17px; }
.ak-ic--lg { width: 21px; height: 21px; }
.ak-ic--xl { width: 26px; height: 26px; }

/* Dekoratives Icon bekommt aria-hidden="true" im Markup. Ein Icon, das
   ALLEIN eine Aktion traegt, braucht dagegen einen zugaenglichen Namen —
   dafuer .ak-sr aus der Basisschicht im Knopf. */

.ak-ic--check   { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M4 12.5l5 5L20 6.5'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M4 12.5l5 5L20 6.5'/></svg>"); }
.ak-ic--cross   { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M7 7l10 10M17 7L7 17'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M7 7l10 10M17 7L7 17'/></svg>"); }
.ak-ic--info    { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9'/><path d='M12 11v5M12 8h.01'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9'/><path d='M12 11v5M12 8h.01'/></svg>"); }
.ak-ic--warn    { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4.5 21 19H3z'/><path d='M12 10v4M12 17h.01'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4.5 21 19H3z'/><path d='M12 10v4M12 17h.01'/></svg>"); }
.ak-ic--lock    { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><rect x='4.5' y='10' width='15' height='10' rx='2.5'/><path d='M8 10V7.5a4 4 0 0 1 8 0V10'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><rect x='4.5' y='10' width='15' height='10' rx='2.5'/><path d='M8 10V7.5a4 4 0 0 1 8 0V10'/></svg>"); }
.ak-ic--refresh { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M20 12a8 8 0 1 1-2.4-5.7M20 4v4h-4'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M20 12a8 8 0 1 1-2.4-5.7M20 4v4h-4'/></svg>"); }
.ak-ic--search  { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='6.5'/><path d='m16 16 4 4'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='6.5'/><path d='m16 16 4 4'/></svg>"); }
.ak-ic--bulb    { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M9 18h6M12 3a6 6 0 0 1 4 10.5V16H8v-2.5A6 6 0 0 1 12 3Z'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M9 18h6M12 3a6 6 0 0 1 4 10.5V16H8v-2.5A6 6 0 0 1 12 3Z'/></svg>"); }
.ak-ic--dot     { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='5' fill='black'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='5' fill='black'/></svg>"); }
.ak-ic--circle  { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9'><circle cx='12' cy='12' r='7'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9'><circle cx='12' cy='12' r='7'/></svg>"); }
.ak-ic--menu    { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round'><path d='M4 7h16M4 12h16M4 17h16'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round'><path d='M4 7h16M4 12h16M4 17h16'/></svg>"); }
.ak-ic--chevron { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>"); }
.ak-ic--jar     { -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M7 8h10l-.8 10.6A2.4 2.4 0 0 1 13.8 21h-3.6a2.4 2.4 0 0 1-2.4-2.4L7 8Z'/><path d='M8 4.5h8a1 1 0 0 1 1 1V8H7V5.5a1 1 0 0 1 1-1ZM10 6h4'/></svg>"); mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M7 8h10l-.8 10.6A2.4 2.4 0 0 1 13.8 21h-3.6a2.4 2.4 0 0 1-2.4-2.4L7 8Z'/><path d='M8 4.5h8a1 1 0 0 1 1 1V8H7V5.5a1 1 0 0 1 1-1ZM10 6h4'/></svg>"); }

/* Icon-Plaettchen: Icon auf getoenter Flaeche, wie im Handoff durchgaengig. */
.ak-ic-chip {
  display: grid; place-items: center;
  width: 44px; height: 44px; flex: none;
  border-radius: var(--ak-r-btn);
  background: var(--ak-accent-soft);
  color: var(--ak-accent-deep);
}


/* ══ 2 · BUTTONS ════════════════════════════════════════════════════════ */

/* M3: Werte aus der SSOT, Abschnitt 5. Eigene Zutaten sind nur die drei,
   die unser Markup braucht und die die SSOT in ihrem eigenen Reset
   erledigt: der durchsichtige 1,5px-Rand (sonst springt das Layout,
   sobald eine Variante einen Rand setzt), position und cursor. */
.ak-btn {
  color: var(--ak-ink);          /* N1 der SSOT: jede Variante nennt ihre Farbe */
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--ak-s2);
  position: relative;
  min-height: var(--ak-tap-min);
  padding: 13px 22px;
  border: 1.5px solid transparent;
  border-radius: var(--ak-r-input);
  white-space: nowrap;
  /* KEINE font-family hier. Sie kommt aus .ak und wird damit vererbt.
     Gemessen: mit `font-family: var(--ak-font-body)` an dieser Stelle
     schlug .ak-btn (0,1,0, spaeter geladen) die Rolle .ak-de--inline
     (0,1,0, frueher geladen) — ein Knopf mit deutschem Text stand dann
     in der tuerkischen Familie. Ein Knopf hat keine eigene Sprache; die
     Sprache bestimmt der Inhalt. */
  font-size: var(--ak-fs-md); font-weight: var(--ak-fw-semibold); line-height: 1.2;
  text-align: center; text-decoration: none;
  cursor: pointer;
  transition: background var(--ak-dur-fast), border-color var(--ak-dur-fast),
              color var(--ak-dur-fast), transform var(--ak-dur-fast);
}

/* Primaer — dunkel mit Schatten, die eine Hauptaktion je Bereich. */
.ak-btn--primary {
  background: var(--ak-ink); color: var(--ak-on-fill);
  box-shadow: var(--ak-sh-button);
}
.ak-btn--primary:hover { background: var(--ak-dark-3); color: var(--ak-on-fill); }

/* Sekundaer — Umriss auf heller Flaeche. */
/* Sekundaer: Rand auf --ak-line-input. WCAG 1.4.11 verlangt 3:1 fuer die
   Umrandung eines Bedienelements; --ak-line ist ein dekorativer Haarstrich
   (1,3:1) und reicht dafuer nicht. Genau diese Trennung fuehrt die SSOT. */
.ak-btn--secondary {
  background: var(--ak-surface); color: var(--ak-ink);
  border-color: var(--ak-line-input);
}
.ak-btn--secondary:hover { border-color: var(--ak-ink); color: var(--ak-ink); }

/* Tertiaer / flach — keine Flaeche, kein Rahmen. Traegt „Atla".
   ink-2 statt ink-3: gemessen erreichte ink-3 auf dem Cremegrund nur
   2.87:1 und verfehlte damit AA. „Atla" ist eine echte Aktion und muss
   lesbar sein — nicht dezent bis zur Unkenntlichkeit. */
.ak-btn--ghost { background: none; color: var(--ak-link); padding-inline: var(--ak-s2); }
.ak-btn--ghost:hover { background: var(--ak-surface-warm); color: var(--ak-link-hover); }

/* Akzent — Lila. Sparsam: fuer Aktionen, die zum Lernweg gehoeren. */
.ak-btn--accent { background: var(--ak-a1-solid); color: var(--ak-on-fill); }
.ak-btn--accent:hover { background: var(--ak-accent-deep); color: var(--ak-on-fill); }

/* Destruktiv — nur wo das Produkt es wirklich braucht: Konto loeschen,
   Abo kuendigen. Bewusst als Umriss, nicht als rote Flaeche: eine grosse
   rote Flaeche laedt zum versehentlichen Klicken ein. */
.ak-btn--danger {
  background: var(--ak-error-soft); color: var(--ak-error-fg);
  border-color: var(--ak-error-border);
}
/* Die SSOT nennt fuer den Umriss-Danger keinen Schwebezustand. Statt einen
   Farbwert zu erfinden, verstaerkt der Schwebezustand den vorhandenen
   Rand auf --ak-error. Kein neuer Wert, nur ein vorhandener Token. */
.ak-btn--danger:hover { border-color: var(--ak-error); color: var(--ak-error-fg); }

/* display:flex zusaetzlich zur SSOT: unsere Blockknoepfe stehen teils als
   <a>, und ein inline-flex-Element fuellt die Zeile nicht. */
.ak-btn--block   { display: flex; width: 100%; }

/* Groessen der SSOT. --compact bleibt daneben bestehen, weil der Player sie
   erzeugt; sie ist enger als --sm und hat kein Gegenstueck in der SSOT. */
.ak-btn--lg { padding: 16px 28px; font-size: var(--ak-fs-base-lg); border-radius: var(--ak-r-button-lg); }
.ak-btn--sm { padding: 10px 16px; font-size: var(--ak-fs-caption); min-height: 38px; border-radius: var(--ak-r-chip); }
.ak-btn--compact { padding: 9px var(--ak-sp-4); font-size: var(--ak-fs-body-sm); }

/* Icon-Knopf — quadratisch. Braucht IMMER einen zugaenglichen Namen,
   entweder aria-label oder ein .ak-sr im Inneren. */
.ak-btn--icon {
  padding: 0; width: 42px; height: 42px;
  border-radius: var(--ak-r-btn);
}

/* Deaktiviert.
   `disabled` nimmt das Element aus der Tastaturreihenfolge — richtig fuer
   Knoepfe, die es JETZT nicht gibt. Wo der Nutzer erfahren soll, WARUM
   etwas nicht geht, nimmt man stattdessen aria-disabled="true": das
   Element bleibt fokussierbar und vorlesbar. Beide sehen gleich aus. */
/* Deaktiviert — Flaeche und Rand aus der SSOT, Textfarbe eine Stufe
   dunkler als dort.
   Die SSOT setzt --ak-ink-4 auf --ak-line; gemessen ergibt das 4,29:1.
   Fuer ein ausgegrautes Formularfeld waere das zulaessig, WCAG nimmt
   inaktive Bedienelemente aus. Unsere deaktivierten Knoepfe TRAGEN aber
   Information („Hazırlanıyor", „Geri" am ersten Schritt) — sie sind der
   einzige Hinweis, warum es hier nicht weitergeht. Deshalb --ak-ink-2
   (4,95:1). Unterschieden werden sie ueber Flaeche, fehlenden Schatten
   und den Zeiger, nicht ueber blasse Schrift. Dieselbe Abwaegung wie in
   Block A bei den Navigationszustaenden, und dieselbe, mit der die SSOT
   selbst dreizehn eigene Farbpaare nachgezogen hat. */
.ak-btn:disabled,
.ak-btn[aria-disabled="true"] {
  background: var(--ak-line);
  color: var(--ak-ink-2);
  border-color: var(--ak-line);
  box-shadow: none;
  cursor: not-allowed;
}

/* Ladezustand — OHNE Layoutsprung.
   Die Beschriftung bleibt stehen und wird nur unsichtbar; der Ring liegt
   mittig darueber. Wuerde man den Text ersetzen, aenderte sich die
   Knopfbreite und alles daneben wuerde springen. */
.ak-btn.is-loading { color: transparent; pointer-events: none; }
.ak-btn.is-loading::after {
  content: "";
  position: absolute; top: 50%; left: 50%;
  width: 18px; height: 18px; margin: -9px 0 0 -9px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--ak-r-pill);
  animation: akSpin .7s linear infinite;
}
.ak-btn--primary.is-loading::after,
.ak-btn--accent.is-loading::after { border-color: var(--ak-on-fill); border-top-color: transparent; }
.ak-btn--secondary.is-loading::after,
.ak-btn--ghost.is-loading::after  { border-color: var(--ak-ink); border-top-color: transparent; }

@keyframes akSpin { to { transform: rotate(360deg) } }


/* ══ 3 · KARTEN ═════════════════════════════════════════════════════════
   Eine Karte ist von sich aus NICHT interaktiv. Nur .ak-card--action
   bekommt Zustaende — sonst suggeriert jede Karte Klickbarkeit, und der
   Nutzer klickt ins Leere. */

/* M3: Werte aus der SSOT, Abschnitt 7. Die SSOT traegt den Schatten NICHT
   in .ak-card, sondern in .ak-card--raised — eine schlichte Karte ist dort
   flach. Das Markup bleibt unveraendert: von unseren sieben Kartenstellen
   bringen --lg und --dark ihren Schatten selbst mit, und --compact und
   --feature sind in der SSOT flach gemeint. Wer einen Schatten will,
   schreibt --raised dazu, statt ihn jeder Karte mitzugeben. */
.ak-card {
  background: var(--ak-surface);
  border: 1px solid var(--ak-line);
  border-radius: var(--ak-r-card);
  padding: var(--ak-card-pad-sm);
}
.ak-card--raised  { box-shadow: var(--ak-sh-card); border-radius: var(--ak-r-card-lg); padding: var(--ak-card-pad); }
.ak-card--hero    { box-shadow: var(--ak-sh-card-lg); border-radius: var(--ak-r-panel); padding: var(--ak-card-pad); }
.ak-card--flat    { box-shadow: none; border-radius: var(--ak-r-row); }
.ak-card--compact { padding: var(--ak-card-pad-sm); border-radius: var(--ak-r-row); }
.ak-card--lg      { border-radius: var(--ak-r-panel); box-shadow: var(--ak-sh-card-lg); }

/* Hervorgehoben — lila Tonung, fuer den einen Punkt, der zaehlt. */
.ak-card--feature {
  background: var(--ak-purple-1);
  border-color: var(--ak-purple-border-1);
}

/* Dunkel — die dunklen Panels des Handoffs. */
.ak-card--dark {
  background: var(--ak-dark);
  border-color: var(--ak-dark);
  color: var(--ak-on-dark);
  border-radius: var(--ak-r-card-lg);
}
.ak-card--dark .ak-meta { color: var(--ak-ink-inverse-2); }

/* Anklickbar. Als <a> oder <button> bauen, nie als div mit Klickhandler:
   sonst fehlen Tastaturbedienung, Rolle und Name. */
.ak-card--action {
  display: block; width: 100%; text-align: inherit;
  cursor: pointer;
  transition: border-color var(--ak-t-toggle) var(--ak-ease),
              box-shadow var(--ak-t-toggle) var(--ak-ease);
}
.ak-card--action:hover { border-color: var(--ak-accent); box-shadow: var(--ak-sh-card-lg); }

/* Gesperrt — gedaempft und nicht anklickbar. Die Karte MUSS zusaetzlich
   ein Schloss-Icon und das Wort „Kilitli" tragen; die Daempfung allein
   waere reine Farbcodierung. */
.ak-card--locked {
  opacity: .72;
  background: var(--ak-disabled-surface);
  border-color: var(--ak-disabled-border);
  box-shadow: none;
  cursor: not-allowed;
  pointer-events: none;
}

/* Statuskarte — farbiger Streifen links, in der Level- oder Statusfarbe. */
.ak-card--status { border-left: 5px solid var(--ak-line-strong); }
.ak-card--status.is-ok    { border-left-color: var(--ak-ok); }
.ak-card--status.is-warn  { border-left-color: var(--ak-warn); }
.ak-card--status.is-err   { border-left-color: var(--ak-err); }
.ak-card--status.is-info  { border-left-color: var(--ak-info); }


/* ══ 4 · CHIPS UND BADGES ═══════════════════════════════════════════════
   Semantisch getrennt, und das ist keine Feinheit:

     .ak-chip   ist ein STEUERELEMENT. Immer <button> oder <input>+<label>.
     .ak-badge  ist reine INFORMATION. Immer <span>. Nie klickbar.

   Ein <span>, der wie ein Knopf aussieht, ist fuer Tastatur und
   Vorleseprogramm unsichtbar. Deshalb hier die Trennung im Namen. */

/* M3: Werte aus der SSOT, Abschnitt 8. */
.ak-chip {
  display: inline-flex; align-items: center; gap: var(--ak-s2);
  min-height: var(--ak-tap-min);
  padding: 8px var(--ak-s4);
  border: 1.5px solid var(--ak-line-input);
  border-radius: var(--ak-r-pill);
  background: var(--ak-surface);
  color: var(--ak-ink-2);
  font-size: var(--ak-fs-xs); font-weight: var(--ak-fw-semibold);
  cursor: pointer;
  transition: background var(--ak-dur-fast), border-color var(--ak-dur-fast),
              color var(--ak-dur-fast);
}
.ak-chip:hover { border-color: var(--ak-ink-3); color: var(--ak-ink); }

/* Ausgewaehlt. Das Markup traegt zusaetzlich aria-pressed="true" (Filter)
   oder aria-selected — die Farbe allein sagt einem Vorleseprogramm nichts. */
/* Ausgewaehlt: die SSOT faerbt den aktiven Chip dunkel und invertiert die
   Schrift. Der verschachtelte Zaehler und das Icon muessen mitziehen —
   genau dort lag Blocker 4 des v2.1.1-Audits (3,62:1). */
.ak-chip[aria-pressed="true"],
.ak-chip.is-active,
.ak-chip.is-selected {
  background: var(--ak-ink);
  border-color: var(--ak-ink);
  color: var(--ak-on-fill);
}
.ak-chip[aria-pressed="true"] .ak-meta,
.ak-chip.is-active .ak-meta,
.ak-chip.is-selected .ak-meta,
.ak-chip[aria-pressed="true"] .ak-label,
.ak-chip.is-active .ak-label,
.ak-chip.is-selected .ak-label { color: var(--ak-on-dark-2); }
.ak-chip[aria-pressed="true"] svg,
.ak-chip.is-active svg,
.ak-chip.is-selected svg { color: var(--ak-on-fill); }
.ak-chip:disabled,
.ak-chip[aria-disabled="true"] {
  background: var(--ak-disabled-surface);
  border-color: var(--ak-disabled-border);
  color: var(--ak-disabled-text);
  cursor: not-allowed;
}
.ak-chip .ak-chip-count { font-variant-numeric: tabular-nums; opacity: .75; }

.ak-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: var(--ak-r-tag);
  font-size: var(--ak-fs-micro); font-weight: 700;
  letter-spacing: var(--ak-ls-micro); text-transform: uppercase;
  background: var(--ak-surface-warm); color: var(--ak-ink-2);
  border: 1px solid var(--ak-line);
}
.ak-badge--ok   { background: var(--ak-ok-surface);   color: var(--ak-ok-text);   border-color: var(--ak-ok-border); }
.ak-badge--warn { background: var(--ak-warn-surface); color: var(--ak-warn-text); border-color: var(--ak-warn-border); }
.ak-badge--err  { background: var(--ak-err-surface);  color: var(--ak-err-text);  border-color: var(--ak-err-border); }
.ak-badge--info { background: var(--ak-info-surface); color: var(--ak-info-text); border-color: var(--ak-info-border); }
.ak-badge--lock { background: var(--ak-disabled-surface); color: var(--ak-ink-2); border-color: var(--ak-disabled-border); }

/* Der Produktakzent als Abzeichen — die Referenz nutzt ihn fuer den
   laufenden Zustand („DEVAM EDİYOR"). */
.ak-badge--accent { background: var(--ak-accent-soft); color: var(--ak-accent-deep);
  border-color: var(--ak-purple-border-1); }

/* Levelabzeichen — sechs Level, feste Farben, kein A3.
   Outfit, weil es eine Zahl/Kuerzel ist. */
.ak-level {
  display: inline-grid; place-items: center;
  min-width: 44px; padding: 6px 10px;
  border-radius: var(--ak-r-btn);
  font-family: var(--ak-font-display);
  font-size: var(--ak-fs-xl); font-weight: var(--ak-fw-bold); line-height: 1;
}
.ak-level--a1 { background: var(--ak-a1-soft); color: var(--ak-a1-deep); }
.ak-level--a2 { background: var(--ak-a2-soft); color: var(--ak-a2-deep); }
.ak-level--b1 { background: var(--ak-b1-soft); color: var(--ak-b1-deep); }
.ak-level--b2 { background: var(--ak-b2-soft); color: var(--ak-b2-deep); }
.ak-level--c1 { background: var(--ak-c1-soft); color: var(--ak-c1-deep); }
.ak-level--c2 { background: var(--ak-c2-soft); color: var(--ak-c2-deep); }
.ak-level--locked { background: var(--ak-disabled-surface); color: var(--ak-disabled-text); }


/* ══ 5 · FORMULARFELDER ═════════════════════════════════════════════════
   Das Label bleibt IMMER sichtbar. Ein Platzhalter ist kein Label: er
   verschwindet beim Tippen, genau dann, wenn man ihn braucht, und viele
   Vorleseprogramme lesen ihn nicht als Namen. */

/* M3: Werte aus der SSOT, Abschnitt 6. */
.ak-field { display: grid; gap: 7px; }
.ak-label { font-size: var(--ak-fs-xs); font-weight: var(--ak-fw-semibold); color: var(--ak-ink); }
.ak-label .ak-req { color: var(--ak-err); }

.ak-input,
.ak-select,
.ak-textarea {
  width: 100%;
  padding: 14px 16px;
  /* --ak-line-input statt --ak-line: WCAG 1.4.11 verlangt 3:1 fuer die
     Umrandung eines Bedienelements. */
  border: 1.5px solid var(--ak-line-input);
  border-radius: var(--ak-r-input);
  background: var(--ak-surface);
  color: var(--ak-ink);
  font-family: var(--ak-font-body);
  font-size: var(--ak-fs-body);
  line-height: 1.5;
  outline: none;
  transition: border-color var(--ak-dur-fast), box-shadow var(--ak-dur-fast);
}
/* ── Auswahlfeld ──────────────────────────────────────────────────────
   P0-6 (02.08.2026). Bis heute stand hier nur Schriftschnitt und Polster.
   Gemessen im Browser: `appearance: auto` — das Betriebssystem zeichnete
   Rahmen, Grund und Pfeil selbst. Ein Feld mit systemeigenem Pfeil und
   systemeigener Innenflaeche steht neben unseren Knoepfen wie ein
   Fremdkoerper; genau das war der Befund „wirkt wie ein rohes
   Browserelement".

   Es bleibt ein NATIVES <select>. Kein nachgebautes Menue aus
   JavaScript: das native Feld kann Tastatur, Typeahead, die Auswahlliste
   des Betriebssystems und die Bedienhilfen — alles, was ein Nachbau erst
   muehsam wieder herstellen muesste, meist schlechter. Geaendert wird
   nur, was WIR zeichnen duerfen: Rahmen, Grund, Schrift und der Pfeil.

   Der Pfeil ist ein eingebettetes SVG (data:), kein Zeichen aus einer
   Schrift und keine Datei von aussen — die CSP der App laesst keinen
   fremden Host zu, und ein Textpfeil („▾") saehe in jeder Schrift anders
   aus. Rechts bleibt Platz dafuer frei, damit ein langer Eintrag nicht
   unter dem Pfeil verschwindet. */
.ak-select {
  font-weight: var(--ak-fw-semibold);
  padding-block: 12px;
  padding-right: 40px;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none' stroke='%2314182B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 7 7.5 13 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  cursor: pointer;
}
/* Ohne diese Zeile faerbt Firefox den Text eines deaktivierten Feldes grau
   und laesst den Pfeil dunkel — das Feld sieht dann halb bedienbar aus. */
.ak-select:disabled { background-image: none; cursor: not-allowed; }
.ak-textarea { min-height: 110px; resize: vertical; line-height: 1.7; }
.ak-input::placeholder,
.ak-textarea::placeholder { color: var(--ak-ink-3); }

.ak-input:hover, .ak-select:hover, .ak-textarea:hover { border-color: var(--ak-line-strong); }

/* Zustaende. Fehler und Erfolg NIE nur ueber die Randfarbe: dazu gehoert
   die Meldung darunter, und das Feld verweist mit aria-describedby auf
   sie. Bei Fehlern zusaetzlich aria-invalid="true". */
.ak-input.is-error,   .ak-select.is-error,   .ak-textarea.is-error   { border-color: var(--ak-err); }
.ak-input.is-success, .ak-select.is-success, .ak-textarea.is-success { border-color: var(--ak-ok); }

.ak-input:disabled, .ak-select:disabled, .ak-textarea:disabled {
  background: var(--ak-disabled-surface);
  color: var(--ak-disabled-text);
  border-color: var(--ak-disabled-border);
  cursor: not-allowed;
}
.ak-input[readonly], .ak-textarea[readonly] {
  background: var(--ak-surface-warm);
  border-color: var(--ak-line);
}

.ak-help { font-size: var(--ak-fs-meta); color: var(--ak-ink-2); }
.ak-msg {
  display: flex; align-items: flex-start; gap: 6px;
  font-size: var(--ak-fs-meta); font-weight: 600;
}
.ak-msg--err { color: var(--ak-err-text); }
.ak-msg--ok  { color: var(--ak-ok-text); }

/* Feld mit fuehrendem Icon (Suche, Passwort mit Umschalter). */
.ak-input-wrap { position: relative; display: flex; align-items: center; }
.ak-input-wrap > .ak-ic { position: absolute; left: var(--ak-sp-4); color: var(--ak-ink-2); pointer-events: none; }
.ak-input-wrap > .ak-ic ~ .ak-input { padding-left: 44px; }
.ak-input-wrap > .ak-input-action {
  position: absolute; right: 6px;
  padding: 8px 10px; border-radius: var(--ak-r-btn);
  background: none; color: var(--ak-ink-2);
  font-size: var(--ak-fs-meta); font-weight: 600;
}
.ak-input-wrap > .ak-input-action:hover { color: var(--ak-ink); background: var(--ak-surface-warm); }

/* Kontrollkaestchen und Auswahlknopf — das native Element bleibt und wird
   nur vergroessert und eingefaerbt. Ein nachgebautes Kaestchen aus <span>
   verliert Tastaturbedienung und Vorlesbarkeit. */
.ak-check {
  display: flex; align-items: flex-start; gap: var(--ak-sp-3);
  font-size: var(--ak-fs-body-sm); line-height: 1.5; cursor: pointer;
}
.ak-check input[type="checkbox"],
.ak-check input[type="radio"] {
  width: 20px; height: 20px; flex: none; margin: 1px 0 0;
  accent-color: var(--ak-accent);
  cursor: pointer;
}
.ak-check input:disabled { cursor: not-allowed; }
.ak-check:has(input:disabled) { color: var(--ak-disabled-text); cursor: not-allowed; }

/* Segmentierter Schalter. Als Gruppe echter Knoepfe mit role="tablist"
   ODER als Radiogruppe bauen — nicht als divs. Auf dem Telefon fuellt er
   die Zeile zu gleichen Teilen (Regel aus der Basisschicht). */
.ak-seg {
  display: inline-flex; gap: 4px; padding: 4px;
  background: var(--ak-surface-warm);
  border-radius: var(--ak-r-pill);
}
.ak-seg > * {
  padding: 9px var(--ak-sp-4);
  border-radius: var(--ak-r-pill);
  background: none; border: none;
  font-size: var(--ak-fs-body-sm); font-weight: 600;
  color: var(--ak-ink-2); cursor: pointer;
  white-space: nowrap;
}
.ak-seg > [aria-selected="true"],
.ak-seg > .is-selected {
  background: var(--ak-surface); color: var(--ak-ink);
  box-shadow: var(--ak-sh-card);
}
@media (max-width: 767px) { .ak-seg { display: flex; width: 100%; } .ak-seg > * { flex: 1 1 0; min-width: 0; } }


/* ══ 6 · OPTIONSREIHEN ══════════════════════════════════════════════════
   Grundlage der spaeteren Uebungen — hier NUR die Darstellung, keine
   Logik.

   DER GRUNDSATZ DES HANDOFFS, WOERTLICH:
   „Selection and result never share a style." Auswahl ist lila, Ergebnis
   ist teal oder rot. Wer beides gleich faerbt, macht aus „ich habe das
   gewaehlt" und „das war richtig" denselben Eindruck.

   Und: jeder Ergebniszustand traegt zusaetzlich ein Icon im Marker sowie
   einen Text (.ak-sr genuegt, wenn kein Platz ist). Farbe allein reicht
   nie. */

.ak-opts { display: grid; gap: 11px; }

.ak-opt {
  display: flex; align-items: center; gap: 13px;
  width: 100%; text-align: left;
  padding: var(--ak-sp-4) 18px;
  border: 1.5px solid var(--ak-line);
  border-radius: var(--ak-r-opt);
  background: var(--ak-bg);
  color: var(--ak-ink);
  font-size: var(--ak-fs-base-lg); font-weight: var(--ak-fw-medium); line-height: 1.45;
  cursor: pointer;
  transition: background-color var(--ak-t-toggle) var(--ak-ease),
              border-color var(--ak-t-toggle) var(--ak-ease);
}
.ak-opt:hover { border-color: var(--ak-line-strong); }

/* Marker links: traegt den Buchstaben und im Ergebnisfall das Icon. */
.ak-opt-mark {
  display: grid; place-items: center;
  width: 26px; height: 26px; flex: none;
  border: 1.5px solid var(--ak-line);
  border-radius: var(--ak-r-pill);
  background: var(--ak-surface);
  color: var(--ak-ink-2);
  font-size: var(--ak-fs-meta); font-weight: var(--ak-fw-bold);
}
.ak-opt-text { min-width: 0; }
.ak-opt-note { display: block; font-size: var(--ak-fs-meta); color: var(--ak-ink-2); margin-top: 2px; }

/* AUSWAHL — lila. Noch keine Aussage ueber richtig oder falsch. */
.ak-opt.is-selected {
  background: var(--ak-accent-soft);
  border-color: var(--ak-accent);
}
.ak-opt.is-selected .ak-opt-mark {
  background: var(--ak-accent); border-color: var(--ak-accent);
  color: var(--ak-ink-inverse);
}

/* ERGEBNIS — teal, rot, gelb. Jeweils mit Icon im Marker. */
.ak-opt.is-correct {
  background: var(--ak-ok-surface); border-color: var(--ak-ok-bar);
  color: var(--ak-ok-text);
}
.ak-opt.is-correct .ak-opt-mark {
  background: var(--ak-ok-bar); border-color: var(--ak-ok-bar);
  color: var(--ak-ink-inverse);
}
.ak-opt.is-wrong {
  background: var(--ak-err-surface); border-color: var(--ak-err);
  color: var(--ak-err-text);
}
.ak-opt.is-wrong .ak-opt-mark {
  background: var(--ak-err); border-color: var(--ak-err);
  color: var(--ak-ink-inverse);
}

/* PLAUSIBEL — der Zustand, den der Handoff nicht kannte und den Phase 1
   braucht: die Antwort war sprachlich moeglich, aber nicht die gesuchte.
   Der Warnton heisst im Handoff „needs review" und passt genau. Nicht
   rot: es war kein Fehler des Lernenden. */
.ak-opt.is-plausible {
  background: var(--ak-warn-surface); border-color: var(--ak-warn);
  color: var(--ak-warn-text);
}
.ak-opt.is-plausible .ak-opt-mark {
  background: var(--ak-warn); border-color: var(--ak-warn);
  color: var(--ak-ink-inverse);
}

/* AUSGEGRAUT — Stufe 2 der spaeteren Hilfe entfernt Moeglichkeiten.
   Sie verschwinden NICHT: sonst springt das Layout und der Lernende
   verliert die Orientierung. */
.ak-opt:disabled,
.ak-opt[aria-disabled="true"],
.ak-opt.is-dimmed {
  background: var(--ak-disabled-surface);
  border-color: var(--ak-disabled-border);
  color: var(--ak-disabled-text);
  cursor: not-allowed;
}
.ak-opt.is-dimmed .ak-opt-mark { color: var(--ak-disabled-text); }

.ak-opt.is-locked { cursor: not-allowed; opacity: .72; pointer-events: none; }


/* ══ 7 · RUECKMELDEPANEL ════════════════════════════════════════════════
   BEWUSST ALS BEHAELTER, NICHT ALS EINZELNER TEXTBLOCK.

   Der Prototyp hat genau ein Panel mit einem Titel und einem Text. Fuer
   Phase 1 muessen mehrere Hilfestufen UNTEREINANDER stehen bleiben —
   Stufe 1 verschwindet nicht, wenn Stufe 2 kommt. Ein ueberschreibbarer
   Textblock koennte das nie tragen und muesste spaeter neu gebaut werden.
   Deshalb: .ak-fb ist die Huelle, .ak-fb-item ist ein Eintrag.

   aria-live gehoert an die HUELLE, nicht an den Eintrag — sonst meldet
   das Vorleseprogramm nichts, wenn ein neuer Eintrag erscheint. */

.ak-fb { display: grid; gap: var(--ak-sp-2); margin-top: var(--ak-sp-5); }

.ak-fb-item {
  display: flex; align-items: flex-start; gap: var(--ak-sp-3);
  padding: var(--ak-sp-4) 18px;
  border: 1px solid var(--ak-line);
  border-radius: var(--ak-r-opt);
  background: var(--ak-surface);
  animation: akRise .25s var(--ak-ease) both;
}
.ak-fb-icon {
  display: grid; place-items: center;
  width: 32px; height: 32px; flex: none;
  border-radius: var(--ak-r-pill);
  background: var(--ak-ink-3); color: var(--ak-ink-inverse);
}
.ak-fb-title { font-size: var(--ak-fs-body-lg); font-weight: var(--ak-fw-bold); margin: 0 0 5px; }
.ak-fb-text  { font-size: var(--ak-fs-md); line-height: 1.6; color: var(--ak-ink-2); margin: 0; }

.ak-fb-item--ok    { background: var(--ak-ok-surface);   border-color: var(--ak-ok-border); }
.ak-fb-item--ok    .ak-fb-icon { background: var(--ak-ok-bar); }
.ak-fb-item--ok    .ak-fb-title { color: var(--ak-ok-text); }

.ak-fb-item--err   { background: var(--ak-err-surface);  border-color: var(--ak-err-border); }
.ak-fb-item--err   .ak-fb-icon { background: var(--ak-err); }
.ak-fb-item--err   .ak-fb-title { color: var(--ak-err-text); }

.ak-fb-item--warn  { background: var(--ak-warn-surface); border-color: var(--ak-warn-border); }
.ak-fb-item--warn  .ak-fb-icon { background: var(--ak-warn); }
.ak-fb-item--warn  .ak-fb-title { color: var(--ak-warn-text); }

.ak-fb-item--info  { background: var(--ak-info-surface); border-color: var(--ak-info-border); }
.ak-fb-item--info  .ak-fb-icon { background: var(--ak-info); }
.ak-fb-item--info  .ak-fb-title { color: var(--ak-info-text); }

/* Erklaerung — ruhiger als die Zustaende, sie bewertet nichts. */
.ak-fb-item--explain {
  background: var(--ak-purple-1); border-color: var(--ak-purple-border-1);
}
.ak-fb-item--explain .ak-fb-icon { background: var(--ak-accent); }
.ak-fb-item--explain .ak-fb-title { color: var(--ak-accent-deep); }

/* Aeltere Eintraege duerfen gedaempft werden, wenn ein neuerer daruntersteht —
   sie bleiben lesbar, treten aber zurueck. */
.ak-fb-item.is-past { opacity: .7; }

.ak-fb-item--loading .ak-fb-icon { background: var(--ak-surface-warm); }


/* ══ 8 · FORTSCHRITTSANZEIGE ════════════════════════════════════════════
   Markup traegt role="progressbar" mit aria-valuenow/min/max, oder es ist
   ein <progress>. Die Breite wird per style-Attribut vom Server gesetzt —
   das ist der EINE Fall, in dem ein Inline-Wert richtig ist, weil er
   Daten sind und nicht Gestaltung. */

.ak-prog {
  height: 10px; width: 100%;
  border-radius: var(--ak-r-pill);
  background: var(--ak-line);
  overflow: hidden;
}
.ak-prog-bar {
  height: 100%; width: 0;
  border-radius: var(--ak-r-pill);
  background: var(--ak-accent);
  transition: width var(--ak-t-progress) var(--ak-ease);
}
.ak-prog--sm { height: 6px; }
.ak-prog.is-complete .ak-prog-bar { background: var(--ak-ok-bar); }

.ak-prog-row { display: flex; align-items: center; gap: var(--ak-sp-3); }
.ak-prog-row .ak-prog { flex: 1 1 auto; }
.ak-prog-label { font-size: var(--ak-fs-meta); font-weight: 600; color: var(--ak-ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Unbestimmt — laeuft, solange kein Wert bekannt ist. Markup laesst
   aria-valuenow weg. */
.ak-prog--indeterminate .ak-prog-bar {
  width: 40%;
  animation: akIndet 1.3s var(--ak-ease) infinite;
}
@keyframes akIndet {
  0%   { transform: translateX(-100%) }
  100% { transform: translateX(250%) }
}


/* ══ 9 · STATUSDARSTELLUNGEN ════════════════════════════════════════════
   Immer Punkt/Icon UND Text. Die Klasse faerbt nur; das Wort steht im
   Markup und ist die eigentliche Aussage. */

/* M3: Die Grundregel von .ak-status kommt jetzt aus der SSOT (weiter
   unten im Nachtrag). Hier bleiben nur unsere EIGENEN Zustaende, die die
   SSOT nicht kennt: --open, --current, --done, --locked, --hint,
   --review, --empty. Sie tragen andere Namen als die SSOT-Zustaende und
   stehen deshalb nicht in Konkurrenz zu ihnen. --error dagegen gibt es
   in beiden; er kommt jetzt aus der SSOT und ist hier entfernt. */
.ak-status .ak-ic { width: 14px; height: 14px; }

/* Der farbige Punkt vor der Beschriftung. Die Referenz setzt ihn in der
   Lektionsliste; er ist ZUSATZ zum Wort, nie sein Ersatz — deshalb
   aria-hidden ueber ::before und nicht als eigenes Element. */
.ak-status::before {
  content: ""; flex: none;
  width: 7px; height: 7px;
  border-radius: var(--ak-r-pill);
  background: currentColor;
}

.ak-status--open     { color: var(--ak-ink-2); }
.ak-status--current  { color: var(--ak-accent-deep); }
.ak-status--done     { color: var(--ak-ok-text); }
.ak-status--locked   { color: var(--ak-ink-2); }
.ak-status--hint     { color: var(--ak-info-text); }
.ak-status--review   { color: var(--ak-warn-text); }
.ak-status--empty    { color: var(--ak-ink-2); font-style: italic; }


/* ══ 10 · LADEZUSTAENDE ═════════════════════════════════════════════════
   Der Handoff hatte keinen. Ergaenzt, weil jede echte Seite ihn braucht.

   Regel: kein springendes Layout. Ein Skelett hat die Groesse dessen, was
   es ersetzt — sonst huepft die Seite, sobald die Daten da sind. */

.ak-spin {
  display: inline-block; width: 20px; height: 20px;
  border: 2px solid var(--ak-line);
  border-top-color: var(--ak-accent);
  border-radius: var(--ak-r-pill);
  animation: akSpin .7s linear infinite;
}
.ak-spin--lg { width: 32px; height: 32px; border-width: 3px; }

/* Der Ladehinweis braucht einen Text fuer Vorleseprogramme; das Markup
   setzt role="status". Ein sich drehender Kreis allein sagt nichts. */
.ak-loading { display: inline-flex; align-items: center; gap: var(--ak-sp-3); color: var(--ak-ink-2); font-size: var(--ak-fs-body-sm); }

.ak-skel {
  background: var(--ak-surface-warm);
  border-radius: var(--ak-r-btn);
  position: relative; overflow: hidden;
}
.ak-skel::after {
  content: ""; position: absolute; inset: 0;
  /* M3: der harte Weissverlauf ist weg. Die SSOT kennt keinen Schimmer —
     ihr Ladeplatzhalter ist eine ruhige Flaeche. Statt einen Farbwert zu
     erfinden, laeuft der Schimmer jetzt ueber die Kartenflaeche der SSOT:
     derselbe helle Zug, aber kein Wert ausserhalb der Tokens. */
  background: linear-gradient(90deg, transparent, var(--ak-surface), transparent);
  animation: akShimmer 1.4s infinite;
}
@keyframes akShimmer { from { transform: translateX(-100%) } to { transform: translateX(100%) } }

.ak-skel--line  { height: 14px; margin-bottom: var(--ak-sp-2); }
.ak-skel--title { height: 22px; width: 60%; margin-bottom: var(--ak-sp-3); }
.ak-skel--card  { height: 120px; border-radius: var(--ak-r-card); }

/* Bewegungsreduktion: alles steht still, aber bleibt sichtbar. Ein
   unsichtbares Skelett waere schlimmer als ein unbewegtes. */
@media (prefers-reduced-motion: reduce) {
  .ak-skel::after { animation: none; }
  .ak-spin,
  .ak-btn.is-loading::after,
  .ak-prog--indeterminate .ak-prog-bar { animation: none; }
  .ak-prog--indeterminate .ak-prog-bar { width: 100%; opacity: .4; }
}


/* ══ 11 · LEER- UND FEHLERZUSTAENDE ═════════════════════════════════════
   Muster aus der Zustandsgalerie des Handoffs: Icon, Ueberschrift,
   Erklaerung, EINE konkrete naechste Handlung.

   Kein erfundener Inhalt, kein „bald verfuegbar" ohne Datum. Wo es nichts
   zu tun gibt, entfaellt der Knopf — er ist optional, nicht Pflicht. */

.ak-state {
  display: grid; justify-items: center; text-align: center;
  gap: var(--ak-sp-3);
  padding: var(--ak-sp-8) var(--ak-sp-5);
  max-width: 44ch; margin-inline: auto;
}
.ak-state-icon {
  display: grid; place-items: center;
  width: 64px; height: 64px;
  border-radius: var(--ak-r-pill);
  background: var(--ak-surface-warm);
  color: var(--ak-ink-2);
}
.ak-state-title { font-family: var(--ak-font-display); font-size: var(--ak-fs-2xl); font-weight: var(--ak-fw-bold); margin: 0; }
.ak-state-text  { font-size: var(--ak-fs-body); line-height: var(--ak-lh-body); color: var(--ak-ink-2); margin: 0; }
.ak-state-code  { font-size: var(--ak-fs-micro); font-weight: 700; letter-spacing: var(--ak-ls-micro); color: var(--ak-ink-2); }

.ak-state--error   .ak-state-icon { background: var(--ak-err-surface);  color: var(--ak-err); }
.ak-state--warn    .ak-state-icon { background: var(--ak-warn-surface); color: var(--ak-warn); }
.ak-state--locked  .ak-state-icon { background: var(--ak-disabled-surface); color: var(--ak-disabled-text); }
.ak-state--info    .ak-state-icon { background: var(--ak-info-surface); color: var(--ak-info); }


/* ══ 12 · FORTSCHRITTSRING ══════════════════════════════════════════════
   Nachgetragen nach der visuellen Referenzpruefung: die Landingpage zeigt
   den Fortschritt als KREIS, nicht als Balken. Ohne Rendern des Prototyps
   waere das nicht aufgefallen.

   TECHNIK: ein SVG mit zwei Kreisen. Der Fortschritt kommt ueber
   stroke-dashoffset — das ist der EINE Fall, in dem ein style-Attribut
   im Markup richtig ist, weil es ein DATUM ist und keine Gestaltung.
   Der Umfang steht als Custom Property, damit das Markup ihn nicht
   ausrechnen muss.

   BARRIEREFREIHEIT: role="img" mit aria-label am SVG, oder ein
   role="progressbar" am Behaelter. Ein Ring ohne Textentsprechung ist
   fuer ein Vorleseprogramm nichts. */

.ak-ring { position: relative; display: inline-grid; place-items: center; }
.ak-ring svg { display: block; transform: rotate(-90deg); }
/* Die Staerke stand nirgends — SVG nimmt dann 1 px, und der Ring war ein
   Haarstrich. Er traegt die wichtigste Zahl der Startseite; er darf
   gesehen werden. */
.ak-ring-spur { stroke: var(--ak-line); fill: none; stroke-width: 8; }
.ak-ring-wert {
  stroke: var(--ak-ok-bar); fill: none; stroke-linecap: round; stroke-width: 8;
  transition: stroke-dashoffset var(--ak-t-ring) var(--ak-ease);
}
.ak-ring--accent .ak-ring-wert { stroke: var(--ak-accent); }
.ak-ring-mitte {
  position: absolute; display: grid; place-items: center; text-align: center;
}
.ak-ring-zahl {
  font-family: var(--ak-font-display);
  font-size: var(--ak-fs-4xl); font-weight: var(--ak-fw-bold); line-height: 1;
  font-variant-numeric: tabular-nums;
}
/* Die Laengenstufen von vorher sind entfallen: im Kreis steht jetzt der
   Prozentwert, und der ist immer kurz. Ein Notbehelf weniger. */
.ak-ring-label { font-size: var(--ak-fs-meta); color: var(--ak-ink-2); margin-top: 2px; }
/* Die Beschriftung steht UNTER dem Ring, nicht darin und nicht daneben.
   Im Kreis ist der Platz knapp; jedes Wort dort drueckt die Zahl
   kleiner. Daneben gestellt sah sie aus wie ein loses Wort — sie
   braucht deshalb eine eigene Spalte MIT dem Ring. */
.ak-ring-mit-text {
  display: inline-flex; flex-direction: column; align-items: center;
  flex: none;
}
.ak-ring-unterschrift {
  margin-top: 6px; text-align: center;
  font-size: var(--ak-fs-meta); color: var(--ak-ink-3);
}


/* ══ 13 · FERTIGKEITSBALKEN ═════════════════════════════════════════════
   Beschrifteter Balken mit Wert rechts. Anders als .ak-prog ist das eine
   ZEILE mit Name und Zahl, kein nackter Balken — in der Referenz stehen
   vier davon untereinander (Okuma, Dinleme, Yazma, Konuşma).

   Die Breite kommt als Datum vom Server. aria-* gehoert an den Balken. */

.ak-skills { display: grid; gap: var(--ak-sp-3); }
.ak-skill { display: grid; gap: 6px; }
.ak-skill-kopf {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--ak-sp-3);
  font-size: var(--ak-fs-body-sm); font-weight: 600;
}
.ak-skill-wert { color: var(--ak-ink-2); font-variant-numeric: tabular-nums; }
.ak-skill-spur {
  height: 8px; border-radius: var(--ak-r-pill);
  background: var(--ak-line); overflow: hidden;
}
.ak-skill-bar {
  height: 100%; width: 0; border-radius: var(--ak-r-pill);
  background: var(--ak-accent);
  transition: width var(--ak-t-progress) var(--ak-ease);
}
.ak-skill--ok   .ak-skill-bar { background: var(--ak-ok-bar); }
.ak-skill--warn .ak-skill-bar { background: var(--ak-warn); }


/* ══ 14 · KENNZAHLKARTE ═════════════════════════════════════════════════
   Grosse Zahl, kleines Label, optional ein Icon. In der Referenz mehrfach:
   Punkte, Erfolge, Woerter, Genauigkeit.

   WICHTIG FUER DIESES PRODUKT: Die Karte zeigt, was WIRKLICH da ist. Wo
   es keine echte Zahl gibt, gehoert die Platzhalterkarte darunter — keine
   erfundene Zahl. */

.ak-stat {
  display: grid; gap: 4px;
  padding: var(--ak-pad-card-sm);
  background: var(--ak-surface);
  border: 1px solid var(--ak-line);
  border-radius: var(--ak-r-card);
}
.ak-stat-kopf { display: flex; align-items: center; gap: var(--ak-sp-2); }
.ak-stat-zahl {
  font-family: var(--ak-font-display);
  font-size: var(--ak-fs-4xl); font-weight: var(--ak-fw-bold); line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.ak-stat-label { font-size: var(--ak-fs-meta); font-weight: 600; color: var(--ak-ink-2); }
.ak-stat--accent .ak-stat-zahl { color: var(--ak-accent-deep); }
.ak-stat--ok     .ak-stat-zahl { color: var(--ak-ok-text); }


/* ══ 15 · GESTRICHELTE PLATZHALTERKARTE ═════════════════════════════════
   Der Handoff loest Platzhalter vorbildlich: gestrichelter Rahmen,
   Gedankenstriche statt Zahlen und ein SICHTBARES Etikett
   „YER TUTUCU · gerçek veri yok". Kein erfundener Wert.

   Das ist genau der Projektgrundsatz „keine leeren Versprechen", nur
   visuell. Diese Karte macht ihn benutzbar: wo noch keine echten Daten
   existieren, steht sichtbar, dass keine da sind. */

.ak-placeholder {
  display: grid; gap: var(--ak-sp-2);
  padding: var(--ak-pad-card-sm);
  border: 1.5px dashed var(--ak-line-strong);
  border-radius: var(--ak-r-card);
  background: transparent;
  color: var(--ak-ink-2);
}
.ak-placeholder-etikett {
  justify-self: start;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px;
  border: 1px dashed var(--ak-line-strong);
  border-radius: var(--ak-r-tag);
  font-size: var(--ak-fs-micro); font-weight: 700;
  letter-spacing: var(--ak-ls-micro); text-transform: uppercase;
  color: var(--ak-ink-2);
}
.ak-placeholder-wert {
  font-family: var(--ak-font-display);
  font-size: var(--ak-fs-4xl); font-weight: var(--ak-fw-bold); line-height: 1.05;
  color: var(--ak-ink-3);
}
.ak-placeholder-text { font-size: var(--ak-fs-body-sm); margin: 0; }


/* ══ 16 · KREIS-PLAY-KNOPF ══════════════════════════════════════════════
   Ausdruecklich KEINE neue Komponentenfamilie, sondern eine Variante des
   vorhandenen Icon-Knopfs: rund statt eckig, mit Rahmen. In der Referenz
   steht er im Hero neben dem Textlink „Örnek dersi aç".

   Er braucht wie jeder alleinstehende Icon-Knopf einen zugaenglichen
   Namen. */

.ak-btn--icon.ak-btn--kreis {
  border-radius: var(--ak-r-pill);
  border: 1.5px solid var(--ak-line);
  background: var(--ak-surface);
  width: 46px; height: 46px;
}
.ak-btn--icon.ak-btn--kreis:hover { border-color: var(--ak-accent); color: var(--ak-accent-deep); }

/* Textlink mit vorangestelltem Kreisknopf — die Kombination aus dem Hero. */
.ak-play-link {
  display: inline-flex; align-items: center; gap: var(--ak-sp-3);
  font-size: var(--ak-fs-body); font-weight: 600;
  color: var(--ak-ink); text-decoration: none;
}
.ak-play-link:hover { color: var(--ak-accent-deep); }
.ak-play-link:hover .ak-btn--kreis { border-color: var(--ak-accent); }

/* ── Strichstaerke der Helfer-Icons ───────────────────────────────────
   App\Icons::render() erzeugt inline-SVG mit stroke-width="1.7" als
   PRAESENTATIONSATTRIBUT. Der Handoff verlangt 1.9 (2.4 bei Haken und
   Kreuz). Eine CSS-Eigenschaft schlaegt das Attribut — damit stimmt die
   Strichstaerke, ohne den geteilten Helfer anzufassen, den auch die
   Produkt-App benutzt. Deren Aussehen bleibt unveraendert, weil die
   Regel nur innerhalb von .ak greift. */
.ak .ak-ic-svg { stroke-width: 1.9; }
.ak .ak-ic-svg--stark { stroke-width: 2.4; }


/* ── Umgebungshinweis ─────────────────────────────────────────────────
   Sagt, in welcher Umgebung man ist. Haengt ausschliesslich an
   APP_TIER=sandbox und erscheint in Produktion nie. Steht IM FLUSS, nicht
   fixiert: fixiert muesste jede Kopfzeile darunter ausweichen, und dann
   verschiebt eine Umgebungsangabe das Produktlayout.

   Er lag vorher in design-app.css an `body.ak-app` gebunden und hiess
   .app-tier-banner. Auf der Auth-Seite, die design-app.css nicht laedt,
   stand er damit als ungestalteter Absatz oben links — gemessen. Eine
   Umgebungsangabe ist keine App-Komponente, sondern gilt fuer alle
   Flaechen; deshalb liegt sie hier.

   Der Name traegt jetzt das Praefix. Der alte lag ausserhalb des
   .ak-Namensraums und wurde beim Verschieben von der eigenen Testregel
   gemeldet („kein globaler Selektor ausserhalb des .ak-Namensraums") —
   die Regel hat funktioniert. */

.ak-umgebung {
  margin: 0;
  padding: 6px 16px;
  background: var(--ak-warn-surface);
  color: var(--ak-warn-text);
  border-bottom: 1px dashed var(--ak-warn-border);
  font-family: var(--ak-font-body);
  font-size: var(--ak-fs-meta); font-weight: var(--ak-fw-semibold); letter-spacing: .2px;
  text-align: center;
}

@media (max-width: 900px) {
  .ak-umgebung { padding: 5px 12px; font-size: var(--ak-fs-tiny); }
}


/* ══ 17 · BAUTEILE DER SSOT, DIE UNS NOCH FEHLTEN ═══════════════════════
   M3, 01.08.2026. Wortgetreu aus design_handoff_v2.1.2/almanca-kumbaram.css,
   Abschnitte 5, 6, 8 und 9. Aufgenommen sind nur Regeln, deren Selektor
   KEINE Klasse nennt, die wir schon fuehren — es entsteht also keine
   zweite Regel zu einem bestehenden Namen.

   WARUM JETZT UND NICHT ERST BEI BEDARF
   Diese Bauteile sind die Bausteine, aus denen M4 aufwaerts gebaut wird:
   der Adminbereich braucht Etiketten, Avatare, Segmente und Tabellen, das
   Dashboard braucht Balken, Punkte, Diagramm und Kalender. Sie hier
   abzulegen heisst, dass jedes spaetere Paket sie nur noch benutzt statt
   sie einzeln nachzubauen — und dass sie EINMAL geprueft sind statt
   viermal. Bis dahin sind es ungenutzte Regeln; das ist der Preis, und er
   ist kleiner als vier Nachbauten.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Knoepfe der SSOT, die uns fehlten — SSOT 5. BUTTONS ── */

.ak-btn--success, a.ak-btn--success { background: var(--ak-success-solid); color: var(--ak-on-fill); }

/* Square icon-only button */
.ak-icon-btn {
  display: grid;
  place-items: center;
  width: var(--ak-tap-min); height: var(--ak-tap-min);
  min-width: var(--ak-tap-min); min-height: var(--ak-tap-min);
  flex: none;
  border-radius: var(--ak-r-chip);
  background: var(--ak-surface);
  border: 1.5px solid var(--ak-line-input);
  color: var(--ak-ink);
}

.ak-icon-btn:hover { border-color: var(--ak-ink); }

.ak-icon-btn--round { border-radius: var(--ak-r-pill); }

.ak-icon-btn--plain { background: none; border: none; }

/* ── Formularbauteile der SSOT, die uns fehlten — SSOT 6. FORMS ── */

.ak-field__label { font-size: var(--ak-fs-xs); font-weight: var(--ak-fw-semibold); color: var(--ak-ink); }

/* Helper line under a field — always carries an icon, never color alone */
.ak-field__hint { display: flex; align-items: center; gap: 6px; font-size: var(--ak-fs-meta); font-weight: var(--ak-fw-semibold); color: var(--ak-ink-3); }

.ak-field__hint--ok { color: var(--ak-success-fg-2); }

.ak-field__hint--err { color: var(--ak-error-fg-2); }

/* Toggle switch */
.ak-switch {
  width: 50px; height: 29px;
  padding: 3px;
  border-radius: var(--ak-r-pill);
  background: var(--ak-line-strong);
  display: flex; align-items: center; justify-content: flex-start;
  flex: none;
  transition: background var(--ak-dur-fast);
}

.ak-switch[aria-checked="true"] { background: var(--ak-success-solid); justify-content: flex-end; }

.ak-switch__knob { width: 23px; height: 23px; border-radius: var(--ak-r-pill); background: var(--ak-on-fill); box-shadow: var(--ak-sh-knob); }

/* Search field */
.ak-search {
  display: flex; align-items: center; gap: 9px;
  background: var(--ak-surface);
  border: 1.5px solid var(--ak-line-input);
  border-radius: var(--ak-r-button);
  padding: 0 13px;
  min-height: var(--ak-tap-min);
}

/* ── Etiketten, Stufenmarken, Avatare, Segmente — SSOT 8. BADGES, CHIPS, TAGS, AVATARS ── */

/* Small square tag, e.g. "A1", "ÇEKİRDEK DERS" */
.ak-tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: var(--ak-r-tag);
  font-size: var(--ak-fs-micro);
  font-weight: var(--ak-fw-bold);
  letter-spacing: .3px;
  background: var(--ak-surface-warm);
  color: var(--ak-ink-2);
  white-space: nowrap;
}

.ak-tag--a1 { background: var(--ak-a1-soft); color: var(--ak-a1-deep); }

.ak-tag--a2 { background: var(--ak-a2-soft); color: var(--ak-a2-deep); }

.ak-tag--b1 { background: var(--ak-b1-soft); color: var(--ak-b1-deep); }

.ak-tag--b2 { background: var(--ak-b2-soft); color: var(--ak-b2-deep); }

.ak-tag--c1 { background: var(--ak-c1-soft); color: var(--ak-c1-deep); }

.ak-tag--c2 { background: var(--ak-c2-soft); color: var(--ak-c2-deep); }

.ak-tag--success { background: var(--ak-success-soft); color: var(--ak-success-fg-2); }

.ak-tag--warning { background: var(--ak-warning-soft); color: var(--ak-warning-fg); }

.ak-tag--error { background: var(--ak-error-soft);   color: var(--ak-error-fg-2); }

.ak-tag--info { background: var(--ak-info-soft);    color: var(--ak-info-fg); }

/* "Opsiyonel" / "Yer tutucu" markers — these must stay visible in production
   until the feature is decided or real data exists. */
.ak-tag--optional { background: var(--ak-b1-soft); color: var(--ak-b1-deep); }

.ak-tag--placeholder { background: var(--ak-b1-soft); color: var(--ak-b1-deep); }

/* Segmented control. On phone every segment takes an equal share of the row. */
.ak-segment {
  display: flex; gap: 6px;
  background: var(--ak-surface);
  border: 1px solid var(--ak-line);
  border-radius: var(--ak-r-input);
  padding: 4px;
  width: fit-content;
  max-width: 100%;
  overflow-x: auto;
}

.ak-segment__item {
  flex: 0 0 auto;
  padding: 10px 16px;
  border-radius: var(--ak-r-chip);
  font-size: var(--ak-fs-xs);
  font-weight: var(--ak-fw-semibold);
  color: var(--ak-ink-2);
  white-space: nowrap;
}
.ak-segment__item.is-active { background: var(--ak-ink); color: var(--ak-on-fill); }

/* Avatar */
.ak-avatar {
  display: grid; place-items: center;
  width: 40px; height: 40px;
  border-radius: var(--ak-r-pill);
  font-family: var(--ak-font-display);
  font-weight: var(--ak-fw-bold);
  font-size: var(--ak-fs-sm);
  background: var(--ak-accent-soft);
  color: var(--ak-a1-deep);
  border: 1.5px solid var(--ak-accent-border);
  flex: none;
}

a.ak-avatar, button.ak-avatar { min-width: var(--ak-tap-min); min-height: var(--ak-tap-min); }

/* Initials must stay legible whatever soft fill is applied inline. */
.ak-avatar { color: var(--ak-ink); }

.ak-avatar--sm, span.ak-avatar--sm, a.ak-avatar--sm, button.ak-avatar--sm { color: var(--ak-ink); }

.ak-avatar.ak-lv-a1, .ak-avatar.ak-lv-a2, .ak-avatar.ak-lv-b1,
.ak-avatar.ak-lv-b2, .ak-avatar.ak-lv-c1, .ak-avatar.ak-lv-c2 { color: var(--ak-lv-deep); }

.ak-avatar--sm { width: 30px; height: 30px; font-size: var(--ak-fs-micro); border-width: 0; }

a.ak-avatar--sm, button.ak-avatar--sm { min-width: var(--ak-tap-min); min-height: var(--ak-tap-min); }

.ak-avatar--lg { width: 84px; height: 84px; font-size: var(--ak-fs-5xl); border-width: 2px; }

.ak-avatar--placeholder { background: var(--ak-surface-warm); color: var(--ak-ink-2); font-size: var(--ak-fs-tiny); border: none; }

.ak-status__dot { width: 8px; height: 8px; border-radius: var(--ak-r-pill); background: var(--ak-line-strong); flex: none; }

/* ── Fortschritt und Datenanzeige — SSOT 9. PROGRESS & DATA DISPLAY ── */

.ak-bar {
  height: 8px;
  border-radius: var(--ak-r-pill);
  background: var(--ak-surface-warm);
  overflow: hidden;
}

.ak-bar--sm { height: 6px; }

.ak-bar--xs { height: 5px; }

.ak-bar__fill {
  height: 100%;
  border-radius: var(--ak-r-pill);
  background: var(--ak-accent);
  transition: width var(--ak-dur-slow) var(--ak-ease);
}

.ak-bar__fill--success { background: var(--ak-success-bar); }

.ak-bar__fill--warning { background: var(--ak-b1); }

.ak-bar__fill--error { background: var(--ak-b2); }

.ak-ring__track { stroke: var(--ak-surface-warm); fill: none; }

.ak-ring__value { stroke: var(--ak-success-bar); fill: none; stroke-linecap: round; transition: stroke-dashoffset var(--ak-dur-result) var(--ak-ease); }

.ak-ring__label { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; }

/* Step dots under a lesson */
.ak-dots { display: flex; gap: 6px; align-items: center; }

.ak-dots__dot { width: 8px; height: 8px; border-radius: var(--ak-r-pill); background: var(--ak-line); transition: all var(--ak-dur-base); }

.ak-dots__dot.is-done { background: var(--ak-accent-border-2); }

.ak-dots__dot.is-current { width: 26px; background: var(--ak-accent); }

/* Weekly bar chart */
.ak-chart { display: flex; align-items: flex-end; gap: var(--ak-s2); height: 150px; }

.ak-chart__col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }

.ak-chart__bar { border-radius: var(--ak-r-bar) var(--ak-r-bar) var(--ak-r-cell) var(--ak-r-cell); background: var(--ak-success-bar); }

.ak-chart__bar--muted { background: var(--ak-surface-warm); }

.ak-chart__bar--today { background: var(--ak-accent); }

.ak-chart__label { font-size: var(--ak-fs-tiny); font-weight: var(--ak-fw-semibold); color: var(--ak-ink-3); text-align: center; margin-top: 5px; }

/* Calendar heatmap */
.ak-heatmap { display: grid; grid-template-columns: repeat(8, 1fr); gap: 5px; }

.ak-heatmap__cell { aspect-ratio: 1; border-radius: var(--ak-r-cell); background: var(--ak-heat-0); }

.ak-heatmap__cell[data-level="1"] { background: var(--ak-heat-1); }

.ak-heatmap__cell[data-level="2"] { background: var(--ak-heat-2); }

.ak-heatmap__cell[data-level="3"] { background: var(--ak-heat-3); }

.ak-stat__value { font-family: var(--ak-font-display); font-weight: var(--ak-fw-bold); font-size: var(--ak-fs-4xl); letter-spacing: -.5px; color: var(--ak-ink); }


/* ── Stufenhelfer — SSOT Abschnitt 15 ──
   Setzt --ak-lv, --ak-lv-soft und --ak-lv-deep auf die Farben einer
   Stufe. Ohne diese Regeln laufen die Avatar- und Kartenregeln oben ins
   Leere, weil sie var(--ak-lv-deep) lesen. */

.ak-lv-a1 { --ak-lv: var(--ak-a1); --ak-lv-soft: var(--ak-a1-soft); --ak-lv-deep: var(--ak-a1-deep); }
.ak-lv-a2 { --ak-lv: var(--ak-a2); --ak-lv-soft: var(--ak-a2-soft); --ak-lv-deep: var(--ak-a2-deep); }
.ak-lv-b1 { --ak-lv: var(--ak-b1); --ak-lv-soft: var(--ak-b1-soft); --ak-lv-deep: var(--ak-b1-deep); }
.ak-lv-b2 { --ak-lv: var(--ak-b2); --ak-lv-soft: var(--ak-b2-soft); --ak-lv-deep: var(--ak-b2-deep); }
.ak-lv-c1 { --ak-lv: var(--ak-c1); --ak-lv-soft: var(--ak-c1-soft); --ak-lv-deep: var(--ak-c1-deep); }
.ak-lv-c2 { --ak-lv: var(--ak-c2); --ak-lv-soft: var(--ak-c2-soft); --ak-lv-deep: var(--ak-c2-deep); }








/* ── Nachtrag M3 ──────────────────────────────────────────────────────
   Beim ersten Uebertrag habe ich die Abschnittsgrenzen der SSOT zu eng
   gezogen; dadurch fiel je Abschnitt die letzte Regel weg. Aufgefallen
   ist es an der visuellen Gegenprobe: das Suchfeld zeigte den
   Browserrahmen im Rahmen, weil `.ak-search input { border: none }`
   fehlte. Hier stehen die betroffenen Regeln nach — einzeln benannt,
   nicht ueber einen zweiten Bereichsschnitt.

   Die Zustandsfarben von .ak-status gelten fuer HELLE Flaechen. Die
   dunkle Entsprechung liegt seit M2 in design-base.css; beide zusammen
   ergeben den vollstaendigen Kontext. */

.ak-search input {
  flex: 1; min-width: 0;
  border: none; outline: none; background: none;
  font-size: var(--ak-fs-sm);
  min-height: var(--ak-tap-min);   /* the input is the operable element */
  align-self: stretch;
}

.ak-input:focus, .ak-textarea:focus, .ak-select:focus {
  border-color: var(--ak-accent);
  box-shadow: var(--ak-focus-ring);
}

.ak-input.is-valid   { border-color: var(--ak-success-bar); }

.ak-input.is-invalid { border-color: var(--ak-error); }

.ak-status { display: inline-flex; align-items: center; gap: 7px; font-size: var(--ak-fs-meta); font-weight: var(--ak-fw-semibold); }
.ak-status--ok      { color: var(--ak-success-fg-2); } .ak-status--ok .ak-status__dot      { background: var(--ak-success-bar); }
.ak-status--active  { color: var(--ak-accent-deep); }  .ak-status--active .ak-status__dot  { background: var(--ak-accent); }
.ak-status--warn    { color: var(--ak-b1-deep); }      .ak-status--warn .ak-status__dot    { background: var(--ak-b1); }
.ak-status--error   { color: var(--ak-error-fg-2); }   .ak-status--error .ak-status__dot   { background: var(--ak-error); }
.ak-status--muted   { color: var(--ak-ink-3); }



/* ── Auth-Saeule — SSOT Abschnitt 7 (M6) ──
   Die volle Markenspalte der Anmeldebildschirme. Wortgetreu uebernommen;
   sie war bisher als eigene Regel in design-auth.css nachgebaut. */

/* Full-height brand column on auth screens — square edges, content pushed apart */
.ak-auth-panel {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-radius: 0;
}


/* ══ 18 · BEDIENZIELE — SSOT §14c ═══════════════════════════════════════
   Auf Tablet und Telefon muss jedes bedienbare Element mindestens
   44 x 44 px anbieten. Kleine Elemente behalten ihr Aussehen und
   bekommen die Flaeche ueber eine durchsichtige ::after-Auflage — so
   verschiebt sich optisch nichts.

   AUSDRUECKLICH AUSGENOMMEN, weil nicht bedienbar:
     .ak-status__dot     Zustandspunkt, nie klickbar
     .ak-heatmap__cell   Kalenderfeld, nur lesbar
     .ak-chart__bar      Diagrammbalken, nur lesbar
     .ak-skel            Ladeplatzhalter
   Wird eines davon je klickbar, braucht es zusaetzlich .ak-touch.

   Die Auflage darf Nachbarn nicht ueberdecken: die SSOT hat dafuer in
   v2.1.2 den Abstand der Schrittpunkte auf die volle Zielbreite gezogen
   statt die Auflage ueber den Nachbarn zu legen. Gemessen wurde das im
   Abschluss-Audit: Mittenabstand 44 px, null Ueberlappungen.
   ══════════════════════════════════════════════════════════════════════ */

.ak-touch { position: relative; }
.ak-touch::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  translate: -50% -50%;
  width: max(100%, var(--ak-tap-min));
  height: max(100%, var(--ak-tap-min));
}

/* iOS Safari zoomt die Ansicht, sobald ein fokussiertes Feld kleiner als
   16px rendert. Jedes Texteingabefeld ist deshalb auf Beruehrgeraeten auf
   16px festgelegt — Plattformanforderung, keine Typografieentscheidung. */
@media (pointer: coarse), (max-width: 1099px) {
  /* Bewusst NUR innerhalb von .ak: die SSOT schreibt hier nackte
     Elementselektoren (input, textarea, select). Die wuerden auch auf
     Flaechen wirken, die noch gar nicht umgestellt sind — der
     Adminbereich zum Beispiel. Solange nicht alles umgestellt ist,
     bleibt die Regel im eigenen Namensraum. */
  .ak .ak-input, .ak .ak-textarea, .ak .ak-select, .ak .ak-search input,
  .ak input:not([type=checkbox]):not([type=radio]), .ak textarea, .ak select {
    font-size: var(--ak-fs-base-lg);
  }
  .ak-btn, .ak-chip, .ak-icon-btn, .ak-segment__item,
  .ak-btn--sm, .ak-btn--compact { min-height: var(--ak-tap-min); }

  /* NACHGETRAGEN MIT M5a (01.08.2026).
     Diese Regeln standen in §14c der SSOT und fehlten bei uns — sie
     waren Teil des Blocks, den ich in M3 versehentlich zu weit
     geschnitten und dann vollstaendig zurueckgenommen hatte. Ohne sie
     blieben 543 klassenlose Links in Fusszeile und Rechtsnavigation bei
     24 px Hoehe.

     Wie in M3 laufen sie NUR innerhalb von .ak. Die SSOT schreibt hier
     nackte Elementselektoren; die wuerden auch Flaechen treffen, die
     noch nicht umgestellt sind. */

  /* Jeder Anker mit einer ak-Klasse — Wortmarke, Zuruecklink, Kartenlink. */
  .ak a[class*="ak-"] { min-height: var(--ak-tap-min); }

  /* Textlinks in Fliesstext und Listen: Flaeche ohne Umbruch im Satz.
     Die Zeilenhoehe traegt die Flaeche, das Schriftbild bleibt. */
  .ak .ak-body a, .ak .ak-body-sm a, .ak .ak-lead a, .ak .ak-meta a,
  .ak .ak-link-quiet, .ak li > a, .ak p > a, .ak span > a {
    position: relative; display: inline-block;
    min-height: var(--ak-tap-min); line-height: var(--ak-tap-min);
  }

  /* Aufklappzeilen sind bedienbar. */
  .ak summary { min-height: var(--ak-tap-min); display: flex; align-items: center; }

  /* Anker IN einer Ueberschrift. Die SSOT nennt nur li, p und span; bei
     uns traegt die Stufenuebersicht ihren Verweis in der H2. Hier nur die
     Hoehe — eine Zeilenhoehe von 44 px wuerde das Schriftbild der
     Ueberschrift veraendern, und das ist keine Bedienfrage. */
  .ak h1 > a, .ak h2 > a, .ak h3 > a { display: inline-block; min-height: var(--ak-tap-min); }

  /* Kurze Beschriftungen erreichen die Hoehe, aber nicht die Breite:
     „TR", „DE", „FAQ", „AGB" sind 37 bis 43 px breit. Ein Ziel ist erst
     mit BEIDEN Massen erreicht. */
  .ak li > a, .ak .ak-body a, .ak .ak-body-sm a { min-width: var(--ak-tap-min); }

  /* Reihen und Raster, die einen Anker direkt enthalten. */
  .ak .ak-row > a, .ak .ak-stack > a, .ak .ak-stack-sm > a, .ak .ak-grid > a,
  .ak a.ak-row, .ak button.ak-row { min-height: var(--ak-tap-min); }

  /* Ghostknoepfe haben von sich aus keinen waagerechten Innenabstand. */
  .ak .ak-btn--ghost { min-width: var(--ak-tap-min); padding-inline: var(--ak-s3); }

  /* NACHGETRAGEN MIT M6: Bedienelemente, deren sichtbare Flaeche kleiner
     ist als das Ziel — Kontrollkaestchen, Schalter, Blattzahlen. Sie
     behalten ihr Aussehen und bekommen die Flaeche ueber eine
     durchsichtige Auflage. Ohne diese Regeln blieben die beiden
     Zustimmungskaestchen der Registrierung bei 24 x 24 px. */
  /* Controls whose visual box is deliberately smaller than the target. */
    .ak-page-btn,
    .ak-switch,
    .ak-icon-btn--plain,
    .ak-dots__dot,
    .ak-drag,
    .ak-check input[type="checkbox"],
    .ak-check input[type="radio"] { position: relative; }

    .ak-page-btn::after,
    .ak-switch::after,
    .ak-icon-btn--plain::after,
    .ak-dots__dot::after,
    .ak-drag::after,
    .ak-check input[type="checkbox"]::after,
    .ak-check input[type="radio"]::after {
      content: '';
      position: absolute;
      left: 50%; top: 50%;
      translate: -50% -50%;
      width: max(100%, var(--ak-tap-min));
      height: max(100%, var(--ak-tap-min));
    }
}


/* ══ 19 · TABELLEN — SSOT ABSCHNITT 13 ══════════════════════════════════
   M4, 01.08.2026. Wortgetreu uebernommen. Der Adminbereich ist heute der
   einzige Ort mit Tabellen, aber die Regeln gehoeren in die gemeinsame
   Ebene: die Layoutvertraege darin (min-width:0 auf Rasterkindern,
   .ak-row--actions, Formularfelder nie breiter als ihr Behaelter) gelten
   ueberall und haben in der SSOT genau den Ueberlauf im Lektionseditor
   behoben.
   ══════════════════════════════════════════════════════════════════════ */

/* -----------------------------------------------------------------------------
   13. TABLES (admin)
   Grid-based so cells align without table markup. Always wrap in .ak-table-scroll.
   -------------------------------------------------------------------------- */

.ak-table-scroll { overflow-x: auto; max-width: 100%; overscroll-behavior-x: contain; }
/* A scroll container must be able to become narrower than its content. Without
   an explicit min-width:0 a grid/flex parent sizes it to the table's min-width
   (660px) and the page grows. The scroll happens INSIDE the container. */
.ak-table-scroll { min-width: 0; width: 100%; }

/* Header rows that pair a back-link with an action group: allow the group to
   wrap onto its own line instead of forcing the row wider than the viewport. */
.ak-row { min-width: 0; }
.ak-row > .ak-row { flex-wrap: wrap; }

/* A trailing group of actions in a header row. It keeps its items together and
   pushes right, but it may wrap onto its own line rather than force the row
   wider than the viewport — the cause of the 390px overflow in the admin
   lesson editor. Never use flex:none here. */
.ak-row--actions {
  display: flex; align-items: center; gap: var(--ak-s2);
  flex: 0 1 auto; flex-wrap: wrap;
  margin-left: auto;
}

/* Grid and flex children default to min-width:auto, so a wide child (a table,
   a long word) can push its track past the container. Track children are
   allowed to shrink to their container; the CONTENT inside them keeps a usable
   width because anything genuinely wide lives in a .ak-table-scroll.
   This is a layout contract, not a repair. */
.ak-split > *, .ak-split--rev > *, .ak-split--even > *,
.ak-checkout > *, .ak-grid > *, .ak-grid--xs > *, .ak-grid--sm > *,
.ak-grid--md > *, .ak-grid--lg > * { min-width: 0; }
.ak-stack > * { min-width: 0; }

/* Form controls never exceed their container. */
.ak-textarea, .ak-input, .ak-select { max-width: 100%; }
.ak-table {
  display: grid;
  gap: 1px;
  background: var(--ak-line);
  min-width: 660px;
}
.ak-table__head {
  background: var(--ak-bg);
  padding: 12px 16px;
  font-size: var(--ak-fs-nano);
  font-weight: var(--ak-fw-bold);
  letter-spacing: .7px;
  color: var(--ak-ink-3);
}
.ak-table__cell {
  background: var(--ak-surface);
  padding: 12px 16px;
  display: flex; align-items: center;
  font-size: var(--ak-fs-xs);
  min-width: 0;
}
.ak-table__cell--muted { color: var(--ak-ink-3); }
.ak-table__cell--num   { justify-content: flex-end; font-variant-numeric: tabular-nums; }
.ak-table__cell--center{ justify-content: center; }

/* Truncating text inside a grid cell */
.ak-truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }

/* Drag handle */
.ak-drag { cursor: grab; color: var(--ak-line-strong); }

/* Pagination */
.ak-page-btn {
  width: 34px; height: 34px;
  border-radius: var(--ak-r-chip);
  background: var(--ak-surface);
  border: 1px solid var(--ak-line);
  font-size: var(--ak-fs-caption); font-weight: var(--ak-fw-bold);
  color: var(--ak-ink-2);
}

/* ── DIE MARKE ─────────────────────────────────────────────────────
   Zeichen und Wortmarke des Eigentuemers (08.09.2026, src/Marke.php).
   Beide tragen ihre Groesse als Attribut, damit vor dem Stylesheet
   nichts springt; hier steht nur, was sich mit der Breite aendert.

   `width: auto` an der Wortmarke ist keine Bequemlichkeit: das SVG
   traegt ein viewBox-Verhaeltnis von 583.2 : 50.96. Wer Breite UND
   Hoehe setzt, verzerrt sie. Gesteuert wird ausschliesslich ueber die
   Hoehe. */
.ak-marke-zeichen { display: block; flex: none; }

/* ── DER SYMBOLVORRAT (17.09.2026) ──────────────────────────────────
   `Icons::sprite()` legt die `<symbol>`-Definitionen einmal in die
   Seite; Flaechen, die von JavaScript aufgebaut werden, verweisen mit
   `<use href="#ak-ic-…">` darauf. Der Traeger traegt schon Nullmasse im
   Markup — diese Regel nimmt ihn zusaetzlich aus dem Fluss.

   NICHT `display: none`: dass ein `<use>` auf einen abgeschalteten Baum
   aufloest, war historisch nicht in jeder Maschine so, und ein Symbol,
   das nicht aufloest, zeichnet nichts — ohne Fehlermeldung. Aus dem
   Fluss nehmen statt abschalten ist der Weg, der ueberall traegt. */
.ak-symbolvorrat { position: absolute; width: 0; height: 0; overflow: hidden; }
.ak-marke-wort    { display: block; width: auto; }
.ak-marke { display: inline-flex; align-items: center; gap: 10px; }
