/* ==========================================================================
   BookTo — Reset, Gerüst, Bedienelemente

   Grundregeln aus dem Design-Handoff (Juli 2026):
   · Trefferflächen 64 px, Hauptaktionen 88 px — nie kleiner.
   · Zustände nie allein über Deckkraft: der Grund steht als Klartext daneben.
   · Fokus, Scan-Rahmen und Verweil-Ziel tragen denselben eigenen Ton.
   · Nichts unter 16 px.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; padding: 0; }
ul, ol { list-style: none; }
img, picture, svg { max-width: 100%; display: block; }
button, input, textarea, select { font: inherit; color: inherit; }

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

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--color-text);
  background: var(--color-bg);
  min-height: 100dvh;
  margin: 0;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
}

h1, h2, h3 { font-family: var(--font-headline); line-height: var(--leading-tight); }
h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }

a { color: var(--color-primary-dark); }

/* Beschriftungen, Reiter, Wortmarke — wie auf assistuk.net. */
.label-font { font-family: var(--font-label); font-weight: 600; letter-spacing: .01em; }

/* ── Fokus, Scan-Rahmen, Verweil-Ziel: ein Ton, eine Regel ──────────────
   In der Hauptfarbe wäre der Ring auf gefüllten Blauflächen unsichtbar.

   Gemessen: #cc6600 gegen #4b698c ergibt 1,5:1 — weit unter den 3:1, die
   WCAG 2.2 für Bedienelement-Umrisse verlangt. Gegen den Seitengrund sind
   es 3,5:1. Der Ring liegt durch `outline-offset` zwar auf dem Grund, aber
   das ist knapp und hängt davon ab, worauf ein Knopf gerade sitzt.
   Deshalb zusätzlich ein Trennring in der Flächenfarbe zwischen Knopf und
   Ring: dann steht der orange Ring nie direkt auf Blau. Genauso zeigt es
   der Entwurf (dunkler Rand innen, oranger Ring außen). */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px var(--color-surface);
  border-radius: var(--radius-sm);
}
/* Die Füllfläche steht in lock.css — dort läuft sie im Ein-Taster-Betrieb
   als Restzeit mit (`--scan-progress`). Eine Vollfüllung hier würde sie
   überschreiben, je nach Ladereihenfolge. */
.is-scan-item {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px var(--color-surface);
}
.is-scan-group {
  outline: 6px solid var(--color-focus);
  outline-offset: 4px;
  border-radius: var(--radius-lg);
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--color-primary-deep); color: #fff;
  padding: var(--space-3) var(--space-4);
  z-index: var(--z-modal);
}
.skip-link:focus { left: 0; }

/* ── App-Gerüst ───────────────────────────────────────────────────────────
   `viewport-fit=cover` in index.html holt die App unter Kerbe, abgerundete
   Ecken und Home-Anzeiger — wer das tut, muss den Platz auch wieder
   freihalten. Ohne diese Polster lagen auf dem iPhone die Blätterleiste und
   der Fortschrittsbalken unter dem Home-Anzeiger und im Querformat der
   Schließen-Knopf unter der Kerbe. Auf Geräten ohne solche Ränder sind alle
   vier Werte 0 — am Schreibtisch ändert sich nichts.
   `box-sizing: border-box` steht im Reset ganz oben, die Polster fressen
   also nichts von den 100dvh. */
#app {
  min-height: 100dvh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  padding:
    env(safe-area-inset-top, 0px)
    env(safe-area-inset-right, 0px)
    env(safe-area-inset-bottom, 0px)
    env(safe-area-inset-left, 0px);
}

.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.screen__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-hairline);
  flex: 0 0 auto;
}
.screen__title {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 1.75rem;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.screen__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-5) var(--space-4);
}
.screen__body--pad0 { padding: 0; }

