/* ==========================================================================
   HMS-melding — Umoe Industries AS
   Designsystem: «industriell presisjon, rolig premium».
   Ett grønt aksentspråk på varmt papir, ekte elevasjonsskala, rolig bevegelse.
   Alle trykkflater er minst 56 px slik at de kan brukes med arbeidshansker.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  color-scheme: light;

  /* Merkevaregrønn.
     `--umoe-green` er logofargen og ankeret for hele skalaen. Har dere den
     eksakte verdien fra designmanualen, bytt den her — og i `icon.svg`,
     `logo.svg` og `theme-color` i `index.html` / `manifest.json`. */
  --umoe-green: #00552b;

  --brand-50:  #ebf3ee;
  --brand-100: #d2e6da;
  --brand-200: #a4cdb6;
  --brand-300: #69b08c;
  --brand-400: #2c9260;
  --brand-500: #0a7c45;
  --brand-600: #026738;
  --brand-700: #00552b;  /* logogrønn */
  --brand-800: #004123;
  --brand-900: #002b17;

  /* Nøytraler med et varmt grønnstikk */
  --ink-900: #0c1710;
  --ink-600: #47574d;
  --ink-500: #67766c;
  --ink-400: #8b988f;
  --ink-300: #b7c1ba;
  --ink-200: #d7ded9;
  --ink-100: #e9ede9;
  --ink-50:  #f3f5f2;

  /* Flater */
  --paper: #edf2ee;
  --surface: #f9fbf9;
  --surface-2: #f4f8f5;
  --surface-sunken: #e7eee9;
  --line: #cedbd2;
  --line-strong: #b8cbbd;

  --text: var(--ink-900);
  --text-2: var(--ink-600);
  --text-3: var(--ink-500);
  --text-inv: #ffffff;

  --accent: var(--brand-700);
  --accent-soft: var(--brand-50);
  --accent-ring: rgba(0, 85, 43, 0.22);

  /* Fylte flater med hvit tekst. Egne tokens, fordi den lyse aksenten i mørk
     modus ikke gir nok kontrast mot hvit tekst (WCAG AA). */
  --accent-fill: var(--brand-700);
  --accent-fill-hover: var(--brand-600);
  --pos-fill: #0a7c45;
  /* Tekst på sterke statusfarger (feil, advarsel) */
  --on-tone: #ffffff;
  --track-off: var(--ink-300);

  /* Positiv melding — samme grønn, men lysere og varmere enn aksenten, slik at
     de to modusene er synlig forskjellige uten å bytte merkevarefarge. */
  --pos: #0a7c45;
  --pos-soft: #e7f5ec;
  --pos-line: #a9d6bd;

  /* Alvorlighetsskala — kalibrert for kontrast på lyst papir */
  --sev-1: #2e7d32;  --sev-1-soft: #e9f4ea;
  --sev-2: #ad6800;  --sev-2-soft: #fbf0dc;
  --sev-3: #c2410c;  --sev-3-soft: #fdeade;
  --sev-4: #b3261e;  --sev-4-soft: #fce8e6;

  --danger: #b3261e;
  --danger-soft: #fce8e6;
  --danger-line: #f0bdb8;
  --warn: #ad6800;
  --warn-soft: #fbf0dc;
  --warn-line: #ecd3a3;
  --ok: #2e7d32;

  /* Elevasjon — to lag: kontaktskygge + myk spredning */
  --e1: 0 1px 2px rgba(12, 23, 16, 0.05);
  --e2: 0 1px 2px rgba(12, 23, 16, 0.05), 0 6px 16px -10px rgba(12, 23, 16, 0.22);
  --e3: 0 1px 3px rgba(12, 23, 16, 0.06), 0 14px 32px -16px rgba(12, 23, 16, 0.28);
  --e4: 0 2px 6px rgba(12, 23, 16, 0.07), 0 28px 60px -24px rgba(12, 23, 16, 0.34);

  /* Mørk flate — poengligaen, quizen og adminpanelet er ett lag, ikke tre.
     Hver seksjon satte før sin egen gradient og sine egne hvitnivåer: to
     gradientoppskrifter, to kantfarger og tre forskjellige tekstfarger på det
     som skulle leses som samme produkt. Verdiene står her, én gang. */
  --dark-1: #0d2117;
  --dark-2: #123a26;
  --dark-3: #07542d;
  --dark-line: #183b29;
  --dark-surface: linear-gradient(135deg, var(--dark-1) 0%, var(--dark-2) 62%, var(--dark-3) 100%);
  --dark-ring: rgba(136, 219, 170, 0.18);

  /* Tekst på mørk flate — tre nivåer, som --text / --text-2 / --text-3 på
     papir. Nivå 3 er den lyse merkevaregrønna og bærer stikktitlene. */
  --on-dark: #ffffff;
  --on-dark-2: #c9d9cf;
  --on-dark-3: #8ed3aa;

  /* Glasskortene som ligger oppå den mørke flata. Kantlinja er lys grønn, ikke
     hvit — da leses kanten som refraksjon i grønt lys og ikke som en ramme. */
  --glass-fill: linear-gradient(135deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.06));
  --glass-line: rgba(179, 225, 197, 0.28);
  --glass-inner: inset 0 1px rgba(255, 255, 255, 0.12);

  /* Elevasjon på mørk flate. Samme to-lags oppskrift som --e1..--e4, men tonet
     mot --dark-1 i stedet for rent svart: en svart skygge på en grønnsvart
     flate leses som skitt, ikke som dybde. */
  --de2: 0 1px 2px rgba(5, 16, 10, 0.34), 0 10px 22px -10px rgba(5, 16, 10, 0.5);
  --de3: 0 2px 4px rgba(5, 16, 10, 0.36), 0 16px 35px -14px rgba(5, 16, 10, 0.58);

  /* Kornstruktur. Lå inline i .auth-aside; nå har den mørke flata samme
     tekstur, og URI-en står på ett sted. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");

  /* Form */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-pill: 999px;
  --tap: 56px;

  /* Rytme */
  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px; --sp-5: 20px;
  --sp-6: 24px; --sp-7: 32px; --sp-8: 40px;  --sp-9: 56px;

  /* Bevegelse */
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 0.14s;
  --t-base: 0.24s;
  --t-slow: 0.42s;

  --font-display: 'Barlow Condensed', 'Arial Narrow', sans-serif;
  --font-body: 'Barlow', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  --shell: 1360px;

  /* Språkvelgeren ligger fast oppe til høyre. Topplinja holder av plassen med
     denne, i stedet for med et løst piksltall to steder i fila. Velgeren står
     lukket, så det holder å reservere bredden på den ene flisa — de utslåtte
     valgene legger seg over topplinja mens de er framme. */
  --picker-gutter: 116px;

  /* Lagrekkefølge — én skala i stedet for spredte tall */
  --z-topbar: 60;
  --z-actionbar: 70;
  --z-lightbox: 120;
  --z-toast: 140;
  --z-boot: 200;
  /* Innloggingssekvensen legger seg over alt annet mens den spilles — også
     over oppstartsskjermen, som ligger og venter under. */
  --z-launch: 205;
  --z-skip: 210;
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 120px;
}

body {
  font-family: var(--font-body);
  font-size: clamp(16px, 0.25vw + 15px, 18px);
  line-height: 1.55;
  color: var(--text);
  /* Svakt grønt lys øverst gir flaten dybde uten å bli dekor. */
  background:
    radial-gradient(1100px 420px at 12% -160px, color-mix(in srgb, var(--accent) 8%, transparent), transparent 72%),
    var(--paper);
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'kern' 1, 'liga' 1;
  overflow-wrap: break-word;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

::selection { background: var(--accent-fill); color: #fff; }

/* Hopp-lenke for tastaturbrukere: usynlig til den får fokus. */
.skip {
  position: fixed;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: var(--z-skip);
  padding: 10px 16px;
  border-radius: var(--r-sm);
  background: var(--accent-fill);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--t-base) var(--ease);
}
.skip:focus { transform: none; outline-offset: 3px; }

/* --------------------------------------------------------------------------
   3. Merke
   -------------------------------------------------------------------------- */

/* Logoen er ett SVG-symbol (#umoe-mark) pluss ordet «INDUSTRIES» som HTML-tekst,
   slik at ordet settes i den samme skriften som resten av grensesnittet.
   `--mark-h` styrer hele lockupen; alt annet skalerer fra den. */

.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.62em;
  flex: none;
  --mark-h: 30px;
  font-size: calc(var(--mark-h) * 0.4);
  line-height: 1;
}

/* Merket alene: UM / OE / strek. Tegnes i currentColor. */
.logo-mark {
  width: calc(var(--mark-h) * 0.851); /* 200/235 — merkets bredde/høyde */
  height: var(--mark-h);
  flex: none;
  color: var(--umoe-green);
}

.logo-word {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--umoe-green);
}

/* Grønn flis med hvit logo — brukes der bakgrunnen er lys. */
.logo-tile {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: calc(var(--mark-h) * 1.62);
  height: calc(var(--mark-h) * 1.62);
  border-radius: calc(var(--mark-h) * 0.3);
  background: var(--umoe-green);
}
.logo-tile .logo-mark { color: #fff; }

/* --------------------------------------------------------------------------
   4. Oppstartsskjerm
   -------------------------------------------------------------------------- */

.boot {
  position: fixed;
  inset: 0;
  z-index: var(--z-boot);
  display: grid;
  place-items: center;
  gap: var(--sp-5);
  background: var(--paper);
  transition: opacity var(--t-slow) var(--ease), visibility var(--t-slow);
}
.boot.done { opacity: 0; visibility: hidden; pointer-events: none; }
.boot .logo { --mark-h: 44px; animation: breathe 2.4s var(--ease) infinite; }
.boot-bar {
  width: 148px; height: 3px;
  border-radius: var(--r-pill);
  background: var(--line);
  overflow: hidden;
}
.boot-bar::after {
  content: '';
  display: block;
  width: 40%; height: 100%;
  border-radius: inherit;
  background: var(--accent);
  animation: slide 1.15s var(--ease) infinite;
}
@keyframes slide { 0% { transform: translateX(-110%); } 100% { transform: translateX(360%); } }
@keyframes breathe { 50% { opacity: 0.55; } }

/* --------------------------------------------------------------------------
   5. Innlogging
   -------------------------------------------------------------------------- */

.auth {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1.05fr minmax(440px, 0.95fr);
  background: var(--surface);
  padding-top: env(safe-area-inset-top);
}

.auth-aside {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(32px, 4vw, 56px);
  color: var(--text);
  background:
    radial-gradient(120% 90% at 8% 4%, #d9f3e3 0%, transparent 55%),
    radial-gradient(95% 80% at 92% 96%, #bfe5cf 0%, transparent 60%),
    linear-gradient(155deg, #f4fbf6 0%, #e6f3eb 100%);
  overflow: hidden;
}
.auth-aside::before {
  /* Fin rutenettsstruktur — leses som målebånd, ikke dekor */
  content: '';
  position: absolute;
  inset: -10%;
  z-index: -1;
  background-image:
    linear-gradient(rgba(0, 85, 43, 0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 85, 43, 0.06) 1px, transparent 1px);
  background-size: 64px 64px;
  transform: perspective(700px) rotateX(48deg) scale(1.6);
  transform-origin: 50% 100%;
  opacity: 0.7;
  mask-image: linear-gradient(to top, #000 0%, transparent 72%);
}
.auth-aside::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.4;
  background-image: var(--grain);
  mix-blend-mode: overlay;
  pointer-events: none;
}
.auth-aside .logo { --mark-h: 52px; }

.auth-pitch h2 {
  font-family: var(--font-display);
  font-size: clamp(38px, 4.4vw, 62px);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.005em;
  text-wrap: balance;
  max-width: 13ch;
}
.auth-pitch h2 em { font-style: normal; color: var(--brand-600); }
.auth-pitch p {
  margin-top: var(--sp-4);
  max-width: 42ch;
  color: var(--text-2);
  font-size: 17px;
}

.auth-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-2);
}
.auth-meta span { display: inline-flex; align-items: center; gap: var(--sp-2); }
.auth-meta span::before {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--brand-300);
}

.auth-panel {
  display: grid;
  align-content: center;
  padding: clamp(40px, 6vw, 72px) clamp(24px, 5vw, 76px);
  background: var(--surface);
}
.auth-form { max-width: 400px; width: 100%; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.eyebrow::before {
  content: '';
  width: 18px; height: 1.5px;
  background: currentColor;
}

.auth-form h1 {
  margin: var(--sp-3) 0 var(--sp-3);
  font-family: var(--font-display);
  font-size: clamp(38px, 5vw, 50px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.01em;
}
.auth-intro { color: var(--text-2); margin-bottom: var(--sp-7); text-wrap: pretty; }
.auth-help {
  margin-top: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
  color: var(--text-3);
  font-size: 13.5px;
}
.auth-panel .field + .field { margin-top: var(--sp-4); }
#login-error { min-height: 22px; }
#login-button { margin-top: var(--sp-2); }

/* --------------------------------------------------------------------------
   5b. Språket først

   Under halvparten av dem som melder har norsk som førstespråk. Valget lå i en
   flis oppe i høyre hjørne — riktig plassert for et bytte, feil plassert for
   et førstevalg. På landingssida er språket derfor sitt eget steg, i full
   bredde, før etternavn og passord i det hele tatt vises. Er språket valgt før,
   hoppes steget over og det samme valget ligger som en stripe over skjemaet.
   -------------------------------------------------------------------------- */

/* På innloggingssida er språket allerede framme i panelet. Da skal ikke
   hjørneflisa stå og konkurrere med det. */
body.auth-open .language-picker { display: none; }

.auth-language { max-width: 440px; width: 100%; }
.auth-language h1 {
  margin: var(--sp-3) 0 var(--sp-2);
  font-family: var(--font-display);
  font-size: clamp(34px, 4.6vw, 46px);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.01em;
}
/* Andrelinja står på engelsk uansett valgt språk: den som ikke leser norsk
   skal kjenne igjen hva skjermen spør om, før noe er valgt. */
.auth-language h1 span {
  display: block;
  color: var(--text-3);
  font-size: 0.46em;
  font-family: var(--font-body);
  font-weight: 500;
  letter-spacing: 0.01em;
}
.auth-language .auth-intro { margin-bottom: var(--sp-5); }
.auth-language .lang-help { margin-top: var(--sp-5); }

.lang-grid { display: grid; gap: var(--sp-3); }
.lang-grid button {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-4);
  min-height: 72px;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  box-shadow: var(--e1);
  transition:
    border-color var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease),
    box-shadow var(--t-base) var(--ease),
    transform var(--t-fast) var(--ease);
}
.lang-grid button:hover { border-color: var(--ink-400); box-shadow: var(--e2); transform: translateY(-2px); }
.lang-grid button:active { transform: scale(0.99); box-shadow: var(--e1); }
.lang-grid button.active {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: var(--e2), inset 0 0 0 1px var(--accent);
}
.lang-grid .flag {
  width: 40px; height: 29px;
  flex: none;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.14);
}
.lang-grid span { display: grid; min-width: 0; }
.lang-grid b {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
}
.lang-grid i { color: var(--text-3); font-style: normal; font-size: 13.5px; line-height: 1.3; }
.lang-grid .tick {
  width: 22px; height: 22px;
  color: var(--accent);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease-out);
}
.lang-grid button.active .tick { opacity: 1; transform: none; }

#auth-language-done { margin-top: var(--sp-6); }

/* Stripa over skjemaet: samme valg, mindre plass. Den står der hele tiden, så
   et feilvalg kan rettes uten å logge inn først. */
.auth-strip {
  display: flex;
  gap: 6px;
  margin-bottom: var(--sp-6);
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  width: max-content;
  max-width: 100%;
}
.auth-strip button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 40px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.auth-strip button:hover { background: var(--surface); color: var(--text); }
.auth-strip button:active { transform: scale(0.94); }
.auth-strip button.active { background: var(--accent-fill); color: #fff; box-shadow: var(--e1); }
.auth-strip .flag { width: 20px; height: 15px; flex: none; border-radius: 2px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.14); }
.auth-strip abbr { text-decoration: none; }

/* --------------------------------------------------------------------------
   5b-2. Appen på hjemskjermen

   Steget mellom språket og innloggingen, bare på telefon og nettbrett i
   nettleseren. Samme oppsett som språksteget: overskrift, én forklaring, og så
   det som skal gjøres. Veiledningen er nummererte steg med ikonet brukeren
   faktisk skal lete etter på skjermen — Del-ikonet på iPhone, menyprikkene på
   Android — så de kan kjenne det igjen uten å lese hele setningen.
   -------------------------------------------------------------------------- */
.auth-install { max-width: 440px; width: 100%; }
.auth-install h1 {
  margin: var(--sp-3) 0 var(--sp-2);
  font-family: var(--font-display);
  font-size: clamp(34px, 4.6vw, 46px);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.01em;
}
.auth-install .auth-intro { margin-bottom: var(--sp-5); }

/* Slik appen kommer til å se ut på skjermen: ikonet og navnet. */
.install-app {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-sunken);
}
.install-app img {
  flex: none;
  width: 52px; height: 52px;
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(12, 23, 16, 0.18), 0 8px 18px -10px rgba(0, 60, 30, 0.55);
}
.install-app span { display: grid; min-width: 0; }
.install-app b { font: 600 19px/1.15 var(--font-display); letter-spacing: 0.01em; }
.install-app small { color: var(--text-3); font-size: 13.5px; }

.install-block .btn svg { width: 22px; height: 22px; }
.install-block .btn { gap: 10px; }
.install-note { margin-top: var(--sp-3); color: var(--text-3); font-size: 13.5px; text-align: center; }

.install-steps { display: grid; gap: var(--sp-3); margin: 0; padding: 0; list-style: none; counter-reset: install; }
.install-steps li {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  align-items: start;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--e1);
  counter-increment: install;
}
/* Ikonflisa bærer stegnummeret i hjørnet, så rekkefølgen er lesbar uten tekst. */
.install-key {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border: 1px solid var(--brand-200);
  border-radius: 12px;
  background: var(--accent-soft);
  color: var(--accent);
}
.install-key svg { width: 22px; height: 22px; }
.install-key::after {
  content: counter(install);
  position: absolute;
  top: -7px; left: -7px;
  display: grid;
  place-items: center;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--accent-fill);
  color: #fff;
  font: 700 11px/1 var(--font-body);
  box-shadow: 0 0 0 2px var(--surface);
}
/* Ett steg er ikke en rekkefølge. Da står nummeret ikke. */
.install-steps li:only-child .install-key::after { display: none; }
.install-steps li > span:last-child { display: grid; gap: 3px; padding-top: 2px; }
.install-steps b { font-weight: 600; line-height: 1.35; }
.install-steps small { color: var(--text-3); font-size: 13.5px; line-height: 1.45; }

.install-done {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--pos-line);
  border-radius: var(--r-lg);
  background: var(--pos-soft);
}
.install-done-mark {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--accent-fill);
  color: #fff;
}
.install-done-mark svg { width: 20px; height: 20px; }
.install-done p { display: grid; gap: 2px; margin: 0; }
.install-done p span { color: var(--text-2); font-size: 14px; }

.install-copy, .install-later { gap: 9px; margin-top: var(--sp-3); }
.install-copy svg { width: 18px; height: 18px; }
.install-block + .install-copy, .install-block + .install-later { margin-top: var(--sp-5); }
/* «Ikke nå» er et valg, ikke en handling. Den står uten ramme under alt det
   andre, så den ikke konkurrerer med veiledningen. */
.btn.install-later {
  min-height: 48px;
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  color: var(--text-2);
  font: 600 15px/1.3 var(--font-body);
  letter-spacing: 0;
  text-transform: none;
}
.btn.install-later:hover:not(:disabled) { border-color: var(--line); color: var(--text); transform: none; }

