/* ============================================================
   SPROGMAKKER — Design-system
   ------------------------------------------------------------
   Oversat fra sprogmakker-mockup.jsx (React/Tailwind) til ren CSS.
   Fonten hentes non-blocking fra index.html, importeres ikke her.

   Kontrakt: klassenavnene herunder matcher det app.js/map.js/
   exercise.js skriver til DOM'en. Se CLAUDE.md for skærmoversigt.
   ============================================================ */

/* ---------- Reset ------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: 'Nunito', sans-serif;
  background: var(--slate-950);
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}
button {
  font: inherit;
  border: none;
  background: none;
  cursor: pointer;
  color: inherit;
  /* Slår dobbelt-tryk-zoom fra på knapper uden at spærre browserens
     almindelige pinch-zoom. Det er derfor index.html IKKE sætter
     user-scalable=no, som ville tage zoom fra brugeren helt (V2 afsnit 14). */
  touch-action: manipulation;
}
button:disabled { cursor: default; }
input {
  font: inherit;
}
h1, h2, h3, p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

/* ---------- Farvepalette (fra mockup'ens Tailwind-tokens) ---- */
:root {
  --font-display: 'Fredoka', sans-serif;
  --font-body: 'Nunito', sans-serif;

  --ink: #1e293b;
  --white: #ffffff;

  --teal-900: #134e4a;
  --teal-700: #0f766e;
  --teal-100: #ccfbf1;
  --slate-950: #020617;
  --slate-900: #0f172a;
  --slate-800: #1e293b;
  --slate-700: #334155;
  --slate-600: #475569;
  --slate-500: #64748b;
  --slate-400: #94a3b8;
  --slate-200: #e2e8f0;
  --indigo-950: #1e1b4b;
  --indigo-500: #6366f1;
  --violet-500: #8b5cf6;
  --fuchsia-500: #d946ef;

  --emerald-900: #064e3b;
  --emerald-600: #059669;
  --emerald-400: #34d399;
  --emerald-300: #6ee7b7;
  --emerald-200: #a7f3d0;
  --emerald-50: #ecfdf5;

  --amber-900: #78350f;
  --amber-500: #f59e0b;
  --amber-400: #fbbf24;
  --amber-300: #fcd34d;
  --amber-200: #fde68a;
  --amber-100: #fef3c7;

  --orange-400: #fb923c;
  --orange-100: #ffedd5;
  --orange-50: #fff7ed;

  --sky-400: #38bdf8;
  --sky-100: #e0f2fe;

  /* Vision afsnit 6: aldrig rødt, aldrig et rødt kryds. "Tæt på" bruger
     varme amber/orange-toner i stedet for mockup'ens rose-400. */
  --gentle-bg: var(--amber-400);
  --gentle-bg-soft: var(--amber-100);
  --gentle-ink: var(--amber-900);
  --gentle-border: var(--amber-300);

  /* Fokusring (V2 afsnit 14). Indigo har kontrast nok på de lyse skærme —
     øvelse, placeringstest, Fiko og hvide kort. De mørke skærme overstyrer
     til hvid nedenfor, fordi indigo forsvinder i den mørke gradient og
     amber ville smelte sammen med de amberfarvede primærknapper. */
  --focus-ring: var(--indigo-500);

  /* Typografisk skala (V2 afsnit 4.2). Kun i brug i de dele af øvelses-
     flowet der er genopbygget i Fase 1 indtil videre — resten af skærmene
     migrerer løbende efterhånden som de bliver rørt i senere faser, i
     stedet for i ét stort risikabelt gennemgribende skift nu. */
  --text-xs: 12px;
  --text-sm: 14px;
  --text-md: 17px;
  --text-lg: 21px;
  --text-xl: 28px;
  --text-2xl: 36px;
  --text-hero: clamp(42px, 12vw, 72px);

  /* Afrunding (V2 afsnit 4.3) */
  --radius-sm: 12px;
  --radius-md: 18px;
  --radius-lg: 24px;
  --radius-pill: 999px;

  /* Farvefunktion oven på Tailwind-paletten (V2 afsnit 2.4) — kod mod
     betydning ("korrekt", "prøv igen"), ikke mod et Tailwind-navn, så en
     fremtidig re-tematisering er ét sted at rette, ikke 30 søg-og-erstat. */
  --color-correct: var(--emerald-400);
  --color-correct-ink: var(--emerald-600);
  --color-correct-border: var(--emerald-300);
  --color-gentle: var(--gentle-bg);
  --color-gentle-ink: var(--gentle-ink);
  --color-gentle-border: var(--gentle-border);
  --color-info: var(--indigo-500);
  --color-bonus: var(--violet-500);
  --color-locked: var(--slate-700);
  --color-progress: var(--emerald-400);
}

/* Kun tastatur- og hjælpemiddel-fokus, aldrig et musetryk. Nødvendigt fordi
   body sætter -webkit-tap-highlight-color: transparent, som ellers efterlader
   tastaturbrugere helt uden visuel markering af hvor de er. */
:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}
.view-login,
.view-map,
.view-reward,
.view-loading,
.view-error,
.tabbar { --focus-ring: var(--white); }

