/* =========================================================
   Insulin Buddy – styles.css
   Oppimistyökalu ateriainsuliinin annostelun periaatteisiin.
   ========================================================= */

/* ---------- Teemamuuttujat (vaalea + pimeä) ---------- */
:root {
  /* Kertoo selaimelle kumpaa oletuspalettia lomakekontrollit käyttävät.
     Ilman tätä teemoittamaton kenttä saa selaimen VALKOISEN oletustaustan
     myös tummassa teemassa, jolloin peritty vaalea teksti on lukukelvoton
     (mitattu 1,18:1). Sääntö on turvaverkko: uusi kenttä ei voi kadota
     näkymättömiin pelkästään siksi, että sitä ei muistettu tyylitellä. */
  color-scheme: light;

  --color-primary: #14695c;
  --color-primary-dark: #0f5047;
  --color-primary-light: #d7eae6;
  --color-primary-soft: #edf6f4;
  /* Teksti korostevärien (primary/danger/muted) päällä. Pimeässä teemassa
     korostevärit ovat vaaleita, jolloin valkoinen teksti painuisi
     lukukelvottomaksi (mitattu 1,48:1 annoslaatikossa) — siksi oma token. */
  --color-on-accent: #ffffff;
  /* Syötekenttien reunat: yleinen --color-border (1,35:1) ei täytä
     WCAG 1.4.11:n 3:1-vaatimusta ei-tekstikontrastille. */
  --color-border-input: #8e8e93;

  /* iOS:n ryhmitellyn listan paletti (1.61.0): tausta systemGroupedBackground,
     kortit valkoisia, harmaat järjestelmän sävyistä. Toissijainen teksti on
     tummempi kuin iOS:n secondaryLabel, koska se alittaisi AA:n 4,5:1. */
  --color-bg: #f2f2f7;
  --color-surface: #ffffff;
  --color-surface-alt: #eeeef3;
  /* Kelluva pinta (annoskortti): vaaleassa valkoinen varjolla, tummassa
     vaaleampi kuin kortit, kuten iOS:n tummat nostetut pinnat. */
  --color-surface-elevated: #ffffff;
  --color-text: #1c1c1e;
  --color-text-muted: #636366;
  --color-border: #d8d8dc;
  --color-border-strong: #c6c6c8;

  --color-danger: #b4322a;
  --color-danger-bg: #fbeae8;
  /* #a36b00 antoi 4,12:1 warning-bg:tä vasten (alle AA:n 4,5:1) */
  --color-warning: #8a5c00;
  --color-warning-bg: #fdf4e0;
  --color-info: #2b6697;
  --color-info-bg: #e4effa;
  --color-success: #1f7a4c;
  --color-success-bg: #e2f2e9;

  /* Järjestelmäfontti kuten Applen sovelluksissa (SF Pro iOS:ssä ja
     macOS:ssä, Roboto Androidissa, Segoe UI Windowsissa). Fraunces jää vain
     sovelluksen nimeen (--font-brand), omistajan päätös 5.10.2026. */
  --font-brand: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-display: -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --radius-sm: 6px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --radius-xl: 26px;

  --shadow-sm: 0 1px 2px rgba(20, 40, 36, 0.06);
  --shadow-md: 0 4px 14px rgba(20, 40, 36, 0.08);
  --shadow-lg: 0 12px 36px rgba(20, 40, 36, 0.14);

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-8: 48px;

  --touch-min: 44px;
  --transition-fast: 140ms ease;
  --transition-base: 220ms ease;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
    --color-primary: #3cc9ad;
    --color-primary-dark: #2fb398;
    --color-primary-light: #12352f;
    --color-primary-soft: #0d2622;
    --color-on-accent: #000000;
    --color-border-input: #7c7c80;
    --color-bg: #000000;
    --color-surface: #1c1c1e;
    --color-surface-alt: #2c2c2e;
    --color-surface-elevated: #2c2c2e;
    --color-text: #f5f5f7;
    --color-text-muted: #aeaeb2;
    --color-border: #38383a;
    --color-border-strong: #48484a;
    --color-danger: #f87171;
    --color-danger-bg: #3a1a1a;
    --color-warning: #fbbf24;
    --color-warning-bg: #3a2d10;
    --color-info: #60a5fa;
    --color-info-bg: #162f47;
    --color-success: #4ade80;
    --color-success-bg: #143024;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
    --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.45);
  }
}

/* HUOM: tämä lohko ja yllä oleva @media-lohko ovat sama paletti. Puhdas CSS
   ei salli jakamista (toinen on media-kyselyn sisällä), joten testi
   "teematokenit ovat samat molemmissa lohkoissa" vaatii ne identtisiksi.
   Tarve on mitattu: varjotokenit olivat vain media-lohkossa, joten käyttäjän
   itse valitsema tumma teema jäi vaaleisiin varjoihin. */
[data-theme='dark'] {
  color-scheme: dark;
  --color-primary: #3cc9ad;
  --color-primary-dark: #2fb398;
  --color-primary-light: #12352f;
  --color-primary-soft: #0d2622;
  --color-on-accent: #000000;
  --color-border-input: #7c7c80;
  --color-bg: #000000;
  --color-surface: #1c1c1e;
  --color-surface-alt: #2c2c2e;
  --color-surface-elevated: #2c2c2e;
  --color-text: #f5f5f7;
  --color-text-muted: #aeaeb2;
  --color-border: #38383a;
  --color-border-strong: #48484a;
  --color-danger: #f87171;
  --color-danger-bg: #3a1a1a;
  --color-warning: #fbbf24;
  --color-warning-bg: #3a2d10;
  --color-info: #60a5fa;
  --color-info-bg: #162f47;
  --color-success: #4ade80;
  --color-success-bg: #143024;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.45);
}

/* ---------- Perusnollaukset ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  /* Ylivierityksen tausta (iOS:n kumivieritys) sama kuin sivun, ei
     natiivikuoren oletusväri (1.63.0). */
  background: var(--color-bg);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  /* Nipistyszoomaus on sallittu myös natiivikuorissa (capacitor.config.ts:
     zoomEnabled, UX-20). manipulation estää vain kaksoisnapautuksen
     zoomauksen, joka suurensi sivua vahingossa painikkeita napautettaessa. */
  touch-action: manipulation;
}

body {
  margin: 0;
  font-family: var(--font-body);
  /* rem eikä px: juurifontti skaalautuu iOS:n tekstikoon mukaan
     (app.js: applySystemTextSize) ja selaimen oletusfonttikoon mukaan. */
  font-size: 1rem;
  line-height: 1.5;
  /* Suurella tekstikoolla pitkä sana ("havainnollistamiseen") ei mahtunut
     riville ja sivu vieri vaakasuunnassa (iOS 33–53 px, mitattu 19.9.2026).
     Katkaisee vain sanan, joka ei muuten mahdu. Tavutus ensin, jotta
     katko osuu tavurajalle eikä keskelle sanaa ("ateriainsuliini / n",
     iOS:n suurin tekstikoko, UX-34); kieli tulee <html lang>:sta. */
  overflow-wrap: anywhere;
  -webkit-hyphens: auto;
  hyphens: auto;
  color: var(--color-text);
  background: var(--color-bg);
  /* Annoslaatikon mitattu korkeus (app.js: trackDockHeight). Kiinteä 180 px
     jäi 210–266 px:n laatikon alle, ja alatunnisteen linkit peittyivät. */
  padding-bottom: calc(var(--dock-h, calc(180px + env(safe-area-inset-bottom))) + var(--space-3));
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color var(--transition-base), color var(--transition-base);
}

button { font-family: inherit; cursor: pointer; }
input, select, textarea, button { font-family: inherit; font-size: 1rem; color: inherit; }
/* Kun zoomaus on sallittu, iOS zoomaa automaattisesti jokaiseen alle 16 px:n
   kenttään kohdistettaessa. iOS:n pienillä tekstikoilla juurifontti on
   12,8–15 px (applySystemTextSize), joten kentille annetaan vähimmäiskoko. */