/* Lenken tilbake til steget, under innloggingsknappen. */
.install-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin-top: var(--sp-4);
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: 600 15px var(--font-body);
  cursor: pointer;
}
.install-link svg { width: 18px; height: 18px; }
.install-link:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Skiftet mellom stegene: det ene glir ut, det neste kommer inn fra høyre.
   Uten det ville skjemaet bare poppet opp der språkvalget sto. */
.auth-form.enter, .auth-language.enter, .auth-install.enter { animation: auth-step-in 0.44s var(--ease-out) backwards; }
@keyframes auth-step-in {
  from { opacity: 0; transform: translateX(18px); }
  to { opacity: 1; transform: none; }
}

/* Avvist innlogging: kortet rister én gang. Det er den raskeste måten å si at
   noe ble forsøkt og ikke gikk gjennom. */
.auth-form.deny { animation: auth-deny 0.42s var(--ease); }
@keyframes auth-deny {
  0%, 100% { transform: none; }
  18% { transform: translateX(-8px); }
  42% { transform: translateX(7px); }
  66% { transform: translateX(-4px); }
  84% { transform: translateX(2px); }
}

/* --------------------------------------------------------------------------
   5c. Innloggingssekvensen

   Mellom trykket på «Logg inn» og det ferdige skjemaet ligger et kall som kan
   ta alt fra 200 ms til to sekunder på et dårlig industrinett. Sekvensen
   dekker hele den tiden med én bevegelse i stedet for en spinner i en knapp:
   mørk flate, hvitt merke, en ring som går rundt mens serveren svarer, og en
   hake når svaret er godkjent. Tilstandene settes fra `app.js`:

     .is-open      — flata er framme, ringen går rundt (kallet er ute)
     .is-verified  — serveren sa ja: ringen lukkes, haken lander, navnet vises
     .is-done      — flata løftes vekk og appen står der

   Avvist innlogging får aldri `.is-verified`: flata trekkes tilbake med én
   gang, og feilen står i skjemaet.
   -------------------------------------------------------------------------- */

.auth-launch {
  position: fixed;
  inset: 0;
  z-index: var(--z-launch);
  display: grid;
  place-items: center;
  padding: var(--sp-6);
  color: #fff;
  background:
    radial-gradient(90% 70% at 50% 18%, rgba(42, 146, 96, 0.42) 0%, transparent 62%),
    radial-gradient(70% 60% at 50% 120%, rgba(105, 176, 140, 0.26) 0%, transparent 60%),
    linear-gradient(168deg, var(--brand-900) 0%, var(--brand-800) 44%, var(--brand-700) 100%);
  opacity: 0;
  transition: opacity 0.3s var(--ease), transform 0.5s var(--ease-out), filter 0.5s var(--ease-out);
}
/* Det samme fine rutenettet som på innloggingssida — flata er den samme
   verdenen, bare snudd til mørk. */
.auth-launch::before {
  content: '';
  position: absolute;
  inset: -10%;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.07) 1px, transparent 1px);
  background-size: 64px 64px;
  transform: perspective(700px) rotateX(52deg) scale(1.7);
  transform-origin: 50% 100%;
  mask-image: linear-gradient(to top, #000 0%, transparent 70%);
  pointer-events: none;
}
.auth-launch.is-open { opacity: 1; }
.auth-launch.is-done {
  opacity: 0;
  transform: scale(1.05);
  filter: blur(7px);
  pointer-events: none;
}
/* Avvist innlogging: flata trekkes tilbake i stedet for å løftes vekk, så
   bevegelsen ikke lover noe den ikke holder. */
.auth-launch.is-cancel { opacity: 0; transform: scale(0.97); pointer-events: none; }

.launch-core {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--sp-5);
  text-align: center;
}

.launch-ring { position: relative; width: 132px; height: 132px; }
.launch-arc { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.launch-arc circle { fill: none; stroke-width: 3; stroke-linecap: round; }
.launch-track { stroke: rgba(255, 255, 255, 0.16); }
.launch-sweep {
  stroke: #fff;
  /* Omkretsen er 2πr = 364.4 ved r = 58. Bue på en fjerdedel som går rundt. */
  stroke-dasharray: 92 273;
  transform-origin: 66px 66px;
}
.auth-launch.is-open .launch-sweep { animation: launch-spin 1.05s linear infinite; }
.auth-launch.is-verified .launch-sweep { animation: launch-close 0.44s var(--ease-out) forwards; }

.launch-mark, .launch-tick {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}
.launch-mark svg { width: 46px; height: 54px; color: #fff; }
.launch-mark { transition: opacity 0.26s var(--ease), transform 0.34s var(--ease-out); }
.auth-launch.is-open .launch-mark { animation: launch-mark-in 0.6s var(--ease-out) backwards; }
.auth-launch.is-verified .launch-mark { opacity: 0; transform: scale(0.8); }

.launch-tick svg { width: 46px; height: 46px; color: #fff; }
.launch-tick { opacity: 0; transform: scale(0.5); }
.auth-launch.is-verified .launch-tick { animation: launch-tick-in 0.5s var(--ease-out) 0.22s forwards; }

.launch-status {
  font-family: var(--font-display);
  font-size: clamp(22px, 3.4vw, 30px);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.92);
}
.launch-status.swap { animation: launch-line 0.42s var(--ease-out); }

.launch-name {
  margin-top: calc(var(--sp-3) * -1);
  min-height: 24px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.58);
}
.launch-name.swap { animation: launch-line 0.46s var(--ease-out); }

.launch-steps { display: flex; gap: 8px; list-style: none; }
.launch-steps li {
  width: 34px; height: 3px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.22);
  transition: background 0.3s var(--ease), width 0.3s var(--ease);
}
.launch-steps li.on { background: #fff; width: 44px; }

@keyframes launch-spin { to { transform: rotate(360deg); } }
@keyframes launch-close {
  from { stroke-dasharray: 92 273; }
  to { stroke-dasharray: 365 0; }
}
@keyframes launch-mark-in {
  from { opacity: 0; transform: scale(0.72); }
  to { opacity: 1; transform: none; }
}
@keyframes launch-tick-in {
  0% { opacity: 0; transform: scale(0.5); }
  62% { opacity: 1; transform: scale(1.12); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes launch-line {
  from { opacity: 0; transform: translateY(9px); }
  to { opacity: 1; transform: none; }
}

/* Appen kommer inn under flata som løftes vekk: topplinja faller ned, og
   innholdet stiger de siste pikslene. Én gang, ved innlogging. */
#app-shell.enter .topbar { animation: shell-top-in 0.5s var(--ease-out) backwards; }
#app-shell.enter .shell,
#app-shell.enter .stats-view,
#app-shell.enter .quiz-view { animation: shell-body-in 0.62s var(--ease-out) 0.07s backwards; }
@keyframes shell-top-in {
  from { opacity: 0; transform: translateY(-14px); }
  to { opacity: 1; transform: none; }
}
@keyframes shell-body-in {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   6. Skjemakontroller
   -------------------------------------------------------------------------- */

.field { margin-bottom: var(--sp-6); }
.field:last-child { margin-bottom: 0; }

label, .label {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}
/* Valgflisene er <label>-elementer, men skal ikke arve etikettens marg. */
.choice, .mode-opt, .switch { margin-bottom: 0; }

.req {
  color: var(--accent);
  font-size: 15px;
  line-height: 1;
}
.opt {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-3);
}

.control {
  position: relative;
  display: block;
}

input[type='text'],
input[type='password'],
input[type='datetime-local'],
/* Månedsvelgeren i administrasjonen og søkefeltet i brukerlista er skrivefelt
   som alle andre. Uten dem her falt de tilbake til nettleserens eget,
   halvhøye felt midt i et skjema der alt annet er 56 px. */
input[type='month'],
input[type='search'],
textarea {
  width: 100%;
  min-height: var(--tap);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16.5px;
  line-height: 1.5;
  padding: 15px 16px;
  box-shadow: var(--e1);
  transition:
    border-color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease);
}
input[type='datetime-local'],
input[type='month'] { font-family: var(--font-mono); font-size: 15px; }
textarea { min-height: 132px; resize: vertical; line-height: 1.6; }
textarea.compact { min-height: 104px; }

input:hover:not(:focus), textarea:hover:not(:focus) { border-color: var(--ink-400); }

input:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 4px var(--accent-ring);
}
input::placeholder, textarea::placeholder { color: var(--text-3); opacity: 1; }
input:disabled, textarea:disabled {
  background: var(--surface-sunken);
  color: var(--text-3);
  cursor: not-allowed;
  box-shadow: none;
}

.has-toggle input { padding-right: 60px; }
.reveal {
  position: absolute;
  top: 50%; right: 8px;
  transform: translateY(-50%);
  display: grid; place-items: center;
  width: 42px; height: 42px;
  border: 0; border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast), scale var(--t-fast) var(--ease);
}
.reveal:active { scale: 0.92; }
.reveal:hover { color: var(--text); background: var(--surface-sunken); }
.reveal svg { width: 21px; height: 21px; }

.hint {
  display: block;
  margin-top: var(--sp-2);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-3);
  text-wrap: pretty;
}

.counter {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.counter.near { color: var(--warn); }
.counter.over { color: var(--danger); }

/* Feilmelding per felt */
.err {
  display: none;
  align-items: flex-start;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  color: var(--danger);
  font-size: 14px;
  font-weight: 500;
}
.err::before {
  content: '!';
  flex: none;
  display: grid; place-items: center;
  width: 17px; height: 17px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--danger);
  color: var(--on-tone);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
}
.field.invalid .err { display: flex; }
.field.invalid input,
.field.invalid textarea { border-color: var(--danger); }
.field.invalid input:focus,
.field.invalid textarea:focus { box-shadow: 0 0 0 4px var(--danger-line); }

/* --------------------------------------------------------------------------
   7. Knapper
   -------------------------------------------------------------------------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: 0 var(--sp-6);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  /* `.btn` brukes også på <a> (404-sida), som ellers arver understreking. */
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  transition:
    transform var(--t-fast) var(--ease),
    box-shadow var(--t-base) var(--ease),
    background var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease);
}
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.99); }
.btn:disabled { cursor: not-allowed; opacity: 0.6; }

.btn-primary {
  background: var(--accent-fill);
  color: #fff;
  box-shadow: var(--e2);
}
.btn-primary:hover:not(:disabled) { background: var(--accent-fill-hover); box-shadow: var(--e3); }
.btn:hover:not(:disabled) { transform: translateY(-2px); }
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.97); box-shadow: var(--e1); transition-duration: 70ms; }
.btn-primary:disabled { background: var(--accent-fill); }

.btn-ghost {
  background: var(--surface);
  border-color: var(--line-strong);
  color: var(--text-2);
  box-shadow: var(--e1);
}
.btn-ghost:hover:not(:disabled) { border-color: var(--ink-400); color: var(--text); }

.btn-block { width: 100%; }
.btn-lg { min-height: 62px; font-size: 20px; }

.btn .spin {
  width: 18px; height: 18px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
.btn-ghost .spin { border-color: var(--line-strong); border-top-color: var(--text-2); }
@keyframes spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------------------------------
   8. Topplinje
   -------------------------------------------------------------------------- */

/* Merkestripa øverst. Tre stopp i stedet for to: den mørke enden holder igjen
   mot papiret, midtpartiet bærer lyset, og høyre ende lander i merkegrønn
   igjen — en trykt kant, ikke en tofarget overgang. */
.hairline {
  height: 3px;
  background: linear-gradient(90deg, var(--brand-800) 0%, var(--brand-600) 26%, var(--brand-400) 58%, var(--brand-600) 100%);
}

/* Språkvelger.

   Fire faste knapper la beslag på nesten halve topplinja på telefon. Velgeren
   står derfor lukket: den viser flisa for språket som er valgt, og legger de
   andre valgene ut mot venstre først når den blir trykt på. Etter et valg
   lukker den seg igjen, slik at plassen går tilbake til innholdet.

   `flex-direction: row-reverse` gjør at knappen blir stående i ro mot høyre
   kant mens lista vokser innover — markup-en leses fortsatt knapp før liste. */
.language-picker {
  position: fixed;
  z-index: calc(var(--z-topbar) + 2);
  top: calc(12px + env(safe-area-inset-top));
  right: 14px;
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  box-shadow: var(--e2);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: box-shadow var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
.language-picker.open {
  border-color: color-mix(in srgb, var(--accent) 32%, var(--line-strong));
  box-shadow: var(--e3);
}
.language-picker button {
  min-width: 52px;
  height: 44px;
  padding: 0 9px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-2);
  font: 700 12px var(--font-body);
  letter-spacing: .04em;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast) var(--ease);
}
.language-picker abbr { text-decoration: none; }
.language-picker .flag { width: 22px; height: 16px; flex: none; border-radius: 2px; box-shadow: 0 0 0 1px rgba(0,0,0,.14); }
@media (hover: hover) {
  .language-picker button:hover { color: var(--text); background: var(--surface-sunken); }
}
.language-picker button:active { transform: scale(.94); }
.language-options button.active { color: #fff; background: var(--accent-fill); box-shadow: var(--e1); }

/* Den lukkede flisa. Flagget byttes ved språkskifte, og sjevronen snur seg
   når lista er åpen. */
.language-toggle .language-code { font-variant-numeric: tabular-nums; }
.language-chevron {
  width: 12px; height: 12px;
  flex: none;
  opacity: .55;
  transition: transform var(--t-base) var(--ease), opacity var(--t-fast);
}
.language-picker.open .language-chevron { transform: rotate(180deg); opacity: .9; }
.language-picker.open .language-toggle { color: var(--text); background: var(--surface-sunken); }
/* Flagget skiftes mens flisa er lukket, så byttet får sin egen lille kvittering. */
.language-toggle.swap .flag { animation: flag-swap .42s var(--ease-out); }
@keyframes flag-swap {
  0% { transform: scale(.55) rotate(-12deg); opacity: 0; }
  60% { transform: scale(1.06) rotate(2deg); opacity: 1; }
  100% { transform: none; }
}

/* Lista klippes bort i lukket tilstand. `max-width` animeres mot en verdi som
   er romsligere enn innholdet — bredden er kjent og fast (fire fliser). */
.language-options {
  display: flex;
  gap: 3px;
  overflow: hidden;
  max-width: 0;
  opacity: 0;
  transition: max-width var(--t-slow) var(--ease), opacity var(--t-base) var(--ease);
}
.language-picker.open .language-options { max-width: 280px; opacity: 1; }
/* Fokusringen ville blitt klippet av `overflow: hidden`; den legges innenfor. */
.language-options button:focus-visible { outline-offset: -3px; }
.language-options button {
  opacity: 0;
  transform: translateX(14px) scale(.9);
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease),
              color var(--t-fast), background var(--t-fast);
}
.language-picker.open .language-options button { opacity: 1; transform: none; }
.language-picker.open .language-options button:active { transform: scale(.94); }
/* Valgene legger seg ut fra knappen og utover, ett hakk i slengen. */
.language-picker.open .language-options button:nth-child(4) { transition-delay: 40ms; }
.language-picker.open .language-options button:nth-child(3) { transition-delay: 80ms; }
.language-picker.open .language-options button:nth-child(2) { transition-delay: 120ms; }
.language-picker.open .language-options button:nth-child(1) { transition-delay: 160ms; }

/* Første besøk: ingen lagret språkvalg. Da blinker flisa rolig to ganger, slik
   at velgeren blir oppdaget uten at den tar plass resten av tiden. */
.language-picker.hint .language-toggle { animation: picker-hint 2.4s var(--ease) 2; }
@keyframes picker-hint {
  0%, 62%, 100% { box-shadow: 0 0 0 0 var(--accent-ring); }
  74% { box-shadow: 0 0 0 7px transparent; }
}

#app-shell:not([hidden]) .topbar-row { padding-right: var(--picker-gutter); }

/* Topplinja er den ene flata som står på skjermen hele tiden, så den er
   bygget som et vindu og ikke som et felt: en loddrett tone i glasset, en
   lysstrek langs overkanten, og en kant som først strammer seg til når det
   ligger innhold under. I ro skal den knapt merkes; festet skal den bære. */
.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-topbar);
  /* `viewport-fit=cover` + gjennomsiktig statuslinje: uten denne legger
     topplinja seg under hakket på telefonene som har ett. */
  padding-top: env(safe-area-inset-top);
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--surface) 94%, transparent),
    color-mix(in srgb, var(--surface) 80%, transparent)
  );
  backdrop-filter: saturate(1.75) blur(18px);
  -webkit-backdrop-filter: saturate(1.75) blur(18px);
  border-bottom: 1px solid color-mix(in srgb, var(--line) 62%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
  transition:
    border-color var(--t-base) var(--ease),
    box-shadow var(--t-base) var(--ease);
}
.topbar.stuck {
  border-bottom-color: var(--line);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 14px 30px -24px rgba(12, 23, 16, 0.75);
}

.topbar-row {
  display: flex;
  align-items: center;
  gap: clamp(8px, 1.3vw, 16px);
  max-width: var(--shell);
  margin: 0 auto;
  padding: 12px clamp(16px, 3vw, 28px);
  transition: padding var(--t-base) var(--ease);
}
.topbar.stuck .topbar-row { padding-top: 8px; padding-bottom: 8px; }

/* Merkeflisa i topplinja. Den flate grønnfargen leste som en plassholder ved
   siden av resten av flatene; her er den støpt: en tone på tvers, en lysstrek
   langs overkanten og en skygge i samme grønn i stedet for i svart. */
.topbar .logo-tile {
  --mark-h: 22px;
  position: relative;
  overflow: hidden;
  border-radius: 13px;
  background: linear-gradient(152deg, var(--brand-500) 0%, var(--brand-700) 58%, var(--brand-800) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08),
    0 6px 16px -10px rgba(0, 60, 30, 0.9);
}
/* Lyset som ligger igjen på den øvre halvdelen av et støpt skilt. */
.topbar .logo-tile::after {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 52%;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), transparent);
  pointer-events: none;
}
.topbar .logo-tile .logo-mark { position: relative; z-index: 1; }

.topbar-titles { display: grid; min-width: 0; }
.topbar-titles .kicker {
  font-family: var(--font-display);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--accent) 76%, var(--text-3));
}
.topbar-titles h1 {
  font-family: var(--font-display);
  font-size: 23px;
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: 0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-spacer { flex: 1; }

/* --------------------------------------------------------------------------
   Hovedmenyen

   Fire valg i én ramme. Den aktive flata er ett element som glir mellom dem
   (`.nav-ink`) i stedet for fire flater som tennes og slukkes — da leses
   menyen som én kontroll, og skiftet forteller hvor man kom fra.

   Posisjon og bredde settes fra `app.js`, fordi de avhenger av teksten og
   dermed av språket. Uten skript får den aktive knappen flata si egen:
   `.app-nav:not(.ready)` nedenfor er hele reserveløsningen.
   -------------------------------------------------------------------------- */
.app-nav {
  position: relative;
  display: flex;
  gap: 2px;
  padding: 4px;
  border: 1px solid color-mix(in srgb, var(--line) 85%, transparent);
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--surface-sunken), color-mix(in srgb, var(--surface-sunken) 55%, var(--surface)));
  box-shadow: inset 0 1px 2px rgba(12, 23, 16, 0.06);
}
.nav-ink {
  position: absolute;
  z-index: 0;
  top: 4px;
  left: 0;
  width: var(--nav-w, 0);
  height: calc(100% - 8px);
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, #fff, var(--surface));
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.9),
    0 1px 2px rgba(12, 23, 16, 0.09),
    0 8px 16px -10px rgba(12, 23, 16, 0.45);
  opacity: 0;
  transform: translateX(var(--nav-x, 0));
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease);
}
.app-nav.ready .nav-ink {
  opacity: 1;
  transition:
    transform 0.44s var(--ease),
    width 0.44s var(--ease),
    opacity var(--t-base) var(--ease);
}
.nav-btn {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 42px;
  padding: 0 clamp(12px, 1.4vw, 18px);
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-2);
  font: 600 clamp(13px, .25vw + 12px, 15px) var(--font-body);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.nav-btn svg { width: 16px; height: 16px; opacity: .72; transition: opacity var(--t-fast) var(--ease); }