/* ---------- App-skal ------------------------------------------ */
#root, .app {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.screen {
  flex: 1;
  min-height: 0;
  position: relative;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Loading / fejl, fejltolerant opstart så skærmen aldrig bare er blank */
.view-loading, .view-error {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: linear-gradient(180deg, var(--teal-900), var(--slate-900));
  color: var(--white);
  text-align: center;
  padding: 24px;
}
/* Uden animation her stod maskotten helt stille, hvilket på en telefon med
   højere netværkslatens kunne se ud som om appen var gået i stå, selvom
   den arbejdede (fundet under test på fysisk telefon, 2026-08-03). */
.view-loading__mascot { font-size: 56px; animation: bob 2.2s ease-in-out infinite; }
.view-error__title { font-family: var(--font-display); font-weight: 600; font-size: 18px; }
.view-error__body { color: var(--slate-400); font-size: 14px; max-width: 280px; }
.view-loading__progress { width: 100%; max-width: 220px; display: flex; flex-direction: column; align-items: center; gap: 6px; margin-top: 4px; }
.view-loading__percent { font-family: var(--font-display); font-weight: 700; font-size: 13px; color: var(--slate-400); }

/* ---------- Bundnavigation ------------------------------------ */
.tabbar {
  display: flex;
  align-items: stretch;
  background: var(--slate-950);
  border-top: 1px solid var(--slate-800);
  padding-bottom: env(safe-area-inset-bottom, 0);
  flex-shrink: 0;
}
.tabbar[hidden] { display: none; }
.tabbar__btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 4px 8px;
  color: var(--slate-500);
  font-weight: 700;
  font-size: 11px;
  transition: color .15s ease, transform .15s ease;
}
.tabbar__btn__icon { font-size: 20px; line-height: 1; }
.tabbar__btn.is-active { color: var(--amber-300); }
.tabbar__btn.is-active .tabbar__btn__icon { transform: translateY(-1px); }

/* ---------- Fælles komponenter --------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 700;
  border-radius: 999px;
  padding: 13px 28px;
  box-shadow: 0 8px 20px -8px rgba(0,0,0,.35);
  transition: transform .12s ease, box-shadow .12s ease, opacity .12s ease;
}
.btn:active { transform: scale(.96); }
.btn--primary { background: var(--amber-300); color: var(--amber-900); }
.btn--ghost { background: rgba(255,255,255,.12); color: var(--white); border: 1.5px solid rgba(255,255,255,.25); }
.btn--dark-ghost { background: rgba(15,23,42,.06); color: var(--slate-700); border: 1.5px solid var(--slate-200); }
.btn--full { width: 100%; }
.btn[disabled] { opacity: .45; box-shadow: none; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
}
.pill--streak { background: rgba(251,146,60,.2); color: #fdba74; }
.pill--coins { background: rgba(252,211,77,.2); color: var(--amber-300); }

.progress-bar {
  height: 10px;
  border-radius: 999px;
  background: var(--slate-200);
  overflow: hidden;
}
.progress-bar__fill {
  height: 100%;
  border-radius: 999px;
  background: var(--color-progress);
  transition: width .35s ease;
}
.progress-bar--dark { background: var(--slate-700); }

.speech-bubble {
  position: relative;
  background: var(--white);
  border-radius: 18px;
  padding: 10px 16px;
  box-shadow: 0 6px 16px -8px rgba(0,0,0,.3);
  font-family: var(--font-display);
  color: var(--slate-700);
  font-size: 14px;
  text-align: center;
}

/* ============================================================
   LOGIN / PROFILVÆLGER
   ============================================================ */
.view-login {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--teal-900) 0%, var(--slate-900) 55%, var(--indigo-950) 100%);
  padding: env(safe-area-inset-top, 28px) 20px 32px;
  color: var(--white);
}
.login-hero { text-align: center; padding: 18px 0 22px; }
.login-hero__mascot { font-size: 54px; }
.login-hero__title { font-family: var(--font-display); font-weight: 700; font-size: 22px; margin-top: 6px; }
.login-hero__subtitle { color: var(--slate-400); font-size: 13px; margin-top: 4px; }

.profile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  padding: 4px 4px 20px;
}
.profile-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 6px;
  border-radius: 20px;
  background: rgba(255,255,255,.06);
  border: 1.5px solid rgba(255,255,255,.1);
  transition: transform .12s ease, background .12s ease;
}
.profile-card:active { transform: scale(.95); }
.profile-card__avatar {
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  font-size: 30px;
  border-radius: 50%;
  background: rgba(252,211,77,.15);
}
.profile-card__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  text-align: center;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-card--new {
  background: rgba(252,211,77,.1);
  border: 1.5px dashed rgba(252,211,77,.4);
}
.profile-card--new .profile-card__avatar { background: transparent; font-size: 26px; color: var(--amber-300); }
.profile-card--new .profile-card__name { color: var(--amber-300); }

