/* App chrome, screens, and the overlays. Mobile-first throughout. */

body {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

/* --- App bar -------------------------------------------------------- */

.appbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg-deep) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.appbar__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: var(--space-2) var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.appbar__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--ink);
  text-decoration: none;
  font-weight: 700;
  letter-spacing: -0.02em;
  min-height: var(--touch-min);
}
.appbar__mark { color: var(--accent); display: grid; place-items: center; }
.appbar__name { font-size: var(--step-1); }

.appbar__nav {
  display: flex;
  gap: var(--space-1);
  margin-left: auto;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.appbar__nav::-webkit-scrollbar { display: none; }

.appbar__nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  text-decoration: none;
  font-weight: 550;
  font-size: var(--step--1);
  white-space: nowrap;
}
.appbar__nav a:hover { color: var(--ink); background: var(--surface); }
.appbar__nav a.is-active { color: var(--accent); background: var(--accent-soft); }

/* --- Page ----------------------------------------------------------- */

.page {
  flex: 1;
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding: var(--space-5) var(--space-4) var(--space-7);
}
.page:focus { outline: none; }

.screen__head { margin-bottom: var(--space-5); }
.screen__head .lede { margin-top: var(--space-2); font-size: var(--step-0); }
.screen__head > .btn { margin-bottom: var(--space-3); }

/* --- Progress strip -------------------------------------------------- */

.progress-strip { margin-bottom: var(--space-5); }
.progress-strip__bar {
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  overflow: hidden;
  margin-bottom: var(--space-2);
}
.progress-strip__bar > i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--gold));
  transition: width var(--slow) var(--ease);
}

/* --- Puzzle cards ---------------------------------------------------- */

.puzzle-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}

.puzzle-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.puzzle-card:hover { border-color: var(--border-strong); }
.puzzle-card__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); height: 100%; }
.puzzle-card__skill { margin: 0; text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; font-weight: 650; }
.puzzle-card__blurb { margin: 0; color: var(--ink-muted); font-size: var(--step--1); flex: 1; }
.puzzle-card__actions { margin-top: auto; }

.puzzle-card__levels { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.levelchip {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-sunken);
  color: var(--ink-muted);
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.levelchip:hover:not(.is-locked) { border-color: var(--accent); color: var(--accent); }
.levelchip.is-solved { background: var(--ok-soft); border-color: transparent; color: var(--ok); }
.levelchip.is-locked { opacity: 0.4; cursor: not-allowed; }

/* Touch targets: 36px is fine for a dense grid on a pointer device, but on a
   coarse pointer they need the full 44. */
@media (pointer: coarse) {
  .levelchip { width: var(--touch-min); height: var(--touch-min); }
}

/* --- Level screen ---------------------------------------------------- */

.level__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.level__title { flex: 1; min-width: 0; }
.level__title h1 { font-size: var(--step-2); }
.level__title p { margin: 0; }

/* --- Tutorials ------------------------------------------------------- */

.tutorial-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.tutorial-list .card { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }

/* --- Forms ----------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field__label { font-weight: 600; font-size: var(--step--1); }

.select {
  font: inherit;
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-sunken);
  color: var(--ink);
  width: 100%;
  max-width: 320px;
}

.check { display: flex; align-items: center; gap: var(--space-3); cursor: pointer; min-height: var(--touch-min); }
.check input[type="checkbox"] {
  width: 20px; height: 20px; flex: none; margin: 0;
  accent-color: var(--accent);
}

.settings__about { margin-top: var(--space-6); }
.settings__about p { margin: 0 0 var(--space-1); }

/* --- Footer ---------------------------------------------------------- */

.sitefoot {
  border-top: 1px solid var(--border);
  background: var(--bg-deep);
  margin-top: auto;
}
.sitefoot__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: var(--space-5) var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  align-items: center;
  justify-content: space-between;
}
.sitefoot__links { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.sitefoot__links a { color: var(--ink-muted); }
.sitefoot__links a:hover { color: var(--accent); }

/* --- Result dialog --------------------------------------------------- */

.result {
  position: fixed;
  inset: 0;
  /* Above the consent banner: if both are open, the one the player just
     triggered is the one they need to act on. */
  z-index: 65;
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--bg-deep) 82%, transparent);
  backdrop-filter: blur(4px);
  animation: fade var(--normal) var(--ease);
}
.result__card {
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
  max-width: 380px;
  width: 100%;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  align-items: center;
}
.result__icon { color: var(--gold); }
.result__stats {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-2) var(--space-4);
  width: 100%;
  margin: 0;
  text-align: left;
  font-size: var(--step--1);
}
.result__stats dt { color: var(--ink-muted); }
.result__stats dd { margin: 0; font-weight: 650; font-variant-numeric: tabular-nums; }
.result__stat { display: contents; }
.result__actions { display: flex; gap: var(--space-3); flex-wrap: wrap; justify-content: center; width: 100%; }
.result__actions .btn { flex: 1; min-width: 130px; }

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* --- Consent banner --------------------------------------------------- */