.nav-btn:hover { color: var(--text); }
.nav-btn:hover svg { opacity: 1; }
.nav-btn.active { color: var(--accent); }
.nav-btn.active svg { opacity: 1; }
/* Uten skript bærer knappen flata selv. */
.app-nav:not(.ready) .nav-btn.active { background: var(--surface); box-shadow: var(--e1); }
/* Menya kan rulle vannrett på telefon; da klipper `overflow` fokusringen.
   `outline-offset: -2px` legger den innenfor knappen i stedet. */
.nav-btn:focus-visible { outline-offset: -2px; }

/* Nettstatus.
   Den gamle flisa hadde to tilstander og bare `navigator.onLine` bak seg — den
   sa «Tilkoblet» på et nett som ikke nådde tjenesten, og den sa ingenting om
   meldinger som lå i kø. Nå bærer den fem tilstander i `data-state`, og hver
   av dem har sin egen farge, sitt eget signalikon og sin egen undertekst.
   Flata er en knapp: den sender køen og kontrollerer forbindelsen. */

.netstat {
  --net: var(--ok);
  --net-soft: color-mix(in srgb, var(--ok) 13%, var(--surface-2));
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 40px;
  padding: 0 11px 0 10px;
  border: 1px solid color-mix(in srgb, var(--net) 30%, var(--line));
  border-radius: var(--r-pill);
  background: var(--net-soft);
  color: var(--text-2);
  font: inherit;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
  transition:
    border-color var(--t-base) var(--ease),
    background var(--t-base) var(--ease),
    transform var(--t-fast) var(--ease),
    box-shadow var(--t-base) var(--ease);
}
.netstat:hover {
  border-color: color-mix(in srgb, var(--net) 55%, var(--line));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), var(--e1);
}
.netstat:active { transform: scale(0.97); }

/* Tre stolper. Antallet som lyser er selve statusen — den leses på en meters
   avstand, før teksten rekker å bli lest. */
.netstat-sig {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  height: 14px;
  flex: none;
}
.netstat-sig i {
  width: 3px;
  border-radius: 2px;
  background: var(--net);
  opacity: 0.22;
  transition: opacity var(--t-base) var(--ease), height var(--t-base) var(--ease);
}
.netstat-sig i:nth-child(1) { height: 6px; }
.netstat-sig i:nth-child(2) { height: 10px; }
.netstat-sig i:nth-child(3) { height: 14px; }

.netstat-body { display: grid; min-width: 0; }
.netstat-label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--net) 72%, var(--text));
}
.netstat-note {
  font-size: 11.5px;
  line-height: 1.25;
  color: var(--text-3);
  overflow: hidden;
  text-overflow: ellipsis;
}
.netstat-count {
  display: grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--net);
  color: var(--on-tone);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
}

/* Tilkoblet: alle tre stolpene lyser, og ingenting beveger seg. */
.netstat[data-state='online'] .netstat-sig i { opacity: 1; }

/* Sender: stolpene fylles nedenfra og opp, om og om igjen. */
.netstat[data-state='syncing'] { --net: var(--brand-500); --net-soft: var(--accent-soft); }
.netstat[data-state='syncing'] .netstat-sig i { animation: net-climb 1.1s var(--ease) infinite; }
.netstat[data-state='syncing'] .netstat-sig i:nth-child(2) { animation-delay: 0.13s; }
.netstat[data-state='syncing'] .netstat-sig i:nth-child(3) { animation-delay: 0.26s; }

/* I kø: nettet er der, men noe venter. Den skal be om et trykk. */
.netstat[data-state='queued'] { --net: var(--warn); --net-soft: var(--warn-soft); }
.netstat[data-state='queued'] .netstat-sig i { opacity: 1; }

/* Ustabilt: nettleseren tror den er på nett, men tjenesten svarer ikke. */
.netstat[data-state='unstable'] { --net: var(--warn); --net-soft: var(--warn-soft); }
.netstat[data-state='unstable'] .netstat-sig i:nth-child(1),
.netstat[data-state='unstable'] .netstat-sig i:nth-child(2) { opacity: 1; }
.netstat[data-state='unstable'] .netstat-sig i:nth-child(3) { animation: net-blink 1.5s var(--ease) infinite; }

/* Frakoblet: stolpene står mørke. Meldingen er trygg, og det står det. */
.netstat[data-state='offline'] { --net: var(--danger); --net-soft: var(--danger-soft); }
.netstat[data-state='offline'] .netstat-sig i:nth-child(1) { opacity: 1; }

/* Et tilstandsskifte skal merkes uten å bråke: teksten bytter med en kort
   heving, og ramma får ett pust av fargen den nettopp gikk til. */
.netstat.shift .netstat-body { animation: net-shift 0.38s var(--ease-out); }
.netstat.shift { animation: net-ping 0.9s var(--ease-out); }

@keyframes net-climb {
  0%, 100% { opacity: 0.22; }
  40% { opacity: 1; }
}
@keyframes net-blink { 50% { opacity: 0.22; } }
@keyframes net-shift {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: none; }
}
@keyframes net-ping {
  from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--net) 45%, transparent); }
  to { box-shadow: 0 0 0 9px transparent; }
}
@keyframes pulse { 50% { opacity: 0.35; } }

.user {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 40px;
  padding: 0 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--surface), var(--surface-2));
  color: var(--text-2);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
  transition:
    border-color var(--t-fast),
    color var(--t-fast),
    box-shadow var(--t-base) var(--ease),
    transform var(--t-fast) var(--ease);
}
.user:hover {
  border-color: var(--line-strong);
  color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), var(--e2);
}
.user:active { transform: scale(0.96); }
.user .avatar {
  display: grid; place-items: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: linear-gradient(150deg, var(--brand-100), var(--brand-50));
  box-shadow: inset 0 0 0 1px rgba(0, 85, 43, 0.14);
  color: var(--accent);
  font-size: 12px;
  letter-spacing: 0;
}
.user .txt { padding-right: 8px; }

/* Framdriftslinje */
.progress {
  height: 2px;
  background: var(--line);
  overflow: hidden;
}
.progress i {
  display: block;
  height: 100%;
  width: var(--p, 0%);
  background: linear-gradient(90deg, var(--brand-500), var(--brand-300));
  transition: width var(--t-slow) var(--ease);
}

/* Købanner */
.queue {
  display: none;
  align-items: center;
  gap: var(--sp-3);
  max-width: var(--shell);
  margin: 0 auto;
  padding: 11px clamp(16px, 3vw, 28px);
  font-size: 15px;
}
.queue.show { display: flex; }
.queue-wrap { background: var(--warn-soft); border-bottom: 1px solid var(--warn-line); }
.queue .badge {
  display: grid; place-items: center;
  min-width: 25px; height: 25px;
  padding: 0 7px;
  border-radius: var(--r-pill);
  background: var(--warn);
  color: var(--on-tone);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
}
.queue button {
  margin-left: auto;
  min-height: 38px;
  padding: 0 15px;
  border: 1px solid var(--warn);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--warn);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.queue button:hover { background: var(--warn); color: var(--on-tone); }
.queue button:active { transform: scale(0.97); }

/* --------------------------------------------------------------------------
   9. Layout
   -------------------------------------------------------------------------- */

.shell {
  max-width: var(--shell);
  margin: 0 auto;
  /* Bunnen holdt av 180 px til handlingslinja uansett om den vistes eller ei.
     `--actionbar-h` er linjas målte høyde (`syncActionbarHeight` i app.js), så
     tomrommet under siste felt er nøyaktig så stort som det må være. */
  padding:
    clamp(24px, 4vw, 44px)
    max(clamp(16px, 3vw, 28px), env(safe-area-inset-right))
    calc(var(--actionbar-h, 96px) + clamp(24px, 4vw, 44px))
    max(clamp(16px, 3vw, 28px), env(safe-area-inset-left));
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(24px, 3vw, 40px);
}
@media (min-width: 1080px) {
  .shell { grid-template-columns: minmax(0, 1fr) 316px; align-items: start; }
  /* Kvitteringen står alene — da skal ikke sidepanelets spor holdes av. */
  .shell:has(.receipt.show) { grid-template-columns: minmax(0, 1fr); }
}

.lede { margin-bottom: var(--sp-7); max-width: 58ch; }
.lede h2 {
  margin: var(--sp-3) 0 var(--sp-3);
  font-family: var(--font-display);
  font-size: clamp(30px, 4vw, 40px);
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.lede p { color: var(--text-2); text-wrap: pretty; }

/* --------------------------------------------------------------------------
   10. Kort / seksjoner
   -------------------------------------------------------------------------- */

.card {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--e2);
  padding: clamp(20px, 3vw, 30px);
  transition: box-shadow var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
.card + .card { margin-top: var(--sp-5); }
.card:focus-within { box-shadow: var(--e3); }
.card.wizard-pending {
  display: none;
}
.card:not(.wizard-pending) {
  animation: reveal-step 360ms var(--ease-out) both;
}
@keyframes reveal-step {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

.card-head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.card-head > div { min-width: 0; flex: 1; }
.card-toggle {
  display: none;
  flex: none;
  min-height: 40px;
  padding: 0 15px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--accent);
  font: 600 13px var(--font-body);
  cursor: pointer;
}
.card.done .card-toggle,
#form .card.collapsed .card-toggle { display: inline-flex; align-items: center; }
.card-toggle:hover { border-color: var(--accent); background: var(--accent-soft); }

/* Foldingen glir i stedet for å klippe.

   `display: none` fikk et kort på fire hundre piksler til å forsvinne mellom
   to bilder: alt under hoppet opp, og på en telefon leste det som en feil i
   appen. Kortet er i stedet et rutenett med to rader — overskriften og
   kroppen — og kroppen går fra `1fr` til `0fr`. Da er det den samme
   bevegelsen, men øyet rekker å følge den.

   Nettlesere uten animert `grid-template-rows` faller tilbake til det gamle
   klippet. Ingenting går i stykker, det går bare fortere. */
#form .card {
  display: grid;
  grid-template-rows: auto 1fr;
  transition:
    grid-template-rows var(--t-slow) var(--ease),
    padding var(--t-slow) var(--ease),
    box-shadow var(--t-base) var(--ease),
    border-color var(--t-base) var(--ease);
}
#form .card.wizard-pending { display: none; }
/* Alle fire stegene står i skjemaet så snart meldingstypen er valgt. De tones
   inn etter tur i stedet for alle i samme bilde — rekkefølgen er selve
   beskjeden: dette er veien, og du er på det første steget. */
#form #card-2 { animation-delay: 60ms; }
#form #card-3 { animation-delay: 120ms; }
#form #card-4 { animation-delay: 180ms; }
/* Ett kort er åpent, resten er rader. Det foldede kortet legger seg flatt mot
   bakgrunnen, så det åpne er det eneste som leses som en flate med innhold. */
#form .card.collapsed { background: var(--surface-2); box-shadow: none; }
/* Hele toppen av et foldet kort åpner steget — på en telefon er overskriften
   det man treffer, ikke knappen ved siden av. */
#form .card.collapsed .card-head { cursor: pointer; }
@media (hover: hover) {
  #form .card.collapsed:hover { border-color: var(--line-strong); background: var(--surface); }
  #form .card.collapsed:hover .card-toggle { border-color: var(--accent); background: var(--accent-soft); }
}
/* Rutenettceller starter med `min-width: auto` og lar innholdet sprenge
   kolonnen. Sammendraget i en foldet topp er én lang linje: uten dette skjøv
   det «Rediger» ut over kanten i stedet for å kuttes med ellipse. */
#form .card > * { min-width: 0; }
#form .card > .card-body { min-height: 0; overflow: hidden; }
#form .card-head {
  transition:
    margin var(--t-slow) var(--ease),
    padding var(--t-slow) var(--ease),
    border-color var(--t-slow) var(--ease);
}
.card.collapsed { padding-top: 16px; padding-bottom: 16px; }
#form .card.collapsed { grid-template-rows: auto 0fr; }
.card.collapsed .card-head { align-items: center; margin: 0; padding: 0; border-color: transparent; }
.card.collapsed .card-head p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Foten av kortet: hvor du er, og veien videre. «Neste» er den eneste
   handlingen som folder sammen steget og flytter skjermen — alt annet i
   skjemaet står i ro, slik at ingenting hopper mens du skriver. */
.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}
.card-foot-step {
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--text-3);
}
.btn-next {
  flex: none;
  gap: var(--sp-3);
  min-height: 52px;
  padding: 0 var(--sp-5);
  border-color: var(--line-strong);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 16px;
}
.btn-next .next-lead { font-weight: 600; }
/* Overskriften på steget som kommer. Den er løftet ut av `text-transform` i
   `.btn`, for et setningsledd i store bokstaver leses tregere enn det står. */
.btn-next .next-title {
  max-width: 16ch;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-3);
}
.btn-next svg { width: 18px; height: 18px; flex: none; }
/* Er steget ferdig, skifter knappen til den aksenten resten av skjemaet bruker
   for «dette er gjort». Den er trykkbar hele veien: et trykk før steget er
   ferdig merker feltene som mangler i stedet for å gjøre ingenting. */
.btn-next.ready {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}
.btn-next.ready .next-title { color: inherit; opacity: 0.75; }
body.kind-positive .btn-next.ready {
  border-color: var(--pos);
  background: var(--pos-soft);
  color: var(--pos);
}
@media (hover: hover) {
  .btn-next:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
}
.btn-next:active { transform: scale(0.99); }

/* Et foldet steg bytter hjelpeteksten mot et sammendrag av det som ble fylt
   ut, så brukeren ser hva som står i kortet uten å åpne det igjen. */
.card-head .card-recap { display: none; }
/* Er steget fylt ut, bytter hjelpeteksten plass med sammendraget. Er det ikke
   det — et steg lenger fram i skjemaet — står hjelpeteksten igjen, så en
   foldet rad aldri er bare en overskrift. */
.card.collapsed.has-recap .card-head > div > p { display: none; }
.card.collapsed .card-head .card-recap:not([hidden]) {
  display: block;
  color: var(--text-2);
  font-weight: 600;
}
.step {
  flex: none;
  display: grid; place-items: center;
  width: 36px; height: 36px;
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.card-head h3 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
}
.card-head p { margin-top: 2px; color: var(--text-3); font-size: 14px; }
.step { position: relative; transition: background var(--t-base) var(--ease), color var(--t-base) var(--ease); }
/* Ferdig seksjon: nummeret byttes med en hake. Tallet står igjen i DOM-en. */
.card.done .step { background: var(--accent-fill); color: transparent; }
.card.done .step::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 16px; height: 16px;
  background: #fff;
  -webkit-mask: var(--check) center / contain no-repeat;
  mask: var(--check) center / contain no-repeat;
  animation: pop var(--t-base) var(--ease-out);
}
:root {
  --check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   11. Valg — type hendelse
   -------------------------------------------------------------------------- */

.choices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
  gap: var(--sp-3);
}
.choice { position: relative; display: block; }
.choice input { position: absolute; opacity: 0; width: 0; height: 0; }

.choice > span {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--tap);
  height: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text-2);
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: var(--e1);
  transition:
    border-color var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease);
}
.choice > span svg {
  width: 34px; height: 34px; flex: none; padding: 6px;
  border-radius: 9px; color: var(--choice-tone, var(--accent));
  background: color-mix(in srgb, var(--choice-tone, var(--accent)) 12%, transparent);
  opacity: 0.9; transition: opacity var(--t-fast), transform var(--t-fast);
}
.choice:nth-child(2n) { --choice-tone: #2563a9; }
.choice:nth-child(3n) { --choice-tone: #a35b00; }
.choice:nth-child(4n) { --choice-tone: #7c3b9d; }
.choice:nth-child(5n) { --choice-tone: #b3261e; }
.choice:nth-child(6n) { --choice-tone: #007c78; }
.choice:hover > span { border-color: var(--ink-400); }
.choice > span:active { transform: scale(0.985); }

.choice input:checked + span {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent) inset, var(--e1);
}
.choice input:checked + span svg { opacity: 1; transform: scale(1.08); }
.choice input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Alvorlighetsgrad */
.sev-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(146px, 1fr));
  gap: var(--sp-3);
}
.sev-grid .choice > span {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 3px;
  min-height: 78px;
  padding: 13px 15px;
}
.sev-grid .choice > span b {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 18px;
  font-weight: 600;
}
.sev-grid .choice > span b::before {
  content: '';
  width: 9px; height: 9px;
  border-radius: 2px;
  background: var(--tone, var(--ink-400));
}
.sev-grid .choice > span i {
  font-family: var(--font-body);
  font-style: normal;
  font-size: 12.5px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.35;
  color: var(--text-3);
}
.sev-grid .choice input:checked + span {
  border-color: var(--tone);
  background: var(--tone-soft);
  color: var(--tone);
  box-shadow: 0 0 0 1px var(--tone) inset, var(--e1);
}
.sev-grid .choice input:checked + span i { color: var(--tone); opacity: 0.85; }
.sev-grid .choice input:focus-visible + span { outline-color: var(--tone); }

.sev-grid .choice[data-i='0'] { --tone: var(--sev-1); --tone-soft: var(--sev-1-soft); }
.sev-grid .choice[data-i='1'] { --tone: var(--sev-2); --tone-soft: var(--sev-2-soft); }
.sev-grid .choice[data-i='2'] { --tone: var(--sev-3); --tone-soft: var(--sev-3-soft); }
.sev-grid .choice[data-i='3'] { --tone: var(--sev-4); --tone-soft: var(--sev-4-soft); }

/* --------------------------------------------------------------------------
   12. Varsler
   -------------------------------------------------------------------------- */

.notice {
  display: none;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--danger-line);
  border-left: 3px solid var(--danger);
  border-radius: var(--r-md);
  background: var(--danger-soft);
  font-size: 14.5px;
  line-height: 1.55;
  animation: drop var(--t-base) var(--ease-out);
}
.notice.show { display: flex; }
.notice svg { width: 21px; height: 21px; flex: none; color: var(--danger); margin-top: 1px; }
.notice b {
  display: block;
  margin-bottom: 3px;
  color: var(--danger);
  font-family: var(--font-display);
  font-size: 16px;
  letter-spacing: 0.02em;
}
.notice b.inline { display: inline; margin: 0; font: inherit; font-weight: 700; letter-spacing: 0; }
@keyframes drop { from { opacity: 0; transform: translateY(-6px); } }

.summary-errors {
  display: none;
  padding: var(--sp-4) var(--sp-5);
  margin-bottom: var(--sp-5);
  border: 1px solid var(--danger-line);
  border-radius: var(--r-md);
  background: var(--danger-soft);
  box-shadow: var(--e1);
}
.summary-errors:focus-visible { outline: 2px solid var(--danger); outline-offset: 3px; border-radius: var(--r-md); }
.summary-errors.show { display: block; animation: drop var(--t-base) var(--ease-out); }
.summary-errors strong {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  color: var(--danger);
  font-family: var(--font-display);
  font-size: 18px;
  letter-spacing: 0.01em;
}
.summary-errors ol { list-style: none; display: grid; gap: 0; }
.summary-errors li.plain { padding: 5px 0; color: var(--danger); }
.summary-errors strong svg { width: 20px; height: 20px; flex: none; }
.summary-errors a {
  display: block;
  padding: 5px 0;
  color: var(--danger);
  font-size: 15px;
  text-decoration-color: color-mix(in srgb, var(--danger) 40%, transparent);
  text-underline-offset: 3px;
}
.summary-errors a:hover { text-decoration-color: currentColor; }

/* --------------------------------------------------------------------------
   13. Tidspunkt
   -------------------------------------------------------------------------- */

.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.chip {
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-2);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast), transform var(--t-fast) var(--ease);
}
.chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.chip:active { transform: scale(0.96); }

