/* Säätutka-demosivu — docs/specs/weather-radar.md, ulkoasu ui-design.md 3A */

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

/* Kartta on sivun pääsisältö (WR-1). Työpöydällä se pysyy
   sisältöalueella; kosketuslaitteilla se vie koko ruudun (WR-5, WR-49).

   Näkymä on pino, joka mahtuu yhteen ruutuun, ja jossa **vain kartta
   joustaa**: legendat (WR-3, WR-66, WR-70), Asetukset ja 3D (WR-44,
   WR-67) sekä attribuutio (WR-6) pysyvät näkyvissä ilman vieritystä, ja
   kartta kutistuu, kun sen alle ilmestyy rivejä. Ruudun mitta on
   yläpalkin alapuolelle jäävä osa: navin ylätäyte + yksi tekstirivi. */
.radar {
  display: flex;
  flex-direction: column;
  max-height: calc(100svh - var(--space-4) - var(--leading-base) * 1rem);
  gap: var(--space-2);
  position: relative;
}
/* Muut rivit pitävät mittansa — kutistuminen on kartan tehtävä. */
.radar > * { flex: none; }

.radar .map {
  flex: 0 1 auto;
  height: min(70svh, 640px);
  min-height: 0;
  border: 1px solid var(--color-hairline);
  border-radius: 4px;
  background: var(--color-bg);
}

/* Kellot kelluvat kartan päällä: laitteen aika ja datan aika (WR-4) */
.clocks {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 2;
  display: flex;
  flex-direction: column;
  padding: var(--space-1) var(--space-2);
  border-radius: 4px;
  background: rgb(0 0 0 / 0.65);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.3;
  pointer-events: none;
}
.clock-now { color: var(--color-text-strong); }
.clock-data { color: var(--color-text-muted); }
/* Tuoreusilmaisin: yli 20 min vanha data punaisena (WR-4) */
.clock-data.stale { color: var(--color-alert); }
/* Lähdekatko (WR-97): syy datan ajan alla, samalla varoitusvärillä —
   se on tuoreusilmaisimen tarkennus, ei erillinen ilmoitus. */
.clock-source { color: var(--color-alert); }

/* WR-59: uusi frame saapui itsestään — aika väläytetään valkoisena kaksi
   kertaa. Punainen vanhentuneen datan tila on välähdystä vahvempi, joten
   animaatio ajetaan vain tuoreella datalla. */
.clock-data.flash:not(.stale) { animation: data-flash 0.6s steps(1, end) 2; }
@keyframes data-flash {
  0%, 40% { color: var(--color-text-strong); }
  41%, 100% { color: var(--color-text-muted); }
}
@media (prefers-reduced-motion: reduce) {
  .clock-data.flash { animation: none; }
}

/* Hillitty paikannuskehote (WR-36) */
.locate {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  z-index: 2;
  background: rgb(0 0 0 / 0.65);
  color: var(--color-text);
  border: 1px solid var(--color-hairline);
  border-radius: 4px;
  padding: var(--space-1) var(--space-2);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}

/* Kartan tilaviestit yhtenä ryhmänä: kumpikin voi olla näkyvissä yhtä
   aikaa, mutta yhdessä ne vievät yhden rivin verran pystytilaa
   säätimiltä, joiden on pysyttävä peukaloetäisyydellä (WR-5). */