.form-card, .pin-card {
  background: rgba(255,255,255,.06);
  border: 1.5px solid rgba(255,255,255,.1);
  border-radius: 24px;
  padding: 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.form-card__label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--slate-400);
}
.text-input {
  background: rgba(255,255,255,.08);
  border: 1.5px solid rgba(255,255,255,.15);
  border-radius: 14px;
  padding: 12px 14px;
  color: var(--white);
  font-family: var(--font-display);
  font-size: 16px;
}
.text-input::placeholder { color: var(--slate-500); }

.mascot-picker {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}
.mascot-picker__btn {
  aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px;
  border-radius: 16px;
  background: rgba(255,255,255,.06);
  border: 2px solid transparent;
}
.mascot-picker__btn.is-selected {
  background: rgba(252,211,77,.18);
  border-color: var(--amber-300);
}

.pin-dots { display: flex; justify-content: center; gap: 14px; }
.pin-dot {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35);
  transition: background .1s ease, transform .1s ease;
}
.pin-dot.is-filled { background: var(--amber-300); border-color: var(--amber-300); transform: scale(1.1); }
.pin-dot.is-error { border-color: var(--amber-400); animation: shake .35s ease; }

.pin-keys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.pin-key {
  padding: 16px 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  border-radius: 16px;
  background: rgba(255,255,255,.08);
  color: var(--white);
}
.pin-key:active { background: rgba(255,255,255,.18); }
.pin-key--wide { grid-column: span 1; font-size: 15px; color: var(--slate-400); }

.login-error {
  text-align: center;
  color: var(--amber-300);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  min-height: 18px;
}

/* ============================================================
   PLACERINGSTEST
   ============================================================ */
.view-placement {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--sky-100), var(--orange-50));
  padding: env(safe-area-inset-top, 20px) 20px 32px;
}
.placement-intro, .placement-outro {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
}
.placement-intro__mascot, .placement-outro__mascot { font-size: 64px; }
.placement-intro__title, .placement-outro__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 21px;
  color: var(--slate-700);
}
.placement-intro__body, .placement-outro__body {
  color: var(--slate-500);
  font-size: 14px;
  max-width: 280px;
}

.placement-dots { display: flex; justify-content: center; gap: 6px; padding: 10px 0 4px; }
.placement-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--slate-200); }
.placement-dot.is-done { background: var(--emerald-400); }
.placement-dot.is-current { background: var(--amber-400); }

.placement-question {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
}
.placement-question__prompt { font-size: 60px; }
.placement-question__label { font-family: var(--font-display); color: var(--slate-600); font-size: 14px; }

/* ============================================================
   VERDENSKORT
   ============================================================ */
.view-map {
  height: 100%;
  overflow-y: auto;
  background: linear-gradient(180deg, var(--teal-900), var(--slate-900) 45%, var(--indigo-950));
  -webkit-overflow-scrolling: touch;
}
.map-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(env(safe-area-inset-top, 0) + 12px) 16px 12px;
  background: rgba(19,78,74,.82);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid rgba(45,212,191,.2);
}
.map-header__eyebrow { color: var(--amber-300); font-size: 11px; font-weight: 700; letter-spacing: .04em; font-family: var(--font-body); }
.map-header__title { color: var(--white); font-family: var(--font-display); font-size: 17px; font-weight: 600; }
.map-header__stats { display: flex; align-items: center; gap: 10px; }
.map-header__settings {
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
  border-radius: 50%;
  color: var(--slate-400);
  transition: background .12s ease;
}
.map-header__settings:active { background: rgba(255,255,255,.1); }

.map-canvas { position: relative; }

.map-freeplay-btn {
  position: sticky;
  bottom: 16px;
  z-index: 15;
  margin: 0 auto;
  display: block;
  width: fit-content;
}

.scenery {
  position: absolute;
  line-height: 1;
  user-select: none;
  pointer-events: none;
  opacity: .9;
}
.scenery--float { animation: floaty 4s ease-in-out infinite; }
.cloud { position: absolute; opacity: .6; animation: cloudDrift 6s ease-in-out infinite alternate; pointer-events: none; }

.trail-dot {
  position: absolute;
  width: 6px; height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  opacity: .85;
}
.trail-dot--done { background: var(--emerald-300); }
.trail-dot--active { background: var(--amber-200); }
.trail-dot--locked { background: var(--slate-600); }

.map-node-wrap { position: absolute; z-index: 10; }
.map-node__glow {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(252,211,77,.35), transparent 70%);
  filter: blur(6px);
  animation: pulseGlow 2.4s ease-in-out infinite;
}
.map-node__sparkle { position: absolute; font-size: 13px; animation: twinkle 1.8s ease-in-out infinite; }
/* Ekstra wrapper fordi animate-bob's keyframes sætter hele transform-værdien
   (kun translateY) — en inline translateX(-50%) på samme element ville blive
   overskrevet hver animations-frame. Centrering ligger derfor på slot'en. */
.map-node__mascot-slot { position: absolute; }
.map-node__mascot { display: block; font-size: 30px; animation: bob 2.2s ease-in-out infinite; }
.map-node__boss-ring {
  position: absolute;
  inset: -4px;
  border-radius: 20px;
  border: 2px dashed rgba(252,211,77,.6);
  animation: spin 9s linear infinite;
}