/* --------------------------------------------------------------------------
   14. Bilder
   -------------------------------------------------------------------------- */

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  width: 100%;
  min-height: 116px;
  padding: var(--sp-5);
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface-sunken);
  color: var(--text-2);
  cursor: pointer;
  text-align: center;
  transition: border-color var(--t-base) var(--ease), background var(--t-base) var(--ease), color var(--t-base) var(--ease), transform var(--t-fast) var(--ease);
}
.dropzone:active { transform: scale(0.99); }
.dropzone:hover, .dropzone.over {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}
.dropzone svg { width: 26px; height: 26px; transition: transform var(--t-base) var(--ease-out); }
.dropzone:hover svg, .dropzone.over svg { transform: translateY(-2px); }
.dropzone.busy { pointer-events: none; }
.dropzone.busy svg { animation: breathe 1.2s var(--ease) infinite; }
.dropzone b { font-family: var(--font-display); font-size: 18px; font-weight: 600; letter-spacing: 0.01em; }
.dropzone small { font-size: 13px; color: var(--text-3); }
.dropzone.over small, .dropzone:hover small { color: inherit; opacity: 0.8; }

.thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.thumbs:empty { display: none; }
.thumb {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--surface-sunken);
  box-shadow: var(--e1);
  animation: pop var(--t-base) var(--ease-out);
}
@keyframes pop { from { opacity: 0; transform: scale(0.94); } }
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.thumb .rm {
  position: absolute;
  top: 6px; right: 6px;
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border: 0; border-radius: 50%;
  background: rgba(10, 18, 13, 0.62);
  backdrop-filter: blur(6px);
  color: #fff;
  cursor: pointer;
  transition: background var(--t-fast);
}
.thumb .rm:hover { background: var(--danger); }
.thumb .rm:active { transform: scale(0.9); }
.thumb .rm svg { width: 15px; height: 15px; }
.thumb .size {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 14px 8px 5px;
  background: linear-gradient(to top, rgba(10, 18, 13, 0.75), transparent);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 10.5px;
  text-align: center;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: grid;
  place-items: center;
  padding: var(--sp-6);
  background: rgba(8, 14, 10, 0.86);
  backdrop-filter: blur(8px);
  animation: fade var(--t-base) var(--ease);
}
@keyframes fade { from { opacity: 0; } }
.lightbox img { max-width: 100%; max-height: 86dvh; border-radius: var(--r-md); box-shadow: var(--e4); }
.lightbox .close {
  position: absolute;
  top: var(--sp-5); right: var(--sp-5);
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  cursor: pointer;
  transition: background var(--t-fast);
}
.lightbox .close:hover { background: rgba(255, 255, 255, 0.2); }
.lightbox .close svg { width: 22px; height: 22px; }

/* --------------------------------------------------------------------------
   15. Bryter (anonym)
   -------------------------------------------------------------------------- */

.switch {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4);
  margin-bottom: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-sunken);
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.switch:hover { border-color: var(--line-strong); }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .txt { flex: 1; }
.switch .txt b {
  display: block;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.switch .txt small {
  display: block;
  margin-top: 2px;
  color: var(--text-3);
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.45;
}
.switch:has(input:disabled) { opacity: 0.5; cursor: not-allowed; }
.switch:has(input:disabled):hover { border-color: var(--line); }
.track {
  flex: none;
  position: relative;
  width: 52px; height: 30px;
  border-radius: var(--r-pill);
  background: var(--track-off);
  transition: background var(--t-base) var(--ease);
}
.track::after {
  content: '';
  position: absolute;
  top: 3px; left: 3px;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--e1);
  transition: transform var(--t-base) var(--ease);
}
.switch input:checked ~ .track { background: var(--accent-fill); }
.switch input:checked ~ .track::after { transform: translateX(22px); }
.switch input:focus-visible ~ .track { outline: 2px solid var(--accent); outline-offset: 3px; }
.switch:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }

/* --------------------------------------------------------------------------
   16. Sidepanel — levende sammendrag
   -------------------------------------------------------------------------- */

.aside { display: none; }
@media (min-width: 1080px) {
  .aside { display: block; position: sticky; top: 104px; }
}
.aside .card { padding: var(--sp-5); }

.ring-row { display: flex; align-items: center; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.ring { position: relative; width: 62px; height: 62px; flex: none; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 6; }
.ring .bg { stroke: var(--line); }
.ring .fg {
  stroke: var(--accent);
  stroke-linecap: round;
  stroke-dasharray: 163.4;
  stroke-dashoffset: calc(163.4 - 163.4 * var(--p, 0) / 100);
  transition: stroke-dashoffset var(--t-slow) var(--ease);
}
.ring b {
  position: absolute;
  inset: 0;
  display: grid; place-items: center;
  font-family: var(--font-mono);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.ring-row .txt b {
  display: block;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.ring-row .txt small { color: var(--text-3); font-size: 13px; }

.sum { display: grid; gap: 1px; background: var(--line); border-radius: var(--r-sm); overflow: hidden; }
.sum div {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding: 10px 12px;
  background: var(--surface);
  font-size: 14px;
}
.sum dt {
  flex: none;
  width: 78px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}
.sum dd { min-width: 0; color: var(--text); overflow-wrap: anywhere; }
.sum dd.empty { color: var(--text-3); }
.sum dd .tag {
  display: inline-block;
  padding: 1px 9px;
  border-radius: var(--r-pill);
  background: var(--tone-soft, var(--accent-soft));
  color: var(--tone, var(--accent));
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.aside-note {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-3);
}
.aside-note b { color: var(--text-2); }

/* --------------------------------------------------------------------------
   17. Handlingslinje
   -------------------------------------------------------------------------- */

.actionbar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: var(--z-actionbar);
  padding: var(--sp-4) clamp(16px, 3vw, 28px) calc(var(--sp-4) + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(16px);
  -webkit-backdrop-filter: saturate(1.6) blur(16px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -10px 30px -22px rgba(12, 23, 16, 0.5);
  /* Løftet opp over tastaturet. `--keyboard-inset` settes av `syncKeyboardInset`
     i app.js ut fra `visualViewport`; uten tastatur er den null. */
  transform: translateY(calc(-1 * var(--keyboard-inset, 0px)));
}
.actionbar-inner {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  max-width: var(--shell);
  margin: 0 auto;
}
/* Hold linjen i flukt med skjemakolonnen når sidepanelet vises. */
@media (min-width: 1080px) {
  .actionbar-inner { padding-right: calc(316px + clamp(24px, 3vw, 40px)); }
}
.actionbar .meta {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-3);
}
.actionbar .meta b { display: block; color: var(--text-2); font-size: 14px; }
.actionbar .btn { flex: none; min-width: 210px; }

/* På telefon var handlingslinja nesten 180 px høy: to linjer tekst over en
   knapp på 62 px, med luft og hjemknappsone rundt. Den spiste en fjerdedel av
   skjermen — og godt over halvparten av det som var igjen når tastaturet stod
   oppe. Her er den én kompakt linje: statusen i én setning, knappen under. */
@media (max-width: 640px) {
  /* `max()` i stedet for `+`: hjemknappsonen har allerede klaringen innebygd,
     så den skal ikke legges oppå vår egen luft. Det er ti piksler spart på
     hver eneste iPhone. */
  .actionbar { padding: 10px clamp(12px, 3vw, 20px) max(10px, env(safe-area-inset-bottom)); }
  .actionbar-inner { flex-direction: column; align-items: stretch; gap: 6px; }
  .actionbar .btn { width: 100%; min-width: 0; }
  .actionbar .btn-lg { min-height: 52px; font-size: 17px; }
  .actionbar .meta {
    text-align: center;
    font-size: 13px;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .actionbar .meta b { display: inline; font-size: 13px; }
  /* Forklaringen bak statusen får ikke plass på én linje på en telefon, og en
     avkuttet setning sier mindre enn ingen setning. «2 felt gjenstår» alene
     er hele beskjeden. */
  .actionbar .meta-tail { display: none; }
}

/* Mens tastaturet står oppe er det bare knappen som betyr noe. Statusen sier
   det samme som ringen i sammendraget, og plassen trengs til det man skriver. */
body.keyboard-open .actionbar {
  padding-top: 8px;
  padding-bottom: 8px;
  box-shadow: 0 -14px 34px -22px rgba(12, 23, 16, 0.55);
}
body.keyboard-open .actionbar .meta { display: none; }
body.keyboard-open .actionbar .btn-lg { min-height: 48px; }

/* --------------------------------------------------------------------------
   18. Kvittering
   -------------------------------------------------------------------------- */

.receipt { display: none; }
.receipt.show { display: block; animation: rise var(--t-slow) var(--ease-out); }
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }

.receipt .card {
  text-align: center;
  max-width: 620px;
  margin: 0 auto;
  padding: clamp(32px, 5vw, 56px) clamp(20px, 4vw, 48px);
}

.seal {
  position: relative;
  width: 92px; height: 92px;
  margin: 0 auto var(--sp-6);
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
}
.receipt.show:not(.pending) .seal::before {
  content: '✦';
  position: absolute;
  top: -18px; right: -24px;
  color: #e5a900;
  font-size: 24px;
  text-shadow: -96px 28px 0 var(--pos), -72px -18px 0 #e5a900, 8px 94px 0 var(--pos);
  animation: celebrate .7s var(--ease-out) .2s both;
}
@keyframes celebrate { from { opacity: 0; transform: scale(.25) rotate(-25deg); } 60% { transform: scale(1.3) rotate(8deg); } }
.seal::after {
  content: '';
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  border: 1px solid currentColor;
  opacity: 0.22;
  animation: halo 2.6s var(--ease) infinite;
}
@keyframes halo { 0%, 100% { transform: scale(1); opacity: 0.22; } 50% { transform: scale(1.07); opacity: 0.06; } }
.seal svg { width: 46px; height: 46px; }
.seal svg.icon { width: 44px; height: 44px; }
.seal svg path { stroke-dasharray: 48; stroke-dashoffset: 48; animation: draw 0.6s var(--ease-out) 0.15s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.receipt.pending .seal { background: var(--warn-soft); color: var(--warn); }
.receipt.pending .seal svg path { animation: none; stroke-dashoffset: 0; }

.receipt h2 {
  font-family: var(--font-display);
  font-size: clamp(30px, 4vw, 40px);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.005em;
  margin-bottom: var(--sp-3);
}
.receipt > .card > p { color: var(--text-2); max-width: 46ch; margin: 0 auto; text-wrap: pretty; }

.refbox {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-6) 0 var(--sp-3);
  padding: 6px 6px 6px var(--sp-5);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface-sunken);
}
.refbox code {
  font-family: var(--font-mono);
  font-size: 19px;
  letter-spacing: 0.03em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.refbox button {
  display: grid; place-items: center;
  width: 42px; height: 42px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast), transform var(--t-fast) var(--ease);
}
.refbox button:hover { color: var(--accent); border-color: var(--accent); }
.refbox button:active { transform: scale(0.94); }
.refbox button svg { width: 18px; height: 18px; }

.receipt .actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3); margin-top: var(--sp-6); }

/* --------------------------------------------------------------------------
   19. Toaster
   -------------------------------------------------------------------------- */

.toasts {
  position: fixed;
  z-index: var(--z-toast);
  left: 50%;
  bottom: calc(112px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: grid;
  gap: var(--sp-2);
  width: max-content;
  max-width: calc(100vw - 32px);
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 12px 18px;
  border-radius: var(--r-lg);
  background: var(--ink-900);
  color: #fff;
  font-size: 14.5px;
  box-shadow: var(--e4);
  animation: toast-in var(--t-base) var(--ease-out);
}
.toast.out { animation: toast-out var(--t-base) var(--ease) forwards; }
.toast svg { width: 17px; height: 17px; flex: none; color: var(--brand-300); }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px) scale(0.97); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px) scale(0.97); } }

/* --------------------------------------------------------------------------
   20. Bunntekst
   -------------------------------------------------------------------------- */

footer {
  max-width: var(--shell);
  margin: 0 auto;
  /* Handlingslinja ligger fast over bunnen av sida. Uten klaringen her ble de
     nederste linjene i personvernteksten liggende under den, også når man
     hadde rullet helt ned. `--actionbar-h` er null når linja ikke vises. */
  padding: 0 clamp(16px, 3vw, 28px)
    calc(var(--actionbar-h, 0px) + var(--sp-8) + env(safe-area-inset-bottom));
}
.foot-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-6);
  align-items: baseline;
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-3);
}
.foot-inner p { flex: 1; min-width: 260px; max-width: 70ch; }
.emergency {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  flex: none;
  padding: 7px 14px;
  border: 1px solid var(--danger-line);
  border-radius: var(--r-pill);
  background: var(--danger-soft);
  color: var(--danger);
  font-family: var(--font-display);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.build { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); }

.foot-logo { --mark-h: 22px; align-self: center; opacity: 0.7; }
.foot-logo .logo-word { font-size: 10.5px; }

/* --------------------------------------------------------------------------
   21. Meldingstype — «noe gikk galt» / «noe gikk bra»

   De to alternativene har med hensikt lik størrelse, lik kontrast og lik plass.
   Gjøres det positive alternativet mindre eller blassere, blir det lest som
   sekundært — og da meldes det ikke.
   -------------------------------------------------------------------------- */

.mode {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}

.mode-opt { position: relative; display: block; cursor: pointer; }
.mode-opt input {
  position: absolute;
  opacity: 0;
  width: 100%; height: 100%;
  margin: 0;
  cursor: pointer;
}
.mode-opt > span {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 2px var(--sp-3);
  min-height: var(--tap);
  height: 100%;
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--e1);
  transition: border-color var(--t-fast), background var(--t-fast),
              color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast) var(--ease);
}
.mode-opt svg {
  grid-row: 1 / span 2;
  width: 26px; height: 26px;
  color: var(--text-3);
  transition: color var(--t-fast);
}
.mode-opt[data-kind='hendelse'] svg {
  color: var(--danger);
  background: var(--danger-soft);
}
.mode-opt[data-kind='positiv'] svg {
  color: var(--pos);
  background: var(--pos-soft);
}
.mode-opt svg { padding: 7px; width: 42px; height: 42px; border-radius: 12px; }
.mode-opt b {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.15;
}
.mode-opt i {
  font-family: var(--font-body);
  font-weight: 400;
  letter-spacing: 0;
  font-style: normal;
  font-size: 13px;
  line-height: 1.35;
  color: var(--text-3);
}

.mode-opt:hover > span { border-color: var(--ink-400); transform: translateY(-2px); box-shadow: var(--e3); }
.mode-opt:active > span { transform: scale(0.99); }

.mode-opt input:checked + span {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent) inset, var(--e2);
}
.mode-opt input:checked + span svg { color: var(--accent); }
.mode-opt input:checked + span i { color: inherit; opacity: 0.8; }
.mode-opt input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Det positive valget markeres i den lysere grønntonen, så det er tydelig
   hvilken modus skjemaet står i uten å lese teksten. */
.mode-opt[data-kind='positiv'] input:checked + span {
  border-color: var(--pos);
  background: var(--pos-soft);
  color: var(--pos);
  box-shadow: 0 0 0 1px var(--pos) inset, var(--e2);
}
.mode-opt[data-kind='positiv'] input:checked + span svg { color: var(--pos); }

/* På telefon står valgene side om side som kompakte fliser, så skjemaet
   starter høyere opp på skjermen. Lik vekt beholdes. */
@media (max-width: 560px) {
  .mode-opt > span {
    grid-template-columns: 1fr;
    align-content: start;
    gap: 4px;
    padding: var(--sp-4);
  }
  .mode-opt svg { grid-row: auto; margin-bottom: 4px; width: 38px; height: 38px; }
  .mode-opt b { font-size: 18px; }
  .mode-opt i { font-size: 12.5px; }
}
@media (max-width: 340px) {
  .mode { grid-template-columns: 1fr; }
}

.mode-note {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--pos-line);
  border-radius: var(--r-md);
  background: var(--pos-soft);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-2);
}
.mode-note svg { width: 19px; height: 19px; flex: none; color: var(--pos); margin-top: 1px; }
.mode-note b { color: var(--pos); }

/* I positiv modus sier innledningen det samme som notisen — da skjules den. */
body.kind-positive .mode-note { display: none; }
body.kind-positive .mode { margin-bottom: var(--sp-6); }

/* I positiv modus følger stegmerkene og fremdriften den lysere grønntonen. */
body.kind-positive .card.done .step { background: var(--pos-fill); }
body.kind-positive .progress i { background: linear-gradient(90deg, var(--pos), var(--brand-300)); }
body.kind-positive .ring .fg { stroke: var(--pos); }

.receipt.positive .seal { background: var(--pos-soft); color: var(--pos); }

/* --------------------------------------------------------------------------
   22. Kryssoppfordring på kvitteringen
   -------------------------------------------------------------------------- */

/* Kortet rundt er smalt (maks 620 px), så knappen får alltid egen rad.
   På samme linje som teksten ble den klemt og ordene brutt i fire. */
.nudge {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
  padding: var(--sp-5);
  border: 1px solid var(--pos-line);
  border-radius: var(--r-lg);
  background: var(--pos-soft);
  text-align: left;
}
.nudge > svg { width: 28px; height: 28px; color: var(--pos); margin-top: 2px; }
.nudge > div { min-width: 0; }
.nudge b {
  display: block;
  margin-bottom: 3px;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}
.nudge span { font-size: 13.5px; line-height: 1.45; color: var(--text-2); text-wrap: pretty; }
.nudge .btn { grid-column: 2; justify-self: start; }

.btn-pos {
  background: var(--pos-fill);
  color: #fff;
  border-color: var(--pos-fill);
}
.btn-pos:hover:not(:disabled) { filter: brightness(1.07); box-shadow: var(--e3); }

@media (max-width: 520px) {
  .nudge { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .nudge .btn { grid-column: 1; justify-self: stretch; }
}

/* --------------------------------------------------------------------------
   23. Personlig teller i sidepanelet
   -------------------------------------------------------------------------- */

.tally { margin-top: var(--sp-4); }
.tally-head {
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: var(--sp-3);
}
.tally-row { display: flex; gap: var(--sp-6); }
.tally-row span { display: grid; }
.tally-row b {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.tally-row small { font-size: 12px; color: var(--text-3); margin-top: 3px; }
.tally-row .pos b { color: var(--pos); }

.tally-bar {
  height: 5px;
  margin: var(--sp-4) 0 var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--surface-sunken);
  overflow: hidden;
}
.tally-bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--pos);
  transition: width var(--t-slow) var(--ease);
}
.tally-note { font-size: 12.5px; line-height: 1.5; color: var(--text-3); text-wrap: pretty; }

/* --------------------------------------------------------------------------
   24. Poengliga, statistikk og administrasjon

   Seksjonen vokste fram over flere omganger og hadde samlet opp tre lag med
   `.winner-card`, tre `.leader-card` og fem 620 px-blokker som overskrev
   hverandre. Den er nå skrevet ut én gang, i samme form som resten av fila:
   én regel per velger, i den rekkefølgen markup-en leses.

   Bevegelse: seksjonen hadde en gang seks uendelige animasjoner samtidig
   (bane, glimt, to svevende pokaler, glød og ikonpuls) — uro, ikke kvalitet.
   Bevegelsen er nå bygd opp etter én regel: alt som beveger seg gjør det én
   gang, når seksjonen åpnes, og i den rekkefølgen innholdet leses. Bare tre
   ting går rundt og rundt, og alle tre bærer informasjon: pokalen på
   vinnerkortet (og bare når det finnes en vinner), prikken som sier at tallene
   er ferske, og et sjeldent glimt i premiemetallet.

   Detaljene ligger samlet i «Ikonbevegelse» lenger ned i seksjonen.
   -------------------------------------------------------------------------- */

.stats-view {
  width: min(var(--shell), calc(100% - 40px));
  margin: 0 auto;
  padding: var(--sp-7) 0 calc(var(--sp-9) + env(safe-area-inset-bottom));
}