.consent {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 60;
  background: var(--surface-raised);
  border-top: 2px solid var(--accent);
  box-shadow: var(--shadow-lg);
  padding: var(--space-5) var(--space-4) calc(var(--space-5) + env(safe-area-inset-bottom));
}
.consent__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.consent__title { font-size: var(--step-1); }
.consent__body { margin: 0; font-size: var(--step--1); }

/* Both buttons are identical in size and weight. Reject is never de-emphasised. */
.consent__actions { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.consent__actions .btn { flex: 1; min-width: 160px; }

@media (min-width: 720px) {
  .consent__inner { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--space-3) var(--space-6); }
  .consent__title { grid-column: 1; }
  .consent__body { grid-column: 1; }
  .consent__actions { grid-column: 2; grid-row: 1 / span 3; flex-direction: column; }
  .consent__inner > p.small:last-child { grid-column: 1; }
}

/* --- Tour ------------------------------------------------------------- */

.tour { position: fixed; inset: 0; z-index: 70; }

.tour__spotlight {
  position: fixed;
  border-radius: var(--radius);
  border: 2px solid var(--accent);
  /* A huge spread shadow dims everything except the cut-out. */
  box-shadow: 0 0 0 9999px color-mix(in srgb, var(--bg-deep) 78%, transparent);
  transition: all var(--normal) var(--ease);
  pointer-events: none;
}

.tour__bubble {
  position: fixed;
  left: var(--space-4);
  right: var(--space-4);
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  /* A fixed box taller than the viewport cannot be scrolled to, so at 200% zoom
     the buttons simply went off the screen inside a focus-trapped dialog. The
     cap means the bubble's own content scrolls instead, and it is also what
     lets the JS clamp always have a valid range to clamp into.
     dvh first: on mobile the browser chrome makes vh taller than what is
     actually visible, which is the case that needs this most. */
  max-height: calc(100vh - var(--space-4) * 2);
  max-height: calc(100dvh - var(--space-4) * 2);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.tour__title { font-size: var(--step-1); }
.tour__body { margin: 0; font-size: var(--step--1); color: var(--ink-muted); }
.tour__count { margin: 0; }
/* Pinned to the bottom of the bubble, because the bubble is capped at the
   viewport and its text scrolls inside it. Without this the Next button is the
   first thing to disappear on a short screen — the one control the player
   needs most. */
.tour__actions {
  display: flex;
  /* Wraps because the labels are translated: "Anleitung überspringen" and
     "Verstanden" together are wider than a 320px screen, and without wrapping
     the primary button simply left the viewport. */
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  position: sticky;
  bottom: calc(var(--space-5) * -1);
  padding: var(--space-2) 0 var(--space-5);
  margin-bottom: calc(var(--space-5) * -1);
  background: var(--surface-raised);
}

/* Skip sits apart from Back and Next, and takes its own row once they wrap. */
.tour__skip { margin-inline-end: auto; }

@media (min-width: 720px) {
  .tour__bubble { right: auto; bottom: auto; width: 360px; }
  .tour__bubble.is-centred {
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
  }
}
@media (max-width: 719px) {
  /* On a phone the bubble is always pinned; a floating box covers the target. */
  .tour__bubble { top: auto !important; left: var(--space-4) !important; }
}

/* --- Error screen ----------------------------------------------------- */

.errorscreen {
  max-width: 520px;
  margin: var(--space-7) auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  align-items: center;
}

/* --- Language switcher on the legal pages ------------------------------ *
 * Plain links, no JavaScript: these are the pages someone reads when
 * something else has gone wrong.
 * ---------------------------------------------------------------------- */

.langswitch {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  align-items: baseline;
}
.langswitch > p { margin: 0 var(--space-2) 0 0; width: 100%; }
.langswitch a,
.langswitch span {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  text-decoration: none;
}
.langswitch a { color: var(--ink-muted); }
.langswitch a:hover { color: var(--accent); border-color: var(--accent); }
.langswitch span[aria-current] {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: transparent;
  font-weight: 650;
}
@media (pointer: coarse) {
  .langswitch a, .langswitch span { min-height: var(--touch-min); }
}

/* --- Legal / content pages -------------------------------------------- */

.prose { max-width: var(--measure); }
.prose h2 { margin-top: var(--space-6); margin-bottom: var(--space-3); }
.prose h3 { margin-top: var(--space-5); margin-bottom: var(--space-2); }
.prose table { width: 100%; border-collapse: collapse; margin-bottom: var(--space-4); font-size: var(--step--1); }
.prose th, .prose td { text-align: left; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border); vertical-align: top; }
.prose th { color: var(--ink-muted); font-weight: 650; }
.prose dt { font-weight: 650; margin-top: var(--space-4); }
.prose dd { margin: var(--space-1) 0 0; color: var(--ink-muted); }

/* ------------------------------------------------------------------ *
 * FAQ
 * ------------------------------------------------------------------ */

/* A question list at the top: thirteen answers is more than fits on a phone
   screen, and the anchors are the point of the page. */
.faq-toc {
  margin: var(--space-5) 0;
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-sunken);
}

.faq-toc ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.faq-toc a { font-size: var(--step--1); }