/* Seiten, die NICHT scrollen: der Inhalt wird geblättert, nicht gerollt. */
.screen__body--fixed {
  overflow: hidden;
  display: flex;
  align-items: center;
}
.screen__body--fixed .wrap { width: 100%; }
.screen__body--fixed .setrow { padding: var(--space-3) 0; }

.wrap { max-width: 1100px; margin: 0 auto; width: 100%; }

/* ── Glasleiste: Vorlesen, Schriftgröße, Farben — auf jedem Bildschirm ──
   Wer vorlesen lassen will, soll nicht erst ein Buch öffnen müssen. */
.glassbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 84px;
  padding: 10px var(--space-5);
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border-bottom: .5px solid var(--color-hairline);
}
.glassbar--strong {
  background: var(--glass-strong);
  border-top: 1.5px solid var(--color-hairline);
  border-bottom: 0;
}

/* Auf Bildschirmen mit eigenem Kopf (Bibliothek, Einstellungen) sitzen zwei
   Leisten übereinander. In eine Zeile passen beide nicht: allein die
   Knöpfe messen zusammen über 1024 px. Deshalb wird die Glasleiste dort
   flacher — die Ziele bleiben 64 px, nur die Luft darum schrumpft. */
.glassbar--compact {
  min-height: 64px;
  padding: 0 var(--space-5);
}
.glassbar__spacer { flex: 1; }
.glassbar__brand {
  font-family: var(--font-label);
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--color-primary-deep);
  letter-spacing: .01em;
  white-space: nowrap;
}
/* Die beiden A-Knöpfe unterscheiden sich nur in der Schriftgröße. */
.btn--a  { font-size: 1rem;    font-weight: 700; }
.btn--aa { font-size: 1.3125rem; font-weight: 700; }

/* ── Blätterleiste am unteren Rand ────────────────────────────────────── */
.pager {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  background: var(--color-surface);
  border-top: 1px solid var(--color-hairline);
  flex-wrap: wrap;
  justify-content: space-between;
}
.pager__dots {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  justify-content: center;
  flex: 1;
}
.pager__dots .btn { min-height: var(--target-min); padding: var(--space-2); }
.pager__dots .btn[aria-pressed="true"] {
  background: var(--color-primary);
  color: var(--color-text-inverse);
  border-color: var(--color-primary-deep);
  border-width: 3px;
}

/* ── Schaltflächen ────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--target-min);
  min-width: var(--target-min);
  padding: var(--space-3) var(--space-5);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
  color: var(--color-text);
  font-size: var(--text-min);
  font-weight: 600;
  cursor: pointer;
  position: relative;
  touch-action: manipulation;
  /* box-shadow bewusst NICHT mit übergeblendet: der Trennring des Fokus
     liegt darauf, und ein Fokus, der eine Drittelsekunde zum Erscheinen
     braucht, ist bei Tastatur- und Tasterbedienung nicht zu gebrauchen. */
  transition: background var(--transition), border-color var(--transition);
}
.btn:hover { background: var(--color-primary-bg); }
.btn:active { background: var(--color-primary-bg); }

/* Große Ziele nicht skalieren — das wirkt bei Augensteuerung unruhig. */
.btn--lg:active, .btn--primary-size:active { transform: none; }

.btn--primary {
  background: var(--color-primary);
  color: var(--color-text-inverse);
  border-color: var(--color-primary);
}
.btn--primary:hover { background: var(--color-primary-dark); border-color: var(--color-primary-dark); }

.btn--ghost { background: var(--color-surface); border-color: var(--color-border-strong); }
.btn--ghost:hover { background: var(--color-surface-alt); }

.btn--outline { background: var(--color-surface); border: 2px solid var(--color-hairline); }

.btn--danger {
  background: var(--color-surface);
  color: var(--color-error);
  border-color: var(--color-error);
}
.btn--danger-solid {
  background: var(--color-error);
  color: #fff;
  border-color: var(--color-error);
}