/* --------------------------------------------------------------------------
   Administrasjon

   Panelet er bygd som et arbeidsbord, ikke som et skjema: en topp som sier
   hvilken måned som gjelder, to faner, og kort som hver svarer på ett
   spørsmål — hvor står måneden, hva står på spill, hvem vant.

   Fargebruken er den samme som resten av appen. Det eneste stedet som bryter
   med papirflaten er toppen, som låner den mørke grønnflaten fra poengligaen
   slik at administrasjonen leses som samme produkt.
   -------------------------------------------------------------------------- */

.admin-view {
  display: grid;
  gap: var(--sp-6);
  align-content: start;
  width: min(1020px, calc(100% - 32px));
  margin: 0 auto;
  padding: var(--sp-7) 0 calc(var(--sp-9) + env(safe-area-inset-bottom));
}

.admin-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--sp-6);
  padding: clamp(24px, 4vw, 40px);
  border: 1px solid var(--dark-line);
  border-radius: var(--r-xl);
  background: var(--dark-surface);
  color: var(--on-dark);
  box-shadow: var(--e4);
}
.admin-hero .eyebrow { color: var(--on-dark-3); }
.admin-hero h2 {
  margin: 6px 0 8px;
  font: 700 clamp(34px, 5.4vw, 52px)/.98 var(--font-display);
  letter-spacing: -.01em;
}
.admin-hero-copy p { max-width: 46ch; margin: 0; color: var(--on-dark-2); text-wrap: pretty; }

.admin-hero-facts { display: flex; gap: var(--sp-5); margin: 0; }
.admin-hero-facts div {
  padding: 12px 16px;
  border: 1px solid var(--glass-line);
  border-radius: var(--r-md);
  background: var(--glass-fill);
  /* Lavere elevasjon enn premiekortet: flisene er et nøkkeltall, ikke et kort. */
  box-shadow: var(--glass-inner), var(--de2);
}
.admin-hero-facts dt {
  margin: 0 0 2px;
  color: var(--on-dark-2);
  font: 700 11px/1 var(--font-body);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.admin-hero-facts dd {
  margin: 0;
  font: 700 17px/1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Korn på de tre mørke toppene. Samme struktur som innloggingssida, lagt på
   ::before slik at ringene på ::after står urørt. */
.admin-hero::before,
.stats-hero::before,
.quiz-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.5;
  background-image: var(--grain);
  mix-blend-mode: soft-light;
  pointer-events: none;
}

/* Faner. Samme form som hovedmenyen i topplinja, så de leses som samme slags
   valg — bare i innholdet i stedet for i rammen. */
.admin-tabs {
  display: flex;
  gap: 4px;
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface-sunken);
}
.admin-tab {
  display: inline-flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 var(--sp-4);
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-2);
  font: 600 15px var(--font-body);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.admin-tab svg { width: 18px; height: 18px; }
.admin-tab:hover { color: var(--text); }
.admin-tab.active { color: var(--accent); background: var(--surface); box-shadow: var(--e1); }
.admin-tab:focus-visible { outline-offset: -2px; }

.admin-panel { display: grid; gap: var(--sp-6); align-content: start; }

.admin-card {
  padding: clamp(20px, 3.4vw, 34px);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--e2);
}
.admin-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.admin-card-head h3 { margin: 4px 0 0; font: 700 clamp(24px, 3vw, 32px)/1 var(--font-display); }
.admin-lede { max-width: 66ch; margin: 0 0 var(--sp-5); color: var(--text-2); }

/* Statusbrikka sier med ett blikk om måneden er åpen eller gjort opp. */
.admin-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface-sunken);
  color: var(--text-2);
  font: 700 12.5px var(--font-body);
  letter-spacing: .02em;
}
.admin-status::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ink-400);
}
.admin-status.is-count::before { display: none; }
.admin-status.is-open { border-color: var(--pos-line); background: var(--pos-soft); color: var(--brand-800); }
.admin-status.is-open::before { background: var(--pos); }
.admin-status.is-settled { border-color: var(--line-strong); background: var(--ink-50); color: var(--text-2); }
.admin-status.is-settled::before { background: var(--accent); }

/* Månedsvelger */
.month-picker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
  margin-bottom: var(--sp-5);
}
.month-control { position: relative; flex: 0 1 240px; }
.month-control input { padding-left: 46px; }
.month-control-icon {
  position: absolute;
  left: 15px;
  top: 50%;
  width: 19px; height: 19px;
  transform: translateY(-50%);
  color: var(--text-3);
  pointer-events: none;
}
.month-shortcuts { display: flex; gap: 8px; }
.chip-btn {
  min-height: 42px;
  padding: 0 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-2);
  font: 600 13.5px var(--font-body);
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.chip-btn:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }

/* Nøkkeltall for måneden */
.admin-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.admin-metrics article {
  position: relative;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.metric-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  margin-bottom: 10px;
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent);
}
.metric-icon svg { width: 17px; height: 17px; }
.admin-metrics small {
  display: block;
  color: var(--text-3);
  font: 700 11px/1 var(--font-body);
  letter-spacing: .09em;
  text-transform: uppercase;
}
.admin-metrics b {
  display: block;
  margin-top: 5px;
  font: 700 clamp(28px, 3.4vw, 36px)/1 var(--font-display);
  font-variant-numeric: tabular-nums;
}
.admin-metrics i { display: block; margin-top: 3px; color: var(--text-3); font: 400 12.5px var(--font-body); font-style: normal; }

/* Topp fem. Kompakt, fordi den svarer på «hvem leder», ikke «hva er stillinga». */
.admin-top { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.admin-top li {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.admin-top li.is-leader { border-color: var(--brand-200); background: var(--accent-soft); }
.admin-top .rank {
  color: var(--text-3);
  font: 700 15px var(--font-display);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.admin-top li.is-leader .rank { color: var(--accent); }
.admin-top .who { min-width: 0; }
.admin-top .who b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; }
.admin-top .who small { color: var(--text-3); font-size: 12.5px; }
.admin-top .score { font: 700 16px var(--font-body); font-variant-numeric: tabular-nums; white-space: nowrap; }
.admin-empty {
  margin: 0;
  padding: var(--sp-6) var(--sp-4);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  color: var(--text-3);
  text-align: center;
}

/* Skjemaer i panelet */
.admin-card form { display: grid; gap: var(--sp-4); }
.user-form { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); align-items: end; }
.user-form .err,
.user-form .admin-actions { grid-column: 1 / -1; }
.admin-card select {
  width: 100%;
  min-height: var(--tap);
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}
.admin-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); }
.admin-actions .btn { gap: 9px; }
.admin-actions .btn svg { width: 18px; height: 18px; }
.admin-saved { color: var(--ok); font-weight: 600; }
/* Grønt betyr «lagret». En forklaring på hvorfor feltene er låst er ikke en
   bekreftelse, og skal ikke låne den fargen. */
.admin-saved.is-note { color: var(--text-3); font-weight: 400; }

.secondary-prize-field {
  padding: 18px;
  border: 1px solid var(--brand-200);
  border-radius: var(--r-md);
  background: var(--accent-soft);
}
.secondary-prize-field .check-label {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: 11px;
  margin-bottom: 12px;
  cursor: pointer;
}
.secondary-prize-field .check-label input {
  flex: none;
  width: 20px; height: 20px;
  margin-top: 2px;
  accent-color: var(--accent);
}
.check-copy { min-width: 0; }
.check-copy b { display: block; font-size: 15px; }
/* Hjelpeteksten står inne i en <label>, som setter halvfet display-skrift.
   Den skal leses som brødtekst, ikke som en andre overskrift. */
.check-copy small {
  display: block;
  margin-top: 3px;
  color: var(--text-2);
  font: 400 13.5px/1.45 var(--font-body);
  letter-spacing: 0;
}
.secondary-prize-field input[type='text']:disabled { background: var(--surface-2); color: var(--text-3); }

/* Månedsavslutning: to vinnere, side om side, med samme vekt. */
.settle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--sp-3);
}
.settle-winner {
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
.settle-winner.has-winner { border-color: var(--brand-200); background: var(--accent-soft); }
.settle-winner.is-muted { opacity: .72; }
.settle-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  margin-bottom: 12px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text-3);
}
.settle-winner.has-winner .settle-icon { border-color: var(--brand-200); color: var(--accent); }
.settle-icon svg { width: 21px; height: 21px; }
.settle-winner small {
  display: block;
  color: var(--text-3);
  font: 700 11px/1 var(--font-body);
  letter-spacing: .09em;
  text-transform: uppercase;
}
.settle-winner b {
  display: block;
  margin: 7px 0 4px;
  font: 700 clamp(22px, 2.6vw, 28px)/1.05 var(--font-display);
}
.settle-winner span { color: var(--text-2); font-size: 14px; }

.admin-note {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: var(--sp-5) 0 0;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
  color: var(--text-3);
  font-size: 13.5px;
}
.admin-note svg { flex: none; width: 17px; height: 17px; }

/* Feillinjene i panelet står tomme til noe går galt. `.err` er skjult som
   standard fordi skjemaet viser den per felt; her er det teksten som avgjør. */
.admin-card .err:not(:empty) { display: flex; }

/* --------------------------------------------------------------------------
   Innstillinger: hva appen inneholder

   Én rad per del av appen. HMS-meldingen står først og er låst på — den er
   appen, og alt under er bygd oppå den. Tilleggene låner bryteren fra «Meld
   anonymt», så et av/på-valg ser likt ut overalt i appen. En låst rad og en
   bryterrad har samme høyde og samme ikonflis, så lista leses som én ting.
   -------------------------------------------------------------------------- */
.feature-list { display: grid; gap: var(--sp-3); margin: 0; padding: 0; list-style: none; }
.feature-row {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: 78px;
  margin: 0;
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-sunken);
}
.switch.feature-row { margin-bottom: 0; }
.feature-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text-3);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.feature-icon svg { width: 21px; height: 21px; }
.feature-row.is-core .feature-icon,
.switch.feature-row:has(input:checked) .feature-icon { border-color: var(--brand-200); color: var(--accent); }
.feature-copy { flex: 1; min-width: 0; }
.feature-copy b {
  display: block;
  font: 600 17px/1.2 var(--font-display);
  letter-spacing: 0.01em;
}
.feature-copy small {
  display: block;
  margin-top: 3px;
  color: var(--text-3);
  font: 400 13.5px/1.45 var(--font-body);
  letter-spacing: 0;
}
.feature-lock {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-2);
  font: 700 12.5px var(--font-body);
  letter-spacing: .02em;
  white-space: nowrap;
}
.feature-lock svg { width: 14px; height: 14px; }
/* Lagringen tar et øyeblikk. Bryteren er sperret så lenge, men den skal ikke
   se avslått ut — bare banen puster til serveren har svart. */
.switch.feature-row.is-saving { cursor: progress; }
.switch.feature-row.is-saving:has(input:disabled) { opacity: 1; }
.switch.feature-row.is-saving .track { animation: feature-saving .8s var(--ease) infinite alternate; }
@keyframes feature-saving { to { opacity: .55; } }
.feature-saved { margin: var(--sp-4) 0 0; font-size: 14.5px; }
.feature-saved:empty { display: none; }

/* Brukerliste */
.search-control { position: relative; margin-bottom: var(--sp-4); }
.search-control input { padding-left: 46px; }
.search-icon {
  position: absolute;
  left: 15px;
  top: 50%;
  width: 18px; height: 18px;
  transform: translateY(-50%);
  color: var(--text-3);
  pointer-events: none;
}
.user-list { display: grid; gap: 8px; }
.user-row {
  display: grid;
  grid-template-columns: 42px minmax(120px, 1fr) auto auto auto;
  gap: 12px;
  align-items: center;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  transition: border-color var(--t-fast) var(--ease);
}
.user-row:hover { border-color: var(--line-strong); }
.user-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  border-radius: 13px;
  background: var(--accent-soft);
  color: var(--accent);
  font: 700 15px var(--font-body);
}
.user-row.is-admin .user-avatar { background: var(--accent-fill); color: var(--text-inv); }
.user-row .who { min-width: 0; }
.user-row strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-row small { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; }
.user-tag {
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--ink-100);
  color: var(--text-2);
  font: 700 11px var(--font-body);
  letter-spacing: .04em;
  text-transform: uppercase;
}
.user-row.is-inactive { background: var(--surface); opacity: .66; }
.user-row.is-inactive .user-tag { background: var(--warn-soft); color: var(--warn); }
.user-row select { min-height: 42px; width: auto; min-width: 140px; }
.user-row button {
  min-height: 42px;
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-2);
  font: 600 13px var(--font-body);
  white-space: nowrap;
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.user-row button:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.user-row button.danger:hover { border-color: var(--danger-line); color: var(--danger); background: var(--danger-soft); }
.user-row.is-self .user-tag-you { background: var(--accent-soft); color: var(--accent); }

/* Toppseksjon på poengligaen. Mørk flate, men innenfor merkevaregrønt —
   #0d2117 → #07542d er samme familie som resten, ikke et fremmed mørkt felt. */
.stats-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr minmax(280px, 360px);
  align-items: end;
  gap: var(--sp-8);
  margin-bottom: var(--sp-5);
  padding: clamp(26px, 5vw, 52px);
  border: 1px solid var(--dark-line);
  border-radius: var(--r-xl);
  color: var(--on-dark);
  background: var(--dark-surface);
  box-shadow: var(--e4);
}
/* Stille ringer i hjørnet — dybde, ikke bevegelse. */
.stats-hero::after {
  content: '';
  position: absolute;
  z-index: -1;
  top: -210px; right: -120px;
  width: 360px;
  aspect-ratio: 1;
  border: 1px solid var(--dark-ring);
  border-radius: 50%;
  box-shadow: 0 0 0 52px rgba(136, 219, 170, .035), 0 0 0 104px rgba(136, 219, 170, .025);
}
.stats-hero h2 {
  font: 700 clamp(34px, 9vw, 68px)/.95 var(--font-display);
  letter-spacing: -.02em;
  text-wrap: balance;
}
.stats-hero .eyebrow { color: var(--on-dark-3); }
.stats-hero > div > p:last-child {
  max-width: 62ch;
  margin-top: var(--sp-4);
  color: var(--on-dark-2);
  text-wrap: pretty;
}

/* Premiekortet — glass på den mørke flata. */
.prize-card {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5);
  border: 1px solid var(--glass-line);
  border-radius: var(--r-lg);
  color: var(--on-dark);
  background: var(--glass-fill);
  box-shadow: var(--glass-inner), var(--de3);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.prize-item { display: flex; align-items: center; gap: var(--sp-4); }
.prize-item[hidden] { display: none; }
.prize-item.points-prize {
  padding-top: var(--sp-3);
  border-top: 1px solid rgba(255,255,255,.18);
}
/* Ikonet står i en egen flis slik at gløden og gnisten (24b) har noe å henge
   på — pseudoelementer fester seg ikke på <svg>. */
.prize-icon {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
}
.prize-card svg {
  width: 62px; height: 62px;
  flex: none;
  color: #ffd65a;
  filter: drop-shadow(0 6px 12px rgba(5, 16, 10, .42));
}
.prize-text { display: grid; min-width: 0; }
.prize-card small {
  opacity: .8;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.prize-card b { font: 700 21px/1.15 var(--font-display); }

/* Nøkkeltall. Tallene settes med tabellsifre som ellers i appen, slik at de
   ikke hopper sidelengs når verdien endrer seg. */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}
.stats-grid article {
  position: relative;
  overflow: hidden;
  display: grid;
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(145deg, var(--surface), var(--surface-2));
  box-shadow: var(--e2);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.stats-grid article::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: linear-gradient(var(--brand-400), var(--brand-700));
}
@media (hover: hover) {
  .stats-grid article:hover { transform: translateY(-2px); box-shadow: var(--e3); }
}
.stats-grid article:active { transform: scale(.99); }
.stats-grid small { color: var(--text-3); font-weight: 600; }
.stats-grid b {
  margin: 5px 0;
  font: 700 38px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
/* `text-transform: capitalize` sto her og tittelkasset undertekstene på alle
   fire språk («Med Godkjent Bidrag»). Norsk, polsk og rumensk bruker ikke
   tittelkasse — teksten står nå som den er skrevet. */
.stats-grid span { color: var(--text-3); font-size: 12px; }

/* Vinnerkort */
.winner-card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
  padding: 15px 18px;
  border: 1px solid #d8b34b;
  border-radius: var(--r-lg);
  /* Flatene er lagt større enn kortet slik at 24b kan dra gulllyset tvers over
     dem med `background-position` i stedet for å male nye gradienter. */
  background:
    radial-gradient(circle at 92% 0, rgba(255,220,105,.46), transparent 30%),
    linear-gradient(125deg, #fff8d7, #fff 52%, #fff1b8);
  background-size: 135% 135%, 190% 100%;
  background-position: 100% 0, 0 50%;
  box-shadow: 0 18px 42px rgba(112,74,0,.13), inset 0 1px rgba(255,255,255,.9);
}
.winner-card[hidden] { display: none; }
.winner-card::after {
  content: '';
  position: absolute;
  z-index: -1;
  right: -55px;
  width: 120px;
  aspect-ratio: 1;
  border: 1px solid rgba(154,105,0,.14);
  border-radius: 50%;
  box-shadow: 0 0 0 26px rgba(154,105,0,.04), 0 0 0 52px rgba(154,105,0,.025);
}
.winner-icon {
  --tilt: -3deg;
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 48px; height: 48px;
  border-radius: 15px;
  color: #714700;
  /* To lag: et lysstrøk som feies over metallet (24b flytter det med
     `background-position`), og selve legeringen under. */
  background:
    linear-gradient(115deg, transparent 32%, rgba(255,255,255,.92) 47%, transparent 62%) -140% 0 / 260% 100% no-repeat,
    linear-gradient(145deg, #ffe88e, #dca51d);
  box-shadow: inset 0 2px rgba(255,255,255,.7), 0 10px 24px rgba(151,99,0,.25);
  transform: rotate(var(--tilt));
}
.winner-icon svg { width: 25px; height: 25px; }
/* Svevet settes sammen med inngangsbevegelsen i 24b, slik at pokalen ikke får
   to animasjoner som slåss om `transform`. Hvilevinkelen kommer fra `--tilt`,
   så pokalen (−3°) og medaljen (+3°) kan dele samme keyframe. */
@keyframes trophy-float {
  0%, 100% { transform: translateY(0) rotate(var(--tilt)) scale(1); }
  50% { transform: translateY(-2.5px) rotate(calc(var(--tilt) + 2.5deg)) scale(1.028); }
}
.winner-copy { flex: 1; min-width: 0; }
.winner-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.winner-text { min-width: 0; }
.winner-copy .points-winner {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(128,92,10,.18);
}
.winner-copy .points-winner[hidden] { display: none; }
/* Medaljen får sin egen legering, så de to premiene leses fra hverandre på
   én meters avstand — pokalen i gull, poengmedaljen i kobber. */
.winner-icon-medal {
  --tilt: 3deg;
  color: #6a3708;
  background:
    linear-gradient(115deg, transparent 32%, rgba(255,255,255,.92) 47%, transparent 62%) -140% 0 / 260% 100% no-repeat,
    linear-gradient(145deg, #ffd9a0, #d4802a);
  box-shadow: inset 0 2px rgba(255,255,255,.7), 0 10px 24px rgba(151,78,0,.28);
}
.winner-card small {
  color: #805c0a;
  font-weight: 800;
  letter-spacing: .11em;
  text-transform: uppercase;
}
.winner-card h3 { margin: 3px 0; font: 700 21px var(--font-display); }
.winner-card p { color: var(--text-2); font-size: 13px; }
.winner-badge {
  position: relative;
  margin-left: auto;
  padding: 8px 13px;
  border: 1px solid rgba(128,92,10,.22);
  border-radius: var(--r-pill);
  color: #745108;
  background:
    linear-gradient(115deg, transparent 34%, rgba(255,255,255,.95) 50%, transparent 66%) -140% 0 / 240% 100% no-repeat,
    rgba(255,255,255,.55);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Liga + regler */
.leader-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 285px;
  gap: var(--sp-5);
  align-items: start;
}
.leader-card,
.rules-card {
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
}
.leader-card {
  overflow: hidden;
  padding: clamp(22px, 3vw, 34px);
  box-shadow: 0 18px 42px rgba(22,52,36,.1);
}
.leader-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--sp-5);
}
.leader-head h3,
.rules-card h3 { font: 600 25px var(--font-display); }
.live-dot { color: var(--ok); font-size: 12px; font-weight: 600; }
.live-dot::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 7px;
  border-radius: 50%;
  background: currentColor;
}