input, select, textarea { font-size: max(1rem, 16px); }

/* Varmistetaan että iOS WKWebView (erityisesti iPad) sallii numeroiden
   syöttämisen. Näppäimistöä häiritseviä auto-attribuutteja ei voi laittaa
   CSS:llä, ne ovat HTML:ssä; mutta user-select / touch-callout
   -ominaisuudet voivat estää syötön jos ne periytyvät jostain. */
input, textarea {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* Selaimen oletusharmaa (#757575) ei seuraa teemaa: tummassa se antoi
   3,48:1 (MITATTU) eli alle AA:n 4,5:1. `opacity: 1` on Firefoxin takia,
   joka himmentää placeholderia oletuksena. */
input::placeholder,
textarea::placeholder {
  color: var(--color-text-muted);
  opacity: 1;
}

:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- App-layout ---------- */
.app {
  max-width: 820px;
  margin: 0 auto;
  padding: max(var(--space-4), env(safe-area-inset-top)) var(--space-4) var(--space-4);
}

/* ---------- Header ---------- */
.app-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0 var(--space-4);
}

.brand__name {
  margin: 0;
  font-family: var(--font-brand);
  /* Kasvaa tekstikoon mukana 200 %:iin asti (WCAG 1.4.4), ei sen yli: iOS:n
     suurimmalla koolla nimi oli ~100 px ja vei ensimmäisen ruudun yhdessä
     vastuuvapauslausekkeen kanssa (UX-34). Katon kanssa nimi on 64 px, mutta
     suurimmalla koolla ensimmäinen syötekenttä on yhä ensimmäisen ruudun
     alapuolella (iOS-simulaattori 26.9.2026); loput olisi ulkoasupäätös.
     px-raja kertautuu Androidin tekstizoomissa, joten raja pysyy 200 %:ssa. */
  font-size: min(2rem, 64px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--color-text);
}

/* Ikäryhmä ja asetukset kuvakkeina oikeassa laidassa (1.64.0), iOS:n
   navigointipalkin tapaan. Ennen ikäryhmä oli tekstitunnus nimen vieressä,
   ja se rivittyi kapealla näytöllä nimen alle. */
.app-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex: 0 0 auto;
}
.brand__name { min-width: 0; }
/* Kapein näyttö (320 px): kaksi kuvaketta vievät 88 px, ja 2rem:n nimi
   rivittyi kahdelle riville. rem pitää nimen tekstikoon mukana (ei vw). */
@media (max-width: 359px) {
  .brand__name { font-size: min(1.75rem, 56px); }
}

/* Ikäryhmän tilikuvake (1.64.1) Applen sovellusten tapaan: korostusvärinen
   ympyrä ja hahmo (lapsi tai nuori = aikuinen ja lapsi,
   aikuinen = yksi hahmo). Vain valitun ryhmän kuvake näkyy. Kosketusala on
   44 px, kuvake 28 px (mutterin 26 px:n viivakuvakkeen kanssa
   tasapainossa). */
.age-badge {
  width: var(--touch-min); height: var(--touch-min);
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 999px;
  transition: transform var(--transition-fast), opacity var(--transition-fast);
}
.age-badge:active { transform: scale(0.94); opacity: 0.8; }
.age-badge__icon { width: 28px; height: 28px; display: block; }
/* Sama korostusväri kuin asetusmutterissa (1.64.2); hahmo ja erotusreunus
   painikkeiden tekstivärillä (vaalea: valkoinen, tumma: musta). */
.age-badge__disc { fill: var(--color-primary); }
.age-badge__figure { fill: var(--color-on-accent); }
.age-badge__gap { fill: var(--color-primary); }
.age-badge[data-group="child"] .age-badge__icon--adult,
.age-badge[data-group="adult"] .age-badge__icon--child { display: none; }

.icon-btn {
  width: var(--touch-min); height: var(--touch-min);
  display: inline-flex; align-items: center; justify-content: center;
  /* Navigointipalkin painike iOS:n tapaan: ei kehystä, korostusvärinen. */
  background: transparent;
  border: none;
  border-radius: 999px;
  color: var(--color-primary);
  transition: background-color var(--transition-fast), transform var(--transition-fast);
}

.icon-btn:hover { background: var(--color-primary-soft); }
.icon-btn:active { transform: scale(0.96); }
.icon-btn svg { width: 26px; height: 26px; }

/* ---------- Bannerit ---------- */
.banner {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  /* 200 % oletuskoosta (14,4 → 28,8 px), ks. .brand__name (UX-34). */
  font-size: min(0.9rem, 28.8px);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

/* Pysyvä mutta hillitty tietorivi (omistajan päätös 5.10.2026): sama teksti
   aina näkyvissä otsikon alla, mutta ei virheen näköisenä punaisena
   laatikkona. App Review -muistiinpanojen "permanent banner" pysyy totena. */
.banner--disclaimer {
  background: transparent;
  color: var(--color-text-muted);
  border: none;
  padding: 0 var(--space-1);
  font-weight: 400;
  font-size: min(0.82rem, 26px);
  line-height: 1.4;
  gap: var(--space-2);
}
.banner--disclaimer .banner__icon { width: 16px; height: 16px; margin-top: 2px; }

.banner__icon { flex-shrink: 0; width: 20px; height: 20px; margin-top: 2px; }

/* Kokeilun viimeiset päivät (1.54.0): tieto, ei varoitus. Painike rivittyy
   tekstin alle kapealla näytöllä ja suurella tekstikoolla. */
.banner--trial {
  background: var(--color-info-bg);
  color: var(--color-text);
  border: 1px solid var(--color-info);
  align-items: center;
  flex-wrap: wrap;
  justify-content: space-between;
}
.banner--trial span { flex: 1 1 12rem; }

/* ---------- Kortti ---------- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-bottom: var(--space-4);
  box-shadow: var(--shadow-sm);
}

.card__title {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 600;
  margin: 0 0 var(--space-4);
  color: var(--color-text);
  letter-spacing: -0.01em;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}
/* ---------- Lomakekentät ---------- */
.field { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-4); }
.field:last-child { margin-bottom: 0; }

.field__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-text);
}

.field__hint { font-size: 0.8rem; color: var(--color-text-muted); font-weight: 400; }

.field input, .field select {
  min-height: var(--touch-min);
  padding: 10px var(--space-3);
  border: 1.5px solid var(--color-border-input);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
  width: 100%;
  font-size: max(1rem, 16px);
}

.field input:focus, .field select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary);
}

/* ---------- Kentän tyhjennyspainike (roskakori) ----------
   Painike kelluu kentän päällä, joten kentälle varataan tilaa lopusta.
   Loogiset ominaisuudet (inset-inline-end, padding-inline-end) kääntyvät
   itsestään oikealle puolelle RTL-kielillä (ar, he, fa, ckb, ur). */
.input-clear { position: relative; display: flex; }

/* Valitsin on `.field .input-clear input` (0,2,1) eikä `.input-clear input`
   (0,1,1): jälkimmäinen on TASAN yhtä spesifi kuin `.field input`, jolloin
   sääntöjen järjestys ratkaisisi. Sama varovaisuus kuin .pin-inputissa. */
.field .input-clear input { padding-inline-end: 46px; }

.input-clear__btn {
  position: absolute;
  inset-inline-end: 2px;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}
.input-clear__btn:hover { color: var(--color-danger); }

/* [hidden] on globaalisti display:none, mutta tämän säännön oma
   display:flex on yhtä spesifi (0,1,0) ja tulee myöhemmin — ilman tätä
   painike näkyisi tyhjälläkin kentällä. MITATTU. */
.input-clear__btn[hidden] { display: none; }

/* Koko lomakkeen tyhjennys otsikkorivillä. margin-inline-start: auto
   työntää sen riville loppuun kuten .carbs-calc-btn. */
/* Profiilikortin "Kopioi kaikkiin". Oikeaan reunaan kortin loppuun:
   toiminto koskee koko korttia, ei yksittäistä kenttää. */