.map-node {
  position: relative;
  width: 56px; height: 56px;
  border-radius: 50%;
  border: 4px solid;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  box-shadow: 0 8px 16px -6px rgba(0,0,0,.5);
}
.map-node--done { background: var(--emerald-400); border-color: var(--emerald-200); color: var(--emerald-900); }
.map-node--current { background: var(--amber-300); border-color: var(--amber-100); color: var(--amber-900); box-shadow: 0 0 0 8px rgba(252,211,77,.25), 0 8px 16px -6px rgba(0,0,0,.5); animation: pulse 2s ease-in-out infinite; }
.map-node--locked { background: var(--slate-700); border-color: var(--slate-600); color: var(--slate-500); }
.map-node--boss { width: 64px; height: 64px; border-radius: 20px; transform: rotate(3deg); }
.map-node--boss.map-node--done { background: var(--emerald-400); }
.map-node--boss.map-node--locked { background: var(--slate-700); }
.map-node--just-unlocked { animation: pop .4s ease-out; }
.map-node-wrap.is-shaking .map-node { animation: shake .35s ease; }

.map-next-world {
  margin: 30px auto 40px;
  width: fit-content;
  text-align: center;
  background: rgba(30,41,59,.6);
  border: 1px solid rgba(51,65,85,.7);
  border-radius: 18px;
  padding: 14px 22px;
}
.map-next-world__label { color: var(--slate-400); font-size: 11px; }
.map-next-world__name { color: var(--white); font-family: var(--font-display); font-weight: 600; display: flex; align-items: center; gap: 6px; justify-content: center; margin-top: 2px; }

/* ============================================================
   ØVELSESFLOW
   ============================================================ */
.view-exercise {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--sky-100), var(--orange-50));
}
.exercise-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(env(safe-area-inset-top, 0) + 10px) 16px 10px;
  background: rgba(255,255,255,.7);
  border-bottom: 1px solid var(--orange-100);
}
/* __middle rummer progressbaren i level-tilstand og står tom i Øv frit —
   flex:1 spreder close/stat til hver sin side i begge tilfælde, uden at
   have brug for en separat --freeplay-layoutregel. */
.exercise-header__middle { flex: 1; min-width: 0; }
.exercise-header__stat { display: flex; align-items: center; gap: 4px; color: var(--amber-500); font-weight: 700; font-size: 14px; font-family: var(--font-display); }
.exercise-header__close {
  flex-shrink: 0;
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font-size: 20px;
  color: var(--slate-500);
  transition: background .12s ease, color .12s ease;
}
.exercise-header__close:active { background: rgba(15,23,42,.07); color: var(--slate-700); }
.exercise-header__combo { flex-shrink: 0; }
.exercise-header__combo[hidden] { display: none; }
.combo-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: rgba(139,92,246,.15);
  color: var(--color-bonus);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 12px;
  white-space: nowrap;
}
.combo-badge--pop { animation: pop .3s ease-out; }

.exercise-body {
  flex: 1;
  /* min-height:0 + overflow-y gør selve opgaveområdet til scroll-beholderen,
     så topbaren bliver stående, og intet indhold kan havne uden for skærmen
     på en lille telefon (V2 afsnit 13). */
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* "safe center" centrerer som normalt, men skifter til top-justering når
     indholdet er højere end beholderen — ellers ville toppen af opgaven blive
     skåret af og være umulig at scrolle op til. Den første erklæring er
     fallback for browsere der ikke kender safe-nøgleordet. */
  justify-content: center;
  justify-content: safe center;
  gap: 18px;
  /* Bundpolstring uden safe-area her — den flyttede med footeren nedenfor,
     som nu er det element der reelt rører telefonens fysiske underkant.
     To lag safe-area-inset ville bare have talt den samme indhakning to
     gange og spildt lodret plads. */
  padding: 16px 22px 16px;
  text-align: center;
  transition: background .3s ease;
}
/* Fase 4c: "overraskelsesspørgsmål" (V2-planens afsnit 4c) — samme
   øvelsesmotor, en tydeligt anderledes tone på selve krops-baggrunden,
   sammen med en begejstret Fiko-toast (fikoTwist() i fiko.js, se
   exercise.js' applyTwistVisuals). Bevidst INGEN loop-animation her, kun
   en statisk tint — appens øvrige tone er "aldrig overstimulerende"
   (ADHD-venlige principper), og en vedvarende bevægelse gennem hele
   spørgsmålet ville modarbejde det. */
.exercise-body--twist {
  background: linear-gradient(160deg, rgba(139,92,246,.16), rgba(244,114,182,.14));
}
.exercise-mascot { font-size: 64px; animation: bob 2.2s ease-in-out infinite; }
/* Fikos egen replik, adskilt fra den objektive system-feedback nede i
   footerens feedback-panel — to forskellige stemmer, holdt visuelt fra
   hinanden i stedet for stablet oven på hinanden. Tom og usynlig (0
   min-height) før et svar er givet. */
.fiko-caption {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  color: var(--slate-500);
  min-height: 16px;
}
.exercise-illustration {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 64px;
  font-size: 54px;
}
.exercise-illustration img { max-width: 130px; max-height: 130px; }
.exercise-target--word { font-family: var(--font-display); font-weight: 700; color: var(--slate-700); font-size: 26px; }