.leaderboard { list-style: none; }
.leaderboard li {
  display: grid;
  grid-template-columns: 40px 50px 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  min-height: 76px;
  padding: 10px var(--sp-3);
  border-top: 1px solid var(--line);
  transition: background var(--t-base), transform var(--t-base) var(--ease);
}
@media (hover: hover) {
  .leaderboard li:hover { background: var(--surface-sunken); transform: translateX(2px); }
}
.leaderboard li:active { background: var(--surface-sunken); }
/* Pallen */
.leaderboard li:nth-child(-n+3) {
  margin: 5px 0;
  border: 1px solid color-mix(in srgb, var(--brand-300) 55%, var(--line));
  border-radius: var(--r-md);
  background: linear-gradient(90deg, color-mix(in srgb, var(--brand-100) 82%, white), var(--surface));
  box-shadow: 0 8px 20px rgba(20,75,46,.08);
}
.leaderboard li:nth-child(1) {
  border-color: #ddbd55;
  background: linear-gradient(90deg, #fff4bf, #fffdf4 65%, var(--surface));
}
.leaderboard li:nth-child(1) .rank::before {
  content: '★';
  display: block;
  color: #b27a00;
  font-size: 12px;
  line-height: .8;
}
.leaderboard li.eligible:nth-child(n+4) {
  background: linear-gradient(90deg, color-mix(in srgb, var(--brand-100) 52%, transparent), transparent);
}
.rank {
  text-align: center;
  font: 600 17px var(--font-display);
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}
.eligible .rank { color: var(--brand-700); }
.leader-avatar {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border: 2px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 15px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 13px;
  font-weight: 800;
  box-shadow: inset 0 1px #fff;
}
.leader-name { display: grid; min-width: 0; }
.leader-name b {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 16px;
}
.leader-name small { color: var(--text-3); font-variant-numeric: tabular-nums; }
.leaderboard strong {
  font: 700 21px var(--font-display);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
.leader-score { display: grid; justify-items: end; line-height: 1.15; }
/* Sto på 10 px, under lesbar grense for en tallverdi. */
.leader-score em {
  color: #ad6800;
  font-size: 11.5px;
  font-style: normal;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Lasting: skjelettrader i samme form som ei ferdig rad, i stedet for en
   tekstlinje som hopper til innhold. Radene er `aria-hidden` — skjermlesere
   får statusteksten i `.leader-loading` i stedet. */
.leaderboard li.leader-skeleton {
  margin: 0;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  background: none;
  box-shadow: none;
  animation: none;
  pointer-events: none;
}
/* Ett sveip for alle skjelett i appen — poengligaen, nøkkeltallene og
   adminpanelet. Oppskrifta stod før to steder med samme verdier. */
.sk,
.stats-grid.is-loading b,
.admin-metrics.is-loading b {
  background: linear-gradient(90deg, var(--surface-sunken) 0%, var(--ink-100) 50%, var(--surface-sunken) 100%);
  background-size: 200% 100%;
  animation: sk-sweep 1.4s var(--ease) infinite;
}
@keyframes sk-sweep { to { background-position: -200% 0; } }
.sk { display: block; border-radius: var(--r-pill); }

/* Tall som lastes: sjølve sifferet skjules, flata holder plassen. */
.stats-grid.is-loading b,
.admin-metrics.is-loading b {
  min-width: 3ch;
  border-radius: var(--r-sm);
  color: transparent;
}
/* Tellerne under tallet ville ellers stå og peke på en tom flate. */
.admin-metrics.is-loading i { visibility: hidden; }

/* Poengligaen */
.sk-rank { width: 18px; height: 14px; margin: 0 auto; border-radius: var(--r-sm); }
.sk-avatar { width: 46px; height: 46px; border-radius: 15px; }
.sk-name { width: min(62%, 190px); height: 14px; }
.sk-score { width: 48px; height: 18px; border-radius: var(--r-sm); justify-self: end; }
.leader-skeleton:nth-child(2) .sk { animation-delay: .12s; }
.leader-skeleton:nth-child(3) .sk { animation-delay: .24s; }
.leader-skeleton:nth-child(4) .sk { animation-delay: .36s; }
.leader-skeleton:nth-child(n+5) .sk { animation-delay: .48s; }

/* Brukerlista i adminpanelet. Lista viste «Laster brukere …» på én linje og
   hoppet til rader når svaret kom — samme feilen skjelettradene i poengligaen
   ble laget for å unngå. Rutenettet er identisk med .user-row. */
.user-skeleton {
  display: grid;
  grid-template-columns: 42px minmax(120px, 1fr) auto auto auto;
  gap: 12px;
  align-items: center;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  pointer-events: none;
}
.sk-user-avatar { width: 42px; height: 42px; border-radius: 13px; }
.sk-user-who { display: grid; gap: 7px; min-width: 0; }
.sk-user-name { width: min(58%, 150px); height: 14px; }
.sk-user-meta { width: min(36%, 92px); height: 11px; }
.sk-user-role { width: 140px; height: 42px; border-radius: var(--r-md); }
.sk-user-btn { width: 84px; height: 42px; }
.user-skeleton:nth-child(2) .sk { animation-delay: .1s; }
.user-skeleton:nth-child(3) .sk { animation-delay: .2s; }
.user-skeleton:nth-child(n+4) .sk { animation-delay: .3s; }

/* Tomtilstanden er en <li> og arvet derfor både pallens gullflate og
   stjerna fra `li:nth-child(1)`. Den er en beskjed, ikke en førsteplass, så
   velgeren tar med `.leaderboard li` — da vinner den uten `!important`. */
.leaderboard li.leader-empty {
  display: grid;
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: center;
  margin: 0;
  padding: var(--sp-8);
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--text-2);
}
.leader-empty span { font-size: 13px; }
.leader-foot {
  margin-top: var(--sp-4);
  padding: 13px 15px;
  border-radius: var(--r-md);
  background: var(--surface-sunken);
  color: var(--text-2);
  font-size: 12px;
  line-height: 1.55;
}
.leader-foot strong { color: var(--accent); }

.rules-card {
  padding: var(--sp-6);
  background: linear-gradient(160deg, var(--surface) 55%, var(--surface-sunken));
  box-shadow: var(--e2);
}
.rules-card > p:not(.eyebrow) {
  margin-bottom: var(--sp-5);
  color: var(--text-3);
  font-size: 12.5px;
}
.rules-card ul { list-style: none; margin: var(--sp-5) 0; }
.rules-card li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 12px 0;
  border-top: 1px solid var(--line);
}
.rules-card li > span:last-child {
  display: grid;
  /* Uten denne kan ikke tekstkolonnen krympe under sin egen maksbredde, og da
     stakk regelteksten ut over kortkanten på telefon. */
  min-width: 0;
  gap: 2px;
  font-size: 14px;
  line-height: 1.35;
}
.rules-card li small { color: var(--text-3); font-size: 12px; }
.rule-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px; height: 40px;
  border: 1px solid var(--brand-200);
  border-radius: 12px;
  color: var(--accent);
  background: var(--accent-soft);
}
.rule-icon svg { width: 21px; height: 21px; }
.rules-card .streak-rule {
  margin-top: 5px;
  padding-inline: 10px;
  border: 0;
  border-radius: var(--r-md);
  background: linear-gradient(110deg, var(--warn-soft), var(--pos-soft));
}
.streak-rule .rule-icon {
  border-color: var(--warn-line);
  color: var(--warn);
  background: color-mix(in srgb, var(--warn-soft) 70%, white);
}
.rules-card .quiz-rule {
  margin-top: 5px;
  padding-inline: 10px;
  border: 0;
  border-radius: var(--r-md);
  background: linear-gradient(110deg, var(--pos-soft), var(--accent-soft));
}
.quiz-rule .rule-icon { border-color: var(--pos-line); color: var(--pos); background: #fff; }
.rules-card .ticket-rule {
  margin-top: 6px;
  padding: 13px 10px;
  border: 1px solid #ead083;
  border-radius: var(--r-md);
  background: linear-gradient(110deg, #fff8dc, #fffdf4);
}
.ticket-rule .rule-icon { border-color: #e1bd4d; color: #855800; background: #ffefaf; }
.rules-card .rules-note {
  padding: var(--sp-4);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--accent-soft);
  color: var(--text-2) !important;
}
.rules-note strong { color: var(--accent); }
/* Den andre notatblokka forklarer månedsnullstillingen. Den står som en egen
   rad, ikke som en ny kant rett under den forrige. */
.rules-card .rules-note + .rules-note { margin-top: var(--sp-3); }

/* --------------------------------------------------------------------------
   24b. Bevegelse i poengligaen — ikoner og utheving

   Seksjonen vises og skjules med `hidden`, altså `display: none`. Da starter
   animasjonene av seg selv på nytt hver gang poengligaen åpnes — uten en
   eneste linje JavaScript.

   Opptegningen: strekikonene ligger i <use>, og indre former kan ikke velges
   med CSS derfra. Men `stroke-dasharray` og `stroke-dashoffset` er arvede
   SVG-egenskaper, så de går ned i skyggetreet av seg selv. Ingen bane i
   24×24-rutenettet er lengre enn dashen på 120, så hver strek går fra helt
   usynlig til hel — i stedet for å få et hull på midten.

   Fyllmodus er `backwards`, ikke `both`: da slipper animasjonen taket på
   `transform` når den er ferdig, slik at trykk og peker får styre ikonet
   etterpå. Med `both` ville ikonene stått fastlåst i sluttbildet sitt.

   Forsinkelsene er samlet i `--d` på raden, slik at flisa, ikonet, tallet og
   opptegningen henger sammen i stedet for å telles fire steder. Rekkefølgen
   innenfor en rad er alltid den samme: raden lander, så ikonet, så tallet.

   Uthevingen: pallen har et lysstrøk (`sheen`) som går én gang etter at raden
   har landet. Premiekortet og vinnerkortet hadde det samme strøket i sløyfe,
   men det er tatt bort igjen — de to kortene står nå uten feiende lys.

   Bevegelsen er delt i to. Resten av sida holder den rolige regelen — sjelden
   bevegelse som bærer informasjon: prikken som sier at tallene er ferske,
   flammen på vanebonusen og stjerna over førsteplassen, som alle står stille
   i 90 % av løkka.

   Premiekortet og vinnerkortet er unntaket, og det med vilje. De to er
   gulrota i hele poengligaen, så de skal fange blikket fra andre siden av
   rommet: en kant som puster, metall som fanger lys og premietekst som
   skimrer. Pokalen og medaljen har hver sin bevegelse — pokalen letter,
   medaljen svinger i båndet sitt — og de går i utakt, slik at de leses som to
   premier og ikke som én blinkende flate.

   Tempoet er skrudd ned én omgang til. Utslagene er omtrent halvert, og
   løkkene er omtrent dobbelt så lange: det som før slo hvert fjerde sekund
   slår nå hvert sjuende. Tre løkker er tatt helt bort, fordi de gjorde samme
   jobb som en annen løkke på samme flate — gloria bak premieikonet (gløden
   står, den puster ikke lenger), gnisten ved vinnerflisa, og skimmeret på
   merkelappen. Da står det igjen én gest per flate, og bevegelsen leses som
   noe som skjer i stedet for noe som går.

   Alt sammen går på `transform`, `opacity`, `filter`, `background-position`,
   `border-color` og `box-shadow`. Ingen av dem regner om layout, og hele
   blokka slås av av `prefers-reduced-motion` nederst i fila.
   -------------------------------------------------------------------------- */

@keyframes icon-draw { from { stroke-dashoffset: 120; } }
@keyframes icon-rise {
  from { opacity: 0; transform: translateY(10px) scale(.9); }
}
@keyframes icon-pop {
  0% { opacity: 0; transform: scale(.8) rotate(-9deg); }
  58% { transform: scale(1.03) rotate(1.5deg); }
  100% { opacity: 1; transform: none; }
}
@keyframes row-in {
  from { opacity: 0; transform: translateY(12px); }
}
@keyframes bar-grow {
  from { transform: scaleY(0); }
}
@keyframes leader-in {
  from { opacity: 0; transform: translateX(-14px); }
}
/* Tall kommer nedenfra og setter seg — samme gest som i kvitteringen. */
@keyframes value-in {
  from { opacity: 0; transform: translateY(7px) scale(.94); }
}

/* Lysstrøket. Elementet står utenfor venstre kant i hvile og klippes bort av
   `overflow: hidden`; animasjonen drar det tvers over flata og ut igjen. Bare
   `transform` og `opacity` — ingen layout, ingen maling. */
@keyframes sheen {
  0% { opacity: 0; transform: translateX(0) skewX(-16deg); }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translateX(400%) skewX(-16deg); }
}

/* Gnisten som popper ved hjørnet av et ikon — fire spisser, klippet ut av en
   rute, så den koster ingenting å male. */
@keyframes sparkle {
  0%, 74%, 100% { opacity: 0; transform: scale(.2) rotate(0deg); }
  81% { opacity: .85; transform: scale(.9) rotate(45deg); }
  89% { opacity: .45; transform: scale(.66) rotate(72deg); }
}

.leaderboard li:nth-child(-n+3):not(.leader-skeleton):not(.leader-empty)::after {
  content: '';
  position: absolute;
  z-index: 2;
  top: -20%; bottom: -20%;
  left: -55%;
  width: 38%;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.4), transparent);
  animation: sheen 1.5s var(--ease-out) calc(var(--d, 0ms) + 560ms) backwards;
}

/* --------------------------------------------------------------------------
   Premiekortet — hele boksen

   Kortet er stedet der månedens premie og poengpremien står, og det skal
   fange blikket fra andre siden av rommet: kanten og slagskyggen puster i
   gull (`prize-aura`). Lysstrøket som feide over flata er tatt bort.

   Pusten går på `border-color` og `box-shadow` — ingen layout blir regnet om
   mens det går.
   -------------------------------------------------------------------------- */
.prize-card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  animation: prize-aura 7.2s var(--ease) infinite;
}
@keyframes prize-aura {
  0%, 100% {
    border-color: var(--glass-line);
    box-shadow: var(--glass-inner), var(--de3);
  }
  50% {
    border-color: rgba(255,228,146,.5);
    box-shadow:
      inset 0 1px rgba(255,255,255,.18),
      var(--de3),
      0 0 22px rgba(255,214,90,.18);
  }
}
/* Pokalen og medaljen. Flisa bærer gloria og gnist, `<svg>` bærer bevegelsen
   og glimtet — pseudoelementer fester seg ikke på et `<svg>`, så ikonet måtte
   få en beholder rundt seg.

   Gloria pustet før. Den står nå stille: gløden gjør jobben sin like godt i
   ro, og ikonet over den er allerede i bevegelse. */
.prize-icon::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -22%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,214,90,.46), rgba(255,214,90,0) 68%);
  filter: blur(7px);
}
.prize-icon::after {
  content: '';
  position: absolute;
  top: -2%; right: -4%;
  width: 13px;
  aspect-ratio: 1;
  opacity: 0;
  background: #fff8dc;
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%, 41% 59%, 0% 50%, 41% 41%);
  filter: drop-shadow(0 0 5px rgba(255,236,168,.9));
  animation: sparkle 9s var(--ease) 2.4s infinite;
}
.prize-icon-medal::after { animation-delay: 6.8s; }
.prize-item svg {
  stroke-dasharray: 120;
  animation:
    icon-rise .72s var(--ease-out) backwards,
    icon-draw 1.15s var(--ease-out) backwards,
    trophy-lift 7s var(--ease) 1.3s infinite,
    prize-glint 7s var(--ease) 1.3s infinite;
}
.prize-item.points-prize svg {
  /* Medaljen henger i et bånd, så den svinger fra opphenget i stedet for å
     lette. Den er også en halv takt bak pokalen, slik at de to ikke slår i
     samme slag. */
  transform-origin: 50% 12%;
  animation:
    icon-rise .72s var(--ease-out) .14s backwards,
    icon-draw 1.15s var(--ease-out) .14s backwards,
    medal-swing 7s var(--ease) 4.8s infinite,
    prize-glint 7s var(--ease) 4.8s infinite;
}
/* Utslagene er omtrent halvert mot forrige runde: pokalen letter tre piksler
   i stedet for sju, og vrir seg to grader i stedet for seks. Gesten er den
   samme — den er bare ikke lenger en hoppende flate. */