.profile-card__copy {
  display: block;
  /* `width: fit-content` on välttämätön: pelkkä block-elementti täyttää
     rivin, jolloin `margin-inline-start: auto` ei siirrä mitään. */
  width: fit-content;
  margin-inline-start: auto;
  margin-top: var(--space-2);
  padding: 4px 8px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-primary);
}

.clear-all-btn {
  margin-inline-start: auto;
  padding: 2px 8px;
  font-size: 0.9rem;
  font-weight: 500;
}

.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }

/* Erityistilanteen muutosprosenttirivi: ilmestyy field-gridin alle */
#condition-percent-container { margin-top: var(--space-3); }

@media (max-width: 480px) {
  .field-grid { grid-template-columns: 1fr; }
}

/* ---------- Ohjepainike (?) ---------- */
.help-btn {
  /* 24 px = WCAG 2.5.8:n minimi ilman väljyyspoikkeusta (oli 22 px).
     ::before laajentaa osuma-alueen 36 px:iin ilman että painike kasvaa. */
  position: relative;
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: 0.75rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: all var(--transition-fast);
}

.help-btn::before {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
}

.help-btn:hover, .help-btn:focus-visible {
  color: var(--color-primary);
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

/* ---------- hidden-attribuutti ----------
   `[hidden] { display: none }` on SELAIMEN oletustyyli, jonka mikä tahansa
   tekijän display-sääntö voittaa. Mitattu Chromiumissa: `#btn-log-dose`
   (`.dose-dock__log-btn { display: block }`) renderöityi 358 × 44 px kokoisena
   vaikka `hidden` oli asetettu, `#hypo-timer-status` (`display: flex`) näytti
   pysähtynyttä "15:00"-riviä ennen ajastimen käynnistystä, ja `.iob-actions`
   piti lisäyspainikkeen klikattavana kolmella IOB-rivillä (T-22).
   Yksi sääntö kattaa nykyiset ja tulevat tapaukset. */
[hidden] { display: none !important; }

/* ---------- Hälytykset ---------- */
.alert {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: 0.92rem;
  margin-top: var(--space-3);
  display: none;
}

.alert--warning {
  background: var(--color-warning-bg);
  color: var(--color-warning);
  border: 1px solid var(--color-warning);
}

.alert--danger {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border: 1px solid var(--color-danger);
  font-weight: 600;
}

.alert--success {
  background: var(--color-success-bg);
  color: var(--color-success);
  border: 1px solid var(--color-success);
  font-weight: 600;
}

.alert--hypo {
  background: var(--color-info-bg);
  color: var(--color-info);
  border: 1px solid var(--color-info);
  font-weight: 600;
}

.alert.is-visible { display: block; }

/* Varoituspalkissa voi olla useita rivejä (esim. verensokeri JA
   hiilihydraatit). Aiemmin näytettiin vain ensimmäinen. */
.alert__line + .alert__line { margin-top: var(--space-2); }

/* ---------- Laskelman vaiheet ---------- */
/* iOS-listarivit (1.61.0, omistajan päätös 5.10.2026): vaiheen nimi
   vasemmalla, tulos oikealla tasalevyisin numeroin ja laskutoimitus
   harmaana alla. Osat käärii stepRowsHtml (app.js) tekstiä muuttamatta,
   joten jakoteksti ja kuulutus pysyvät ennallaan. */
.calc-steps {
  display: flex;
  flex-direction: column;
  margin-bottom: var(--space-4);
  font-variant-numeric: tabular-nums;
}

.step {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
  font-size: 0.95rem;
  line-height: 1.45;
}
.step--rows {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-3);
  row-gap: 2px;
  align-items: baseline;
}
.step__label { grid-column: 1; grid-row: 1; }
.step__result {
  grid-column: 2;
  grid-row: 1;
  font-weight: 600;
  text-align: end;
  white-space: nowrap;
}
.step__calc {
  grid-column: 1 / -1;
  grid-row: 2;
  color: var(--color-text-muted);
  font-size: 0.85em;
}
.step__calc strong { font-weight: 500; }

.step--modifier:not(.is-visible),
.step--iob:not(.is-visible) { display: none; }

.step--final { border-bottom: none; font-weight: 600; }
.step--final .step__result { color: var(--color-primary); }

/* ---------- IOB-sektio ---------- */
.iob-intro {
  font-size: 0.9rem;
  color: var(--color-text-muted);
  margin: 0 0 var(--space-3);
  font-weight: 500;
}

.iob-row {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  margin-bottom: var(--space-2);
  transition: opacity var(--transition-base);
}

/* Vanhentunut rivi (ei enää vaikutusta). Aiemmin koko rivi himmennettiin
   (opacity 0.55), jolloin "Vanhentunut (ei vaikutusta)" jäi 2,14:1:een
   vaaleassa ja 2,73:1:een tummassa teemassa (mitattu 26.9.2026, UX-27).
   Ero näytetään reunalla ja taustalla; teksti pysyy luettavana. */
.iob-row--expired {
  background: var(--color-bg);
  border-style: dashed;
}
.iob-row--expired .iob-row__active { color: var(--color-text-muted); font-style: italic; }

.iob-row__fields {
  display: grid;
  grid-template-columns: 1fr 1.5fr auto;
  gap: var(--space-2);
  align-items: center;
}

.iob-row__dose {
  position: relative;
  display: flex;
  align-items: center;
}

.iob-row__dose input {
  min-height: var(--touch-min);
  padding: 10px 36px 10px var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  width: 100%;
  font-weight: 600;
}

.iob-row__dose input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary);
}

.iob-row__unit {
  position: absolute;
  inset-inline-end: var(--space-2);
  font-size: 0.8rem;
  color: var(--color-text-muted);
  pointer-events: none;
}

.iob-row__time select {
  min-height: var(--touch-min);
  padding: 10px var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  width: 100%;
  font-size: max(0.9rem, 16px);
}

.iob-row__time select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary);
}

.iob-row__remove {
  width: var(--touch-min);
  height: var(--touch-min);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-danger);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all var(--transition-fast);
  flex-shrink: 0;
}

.iob-row__remove:hover {
  background: var(--color-danger-bg);
  border-color: var(--color-danger);
}

.iob-row__active {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--color-border);
}

.iob-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: var(--space-3);
}

.iob-summary {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-info-bg);
  color: var(--color-info);
  border: 1px solid color-mix(in srgb, var(--color-info) 40%, transparent);
  border-radius: var(--radius-md);
  font-size: 0.92rem;
  text-align: center;
}

/* ---------- Painikkeet ---------- */
.btn {
  min-height: var(--touch-min);
  padding: 10px var(--space-5);
  border-radius: var(--radius-md);
  border: 1.5px solid transparent;
  font-weight: 600;
  font-size: 0.95rem;
  transition: all var(--transition-fast);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

.btn--primary { background: var(--color-primary); color: var(--color-on-accent); }
.btn--primary:hover { background: var(--color-primary-dark); }

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

/* iOS: tekstipainike on korostusvärinen ilman alleviivausta. */
.btn--text {
  background: transparent;
  color: var(--color-primary);
  text-decoration: none;
  border: none;
  padding: 10px var(--space-3);
  font-weight: 500;
}
.btn--text:hover { color: var(--color-primary-dark); }

/* ---------- Kiinteä annoslaatikko ---------- */
.dose-dock {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, transparent 0%, var(--color-bg) 30%, var(--color-bg) 100%);
  z-index: 50;
  pointer-events: none;
}

.dose-dock__inner { max-width: 820px; margin: 0 auto; pointer-events: auto; }

/* Matala näkymä tai suuri teksti: kun kiinteä laatikko veisi yli puolet
   näkymän korkeudesta, se asettuu sivun virtaan laskelman jälkeen eikä peitä
   sisältöä. Mitattu 26.9.2026 (UX-18): puhelimen vaakatilassa laatikko vei
   54–76 % näkymästä, 400 %:n zoomauksessa 91–142 % (kaikki kohdistukset
   peitossa ja hypo-ohje näkymän ulkopuolella), ja Androidin fonttikoolla 2.0
   näppäimistön kanssa kirjoitettava kenttä jäi sen alle. Tila vaihtuu
   app.js:n trackDockHeightissa. */