.btn--pill { border-radius: var(--radius-full); }
.btn--icon { padding: var(--space-3); }
.btn--round { border-radius: 50%; padding: 0; }

/* Hauptaktionen: Weiterlesen, Zurück, Schließen, Dialogknöpfe. */
.btn--primary-size { min-height: var(--target-primary); min-width: var(--target-primary); }
.btn--big { min-height: var(--target-big); font-size: var(--text-lg); padding: var(--space-4) var(--space-6); }

.btn__ico { width: 24px; height: 24px; flex: 0 0 auto; }
.btn--big .btn__ico { width: 34px; height: 34px; }
.btn--primary-size .btn__ico { width: 28px; height: 28px; }

/* ── Gesperrt: Grund als Klartext, Kontrast bleibt ──────────────────────
   Halbdurchsichtige Knöpfe sind für die Zielgruppe schwer zu lesen und
   sagen nicht, warum es nicht weitergeht (Befund 02). */
.btn[disabled],
.btn[aria-disabled="true"] {
  cursor: not-allowed;
  background: var(--color-surface-alt);
  color: var(--color-text-secondary);
  border-color: var(--color-border);
}
.btn[disabled]:hover,
.btn[aria-disabled="true"]:hover { background: var(--color-surface-alt); }
.btn__why {
  display: block;
  font-size: var(--text-min);
  font-weight: 400;
  color: var(--color-text-secondary);
  line-height: 1.2;
}
.locknote {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-warning-bg);
  color: var(--color-warning);
  font-size: var(--text-min);
  font-weight: 600;
}

/* ── Verweil-Rückmeldung ────────────────────────────────────────────────
   BookTo hat KEINE eigene mehr. Den Fortschritt zeigt allein der
   Verweilpunkt der geteilten Engine, direkt am Zeiger — auf jedem Knopf
   gleich.

   ⚠️ Hier lagen einmal zwei zusätzliche Zeichen NUR für den Knopf „Weiter":
   ein Ring am rechten Rand (`.dwellring`) und eine Fläche, die von links
   nach rechts durchlief (`.dwellfill`). Lars hat sie in drei Schritten
   abgelehnt (2026-07-28/29): erst als „Artefakt", dann „nach rechts
   versetzt", zuletzt „verschiebt immer noch Farbe von links nach rechts —
   ruhiges Dwell wie andere Buttons auch bitte".

   Wer so etwas zurückholt, baut es für ALLE Knöpfe, nicht für einen. */

/* Beschriftung und Symbol über den Verweilpunkt heben — aber NUR sie.
   Ohne die Ausnahme bekäme auch der Punkt `position: relative`, würde im
   Fluss mitzählen und den Text im Knopf zur Seite schieben. Genau das
   passierte am „Weiter"-Knopf, sobald der Zeiger darüberkam. */
.btn > *:not(.dwell-dot) {
  position: relative;
  z-index: 1;
}

/* ── Karten ───────────────────────────────────────────────────────────── */
.card {
  background: var(--color-surface);
  border: 2px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.card--lift { transition: transform var(--transition), box-shadow var(--transition); }
.card--lift:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); }

.grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}

/* ── Formularfelder ───────────────────────────────────────────────────── */
.field { display: block; margin-bottom: var(--space-4); }
.field__label { display: block; font-weight: 700; font-size: 1.125rem; margin-bottom: var(--space-2); }
.input, .textarea, .select {
  width: 100%;
  min-height: var(--target-min);
  padding: var(--space-3);
  border: 2px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-size: var(--text-base);
}
.textarea { min-height: 120px; resize: vertical; line-height: var(--leading-normal); }
.input:focus, .textarea:focus, .select:focus {
  border-color: var(--color-primary);
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

.hint { color: var(--color-text-secondary); font-size: var(--text-min); }
.error-text { color: var(--color-error); font-weight: 700; }

/* Kleine Hinweisstreifen (Lizenz, Erfolg, Warnung) */
.note {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-min);
  line-height: 1.4;
}
.note--ok   { background: var(--color-success-bg); color: var(--color-success); }
.note--warn { background: var(--color-warning-bg); color: var(--color-warning); }
.note--err  { background: var(--color-error-bg);   color: var(--color-error); }