@keyframes trophy-lift {
  0%, 68%, 100% { transform: translateY(0) rotate(0deg) scale(1); }
  14% { transform: translateY(-3px) rotate(-2.5deg) scale(1.035); }
  30% { transform: translateY(-.5px) rotate(2deg) scale(1.012); }
  46% { transform: translateY(-1.5px) rotate(-1deg) scale(1.02); }
}
@keyframes medal-swing {
  0%, 74%, 100% { transform: rotate(0deg) scale(1); }
  13% { transform: rotate(-5.5deg) scale(1.03); }
  30% { transform: rotate(3.5deg) scale(1.016); }
  47% { transform: rotate(-2deg) scale(1.008); }
  62% { transform: rotate(1deg) scale(1); }
}
@keyframes prize-glint {
  0%, 52%, 100% { color: #ffd65a; filter: drop-shadow(0 6px 12px rgba(5, 16, 10, .42)); }
  62% {
    color: #fff3c4;
    filter: drop-shadow(0 0 11px rgba(255,240,178,.6)) drop-shadow(0 6px 12px rgba(5, 16, 10, .42));
  }
  76% {
    color: #ffe27a;
    filter: drop-shadow(0 0 6px rgba(255,226,122,.35)) drop-shadow(0 6px 12px rgba(5, 16, 10, .42));
  }
}
/* Premieteksten selv skimrer i gull. `background-clip: text` er pakket inn i
   `@supports`, så teksten aldri kan bli usynlig der klippet mangler. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .prize-card b {
    background: linear-gradient(100deg, #ffe9a8 20%, #ffffff 42%, #ffe9a8 64%) 0 0 / 280% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    animation: text-shimmer 9s var(--ease) 1.6s infinite;
  }
}
/* Skimmeret bruker under en tredjedel av løkka på å passere, og står stille
   resten — det er et glimt, ikke en rulletekst. */
@keyframes text-shimmer {
  0% { background-position: 180% 0; }
  30%, 100% { background-position: -80% 0; }
}

/* --------------------------------------------------------------------------
   Vinnerkortet — begge vinnerne

   Kortet viser to premier: månedens trekning (pokal) og flest poeng
   (medalje). Begge har nå sin egen flis, og begge er i bevegelse:

     · flisa svever eller svinger, og metallet fanger lys (`tile-shine`)
     · selve streken i ikonet tegnes opp og glimter (`winner-glint`)
     · gulllyset driver rolig tvers over kortet (`gold-drift`)

   Pulsen er tatt bort: kanten, gloria rundt flisa, ringene bak kortet og
   merkelappen står nå i ro, og lysstrøket feier ikke lenger over flata.
   Gnisten ved hjørnet av flisa er også tatt bort — metallet fanger allerede
   lys to ganger her, og en tredje blink på samme flate var én for mye.

   Når kortet faktisk har en vinner (`.has-winner`) sprer ringene seg ut én
   gang og svevet starter.
   -------------------------------------------------------------------------- */
.winner-card { animation: gold-drift 14s var(--ease) infinite; }
@keyframes gold-drift {
  0%, 100% { background-position: 100% 0, 0 50%; }
  50% { background-position: 0 100%, 100% 50%; }
}
/* Ringene står stille, og sprer seg ut én gang idet kortet får en vinner. */
.winner-card.has-winner::after {
  animation: winner-rings 1.6s var(--ease-out) .5s backwards;
}
@keyframes winner-rings {
  from { opacity: 0; transform: scale(.55); }
}

/* Flisa: spretter inn og fanger lys. To animasjoner på to ulike egenskaper —
   `transform` og `background-position` — så ingen av dem overskriver
   hverandre. */
.winner-icon {
  animation:
    winner-pop .78s var(--ease-out) .12s backwards,
    tile-shine 7.5s var(--ease) 1.4s infinite;
}
.winner-icon-medal {
  animation:
    winner-pop .78s var(--ease-out) .26s backwards,
    tile-shine 7.5s var(--ease) 5.1s infinite;
}
@keyframes winner-pop {
  0% { opacity: 0; transform: scale(.78) rotate(-14deg); }
  60% { transform: scale(1.05) rotate(1deg); }
  100% { opacity: 1; transform: rotate(var(--tilt)); }
}
/* Strøket bruker den første femtedelen av løkka og hviler resten. */
@keyframes tile-shine {
  0% { background-position: -140% 0, 0 0; }
  20%, 100% { background-position: 150% 0, 0 0; }
}
.winner-icon svg {
  stroke-dasharray: 120;
  animation:
    icon-draw 1.1s var(--ease-out) .3s backwards,
    winner-glint 7.5s var(--ease) 1.8s infinite;
}
.winner-icon-medal svg { animation-delay: .44s, 5.5s; }
/* Glimtet går på `filter`, ikke `color`, slik at streken beholder legeringen
   sin — gull i pokalen, kobber i medaljen. */
@keyframes winner-glint {
  0%, 56%, 100% { filter: none; }
  66% { filter: drop-shadow(0 0 5px rgba(255,255,255,.6)) brightness(1.25); }
  80% { filter: drop-shadow(0 0 2px rgba(255,255,255,.3)) brightness(1.08); }
}
/* Svevet starter først når noen faktisk har vunnet, og først etter at
   inngangsbevegelsen har sluppet taket på `transform`. */
.winner-card.has-winner .winner-icon {
  animation:
    winner-pop .78s var(--ease-out) .12s backwards,
    trophy-float 6.4s ease-in-out 1.3s infinite,
    tile-shine 7.5s var(--ease) 1.4s infinite;
}
.winner-card.has-winner .winner-icon-medal {
  animation:
    winner-pop .78s var(--ease-out) .26s backwards,
    medal-hang 6.4s ease-in-out 2.2s infinite,
    tile-shine 7.5s var(--ease) 5.1s infinite;
}
@keyframes medal-hang {
  0%, 100% { transform: rotate(var(--tilt)) scale(1); }
  25% { transform: rotate(calc(var(--tilt) - 4deg)) scale(1.025); }
  60% { transform: rotate(calc(var(--tilt) + 3deg)) scale(1.015); }
}
.winner-card h3 { animation: value-in .6s var(--ease-out) .34s backwards; }
/* Vinnernavnet står i mørkt gull. Gradienten holder seg i et sjikt som
   fortsatt leses mot det lyse kortet.

   Navnet skimret før, slik premieteksten gjør. Fire skimrende tekster sto da
   framme samtidig — to premier og to vinnere — og det ble en flimrende side i
   stedet for to premier som lyser. Skimmeret er nå premiekortets alene;
   vinnerkortet beholder gullet, men står i ro. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .winner-card.has-winner h3 {
    background: linear-gradient(100deg, #7d5300 22%, #b8791a 48%, #7d5300 74%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}
/* Merkelappen kom inn med et skimmer i tillegg. Navnet ved siden av skimrer
   allerede, så lappen kommer nå bare inn — og blir stående. */
.winner-card .winner-badge { animation: value-in .6s var(--ease-out) .46s backwards; }

/* Nøkkeltallene: kortet kommer opp, aksentstripa vokser ned langs kanten, og
   tallet setter seg først når verdien faktisk er der (`is-loading` er borte).
   Selve opptellingen gjør `countUp` i app.js. */
.stats-grid article {
  --d: 0ms;
  animation: row-in .6s var(--ease-out) var(--d) backwards;
}
.stats-grid article:nth-child(2) { --d: 70ms; }
.stats-grid article:nth-child(3) { --d: 140ms; }
.stats-grid article::before {
  transform-origin: top;
  animation: bar-grow .62s var(--ease-out) calc(var(--d) + 120ms) backwards;
}
.stats-grid:not(.is-loading) b { animation: value-in .5s var(--ease-out) backwards; }

/* Regelkortet. Raden, ikonflisa og opptegningen deler samme `--d`, så de
   kommer inn som én bevegelse i stedet for tre. */
.rules-card li { --d: 0ms; animation: row-in .58s var(--ease-out) var(--d) backwards; }
.rules-card li:nth-child(2) { --d: 90ms; }
.rules-card li:nth-child(3) { --d: 180ms; }
.rules-card li:nth-child(4) { --d: 270ms; }
.rules-card li:nth-child(5) { --d: 360ms; }
.rule-icon {
  animation: icon-pop .66s var(--ease-out) calc(var(--d) + 110ms) backwards;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.rule-icon svg {
  stroke-dasharray: 120;
  animation: icon-draw .95s var(--ease-out) calc(var(--d) + 190ms) backwards;
}
/* Vanebonusen er den ene regelen som handler om noe som holdes i live, så
   flammen blafrer — én gang i sekstende hvert syvende sekund. */
.streak-rule .rule-icon svg {
  animation:
    icon-draw .95s var(--ease-out) calc(var(--d) + 190ms) backwards,
    flame 7s var(--ease) 2.8s infinite;
}
@keyframes flame {
  0%, 86%, 100% { transform: none; }
  90% { transform: translateY(-1.5px) scale(1.04) rotate(-2.5deg); }
  95% { transform: translateY(0) scale(1.005) rotate(2deg); }
}
/* Trykk er hovedgesten på telefon, så flisa svarer på den — ikke bare på peker. */
.rules-card li:active .rule-icon { transform: scale(.93); }
@media (hover: hover) {
  .rules-card li:hover .rule-icon {
    transform: translateY(-1.5px) scale(1.03);
    box-shadow: 0 8px 18px -9px rgba(12, 23, 16, .34);
  }
}

/* Lista. Radene legger seg nedover, og inni hver rad kommer initialene og
   poengsummen etter at raden har landet. */
.leaderboard li { --d: 0ms; animation: leader-in .5s var(--ease-out) var(--d) backwards; }
.leaderboard li:nth-child(2) { --d: 70ms; }
.leaderboard li:nth-child(3) { --d: 140ms; }
.leaderboard li:nth-child(4) { --d: 210ms; }
.leaderboard li:nth-child(n+5) { --d: 270ms; }
/* Pallen klipper lysstrøket mot sin egen avrunding. */
.leaderboard li:nth-child(-n+3):not(.leader-skeleton):not(.leader-empty) {
  position: relative;
  overflow: hidden;
}
.rank { animation: value-in .5s var(--ease-out) calc(var(--d) + 90ms) backwards; }
.leader-avatar {
  animation: icon-pop .62s var(--ease-out) calc(var(--d) + 150ms) backwards;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.leader-score strong { animation: value-in .52s var(--ease-out) calc(var(--d) + 230ms) backwards; }
.leader-score em { animation: value-in .52s var(--ease-out) calc(var(--d) + 290ms) backwards; }
/* Initialene er det eneste i raden som er verdt å ta på — de svarer på både
   peker og trykk, slik regelikonene gjør. */
.leaderboard li:active .leader-avatar { transform: scale(.93); }
@media (hover: hover) {
  .leaderboard li:hover .leader-avatar {
    transform: translateY(-1.5px) scale(1.04) rotate(-1.5deg);
    box-shadow: inset 0 1px #fff, 0 10px 20px -11px rgba(12, 23, 16, .4);
  }
}

/* Stjerna over førsteplassen: spretter på plass, og glitrer deretter like
   sjeldent som premiemetallet. */
.leaderboard li:nth-child(1) .rank::before {
  animation:
    icon-pop .7s var(--ease-out) calc(var(--d) + 420ms) backwards,
    twinkle 11s var(--ease) 3.6s infinite;
}
@keyframes twinkle {
  0%, 88%, 100% { opacity: 1; transform: scale(1) rotate(0); }
  92% { opacity: .9; transform: scale(1.2) rotate(11deg); }
}

/* Prikken som sier at tallene er ferske. */
.live-dot::before { animation: live-pulse 4.2s var(--ease) infinite; }
@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 34%, transparent); }
  62% { box-shadow: 0 0 0 5px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Menyikonet tegner seg opp idet poengligaen blir den aktive fanen. */
.nav-btn.active svg {
  stroke-dasharray: 120;
  animation: icon-draw .8s var(--ease-out) backwards;
}

body.stats-open .progress { opacity: 0; }

/* --------------------------------------------------------------------------
   24c. Ukens HMS-quiz

   Quizen er det eneste stedet i appen som skal føles som et spill. Den låner
   likevel hele designsystemet: samme grønn, samme papir, samme 56 px
   trykkflater. Det som skiller den er tempoet — ett spørsmål om gangen, fire
   store svarflater, og en tilbakemelding som kommer med én gang.

   Tre skjermer bytter på plassen: oversikten, spillet og resultatet. Bare én
   er synlig, og hver av dem eier hele bredden. Ingenting glir sidelengs: på en
   telefon i en hall skal neste spørsmål stå der forrige sto.
   -------------------------------------------------------------------------- */

.quiz-view {
  display: grid;
  gap: var(--sp-6);
  align-content: start;
  width: min(var(--shell), calc(100% - 40px));
  margin: 0 auto;
  padding: var(--sp-7) 0 calc(var(--sp-9) + env(safe-area-inset-bottom));
}
#quiz-hub { display: grid; gap: var(--sp-5); }

/* Merket på menyknappen: står ukens quiz igjen? Det er den eneste plassen
   appen dulter uoppfordret, så det forsvinner i det den er tatt. */
.nav-badge {
  display: inline-grid;
  place-items: center;
  min-width: 19px;
  height: 19px;
  margin-left: 2px;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--accent-fill);
  color: #fff;
  font: 700 11px/1 var(--font-body);
  font-variant-numeric: tabular-nums;
  box-shadow: 0 1px 3px -1px rgba(0, 60, 30, 0.7);
}
.nav-btn.active .nav-badge { background: var(--brand-500); }

/* Toppen — samme mørke flate som poengligaen, så de leses som samme produkt. */
.quiz-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 330px);
  align-items: center;
  gap: var(--sp-7);
  padding: clamp(26px, 5vw, 48px);
  border: 1px solid var(--dark-line);
  border-radius: var(--r-xl);
  color: var(--on-dark);
  background: var(--dark-surface);
  box-shadow: var(--e4);
}
.quiz-hero::after {
  content: '';
  position: absolute;
  z-index: -1;
  top: -180px; left: -140px;
  width: 340px;
  aspect-ratio: 1;
  border: 1px solid var(--dark-ring);
  border-radius: 50%;
  box-shadow: 0 0 0 48px rgba(136, 219, 170, .035), 0 0 0 96px rgba(136, 219, 170, .025);
}
.quiz-hero .eyebrow { color: var(--on-dark-3); }
.quiz-hero h2 {
  margin: 6px 0 var(--sp-4);
  font: 700 clamp(32px, 7vw, 56px)/.97 var(--font-display);
  letter-spacing: -.02em;
  text-wrap: balance;
}
/* Bare brødteksten. Stikktittelen og ukepilla er også <p> her, og en regel
   som tar alle avsnitt vinner over `.quiz-hero .eyebrow` på spesifisitet. */
.quiz-hero-copy > p:not(.eyebrow):not(.quiz-week) { max-width: 54ch; color: var(--on-dark-2); text-wrap: pretty; }
.quiz-hero-copy strong { color: var(--on-dark); }
.quiz-week {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--sp-5);
  padding: 8px 14px;
  border: 1px solid var(--glass-line);
  border-radius: var(--r-pill);
  background: var(--glass-fill);
  color: var(--on-dark-2);
  font-size: 13.5px;
  font-weight: 600;
}
.quiz-week svg { width: 16px; height: 16px; flex: none; color: var(--on-dark-3); }
/* Framdriftskortet: ringen teller månedens fire quizer, ikke spørsmål. Uka er
   én quiz, og en ring med to tilstander er ingen ring. */
.quiz-score-card {
  display: grid;
  gap: var(--sp-4);
  padding: var(--sp-5);
  border: 1px solid var(--glass-line);
  border-radius: var(--r-lg);
  background: var(--glass-fill);
  box-shadow: var(--glass-inner), var(--de3);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.quiz-ring-wrap { position: relative; justify-self: center; width: 148px; }
.quiz-ring { display: block; width: 100%; transform: rotate(-90deg); }
.quiz-ring circle { fill: none; stroke-width: 10; stroke-linecap: round; }
.quiz-ring-track { stroke: rgba(255, 255, 255, .16); }
.quiz-ring-fill {
  stroke: var(--on-dark-3);
  stroke-dasharray: 327;
  /* Settes av app.js. 327 = hele omkretsen, altså tom ring. */
  stroke-dashoffset: 327;
  filter: drop-shadow(0 0 6px rgba(142, 211, 170, .5));
  transition: stroke-dashoffset .9s var(--ease-out);
}
.quiz-ring-label {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  text-align: center;
}
.quiz-ring-label b {
  font: 700 42px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
}
.quiz-ring-label small { color: rgba(255, 255, 255, .72); font-size: 12px; }
.quiz-score-facts { display: grid; gap: var(--sp-2); margin: 0; }
.quiz-score-facts div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
  padding: 9px 12px;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .08);
}
.quiz-score-facts dt { color: rgba(255, 255, 255, .74); font-size: 12px; }
.quiz-score-facts dd {
  margin: 0;
  font: 700 16px/1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Ukens kategori. Ett kort, ikke en vegg av dem: uka har én quiz, og kortet
   er det eneste stedet man skal trykke for å komme i gang. Derfor får det
   hele bredden på en telefon og halve på en skjerm som har plass. */
.quiz-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
}
@media (min-width: 720px) {
  .quiz-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .quiz-card.is-now { grid-column: span 2; }
}
.quiz-card {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: 10px;
  min-height: 210px;
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--e1);
  text-align: left;
  cursor: pointer;
  transition:
    transform var(--t-base) var(--ease),
    box-shadow var(--t-base) var(--ease),
    border-color var(--t-fast) var(--ease);
}
.quiz-card::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--t-base) var(--ease);
}
@media (hover: hover) {
  .quiz-card:hover { transform: translateY(-3px); border-color: var(--brand-300); box-shadow: var(--e3); }
  .quiz-card:hover::before { transform: scaleY(1); }
}
.quiz-card:active { transform: translateY(1px) scale(.995); box-shadow: var(--e1); }
.quiz-card-top { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.quiz-card-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 48px; height: 48px;
  border: 1px solid var(--brand-200);
  border-radius: 14px;
  color: var(--accent);
  background: var(--accent-soft);
  transition: transform var(--t-base) var(--ease), background var(--t-base) var(--ease);
}
.quiz-card-icon svg { width: 25px; height: 25px; }
@media (hover: hover) {
  .quiz-card:hover .quiz-card-icon { transform: rotate(-4deg) scale(1.06); }
}
.quiz-code {
  padding: 4px 9px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
  color: var(--text-3);
  font: 600 11px/1.4 var(--font-mono);
  letter-spacing: .06em;
}
.quiz-card h3 { font: 600 20px/1.15 var(--font-display); text-wrap: balance; }
.quiz-card p { color: var(--text-3); font-size: 13px; line-height: 1.45; }
.quiz-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: 2px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.quiz-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-3);
  font-size: 12.5px;
  font-weight: 600;
}
.quiz-status svg { width: 15px; height: 15px; flex: none; }
.quiz-go {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent);
  font: 600 13px var(--font-body);
}
.quiz-go svg { width: 16px; height: 16px; transition: transform var(--t-base) var(--ease); }
@media (hover: hover) {
  .quiz-card:hover .quiz-go svg { transform: translateX(3px); }
}

/* Tatt, men ikke full pott: kortet er fortsatt åpent, bare merket. */
.quiz-card.is-taken .quiz-status { color: var(--warn); }
.quiz-card.is-taken .quiz-card-icon { border-color: var(--warn-line); color: var(--warn); background: var(--warn-soft); }

/* Full pott: kortet får bonusfargen og en rolig stripe over toppen. */
.quiz-card.is-perfect {
  border-color: var(--pos-line);
  background: linear-gradient(160deg, var(--pos-soft) 0%, var(--surface) 62%);
}
.quiz-card.is-perfect::before { background: var(--pos); transform: scaleY(1); }
.quiz-card.is-perfect .quiz-card-icon { border-color: var(--pos-line); color: var(--pos); background: #fff; }
.quiz-card.is-perfect .quiz-status { color: var(--pos); }
.quiz-points {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--pos);
  color: #fff;
  font: 700 12px/1.4 var(--font-body);
  font-variant-numeric: tabular-nums;
}
.quiz-points svg { width: 13px; height: 13px; }

.quiz-card.is-now {
  min-height: 0;
  padding: clamp(20px, 3.4vw, 30px);
}
.quiz-card.is-now h3 { font-size: clamp(22px, 3vw, 27px); }
.quiz-card.is-now p { font-size: 14px; max-width: 60ch; }

/* --------------------------------------------------------------------------
   Neste uker

   Rotasjonen skal være synlig. Den som vet at kjemikalier kommer om to uker,
   kan lese på kjemikalier — det er hele hensikten med quizen, så lista står
   åpent under ukens kort og ikke gjemt i en regeltekst.
   -------------------------------------------------------------------------- */

.quiz-upcoming {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
}
.quiz-upcoming ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
.quiz-upcoming li {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.quiz-upcoming-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--text-3);
  background: var(--surface);
}
.quiz-upcoming-icon svg { width: 18px; height: 18px; }
.quiz-upcoming-text { display: grid; gap: 1px; min-width: 0; }
.quiz-upcoming-text b {
  font: 600 14px/1.25 var(--font-body);
  overflow-wrap: anywhere;
}
.quiz-upcoming-text small { color: var(--text-3); font-size: 12px; }
.quiz-upcoming-note { color: var(--text-3); font-size: 13px; }

.quiz-rules { border: 1px solid var(--line); border-radius: var(--r-xl); }
.quiz-rules ul { margin-bottom: var(--sp-4); }

/* --------------------------------------------------------------------------
   Spillet

   Ett spørsmål fyller skjermen. Svarene er 56 px høye med et bokstavmerke til
   venstre, slik at de kan treffes med arbeidshansker og leses på en armlengdes
   avstand. Etter trykket låses alle fire, det riktige lyser grønt, og det gale
   valget står igjen i rødt ved siden av — det er den sammenstillingen som gjør
   at man husker svaret til neste uke.
   -------------------------------------------------------------------------- */

.quiz-game,
.quiz-result {
  width: min(680px, 100%);
  margin: 0 auto;
}
.quiz-game {
  display: grid;
  gap: var(--sp-5);
  padding: clamp(18px, 3.4vw, 30px);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--e3);
}
.quiz-game-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
}
.quiz-exit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-2);
  font: 600 13px var(--font-body);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.quiz-exit svg { width: 15px; height: 15px; }