.sentence-frame {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  color: var(--slate-700);
  text-align: center;
  line-height: 1.5;
  max-width: 300px;
}
.sentence-frame strong { color: var(--emerald-600); }
.sentence-blank {
  display: inline-block;
  font-size: 28px;
  vertical-align: middle;
  padding: 0 3px;
}

.answer-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  width: 100%;
  max-width: 320px;
}
.answer-btn {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  min-height: 56px;
  border-radius: var(--radius-md);
  border: 2px solid var(--slate-200);
  /* Fysisk dybde (V2 afsnit 4.3): en tykkere bundkant der "trykkes flad"
     ved :active i stedet for kun en skalering — skal ligne en trykbar
     brik, ikke en flad hjemmesideknap. */
  border-bottom-width: 5px;
  background: var(--white);
  color: var(--slate-700);
  padding: 15px 8px;
  box-shadow: 0 4px 10px -6px rgba(0,0,0,.15);
  transition: transform .1s ease, border-bottom-width .1s ease, background .15s ease, color .15s ease, border-color .15s ease;
}
.answer-btn:active:not(:disabled) { transform: translateY(3px); border-bottom-width: 2px; }
.answer-btn.is-picked { background: var(--slate-200); border-color: var(--slate-400); color: var(--slate-700); }
.answer-btn.is-correct { background: var(--color-correct); border-color: var(--color-correct-border); color: var(--white); }
.answer-btn.is-gentle-wrong { background: var(--color-gentle); border-color: var(--color-gentle-border); color: var(--color-gentle-ink); }
.answer-btn:disabled { opacity: 1; }

/* Fase 4d.2: chat — Fikos spørgsmål og svarmulighederne som en
   samtaletråd i stedet for et knapgitter. Svarboblerne er STADIG
   .answer-btn (samme is-picked/is-correct/is-gentle-wrong-tilstande,
   samme klik-logik i wireFillBlankAnswers), kun layoutet er anderledes —
   .chat-bubble-option har højere specificitet end den delte .answer-btn
   og overskriver kun facade (form, bredde, justering), aldrig farverne. */
.chat-thread { display: flex; flex-direction: column; width: 100%; max-width: 320px; }
.chat-bubble--fiko {
  align-self: flex-start;
  background: var(--white);
  border: 2px solid var(--slate-200);
  border-radius: 18px 18px 18px 4px;
  padding: 12px 16px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.35;
  color: var(--slate-700);
  max-width: 260px;
  text-align: left;
}
.chat-options { display: flex; flex-direction: column; gap: 8px; width: 100%; max-width: 320px; }
.chat-bubble-option.answer-btn {
  align-self: flex-end;
  width: auto;
  max-width: 90%;
  min-height: auto;
  text-align: left;
  border-radius: 18px 18px 4px 18px;
  padding: 12px 16px;
  font-size: 14px;
  border-bottom-width: 2px;
}

/* Fase 4d.4: sætningsbygning — en stiplet "target"-boks der bliver massiv
   når den er fyldt, og en pulje af blandede ordbrikker nedenunder. Egne
   klassenavne (ikke .answer-btn), da dette ikke er svarmuligheder man
   vælger ÉN af, men brikker der flyttes frem og tilbage mellem to zoner. */
.sentence-build-target {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  align-items: center;
  min-height: 52px;
  width: 100%;
  max-width: 320px;
  padding: 10px;
  border-radius: var(--radius-md);
  border: 2px dashed var(--slate-200);
  background: rgba(255,255,255,.5);
}
.sentence-build-target.is-correct { border-style: solid; border-color: var(--color-correct-border); background: rgba(52,211,153,.12); }
.sentence-build-target.is-gentle-wrong { border-style: solid; border-color: var(--color-gentle-border); background: rgba(251,191,36,.12); }
.sentence-build-placeholder { color: var(--slate-400); font-size: 13px; }
.sentence-build-pool { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; width: 100%; max-width: 320px; }
.sentence-tile {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--slate-200);
  border-bottom-width: 4px;
  background: var(--white);
  color: var(--slate-700);
  min-height: 44px;
  transition: transform .1s ease, border-bottom-width .1s ease, background .15s ease;
}
.sentence-tile:active:not(:disabled) { transform: translateY(2px); border-bottom-width: 2px; }
.sentence-tile--built { background: var(--sky-100); border-color: var(--sky-400); }
.sentence-tile--reveal { background: rgba(52,211,153,.15); border-color: var(--color-correct-border); color: var(--color-correct-ink); }
.sentence-tile:disabled { opacity: 1; }

/* Fase 4b: "lyt og skriv"-feltet genbruger answer-btn's fysiske sprog
   (samme trykfladehøjde, samme is-correct/is-gentle-wrong-toner ved svar)
   men som et tekstfelt i stedet for en knap. */