.notes {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.archive-note, .compass-note {
  margin: 0;
  font-size: var(--text-sm);
}

/* Kompassitilan suunnan menetys (WR-9) varoittavana: kartta näyttää
   vanhentunutta suuntaa, ei vain rajattua sisältöä. */
.compass-note { color: var(--color-alert); }

.timeline {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
/* Yksittäistutka on pysäytyskuva (ADR-029): aikajana piiloon kokonaan.
   `display` kumoaisi [hidden]-attribuutin, joten se kumotaan takaisin. */
.timeline[hidden] { display: none; }
.timeline input[type="range"] { flex: 1; min-width: 0; accent-color: var(--color-accent); }
.frame-time {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  min-width: 4ch;
  text-align: right;
}

.play, .toggle, .mode3d, .reset, .settings-toggle, .about-toggle {
  background: none;
  color: var(--color-text);
  border: 1px solid var(--color-hairline);
  border-radius: 4px;
  /* Kosketuskohteen vähimmäiskoko (ui-design.md 4.6) */
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--space-2);
  font: inherit;
  cursor: pointer;
}
.toggle[aria-pressed="true"],
.mode3d[aria-pressed="true"] { color: var(--color-accent); border-color: var(--color-accent); }
/* 3D-painike ei kutistu rivin toisen puolen mukana (WR-67) */
.mode3d { flex: none; font-family: var(--font-mono); }

/* Palauta (WR-95): 3D-painikkeen oikealla puolella, näkyvissä vain kun
   asetuksia on muutettu. Ei kutistu, jottei ilmestyminen siirrä
   vasemman puolen painikkeita. */
.reset { flex: none; }

/* Odotustila (WR-74): tilavuuden kokoaminen kestää sekunteja, joten
   painallus näkyy heti. Painike ottaa korostusvärin ja alalaitaansa
   liikkuvan palkin, joka kertoo työn olevan yhä kesken. Palkki on
   painikkeen sisällä absoluuttisesti aseteltu, jottei säädinrivin mitta
   muutu latauksen ajaksi (WR-67). */
.mode3d[aria-busy="true"] {
  position: relative;
  overflow: hidden;
  color: var(--color-accent);
  border-color: var(--color-accent);
  cursor: progress;
}
.mode3d[aria-busy="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 40%;
  height: 3px;
  background: var(--color-accent);
  animation: busy-sweep 1.1s ease-in-out infinite alternate;
}
/* 40 % leveä palkki + 150 % omaa leveyttään = tasan painikkeen mitta. */
@keyframes busy-sweep { to { transform: translateX(150%); } }
/* Liikkumaton palkki kertoo saman kuin liikkuva; odotuksen kesto tulee
   joka tapauksessa tekstistä (WR-74). */
@media (prefers-reduced-motion: reduce) {
  .mode3d[aria-busy="true"]::after { animation: none; width: 100%; }
}

/* Säätimet legendojen alla: säädinrivi ja sen alle avautuva asetuslista.
   Rivi on oma laatikkonsa, jotta avautuva lista ei kasvata sitä — muuten
   koko rivin levyinen lista työntäisi 3D-painikkeen ruudun toiseen
   laitaan (WR-67). */
.controls {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.controls-bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Asetukset-painike (WR-44): avaa ja sulkee listan. Avautumissuunta
   näkyviin — kolmio kääntyy alas, kun lista on auki. */
.settings-toggle { display: flex; align-items: center; }
.settings-toggle::after {
  content: "▸";
  margin-left: var(--space-2);
  color: var(--color-text-muted);
  transition: transform 120ms var(--ease-out, ease);
}
.settings-toggle[aria-expanded="true"]::after { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .settings-toggle::after { transition: none; }
}

/* Asetuslista (WR-44): säädinrivin alla, oletuksena kiinni. Yksi valinta
   riviä kohti — säädin vasemmalla, vaikutuksen kuvaus oikealla.

   Avattu lista ei saa kutistaa karttaa olemattomiin: pitkä lista vierii
   itsensä sisällä, jolloin kartta, legendat ja säätimet pysyvät samassa
   ruudussa (WR-1, WR-5, WR-44). */
.settings { max-height: 45svh; overflow-y: auto; }

/* Ryhmittely (WR-44): kuvan valinta ja näkymän käyttäytyminen omina
   osioinaan saman avauksen alla. Otsikko ei ole säädinrivi, joten rivien
   rakennesäännöt koskevat vain `.setting`-elementtejä. */
.settings-section[hidden] { display: none; }
.settings-heading {
  margin: 0;
  padding-top: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.settings-section + .settings-section .settings-heading {
  margin-top: var(--space-2);
  border-top: 1px solid var(--color-hairline);
}

.setting {
  display: grid;
  grid-template-columns: minmax(0, 12rem) 1fr;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  /* Rivit samanpaksuisiksi: säädin ja kaksirivinen kuvaus mahtuvat
     samaan mittaan, joten rivien korkeus ei heilu valinnasta toiseen. */
  min-height: 3.75rem;
  /* Ohjeelle varattu rivimäärä (WR-88): valinnan vaihtuessa vaihtuva
     teksti mahtuu samaan tilaan, joten lista ei hypi valinnan alta.
     Speksitesti todentaa, että jokainen ohje mahtuu varattuun mittaan. */
  --help-lines: 2;
  padding: var(--space-2) 0;
}
.setting + .setting { border-top: 1px solid var(--color-hairline); }
.setting[hidden] { display: none; }
.setting p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  text-wrap: pretty;
  line-height: 1.45;
  min-height: calc(var(--help-lines) * 1.45em);
}
/* Isolla näytöllä ohje kertoo enemmän: lisälause mahtuu samaan varaukseen,
   kun kuvaussarake on leveä. Kapealla se jäisi rivien mitaksi (WR-88). */
.help-wide { display: inline; }
.setting select {
  width: 100%;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-hairline);
  border-radius: 4px;
  min-height: 44px;
  padding: 0 var(--space-2);
  font: inherit;
  font-size: var(--text-sm);
}
.setting .toggle { width: 100%; }

/* Legenda: väriskaala palvelimen metadatasta (WR-3) */
.legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.legend-item { display: inline-flex; align-items: center; gap: var(--space-1); }
.legend-item i { width: 1.25rem; height: 0.6rem; border-radius: 2px; display: inline-block; }

/* Heijastuvuuden legenda on jatkuva nauha: portaat vierekkäin ja lukemat
   nauhan yläpuolella omissa kohdissaan. Yksikkö pysyy nauhan oikealla
   puolella, jottei se siirrä lukemia. */
.legend[data-kind="band"] {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 0 var(--space-2);
}
.legend-ticks { grid-column: 1; position: relative; height: 1.2em; }
.legend-ticks span { position: absolute; transform: translateX(-50%); }
/* Ylin lukema on nauhan päässä: se kaartuu sisäänpäin, ei ulos reunasta. */
.legend-ticks span:last-child { transform: translateX(-100%); }
.legend-band { grid-column: 1; display: flex; height: 0.6rem; border-radius: 2px; overflow: hidden; }
.legend-band i { flex: 1 1 0; }
.legend[data-kind="band"] .legend-unit { grid-column: 2; grid-row: 2; }

/* 3D-sadekartan korkeusselite (WR-70): yksi rivi legendojen alla, näkyy
   vain 3D-tilassa. Kapealla näytöllä loppupää saavutetaan vaakavierityksellä
   kuten salamalegendassa — rivittyminen söisi kartan tilaa (WR-5).
   `.legend`in display: flex voittaisi [hidden]-oletuksen. */
.volume-legend { white-space: nowrap; overflow-x: auto; }
.volume-legend[hidden] { display: none; }
/* Katkoshuomautus ja odotusteksti (WR-72, WR-74) asuvat samassa kohdassa
   säädinrivin yläpuolella: kumpikin näkyy vuorollaan, ei koskaan yhtä
   aikaa. */
.volume-note, .volume-progress { margin: 0; font-size: var(--text-sm); }
.volume-progress { color: var(--color-text-muted); }

/* Salamalegenda (WR-66): sama koko kuin tutkalegendalla, mutta aina
   yhden rivin paksuinen — kapealla näytöllä loppupää saavutetaan
   vaakavierityksellä rivittymisen sijaan. */
.strike-legend { flex-wrap: nowrap; overflow-x: auto; }
/* `.legend`in display: flex voittaisi [hidden]-oletuksen (WR-22, WR-66) */
.strike-legend[hidden] { display: none; }
.strike-legend .legend-item { flex: none; }
.strike-legend svg { width: 1.25rem; height: 1.25rem; }

.attribution {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0;
}

/* 3D-tilassa kartalle annetaan kaikki, mikä irtoaa (WR-100): näkymä
   päättyy säädinriviin, jolla 3D-painike on. Kaikki kartan alapuolinen
   sisältö — asennusvihje, Ohje-painike ja sivun alatunniste — jää pois,
   jolloin säädinrivi on ruudun alin rivi eikä sen alle jää vieritettävää.
   Attribuutio (WR-6) ei katoa lähtiessään alatunnisteesta, vaan siirtyy
   heti kartan alle. */
.radar[data-volume="1"] ~ .install-hint,
.radar[data-volume="1"] ~ .about-block,
.radar[data-volume="1"] ~ .site-footer { display: none; }
.radar[data-volume="1"] > * { order: 2; }
.radar[data-volume="1"] > .map { order: 0; }
.radar[data-volume="1"] > .attribution { order: 1; }

/* Asennusvihje (WR-57) ja ohjeosio (WR-58) kartan alapuolella, tyylit
   site.css:ssä. Ohjeosio on painike ja sen avaama teksti samassa
   laatikossa, jotta ne asettuvat samalle vasemmalle reunalle. Laatikko
   ei ole keskitetty eikä kanna omaa reunaväliään: se noudattaa kartan ja
   säädinrivien reunoja, jolloin Ohje-painike alkaa samasta vasemmasta
   laidasta kuin muukin näkymä. Ohjetekstin lukumitan hoitaa `.about`.
   Laatikko ei kanna omaa alaväliään: erottelun alatunnisteesta hoitaa
   alatunnisteen oma ylämarginaali ja viivansa. */
.tutka .install-hint,
.tutka .about-block {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* Ohjeteksti avautuu painikkeesta (WR-58) samaan tapaan kuin asetuslista:
   sama painikkeen ulkoasu ja sama avautumissuunnan kolmio. Kartta pysyy
   perusnäkymänä, eikä teksti vie siltä tilaa ennen kuin se avataan. */
.tutka .about-toggle {
  display: flex;
  align-items: center;
  /* Painike on tekstinsä levyinen, ei koko lukumitan levyinen. */
  width: max-content;
  /* Ei omaa ylämarginaalia: painike jatkaa edellistä riviä samalla
     rytmillä kuin säädinrivit, eikä jätä väliinsä tyhjää kaistaa. */
}
/* Avattu teksti irti painikkeestaan, muttei muusta sisällöstä. */
.tutka .about { margin-top: var(--space-3); }
.about-toggle::after {
  content: "▸";
  margin-left: var(--space-2);
  color: var(--color-text-muted);
  transition: transform 120ms var(--ease-out, ease);
}
.about-toggle[aria-expanded="true"]::after { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .about-toggle::after { transition: none; }
}

/* --- Koko ruudun karttatila kosketuslaitteilla, myös tableteilla
       (WR-5, WR-49) --- */
@media (pointer: coarse), (max-width: 700px) {
  /* Kartta täyttää ensimmäisen ruudun, muttei lukitse sivua: WR-58:n
     ohjeteksti ja asennusvihje (WR-57) ovat vierittämällä saavutettavissa. */
  .radar {
    box-sizing: border-box;
    height: 100dvh;
    /* Yläpalkki on piilossa toimintasivuna (site.css, ui-design.md
       4.13), joten koko ruutu on näkymän käytössä. */
    max-height: none;
    background: var(--color-bg);
    gap: var(--space-1);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .radar .map {
    /* Kartta ottaa kaiken sen, mitä säätimet eivät vie. */
    flex: 1;
    height: auto;
    border: 0;
    border-radius: 0;
  }
  /* Kellot käyttöjärjestelmän tilarivin alapuolelle: koko ruudun tilassa
     (asennettu appi, piiloutunut selainpalkki) tilarivi peittää yläreunan,
     eikä safe-area-inset-top kata sitä kaikilla laitteilla (WR-4). */
  .clocks { top: max(var(--space-5), calc(env(safe-area-inset-top) + var(--space-2))); }
  /* Puhelin näyttää oman kellonsa tilarivillä — sen toisto on turhaa (WR-4) */
  .clock-now { display: none; }
  /* Säätimet peukaloetäisyydelle ruudun alalaitaan (WR-5) */
  .timeline, .controls, .legend, .attribution, .notes, .volume-note, .volume-progress {
    padding: 0 max(var(--space-2), env(safe-area-inset-left))
             0 max(var(--space-2), env(safe-area-inset-right));
  }
  /* Asennusvihje ja ohjeosio samaan vasempaan laitaan säätimien kanssa. */
  .tutka .install-hint,
  .tutka .about-block {
    padding-left: max(var(--space-2), env(safe-area-inset-left));
    padding-right: max(var(--space-2), env(safe-area-inset-right));
  }
  .attribution { font-size: 0.75rem; }
  /* Kapealla näytöllä kuvaukselle jää tilaa vain kaventamalla säädintä */
  .setting {
    grid-template-columns: minmax(0, 8.5rem) 1fr;
    gap: var(--space-2);
    --help-lines: 4;
  }
  .help-wide { display: none; }
}


/* --- Varoitusrivi ja detaljipaneeli (WR-30, WR-34, WR-35) --- */

/* Rivi kelluu kartan yläreunassa kellojen oikealla puolella. Kun uhkaa
   ei ole, rivi on tyhjä eikä vie tilaa — "kaikki kunnossa" -tilaa ei ole. */
.threats {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  z-index: 3;
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
}

.threat {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border: 1px solid currentColor;
  border-radius: 4px;
  background: rgb(0 0 0 / 0.72);
  color: var(--color-accent);
  font: inherit;
  font-size: var(--text-sm);
  min-height: 44px;   /* kosketuskohde (ui-design.md 4.6) */
  cursor: pointer;
}
.threat[data-level="red"] { color: var(--color-alert); }

/* Ukkosikonin ympyrä + kehällä kiertävä suuntakolmio (WR-32) */
.threat-mark {
  position: relative;
  width: 30px;
  height: 30px;
  flex: none;
}
.threat-mark svg { width: 100%; height: 100%; display: block; }
.threat-dist { font-family: var(--font-mono); white-space: nowrap; }
/* Sateen jo satessa lukemaa ei ole (WR-81): tyhjä elementti ei saa jättää
   ikonin viereen aukkoa, joka näyttäisi puuttuvalta arvolta. */
.threat-dist:empty { display: none; }
.threat-stale { color: var(--color-alert); font-family: var(--font-mono); }

/* Uuden iskemän välähdys (WR-20): sama 2 s impulssi kuin karttarastilla
 *
 * Lepoarvo on `brightness(1)`, ei `none`, vaikka ne piirtyvät samoin:
 * headless WebKit kaataa renderöijän, kun `filter`-animaatio saapuu
 * jaksoon, jonka arvo on **molemmissa päissä `none`** (tässä 40 % → 100 %).
 * Tämä oli /tutka-sivun ~1 s kaatumisen juurisyy CI:ssä; minimitoisto ja
 * mittaukset: docs/notes/arkisto/2026-08-09-webkit-juurisyy.md.
 */
@keyframes threat-flash {
  0%, 100% { filter: brightness(1); }
  8% { filter: brightness(2.6); }
  16% { filter: brightness(1); }
  24% { filter: brightness(2.2); }
  40% { filter: brightness(1); }
}
.threat[data-flash="1"] .threat-mark { animation: threat-flash 2s var(--ease-out) 1; }

@media (prefers-reduced-motion: reduce) {
  /* Sykintä vaimenee yhdeksi himmeäksi korostukseksi (WR-14) */
  .threat[data-flash="1"] .threat-mark { animation: none; filter: brightness(1.5); }
}

.detail {
  position: absolute;
  top: calc(var(--space-2) + 52px);
  right: var(--space-2);
  z-index: 4;
  max-width: min(22rem, calc(100% - 2 * var(--space-2)));
  padding: var(--space-3);
  border: 1px solid var(--color-hairline);
  border-radius: 4px;
  background: rgb(0 0 0 / 0.92);
  font-size: var(--text-sm);
}
.detail h2 { font-size: var(--text-base); margin: 0 0 var(--space-2); }
.detail dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: var(--space-1) var(--space-3); }
.detail dt { color: var(--color-text-muted); }
.detail dd { margin: 0; }
/* Menetelmän rajoitus (WR-84): luettava mutta lukemaa hillitympi. */
.detail-note {
  margin: var(--space-3) 0 0;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  max-width: 42ch;
}
.detail-close {
  position: absolute;
  top: var(--space-1);
  right: var(--space-1);
  min-width: 44px;
  min-height: 44px;
  background: none;
  border: 0;
  color: var(--color-text-muted);
  font-size: var(--text-lg);
  cursor: pointer;
}