.dose-dock--inline {
  position: static;
  padding: 0 0 var(--space-4);
  background: none;
  pointer-events: auto;
}
.dose-dock--inline .dose-dock__inner { max-width: none; }
#review-alert { margin-top: 0; margin-bottom: var(--space-2); }

/* Terveys-tyyli (1.61.0, omistajan päätös 5.10.2026): vaalea (tummassa
   tumma) kortti, iso luku korostusvärillä ja harmaa selite. Hälytystilat
   (hiilihydraatit, virhe) pysyvät täytettyinä punaisina, jotta ne erottuvat
   annoksesta yhdellä silmäyksellä. */
.dose-box {
  background: var(--color-surface-elevated);
  color: var(--color-text);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  text-align: center;
  transition: background-color var(--transition-base);
}

.dose-box .dose-box__value { color: var(--color-primary); }
.dose-box--error,
.dose-box--carbs { background: var(--color-danger); color: var(--color-on-accent); }
.dose-box--error .dose-box__value,
.dose-box--carbs .dose-box__value { color: inherit; }
.dose-box--locked .dose-box__value { color: var(--color-text-muted); }

.dose-box__label {
  font-size: 0.85rem;
  font-weight: 600;
  color: inherit;
  opacity: 0.8;
}

.dose-box__value {
  display: block;
  font-family: var(--font-display);
  font-size: 2.6rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  margin: var(--space-1) 0;
}

.dose-box__note { font-size: 0.78rem; opacity: 0.9; }

.dose-dock__log-btn {
  display: block;
  width: 100%;
  margin-top: var(--space-2);
  box-shadow: var(--shadow-md);
}

/* Kuittaus ja jako samalla rivillä (IB-2). Jakopainike on neliö, jotta
   laatikon korkeus ei kasva annostilassa. Rivin oma väli korvaa
   kuittauspainikkeen marginaalin. */
.dose-dock__actions {
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.dose-dock__actions .dose-dock__log-btn { flex: 1 1 auto; width: auto; margin-top: 0; }
.dose-dock__share-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  box-shadow: var(--shadow-md);
}

.dose-dock__log-btn:disabled {
  /* Teksti "Aiempien annosten lista täynnä (3/3)" kertoo, miksi kuittaus ei
     onnistu. Läpinäkyvyydellä himmennettynä se oli 2,80:1 (UX-27). */
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  border-color: var(--color-border-strong);
  box-shadow: none;
  cursor: not-allowed;
}

.hypo-timer-section {
  margin-top: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  box-shadow: var(--shadow-md);
}

.hypo-guide-text {
  font-size: 0.85rem;
  font-weight: 500;
  margin-bottom: var(--space-2);
  color: var(--color-text);
}

.hypo-timer-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.hypo-timer-status {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.hypo-timer-display {
  font-family: monospace;
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--color-danger);
}

.toast-msg {
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--color-primary);
  color: var(--color-on-accent);
  border-radius: var(--radius-md);
  font-size: 0.85rem;
  font-weight: 600;
  text-align: center;
  box-shadow: var(--shadow-md);
}
/* Kuulutusalue on aina olemassa ja vain tyhjänä näkymätön: `hidden` poisti
   sen saavutettavuuspuusta, ja alue ilmestyi samalla hetkellä tekstinsä
   kanssa, jolloin kuulutus oli epävarma (UX-25). display: none tekisi saman. */
.toast-msg:empty { margin: 0; padding: 0; box-shadow: none; }

/* Tallennusvirhe: pysyy näkyvissä, kunnes käyttäjä sulkee sen, ja näkyy myös
   avoimen modaalin päällä. Aiemmin se oli 4 sekunnin ilmoitus samalla
   värillä kuin onnistuminen, eikä myöhemmistä virheistä kerrottu (UX-25). */
.storage-error {
  position: fixed;
  top: max(var(--space-2), env(safe-area-inset-top));
  left: var(--space-2);
  right: var(--space-2);
  z-index: 200;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  max-width: 820px;
  margin: 0 auto;
  padding: var(--space-3) var(--space-4);
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  font-weight: 600;
}
.storage-error__text { margin: 0; flex: 1; }
.storage-error .btn { flex: none; color: var(--color-danger); }

.log-dose-text {
  font-size: 1rem;
  line-height: 1.5;
  color: var(--color-text);
}

/* Oma vahvistus- ja ilmoitusdialogi (UX-39, app.js: showAppDialog) */
.app-dialog { max-width: 440px; }
.app-dialog__text {
  margin: 0;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--color-text);
}

.carbs-calc-btn {
  margin-inline-start: auto;
  padding: 2px 8px;
  font-size: 0.75rem;
  color: var(--color-primary);
  font-weight: 600;
}

/* Rivi: nimi, grammat, poisto. Nimen perusleveys riittää suomen
   placeholderille ("Ruoka (valinnainen)") 375 px:n näytöllä. Kapeammalla
   tai suurella tekstikoolla nimi saa oman rivinsä ja grammakenttä levenee
   sen alle (mitattu Chromiumissa 27.9.2026, 41 kieltä). */
.carbs-calc-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-2);
}

/* Rivit rakennetaan JS:llä eivätkä ne ole `.field`in sisällä, joten
   kenttien teema on kirjoitettava tähän erikseen. Ennen tätä ne jäivät
   selaimen oletuksille: tummassa teemassa peritty vaalea teksti valkoisella
   taustalla = 1,18:1 (MITATTU Chromiumissa) eli käytännössä näkymätön. */
.carbs-calc-row input {
  min-width: 0;
  min-height: var(--touch-min);
  padding: 10px var(--space-3);
  border: 1.5px solid var(--color-border-input);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: max(1rem, 16px);
}
.carbs-calc-row input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary);
}
.carbs-calc-row__name { flex: 3 1 11em; text-overflow: ellipsis; }
.carbs-calc-row__grams { flex: 1 0 4em; }
/* Kapeampi poistopainike jättää nimelle tilaa (28 × 44 px, WCAG 2.5.8:n
   vähimmäiskoko 24 × 24). Pitkät placeholderit (hr, ru, uk) päättyvät
   375 px:n näytöllä kolmeen pisteeseen eivätkä katkea kesken. */
.carbs-calc-row .btn--text { padding-inline: var(--space-2); }

/* Ruokahaku (1.59.0). Lista on rivin alla sivun virrassa eikä
   kelluvana, jotta se ei peitä seuraavaa riviä eikä jää modaalin
   vierityksen alle. Painotilan rivi erottuu vasemmasta reunuksesta. */