.listen-write-input {
  width: 100%;
  max-width: 280px;
  min-height: 56px;
  border-radius: var(--radius-md);
  border: 2px solid var(--slate-200);
  border-bottom-width: 5px;
  background: var(--white);
  color: var(--slate-700);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  text-align: center;
  padding: 12px 16px;
  box-shadow: 0 4px 10px -6px rgba(0,0,0,.15);
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.listen-write-input::placeholder { color: var(--slate-400); font-weight: 600; font-size: 15px; }
.listen-write-input.is-correct { background: var(--color-correct); border-color: var(--color-correct-border); color: var(--white); }
.listen-write-input.is-gentle-wrong { background: var(--color-gentle); border-color: var(--color-gentle-border); color: var(--color-gentle-ink); }
.listen-write-input:disabled { opacity: 1; }

/* Feedbackpanelet bor i exercise-footer, ikke i den scrollende krop (Fase 3,
   V2 afsnit 6) — glider op sammen med bundknappen som ÉN samlet besked,
   i stedet for tekst midt i opgaveindholdet adskilt fra selve knappen. */
.feedback-panel {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  text-align: center;
  padding: 8px 14px;
  border-radius: var(--radius-md);
  animation: feedbackSlideUp .25s ease-out;
}
.feedback-panel--correct { background: rgba(52,211,153,.15); color: var(--color-correct-ink); }
.feedback-panel--gentle { background: rgba(251,191,36,.18); color: #b45309; }

.speak-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  border-radius: var(--radius-pill);
  padding: 12px 22px;
  font-family: var(--font-display);
  font-weight: 600;
  background: var(--color-info);
  color: var(--white);
  box-shadow: 0 6px 14px -6px rgba(99,102,241,.6);
}
.speak-btn:active { transform: scale(.97); }
.speak-hint { display: flex; align-items: center; gap: 5px; color: var(--slate-400); font-size: 12px; }

.pronounce-target {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 30px;
  color: var(--slate-700);
  text-align: center;
}
.pronounce-target--sentence {
  font-size: 22px;
  max-width: 300px;
  line-height: 1.4;
}
.pronounce-mic-btn {
  width: 84px; height: 84px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 34px;
  background: var(--indigo-500);
  color: var(--white);
  box-shadow: 0 10px 22px -8px rgba(99,102,241,.55);
  transition: transform .12s ease, background .15s ease;
}
.pronounce-mic-btn:active { transform: scale(.95); }
.pronounce-mic-btn.is-listening { background: var(--fuchsia-500); animation: pulse 1s ease-in-out infinite; }
.pronounce-result {
  font-family: var(--font-display);
  font-weight: 700;
  min-height: 22px;
  text-align: center;
}
.pronounce-result--good { color: var(--emerald-600); }
.pronounce-result--try { color: #b45309; }
.pronounce-skip {
  color: var(--slate-400);
  font-size: 13px;
  text-decoration: underline;
  /* Visuelt et lille tekstlink, men trykfladen løftes op mod de 48px V2
     afsnit 2.5 kræver af alt interaktivt — via polstring, ikke synlig
     boks-styling, så udtrykket forbliver et diskret "spring over". */
  padding: 16px 14px;
  margin-top: -8px;
}

/* ---------- Fast bundknap (V2 afsnit 5.5) -----------------------
   Egen flex-søster til exercise-body, ikke en del af dens scroll-
   indhold, så knappen altid er synlig og let at nå med tommelfingeren,
   uanset hvor langt opgaveindholdet ovenover er scrollet. */
.exercise-footer {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 22px calc(14px + env(safe-area-inset-bottom, 0px));
  background: rgba(255,255,255,.75);
  border-top: 1px solid var(--orange-100);
  /* Forhindrer at footeren klapper sammen til 0 højde og hopper, når den
     står tom mellem svar og næste spørgsmål (fx under udtale-trinnet). */
  min-height: 1px;
}
.exercise-primary-btn {
  width: 100%;
  min-height: 58px;
  border: none;
  border-bottom: 5px solid rgba(0,0,0,.15);
  transition: transform .1s ease, border-bottom-width .1s ease, background .15s ease, color .15s ease;
}
.exercise-primary-btn:active:not(:disabled) { transform: translateY(3px); border-bottom-width: 2px; }
.exercise-primary-btn--correct { background: var(--color-correct); color: var(--white); border-bottom-color: var(--emerald-600); }
.exercise-primary-btn--gentle { background: var(--color-gentle); color: var(--color-gentle-ink); border-bottom-color: var(--amber-500); }
/* Grå og inaktiv før et gyldigt svar, som V2 kræver — en dedikeret grå
   tone frem for blot en gennemsigtig amber, så "endnu ikke muligt" ikke
   kan forveksles med en svag udgave af den aktive knap. */
.exercise-primary-btn[disabled] { background: var(--slate-200); color: var(--slate-500); opacity: 1; box-shadow: none; border-bottom-color: var(--slate-400); }

.freeplay-running-stat {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--emerald-600);
  font-size: 13px;
  animation: pop .3s ease-out;
}

/* ---------- Fiko-toast (V2 afsnit 7) ----------------------------
   Kort hilsen ved sessionstart, ikke en del af nogens layout — position
   fixed, tonet ind og selv ud igen, aldrig i vejen for et tryk. */
.fiko-toast {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 66px);
  left: 50%;
  transform: translateX(-50%);
  max-width: 280px;
  z-index: 30;
  background: var(--white);
  border-radius: var(--radius-pill);
  padding: 10px 18px;
  box-shadow: 0 8px 20px -8px rgba(0,0,0,.25);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  color: var(--slate-700);
  text-align: center;
  pointer-events: none;
  animation: fikoToastIn .25s ease-out, fikoToastOut .3s ease-in 2.4s forwards;
}