/* ── Meldung unten ────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  background: var(--color-primary-deep);
  color: #fff;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-lg);
  z-index: var(--z-toast);
  max-width: 90vw;
  text-align: center;
  animation: toast-in var(--transition) both;
}
html[data-contrast="high"] .toast { border: 2px solid #fff; }
.toast__act {
  min-height: var(--target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 2px solid rgba(255,255,255,.6);
  background: transparent;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
}
.toast__act:hover { background: rgba(255,255,255,.14); }
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ── Dialoge ──────────────────────────────────────────────────────────── */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(26,58,106,.55);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Der Rand ist der Abstand zum Bildschirmrand — und auf Geräten mit Kerbe
     und Home-Anzeiger auch der Abstand dazu. `#app` kann hier nicht helfen:
     Dialoge sind `fixed` und hängen am Ansichtsfenster, nicht an #app. */
  padding: calc(var(--space-5) + env(safe-area-inset-top, 0px))
           calc(var(--space-5) + env(safe-area-inset-right, 0px))
           calc(var(--space-5) + env(safe-area-inset-bottom, 0px))
           calc(var(--space-5) + env(safe-area-inset-left, 0px));
  z-index: var(--z-modal);
  animation: fade-in var(--transition) both;
}
.modal__box {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  width: 720px;
  max-width: 100%;
  max-height: 100%;
  /* Ohne das schrumpft ein Dialog nie unter seine Mindest-Inhaltsbreite:
     Flex-Elemente haben `min-width: auto`. Auf dem iPhone stand der
     Zahlenschloss-Dialog dadurch 76 px über dem rechten Rand. */
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* Quer statt hoch: `hidden` für die Breite (die abgerundeten Ecken),
     `auto` für die Höhe. Sonst schneidet der Kasten seinen eigenen Fuß ab,
     sobald Kopf und Fuß zusammen höher sind als der erlaubte Kasten —
     gemessen beim Lösch-Dialog auf 360 × 640 mit der größten Schrift:
     Kopf 451 px, Fuß 253 px, erlaubt 589 px. „Endgültig löschen" lag damit
     180 px unter dem Rand und war mit nichts zu erreichen. */
  overflow-x: hidden;
  overflow-y: auto;
  animation: modal-in var(--transition-enter) both;
}
/* „Breit" heißt: so groß wie der Platz hergibt — NICHT 100 % der
   Fensterhöhe. Prozentwerte rechnen hier gegen das Ansichtsfenster, der
   Innenabstand der Hülle kam also oben und unten obendrauf; auf dem iPhone
   lag der Schließen-Knopf des Auskunfts-Dialogs unter dem Bildschirmrand.
   `align-self: stretch` nimmt genau den Platz, den die Hülle übrig lässt. */
.modal__box--wide { width: 100%; align-self: stretch; }
.modal__head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
  border-bottom: 1px solid var(--color-hairline);
}
.modal__head h2 { font-family: var(--font-label); font-weight: 600; font-size: 1.625rem; }
.modal__sub { font-size: 1.125rem; color: var(--color-text-secondary); margin-top: 2px; }
.modal__ico {
  width: 64px; height: 64px;
  flex: 0 0 auto;
  border-radius: var(--radius-md);
  background: var(--color-primary-bg);
  color: var(--color-primary-deep);
  display: flex; align-items: center; justify-content: center;
}
.modal__ico svg { width: 32px; height: 32px; }
.modal__ico--danger { background: var(--color-error-bg); color: var(--color-error); }
.modal__body { padding: var(--space-5); overflow-y: auto; flex: 1; min-height: 0; }
.modal__foot {
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  align-items: center;
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-hairline);
  flex-wrap: wrap;
}
.modal__foot .btn { min-height: var(--target-primary); }
.modal__foot--split { justify-content: space-between; }
/* Kleine Geräte: Dialoge schlanker.

   Kopf und Fuß schrumpfen nicht (dort stehen Überschrift und Knöpfe), der
   Körper dazwischen schon. Auf einem quer gehaltenen Telefon mit der
   größten Schrift brauchten allein Kopf (149 px) und Fuß (130 px) fast die
   ganzen 318 px, die der Dialog hoch sein darf — der Fuß lag 6 px unter
   dem Bildschirmrand, „Fertig" war nicht mehr zu treffen.

   Weg fällt das Schmuck-Symbol im Kopf; es trägt keine Bedeutung, die nicht
   auch im Text steht. Übrig bleiben Überschrift, Erklärung und die Knöpfe —
   in voller Zielgröße. */