.carbs-calc-entry { margin-bottom: var(--space-2); }
.carbs-calc-entry .carbs-calc-row { margin-bottom: 0; }
.carbs-calc-entry--weight {
  padding-inline-start: var(--space-2);
  border-inline-start: 3px solid var(--color-primary);
}
.carbs-calc-list {
  list-style: none;
  margin: var(--space-1) 0 0;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  max-height: 16rem;
  overflow-y: auto;
}
.carbs-calc-option {
  padding: var(--space-2) var(--space-3);
  min-height: var(--touch-min);
  cursor: pointer;
  border-bottom: 1px solid var(--color-border);
}
.carbs-calc-option:last-child { border-bottom: none; }
/* Modaalin yleiset luettelotyylit (sisennys, välit) eivät koske hakulistaa. */
.modal__body .carbs-calc-list { padding: 0; margin-inline-start: 0; }
.modal__body .carbs-calc-option { margin-bottom: 0; }
.carbs-calc-option.is-active,
.carbs-calc-option:hover { background: var(--color-primary-soft); }
.carbs-calc-option__detail { color: var(--color-text-muted); font-size: 0.85em; white-space: nowrap; }
.carbs-calc-food {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0 var(--space-2);
  margin-top: var(--space-1);
  font-size: 0.9rem;
}
.carbs-calc-food__text { margin: 0; }
.carbs-calc-source {
  margin: var(--space-2) 0 0;
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

/* Harjoittelutila (1.60.0). Tunnus erottaa harjoituksen oikeasta
   laskelmasta: varoitusvärit eivätkä annoslaatikon värit. */
.practice-head { min-width: 0; }
.practice-badge {
  display: inline-block;
  margin: var(--space-1) 0 0;
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-warning-bg);
  color: var(--color-warning);
  font-size: 0.85rem;
  font-weight: 600;
}
.practice-open-concepts { margin-bottom: var(--space-3); }
.practice-intro { margin: 0 0 var(--space-2); color: var(--color-text-muted); font-size: 0.9rem; }
.practice-count { margin: 0 0 var(--space-2); font-size: 1rem; }
.practice-situation { margin: var(--space-3) 0; font-weight: 600; }
.practice-answer { margin: 0 0 var(--space-2); border: none; padding: 0; }
.practice-answer legend { padding: 0; margin-bottom: var(--space-1); font-weight: 600; }
.practice-choice { display: inline-flex; align-items: center; gap: var(--space-1); margin-inline-end: var(--space-3); min-height: var(--touch-min); }
.practice-buttons { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-2) 0; }
.practice-solution { margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px solid var(--color-border); }
/* Ratkaisun vaiheet samoina listariveinä kuin päänäkymässä (1.61.0). */
.practice-steps {
  margin: 0 0 var(--space-2);
  padding: 0;
  list-style: none;
  counter-reset: practice-step;
  font-variant-numeric: tabular-nums;
}
.modal__body .practice-steps { padding-inline-start: 0; }
.practice-steps li { margin-bottom: 0; counter-increment: practice-step; }
.practice-steps li::before { content: counter(practice-step) ". "; }
.practice-steps li.step--rows::before { content: none; }
.practice-steps .step--rows .step__label::before { content: counter(practice-step) ". "; }

.carbs-calc-total-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-3);
  font-size: 1.2rem;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

/* ---------- PIN-lukko (entiset inline-tyylit, H-34) ----------
   Nämä olivat `style="…"`-attribuutteina index.html:ssä, jolloin tuotannon
   CSP (`style-src 'self'`) pudotti ne kokonaan: mitattu Chromiumissa
   letter-spacing normal / font-size 16px / text-align start ja 18
   CSP-rikettä konsolissa. Paikallisesti vika ei näy. */
.pin-field {
  max-width: 200px;
  margin-bottom: var(--space-2);
}

.pin-field--modal {
  margin-top: var(--space-3);
  margin-bottom: 0;
}

/* Valitsin on `.field input.pin-input` eikä `.pin-input`, koska
   `.field input` (0,1,1) voittaa pelkän luokan (0,1,0): MITATTU, että
   pelkkä `.pin-input { font-size: 1.5rem }` oli kuollut sääntö —
   renderöity fontti jäi 16 pikseliin. */
.field input.pin-input {
  font-size: 1.5rem;
  letter-spacing: 0.5em;
  text-align: center;
}

.field input.pin-input--sm {
  font-size: max(1.2rem, 16px);
  letter-spacing: 0.3em;
}

.pin-active-note { margin-bottom: var(--space-2); }
.pin-error { margin-top: var(--space-2); }
.pin-forgot { margin-top: var(--space-2); }

.settings-btn-row {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* ---------- Hoitokortti (1.56.0) ----------
   Vain olemassa olevia tokeneita, joten tumma teema toimii ilman uusia
   tokeneita kumpaankaan teemalohkoon. Taulukko vierii vaakasuunnassa
   omassa laatikossaan, jos pitkät otsikot (de, fi) eivät mahdu. */
.care-card {
  margin: 0 0 var(--space-3);
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  overflow-x: auto;
}
.care-card__title {
  margin: 0 0 var(--space-1);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.15rem;
}
.care-card__meta { margin: 0; color: var(--color-text-muted); font-size: 0.9rem; }
.care-card__heading {
  margin: var(--space-3) 0 var(--space-2);
  font-size: 0.95rem;
}
.care-card__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}
.care-card__table th,
.care-card__table td {
  padding: var(--space-1) var(--space-1);
  border-bottom: 1px solid var(--color-border);
  text-align: start;
  vertical-align: top;
}
/* Ajankohdan nimi yhdelle riville: kapeassa sarakkeessa "Aamiainen"
   tavuttui kolmeen osaan. Otsikkorivi saa rivittyä. */
.care-card__table tbody th { white-space: nowrap; padding-inline-start: 0; }
.care-card__table thead th:first-child { padding-inline-start: 0; }
.care-card__table thead th {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-text-muted);
}
.care-card__table td { font-variant-numeric: tabular-nums; white-space: nowrap; }
.care-card__settings { margin: 0; font-size: 0.9rem; }
.care-card__setting {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 var(--space-2);
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--color-border);
}
.care-card__setting dt { color: var(--color-text-muted); }
.care-card__setting dd { margin: 0; font-weight: 600; }
.care-card__hypo { margin: 0; }
.care-card__note,
.care-card__version {
  margin: var(--space-2) 0 0;
  color: var(--color-text-muted);
  font-size: 0.8rem;
}
.care-card__status { margin-top: var(--space-2); }

/* Annoslokin näkymävalinta ja yhteenveto (1.58.0). Yhteenveto käyttää
   hoitokortin tyylejä; valinnat rinnakkain ja kapealla allekkain. */
.log-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-3);
}
.log-controls .field { flex: 1 1 9rem; }
.log-summary__intro { margin: 0 0 var(--space-2); font-size: 0.9rem; }
/* Sarakeotsikot katkeavat vain tavuista: `overflow-wrap: anywhere`
   (body) katkaisi saksan "Einträge" kirjain kerrallaan 320 px:n
   leveydellä. Liian leveä taulukko vierii kortin sisällä. */
.log-summary .care-card__table thead th { overflow-wrap: normal; }

/* Lähtötietojen tuonnin esikatselu (1.57.0) käyttää kortin tyylejä.
   Hylätyt arvot varoitusvärein, jotta ne eivät huku taulukkoon. */
.transfer-preview { margin-top: var(--space-3); }
.transfer-rejected {
  margin: var(--space-3) 0 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-warning-bg);
  color: var(--color-warning);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
}
.transfer-rejected p { margin: 0 0 var(--space-1); }
.transfer-rejected ul { margin: 0; padding-inline-start: 1.2em; }
.transfer-preview .settings-btn-row { margin-top: var(--space-3); }

/* Tulostuksen juuri on näytöllä aina piilossa. */
.print-root { display: none; }

/* Kortin tulostus (body.printing-care-card) näyttää vain #print-rootiin
   kloonatun kortin: muu sovellus ja avoin asetusmodaali piilotetaan.
   Luokka rajaa säännöt kortin tulostukseen, jotta selaimen oma tulostus
   ei tyhjene. Värit kiinteinä mustavalkoisina, jotta tumma teema ei
   tulostu tummana. */