/* ---------- Bekræftelse ved afbrudt level ----------------------
   Vises kun når luk-knappen trykkes midt i et level. Position fixed
   frem for absolute, så den dækker hele skærmen uanset hvor langt
   opgaveområdet er scrollet. */
.exit-confirm {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(15,23,42,.55);
  backdrop-filter: blur(3px);
  animation: fadeIn .18s ease-out;
}
.exit-confirm__card {
  width: 100%;
  max-width: 320px;
  background: var(--white);
  border-radius: var(--radius-lg);
  padding: 24px 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
  box-shadow: 0 24px 48px -18px rgba(0,0,0,.5);
  animation: pop .25s ease-out;
}
.exit-confirm__mascot { font-size: 48px; }
.exit-confirm__title { font-family: var(--font-display); font-weight: 700; font-size: 19px; color: var(--slate-700); }
.exit-confirm__body { color: var(--slate-500); font-size: 14px; line-height: 1.45; margin-bottom: 6px; }

/* ============================================================
   BELØNNINGSSKÆRM
   ============================================================ */
.view-reward {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: linear-gradient(180deg, var(--indigo-500), var(--violet-500), var(--fuchsia-500));
  padding: 20px;
}
.confetti-piece {
  position: absolute;
  bottom: 8%;
  font-size: 20px;
}
.reward-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
  padding: 0 12px;
}
.reward-content__mascot { font-size: 76px; animation: bob 2.2s ease-in-out infinite; }
.reward-content__title { font-family: var(--font-display); font-weight: 700; font-size: 24px; color: var(--white); }
.reward-content__subtitle { color: #e0e7ff; font-size: 14px; }

.reward-card {
  background: rgba(255,255,255,.96);
  border-radius: 24px;
  padding: 20px 22px;
  width: 100%;
  max-width: 300px;
  box-shadow: 0 20px 40px -16px rgba(0,0,0,.4);
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 6px;
}
.reward-row { display: flex; align-items: center; justify-content: space-between; }
.reward-row__label { display: flex; align-items: center; gap: 7px; color: var(--slate-600); font-weight: 700; font-size: 13px; }
.reward-row__value { font-family: var(--font-display); font-weight: 700; color: var(--slate-800); }
.reward-row__value--shield { color: var(--emerald-600); }

/* ============================================================
   FIKO-SKÆRM
   ============================================================ */
.view-fox {
  min-height: 100%;
  background: linear-gradient(180deg, var(--emerald-50), var(--teal-100));
  padding: calc(env(safe-area-inset-top, 0) + 22px) 20px 30px;
}
.fox-hero { text-align: center; padding-bottom: 20px; }
.fox-hero__mascot { font-size: 68px; animation: bob 2.2s ease-in-out infinite; }
.fox-hero__title { font-family: var(--font-display); font-weight: 700; font-size: 18px; color: #134e4a; margin-top: 8px; }
.fox-hero__subtitle { color: var(--teal-700); font-size: 13px; margin-top: 2px; }

/* "Din rejse" (2026-08-05) — samme fysiske sprog som fox-stage/fox-item
   (afrundede kort, teal/emerald-tema), men som rene tal frem for
   opgraderbare tilstande. */
.journey-stats { display: flex; gap: 8px; margin-bottom: 24px; }
.journey-stat {
  flex: 1;
  border-radius: 18px;
  border: 2px solid var(--teal-100);
  background: rgba(255,255,255,.7);
  padding: 14px 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
}
.journey-stat__icon { font-size: 18px; }
.journey-stat__value { font-family: var(--font-display); font-weight: 700; font-size: 17px; color: #134e4a; }
.journey-stat__label { font-size: 11px; color: var(--teal-700); }

/* "Næste mål" — én fremhævet kommende oplåsning, ikke hele listen på én
   gang (den fulde oversigt står stadig i fox-items nedenfor). Ren
   information, ingen mønt-mekanik (se computeNextGoal i app.js). */
.next-goal-card {
  display: flex;
  align-items: center;
  gap: 14px;
  border-radius: 18px;
  border: 2px solid var(--amber-300);
  background: var(--white);
  padding: 14px 16px;
  margin-bottom: 24px;
}
.next-goal-card__emoji { font-size: 32px; }
.next-goal-card__text { display: flex; flex-direction: column; gap: 2px; }
.next-goal-card__label { font-family: var(--font-display); font-weight: 700; font-size: 14px; color: var(--slate-700); }
.next-goal-card__distance { font-size: 12px; color: var(--teal-700); }
.next-goal-card--done { border-color: var(--emerald-300); justify-content: center; text-align: center; }
.next-goal-card--done .next-goal-card__label { color: var(--emerald-600); }

.fox-stages { display: flex; gap: 8px; margin-bottom: 24px; }
.fox-stage {
  flex: 1;
  border-radius: 18px;
  border: 2px solid var(--teal-100);
  background: rgba(255,255,255,.7);
  padding: 16px 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.fox-stage.is-active { background: var(--white); border-color: var(--amber-300); box-shadow: 0 6px 16px -8px rgba(0,0,0,.15); }
.fox-stage__mascot { font-size: 24px; }
.fox-stage.is-locked .fox-stage__mascot { opacity: .3; filter: grayscale(1); }
.fox-stage__label { font-family: var(--font-display); font-weight: 600; font-size: 12px; color: #115e59; }
.fox-stage__req { font-size: 11px; color: var(--teal-700); }

.fox-section-title { font-family: var(--font-display); font-weight: 600; color: #134e4a; margin-bottom: 12px; }
.fox-items { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.fox-item {
  border-radius: 18px;
  border: 2px solid var(--emerald-200);
  background: var(--white);
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.fox-item.is-locked { border-color: var(--slate-200); background: rgba(255,255,255,.5); }
.fox-item__emoji { font-size: 30px; }
.fox-item.is-locked .fox-item__emoji { opacity: .3; filter: grayscale(1); }
.fox-item__label { font-family: var(--font-display); font-weight: 600; font-size: 14px; color: var(--slate-700); }
.fox-item__status { font-size: 11px; font-weight: 700; }
.fox-item__status--unlocked { color: var(--emerald-600); }
.fox-item__status--locked { display: flex; align-items: center; gap: 4px; color: var(--slate-400); }

/* ============================================================
   INDSTILLINGER (V2 afsnit 14)
   ============================================================ */
.view-settings {
  min-height: 100%;
  background: linear-gradient(180deg, var(--emerald-50), var(--teal-100));
  padding: calc(env(safe-area-inset-top, 0) + 14px) 20px 30px;
}
.settings-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 20px;
}
.settings-header__back {
  min-height: 48px;
  padding: 0 14px 0 4px;
  font-family: var(--font-display);
  font-weight: 700;
  color: #134e4a;
}
.settings-header__title { font-family: var(--font-display); font-weight: 700; font-size: 19px; color: #134e4a; }

.settings-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  min-height: 58px;
}
.settings-row__label { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 600; color: var(--slate-700); font-size: 15px; }
.settings-row__icon { font-size: 20px; }

/* Til/fra-kontakt bygget på en almindelig checkbox for rigtig
   tastatur/skærmlæser-understøttelse, blot visuelt gjort om til en
   kontakt — ingen JS-styret "fake toggle" nødvendig. */
.settings-toggle { position: relative; width: 48px; height: 28px; flex-shrink: 0; }
.settings-toggle input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.settings-toggle__track {
  position: absolute;
  inset: 0;
  background: var(--slate-400);
  border-radius: var(--radius-pill);
  transition: background .15s ease;
}
.settings-toggle__thumb {
  position: absolute;
  top: 3px; left: 3px;
  width: 22px; height: 22px;
  background: var(--white);
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0,0,0,.2);
  transition: transform .15s ease;
}
.settings-toggle input:checked ~ .settings-toggle__track { background: var(--color-correct); }
.settings-toggle input:checked ~ .settings-toggle__thumb { transform: translateX(20px); }

/* ============================================================
   ANIMATIONER
   ============================================================ */
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fikoToastIn { from { opacity: 0; transform: translate(-50%, -8px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes fikoToastOut { to { opacity: 0; transform: translate(-50%, -8px); } }
@keyframes feedbackSlideUp { from { transform: translateY(14px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes pop { 0% { transform: scale(.6); opacity: 0; } 60% { transform: scale(1.12); opacity: 1; } 100% { transform: scale(1); } }
@keyframes drift { 0% { transform: translateY(0) rotate(0deg); opacity: 1; } 100% { transform: translateY(-140px) rotate(180deg); opacity: 0; } }
@keyframes twinkle { 0%, 100% { opacity: .25; transform: scale(.8); } 50% { opacity: 1; transform: scale(1.15); } }
@keyframes floaty { 0%, 100% { transform: translate(0,0) rotate(0deg); } 50% { transform: translate(6px,-10px) rotate(6deg); } }
@keyframes cloudDrift { 0% { transform: translateX(0); } 100% { transform: translateX(24px); } }
@keyframes pulse { 0%, 100% { box-shadow: 0 0 0 8px rgba(252,211,77,.25), 0 8px 16px -6px rgba(0,0,0,.5); } 50% { box-shadow: 0 0 0 14px rgba(252,211,77,.12), 0 8px 16px -6px rgba(0,0,0,.5); } }
@keyframes pulseGlow { 0%, 100% { opacity: .5; transform: scale(1); } 50% { opacity: .9; transform: scale(1.08); } }
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; }
}
/* Samme effekt, men som et bevidst tilvalg i appens egne indstillinger
   (V2 afsnit 14), uafhængigt af enhedens OS-niveau — nogle vil reducere
   bevægelse her uden at skulle ændre det globalt på hele telefonen. */
:root.force-reduced-motion * {
  animation-duration: .001ms !important;
  animation-iteration-count: 1 !important;
}