@media (max-height: 620px), (max-width: 560px) {
  .modal__head { padding: var(--space-3) var(--space-4); }
  .modal__head .modal__ico { display: none; }
  .modal__foot { padding: var(--space-2) var(--space-4); }
}

@keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }
@keyframes modal-in {
  from { opacity: 0; transform: translateY(16px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

/* ── Auswahl: Farbe UND Form ──────────────────────────────────────────── */
.pick {
  position: absolute;
  top: 10px; right: 10px;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  border: 3px solid var(--color-surface);
  display: flex; align-items: center; justify-content: center;
}
.pick svg { width: 28px; height: 28px; }

/* ── Leerer Zustand ───────────────────────────────────────────────────── */
.empty {
  text-align: center;
  padding: var(--space-10) var(--space-4);
  color: var(--color-text-secondary);
}
.empty__ico { width: 72px; height: 72px; margin: 0 auto var(--space-4); color: var(--color-primary); }

/* ── Ansagen für Screenreader (Seitenwechsel, Auswahl, Scan) ────────────
   top/left sind nicht kosmetisch: ohne sie behält das Element seine
   Flussposition — also unter #app, das schon die volle Höhe füllt — und
   sein eines Pixel erzeugt eine Bildlaufleiste auf einer App, die
   ausdrücklich nicht scrollen soll. */
#live-region {
  position: absolute;
  top: 0; left: 0;
  width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ── Schmale Geräte ───────────────────────────────────────────────────────
   Umbruch bei 900 px, nicht bei 1080: die Entwürfe sind für 1024 × 768
   gezeichnet und zeigen dort ausdrücklich zwei Spalten. Bei 1080 wäre der
   Zweispalter auf genau dem Zielgerät nie zu sehen. */
@media (max-width: 900px) {
  .two-col { grid-template-columns: 1fr !important; }
}

/* Die Glasleiste auf schmalen Geräten.

   Gemessen auf einem 390er iPhone: vier 64-px-Ziele + Abstände + die
   Wortmarke brauchen 435 px. Die Ziele dürfen nicht schrumpfen (64 px ist
   das Verweil-Mindestmaß), also schob die Leiste die ganze Seite 21 px zur
   Seite — auf jedem Bildschirm der App — und die Beschriftung „Vorlesen"
   lief über den Rand ihres Knopfes auf den nächsten drauf.

   Zwei Stufen, beide nach dem Muster von reader.css: erst fällt die
   Wortmarke weg (sie steht schon im Fenstertitel und auf dem Startbild),
   dann die Beschriftung in den Knöpfen — Symbol und `aria-label` tragen
   weiter, wie beim „Weiter"-Knopf im Reader. */
@media (max-width: 860px) {
  .glassbar__brand { display: none; }
}
@media (max-width: 560px) {
  .glassbar { gap: var(--space-2); padding-left: var(--space-3); padding-right: var(--space-3); }
  .glassbar .gb__label { display: none; }
  .glassbar .btn { padding-left: var(--space-2); padding-right: var(--space-2); }
}