@media print {
  body.printing-care-card > :not(#print-root) { display: none !important; }
  body.printing-care-card { background: #fff !important; }
  body.printing-care-card .print-root { display: block; color: #000; }
  .print-root .care-card {
    border: 0;
    padding: 0;
    background: #fff;
    color: #000;
    overflow: visible;
  }
  .print-root .care-card__meta,
  .print-root .care-card__table thead th,
  .print-root .care-card__setting dt,
  .print-root .care-card__note,
  .print-root .care-card__version { color: #333; }
  .print-root .care-card__table th,
  .print-root .care-card__table td,
  .print-root .care-card__setting { border-color: #999; }
}

.carbs-calc-add { margin-top: var(--space-2); }

.log-history-content {
  max-height: 400px;
  overflow-y: auto;
  overflow-x: auto;
}

.log-history-table {
  width: 100%;
  /* separate + spacing 0 näyttää samalta kuin collapse, mutta sticky-solut
     toimivat siinä luotettavasti. */
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.85rem;
}

.log-history-table th,
.log-history-table td {
  padding: 8px;
  border-bottom: 1px solid var(--color-border);
  text-align: start;
}

.log-history-table th {
  font-weight: 600;
  color: var(--color-text-muted);
  /* Otsikot ovat käännöksiä eivätkä lyhenteitä (H-35), joten sarake saa
     kietoutua; taulukko vierii vaakasuunnassa .log-history-contentissa. */
  vertical-align: bottom;
  min-width: 5.5rem;
}

/* Aikaleima katkeaa vain päivän ja kellonajan välistä. Androidin suurella
   fonttikoolla sarake jäi kapeaksi, ja `overflow-wrap: anywhere` katkaisi
   kellonajan "08.4 / 6" (mitattu emulaattorissa 27.9.2026). */
.log-history-table__time { overflow-wrap: normal; }

/* Poistosarake pysyy näkymän reunassa vaakavierityksessäkin (UX-23): muuten
   se olisi puhelimella annossarakkeen tavoin näkymän ulkopuolella. */
.log-history-table .log-history-table__delete {
  position: sticky;
  inset-inline-end: 0;
  min-width: 0;
  padding: 0 var(--space-1);
  background: var(--color-surface);
  vertical-align: middle;
}
.log-delete-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch-min);
  height: var(--touch-min);
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-danger);
}
.log-delete-btn:hover { background: var(--color-danger-bg); }

/* ---------- Footer ---------- */
.app-footer {
  text-align: center;
  padding: var(--space-4);
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin-top: var(--space-6);
}

.app-footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: center;
  margin-top: var(--space-2);
}

.app-footer button {
  background: none;
  border: none;
  color: var(--color-primary);
  padding: 6px;
  font-size: 0.85rem;
  font-weight: 500;
  min-height: var(--touch-min);
}

.app-footer button:hover { color: var(--color-primary-dark); }

/* Versiorivi ja sen "Mitä uutta?" -painike (1.51.0). */
.app-footer__version {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  column-gap: var(--space-2);
}

/* ---------- Modaalit ---------- */
/* iOS-arkit (1.62.0, omistajan päätös 5.10.2026): puhelimessa alhaalta
   nouseva arkki, jonka yläreunassa kahva ja jonka voi sulkea
   pyyhkäisemällä alas (wireSheetGestures). Leveällä näytöllä keskitetty
   lomakearkki kuten iPadissa. */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: none;
  align-items: flex-end;
  justify-content: center;
  z-index: 100;
  padding: max(var(--space-3), env(safe-area-inset-top)) 0 0;
}

.modal.is-open {
  display: flex;
  animation: fadeIn var(--transition-base);
}

@media (min-width: 640px) {
  .modal { align-items: center; padding: var(--space-5); }
}

.modal__dialog {
  position: relative;
  background: var(--color-surface);
  border-radius: 14px 14px 0 0;
  padding: 0 var(--space-4) calc(var(--space-5) + env(safe-area-inset-bottom));
  max-width: 640px;
  width: 100%;
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  box-shadow: var(--shadow-lg);
  animation: sheetUp 320ms cubic-bezier(0.2, 0.9, 0.3, 1);
}
@media (min-width: 640px) {
  .modal__dialog { border-radius: 14px; max-height: 90vh; padding-bottom: var(--space-5); }
}
/* Asetukset ja Tietoja: harmaa tausta ja valkoiset ryhmät (iOS:n
   ryhmitelty lista). */
.modal__dialog--grouped { background: var(--color-bg); }
.modal__dialog.is-dragging { animation: none; transition: none; }

/* Otsikkorivi pysyy arkin yläreunassa vieritettäessä. Kolme saraketta:
   takaisin (tai tyhjä), keskitetty otsikko, sulje. Kahva on rivin yllä. */
.modal__header {
  position: sticky;
  top: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: var(--touch-min) minmax(0, 1fr) var(--touch-min);
  align-items: center;
  gap: var(--space-2);
  margin: 0 calc(-1 * var(--space-4)) var(--space-3);
  padding: 18px var(--space-4) var(--space-2);
  background: inherit;
  background-color: var(--color-surface);
  border-radius: 14px 14px 0 0;
}
.modal__dialog--grouped .modal__header { background-color: var(--color-bg); }
.modal__header::before {
  content: '';
  position: absolute;
  top: 6px;
  left: 50%;
  width: 36px;
  height: 5px;
  margin-left: -18px;
  border-radius: 3px;
  background: var(--color-border-strong);
}
@media (min-width: 640px) {
  .modal__header::before { display: none; }
}
.modal__header > .modal__back { grid-column: 1; grid-row: 1; }
.modal__header > .modal__title,
.modal__header > .practice-head { grid-column: 2; grid-row: 1; text-align: center; }
.modal__header > .modal__close { grid-column: 3; grid-row: 1; }

.modal__title {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.01em;
}

.modal__close {
  width: 32px; height: 32px;
  justify-self: end;
  position: relative;
  border-radius: 50%;
  border: none;
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.modal__close:hover { background: var(--color-primary-soft); color: var(--color-primary); }

/* Takaisin-painike asetusten alasivulla. Sama muoto kuin sulkupainikkeella,
   jotta otsikkorivi pysyy tasapainossa. RTL-kielillä nuoli peilataan. */
.modal__back {
  width: 32px; height: 32px;
  position: relative;
  border-radius: 50%;
  border: none;
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.modal__back:hover { background: var(--color-primary-soft); color: var(--color-primary); }
/* 32 px:n näkyvä painike, 44 px:n osuma-alue (WCAG 2.5.8, HIG). */
.modal__close::after,
.modal__back::after { content: ''; position: absolute; inset: -6px; }
.modal__close svg,
.modal__back svg { width: 18px; height: 18px; }
[dir='rtl'] .modal__back svg,
[dir='rtl'] .settings-menu__chevron { transform: scaleX(-1); }
/* [hidden] on globaalisti display:none !important, joten piilotettu
   takaisin-painike ei jätä tyhjää tilaa otsikkoriville. */

/* Alasivulla osion nimi on jo modaalin ylärivillä, joten osion oma otsikko
   piilotetaan VISUAALISESTI mutta jätetään DOMiin: se on osion
   `aria-labelledby`-kohde, ja ruudunlukija lukee sen edelleen. */
#settings-views .settings-section__title {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Asetusten osiolista ---------- */
/* iOS:n ryhmitelty lista (1.62.0): ryhmäotsikko pienellä harmaalla,
   valkoinen pyöristetty ryhmä, rivit erotinviivoin kuvakkeen jälkeen. */
.settings-menu { display: flex; flex-direction: column; }
.settings-group__title {
  margin: var(--space-4) var(--space-4) var(--space-1);
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--color-text-muted);
}
.settings-group__title:first-child { margin-top: 0; }
/* Modaalin yleinen h3-tyyli (korostusväri, suurempi koko) ei koske
   ryhmäotsikoita. */
.modal__body .settings-group__title {
  margin: var(--space-4) var(--space-4) var(--space-1);
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--color-text-muted);
}
.modal__body .settings-group__title:first-child { margin-top: 0; }
/* Tietoja-arkissa ryhmän nimi on sama kuin arkin otsikko: piilotetaan
   näkyvistä, mutta ryhmän nimi säilyy ruudunlukijalle. */
#about-list .settings-group__title {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.settings-group {
  background: var(--color-surface);
  border-radius: 10px;
  overflow: hidden;
}
.settings-group__footer {
  margin: var(--space-2) var(--space-4) 0;
  font-size: 0.8rem;
  color: var(--color-text-muted);
  text-align: center;
}