.quiz-exit:hover { border-color: var(--ink-400); color: var(--text); }
.quiz-game-title {
  display: grid;
  justify-items: center;
  gap: 3px;
  min-width: 0;
  text-align: center;
}
.quiz-game-title b {
  max-width: 100%;
  overflow: hidden;
  font: 600 16px/1.2 var(--font-display);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.quiz-counter {
  color: var(--text-3);
  font: 600 14px var(--font-body);
  font-variant-numeric: tabular-nums;
}
.quiz-counter b { color: var(--text); font-size: 20px; }

/* Pipsene er framdriften: én per spørsmål, farget etter hvordan det gikk. */
.quiz-pips { display: flex; gap: 6px; }
.quiz-pips i {
  flex: 1;
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--ink-200);
  transition: background var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.quiz-pips i.now { background: var(--accent); transform: scaleY(1.7); }
.quiz-pips i.hit { background: var(--pos); }
.quiz-pips i.miss { background: var(--danger); }

.quiz-stage { display: grid; gap: var(--sp-5); }
.quiz-question {
  font: 600 clamp(21px, 3.2vw, 27px)/1.25 var(--font-display);
  text-wrap: pretty;
}
.quiz-options { display: grid; gap: 10px; }
.quiz-option {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 22px;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--tap);
  padding: 10px var(--sp-4);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  color: var(--text);
  font: 500 15.5px/1.35 var(--font-body);
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease);
}
@media (hover: hover) {
  .quiz-option:not(:disabled):hover {
    border-color: var(--accent);
    background: var(--accent-soft);
    transform: translateX(3px);
  }
}
.quiz-option:not(:disabled):active { transform: scale(.99); }
.quiz-option:disabled { cursor: default; opacity: 1; }
.quiz-letter {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text-2);
  font: 700 14px var(--font-mono);
}
.quiz-option .mark { width: 22px; height: 22px; opacity: 0; transition: opacity var(--t-base) var(--ease); }

.quiz-option.hit {
  border-color: var(--pos);
  background: var(--pos-soft);
}
.quiz-option.hit .quiz-letter { border-color: var(--pos); color: #fff; background: var(--pos); }
.quiz-option.hit .mark { opacity: 1; color: var(--pos); }
.quiz-option.miss {
  border-color: var(--danger);
  background: var(--danger-soft);
}
.quiz-option.miss .quiz-letter { border-color: var(--danger); color: #fff; background: var(--danger); }
.quiz-option.miss .mark { opacity: 1; color: var(--danger); }
.quiz-option.fade { opacity: .45; }

.quiz-verdict {
  display: grid;
  gap: 3px;
  padding: var(--sp-4);
  border-left: 3px solid var(--pos);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--pos-soft);
  font-size: 14px;
  line-height: 1.45;
  animation: verdict-in .32s var(--ease-out) backwards;
}
.quiz-verdict b { font: 600 16px var(--font-display); color: var(--pos); }
.quiz-verdict.wrong { border-left-color: var(--danger); background: var(--danger-soft); }
.quiz-verdict.wrong b { color: var(--danger); }
@keyframes verdict-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* Handlingsraden er en <div>, ikke en <footer>. Den globale `footer`-regelen
   (bunnteksten på sida) setter `margin: 0 auto` og klaring for handlingslinja
   — på et element inne i spillet ble knappen da krympet til teksten sin og
   fikk et halvt hundre piksler luft under seg. */
.quiz-game-foot { display: grid; gap: 10px; }
.quiz-hint { text-align: center; }
/* `.btn` setter ingen størrelse på ikoner — knappene ellers i appen har ingen.
   Uten dette faller pila tilbake på nettleserens 300 × 150 og fyller knappen. */
.quiz-game-foot .btn svg { width: 22px; height: 22px; flex: none; }
.quiz-hint { color: var(--text-3); font-size: 12.5px; }

/* --------------------------------------------------------------------------
   Resultatet
   -------------------------------------------------------------------------- */

.quiz-result-card {
  position: relative;
  overflow: hidden;
  display: grid;
  justify-items: center;
  gap: var(--sp-3);
  padding: clamp(24px, 4.5vw, 44px) clamp(18px, 3.4vw, 34px);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--e3);
  text-align: center;
}
.quiz-result-card.perfect {
  border-color: var(--pos-line);
  background: linear-gradient(170deg, var(--pos-soft), var(--surface) 55%);
}
.quiz-result-score {
  font: 700 clamp(52px, 12vw, 78px)/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.quiz-result-score span { color: var(--text-3); font-size: .45em; }
.quiz-result-card.perfect .quiz-result-score b { color: var(--pos); }
.quiz-result-card h3 { font: 700 clamp(26px, 4.5vw, 34px)/1.05 var(--font-display); }
.quiz-result-text { max-width: 44ch; color: var(--text-2); text-wrap: pretty; }

.quiz-award {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
  padding: 10px 18px;
  border-radius: var(--r-pill);
  background: var(--pos);
  color: #fff;
  box-shadow: 0 10px 24px -10px rgba(10, 124, 69, .8);
  animation: award-in .6s var(--ease-out) backwards;
}
.quiz-award svg { width: 20px; height: 20px; }
.quiz-award b { font: 700 17px var(--font-display); letter-spacing: .02em; }
@keyframes award-in {
  from { opacity: 0; transform: scale(.7); }
  60% { transform: scale(1.06); }
  to { opacity: 1; transform: none; }
}

/* Gnistene. Åtte strek som spretter ut én gang når full pott er i boks — ren
   CSS, ingen bibliotek, og helt borte når systemet ber om mindre bevegelse. */
.quiz-burst { position: absolute; inset-block-start: 18%; inset-inline: 0; display: none; }
.quiz-result-card.perfect .quiz-burst { display: block; }
.quiz-burst i {
  position: absolute;
  left: 50%;
  width: 7px; height: 14px;
  border-radius: 3px;
  background: var(--pos);
  opacity: 0;
  animation: burst 1.1s var(--ease-out) forwards;
}
.quiz-burst i:nth-child(1) { --x: -150px; --r: -38deg; background: #ffd65a; }
.quiz-burst i:nth-child(2) { --x: -105px; --r: 22deg; animation-delay: .04s; }
.quiz-burst i:nth-child(3) { --x: -62px; --r: -14deg; background: #ffd65a; animation-delay: .09s; }
.quiz-burst i:nth-child(4) { --x: -22px; --r: 30deg; animation-delay: .02s; }
.quiz-burst i:nth-child(5) { --x: 24px; --r: -26deg; animation-delay: .07s; }
.quiz-burst i:nth-child(6) { --x: 66px; --r: 16deg; background: #ffd65a; animation-delay: .01s; }
.quiz-burst i:nth-child(7) { --x: 108px; --r: -32deg; animation-delay: .06s; }
.quiz-burst i:nth-child(8) { --x: 152px; --r: 24deg; background: #ffd65a; animation-delay: .1s; }
@keyframes burst {
  0% { opacity: 0; transform: translate(0, 0) rotate(0) scale(.4); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--x), -120px) rotate(var(--r)) scale(1); }
}

/* Gjennomgangen: alle fem spørsmålene med ditt svar og det riktige. Den er
   grunnen til at et bomsvar er verdt noe — man går ikke tomhendt derfra. */
.quiz-review {
  list-style: none;
  display: grid;
  gap: 8px;
  width: 100%;
  margin-top: var(--sp-4);
  text-align: left;
}
.quiz-review li {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  gap: var(--sp-3);
  padding: 12px var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.quiz-review li.miss { border-color: var(--danger-line); background: var(--danger-soft); }
.quiz-review svg { width: 20px; height: 20px; margin-top: 1px; color: var(--pos); }
.quiz-review li.miss svg { color: var(--danger); }
.quiz-review b { display: block; font: 600 14.5px/1.35 var(--font-body); }
.quiz-review small { display: block; margin-top: 3px; color: var(--text-3); font-size: 12.5px; line-height: 1.45; }
.quiz-review .was { color: var(--danger); }
.quiz-review .right { color: var(--pos); font-weight: 600; }

.quiz-result-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  width: 100%;
  margin-top: var(--sp-5);
}
.quiz-result-actions .btn { flex: 1 1 180px; }
.quiz-result-note { color: var(--text-3); font-size: 12.5px; }

/* Ukens kort og de tre neste ukene kommer inn etter hverandre når visningen
   åpnes — én gang, i den rekkefølgen de leses. Samme regel som poengligaen. */
.quiz-view:not([hidden]) .quiz-card,
.quiz-view:not([hidden]) .quiz-upcoming li {
  animation: row-in .5s var(--ease-out) calc(var(--i, 0) * 45ms) backwards;
}

/* --------------------------------------------------------------------------
   25. Responsivt — appen samlet

   Ett brekkpunkt, ett sted. Tidligere lå 620 px-reglene spredt i fem blokker
   der halvparten ble overskrevet lenger ned i fila.
   -------------------------------------------------------------------------- */

/* Underteksten i nettstatusen er en godhet for skrivebordet. Så snart
   topplinja begynner å bli trang, er den det første som viker — ellers
   presser den overskrifta og menyknappene ut i ellipser. */
@media (max-width: 1024px) {
  .netstat-note { display: none; }
}

@media (max-width: 900px) {
  .auth { grid-template-columns: 1fr; }
  .auth-aside { min-height: 220px; gap: var(--sp-6); padding: var(--sp-6) var(--sp-5); }
  .auth-pitch h2 { font-size: clamp(30px, 8vw, 40px); }
  .auth-pitch p, .auth-meta { display: none; }
  .auth-language { max-width: none; }
  /* Språksteget er det første en telefon møter. Da skal panelet ikke være
     loddrett sentrert med halve valget under skjermkanten. */
  .auth-panel { align-content: start; padding-top: var(--sp-7); }
}

@media (max-width: 560px) {
  .lang-grid button { min-height: 66px; gap: var(--sp-3); padding: var(--sp-3); }
  .lang-grid b { font-size: 19px; }
  .lang-grid i { font-size: 12.5px; }
  .lang-grid .flag { width: 34px; height: 25px; }
  /* Fire flagg fyller bredden i stedet for å klumpe seg til venstre. */
  .auth-strip { width: 100%; justify-content: space-between; }
  .auth-strip button { flex: 1; justify-content: center; padding: 0 8px; }
  .launch-ring { width: 108px; height: 108px; }
  .launch-mark svg { width: 38px; height: 45px; }
  .launch-tick svg { width: 38px; height: 38px; }
}

@media (max-width: 820px) {
  .stats-hero,
  .leader-layout { grid-template-columns: 1fr; }
  .prize-card { max-width: none; }
  .leader-layout .rules-card { grid-row: 1; }
}

@media (max-width: 720px) {
  body { font-size: 16px; }
  .topbar-titles .kicker { display: none; }
  .topbar-titles h1 { font-size: 20px; }
  .user .txt { display: none; }
  .user { padding: 0 5px; }
  .netstat { padding: 0 9px; }
  .card-head { gap: var(--sp-3); margin-bottom: var(--sp-5); }
  .card-head h3 { font-size: 20px; }
  /* «Neste» er handlingen på steget og får plassen den trenger; stegtelleren
     til venstre krymper først. Overskriften på neste steg kuttes med ellipse i
     stedet for å presse knappen ut over kanten. */
  .card-foot { gap: var(--sp-3); }
  .btn-next { flex: 1; min-width: 0; padding-inline: var(--sp-4); }
  .btn-next .next-title { flex: 0 1 auto; min-width: 0; max-width: none; }
}

@media (max-width: 700px) {
  :root { --picker-gutter: 110px; }
  .language-picker { top: calc(9px + env(safe-area-inset-top)); right: 10px; }
  /* Flisa beholder landskoden — den er den eneste teksten som sier hvilket
     språk som er valgt. Valgene under den strammes inn i stedet. */
  .language-options button { min-width: 48px; padding: 0 6px; gap: 4px; }
  /* Telefonen er der dekningen faktisk svikter, så statusen blir stående —
     den krymper til stolpene og et eventuelt køtall i stedet for å forsvinne. */
  .netstat-label { display: none; }
  .netstat { min-height: 34px; padding: 0 8px; gap: 6px; }
  .user .txt { display: none; }
  .admin-hero { grid-template-columns: 1fr; align-items: start; }
  .admin-hero-facts { flex-wrap: wrap; }
  .admin-hero-facts div { flex: 1 1 140px; }
  .user-form { grid-template-columns: 1fr; }
  .month-control { flex: 1 1 100%; }
  .month-shortcuts { width: 100%; }
  .month-shortcuts .chip-btn { flex: 1; }
}

@media (max-width: 620px) {
  /* Topplinja startet 58 px nede for å komme helt under språkvelgeren. Velgeren
     er nå lukket og smal, så det holder å holde av bredden på den ene flisa til
     høyre — de 58 pikslene går tilbake til innholdet.

     Menya ligger på egen rad under, og skal ikke arve det avsettet. Den får
     bredden tilbake med et negativt høyremarg like stort som det den vokser:
     ytre størrelse blir uendret, så raden flyter ikke over. */
  #app-shell:not([hidden]) .topbar-row { padding: 10px 12px; padding-right: var(--picker-gutter); }
  .topbar-row { gap: 8px; flex-wrap: wrap; }
  .topbar .logo-tile { --mark-h: 20px; }
  /* Mellomrommet med `flex: 1` spiste hele restbredden på den første raden,
     og brukerflisa ble presset ned på en rad helt for seg selv — tre rader
     der to holder. Nettstatusen skyver i stedet den høyre gruppa ut. */
  .topbar-spacer { display: none; }
  .netstat { margin-left: auto; }
  .app-nav {
    order: 5;
    width: calc(100% + var(--picker-gutter) - 12px);
    margin-right: calc(12px - var(--picker-gutter));
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .app-nav::-webkit-scrollbar { display: none; }
  /* Menya er den eneste kontrollen på raden her, så knappene deler bredden
     likt og får full trykkhøyde — den skal kunne treffes med arbeidshansker. */
  .nav-btn {
    flex: 1 0 auto;
    min-width: max-content;
    min-height: 46px;
    gap: 6px;
    padding: 0 13px;
    justify-content: center;
  }
  /* Tre valg med ikon får plass på en telefon. Det fjerde — Admin — gjør at
     det siste ordet blir stående halvt utenfor kanten, og da er en meny som
     må dras i verre enn en meny uten ikoner. Ikonene viker derfor bare for
     den som faktisk har fire valg. Uten `:has()` ruller menya, som før. */
  .app-nav:has(#nav-admin:not([hidden])):has(#nav-quiz:not([hidden])) .nav-btn svg { display: none; }
  .user { height: 44px; }
  .card { border-radius: var(--r-md); padding: clamp(16px, 5vw, 22px); }
  .shell { padding-inline: 12px; }
  /* 38 px er under det en tommel treffer trygt. Flisene «Nå», «1 time siden»
     og resten er det raskeste sporet gjennom steg 02 — de skal ikke bomme. */
  .chip { min-height: 44px; padding-inline: 16px; }

  .stats-view { width: min(100% - 24px, var(--shell)); padding-top: var(--sp-6); }
  .stats-hero { gap: var(--sp-6); margin-bottom: var(--sp-4); }
  .stats-grid { grid-template-columns: 1fr; gap: var(--sp-3); }
  .stats-grid article { grid-template-columns: 1fr auto; align-items: center; padding: var(--sp-4); }
  .stats-grid article b { grid-row: 1 / 3; grid-column: 2; font-size: 34px; }

  .prize-card { padding: var(--sp-4); }
  .prize-card svg { width: 46px; height: 46px; }
  .prize-card b { font-size: 19px; }

  .winner-card { align-items: flex-start; }
  .winner-badge { display: none; }

  .leader-card { padding: var(--sp-4); }
  .leaderboard li {
    grid-template-columns: 26px 40px minmax(0, 1fr) auto;
    gap: 8px;
    min-height: 68px;
    padding-inline: 4px;
  }
  .leader-avatar { width: 38px; height: 38px; border-radius: 12px; }
  .sk-avatar { width: 38px; height: 38px; border-radius: 12px; }
  .leader-name small { font-size: 11.5px; }
  /* 12 px brødtekst i en fotnote leses dårlig på en telefon i dagslys. */
  .leader-foot { font-size: 13px; }
  .rules-card { padding: var(--sp-5) var(--sp-4); }

  /* Quizen: toppen stables, ringen krymper, og svarene får hele bredden. */
  .quiz-view { width: min(100% - 24px, var(--shell)); padding-top: var(--sp-6); }
  .quiz-hero { grid-template-columns: 1fr; gap: var(--sp-5); }
  .quiz-ring-wrap { width: 124px; }
  .quiz-ring-label b { font-size: 34px; }
  .quiz-grid { grid-template-columns: 1fr; gap: var(--sp-3); }
  .quiz-card { min-height: 0; padding: var(--sp-4); }
  .quiz-game { padding: var(--sp-4); border-radius: var(--r-md); }
  .quiz-game-head { grid-template-columns: auto minmax(0, 1fr) auto; }
  .quiz-exit span { display: none; }
  .quiz-exit { padding: 0 11px; }
  .quiz-option { grid-template-columns: 30px minmax(0, 1fr) 20px; padding: 10px 12px; font-size: 15px; }
  .quiz-letter { width: 30px; height: 30px; border-radius: 9px; font-size: 13px; }
  .quiz-result-actions .btn { flex: 1 1 100%; }

  /* Brukerraden bryter til to rader: person øverst, handlingene under. Alt
     holder 42 px høyde, så den kan brukes med arbeidshansker. */
  .admin-view { width: calc(100% - 24px); }
  .admin-tab { font-size: 13.5px; gap: 6px; padding: 0 var(--sp-3); }
  /* Tre faner får plass på én linje når ikonene viker og hver fane tar den
     bredden teksten trenger. Med to faner — poengligaen av — står ikonene. */
  .admin-tabs:has(#admin-tab-month:not([hidden])) .admin-tab { flex: 1 1 auto; white-space: nowrap; }
  .admin-tabs:has(#admin-tab-month:not([hidden])) .admin-tab svg { display: none; }

  /* Innstillingene: tittel og bryter på første linje, forklaringen under i
     full bredde. Side om side klemte bryteren teksten ned i en smal søyle. */
  .feature-row {
    display: grid;
    grid-template-columns: 38px minmax(0, 1fr) auto;
    column-gap: var(--sp-3);
    row-gap: 4px;
    align-items: center;
  }
  .feature-icon { grid-row: 1 / span 2; align-self: start; width: 38px; height: 38px; }
  .feature-copy { display: contents; }
  .feature-copy b { grid-column: 2; }
  .feature-copy small { grid-column: 2 / -1; margin-top: 0; }
  .feature-row .feature-lock,
  .feature-row .track { grid-column: 3; grid-row: 1; }
  .user-row,
  .user-skeleton { display: flex; flex-wrap: wrap; }
  .user-row .who,
  .sk-user-who { flex: 1 1 auto; }
  .user-row select,
  .sk-user-role { flex: 1 1 100%; width: 100%; min-width: 0; }
  .user-row button,
  .sk-user-btn { flex: 1 1 0; min-width: 0; }
}

@media (max-width: 420px) {
  .choices { grid-template-columns: 1fr; }
  .sev-grid { grid-template-columns: 1fr 1fr; }
  /* På de smaleste skjermene ville fire koder pluss flisa gått ut over kanten.
     Valgene står som rene flagg; `aria-label` bærer fortsatt språknavnet. */
  .language-options button { min-width: 40px; width: 40px; padding: 0; }
  .language-options abbr { display: none; }
}

@media (max-width: 380px) {
  .topbar-titles { display: none; }
  .quiz-question { font-size: 19px; }
  .quiz-option { font-size: 14.5px; }
  .card-head p { font-size: 13px; }
  .card-toggle { min-height: 38px; padding-inline: 11px; }
  .btn-next .next-title { display: none; }

  .leaderboard li { grid-template-columns: 22px 34px minmax(0, 1fr) auto; gap: 6px; min-height: 62px; }
  .leader-avatar, .sk-avatar { width: 34px; height: 34px; border-radius: 11px; }
  .leader-name b { font-size: 15px; }
  .leaderboard strong { font-size: 19px; }
  /* Rekka med lodd og måneder er det første som må vike når bredden tar slutt. */
  .leader-score em { font-size: 11px; }
  .prize-card svg { width: 40px; height: 40px; }
  .rule-icon { width: 36px; height: 36px; }
  .rule-icon svg { width: 19px; height: 19px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media print {
  .topbar, .actionbar, .queue-wrap, .toasts, .hairline, .skip { display: none !important; }
  .card { box-shadow: none; border-color: #ccc; }
  .shell { padding-bottom: 0; }
}