.settings-menu__row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-min);
  padding: 10px var(--space-4);
  background: transparent;
  border: none;
  border-radius: 0;
  color: var(--color-text);
  font-size: 1rem;
  font-weight: 400;
  text-align: start;
  cursor: pointer;
}
/* Erotinviiva alkaa tekstin kohdalta kuten iOS:ssä (kuvake 29 px + väli). */
.settings-menu__row + .settings-menu__row::before {
  content: '';
  position: absolute;
  top: 0;
  inset-inline-start: calc(var(--space-4) + 29px + var(--space-3));
  inset-inline-end: 0;
  border-top: 1px solid var(--color-border);
}
.settings-menu__row:hover,
.settings-menu__row:active { background: var(--color-surface-alt); }
.settings-menu__icon {
  flex: none;
  width: 29px;
  height: 29px;
  border-radius: 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.settings-menu__icon--practice { background-color: #34c759; }
.practice-entry { margin-bottom: var(--space-4); }
/* Otsikko ja yhteenveto ovat samalla rivillä, jos ne mahtuvat, ja muuten
   yhteenveto siirtyy otsikon alle. Ennen otsikko sai kutistua nollaan, kun
   yhteenveto ei saanut rivittyä: Androidin fonttikoolla 1.5–2.0 "Teema"
   hajosi kirjain kerrallaan allekkain ja "Järjestelmän mukaan" valui rivin
   yli (mitattu emulaattorissa 27.9.2026). */
.settings-menu__text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-3);
}
.settings-menu__label { flex: 1 1 auto; min-width: 0; }
.settings-menu__value {
  margin-inline-start: auto;
  color: var(--color-text-muted);
  font-weight: 400;
  font-size: 0.9rem;
  text-align: end;
}
.settings-menu__chevron { flex: none; color: var(--color-border-strong); }

.modal__body { color: var(--color-text); }
.modal__body p { margin: 0 0 var(--space-3); }
.modal__body h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  margin: var(--space-4) 0 var(--space-2);
  color: var(--color-primary);
}
.modal__body ul {
  margin: 0 0 var(--space-3);
  padding-inline-start: var(--space-5);
}
.modal__body li { margin-bottom: var(--space-2); }
.modal__body li:last-child { margin-bottom: 0; }
/* Lähdeluettelon DOI-tunnisteet ja osoitteet ovat pitkiä yhtenäisiä
   merkkijonoja, jotka muuten venyttäisivät kapeaa ikkunaa. */
.modal__body .sources-list li { overflow-wrap: anywhere; }
/* Ohjetekstin lähdeviite (liikuntaohje). */
.modal__body .help-source {
  margin-top: var(--space-4);
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

/* Asetusmodalin osiot (AIT vs henkilökohtaiset lähtötiedot) */
.settings-section {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
}
.settings-section:first-child { padding-top: 0; }
.settings-section:last-child { border-bottom: none; padding-bottom: 0; }
.settings-section__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--color-primary);
}
.settings-section__hint {
  margin: 0 0 var(--space-3);
  color: var(--color-text-muted);
  font-size: 0.9rem;
}
.settings-explainer {
  margin: var(--space-3) 0 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
}
/* Profiilikorttien rivin gap on var(--space-3); käytetään samaa selittäjien ja gridin välissä */
.settings-section .profile-grid { margin-top: var(--space-3); }
.settings-explainer summary {
  cursor: pointer;
  padding: var(--space-2) var(--space-3);
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--color-primary);
}
.settings-explainer summary:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.settings-explainer__body {
  padding: 0 var(--space-3) var(--space-3);
  font-size: 0.88rem;
  color: var(--color-text);
}
.settings-explainer__body p { margin: 0 0 var(--space-2); }
.settings-explainer__body p:last-child { margin-bottom: 0; }

/* TDD-laskuri (Miten TDD lasketaan? -selittäjän sisällä) */
.tdd-calc {
  margin-top: var(--space-3);
  padding: var(--space-3);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.tdd-calc__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}
.tdd-calc__row:last-of-type { margin-bottom: var(--space-3); }
.tdd-calc__label-text {
  flex: 1;
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--color-text);
}
.tdd-calc__row input {
  width: 110px;
  min-height: var(--touch-min);
  padding: 8px var(--space-3);
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  text-align: center;
  font-weight: 600;
}
/* Valikko oli tämän säännön ulkopuolella (`... input` ei kata `select`),
   joten se jäi selaimen oletustaustalle — sama 1,18:1 tummassa teemassa. */
.tdd-calc__row select {
  flex: 0 1 auto;
  max-width: 55%;
  min-height: var(--touch-min);
  padding: 8px var(--space-3);
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-weight: 600;
}
.tdd-calc__row input:focus,
.tdd-calc__row select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary);
}
.tdd-calc__result {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--color-border);
  font-size: 0.92rem;
}
.tdd-calc__result strong {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--color-primary);
  font-weight: 600;
}
.tdd-calc__intro {
  margin-top: var(--space-3) !important;
  color: var(--color-text-muted);
}
.tdd-calc__note {
  margin-top: var(--space-3) !important;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

/* Profiilikorttien alle keskitetty tuhoava toiminto, joka ei kilpaile actions-rivin kanssa */
.settings-section__reset {
  margin-top: var(--space-3);
  display: flex;
  justify-content: center;
}
/* Tuhoava toiminto. Tausta ja reuna annetaan itse: ilman niitä painike sai
   selaimen oletustaustan, tummassa teemassa harmaan #6b6b6b, ja "Tyhjennä
   loki" sekä "Poista vanhemman lukitus" jäivät 1,93:1:een (mitattu
   26.9.2026, UX-27). Tekstipainikkeen muunnelma pysyy läpinäkyvänä. */
.btn--danger {
  color: var(--color-danger);
  background: var(--color-surface);
  border-color: var(--color-danger);
}
.btn--danger:hover { color: var(--color-danger); background: var(--color-danger-bg); }
.btn--text.btn--danger,
.btn--text.btn--danger:hover { background: transparent; }

.modal__actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  margin-top: var(--space-5);
  flex-wrap: wrap;
}
.modal__actions--centered { justify-content: center; }
/* Kauppanäkymä (1.54.0): painikkeet allekkain koko leveydeltä. */
.modal__actions--stacked { flex-direction: column; align-items: stretch; }
/* Ilman hintaa (kauppaan ei yhteyttä) kokeilua ja ostoa ei voi aloittaa:
   painikkeen on näytettävä poissa käytöstä olevalta (mitattu simulaattorissa
   3.10.2026 — ilman tätä painike näytti aktiiviselta). Värit kuten
   .dose-dock__log-btn:disabled: läpinäkyvyys laski kontrastin 2,8:1:een
   (UX-27). */
.modal__actions--stacked .btn:disabled {
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  border-color: var(--color-border-strong);
  box-shadow: none;
  cursor: not-allowed;
}
.store-status { font-weight: 600; }

/* Ikäryhmän valinta suostumusruudussa (1.53.0) */
.age-choice {
  margin: var(--space-4) 0 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.age-choice__legend {
  padding: 0 var(--space-1);
  font-weight: 600;
}
.age-choice__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
}
/* Oma väri ja tausta myös valintanapille: kontrastitesti vaatii ne
   jokaiselta kentältä. */
.age-choice__option input {
  width: 20px; height: 20px; margin: 0; flex: none;
  color: var(--color-text);
  background: var(--color-surface);
  accent-color: var(--color-primary);
}
.age-choice__hint {
  margin: var(--space-2) 0 0;
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

/* Kielenvalintamodaali (ensikäynnistys) */
.lang-picker__intro {
  text-align: center;
  font-size: 0.95rem;
  color: var(--color-text-muted);
}
.lang-picker {
  display: grid;
  /* Auto-fit skaalaa sarakkeet leveyden mukaan: 2 saraketta kapeassa
     mobiilissa, 3-4 saraketta tabletilla, ilman erillisiä mediaqueryitä.
     Vähimmäisleveys 115 px riittää pisimmille autonyymeille (Slovenčina,
     Українська, Latviešu) */
  grid-template-columns: repeat(auto-fit, minmax(115px, 1fr));
  gap: var(--space-2);
  margin-top: var(--space-3);
  /* Pitkä lista (41 kieltä) — pidetään modaali scrollattavana */
  max-height: 70vh;
  overflow-y: auto;
}
.lang-picker__btn {
  width: 100%;
  font-size: 0.95rem;
  padding: var(--space-2) var(--space-2);
}

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } }

/* ---------- Profiilikortit (asetusmodaali) ---------- */
.profile-grid {
  display: grid;
  /* minmax(0, …): pelkkä 1fr ei kutistu sisältönsä alle. Androidin
     fonttikoolla 2.0 kortit olivat 445 px leveitä 339 px:n alueella, ja
     "3/3" sekä kenttien oikea reuna leikkautuivat (mitattu 26.9.2026, UX-28). */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

@media (max-width: 480px) {
  .profile-grid { grid-template-columns: minmax(0, 1fr); }
}

.profile-card {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}

/* Kortin otsikkorivi on <summary>, eli natiivi avauspainike: näppäimistö
   ja ruudunlukija saavat toiminnallisuuden ilmaiseksi. Natiivimerkki
   piilotetaan ja tilalle tulee oma chevron, koska WebKitin oma merkki
   (::-webkit-details-marker) tyylittyy eri tavalla kuin muiden. */
.profile-card__summary {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--color-primary);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  cursor: pointer;
  list-style: none;
}
.profile-card__summary::-webkit-details-marker { display: none; }
.profile-card__summary::after {
  content: '';
  flex: none;
  width: 9px;
  height: 9px;
  margin-inline-start: var(--space-1);
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--transition-fast);
}
.profile-card[open] > .profile-card__summary::after { transform: rotate(45deg); }

/* Täyttötilanne ("2/3") otsikkorivin loppuun. Vihreä vasta kun kaikki
   pakolliset ovat kunnossa — puuttuva arvo on se, joka pitää laskurin
   lukossa, joten se ei saa näyttää samalta kuin valmis. */
.profile-card__status {
  margin-inline-start: auto;
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-warning);
}
.profile-card__status--ok { color: var(--color-success); }

.profile-card > *:not(.profile-card__summary):first-of-type { margin-top: var(--space-2); }

.profile-card__field { display: flex; flex-direction: column; gap: 2px; margin-bottom: var(--space-2); }
.profile-card__field:last-child { margin-bottom: 0; }

.profile-card__label-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.profile-card__field label {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  font-weight: 500;
}

/* Inline-help-painike (?) profiilikorttien kentissä — kevyempi fontti,
   mutta sama 24 px:n koko kuin pääsivulla (WCAG 2.5.8). */
.help-btn--inline {
  /* Oli 18 px — axe: target-size (WCAG 2.5.8) 19.9.2026. */
  width: 24px;
  height: 24px;
  font-size: 0.7rem;
}

.profile-card__field input {
  /* Kentän oletusleveys (size="20") kasvaa fonttikoon mukana; ilman näitä se
     venytti kortin yli näytön (UX-28). */
  width: 100%;
  min-width: 0;
  min-height: var(--touch-min);
  padding: 8px var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  text-align: center;
  font-weight: 600;
}

.profile-card__field input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary);
}

/* ---------- Kentän virheviesti (WCAG 3.3.1) ----------
   Elementti on olemassa tyhjänäkin, jotta aria-live-alue kuuluttaa
   ensimmäisenkin virheen. Tyhjänä se on pois virtauksesta: .field on
   flex-sarake, ja tyhjäkin lapsi saisi oman välinsä. */
.field__error {
  display: block;
  color: var(--color-danger);
  font-size: 0.85rem;
  line-height: 1.4;
}
.field__error:empty { position: absolute; }
input[aria-invalid="true"] { border-color: var(--color-danger); }

/* ---------- AIT-valikko ja sen ?-painike samalla rivillä ---------- */
.field--with-help { flex-direction: row; align-items: center; }
.field--with-help select { flex: 1; min-width: 0; }

/* ---------- Laskelman vaiheiden numerointi ----------
   Numerot olivat käännöksissä ("1. …"), joten piilotettu vaihe jätti
   aukon: normaalitilassa 1, 3, 4, 5, 6. Laskuri numeroi vain näkyvät. */
.calc-steps { counter-reset: calc-step; }
.step:empty { display: none; }
.step { counter-increment: calc-step; }
.step::before { content: counter(calc-step) ". "; }
.step--rows::before { content: none; }
.calc-steps .step--rows .step__label::before { content: counter(calc-step) ". "; }
:lang(ar) .step::before,
:lang(ckb) .step::before { content: counter(calc-step, arabic-indic) ". "; }
:lang(fa) .step::before { content: counter(calc-step, persian) ". "; }

/* ---------- Fokus ei jää annoslaatikon alle (WCAG 2.4.11) ---------- */
html { scroll-padding-bottom: calc(var(--dock-h, 180px) + var(--space-3)); }

/* ---------- Annoslaatikon tekstikoon katto ----------
   Laatikko on kiinteä ja kasvaa tekstin mukana: iOS:n saavutettavuuskoossa
   40 px se vei 526 px eli 62 % näytöstä, 53 px:ssä enemmän kuin koko
   näytön (mitattu simulaattorissa 19.9.2026). Kuten iOS:n omissa palkeissa,
   laatikon teksti rajataan suurimpaan tavalliseen kokoon (23 px); muu sivu
   skaalautuu täysin. Laatikon koot ovat siksi em-yksikköinä. */
/* Androidin WebView kertoo järjestelmän fonttikoolla myös px-arvot (koko 2.0:
   23 px → 46 px), jolloin katto ei pitänyt ja laatikko vei puolet näytöstä
   (mitattu 26.9.2026, UX-18). --text-zoom on mitattu kerroin (app.js:
   applyTextZoomCompensation); muualla se on 1. */
.dose-dock { font-size: min(1rem, calc(23px / var(--text-zoom, 1))); }
.dose-dock .dose-box__label,
.dose-dock .dose-box__note { font-size: 0.78em; }
.dose-dock .dose-box__value { font-size: 2.6em; }
.dose-dock .alert { font-size: 0.92em; }
.dose-dock .btn { font-size: 0.95em; }
.dose-dock .hypo-guide-text,
.dose-dock .toast-msg { font-size: 0.85em; }
.dose-dock .hypo-timer-display { font-size: 1.3em; }

/* ---------- Arkkien ja push-navigoinnin liikkeet (1.62.0) ----------
   Vähennetty liike (prefers-reduced-motion) lyhentää nämä tyhjiin yllä
   olevalla yleissäännöllä. */
@keyframes sheetUp {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
@keyframes pushIn {
  from { transform: translateX(30%); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}
@keyframes popIn {
  from { transform: translateX(-30%); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}
[dir='rtl'] .settings-push-in { animation-name: popIn; }
[dir='rtl'] .settings-pop-in { animation-name: pushIn; }
.settings-push-in { animation: pushIn 280ms cubic-bezier(0.2, 0.9, 0.3, 1); }
.settings-pop-in { animation: popIn 280ms cubic-bezier(0.2, 0.9, 0.3, 1); }

/* ---------- Verkkoversion oppimistyökalu (1.69.0) ---------- */
/* Esimerkkiarvojen painike lähtötietojen alla, sama keskitys kuin
   nollauspainikkeella. */
.settings-section__example {
  margin-top: var(--space-3);
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* Tilannevertailu: rivit kuten hoitokortin asetuslista. */
.compare-card__intro {
  margin: 0 0 var(--space-3);
  color: var(--color-text-muted);
  font-size: 0.9rem;
}
.compare-list { margin: 0; }
.compare-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0 var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}
.compare-row:last-child { border-bottom: none; }
.compare-row dt { flex: 1 1 10rem; }
.compare-row dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.compare-row__tag {
  display: inline-block;
  margin-inline-start: var(--space-2);
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  background: var(--color-info-bg);
  color: var(--color-text);
  font-size: 0.8em;
  font-weight: 600;
}
