/* Agenttinen Katakri — käyttöliittymätyylit
 * Sijoitus: src/katakri_core/views/static/katakri/katakri.css
 * Riippuvuudet: tokens.css (muuttujat), fonts.css (@font-face). Ladattava TÄSSÄ järjestyksessä.
 * EI ULKOISIA VIITTAUKSIA. Ei npm:ää, ei build-vaihetta, ei preprosessoria.
 * Kaikki arvot tulevat tokens.css:n muuttujista — älä kirjoita literaaleja värejä tähän.
 * Luokkaprefiksi: katakri-
 */

/* ============ Perusta ============ */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;font-family:var(--font-sans);font-size:var(--text-body-md);line-height:var(--leading-normal);
  color:var(--text-body);background:var(--surface-page);-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{margin:0;font-family:var(--font-sans);letter-spacing:var(--tracking-tight);color:var(--text-heading);text-wrap:pretty}
h1{font-size:var(--text-h1);font-weight:var(--weight-bold);line-height:var(--leading-snug)}
h2{font-size:var(--text-h2);font-weight:var(--weight-semibold);line-height:var(--leading-snug)}
h3{font-size:var(--text-h3);font-weight:var(--weight-semibold);line-height:var(--leading-snug)}
h4{font-size:var(--text-h4);font-weight:var(--weight-semibold);line-height:var(--leading-snug)}
p{margin:0}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hover);text-decoration:underline}
:focus-visible{outline:none;box-shadow:var(--shadow-focus-accent)}
button{font:inherit;color:inherit}
.katakri-vain-ruudunlukija{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ============ Ikonit (sprite) ============ */
.katakri-ikoni{width:17px;height:17px;flex:none;display:inline-block;vertical-align:middle}
.katakri-ikoni--s{width:15px;height:15px}
.katakri-ikoni--l{width:20px;height:20px}

/* ============ Tumma pinta (ent. mesh-pintakuvio) ============
 * Luokka oli Meshlyn brändipinta: tumma tausta ja sen päällä
 * `radial-gradient`-pistekuvio (`--mesh-dot-dark`, `--mesh-grid-dark`).
 * Apexin tumma pinta on tasainen, ja sen tokeni on `--shell-1` — sama
 * ratkaisu, jonka `.katakri-banneri` ja kirjautumisen esittely tekivät jo
 * kierroksella 8 kumoamalla kuvion `background-image:none`:lla.
 *
 * Luokalla oli kaksi käyttökohtaa, ja molemmat kumosivat kuvion jo
 * kierroksella 8 omalla `background-image:none`-deklaraatiollaan:
 *   - yleiskuvan banneri — `index.html`, sen partiaali
 *     `partials/_yleiskuva_banneri.html` ja näyttömalli
 *     `naytot/index.html`; kumoaa `.katakri-banneri`-säännössä;
 *   - kirjautumisen esittelypuoli — `partials/_kirjautumisen_esittely.html`
 *     ja näyttömalli `naytot/kirjautuminen.html`; kumoaa
 *     `.katakri-kirjautuminen__esittely`-säännössä.
 * Tehtävä 09c9ad32 poistaa `katakri-mesh`-luokan kaikista viidestä
 * ytimen merkkauskohdasta — grep ei enää löydä sitä templateista.
 *
 * SÄÄNTÖ silti jää: molemmat partiaalit ovat YLIKIRJOITETTAVISSA, joten jo
 * kopioitu asiakasversio voi kantaa yhä `katakri-mesh`-luokkaa ja omaa
 * kuviotaan. `background-image:none` on tässä nimenomaan sitä varten, että
 * se kumoaa myös asiakaskerroksen kuvion, jos sellainen on. */
.katakri-mesh{background-color:var(--shell-1);background-image:none}

/* ============ Sovelluskehikko ============
 * Kaksi saraketta ja kaksi riviä. Silmälle: ylärivi ylhäällä koko
 * leveydeltä, navi vasemmalla sen alta alkaen ja pääosa oikealla navin
 * vieressä. Ruudukossa navi on silti koko korkeudeltaan, ja palkin alle
 * jäävä kaista on navin omaa yläreunusta — miksi, se on alempana omana
 * kohtanaan. Rivi ja sarake on
 * kirjoitettu kullekin osalle erikseen (`grid-row`/`grid-column` alla), joten
 * lähdejärjestys ei ratkaise sijoittelua — mutta ruudukko sijoittaa vain
 * SUORIA lapsiaan. Siksi ylärivi (`katakri/_ylapalkki.html`) on navin sisar
 * eikä pääosan sisällä: pääosan sisällä sen `grid-column:1 / -1` jäisi
 * vaikutuksetta ja rivi latoutuisi pääosan flex-pinoon, `.katakri-paaosa`:n
 * reunusten ja välien sisään. Navin sisällä se taas olisi navin levyinen.
 *
 * Ylärivi oli ennen VAALEA (`--card`) ja vain sisältösarakkeen päällä.
 * Kierroksen 8 kuvat (p16-1, p17-1; sama kehys kierroksen 6 p5-1:ssä)
 * näyttävät mustan koko levyisen palkin, jonka alta navi alkaa, ja Apexin
 * oma kehikko on sama (`.shell` `grid-template-areas:"topbar topbar"
 * "sidenav workspace"`). Aiempi perustelu rivin vaaleudelle — "tummana rivi
 * tekisi L-kirjaimen muotoisen pinnan, jollaista Apex-prototyypissä ei ole"
 * — nojasi siihen, että rivi on vain sisältösarakkeen levyinen. Rivi yltää
 * nyt laidasta laitaan, joten L:ää ei synny: musta pinta on palkki ja sen
 * alta jatkuva palsta, niin kuin kuvissa.
 *
 * **Miksi navi on ruudukossa yhä koko korkeudeltaan (`grid-row:1 / -1`).**
 * Palkin alle jäävä kaista tehdään navin omalla yläreunuksella
 * (`padding-top` = `--header-height` + tavallinen reunus) eikä sillä, että
 * navi siirrettäisiin riville 2. Syy on vieriminen:
 *
 * * Navi on `position:sticky` + `height:100vh` ja jää paikalleen, kun sivu
 *   vierii. Sticky-elementti on rajattu SISÄLTÄVÄÄN LOHKOONSA, ja
 *   ruudukkokohteella se on sen oma ruudukkoalue. Rivillä 2 navi mahtuisi
 *   enintään `calc(100vh - var(--header-height))`:n korkuiseksi ilman, että
 *   sivun vähimmäiskorkeus kasvaa yli ruudun — ja kiinnityttyään se
 *   jättäisi ruudun alalaitaan 64 px:n vaalean kaistan. Koko korkeudelta se
 *   on kiinnittyneenä tasan ruudun korkuinen.
 * * Samasta syystä ylärivi EI ole `sticky`. Apexin oma `.topbar` on
 *   (`position:sticky;top:0;z-index:40`), mutta Apexin kehikossa se on
 *   ruudukkokohde 64 px:n rivillä aivan kuten tässä, joten sen sticky-väli
 *   on nolla eikä se jää mihinkään kiinni. Rivi vierii siis sivun mukana,
 *   niin kuin se vieri ennenkin; `position:fixed` olisi uusi mekanismi eikä
 *   tämän tehtävän sisältöä.
 *
 * Rivi ja navi menevät päällekkäin ruudukon rivillä 1 sarakkeessa 1, ja
 * juuri se tekee kuvien yhtenäisen mustan pinnan: kummankin pinta on
 * `--shell-1`, eikä navilla ole siinä kaistassa sisältöä (yläreunus pitää
 * sen alempana). Rivi tarvitsee silti `position:relative` +
 * `z-index:1`, eikä se ole koristetta: navi on `position:sticky` eli
 * SIJOITETTU, ja sijoitettu elementti maalautuu virran sisällön päälle
 * lähdejärjestyksestä riippumatta. Ilman sitä navi peittäisi rivin vasemmat
 * 264 px — eli brändin. Tiedoston ainoa toinen `z-index` on
 * käyttäjävalikon paneeli (20) rivin sisällä, joten rivin oma
 * pinoutumiskonteksti ei jää minkään alle.
 *
 * `.katakri-sovellus` ja `.katakri-paaosa` eivät rajaa omaa
 * vierityslaatikkoaan (ei `overflow`ia eikä kiinteää korkeutta), joten
 * sticky toimii lainkaan: sen sanoo Apexin handoff suoraan ("Never put
 * `overflow` on `.workspace` (breaks sticky)").
 *
 * Ensimmäinen sarake on `auto` eikä `--katakri-nav-width`, jotta navin oma
 * leveys ratkaisee sen — kapean näytön sääntö kaventaa navin 58 px:iin, ja
 * ruudukkoon kirjoitettu leveys jättäisi sen viereen tyhjän kaistan.
 */
.katakri-sovellus{display:grid;grid-template-columns:auto minmax(0,1fr);
  grid-template-rows:auto minmax(0,1fr);min-height:100vh}
.katakri-sisalto{grid-column:2;grid-row:1 / -1;min-width:0;display:flex;align-items:stretch}
.katakri-paaosa{grid-column:2;grid-row:2;flex:1;min-width:0;
  padding:var(--space-8) var(--space-8) var(--space-16);
  display:flex;flex-direction:column;gap:var(--space-6)}

/* ============ Navigaatio — YLIKIRJOITETTAVISSA ============
 * Apex 2.2 -shell (tehtävä 72ca7e29). Tumma palsta lukee Apexin
 * shell-tokeneita: pinta `--shell-1`, leijunta `--shell-2`, valittu kohta
 * `--shell-3`, teksti `--on-shell`/`--on-shell-2`/`--on-shell-3` ja erotin
 * `--shell-line`. Vastine on Apexin `.sidenav`/`.nav-item`
 * (docs/ui/kierros-8/apex/components.css §2), josta on luettu tilat eika
 * mittoja: Apexin `rgba(255,255,255,.08|.15)` -leijunta ja -merkki ovat
 * literaaleja eivatka kelpaa tahan tiedostoon, ja sama porrastus on
 * `--shell-2`/`--shell-3`:ssa tokeneina.
 *
 * Mitat, valistys ja typografia EIVAT muutu. `--katakri-nav-width` on
 * mitattu suunnittelupaketin kuvista (tokens.css), ja Apexin oma
 * valistysasteikko on eri arvoinen kuin ytimen (`--s5` 24 px vs.
 * `--space-5` 20 px), joten asteikon vaihto siirtaisi asettelua. Apexilla ei
 * myoskaan ole typografian asteikkoa tokeneina. Asteikot EIVAT yhdistyneet,
 * kun Meshly-lohko poistui (teht. 24cd5d6c): ytimen `--space-*` ja
 * `--radius-*` ovat nyt tokens.css:n lohkossa "Ytimen asteikko" ytimen
 * ominaan, ja Apexin oma `--s*`/`--r-*` on sen vieressa vendoroituna.
 */
.katakri-navi{grid-column:1;grid-row:1 / -1;width:var(--katakri-nav-width);background:var(--shell-1);
  display:flex;flex-direction:column;gap:var(--space-1);
  padding:calc(var(--header-height) + var(--space-5)) 14px var(--space-5);
  position:sticky;top:0;align-self:start;height:100vh}
/* Luovutuspaketin kytkemättömät näytöt (`katakri/naytot/`) ovat kierroksen 3
   kehys, jossa ylariviä ei ole lainkaan: navi yltää sivun yläreunaan ja pitää
   brändin ja käyttäjälohkon itsellään. Niiden oma kääre `.katakri-sisalto` ei
   esiinny yhdelläkään ytimen sivulla, joten se tunnistaa ne. Ilman tätä
   poikkeusta navin yläreunukseen jäisi niillä 64 px tyhjää sille palkille,
   jota sivulla ei ole. */
.katakri-sovellus:has(> .katakri-sisalto) .katakri-navi{padding-top:var(--space-5)}
/* Navin brändilohko. Ydin ei enää kirjoita sitä — brändi siirtyi ylariviin
   (`katakri/_ylapalkki.html`), jossa se on kierroksen 8 kuvissa — mutta
   säännöt jäävät samasta syystä kuin `.katakri-navi__jalki`:n alempana:
   kytkemättömät näytöt (`katakri/naytot/`, `katakri/partials/_navigaatio.html`)
   kirjoittavat ne yhä. */
.katakri-navi__brandi{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2) var(--space-5)}
.katakri-navi__merkki{width:22px;height:22px;flex:none;display:block;border-radius:var(--radius-xs)}
.katakri-navi__nimi{display:block;font-family:var(--font-sans);font-size:var(--text-body-sm);
  font-weight:var(--weight-semibold);line-height:1;color:var(--on-shell)}
.katakri-navi__ymparisto{display:block;margin-top:var(--space-1);font-family:var(--font-mono);font-size:10px;
  line-height:1;letter-spacing:var(--tracking-label);color:var(--on-shell-3)}
.katakri-navi__lista{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-1)}
.katakri-navi__linkki{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:9px 10px;
  border-radius:var(--radius-md);font-size:var(--text-body-sm);font-weight:var(--weight-medium);line-height:1;
  color:var(--on-shell-2);text-decoration:none;transition:background var(--duration-fast) var(--ease-standard),color var(--duration-fast) var(--ease-standard)}
.katakri-navi__linkki:hover{background:var(--shell-2);color:var(--on-shell);text-decoration:none}
/* Aktiivisen kohdan merkki on kellanruskea eika sininen (kierros 6,
   suunnitteluviite p5-1/p5-2/p5-3). Indigo on linkin ja ensisijaisen
   painikkeen vari koko sovelluksessa (`--accent`), eli sen vari, jota
   *painetaan*; navigaation merkki ei ole toiminto vaan tieto siita, missa
   ollaan. Samanvarisina ne ovat kaksi eri asiaa samassa asussa.
   Palkki on 3 px eika 2 px: mitattuna p5-1:sta se on 6 kuvapistetta
   2x-tarkkuudella, varina #F0B44E. Ennen tassa oli `--amber-500` (#F59E0B)
   lahimpana olemassa olevana huomiotokenina; Apex 2.2 tuo mitatun arvon
   nimella `--accent2-on-dark` (#f0b44e), ja Apexin oma `.nav-item.on::before`
   kayttaa juuri sita. Kuvassa palkki on navigaation omassa reunassa, tassa
   linkin -- navin 14 px:n sisennyksen verran oikeammalla. */
.katakri-navi__linkki[aria-current="page"]{background:var(--shell-3);color:var(--on-shell);
  font-weight:var(--weight-semibold);box-shadow:inset 3px 0 0 var(--accent2-on-dark)}
.katakri-navi__nimike{flex:1}
.katakri-navi__luku{font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-semibold);color:var(--on-shell-2)}
/* Navin alalaidan käyttäjälohko. Ydin ei enää kirjoita sitä — lohko siirtyi
   ylariviin (`katakri/_ylapalkki.html`) — mutta säännöt jäävät, koska
   luovutuspaketin kytkemättömät näytöt (`katakri/naytot/`,
   `katakri/partials/_navigaatio.html`) kirjoittavat ne yhä. Vain ne:
   `_poikkeamalista.html` kirjoittaa eri valitsimen
   `.katakri-navi__rooli--koodi`, joka on alempana oma itsenäinen sääntönsä
   eikä peri tästä mitään — nimi on BEM-muunnoksen näköinen, mutta
   peruslohkoa ei ole sen rinnalla merkkauksessa.
   `.katakri-navi__nimikirjaimet` on niistä ainoa, jonka ydin yhä kirjoittaa:
   sen kantaa ylärivin valikon avain. */
.katakri-navi__jalki{margin-top:auto;display:flex;flex-direction:column;gap:var(--space-3);
  padding:var(--space-4) var(--space-2) var(--space-1);border-top:var(--border-hairline) solid var(--shell-line)}
.katakri-navi__kayttaja{display:flex;align-items:center;gap:var(--space-2)}
/* Nimikirjainten avain on Apexin `.avatar`: pehmea aksenttipinta ja tumma
   aksenttimuste. Se on tassa yksi varipari eika kaksi, koska sama avain
   renderoityy kahdella pohjalla -- navin tummassa jalkilohkossa
   (`partials/_navigaatio.html`) ja ylarivin vaalealla pinnalla
   (`_ylapalkki.html`) -- ja Apexin oma avain on samanlainen molemmissa. */
.katakri-navi__nimikirjaimet{width:28px;height:28px;border-radius:var(--radius-pill);background:var(--accent-soft);
  color:var(--accent-ink);display:inline-flex;align-items:center;justify-content:center;flex:none;
  font-size:var(--text-caption);font-weight:var(--weight-semibold);line-height:1}
.katakri-navi__kayttajanimi{display:block;font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--on-shell)}
.katakri-navi__rooli{display:block;font-size:var(--text-overline);color:var(--on-shell-3)}
.katakri-navi__ulos{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) 0;
  background:none;border:0;cursor:pointer;font-size:var(--text-caption);font-weight:var(--weight-medium);color:var(--on-shell-3)}
.katakri-navi__ulos:hover{color:var(--on-shell)}

/* ============ Ylärivi — YLIKIRJOITETTAVISSA ============
 * Kierroksen 8 sovelluskuvien ylärivi: musta, koko sivun levyinen palkki,
 * jonka alta navi alkaa (p16-1, p17-1). Vasemmalla brändi, keskellä
 * hakukenttä, oikealla ohje · ilmoituskello · käyttäjävalikko.
 *
 * Rivi on tumma (`--shell-1`) ja lukee shell-tokeneita kuten navi:
 * `--on-shell`/`--on-shell-2`/`--on-shell-3` tekstille ja kuvakkeille,
 * `--shell-2` kohotetulle pinnalle (hakukenttä, leijunta) ja `--shell-3`
 * sen päälle (pikanäppäinvihje). Apexin omat `rgba(255,255,255,.08|.10|.12)`
 * ovat literaaleja eivätkä kelpaa tähän tiedostoon, ja sama porrastus on
 * näissä tokeneina — sama ratkaisu ja sama syy kuin navigaatiolohkossa.
 * Vaalea `--ink-*` EI kelpaa riville enää: se oli rivin väri silloin, kun
 * rivi oli `--card`.
 *
 * Mitat on luettu Apexin kehikosta ja mitattu kuvista: palkin korkeus
 * `--header-height` (64 px), vasen reunus 14 px — sama kuin navin oma
 * sisennys, joten brändimerkki on samalla pystyviivalla navin kuvakkeiden
 * kanssa — ja oikea reunus `--space-5`. Brändilohko vie tasan navin
 * leveyden miinus vasen reunus ja lohkojen väli, jolloin hakukenttä alkaa
 * täsmälleen siitä, mihin navi loppuu (kuvissa x = 265 px, navin leveys).
 * Hakukentän enimmäisleveys 520 px on mitattu samoista kuvista (x 265…784).
 *
 * Valikko on `<details>`, joten avautuva paneeli tarvitsee sijoittelun:
 * `position:absolute` irrottaa sen rivin korkeudesta, jota se muuten
 * venyttäisi auki ollessaan. Paneeli itse pysyy vaaleana: se on Apexin
 * `.pop`, joka on vaalea myös tumman palkin alla.
 */
.katakri-ylapalkki{grid-column:1 / -1;grid-row:1;display:flex;align-items:center;
  gap:var(--space-6);min-height:var(--header-height);padding:0 var(--space-5) 0 14px;
  background:var(--shell-1);color:var(--on-shell);position:relative;z-index:1}
/* Brändi. Lohko vie navin leveyden, jotta hakukenttä alkaa navin reunasta.
   `min-width:0` sallii nimen katkaisun, kun rivi on ahdas. */
.katakri-ylapalkki__brandi{display:flex;align-items:center;gap:10px;min-width:0;
  flex:0 0 calc(var(--katakri-nav-width) - 14px - var(--space-6))}
.katakri-ylapalkki__merkki{width:30px;height:30px;flex:none;display:block;border-radius:var(--radius-md)}
.katakri-ylapalkki__nimi{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:var(--font-sans);font-size:var(--text-body-md);font-weight:var(--weight-black);
  line-height:var(--leading-snug);letter-spacing:var(--tracking-snug);color:var(--on-shell)}
/* Hakukenttä. Se on ESITYS eikä toiminto: kenttä on `disabled`, lohko ei ole
   lomake eikä riviltä lähde pyyntöä mihinkään. Syy on kirjattu
   `katakri/_ylapalkki.html`:aan. Tyyli on silti kuvien mukainen, koska juuri
   se on tämän tehtävän kohde — ja `:disabled`-sääntö alla kumoaa selaimen
   oman himmennyksen, joka tekisi paikanpitäjästä lukukelvottoman tummalla
   pinnalla. `cursor:not-allowed` ja kentän vieressä oleva ruudunlukijan
   selite kertovat, ettei haku vielä toimi. */
.katakri-ylapalkki__haku{flex:1;max-width:520px;min-width:0;position:relative;display:flex;align-items:center}
.katakri-ylapalkki__kentta{width:100%;height:38px;padding:0 62px 0 38px;
  border:var(--border-hairline) solid transparent;border-radius:var(--radius-md);
  background:var(--shell-2);color:var(--on-shell);cursor:not-allowed;
  font-family:var(--font-sans);font-size:var(--text-body-sm);font-weight:var(--weight-medium)}
.katakri-ylapalkki__kentta:disabled{opacity:1;-webkit-text-fill-color:var(--on-shell-3);color:var(--on-shell-3)}
.katakri-ylapalkki__kentta::placeholder{color:var(--on-shell-3);opacity:1}
.katakri-ylapalkki__hakukuvake{position:absolute;left:11px;color:var(--on-shell-3);pointer-events:none}
.katakri-ylapalkki__pikanappain{position:absolute;right:10px;padding:2px 7px;border-radius:var(--radius-sm);
  background:var(--shell-3);color:var(--on-shell-2);font-family:var(--font-sans);
  font-size:var(--text-overline);font-weight:var(--weight-semibold);line-height:var(--leading-snug);
  pointer-events:none}
/* Oikea laita. `margin-left:auto` työntää lohkon laitaan silloinkin, kun
   hakukenttä on piilossa kapealla näytöllä. */
.katakri-ylapalkki__toiminnot{margin-left:auto;display:flex;align-items:center;gap:var(--space-1)}
/* Ylärivin "?"-linkki. Kuvake on sen koko näkyvä sisältö, ja nimi on
   ruudunlukijalle (`katakri-vain-ruudunlukija`) sekä `title`-kentässä —
   sama kuvio kuin käyttäjävalikon avauksella. */
.katakri-ylapalkki__ohje{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;color:var(--on-shell-2);border-radius:var(--radius-pill);
  text-decoration:none}
.katakri-ylapalkki__ohje:hover{color:var(--on-shell);background:var(--shell-2)}
.katakri-ylapalkki__ohje:focus-visible{outline:none;box-shadow:var(--shadow-focus-accent)}
/* Ilmoituskello. Kuten hakukenttä: esitys eikä toiminto. Se on `<span>` eikä
   painike, koska painike kuuluisi sarkainkierrokseen ja lupaisi avautuvan
   jotakin — ilmoituksilla ei ole ytimessä lähdettä. Väri on `--on-shell-3`
   eikä `--on-shell-2`, jotta kello erottuu ohjelinkistä, joka vie johonkin.
   Leijuntaa ei ole samasta syystä. */
.katakri-ylapalkki__ilmoitukset{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;color:var(--on-shell-3)}
.katakri-kayttajavalikko{position:relative}
.katakri-kayttajavalikko__avaus{display:inline-flex;align-items:center;cursor:pointer;
  border-radius:var(--radius-pill);list-style:none}
/* Kolmio pois molemmilla kirjoitustavoilla: `display` kattaa WebKitin ja
   `list-style` muut, eikä kumpikaan yksin kata molempia. */
.katakri-kayttajavalikko__avaus::-webkit-details-marker{display:none}
.katakri-kayttajavalikko__avaus:focus-visible{outline:none;box-shadow:var(--shadow-focus-accent)}
/* Apexin `.pop`: vaalea kortti, hiusviiva `--line-1` ja popover-varjo. */
.katakri-kayttajavalikko__paneeli{position:absolute;right:0;top:calc(100% + var(--space-2));z-index:20;
  min-width:200px;display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-3);
  background:var(--card);border:var(--border-hairline) solid var(--line-1);
  border-radius:var(--radius-md);box-shadow:var(--sh-pop)}
.katakri-kayttajavalikko__kayttaja{display:flex;flex-direction:column;gap:2px}
.katakri-kayttajavalikko__nimi{font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--ink-1)}
.katakri-kayttajavalikko__rooli{font-family:var(--font-mono);font-size:10px;letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:var(--ink-3)}
.katakri-kayttajavalikko__ulos{display:flex;align-items:center;gap:var(--space-2);width:100%;
  padding:var(--space-2) 0;background:none;border:0;cursor:pointer;
  font-size:var(--text-caption);font-weight:var(--weight-medium);color:var(--ink-2)}
.katakri-kayttajavalikko__ulos:hover{color:var(--ink-1)}

/* ============ Sivun otsikko ============ */
.katakri-sivuotsikko{display:flex;flex-wrap:wrap;gap:var(--space-4);align-items:flex-end;justify-content:space-between}
.katakri-sivuotsikko__teksti{display:flex;flex-direction:column;gap:var(--space-2);min-width:0}
.katakri-sivuotsikko__toiminnot{display:flex;gap:var(--space-3);flex-wrap:wrap}
.katakri-ylarivi{font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-medium);
  line-height:1;letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--text-hint)}
.katakri-ylarivi--kaanteinen{color:var(--accent-on-dark)}
/* Tummalla taustalla oleva ylärivi, joka jää taka-alalle: kirjautumissivun
   alanurkan toimittajamerkintä. Oli style-attribuutti (color:var(--ink-4))
   ennen ADR 0061 kohdan 7 CSP:tä. */
.katakri-ylarivi--vaimea-kaanteinen{color:var(--on-shell-3)}
.katakri-johdanto{font-size:var(--text-body-md);color:var(--text-label);max-width:74ch}

/* ============ Murupolku ============ */
.katakri-murupolku{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);
  list-style:none;margin:0;padding:0;font-size:var(--text-caption);color:var(--text-hint)}
/* Erotin on chevron (›), ei kauttaviiva: murupolku on muotoa
   "Vaatimukset › T-03" (kierros 8, K8-0). Apexin `.crumbs` piirtaa erottimen
   omana kuvakkeenaan (`docs/ui/kierros-8/apex/components.css` `.crumbs .i`);
   tama toteutus on tekstierotin, joten sama muoto tulee `content`ista.
   Merkki on `::after`-sisaltoa eika `<li>`n tekstia, jottei ruudunlukija
   lue sita polun kohdaksi. */
.katakri-murupolku li:not(:last-child)::after{content:"›";margin-left:var(--space-2);color:var(--border-control)}
.katakri-murupolku [aria-current="page"]{color:var(--text-body)}

/* ============ Banneri (Apexin tumma shell) ============
 * Yleiskuvan oma luokka: `.katakri-banneri*` esiintyy vain etusivulla
 * (`index.html`), sen banneripartiaalissa (`partials/_yleiskuva_banneri.html`)
 * ja saman sivun nayttomallissa (`naytot/index.html`), joten Apexin arvot ovat
 * tassa paikallaan eivatka sivun kiinnikkeen takana — mikaan muu sivu ei lue
 * naita saantoja. Kiinnike on vain jaetuilla komponenteilla, ks. tiedoston
 * lopun lohko "Yleiskuva — Apex 2.2".
 *
 * Tausta on tasainen `--shell-1`. `background-image:none` kumosi
 * `.katakri-mesh`:n pistekuvion; kuvio poistui itse luokasta tehtavassa
 * 24cd5d6c, kun sen tokenit (`--mesh-dot-dark`, `--mesh-grid-dark`)
 * poistuivat Meshly-lohkon mukana. Tehtava 09c9ad32 poisti itse
 * `katakri-mesh`-luokan taman sivun kolmesta merkkauskohdasta
 * (`index.html`, `partials/_yleiskuva_banneri.html`, `naytot/index.html`).
 * Deklaraatio jaa silti tahan saantoon, koska `_yleiskuva_banneri.html` on
 * YLIKIRJOITETTAVISSA: jo kopioitu asiakasversio voi kantaa yha
 * `katakri-mesh`-luokkaa ja omaa kuviotaan, ja vain CSS tavoittaa senkin. */
.katakri-banneri{border-radius:var(--radius-xl);padding:var(--space-8) var(--space-8);
  display:flex;flex-wrap:wrap;gap:var(--space-8);align-items:flex-end;justify-content:space-between;
  background:var(--shell-1);background-image:none}
.katakri-banneri__teksti{display:flex;flex-direction:column;gap:var(--space-3);min-width:0}
.katakri-banneri h1{color:var(--on-shell)}
.katakri-banneri em{font-style:italic;color:var(--accent-on-dark)}
.katakri-banneri__meta{font-size:var(--text-body-sm);color:var(--on-shell-3)}
.katakri-banneri__toiminnot{display:flex;gap:var(--space-3);flex-wrap:wrap}

/* ============ Kortti ============ */
.katakri-kortti{background:var(--surface-card);border:var(--border-hairline) solid var(--border-divider);
  border-radius:var(--radius-lg);box-shadow:var(--sh-card);padding:var(--space-6)}
.katakri-kortti--korostus{border-top:3px solid var(--accent)}
.katakri-kortti--tiivis{padding:var(--space-4)}
.katakri-kortti--tyhja{padding:0;overflow:hidden}
.katakri-kortti--nostettava{transition:transform var(--duration-base) var(--ease-standard),box-shadow var(--duration-base) var(--ease-standard)}
.katakri-kortti--nostettava:hover{transform:translateY(-2px);box-shadow:var(--sh-pop)}
.katakri-kortti__otsikko{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
  padding:var(--space-5) var(--space-6);border-bottom:var(--border-hairline) solid var(--border-divider)}
/* Kortin otsikko on aina h4-kokoinen, olipa se __otsikko-kääreessä tai suoraan kortissa.
   Älä nojaa kääreeseen — muuten samalla rivillä on 17px ja 24px otsikoita rinnakkain. */
.katakri-kortti h2,.katakri-kortti h3{font-size:var(--text-h4)}
.katakri-kortti__otsikko h2,.katakri-kortti__otsikko h3{flex:1;min-width:0}
/* Otsikkorivi ilman kortin omaa kehystä: kun __otsikko on kortin sisällä
   toisena ryhmittelynä eikä kortin yläreunana. Oli style-attribuutti
   (padding:0;border:0) ennen ADR 0061 kohdan 7 CSP:tä. */
.katakri-kortti__otsikko--paljas{padding:0;border:0}
.katakri-pinolista{display:flex;flex-direction:column;gap:var(--space-5)}
/* Kortin sisäinen pinolista: --space-5 (20px) on liikaa kortin sisällä,
   --space-4 (16px) liian vähän. Oli style-attribuutti (gap:14px). */
.katakri-pinolista--kortti{gap:14px}
/* Sivun osioiden pinolista: --space-6 (24px), sama kuin `.katakri-paaosa`n oma
   gap. Palstoitetulla sivulla osiot eivät ole enää pääosan suoria lapsia, eikä
   gap periydy kääreen läpi — ilman tätä peräkkäisten korttien reunat koskevat
   toisiaan. Luku on sidottu pääosaan eikä valittu erikseen: palstoitus saa
   siirtää osion sarakkeeseen, muttei muuttaa osioiden väliä. */
.katakri-pinolista--osiot{gap:var(--space-6)}
.katakri-ruudukko{display:grid;gap:var(--space-4);align-items:start}
.katakri-ruudukko--kpi{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
.katakri-ruudukko--puolet{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.katakri-ruudukko--kirjasto{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}
.katakri-ruudukko--sivupalkilla{grid-template-columns:minmax(0,2.2fr) minmax(260px,1fr)}
.katakri-ruudukko--raportti{grid-template-columns:minmax(0,1.4fr) minmax(260px,1fr)}

/* ============ KPI ============
 * Yleiskuvan oma luokka (`partials/_kypsyys_kpi.html`, `naytot/index.html`),
 * joten Apexin musteasteikko on tassa eika kiinnikkeen takana. Apexin oma
 * `.kpi` antaa arvolle `--ink-1`:n ja huomiolle `--ink-3`:n. */
.katakri-kpi{display:flex;flex-direction:column;gap:var(--space-2)}
.katakri-kpi__arvo{font-family:var(--font-sans);font-size:var(--text-display-md);font-weight:var(--weight-bold);
  line-height:1;letter-spacing:var(--tracking-tight);color:var(--ink-1)}
.katakri-kpi__huomio{font-size:var(--text-caption);color:var(--ink-3)}

/* ============ Merkki (badge) ============ */
.katakri-merkki{display:inline-flex;align-items:center;gap:6px;padding:3px 9px;border-radius:var(--radius-pill);
  font-size:var(--text-caption);font-weight:var(--weight-medium);line-height:1.4;white-space:nowrap}
.katakri-merkki--s{padding:2px 7px;font-size:var(--text-overline)}
.katakri-merkki::before{content:"";width:6px;height:6px;border-radius:var(--radius-pill);background:currentColor;flex:none}
.katakri-merkki--ei-pistetta::before{display:none}
.katakri-merkki--neutraali{background:var(--surface-sunken);color:var(--ink-2)}
.katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-merkki--varoitus{background:var(--warn-soft);color:var(--accent2-ink)}
.katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-merkki--reunus{background:transparent;border:var(--border-hairline) solid var(--border-control);color:var(--ink-2)}

/* LUOKITUSMERKKI-ALKU */
/* ============ Luokitusmerkki (TL / TLP / merkitsematon) ============
 * `partials/_luokitusmerkki.html`, kierros 8 (K8-1 + K8-11).
 *
 * TAMAN JA `LUOKITUSMERKKI-LOPPU`-MERKIN VALI ON LOHKO, JOKA KULKEE MYOS
 * ILMAN PALVELINTA. Auditointipaketin ZIP:n `yhteenveto.html` avataan
 * `file:`-osoitteesta, jossa ei ole palvelinta tarjoamassa tata tiedostoa,
 * ja `views/standalone_styles.py` leikkaa merkkien valista lohkon sen
 * dokumentin omaan `<style>`-lohkoon. Lohko on siis luettava sellaisenaan:
 * sen jokainen `var()` ratkeaa `tokens.css`:n `:root`-lohkosta, joka kulkee
 * samaa tieta, eika lohkossa ole viittausta mihinkaan muuhun tiedostoon.
 * Merkkien siirtaminen tai poistaminen kaataa
 * `tests/test_luokitusmerkki.py`:n -- ilman sita merkki jaisi viedyssa
 * yhteenvedossa pelkaksi tekstiksi, ja TLP:RED nayttaisi samalta kuin
 * TLP:CLEAR juuri siina dokumentissa, joka luetaan ilman sovellusta.
 *
 * Kymmenen tilaa: TL I-IV, TLP:n viisi luovutusohjetta ja merkitsematon.
 * Yhdestoista saanto on `--luokittelematon`, joka on `markings.MARKINGS`in
 * arvo siina missa muutkin (merkitsematon ei ole luokittelematon).
 *
 * TL-asteikko ja merkitsematon kayttavat teematokeneita: ne ovat taman
 * kayttoliittyman omaa asua, ja asiakaskerros saa vaihtaa ne teemansa
 * mukaisiksi.
 *
 * TLP-VARIT OVAT LITERAALEJA EIVATKA TOKENEITA, JA NE OVAT TASAN TASSA
 * LOHKOSSA. Ne ovat FIRSTin TLP 2.0 -standardin omat arvot -- musta pohja ja
 * standardin nimilapun vari -- eivat taman paletin arvoja. Tokeniksi
 * nimettyna asiakaskerroksen teema vaihtaisi merkinnan toiseksi merkinnaksi,
 * ja juuri tama merkinta ratkaisee, kenelle aineisto luovutetaan.
 * `tests/test_luokitusmerkki.py` mittaa, ettei naita arvoja ole muualla.
 *
 * Varia ei lueta yksin: merkinnan koko kieliasu on merkin sisaltona aina
 * (`classification.marking.*`), ja `title` nimeaa luokituksen lahteen. */
.katakri-luokitusmerkki{display:inline-flex;align-items:center;padding:2px 8px;
  border:var(--border-hairline) solid transparent;border-radius:var(--radius-sm);
  font-size:var(--text-overline);font-weight:var(--weight-semibold);line-height:1.4;
  letter-spacing:var(--tracking-wide);white-space:nowrap;text-transform:uppercase}
.katakri-luokitusmerkki--luokittelematon{background:var(--surface-sunken);color:var(--ink-2)}
.katakri-luokitusmerkki--tl_iv{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-luokitusmerkki--tl_iii{background:var(--warn-soft);color:var(--accent2-ink)}
.katakri-luokitusmerkki--tl_ii{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-luokitusmerkki--tl_i{background:var(--neg-ink);color:var(--on-shell)}
/* Merkitsematon on puute eika taso: katkoviiva erottaa sen jokaisesta
 * merkinnasta, ja teksti sanoo saman sanana. */
.katakri-luokitusmerkki--merkitsematon{background:transparent;color:var(--ink-3);
  border-style:dashed;border-color:var(--border-control)}
.katakri-luokitusmerkki--tlp_red{background:#000000;color:#FF2B2B}
.katakri-luokitusmerkki--tlp_amber_strict{background:#000000;color:#FFC000}
.katakri-luokitusmerkki--tlp_amber{background:#000000;color:#FFC000}
.katakri-luokitusmerkki--tlp_green{background:#000000;color:#33FF00}
.katakri-luokitusmerkki--tlp_clear{background:#000000;color:#FFFFFF}
/* LUOKITUSMERKKI-LOPPU */

/* ============ Painikkeet ============ */
.katakri-painike{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
  padding:0 var(--space-4);height:40px;border-radius:var(--radius-md);
  border:var(--border-hairline) solid transparent;font-size:var(--text-body-sm);font-weight:var(--weight-semibold);
  cursor:pointer;text-decoration:none;white-space:nowrap;
  transition:filter var(--duration-fast) var(--ease-standard),transform var(--duration-fast) var(--ease-standard),background var(--duration-fast) var(--ease-standard)}
.katakri-painike:active{transform:translateY(1px)}
.katakri-painike:hover{text-decoration:none}
.katakri-painike--ensisijainen{background:var(--action-primary);color:var(--on-shell)}
.katakri-painike--ensisijainen:hover{filter:brightness(1.1);color:var(--on-shell)}
.katakri-painike--toissijainen{background:var(--surface-card);border-color:var(--border-control);color:var(--ink-2)}
.katakri-painike--toissijainen:hover{background:var(--surface-sunken);color:var(--ink-1)}
.katakri-painike--haamu{background:transparent;color:var(--ink-2)}
.katakri-painike--haamu:hover{background:var(--surface-sunken)}
.katakri-painike--s{height:32px;padding:0 var(--space-3);font-size:var(--text-caption)}
.katakri-painike--l{height:48px;padding:0 var(--space-5);font-size:var(--text-body-md)}
.katakri-painike--taysleveys{width:100%}
.katakri-tekstipainike{background:none;border:0;padding:0;cursor:pointer;
  font-size:var(--text-caption);font-weight:var(--weight-semibold);color:var(--accent)}
.katakri-tekstipainike:hover{text-decoration:underline}

/* ============ Lomake ============ */
/* Valikko pysyy säiliössään. Natiivin `<select>`:n oletusleveys on sen
   pisimmän vaihtoehdon levyinen, ja kirjausnäkymän vaatimusvalikossa yksi
   vaihtoehto on koko vaatimusteksti ("I-17 — 1. Turvallisuusluokiteltuja
   tietoja…"): kenttä venyi kortin ja näkymän oikean reunan yli. Suljetun
   selectin valittua arvoa EI voi rivittää — selaimet latovat sen aina
   yhdelle riville — joten ainoa keino pitää kenttä kortissa on rajata
   leveys ja jättää ylipitkän tekstin katkaisu selaimelle. Jos koko teksti
   halutaan näkyviin, se on oma elementtinsä valikon ulkopuolella.
   `max-width` eikä `width`: lyhytvaihtoehtoiset valikot (liitteen
   turvallisuusluokka, kieli) saavat yhä olla sisältönsä levyisiä, ja
   `.katakri-syote`n `width:100%` on luokassa niillä, jotka täyttävät rivin. */
select{max-width:100%}
.katakri-kentta{display:flex;flex-direction:column;gap:6px}
.katakri-kentta__nimike{font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--ink-2)}
.katakri-syote{width:100%;height:40px;padding:0 var(--space-3);border-radius:var(--radius-md);
  border:var(--border-hairline) solid var(--border-control);background:var(--surface-card);
  font-family:var(--font-sans);font-size:var(--text-body-md);color:var(--text-heading)}
.katakri-syote::placeholder{color:var(--text-hint)}
.katakri-syote:focus{outline:none;border-color:var(--focus-ring);box-shadow:var(--shadow-focus-accent)}
.katakri-syote--s{height:34px;font-size:var(--text-body-sm)}

/* Suodatinsirut — Apex 2.2 (tehtävä 38ecf4bb)
   Siru on vaatimusnäkymien oma luokka: `.katakri-siru` on vain säännön sivulla
   (`saanto.html`), suodatinpartiaalissa (`partials/_vaatimus_suodattimet.html`)
   ja saman sivun näyttömallissa (`naytot/vaatimuslista.html`), jotka kaikki
   ovat tämän tehtävän templateja. Siksi Apexin arvot ovat tässä paikallaan
   eivätkä sivun kiinnikkeen `.katakri-vaatimukset` takana — mikään muu sivu ei
   lue näitä sääntöjä (vrt. tiedoston lopun lohko "Vaatimusnäkymät — Apex 2.2").

   Asu on Apexin `.chip`: perustila on `.chip.line` (läpinäkyvä pohja,
   `--line-2`-reunus, `--ink-3`-teksti) ja valittu on `.chip.acc`
   (`--accent-soft` / `--accent-ink`). Valittu ei ole umpiaksentti valkoisella
   tekstillä kuten ennen: Apexin `.chip`-asteikolla ei ole umpiaksenttista
   muunnosta lainkaan, ja `.chip.acc` on se pari, jolla Apex merkitsee sirun
   valituksi. Lihavointi jää erottamaan valitun myös väristä riippumatta. */
.katakri-sirut{display:flex;gap:var(--space-2);flex-wrap:wrap;list-style:none;margin:0;padding:0}
.katakri-siru{display:inline-block;flex:none;white-space:nowrap;padding:6px var(--space-3);border-radius:var(--radius-pill);
  border:var(--border-hairline) solid var(--line-2);background:var(--card);cursor:pointer;
  font-size:var(--text-caption);font-weight:var(--weight-medium);color:var(--ink-3);text-decoration:none}
.katakri-siru:hover{background:var(--row-hover);text-decoration:none;color:var(--ink-1)}
.katakri-siru[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--accent-soft);
  color:var(--accent-ink);font-weight:var(--weight-semibold)}

/* Kytkin ja valintanappi (esitysasu) */
.katakri-kytkin{width:36px;height:20px;border-radius:var(--radius-pill);background:var(--line-2);
  display:inline-flex;align-items:center;padding:2px;flex:none;cursor:pointer;border:0}
.katakri-kytkin[aria-checked="true"]{background:var(--action-primary);justify-content:flex-end}
.katakri-kytkin::after{content:"";width:16px;height:16px;border-radius:var(--radius-pill);background:var(--card)}
.katakri-valinta{display:flex;gap:var(--space-3);align-items:flex-start;padding:var(--space-3);
  border:var(--border-hairline) solid var(--border-divider);border-radius:var(--radius-md);
  background:var(--surface-card);cursor:pointer}
.katakri-valinta[aria-checked="true"]{border-color:var(--accent);background:var(--accent-soft)}
.katakri-valinta::before{content:"";width:15px;height:15px;border-radius:var(--radius-pill);flex:none;margin-top:3px;
  border:var(--border-medium) solid var(--border-control);background:var(--card)}
.katakri-valinta[aria-checked="true"]::before{border:5px solid var(--accent)}
.katakri-valinta__nimi{display:block;font-size:var(--text-body-sm);font-weight:var(--weight-semibold);color:var(--text-heading)}
.katakri-valinta__kuvaus{display:block;margin-top:3px;font-size:var(--text-caption);color:var(--text-label)}

/* ============ Edistymispalkki ============ */
/* Edistymispalkin ura on Apexin `.meter`: `--sunken` eikä `--line-1`
   (docs/ui/kierros-8/apex/components.css §12). Meshlyn `--ink-100` oli
   urana vaaleampi kuin erottimet; Apexilla sama suhde on `--sunken`. */
.katakri-edistys{width:100%;height:7px;border-radius:var(--radius-pill);background:var(--sunken);overflow:hidden}
.katakri-edistys--s{height:4px}
.katakri-edistys__taytto{height:100%;border-radius:var(--radius-pill);background:var(--action-primary)}
.katakri-edistys__taytto--ok{background:var(--status-pos)}
.katakri-edistys__taytto--varoitus{background:var(--status-warn)}
.katakri-edistys__nimike{display:flex;justify-content:space-between;gap:var(--space-3);margin-bottom:6px;
  font-size:var(--text-caption);color:var(--text-label)}

/* ============ Osuusleveys ============ */
/* Palvelimella laskettu leveys tulee sivulle LUOKKANA eikä style-attribuuttina.
   Syy on ADR 0061 kohdan 7 CSP: `style-src 'self'` ilman `'unsafe-inline'`ia
   pudottaa jokaisen style-attribuutin, jolloin täyttöpalkki jäisi nollan
   levyiseksi eikä mikään sivulla kertoisi miksi.
   Askel on 5 prosenttiyksikköä. TOTP-ikkunan 30 sekunnissa se on 1,5 sekuntia,
   ja palkki on pysäytyskuva sivun renderöintihetkestä — ei juokseva laskuri,
   koska sivulla ei ole skriptiä. Näkymä pyöristää osuuden tähän asteikkoon
   (views/views.py, `osuuden_luokka`).
   Käytetään täyttöelementissä: .katakri-edistys__taytto ja
   .katakri-koodi__palkki > span. Kumpikaan ei aseta leveyttä itse. */
.katakri-osuus--0{width:0}
.katakri-osuus--5{width:5%}
.katakri-osuus--10{width:10%}
.katakri-osuus--15{width:15%}
.katakri-osuus--20{width:20%}
.katakri-osuus--25{width:25%}
.katakri-osuus--30{width:30%}
.katakri-osuus--35{width:35%}
.katakri-osuus--40{width:40%}
.katakri-osuus--45{width:45%}
.katakri-osuus--50{width:50%}
.katakri-osuus--55{width:55%}
.katakri-osuus--60{width:60%}
.katakri-osuus--65{width:65%}
.katakri-osuus--70{width:70%}
.katakri-osuus--75{width:75%}
.katakri-osuus--80{width:80%}
.katakri-osuus--85{width:85%}
.katakri-osuus--90{width:90%}
.katakri-osuus--95{width:95%}
.katakri-osuus--100{width:100%}

/* ============ Osa-alueen tila ============
 * Yleiskuvan oma luokka (`partials/_osaalueiden_tila.html`,
 * `naytot/index.html`), joten Apexin arvot ovat tassa. `.katakri-tunnus`,
 * `.katakri-edistys*` ja `.katakri-tekstipainike` samassa partiaalissa ovat
 * jaettuja, ja ne saavat Apexin arvon sivun kiinnikkeella (tiedoston loppu). */
.katakri-osaalue{display:flex;flex-direction:column;gap:var(--space-2);padding-bottom:var(--space-4);
  border-bottom:var(--border-hairline) solid var(--line-1)}
.katakri-osaalue:last-child{border-bottom:0;padding-bottom:0}
.katakri-osaalue__rivi{display:flex;align-items:baseline;gap:var(--space-3)}
.katakri-tunnus{font-family:var(--font-mono);font-size:var(--text-body-sm);font-weight:var(--weight-semibold);
  color:var(--accent);flex:none}
.katakri-osaalue__nimi{flex:1;font-weight:var(--weight-medium);color:var(--ink-1)}
.katakri-osaalue__suhde{font-family:var(--font-mono);font-size:var(--text-caption);
  font-weight:var(--weight-semibold);color:var(--ink-3)}

/* ============ Vaatimustaulukko ============ */
.katakri-taulukko{width:100%;border-collapse:collapse;table-layout:fixed}
.katakri-taulukko caption{text-align:left;padding:0 var(--space-6) var(--space-3);
  font-size:var(--text-caption);color:var(--text-label)}
.katakri-taulukko th{text-align:left;padding:var(--space-3) var(--space-6);background:var(--surface-sunken);
  border-bottom:var(--border-hairline) solid var(--border-divider);font-family:var(--font-mono);
  font-size:var(--text-overline);font-weight:var(--weight-semibold);line-height:1;
  letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--text-hint)}
.katakri-taulukko td{padding:15px var(--space-6);border-bottom:var(--border-hairline) solid var(--border-divider);
  vertical-align:middle}
/* Pitka tunnus katkeaa solussa eika jatka naapurisarakkeen paalle.
   `table-layout:fixed` lukitsee sarakeleveydet, mutta se ei riko sanoja:
   katkeamaton `synthetic.1641aaa3a2856824.document.synthetic-dms-1:doc-000022:3.0`
   jatkui versiohistoriassa ulos kortista oikeaan palstaan asti
   (docs/ui/kierros-6/audit-2026-10-23/history-day.png). `anywhere` eika
   `break-word`, koska nama ovat koneluettavia tunnuksia eivat sanoja: ne
   katkeavat mista tahansa, ja juuri se pitaa sarakkeen levean sisallon
   sarakkeessa myos ahtaassa asettelussa.
   Solujen pystytasaus ei ole tassa: dokumenttilistan rivikorkeus ja
   `vertical-align` ovat oma havaintonsa ja oma tehtavansa (76dde623). */
.katakri-taulukko th,.katakri-taulukko td{overflow-wrap:anywhere}
.katakri-taulukko tbody tr:hover{background:var(--surface-sunken)}
.katakri-taulukko--tiivis td{padding:9px var(--space-6)}
.katakri-sarake--tunnus{width:80px}
.katakri-sarake--tila{width:140px}
.katakri-sarake--evidenssi{width:104px}
.katakri-sarake--vastuu{width:158px}
.katakri-vaatimus__nimi{display:block;font-weight:var(--weight-medium);color:var(--text-heading)}
.katakri-vaatimus__osio{display:block;margin-top:3px;font-size:var(--text-caption);color:var(--text-hint)}
/* Lukuarvo taulukkosolussa. Vaatimusnäkymien oma luokka (`naytot/vaatimus.html`,
   `naytot/vaatimuslista.html`), joten Apexin `--ink-3` on tässä paikallaan.
   `.katakri-navi__luku` on eri luokka ja jää navigaation tehtävälle. */
.katakri-luku{font-family:var(--font-mono);font-size:var(--text-body-sm);color:var(--ink-3)}
.katakri-himmea{font-size:var(--text-body-sm);color:var(--text-label)}
.katakri-taulukko a{color:inherit;text-decoration:none}
.katakri-taulukko a:hover{text-decoration:none}

/* ============ Agentin ehdotus — EI YLIKIRJOITETTAVISSA ============ */
/* Varmuusaste ja lähdeluettelo ovat jäljitettävyysketjun esitys. */
.katakri-ehdotus{display:flex;gap:var(--space-3);align-items:flex-start;padding:var(--space-3) 14px;
  background:var(--accent-soft);border:var(--border-hairline) solid var(--accent-soft);
  border-left:3px solid var(--accent);border-radius:var(--radius-md)}
.katakri-ehdotus__ikoni{color:var(--accent);margin-top:2px}
.katakri-ehdotus__runko{display:flex;flex-direction:column;gap:6px;flex:1;min-width:0}
.katakri-ehdotus__nimike{font-family:var(--font-mono);font-size:var(--text-caption);font-weight:var(--weight-semibold);
  line-height:1;letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--accent-ink)}
.katakri-ehdotus__teksti{font-size:var(--text-body-sm);line-height:var(--leading-normal);color:var(--ink-2)}
.katakri-ehdotus__toiminnot{display:flex;gap:var(--space-2);flex:none}
/* Ehdotusrivi, varmuusaste ja lähdeluettelo ovat vaatimusnäkymien omia
   luokkia: `.katakri-ehdotus-rivi` esiintyy vain `naytot/vaatimuslista.html`:ssa
   ja `.katakri-varmuus*` sekä `.katakri-lahde*` vain `naytot/vaatimus.html`:ssa.
   Siksi Apexin arvot ovat tässä paikallaan. Varmuusaste on Apexin `--pos-ink`:
   se on `.chip.pos`:n tekstiväri, eli sama sävy, jolla Apex merkitsee myönteisen
   tilan luettavaksi vaalealla pohjalla (`--pos` yksin on täyttöväri). */
.katakri-ehdotus-rivi td{padding:0 var(--space-6) 14px;border-bottom:var(--border-hairline) solid var(--line-1)}
.katakri-varmuus{display:flex;align-items:center;gap:var(--space-3);padding:10px 14px;
  background:var(--sunken);border-radius:var(--radius-md)}
.katakri-varmuus__arvo{font-family:var(--font-mono);font-size:var(--text-body-sm);
  font-weight:var(--weight-semibold);color:var(--pos-ink);flex:none}

/* ============ Lähdeluettelo — EI YLIKIRJOITETTAVISSA ============ */
.katakri-lahteet{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.katakri-lahde{display:flex;align-items:center;gap:var(--space-3);padding:10px var(--space-3);
  border:var(--border-hairline) solid var(--line-1);border-radius:var(--radius-md)}
.katakri-lahde__ikoni{color:var(--ink-4)}
.katakri-lahde__runko{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}
.katakri-lahde__nimi{font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--ink-1)}
.katakri-lahde__meta{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--ink-4)}

/* ============ Käsittelyhistoria / audit trail — EI YLIKIRJOITETTAVISSA ============ */
.katakri-ketju{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-3)}
.katakri-ketju__kohta{display:flex;gap:var(--space-3);align-items:flex-start}
.katakri-ketju__aika{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--text-hint);
  flex:none;width:112px}
.katakri-ketju__piste{width:7px;height:7px;border-radius:var(--radius-pill);background:var(--line-2);
  flex:none;margin-top:6px}
/* `min-width:0` paastaa lenkin kutistumaan, mutta se ei yksin riita:
   jaljitysketjun lenkki kantaa keruutapahtuman tunnuksen, joka on yksi
   katkeamaton merkkijono (`synthetic.…:doc-000022:3.0`). Asiakirjan sivun
   kapeassa sivupalstassa se jatkui ulos ikkunasta asti ja teki sivulle
   vaakavierityksen (mitattu 1440 px:n leveydella: scrollWidth 1470). */
.katakri-ketju__teksti{font-size:var(--text-body-sm);color:var(--ink-2);min-width:0;
  overflow-wrap:anywhere}

/* ============ Ominaisuuslista ============ */
.katakri-ominaisuudet{margin:0;display:flex;flex-direction:column;gap:0}
.katakri-ominaisuudet div{display:flex;justify-content:space-between;gap:var(--space-3);
  padding-bottom:10px;margin-bottom:10px;border-bottom:var(--border-hairline) solid var(--border-divider)}
.katakri-ominaisuudet div:last-child{border-bottom:0;padding-bottom:0;margin-bottom:0}
.katakri-ominaisuudet dt{font-size:var(--text-body-sm);color:var(--text-label)}
.katakri-ominaisuudet dd{margin:0;font-size:var(--text-body-sm);font-weight:var(--weight-medium);
  color:var(--text-heading);text-align:right}
/* Nimi ja arvo ovat flex-alkioita, eli kumpikaan ei oletuksena kutistu
   sisaltoaan kapeammaksi. Asiakirjan tiedoissa arvo on usein katkeamaton
   tunnus -- keruutapahtuman `event_id`, viite, tiiviste -- ja se tyonsi
   parin ulos kortista (docs/ui/kierros-6/audit-2026-10-23/document-doc-000022.png).

   Kolme saantoa, ja jokainen ratkaisee eri puolen:
   - `min-width:0` paastaa alkion kutistumaan rivilla.
   - `flex-wrap:wrap` siirtaa liian pitkan arvon omalle rivilleen sen sijaan,
     etta se puristaisi kentan nimen muutaman merkin levyiseksi. Leveassa
     palstassa mikaan ei rivity, joten tama nakyy vain siella, missa tilaa ei
     ole -- esimerkiksi tapahtumasivun eheyspalstassa, jossa suunnitelma
     latookin nimen ja tiivisteen allekkain (p5-3).
   - `overflow-wrap:anywhere` on vain arvolla: tunnus katkeaa mista tahansa,
     koska se ei ole sana. Kentan nimi on sana, ja samalla saannolla se latoi
     "Edellinen tapahtuma" pystyyn kirjain kerrallaan. */
.katakri-ominaisuudet div{flex-wrap:wrap}
.katakri-ominaisuudet dt,.katakri-ominaisuudet dd{min-width:0}
.katakri-ominaisuudet dd{overflow-wrap:anywhere}

/* ============ Evidenssikortti ============
 * Evidenssikortin OMA luokkaperhe (`partials/_evidenssi_kortti.html`,
 * `naytot/evidenssi.html`), joten Apexin arvot ovat tassa paikallaan eivatka
 * perheen kiinnikkeen takana — mikaan muu sivu ei lue naita saantoja.
 * Kiinnike on vain jaetuilla komponenteilla, ks. tiedoston lopun lohko
 * "Evidenssi ja auditointipaketti — Apex 2.2".
 *
 * Kuvakelaatta on Apexin `.avatar`/`.chip.acc` -pari (`--accent-soft` pohja,
 * `--accent-ink` veto) — sama arvo, jonka etusivun porautumiskortin kuvake jo
 * sai (teht. 2e372620). */
.katakri-evidenssi{display:flex;flex-direction:column;gap:var(--space-3)}
.katakri-evidenssi__ylaosa{display:flex;align-items:flex-start;gap:10px}
.katakri-evidenssi__kuvake{width:32px;height:32px;border-radius:var(--radius-md);
  background:var(--accent-soft);color:var(--accent-ink);display:inline-flex;
  align-items:center;justify-content:center;flex:none}
.katakri-evidenssi__nimi{display:block;font-weight:var(--weight-semibold);color:var(--ink-1)}
.katakri-evidenssi__lahde{display:block;margin-top:3px;font-family:var(--font-mono);
  font-size:var(--text-caption);color:var(--ink-4)}
.katakri-evidenssi__alaosa{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding-top:10px;border-top:var(--border-hairline) solid var(--line-1)}
.katakri-merkkilista{display:flex;gap:6px;flex-wrap:wrap;list-style:none;margin:0;padding:0}

/* ============ Agenttiajo ============ */
.katakri-jono{list-style:none;margin:0;padding:0}
.katakri-jono__kohta{display:flex;align-items:center;gap:var(--space-3);padding:14px var(--space-6);
  border-bottom:var(--border-hairline) solid var(--border-divider)}
.katakri-jono__kohta:last-child{border-bottom:0}
.katakri-tilapiste{width:8px;height:8px;border-radius:var(--radius-pill);flex:none;background:var(--line-2)}
.katakri-tilapiste--ok{background:var(--status-pos)}
.katakri-tilapiste--info{background:var(--accent)}
.katakri-tilapiste--varoitus{background:var(--status-warn)}
.katakri-tilapiste--vaara{background:var(--status-neg)}
.katakri-jono__runko{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}
.katakri-jono__nimi{font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--text-heading)}
.katakri-jono__vaihe{font-size:var(--text-caption);color:var(--text-hint)}
/* Agenttiajon tiivistelman askeleet (`locked/_agenttiajo_tiivistelma.html`,
   `naytot/index.html`). Askelluokat esiintyvat vain naissa kahdessa, joten
   Apexin musteasteikko on tassa paikallaan (teht. 6b08a81b).

   Askeleen tilapiste saa Apexin tilavarit NIMENOMAAN askeleen sisalla
   rajattuna. `.katakri-tilapiste--*` yksin on jaettu agenttiajon jonorivin
   kanssa (`naytot/agenttiajo.html`, `.katakri-jono__kohta`), joka odottaa omaa
   migraatiotehtavaansa; `.katakri-askel` on se, mika erottaa nama kaksi
   esiintymaa toisistaan merkkauksessa. Tilapisteen oma lohko on ylla. */
.katakri-askeleet{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.katakri-askel{display:flex;gap:10px;align-items:flex-start}
.katakri-askel .katakri-tilapiste{margin-top:5px;background:var(--line-2)}
.katakri-askel .katakri-tilapiste--ok{background:var(--pos)}
.katakri-askel .katakri-tilapiste--info{background:var(--accent)}
.katakri-askel .katakri-tilapiste--varoitus{background:var(--warn)}
.katakri-askel .katakri-tilapiste--vaara{background:var(--neg)}
.katakri-askel__nimi{display:block;font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--ink-1)}
.katakri-askel__meta{display:block;margin-top:2px;font-family:var(--font-mono);font-size:var(--text-caption);color:var(--ink-4)}

/* Tapahtumaloki — EI YLIKIRJOITETTAVISSA
 * Loki on TUMMA pinta, ja siksi sen sävyt eivät ole samat kuin vaalealla
 * kortilla. Apexin oma tumma palaute on `.toast` (components.css §11):
 * pohja `--ink-1`, teksti valkoinen ja onnistumisen merkki `--toast-icon`.
 * Tämä lohko lukee saman porrastuksen: aika on himmein (`--on-shell-3`),
 * viesti sen yläpuolella (`--on-shell-2`) ja tilat ovat Apexin
 * TUMMALLE PINNALLE tarkoitetut sävyt — `--pos`, `--warn` ja `--neg` ovat
 * vaalean pinnan arvoja eivätkä eroa `--ink-1`:stä riittävästi.
 * Punaiselle Apexilla ei ole omaa tummanpinnan sävyä; `--neg-border`
 * (#f2c4c2) on sen paletin ainoa vaalea punainen ja erottuu
 * `--on-shell-2`:sta kylläisyydellään. */
.katakri-loki{background:var(--ink-1);padding:var(--space-4) var(--space-5);margin:0;
  display:flex;flex-direction:column;gap:7px;border-radius:0 0 var(--radius-lg) var(--radius-lg);
  list-style:none;font-family:var(--font-mono);font-size:var(--text-caption);line-height:1.5}
.katakri-loki__rivi{display:flex;gap:10px}
.katakri-loki__aika{color:var(--on-shell-3);flex:none}
.katakri-loki__viesti{color:var(--on-shell-2);min-width:0}
.katakri-loki__viesti--ok{color:var(--toast-icon)}
.katakri-loki__viesti--info{color:var(--accent-on-dark)}
.katakri-loki__viesti--varoitus{color:var(--accent2-on-dark)}
.katakri-loki__viesti--vaara{color:var(--neg-border)}

/* ============ Poikkeamat ============ */
.katakri-poikkeamat{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-3)}
.katakri-poikkeama{display:flex;align-items:center;gap:var(--space-4);flex-wrap:wrap}
.katakri-poikkeama__vakavuus{width:4px;align-self:stretch;min-height:44px;border-radius:var(--radius-pill);
  background:var(--line-2);flex:none}
.katakri-poikkeama__vakavuus--korkea{background:var(--status-neg)}
.katakri-poikkeama__vakavuus--keski{background:var(--status-warn)}
.katakri-poikkeama__runko{display:flex;flex-direction:column;gap:var(--space-1);flex:1;min-width:200px}
.katakri-poikkeama__otsikko{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.katakri-poikkeama__id{font-family:var(--font-mono);font-size:var(--text-body-sm);
  font-weight:var(--weight-semibold);color:var(--text-label)}
.katakri-poikkeama__nimi{font-weight:var(--weight-semibold);color:var(--text-heading)}
.katakri-poikkeama__meta{font-size:var(--text-caption);color:var(--text-label)}
.katakri-poikkeama__maaraaika{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--text-hint);flex:none}

/* ============ Raportti ============ */
.katakri-raportti__kansi{display:flex;flex-direction:column;gap:var(--space-2);
  padding-bottom:var(--space-5);border-bottom:var(--border-thick) solid var(--ink-1)}
/* Kansilehden otsikko on h2-kokoinen mutta lihava: kansi on dokumentin alku,
   ei osion otsikko. Oli style-attribuutti ennen ADR 0061 kohdan 7 CSP:tä. */
.katakri-raportti__kansiotsikko{font-size:var(--text-h2);font-weight:var(--weight-bold)}
.katakri-raportti__osiot{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-5)}
.katakri-raportti__osio{display:flex;gap:var(--space-4);align-items:baseline}
.katakri-raportti__numero{font-family:var(--font-mono);font-size:var(--text-body-sm);
  font-weight:var(--weight-semibold);color:var(--accent);flex:none;width:40px}
.katakri-raportti__nimi{display:block;font-family:var(--font-sans);font-size:var(--text-body-lg);
  font-weight:var(--weight-semibold);color:var(--text-heading)}
.katakri-raportti__runko{display:block;margin-top:6px;font-size:var(--text-body-sm);
  line-height:var(--leading-relaxed);color:var(--ink-2)}
.katakri-viennit{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.katakri-vienti{display:flex;align-items:center;gap:10px;padding:11px var(--space-3);
  border:var(--border-hairline) solid var(--border-divider);border-radius:var(--radius-md);
  color:inherit;text-decoration:none}
.katakri-vienti:hover{background:var(--surface-sunken);text-decoration:none;color:inherit}
.katakri-vienti__nimi{flex:1;font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--text-heading)}
.katakri-vienti__koko{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--text-hint)}

/* ============ Integraatiot ============ */
.katakri-integraatiot{list-style:none;margin:0;padding:0}
.katakri-integraatio{display:flex;align-items:center;gap:14px;padding:14px var(--space-6);
  border-bottom:var(--border-hairline) solid var(--border-divider)}
.katakri-integraatio:last-child{border-bottom:0}
.katakri-integraatio__runko{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}
.katakri-integraatio__nimi{font-weight:var(--weight-medium);color:var(--text-heading)}
.katakri-integraatio__meta{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--text-hint)}
.katakri-valinnat{display:flex;flex-direction:column;gap:10px;list-style:none;margin:0;padding:0}

/* ============ Agenttipaneeli — YLIKIRJOITETTAVISSA (ei viestisisältö) ============
 * Apex 2.2 (tehtävä 72ca7e29). Paneeli on sisältöpintaa eikä shelliä: kortti
 * `--card`, erottimet `--line-1`, muste `--ink-1/2/3/4`. Käyttäjän kupla on
 * ainoa tumma kohta, ja se lukee shell-tokenia (`--shell-2`/`--on-shell`)
 * samasta syystä kuin navi; agentin kupla on Apexin pehmeä aksenttipinta.
 */
.katakri-agentti{flex:0 1 var(--katakri-agentti-width);min-width:260px;max-width:var(--katakri-agentti-width);
  border-left:var(--border-hairline) solid var(--line-1);background:var(--card);
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh}
.katakri-agentti__otsikko{display:flex;align-items:center;gap:10px;padding:var(--space-5);
  border-bottom:var(--border-hairline) solid var(--line-1)}
.katakri-agentti__ikoni{color:var(--accent)}
.katakri-agentti__nimi{display:block;font-size:var(--text-body-sm);font-weight:var(--weight-semibold);color:var(--ink-1)}
.katakri-agentti__malli{display:block;margin-top:2px;font-family:var(--font-mono);font-size:var(--text-overline);
  line-height:1;letter-spacing:var(--tracking-label);color:var(--ink-4)}
.katakri-agentti__sulje{margin-left:auto;background:none;border:0;cursor:pointer;color:var(--ink-4);
  padding:2px;display:inline-flex}
.katakri-agentti__keskustelu{flex:1;min-height:0;overflow-y:auto;padding:var(--space-5);
  display:flex;flex-direction:column;gap:14px;list-style:none;margin:0}
.katakri-viesti{display:flex;flex-direction:column;gap:var(--space-1);align-items:flex-end}
.katakri-viesti--agentti{align-items:flex-start}
.katakri-viesti__kuka{font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-semibold);
  line-height:1;letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--ink-4)}
.katakri-viesti__kupla{max-width:88%;padding:10px var(--space-3);border-radius:var(--radius-md);
  font-size:var(--text-body-sm);line-height:var(--leading-normal);background:var(--shell-2);color:var(--on-shell)}
.katakri-viesti--agentti .katakri-viesti__kupla{background:var(--accent-softer);color:var(--ink-2);
  border:var(--border-hairline) solid var(--accent-soft)}
.katakri-agentti__ehdotukset{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);
  background:var(--sunken);border-radius:var(--radius-md);list-style:none;margin:0}
.katakri-agentti__ehdotus{display:block;width:100%;text-align:left;padding:9px 11px;background:var(--card);
  border:var(--border-hairline) solid var(--line-1);border-radius:var(--radius-md);cursor:pointer;
  font-size:var(--text-body-sm);font-weight:var(--weight-medium);color:var(--ink-2)}
.katakri-agentti__ehdotus:hover{background:var(--row-hover)}
.katakri-agentti__syote{padding:14px var(--space-5) var(--space-5);
  border-top:var(--border-hairline) solid var(--line-1);display:flex;gap:var(--space-2);align-items:center}

/* ============ Kontrollinäkymän jäljitettävyys — LISÄTTY YTIMESSÄ ============
 * Nämä luokat eivät ole luovutuspaketista vaan ytimen elävistä sivuista
 * (`_agenttipaneeli.html`, `tapahtuma.html`, `saanto.html`). Ne ovat täällä
 * eivätkä style.css:ssä, koska `katakri-`-komponenttiluokat luetaan tästä
 * tiedostosta; seuraava luovutuskierros yhdistää ne omiinsa. Sama sääntö
 * pätee: värit, varjot ja kirjainperheet tokens.css:n muuttujista. Mitat
 * ovat tässä osiossa niin kuin muuallakin tiedostossa osin literaaleja.
 */

/* Agenttipaneelin neljä tilaa. Katkoviivakehys on se ero, joka näkyy myös
   mustavalkoisena tulosteena: "ei käytössä" ei ole tyhjä vastaus vaan
   vastauksen puuttuminen, eikä ero saa jäädä värin varaan. */
.katakri-paneeli__otsikko{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
  margin-bottom:var(--space-4)}
.katakri-paneeli__otsikko .katakri-ikoni{color:var(--accent)}
.katakri-paneeli--ei-kaytossa{border-style:dashed;border-color:var(--line-2);
  background:var(--sunken);box-shadow:none}
.katakri-paneeli__tyhja{display:flex;align-items:center;gap:var(--space-2);
  font-size:var(--text-body-sm);color:var(--ink-3)}
.katakri-paneeli__valmis{color:var(--pos)}

/* Kolme hetkeä aikajanana: järjestys on itsessään tieto, joten pisteet ovat
   yhdellä viivalla eivätkä kolmena erillisenä kenttänä.
 *
 * Apex 2.2 paikallaan (tehtävä 02537cdd): `.katakri-hetket*` renderöityy vain
 * `tapahtuma.html`:ssä, joka on tämän tehtävän näkymä, joten kiinnike olisi
 * spesifisyyttä ilman syytä — sama jako kuin yleiskuvan omilla luokilla.
 * Apexilla on kaksi viivaa neljän sijaan: yhdistävä hiusviiva on `--line-1`
 * (`.comp`-rivien erotin) ja piste `--line-2` (kontrollien viiva), eli
 * järjestys "ohut vaalea viiva, tummempi piste" säilyy. */
.katakri-hetket{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-4)}
.katakri-hetket__kohta{display:grid;grid-template-columns:auto minmax(0,1fr);
  column-gap:var(--space-3);row-gap:var(--space-1);align-items:baseline;position:relative}
.katakri-hetket__kohta:not(:last-child)::before{content:"";position:absolute;left:3px;top:var(--space-4);
  bottom:calc(-1 * var(--space-4));width:var(--border-hairline);background:var(--line-1)}
.katakri-hetket__piste{grid-row:1;grid-column:1;width:7px;height:7px;border-radius:var(--radius-pill);
  background:var(--line-2);align-self:center}
.katakri-hetket__nimi{grid-row:1;grid-column:2;font-size:var(--text-body-sm);
  font-weight:var(--weight-semibold);color:var(--ink-1)}
.katakri-hetket__arvo{grid-row:2;grid-column:2;font-family:var(--font-mono);
  font-size:var(--text-body-sm);color:var(--ink-2)}
.katakri-hetket__kentta{grid-row:3;grid-column:2;font-family:var(--font-mono);
  font-size:var(--text-overline);letter-spacing:var(--tracking-label);color:var(--ink-4)}

/* Kopiointipainike: lisä arvon vieressä, ei arvon korvaaja. */
.katakri-kopioi{display:inline-flex;align-items:center;margin-left:var(--space-2);
  color:var(--text-hint);vertical-align:middle}
.katakri-kopioi:hover{color:var(--accent)}
.katakri-kopioi[data-kopioitu]{color:var(--status-pos)}

.katakri-ohje{font-size:var(--text-caption);color:var(--text-label)}
.katakri-koodilohko{margin:0;padding:var(--space-4);border-radius:var(--radius-md);
  background:var(--shell-1);color:var(--on-shell-2);font-family:var(--font-mono);
  font-size:var(--text-body-sm);line-height:var(--leading-normal);overflow-x:auto}

/* ============ Kirjautuminen ============ */
.katakri-kirjautuminen{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);min-height:100vh}
/* Apex-shell: tasainen tumma pohja ilman mesh-pistekuviota (Kierros 8). */
.katakri-kirjautuminen__esittely{padding:56px var(--space-12);display:flex;flex-direction:column;
  justify-content:space-between;gap:var(--space-12);background:var(--shell-1);background-image:none}
.katakri-kirjautuminen__esittely h1{font-size:var(--text-display-lg);color:var(--on-shell);line-height:var(--leading-tight)}
.katakri-kirjautuminen__esittely em{font-style:italic;color:var(--accent-on-dark)}
/* Sanamerkki skaalataan korkeudesta: SVG:n width/height-attribuutit pitävät
   kuvasuhteen, luokka antaa esitetyn koon. Oli style-attribuutti
   (height:26px;width:auto;display:block) ennen ADR 0061 kohdan 7 CSP:tä. */
.katakri-kirjautuminen__sanamerkki{height:26px;width:auto;display:block}
.katakri-kirjautuminen__teksti{display:flex;flex-direction:column;gap:var(--space-5);max-width:460px}
.katakri-kirjautuminen__johdanto{font-size:var(--text-body-lg);line-height:var(--leading-relaxed);color:var(--on-shell-2)}
.katakri-kirjautuminen__jalki{display:flex;flex-direction:column;gap:var(--space-2);
  font-size:var(--text-body-sm);color:var(--on-shell-3);border-top:var(--border-hairline) solid var(--shell-line);padding-top:var(--space-4)}
/* Vaalea puoli: pohja JA periytyva edustavari Apexilta. `color` on tassa
   samasta syysta kuin yleiskuvan kiinnikkeessa (ks. tiedoston loppu): ilman
   sita jokainen varisaannoton elementti perii `body`n `--text-body`n --
   kierroksella 1 Meshlyn musteen, tehtavan 24cd5d6c jalkeen Apexin
   aliaksen. Nakyvin on `.katakri-tunnistettu`:n kayttajaikoni, jonka
   veto on `icons.svg`:ssa `currentColor` eika silla ole omaa varisaantoa.
   Saanto on lomakepuolella eika `.katakri-kirjautuminen`-kaareessa, jotta se
   ei ylla esittelypuolen tummalle pinnalle. */
.katakri-kirjautuminen__lomake{display:flex;align-items:center;justify-content:center;
  padding:var(--space-12) var(--space-10);background:var(--page);color:var(--ink-2)}
.katakri-kirjautuminen__lomake form{width:100%;max-width:380px;display:flex;flex-direction:column;gap:var(--space-6)}
.katakri-kirjautuminen__kentat{display:flex;flex-direction:column;gap:var(--space-4)}
.katakri-huomio{display:flex;align-items:center;gap:var(--space-2);padding:10px var(--space-3);
  background:var(--pos-soft);border:var(--border-hairline) solid var(--pos-soft);
  border-radius:var(--radius-md);font-size:var(--text-caption);font-weight:var(--weight-medium);color:var(--pos-ink)}
.katakri-huomio .katakri-ikoni{color:var(--pos-ink)}

/* ============ Responsiivisuus ============ */
@media (max-width:1240px){
  .katakri-agentti{display:none}
}
@media (max-width:1100px){
  .katakri-ruudukko--sivupalkilla,.katakri-ruudukko--raportti{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:1000px){
  .katakri-navi{width:58px;padding-left:var(--space-2);padding-right:var(--space-2)}
  .katakri-navi__nimike,.katakri-navi__luku,.katakri-navi__brandi div,
  .katakri-navi__kayttaja div,.katakri-navi__ulos span,.katakri-navi__ryhmanimi{display:none}
  .katakri-paaosa{padding:var(--space-5) var(--space-5) var(--space-12)}
  /* Kapealla näytöllä navi on kuvakekaista, eikä brändinimi mahdu ylarivin
     sen levyiseen lohkoon: merkki jää, nimi menee. Haku menee kokonaan —
     sama pari kuin Apexin omassa kapeassa kehikossa (`.shell` kaventuu
     `--nav-w-min`:iin ja `.tb-search{display:none}` samassa lohkossa). */
  .katakri-ylapalkki__brandi{flex:0 0 auto}
  .katakri-ylapalkki__nimi,.katakri-ylapalkki__haku{display:none}
}
@media (max-width:860px){
  .katakri-sarake--evidenssi,.katakri-sarake--vastuu,
  .katakri-taulukko td.katakri-solu--valinnainen{display:none}
  .katakri-kirjautuminen{grid-template-columns:minmax(0,1fr)}
  .katakri-kirjautuminen__esittely{min-height:auto}
}

/* ============ Tulostus ============ */
@media print{
  /* Ylärivi on navin tavoin ruudun kehystä: paperilla siinä on vain
     käyttäjävalikon avain, jota ei voi avata. */
  .katakri-navi,.katakri-ylapalkki,.katakri-agentti,
  .katakri-sivuotsikko__toiminnot,.katakri-banneri__toiminnot{display:none}
  /* Kopiointipainike on paperilla toimimaton, mutta katkoviivakehys ja merkki
     jäävät: tulosteesta on yhä luettavissa, onko agenttikerros käytössä. */
  .katakri-kopioi{display:none}
  body{background:var(--card)}
  .katakri-kortti{box-shadow:none;break-inside:avoid}
  .katakri-paaosa{padding:0}
}

/* ============ Saavutettavuus ============ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;transition-duration:.001ms !important}
}

/* ============ UI v2 — LISÄTTY LUOVUTUKSESTA 2026-09-28 ============
 * Lähde: Claude Design -luovutus design_handoff_katakri_ui_v2 (docs/ui/kierros-3/).
 * Samat säännöt kuin muualla: värit, fontit ja varjot tokens.css:stä.
 * Gridin kiinteät raideleveydet on koottu --katakri-v2-*-muuttujiksi.
 */
:root {
  --katakri-v2-sivupaneeli: 300px;
  --katakri-v2-lomakepaneeli: 340px;
  --katakri-v2-muutostietue: 220px;
  --katakri-v2-kontrollit: 88px;
}

/* ---------------------------------------------------------------------------
 * Navigaation ryhmät (3a). YLIKIRJOITETTAVISSA — _navigaatio.html
 * Ryhmittely on esitystä: NAVIGATION-tuplen järjestys säilyy, ja ryhmä
 * johdetaan toiminnosta (VIEW/ACK/BASE/PKG = työ, CONF/USERS/COLL = hallinta).
 * ------------------------------------------------------------------------- */
.katakri-navi__ryhma{display:flex;flex-direction:column;gap:2px;padding-bottom:14px}
.katakri-navi__ryhmanimi{padding:0 10px 6px;font-family:var(--font-mono);font-size:10px;
  font-weight:var(--weight-semibold);line-height:1;letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:var(--on-shell-3)}
/* Odottavan tyon merkki on Apexin `.nav-item .pill.hot`: toinen aksentti
   taustana ja shell-teksti sen paalla. */
.katakri-navi__odottaa{font-family:var(--font-mono);font-size:var(--text-overline);
  font-weight:var(--weight-semibold);line-height:1;color:var(--on-shell);
  background:var(--accent2);padding:3px 6px;border-radius:var(--radius-pill)}
/* Kirjaajan rooli koodina. Luokka on navin nimiavaruudessa mutta renderöityy
   vain `_poikkeamalista.html`:ssä, eli poikkeaman ja riskin hyväksynnän
   sivuilla (tehtävä 08decf84) — ei navigaatiossa. Siksi Apexin arvo on tässä
   paikallaan, ja tehtävän 72ca7e29 lykkäys ("jää tieten Meshlyyn: renderöityy
   kehyksen ulkopuolisilla sivuilla") purkautuu tässä.

   Väri on `--accent` eikä Meshlyn `--blue-300`:n lähin vastine
   `--accent-on-dark` (#8e99f0): rooli luetaan vaalealla kortilla, jossa
   #9AA8FA jäi lukukelvottomaksi (kontrasti valkoista vasten 1,9:1). Navin
   tumma pohja, jolle sävy alun perin valittiin, ei ole tämän luokan ainoa
   esiintymä vaan sen yksikään. */
.katakri-navi__rooli--koodi{font-family:var(--font-mono);font-size:10px;letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:var(--accent)}

/* ---------------------------------------------------------------------------
 * Vuosikello — neljä neljännestä rinnakkain
 * ------------------------------------------------------------------------- */
/* Vain `vuosikello.html`:n luokkia, joten mitat ovat tässä paikallaan.
 *
 * NELJÄ SARAKETTA, EIKÄ `auto-fit`. Vuosikellon sarakkeet ovat nimettyjä
 * neljänneksiä, ja niiden LUKUMÄÄRÄ on sivun lupaus: `auto-fit` kääntäisi
 * kapealla näytöllä Q3:n ja Q4:n toiselle riville, jolloin sarakkeen paikka
 * ei enää kertoisi, mikä neljännes se on.
 *
 * `minmax(0,1fr)` EIKÄ `minmax(<mitta>,1fr)`, ja tämä on se kohta, joka pitää
 * sivun 1024 px:ssä ilman vaakavieritystä. Radan alaraja on raidan pienin
 * mahdollinen mitta: `0` päästää sarakkeen kutistumaan säiliöönsä, kun taas
 * kiinteä alaraja on raidalle vaadittu tila, jonka ruudukko ottaa säiliön yli
 * ja vierittää sivua vaakasuunnassa. Laskelma 1024 px:llä: 1024 − 264
 * (`--katakri-nav-width`) − 2 × 32 (`--space-8`, pääosan reunus) = 696 px
 * sisällölle, josta kortin reunukset ja kolme `--space-4`-väliä vievät osansa
 * — alle 180 px saraketta kohden, eli mikä tahansa totuttu korttileveys
 * alarajana rikkoisi sen. `tests/test_vuosikellonakyma.py` laskee saman
 * mitan lähdetekstistä.
 *
 * `min-width:0` jokaisella sarakkeella samasta syystä: ruudukon alkio on
 * oletuksena `min-width:auto`, eli vähintään sisältönsä levyinen, ja pitkä
 * katkeamaton velvoitetunnus leventäisi saraketta radan alarajasta
 * riippumatta. `overflow-wrap` katkaisee sen rivin sisällä. */
.katakri-vuosikello{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:var(--space-4);align-items:start}
.katakri-vuosikello__neljannes{min-width:0;overflow-wrap:anywhere}
.katakri-vuosikello__jaksot{list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:var(--space-3)}
.katakri-vuosikello__jakso{display:flex;flex-direction:column;gap:var(--space-2);min-width:0}
/* Sarakkeen radan alaraja on 0 (`minmax(0,1fr)`), mutta rata ei estä
   katkeamatonta sisältöä: merkki ja painike ovat muualla `white-space:nowrap`,
   eikä `overflow-wrap:anywhere` koske niihin — se purkaa sanan, ei kiellettyä
   rivinvaihtoa. Mitattuna 1024 px:ssä sarake on 157 px ja painikkeen sisäleveys
   75 px, ja nimike on nowrapilla 87,3 px (fi), 127,4 px (sv) ja 90,8 px (en):
   jokaisen kolmen kielen nimike vuotaisi laatikostaan
   (docs/ui/kierros-8/mittaus-5a4afb25/). Ruutu päästää molemmat katkeamaan;
   sama kuvio kuin ajautumarivillä ja dokumenttitaulukolla. Painikkeen korkeus
   on `auto`, koska kahdelle riville katkeava teksti ei mahdu 40 px:n
   laatikkoon. */
.katakri-vuosikello__jakso .katakri-merkki{white-space:normal}
.katakri-vuosikello__jakso .katakri-painike{white-space:normal;height:auto;
  min-height:40px;padding:var(--space-2) var(--space-4);text-align:center}

/* ---------------------------------------------------------------------------
 * Riskit-näkymä — otsake, suodatinrivi, matriisi, selite ja riskitaulukko
 * ------------------------------------------------------------------------- */
/* Vain `riskit.html`:n luokkia, joten mitat ovat tässä paikallaan. Mitat on
 * luettu kierroksen 8 prototyypistä (`design/Kierros 8.dc.html`, näyttö 1) ja
 * luovutuskuvasta `docs/ui/kierros-8/kuvat/p15-1-riskit.png`; värit, kulmat ja
 * välistys ovat Apex 2.2:n tokeneita (`tokens.css`).
 *
 * Sivun oma kiinnike on `.katakri-riskinakyma`, jotta nämä säännöt eivät yllä
 * muihin näkymiin: `.katakri-kortti`, `.katakri-merkki` ja `.katakri-painike`
 * ovat sovelluksen yhteisiä komponentteja, ja vain niiden sijoittelu on
 * tässä. */
/* Lohkojen pystyväli on 18px — prototyypin oma mitta (`gap:18px` sivun
 * pystypinossa, `design/Kierros 8.dc.html`). Ei 4px-askeleella, joten
 * literaali: 16px siirtäisi ohjeraidan, suodatinrivin ja kortit kuvasta
 * ylöspäin, ja virhe kasvaisi joka lohkolla. */
.katakri-riskinakyma{gap:18px}
.katakri-riskinakyma .katakri-murupolku{margin-bottom:0}

/* Otsake: otsikko ja yksi rivi, jolla lähde, vienti, keruuaika ja
   "vain luku". Otsakkeen jälkeen on lohkovälin lisäksi oma väli (Apexin
   `.page-head{margin-bottom}`): ilman sitä ohjeraita nousisi kuvasta 16px
   ylös ja veisi koko sivun loppuosan mukanaan. */
.katakri-riskinakyma__otsake{display:flex;flex-direction:column;gap:var(--space-2);
  margin-bottom:var(--space-4)}
.katakri-riskinakyma__otsake h1{margin:0}
.katakri-riskinakyma__meta{display:flex;flex-wrap:wrap;gap:0 var(--space-2);
  margin:0;padding:0;list-style:none;
  font-size:var(--text-body-sm);line-height:1.45;color:var(--ink-3)}
/* Erotin on sisällön oma merkki eikä elementti: rivi on yksi lause, ja
   kahdesta lähteestä luettuna erottimen pitää tulla rivin omasta rakenteesta
   eikä templaten toistamasta pisteestä. */
.katakri-riskinakyma__meta li + li::before{content:"· ";color:var(--ink-4)}
/* Lähteen sisäinen erotin on sama merkki samalla sävyllä kuin lähteiden
   välinen, jotta rivi luetaan yhtenä lauseena. */
.katakri-riskinakyma__erotin{color:var(--ink-4)}

/* Ohjeraita (Apexin NoteStrip): neutraali, ei tilailmoitus. */
.katakri-riskinakyma__ohjeraita{margin:0;padding:10px var(--space-4);
  background:var(--sunken);border-radius:var(--radius-md);
  font-size:var(--text-body-sm);line-height:1.45;color:var(--ink-3)}

/* Suodatinrivi: tiivis ja vaakasuora, määrä oikeassa reunassa. */
.katakri-riskisuodatin{display:flex;flex-wrap:wrap;align-items:flex-end;
  gap:var(--space-3) var(--space-5)}
.katakri-riskisuodatin__kentta{display:flex;flex-direction:column;gap:var(--space-1)}
.katakri-riskisuodatin__kentta label{font-size:var(--text-caption);
  font-weight:var(--weight-semibold);line-height:1.35;color:var(--ink-3)}
.katakri-riskisuodatin__kentta select{height:34px;min-width:150px}
/* Omistajavalikko on leveämpi kuin vaatimusvalikko (prototyypin 170 px):
   siinä lukee nimi, vaatimusvalikossa tunnus. */
.katakri-riskisuodatin__kentta--omistaja select{min-width:170px}
.katakri-riskisuodatin__laheta{height:34px;padding:0 var(--space-3);
  font-size:var(--text-body-sm)}
/* Rajavalinta on linkki, ei painike: valinta vaikuttaa heti ilman skriptiä
   (ks. riskit.html, kohta 4). Päällä se on Apexin `.chip.neg`in täysi pari —
   `--neg` pohjana ja valkoinen teksti — jotta päällä olevan rajauksen näkee
   ilman, että taulukkoa vertaa määrään. */
.katakri-riskinakyma .katakri-riskisuodatin__raja{display:inline-flex;align-items:center;gap:var(--space-2);
  height:34px;padding:0 var(--space-3);border-radius:var(--radius-md);
  border:var(--border-hairline) solid var(--border-control);
  background:var(--surface-card);color:var(--ink-1);
  font-size:var(--text-body-sm);font-weight:var(--weight-semibold);
  line-height:1;text-decoration:none;white-space:nowrap}
.katakri-riskinakyma .katakri-riskisuodatin__raja:hover{background:var(--surface-sunken);
  color:var(--ink-1);text-decoration:none}
.katakri-riskinakyma .katakri-riskisuodatin__raja[data-paalla="kylla"]{background:var(--neg);
  border-color:var(--neg);color:var(--on-shell)}
.katakri-riskinakyma .katakri-riskisuodatin__raja[data-paalla="kylla"]:hover{color:var(--on-shell);
  filter:brightness(1.08)}
/* Laskuri on koko taulukon huomioiden määrä. Erotin on CSS:n oma merkki,
   jotta luku on templatessa yksi arvo eikä lauseen osa. */
.katakri-riskisuodatin__laskuri{font-family:var(--font-mono);
  font-weight:var(--weight-bold)}
.katakri-riskisuodatin__laskuri::before{content:"· ";font-family:var(--font-sans);
  font-weight:var(--weight-regular)}
.katakri-riskisuodatin__maara{margin-left:auto;font-size:var(--text-caption);
  font-weight:var(--weight-medium);color:var(--ink-3);white-space:nowrap}

/* Kaksi palstaa: matriisi vasemmalla, selite ja huomio oikealla. Matriisin
   palsta on kiinteä perusleveys ja oikea palsta joustaa — kapealla näytöllä
   ne pinoutuvat, eikä kumpikaan vieritä sivua vaakasuunnassa. */
.katakri-riskinakyma__palstat{display:flex;flex-wrap:wrap;gap:var(--space-5);
  align-items:flex-start}
.katakri-riskinakyma__matriisikortti{flex:0 1 520px;min-width:min(100%,440px)}
.katakri-riskinakyma__sivupalsta{flex:1 1 280px;min-width:0;
  display:flex;flex-direction:column;gap:var(--space-3)}

/* Kortin otsake: nimi ja alaotsikko, erottimena kortin oma hiusviiva. */
.katakri-riskinakyma__kortinotsake{padding:var(--space-4) 18px;
  border-bottom:var(--border-hairline) solid var(--border-divider)}
.katakri-riskinakyma__kortinotsake h2{margin:0;font-size:var(--text-h4);
  line-height:1.35;color:var(--ink-1)}
.katakri-riskinakyma__kortinotsake p{margin:2px 0 0;font-size:var(--text-body-sm);
  line-height:1.4;color:var(--ink-3)}
.katakri-riskinakyma__matriisi{padding:var(--space-4) 18px 14px}

/* Selitekortti ja huomiobanneri. */
.katakri-riskinakyma__selite{margin:0;padding:var(--space-4) 18px;list-style:none;
  display:flex;flex-direction:column;gap:10px;
  font-size:var(--text-caption);line-height:1.45;color:var(--ink-2)}
.katakri-riskinakyma__selite li{display:flex;align-items:center;gap:10px}
.katakri-riskinakyma__selite .katakri-riskimatriisi__piste{margin:0;flex:none}
/* Haamupainike on <a>, ja `.katakri-poikkeamanakymat a` (0,1,1) voittaisi
   `.katakri-painike--haamu`n (0,1,0). Sivun oma kiinnike nostaa sen takaisin. */
.katakri-riskinakyma .katakri-painike--haamu{color:var(--ink-2)}
.katakri-riskinakyma .katakri-painike--haamu:hover{color:var(--ink-1)}
/* Rajan kuvio on sama porras kuin matriisissa: 2 px `ink-1` vasemmalla ja
   alhaalla, `sunken` pohjana. Kirjoitettu kuvioksi eikä kuvaksi, jotta se
   seuraa samoja tokeneita kuin matriisin ruutu. */
.katakri-riskinakyma__selitekuvio{flex:none;width:30px;height:14px;
  background:var(--sunken);border-left:2px solid var(--ink-1);
  border-bottom:2px solid var(--ink-1)}
.katakri-riskinakyma__banneri{display:flex;align-items:flex-start;gap:10px;
  padding:var(--space-3) var(--space-4);
  background:var(--warn-soft);border:var(--border-hairline) solid var(--accent2-border);
  border-radius:var(--radius-md);color:var(--ink-1)}
.katakri-riskinakyma__banneri .katakri-ikoni{margin-top:2px;color:var(--accent2-ink)}
.katakri-riskinakyma__banneri b{display:block;font-size:var(--text-body-sm);
  font-weight:var(--weight-semibold);line-height:1.4}
.katakri-riskinakyma__banneri p{margin:2px 0 0;font-size:var(--text-body-sm);
  line-height:1.5;color:var(--accent2-ink)}

/* Riskitaulukon kortti on täysleveä ja sen taulukko ulottuu kortin reunoihin:
   `--tyhja` poistaa kortin oman reunuksen, ja solut tuovat sen takaisin. */
.katakri-riskinakyma__taulukkokortti{width:100%}
.katakri-riskinakyma__vieritys{overflow-x:auto;overflow-y:hidden}
.katakri-riskinakyma__tyhja{display:flex;flex-direction:column;gap:6px;
  padding:22px 18px;border-top:var(--border-hairline) solid var(--border-divider)}
.katakri-riskinakyma__tyhja b{font-size:var(--text-h4);font-weight:var(--weight-semibold);
  line-height:1.4;color:var(--ink-1)}
.katakri-riskinakyma__tyhja p{margin:0;font-size:var(--text-body-sm);
  line-height:1.45;color:var(--ink-3)}
.katakri-riskinakyma__tyhjakortti{display:flex;flex-direction:column;
  align-items:flex-start;gap:10px;padding:26px var(--space-6)}
.katakri-riskinakyma__tyhjakortti h2{margin:0;font-size:var(--text-h4)}
.katakri-riskinakyma__tyhjakortti p{margin:0;max-width:640px;
  font-size:var(--text-body-sm);line-height:1.5;color:var(--ink-2)}
.katakri-riskinakyma__tyhjakuvake{display:grid;place-items:center;
  width:40px;height:40px;border-radius:var(--radius-pill);
  background:var(--sunken);color:var(--ink-3)}

/* ---- Riskimatriisi — 5 × 5, hyväksyntäraja porrasviivana ----
 *
 * RAJAVIIVA PIIRRETÄÄN RUUDUN REUNANA, EI OMANA ELEMENTTINÄÄN. Raja kulkee
 * portaana ruutujen välistä, ja sen paikka seuraa raja-arvoa: ruutu tietää
 * itse, onko sen vasen tai alapuolinen naapuri rajan toisella puolen
 * (`views/risks.py::MatrixCell.edge_left`, `edge_bottom`). Päälle piirretty
 * viiva vaatisi absoluuttisen sijoittelun ja tiedon ruudun mitoista, ja se
 * osuisi väärään kohtaan heti kun konfiguraatio asettaa toisen rajan.
 *
 * Rajan yläpuolinen alue on `--sunken`, eli sama upotettu pinta kuin muilla
 * taustoitetuilla alueilla. Väri ei kanna merkitystä yksin: ruudussa lukee
 * riskitulo koneluettavana (`data-riskitulo`, `data-yli`) ja näkyvänä lukuna,
 * ja pisteessä riskitunnus tekstinä.
 *
 * Akselit: vakavuus kasvaa ylöspäin (rivit) ja todennäköisyys oikealle
 * (sarakkeet). Suunta tulee lukukerrokselta (`RiskRegister.matrix`), ja
 * akselitekstit ovat taulukon alla samassa järjestyksessä kuin kuvassa. */
.katakri-riskimatriisi{width:100%;table-layout:fixed;border-collapse:collapse}
.katakri-riskimatriisi__sarake--akseli{width:26px}
.katakri-riskimatriisi__akseli{padding:0;background:none;border:0;
  text-align:center;vertical-align:middle;
  font-family:var(--font-mono);font-size:11px;font-weight:var(--weight-medium);
  line-height:14px;color:var(--ink-4)}
.katakri-riskimatriisi tfoot .katakri-riskimatriisi__akseli{padding-top:6px;
  border-top:var(--border-hairline) solid var(--line-1)}
.katakri-riskimatriisi__ruutu{position:relative;height:62px;padding:5px;
  vertical-align:top;min-width:0;overflow-wrap:anywhere;background:var(--card);
  border-right:var(--border-hairline) solid var(--line-1);
  border-top:var(--border-hairline) solid var(--line-1);
  border-bottom:var(--border-hairline) solid transparent}
.katakri-riskimatriisi__ruutu--yli{background:var(--sunken)}
.katakri-riskimatriisi__ruutu--raja-vasen{border-left:2px solid var(--ink-1)}
.katakri-riskimatriisi__ruutu--raja-ala{border-bottom:2px solid var(--ink-1)}
.katakri-riskimatriisi__pisteet{display:flex;flex-wrap:wrap;align-content:flex-start;
  gap:var(--space-1)}
/* Riskitulo on ruudun oikeassa alakulmassa, eikä se vie tilaa pisteiltä. */
.katakri-riskimatriisi__tulo{position:absolute;right:5px;bottom:3px;
  font-family:var(--font-mono);font-size:10px;line-height:12px;color:var(--ink-4)}
/* Akselitekstit: vakavuus vasemmalla, todennäköisyys oikealla, matriisin alla.
   Vasen reunus on akselisarakkeen leveys, jotta teksti alkaa ruudukon
   vasemmasta reunasta eikä rivinimikkeen kohdalta. */
.katakri-riskimatriisi__akselit{display:flex;justify-content:space-between;
  margin:6px 0 0;padding-left:26px;font-size:var(--text-overline);
  font-weight:var(--weight-semibold);line-height:1.3;color:var(--ink-3)}
/* Piste on linkki, ja sen tunnus on aina luettavissa: merkki ilman tekstiä
   katoaisi mustavalkotulosteesta ja ruudunlukijalta. Huomiotilan piste on
   täytetty `neg`, hyväksytty saa `ink-2`-kehyksen ja rajan alle jäävä
   `line-2`-kehyksen (docs/ui/kierros-8/README.md, §6). */
.katakri-riskinakyma .katakri-riskimatriisi__piste{display:inline-block;
  padding:1px var(--space-2);border-radius:var(--radius-pill);
  font-family:var(--font-mono);font-size:11px;font-weight:var(--weight-bold);
  line-height:16px;border:var(--border-hairline) solid var(--line-2);
  background:var(--card);color:var(--ink-3);text-decoration:none}
.katakri-riskinakyma .katakri-riskimatriisi__piste:hover{text-decoration:none}
.katakri-riskinakyma .katakri-riskimatriisi__piste--hyvaksytty{border-color:var(--ink-2);color:var(--ink-1)}
.katakri-riskinakyma .katakri-riskimatriisi__piste--huomio{border-color:var(--neg);
  background:var(--neg);color:var(--on-shell)}

/* ---- Riskitaulukko ----
 * Sarakeleveydet ovat `<colgroup>`issa ja mitat prototyypistä. Taulukolla on
 * vähimmäisleveys, jotta kapealla näytöllä vieritetään KORTIN sisällä
 * (`__vieritys`) eikä koko sivua. */
.katakri-riskitaulukko{width:100%;min-width:1000px;border-collapse:collapse;
  table-layout:fixed}
.katakri-riskitaulukko__sarake--id{width:72px}
.katakri-riskitaulukko__sarake--vaatimukset{width:122px}
.katakri-riskitaulukko__sarake--tulo{width:132px}
.katakri-riskitaulukko__sarake--kehitys{width:122px}
.katakri-riskitaulukko__sarake--omistaja{width:152px}
.katakri-riskitaulukko__sarake--jaannos{width:202px}
.katakri-riskitaulukko th{padding:9px var(--space-2);background:var(--sunken);
  text-align:left;vertical-align:middle;
  font-size:10.5px;font-weight:var(--weight-bold);line-height:14px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.katakri-riskitaulukko td{padding:10px var(--space-2);vertical-align:middle;
  border-top:var(--border-hairline) solid var(--line-1);
  font-size:var(--text-body-sm);line-height:1.45;color:var(--ink-2);
  overflow-wrap:anywhere}
.katakri-riskitaulukko th:first-child,
.katakri-riskitaulukko td:first-child{padding-left:18px}
.katakri-riskitaulukko th:last-child,
.katakri-riskitaulukko td:last-child{padding-right:18px}
.katakri-riskitaulukko td[data-testid="riskin-uhka"]{color:var(--ink-1);text-wrap:pretty}
/* Huomiorivin tausta on `accent-softer` (kierros 8, README §6). Väri ei kanna
   merkitystä yksin: rivillä on merkki "Yli rajan" ja `data-huomio`. */
.katakri-riskitaulukko__rivi--huomio{background:var(--accent-softer)}
.katakri-riskinakyma .katakri-riskitaulukko__tunnus a{font-family:var(--font-mono);
  font-size:12.5px;font-weight:var(--weight-bold);line-height:18px;
  color:var(--ink-1);text-decoration:none}
.katakri-riskinakyma .katakri-riskitaulukko__tunnus a:hover{text-decoration:underline}
.katakri-riskitaulukko__vaatimukset{display:flex;flex-wrap:wrap;gap:var(--space-1)}
.katakri-riskinakyma .katakri-riskitaulukko__vaatimus{font-family:var(--font-mono);font-size:12px;
  font-weight:var(--weight-medium);line-height:18px;padding:0 6px;
  border:var(--border-hairline) solid var(--line-2);border-radius:var(--radius-xs);
  background:var(--card);color:var(--ink-1);text-decoration:none}
.katakri-riskinakyma .katakri-riskitaulukko__vaatimus:hover{text-decoration:none;background:var(--sunken)}
.katakri-riskitaulukko__tulo{font-family:var(--font-mono);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.katakri-riskitaulukko__tulo b{font-weight:var(--weight-black);color:var(--ink-1)}
.katakri-riskitaulukko__kehitys{white-space:nowrap}
.katakri-riskitaulukko__kehityskuvake{margin-right:6px}
.katakri-riskitaulukko__kehityskuvake--kasvava{color:var(--neg)}
.katakri-riskitaulukko__kehityskuvake--laskeva{color:var(--pos)}
.katakri-riskitaulukko__kehityskuvake--ennallaan{color:var(--ink-4)}
/* Merkit ovat solun SISÄLLÄ olevassa kääreessä eivätkä solussa itsessään:
   `display:flex` solulla pudottaisi sen taulukon asettelusta, ja rivin
   sarakkeet eivät enää osuisi otsikkoriviin. */
.katakri-riskitaulukko__merkit{display:flex;flex-wrap:wrap;gap:6px;
  align-items:center}
.katakri-riskitaulukko__merkit .katakri-merkki{white-space:nowrap}

/* ---------------------------------------------------------------------------
 * Etusivu (3b) — porautumiskortit
 * ------------------------------------------------------------------------- */
/* Porautumiskortit ovat vain etusivun luokkia (`index.html`), joten Apexin
   pinta, viiva, varjo ja liike ovat tassa eivatka sivun kiinnikkeen takana.
   Korotus on `--sh-card` ja nosto `--sh-pop`: Apexin `.card` kayttaa
   edellista, ja jalkimmainen on sen asteikon seuraava askel. */
.katakri-porautumiset{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--space-4)}
.katakri-porautumiskortti{display:flex;flex-direction:column;gap:14px;padding:22px;
  background:var(--card);border:var(--border-hairline) solid var(--line-1);
  border-top:3px solid var(--accent);border-radius:var(--radius-lg);box-shadow:var(--sh-card);
  color:inherit;text-decoration:none;
  transition:transform var(--duration-base) var(--ease-standard),box-shadow var(--duration-base) var(--ease-standard)}
.katakri-porautumiskortti:hover{transform:translateY(-2px);box-shadow:var(--sh-pop);text-decoration:none;color:inherit}
.katakri-porautumiskortti__ylaosa{display:flex;align-items:center;gap:10px}
.katakri-porautumiskortti__kuvake{width:32px;height:32px;border-radius:var(--radius-md);
  background:var(--accent-soft);color:var(--accent-ink);display:inline-flex;
  align-items:center;justify-content:center;flex:none}
.katakri-porautumiskortti__nimi{flex:1;font-family:var(--font-sans);font-size:var(--text-h4);
  font-weight:var(--weight-semibold);line-height:1.2;color:var(--ink-1)}
.katakri-porautumiskortti__nuoli{color:var(--ink-4)}
.katakri-porautumiskortti__arvo{font-family:var(--font-sans);font-size:var(--text-display-md);
  font-weight:var(--weight-bold);line-height:1;letter-spacing:var(--tracking-tight);color:var(--ink-1)}
.katakri-porautumiskortti__huomio{font-size:var(--text-caption);line-height:1.45;color:var(--ink-3)}
/* Kortin sisäinen otsikkorivi: otsikko + merkki/määrä samalla rivillä (lisätty ytimessä). */
.katakri-otsikkorivi{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap}
.katakri-otsikkorivi h2,.katakri-otsikkorivi h3{flex:1;min-width:0}
.katakri-maara{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--text-hint)}
/* Sivun alalaidan lähde- ja kielirivi (lisätty ytimessä). Vain etusivulla,
   joten Apexin `--ink-4` on tassa eika sivun kiinnikkeen takana. */
.katakri-sivun-alaosa{display:flex;flex-direction:column;gap:var(--space-1);
  font-size:var(--text-caption);color:var(--ink-4)}

/* ---------------------------------------------------------------------------
 * Yhteinen: valintapalkki (ajautuma, kuittaukset). GET-lomake.
 * ------------------------------------------------------------------------- */
.katakri-valintapalkki{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--space-3);
  padding:var(--space-4) 18px;background:var(--surface-card);
  border:var(--border-hairline) solid var(--border-divider);border-radius:var(--radius-lg)}
/* Ohjeteksti on vain ajautuman valintapalkissa (`ajautuma.html`), joten Apexin
   `--ink-3` on tässä paikallaan. Palkin oma pinta ja reunus ovat kiinnikkeen
   takana: `.katakri-valintapalkki` on kolmella muulla sivulla. */
.katakri-valintapalkki__ohje{flex:1 1 240px;padding-bottom:9px;font-size:var(--text-caption);
  line-height:1.4;color:var(--ink-3)}
.katakri-valintapalkki__maarat{flex:1 0 auto;text-align:right;white-space:nowrap;
  font-size:var(--text-caption);color:var(--text-label)}

/* ---------------------------------------------------------------------------
 * Ajautuma (3c). LUKITTU — ajautuma.html, _ajautumataulukko.html
 * ------------------------------------------------------------------------- */
.katakri-ajautuma{display:grid;grid-template-columns:minmax(0,1fr) var(--katakri-v2-sivupaneeli);
  gap:var(--space-5);align-items:start}

/* Mittauksen tila. Kaksi muunnosta EIVÄT saa näyttää samalta:
 * --mitattu on neljän solun tilarivi, --ei-mitattu katkoviivainen varoitus.
 *
 * Apex 2.2 (tehtävä 08decf84). Tästä alkava lohko aina `.katakri-jakauma*`:iin
 * asti on ajautumanäkymän omaa nimiavaruutta — jokainen alla vaihdettu luokka
 * esiintyy VAIN `ajautuma.html`:ssä tai `_ajautumataulukko.html`:ssä — joten
 * Apexin arvot ovat tässä paikallaan eivätkä sivun kiinnikkeen takana. Kaksi
 * poikkeusta ovat kiinnikkeellä tiedoston lopussa: `.katakri-ajautumarivi__laji`
 * renderöityy myös `perustila.html`:ssä ja `.katakri-ajautumataulukko` on sen
 * taulukon luokka. Vaihdettuja ovat vain väri-, varjo- ja reunavärit; välistys,
 * kulmat ja typografia käyttävät ytimen omaa asteikkoa kuten tehtävissä
 * 72ca7e29, 2e372620 ja 38ecf4bb. Asteikot eivät yhdistyneet, kun
 * Meshly-lohko poistui (teht. 24cd5d6c); ks. tokens.css:n lohko-otsikot.
 *
 * Mittarin kortti on Apexin `.card`: `--card` + `--line-1` + `--sh-card`. */
.katakri-mittaustila{display:grid;grid-template-columns:minmax(0,1.3fr) repeat(3,minmax(0,1fr));
  background:var(--card);border:var(--border-hairline) solid var(--line-1);
  border-radius:var(--radius-lg);box-shadow:var(--sh-card)}
.katakri-mittaustila__solu{display:flex;flex-direction:column;gap:6px;padding:18px var(--space-5);
  border-right:var(--border-hairline) solid var(--line-1)}
.katakri-mittaustila__solu:last-child{border-right:0}
/* Määrien ryhmä on vain `data-testid="ajautuman-maarat"` -tunnisteen kantaja:
 * kolme solua ovat ruudukon omia sarakkeita, joten ryhmä ei saa olla oma
 * ruudukkokohta. `display:contents` pitää tunnisteen ja asettelun yhdessä. */
.katakri-mittaustila__maarat{display:contents}
.katakri-mittaustila__nimike{font-size:var(--text-caption);color:var(--ink-3)}
.katakri-mittaustila__arvo{font-family:var(--font-sans);font-size:var(--text-h2);
  font-weight:var(--weight-bold);line-height:1;color:var(--ink-1)}
/* Ajautuneiden ja perustilan mukaisten luvut ovat Apexin tilavärit. Luku on
   iso ja yksin pohjallaan, joten se saa täyttövärin (`--neg`/`--pos`) eikä
   pehmeän parin tekstisävyä (`--neg-ink`/`--pos-ink`), jota Apex käyttää
   `.chip`-pohjan päällä. */
.katakri-mittaustila__arvo--ajautunut{color:var(--neg)}
.katakri-mittaustila__arvo--mukainen{color:var(--pos)}
.katakri-mittaustila__tila{display:flex;align-items:center;gap:var(--space-2);
  font-size:var(--text-caption);font-weight:var(--weight-semibold);color:var(--pos)}
.katakri-mittaustila__tila::before{content:"";width:8px;height:8px;border-radius:var(--radius-pill);background:var(--pos)}
/* Mittaamaton = Apexin `.banner.warn` katkoviivalla: `--accent2-soft`-pohja ja
   `--accent2-ink`-teksti. Reuna on `--warn` eikä `--accent2-border`, koska
   katkoviiva on tämän muunnon ainoa muotoero mitattuun nähden ja häviäisi
   pehmeällä sävyllä. */
.katakri-mittaustila--ei-mitattu{display:flex;gap:14px;align-items:flex-start;padding:18px var(--space-5);
  background:var(--accent2-soft);border:var(--border-hairline) dashed var(--warn);box-shadow:none}
.katakri-mittaustila--ei-mitattu .katakri-mittaustila__otsikko{font-weight:var(--weight-semibold);color:var(--ink-1)}
.katakri-mittaustila--ei-mitattu p{font-size:var(--text-body-sm);line-height:1.55;color:var(--accent2-ink)}

/* Luokkamerkki osion otsikossa: neliö, ei piste — erottuu tilapisteestä.
   Neutraali on Apexin kontrolliviiva `--line-2`, vaikuttava tilaväri `--neg`. */
.katakri-luokkamerkki{width:10px;height:10px;border-radius:2px;flex:none;background:var(--line-2)}
.katakri-luokkamerkki--vaikuttaa{background:var(--neg)}

/* Ajautumarivi: viisi raidetta. Muutostietue-raide on kiinteä, koska merkki on nowrap. */
.katakri-ajautumataulukko{width:100%}
.katakri-ajautumarivi,.katakri-ajautumarivi--otsake{display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.3fr) minmax(0,1.3fr) var(--katakri-v2-muutostietue) var(--katakri-v2-kontrollit);
  gap:14px;align-items:start;padding:13px var(--space-5);border-bottom:var(--border-hairline) solid var(--line-1)}
/* Otsake- ja solurivi ovat Apexin `.tbl`: otsake `--sunken` + `--ink-3`,
   erotin `--line-1`, kohteen nimi `--ink-1` (`.tbl .name`). */
.katakri-ajautumarivi--otsake{padding:10px var(--space-5);background:var(--sunken);
  font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-semibold);
  line-height:1;letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--ink-3)}
.katakri-ajautumarivi__kohde{font-family:var(--font-mono);font-size:var(--text-body-sm);
  font-weight:var(--weight-medium);color:var(--ink-1);overflow-wrap:anywhere}
/* Lajiteksti EI ole tässä Apexissa: `.katakri-ajautumarivi__laji` renderöityy
   myös `perustila.html`:ssä, jolla on oma migraatiotehtävänsä. Sen Apex-arvo
   on tiedoston lopun kiinnikelohkossa. */
.katakri-ajautumarivi__laji{font-size:var(--text-caption);color:var(--text-hint)}
/* Taulukko säilyy semanttisena (role-attribuutit), rivi piirretään gridinä. */
.katakri-ajautumataulukko,.katakri-ajautumataulukko thead,.katakri-ajautumataulukko tbody{display:block;border-collapse:collapse}
.katakri-ajautumataulukko th{text-align:left;font:inherit;letter-spacing:inherit;padding:0;min-width:0;overflow-wrap:anywhere;hyphens:auto}
.katakri-ajautumataulukko td{padding:0;min-width:0;display:flex;flex-direction:column;gap:var(--space-1)}
.katakri-ajautumarivi:last-child{border-bottom:0}
.katakri-ajautumarivi td[data-testid="rivin-kontrollit"]{flex-direction:row;flex-wrap:wrap}
.katakri-ajautumarivi .katakri-merkki{white-space:normal}

/* Arvopari luetaan yhtenä muutoksena: ennen yliviivattuna, nyt korostettuna.
   Musteet ovat tehtävän 08decf84 antama pari `--ink-2`/`--ink-3`: nykyinen
   arvo on tummempi (`--ink-2`) ja perustilan arvo vaaleampi (`--ink-3`), joten
   pari erottuu myös ilman yliviivausta. Nykyisen arvon kehys on Apexin
   `.banner.info`-pari `--accent-softer` + `--accent-soft`, ja nuoli on
   `--accent`: se on tämän rivin ainoa siirtymän merkki. */
.katakri-arvopari{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-width:0}
.katakri-arvopari__ennen{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--ink-3);
  background:var(--sunken);padding:3px 6px;border-radius:var(--radius-xs);
  text-decoration:line-through;text-decoration-color:var(--line-2);overflow-wrap:anywhere}
.katakri-arvopari__nyt{font-family:var(--font-mono);font-size:var(--text-caption);font-weight:var(--weight-semibold);
  color:var(--ink-2);background:var(--accent-softer);border:var(--border-hairline) solid var(--accent-soft);
  padding:2px 6px;border-radius:var(--radius-xs);overflow-wrap:anywhere}
.katakri-arvopari__nuoli{color:var(--accent)}

.katakri-muutostietue{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--ink-2)}
.katakri-muutostietue--puuttuu{font-family:var(--font-sans);font-weight:var(--weight-semibold);color:var(--neg)}

/* Kontrollisiru EI ole tässä Apexissa: se renderöityy myös
   `_paatoslokimerkinta.html`:ssä. Apex-arvo on tiedoston lopun lohkossa. */
.katakri-kontrollisiru{font-family:var(--font-mono);font-size:var(--text-caption);font-weight:var(--weight-semibold);
  line-height:1;padding:4px 6px;border:var(--border-hairline) solid var(--accent-halo);
  border-radius:var(--radius-xs);background:var(--surface-card)}

/* Palautettu tila ja kontrolleittain -jakauma (sivupaneeli). Tietopari on
   Apexin `.row`: erotin `--line-1`, nimi `--ink-3`, arvo `--ink-1`. Jakauman
   ura on `--line-1` ja sen neutraali osa `--line-2`; vaikuttava osa on sama
   tilaväri `--neg` kuin osion luokkamerkissä, jotta palkki ja merkki lukevat
   samaa asteikkoa. */
.katakri-palautettu dl{margin:0;display:flex;flex-direction:column}
.katakri-palautettu div{display:flex;flex-direction:column;gap:3px;padding:9px 0;
  border-bottom:var(--border-hairline) solid var(--line-1)}
.katakri-palautettu dt{font-size:var(--text-caption);color:var(--ink-3)}
.katakri-palautettu dd{margin:0;font-family:var(--font-mono);font-size:var(--text-caption);
  font-weight:var(--weight-medium);color:var(--ink-1);overflow-wrap:anywhere}
.katakri-jakauma{display:grid;grid-template-columns:48px minmax(0,1fr) auto;gap:10px;align-items:center}
.katakri-jakauma__palkki{height:6px;border-radius:var(--radius-pill);background:var(--line-1);overflow:hidden;display:flex}
.katakri-jakauma__vaikuttaa{background:var(--neg)}
.katakri-jakauma__muu{background:var(--line-2);flex:1}
.katakri-jakauma__vaikuttaa--0{width:0%}
.katakri-jakauma__vaikuttaa--1{width:10%}
.katakri-jakauma__vaikuttaa--2{width:20%}
.katakri-jakauma__vaikuttaa--3{width:30%}
.katakri-jakauma__vaikuttaa--4{width:40%}
.katakri-jakauma__vaikuttaa--5{width:50%}
.katakri-jakauma__vaikuttaa--6{width:60%}
.katakri-jakauma__vaikuttaa--7{width:70%}
.katakri-jakauma__vaikuttaa--8{width:80%}
.katakri-jakauma__vaikuttaa--9{width:90%}
.katakri-jakauma__vaikuttaa--10{width:100%}
.katakri-jakaumalista{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-2)}
.katakri-jakauma--kohde{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) auto}
.katakri-palautettu__vaitteet{list-style:none;margin:var(--space-3) 0 0;padding:0;display:flex;flex-direction:column;gap:var(--space-2)}
.katakri-palautettu__vaitteet li{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
.katakri-kortti__tyhjateksti{padding:var(--space-5) var(--space-6);font-size:var(--text-body-sm);color:var(--text-label)}
.katakri-huomio--varoitus{background:var(--warn-soft);border-color:var(--accent2-border);color:var(--ink-1)}
/* Huomautus = Apexin `.banner.warn`. Oma muunnoksensa `--varoitus`in rinnalla,
   koska kirjausnäkymillä `--varoitus` on `.banner.neg`: siellä se on
   validointivirhe, joka esti kirjauksen. Aluetyypin huomautus ei estä mitään
   — kirjaus menee läpi — eikä punainen virhelaatikko kertoisi sitä. */
.katakri-huomio--huomautus{background:var(--accent2-soft);border-color:var(--accent2-border);
  color:var(--accent2-ink)}

/* Priorisoija. LUKITTU — _priorisoija.html
   Apex 2.2 (tehtävä 72ca7e29): huomautus on Apexin `.banner.warn` (toinen
   aksentti), sija aksenttina `.pop-i.user-pick.on`:n tapaan, erottimet
   `--line-1`. */
.katakri-priorisoija__huomautus{padding:10px var(--space-3);background:var(--accent2-soft);
  border-radius:var(--radius-md);font-size:var(--text-caption);font-weight:var(--weight-medium);
  line-height:1.45;color:var(--accent2-ink)}
.katakri-priorisoija__jarjestys{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--space-2)}
.katakri-priorisoija__kohta{display:grid;grid-template-columns:32px minmax(0,220px) minmax(0,1fr);gap:var(--space-3);
  align-items:baseline;padding:10px var(--space-3);border:var(--border-hairline) solid var(--line-1);border-radius:var(--radius-md)}
.katakri-priorisoija__sija{font-family:var(--font-mono);font-size:var(--text-h4);font-weight:var(--weight-bold);
  line-height:1;color:var(--accent)}
.katakri-priorisoija__jaljitys{margin:0;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--space-3);
  padding-top:var(--space-3);border-top:var(--border-hairline) solid var(--line-1)}
.katakri-priorisoija__jaljitys dt{font-size:var(--text-caption);color:var(--ink-3)}
.katakri-priorisoija__jaljitys dd{margin:0;font-family:var(--font-mono);font-size:var(--text-caption);
  font-weight:var(--weight-medium);color:var(--ink-1);overflow-wrap:anywhere}
/* Pois käytöstä: sama kehysero kuin agenttipaneelissa (katkoviiva + harmaa).
   Luokka EI ole vain priorisoijan: `kuittaukset.html` ja `paatoslokit.html`
   kirjoittavat sen omalle "agenttikerrosta ei ole" -vastaukselleen
   (`data-testid="paatosloki-poissa"`), eivätkä ne olleet tämän tehtävän
   sivuja. Siksi app-laajuinen sääntö jäi silloin Meshly-tokeneihin ja Apexin
   arvo annettiin erikseen priorisoijan oman lohkon sisällä. Tehtävä 24cd5d6c
   käänsi app-laajuisenkin säännön (`--page`, `--border-control`), joten
   säännöt eroavat nyt vain sävyltä: priorisoijan oma on upotettu
   (`--sunken`) ja app-laajuinen sivun pohja. Sama kuvio kuin
   `.katakri-kirjautuminen`illa (päätös 2e305611). Priorisoijan juuri on
   `[data-testid="priorisoija"]` (`_priorisoija.html`), ja koska partiaali on
   lukittu, kiinnike on sen attribuutti eikä uusi luokka. */
.katakri-priorisoija--pois{padding:14px;background:var(--page);border:var(--border-hairline) dashed var(--border-control);
  border-radius:var(--radius-md)}
[data-testid="priorisoija"] .katakri-priorisoija--pois{background:var(--sunken);border-color:var(--line-2)}

/* ---------------------------------------------------------------------------
 * Kuittaukset (3d). LUKITTU — kuittaukset.html, _paatoslokimerkinta.html
 * ------------------------------------------------------------------------- */
/* Kuittaussivu on yksipalstainen ja päätöslokin luettelo on taulukko, joten
 * luovutuksen kaksipalstaista `.katakri-kuittaus`-gridiä, sen 360 px:n
 * `--katakri-v2-kuittauslista`-raidetta eikä `a.katakri-merkintalista__kohta`
 * -linkkiriviä ole täällä: ne olisivat tyyliä ilman merkkausta. Syy on mitattu
 * eikä lykätty (docs/ui/luovutus.md "Poikkeamat luovutuksen ohjeesta"), ja
 * asettelun määritelmä säilyy docs/ui/kierros-3/README.md kohdassa 6.3, josta
 * sen saa takaisin jos kaksipalstaisuus joskus valitaan. */
.katakri-vaitekoodi{font-family:var(--font-mono);font-size:var(--text-caption);font-weight:var(--weight-medium);
  line-height:1;color:var(--ink-2);background:var(--surface-sunken);padding:3px 6px;border-radius:var(--radius-xs)}

/* Apex 2.2 (tehtävä ebc2cfc3). Nämä ovat audit trail -perheen OMIA luokkia:
   `.katakri-merkinta*` ja `.katakri-vastavaite` renderöityvät vain tämän
   tehtävän templateissa (`_paatoslokimerkinta.html`, `_paatoslokilista.html`,
   `locked/_hyvaksyntalista.html`, `locked/_hyvaksyntalomake.html`), joten
   Apexin arvo on tässä paikallaan eikä sivun kiinnikkeen takana. Kiinnikkeen
   saavat vain app-laajuiset komponentit (tiedoston lopun lohko). */
.katakri-merkinta__perustelu{font-size:var(--text-body-lg);font-weight:var(--weight-medium);line-height:1.5;color:var(--ink-1)}
.katakri-merkinta__tiedot{margin:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px var(--space-5)}
.katakri-merkinta__tiedot dt{font-size:var(--text-caption);color:var(--ink-3)}
.katakri-merkinta__tiedot dd{margin:0;font-family:var(--font-mono);font-size:var(--text-caption);
  font-weight:var(--weight-medium);color:var(--ink-1);overflow-wrap:anywhere}
.katakri-merkinta__perusteet{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-3);
  padding-top:14px;border-top:var(--border-hairline) solid var(--line-1)}
.katakri-vastavaite{display:flex;flex-direction:column;gap:6px;padding:10px;border:var(--border-hairline) solid var(--line-1);
  border-left:3px solid var(--line-2);border-radius:var(--radius-md)}
.katakri-vastavaite[data-lopputulos="upheld"]{border-left-color:var(--pos)}
.katakri-vastavaite[data-lopputulos="rebutted"]{border-left-color:var(--neg)}

/* Päätöslokin luettelo pysyy taulukkona: jokaisella sarakkeella on otsikko
 * (test_paatoslokinakyma.py). Lisätty ytimessä; README 6.3 ehdotti linkkilistaa.
 *
 * `table-layout:fixed` on se, mikä pitää taulukon pääosan sisällä. Pelkkä
 * `width:100%` ei pidä: automaattisessa asettelussa `width` häviää sarakkeiden
 * vähimmäisleveyksille, ja kahdeksan katkeamatonta otsikkoa ja ISO-hetki
 * kasvattivat taulukon 1193 px:iin kehyksen 1138 px:n sisällä. Kehyksen
 * `overflow-x` vieritti sisällön, mutta taulukon oma laatikko jäi silti
 * pääosan oikean reunan yli (mitattu Firefoxilla 1440 px:n leveydellä).
 *
 * Kiinteä asettelu tekee katkeamattomasta tekstistä vastaavasti sarakkeensa
 * yli maalautuvaa, joten sarakkeita leveämpi sisältö rivittyy sen sijaan:
 * otsikot ja ISO-hetki ilman `nowrap`ia, solut `overflow-wrap:anywhere`illa.
 * Rivittyminen eikä katkeaminen on suunnittelupaketin ehto
 * (docs/ui/kierros-6/README.md §2), sama ratkaisu kuin ajautumarivillä. */
.katakri-merkintataulu{overflow-x:auto}
.katakri-merkintataulu table{width:100%;border-collapse:collapse;font-size:var(--text-body-sm);table-layout:fixed}
.katakri-merkintataulu th{padding:10px var(--space-4);background:var(--sunken);text-align:left;
  font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-semibold);
  letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--ink-3);overflow-wrap:anywhere}
.katakri-merkintataulu td{padding:var(--space-3) var(--space-4);border-top:var(--border-hairline) solid var(--line-1);
  vertical-align:top;overflow-wrap:anywhere}
.katakri-merkintataulu td[data-testid="rivin-rooli"],.katakri-merkintataulu td[data-testid="rivin-hetki"]{font-family:var(--font-mono);font-size:var(--text-caption);color:var(--ink-3)}
.katakri-merkintataulu tr[aria-current="true"] td{background:var(--accent-soft)}
.katakri-merkintataulu tr[aria-current="true"] td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
.katakri-merkintalista__ajot{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-5) var(--space-6);
  border-top:var(--border-hairline) solid var(--line-1)}
.katakri-ajolista{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-3)}
.katakri-ajolista > li{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);
  border:var(--border-hairline) dashed var(--line-2);border-radius:var(--radius-md);background:var(--sunken)}
.katakri-luettelo{list-style:none;margin:0;padding:0}
.katakri-pinolista--tiivis{gap:var(--space-2)}
.katakri-tiedot-pieni{margin:0;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px var(--space-2);font-size:var(--text-caption)}
.katakri-tiedot-pieni dt{color:var(--text-label)}
.katakri-tiedot-pieni dd{margin:0;font-family:var(--font-mono);color:var(--ink-1);overflow-wrap:anywhere}
.katakri-vastavaite[data-kannanotto="accepted"]{border-left-color:var(--pos)}
.katakri-vastavaite[data-kannanotto="rejected"]{border-left-color:var(--neg)}
.katakri-huomio--neutraali{background:var(--surface-sunken);border-color:var(--border-divider);color:var(--text-label)}
.katakri-merkinta__tiedot > div{display:flex;flex-direction:column;gap:3px;min-width:0}

/* Lomake: numeroidut askeleet 1 valvontapiste -> 2 kannanotto -> 3 perustelu */
.katakri-kuittauslomake{display:flex;flex-direction:column;gap:18px}
.katakri-kuittauslomake fieldset{margin:0;padding:0;border:0;display:flex;flex-direction:column;gap:var(--space-2)}
.katakri-kuittauslomake legend,.katakri-kuittauslomake__nimike{padding:0 0 var(--space-2);
  font-size:var(--text-body-sm);font-weight:var(--weight-semibold);line-height:1;color:var(--text-heading)}
/* Askelnumero Apexin aksentilla paikallaan (tehtävä 02537cdd): luokka on vain
   `kirjaukset.html`:n ja `kuittaukset.html`:n lomakkeilla, eli tämän tehtävän
   näkymissä. */
.katakri-askelnumero{font-family:var(--font-mono);color:var(--accent);margin-right:var(--space-2)}
.katakri-kuittauslomake__ohje{font-size:var(--text-caption);line-height:1.45;color:var(--text-label)}
.katakri-kannanotto{position:relative}

/* Apex 2.2 paikallaan (tehtävä 02537cdd): `.katakri-valvontapiste*` on vain
   `kuittaukset.html`:n lomakkeella. Valittu ruutu on Apexin `.act.pri`:n
   pehmeä pari — `--accent-soft` pohja ja `--accent` reuna — eikä umpiaksentti,
   koska teksti on ruudussa mustetta eikä valkoista. */
.katakri-valvontapisteet{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:var(--space-2)}
.katakri-valvontapiste{display:flex;gap:10px;align-items:flex-start;padding:10px var(--space-3);
  border:var(--border-hairline) solid var(--line-1);border-radius:var(--radius-md);
  background:var(--card);cursor:pointer}
.katakri-valvontapiste:has(input:checked){border-color:var(--accent);background:var(--accent-soft)}
.katakri-valvontapiste input{margin:2px 0 0;accent-color:var(--accent)}
.katakri-valvontapiste__nimi{display:block;font-size:var(--text-body-sm);font-weight:var(--weight-semibold);
  line-height:1.3;color:var(--ink-1)}
.katakri-valvontapiste__koodi{display:block;font-family:var(--font-mono);font-size:var(--text-overline);color:var(--ink-4)}

/* Kannanotto: kolme yhtä leveää segmenttiä. Radio piilotetaan vain visuaalisesti. */
.katakri-kannanotot{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  border:var(--border-hairline) solid var(--border-control);border-radius:var(--radius-md);overflow:hidden}
.katakri-kannanotto{display:flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-3);
  cursor:pointer;background:var(--surface-card);color:var(--ink-2);
  font-size:var(--text-body-sm);font-weight:var(--weight-semibold);line-height:1}
.katakri-kannanotto + .katakri-kannanotto{border-left:var(--border-hairline) solid var(--border-control)}
.katakri-kannanotto input{position:absolute;opacity:0;pointer-events:none}
.katakri-kannanotto:has(input:focus-visible){box-shadow:inset var(--shadow-focus-accent)}
.katakri-kannanotto--accepted:has(input:checked){background:var(--status-pos);color:var(--on-shell)}
.katakri-kannanotto--rejected:has(input:checked){background:var(--status-neg);color:var(--on-shell)}
.katakri-kannanotto--deferred:has(input:checked){background:var(--ink-2);color:var(--on-shell)}

.katakri-tekstialue{width:100%;min-height:88px;padding:10px var(--space-3);border-radius:var(--radius-md);
  border:var(--border-hairline) solid var(--border-control);background:var(--surface-card);
  font-family:var(--font-sans);font-size:var(--text-body-sm);line-height:1.5;color:var(--text-heading);resize:vertical}
.katakri-tekstialue:focus{outline:none;border-color:var(--focus-ring);box-shadow:var(--shadow-focus-accent)}

/* ---------------------------------------------------------------------------
 * Perustila (3e). LUKITTU — perustila.html
 * Apex 2.2 (tehtävä 72ca7e29): rivistö on Apexin `.tbl` — otsakerivi
 * `--sunken`/`--ink-3`, rivin erotin `--line-1`, luku `--ink-1`. Poikkeava
 * poisjääneiden luku on Apexin huomioväri vaalealla (`--warn`); ennen
 * `--amber-600` (#C2780A), nyt #b4741a. Nämä kaksi luokkaa ovat vain tällä
 * sivulla, joten ne migratoituvat paikallaan.
 * ------------------------------------------------------------------------- */
.katakri-perustila{display:grid;grid-template-columns:minmax(0,1fr) var(--katakri-v2-lomakepaneeli);
  gap:var(--space-5);align-items:start}
.katakri-perustilarivi,.katakri-perustilarivi--otsake{display:grid;
  grid-template-columns:minmax(0,1.6fr) 1fr 72px 72px 88px minmax(0,1.4fr);
  gap:14px;align-items:start;padding:15px var(--space-5);border-bottom:var(--border-hairline) solid var(--line-1)}
.katakri-perustilarivi--otsake{padding:var(--space-3) var(--space-5);background:var(--sunken);
  font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-semibold);
  line-height:1;letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--ink-3)}
.katakri-poisjaaneet{font-family:var(--font-mono);font-size:var(--text-body-sm);font-weight:var(--weight-semibold);color:var(--ink-1)}
.katakri-poisjaaneet--nollasta-poikkeava{color:var(--warn)}
.katakri-tiiviste{overflow-wrap:anywhere}
/* Viite (K7-2): lyhennetty asu rivillä, koko polku <details>-lohkossa.
   `partials/_viite.html` on tämän tehtävän template, ja `.katakri-viite*` on
   vain sen luokka — joten Apexin arvo on tässä paikallaan. Partiaali
   renderöityy asiakirjan sivulla (`partials/_dokumentin_tiedot.html`), jonka
   oma migraatio on tehtävä 7a65ed19; kiinnike `.katakri-vaatimukset` ei
   tavoittaisi sitä siellä, eli kiinnikkeen takana sääntö jäisi kuolleeksi.
   Vaihdettavaa on yksi hiusviiva, ja sen Apex-vastine on `--line-1`. */
.katakri-viite{display:inline-block;max-width:100%;vertical-align:top;overflow-wrap:anywhere}
.katakri-viite__polku>summary{cursor:pointer}
.katakri-viite__kansiot{list-style:none;margin:var(--space-2) 0 0;padding:0 0 0 var(--space-3);
  border-left:var(--border-hairline) solid var(--line-1)}
.katakri-viite__kansiot>li{padding:2px 0}
.katakri-viite__polku .katakri-viite__kokonaan{display:block;margin-top:var(--space-2)}
.katakri-perustilarivi:last-child{border-bottom:0}
/* Muuttumattomuuden huomautus (vain perustila.html): Apexin `.banner.warn`. */
.katakri-muuttumattomuus{padding:10px var(--space-3);background:var(--accent2-soft);border-radius:var(--radius-md);
  font-size:var(--text-caption);font-weight:var(--weight-medium);line-height:1.45;color:var(--accent2-ink)}

/* ---------------------------------------------------------------------------
 * Auditointipaketti (3f) — auditointipaketti.html, _auditointipaketti_sisalto.html
 * HUOM: _auditointipaketti_sisalto.html renderöidään myös ZIP:n yhteenvetoon
 * ILMAN tätä tyylitiedostoa. Esikatselun luokat eivät saa olla ainoa paikka,
 * jossa sisällön järjestys tai merkitys näkyy.
 *
 * Apex 2.2 (teht. 6b08a81b): nama ovat koostajan sivun OMIA luokkia — jokainen
 * esiintyy vain `auditointipaketti.html`:ssa ja sen sisaltoosassa — joten
 * Apexin arvot ovat tassa paikallaan eivatka perheen kiinnikkeen takana.
 * Kiinnike on vain jaetuilla komponenteilla, ks. tiedoston lopun lohko
 * "Evidenssi ja auditointipaketti — Apex 2.2".
 * ------------------------------------------------------------------------- */
/* Koostajan sivu on PYSTYPINO kaikilla ikkunakokoilla: valinta ensin pääosan
   koko sisältöleveydellä, esikatselu sen alla (tehtävä 91d6b3c9). Aiempi
   `grid-template-columns:var(--katakri-v2-lomakepaneeli) minmax(0,1fr)` jätti
   valinnalle 340 px myös leveällä näytöllä, ja juuri se teki pitkien
   vaatimusnimien valitsemisesta hankalaa, kun kohteita on paljon. Palsta ei
   palaa leveälläkään näytöllä, joten tällä luokalla ei ole enää
   `@media`-sääntöä alempana. Reunavälit tulevat yhä `.katakri-paaosa`:lta. */
.katakri-paketti{display:flex;flex-direction:column;gap:var(--space-5);min-width:0}
.katakri-vaatimusryhma{display:flex;align-items:center;gap:10px;padding:9px 10px;
  border:var(--border-hairline) solid var(--line-1);border-radius:var(--radius-md)}
.katakri-vaatimusryhma input{accent-color:var(--accent)}
.katakri-paketti__valinta{margin:0;padding:0;border:0;min-width:0}
.katakri-paketti__valinta legend{padding:0 0 var(--space-2)}
/* Vaatimusluettelo latoutuu koko leveydelle niin moneen palstaan kuin mahtuu.
   Raiteen alaraja 280 px on luettavuuden raja tunnukselle, käsikirjakuvakkeelle
   ja nimelle; `1fr` ylärajana jakaa jäljelle jäävän tilan, joten yhtään
   vaakavieritystä ei synny. Kapealla ikkunalla `auto-fill` päätyy yhteen
   palstaan ja luettelo on sama pino kuin ennen. `min(280px,100%)` on tässä
   pakollinen eikä paljas 280px: alle 280 px:n sisältöleveydellä kiinteä
   alaraja jäisi raiteen leveydeksi ja luettelo vierisi vaakasuunnassa (mitattu
   320 px:n ikkunassa 108 px ja 390 px:n ikkunassa 38 px ylitystä).
   Korkeuskatto on sidottu ikkunaan, koska leveällä näytöllä palstoitus
   lyhentää luetteloa niin, että kiinteä 420 px jätti alleen tyhjää. */
.katakri-vaatimusvalinta{display:grid;
  grid-template-columns:repeat(auto-fill,minmax(min(280px,100%),1fr));
  gap:var(--space-1);align-content:start;max-height:min(60vh,720px);overflow-y:auto}
.katakri-vaatimusryhma{align-items:flex-start;font-size:var(--text-body-sm);min-width:0}
/* Pitkä nimi katkeaa solun sisällä eikä työnnä palstaa leveämmäksi.
 *
 * Rivikatkaisu: katalogin `title` EI ole lyhyt nimi vaan vaatimuksen koko
 * teksti — F-02:n kohdalla yli 1500 merkkiä. Ilman kattoa yksi kohta on
 * mitattuna satoja pikseleitä korkea, ja ruudukossa rivin korkeus on sen
 * korkeimman kohdan korkeus, joten luettelo olisi täynnä tyhjää ja
 * valittavien kohteiden selaaminen jäisi yhtä hankalaksi kuin kapeassa
 * palstassa (tehtävän alkuperäinen valitus). Viisi riviä riittää
 * erottamaan kohdat toisistaan; koko teksti luetaan vieressä olevasta
 * käsikirjalinkistä, joka on jokaisella rivillä jo ennestään.
 * `-webkit-box` on tämän ominaisuuden vaadittu näyttöarvo kaikissa
 * selaimissa, myös niissä, jotka tukevat vakiomuotoista `line-clamp`ia. */
.katakri-vaatimusryhma > span{min-width:0;overflow-wrap:anywhere;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:5;line-clamp:5;
  overflow:hidden}
.katakri-kenttapari{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-3)}
/* Jakso-, ryhmittely- ja kielikentät ovat lyhyitä syötteitä. `.katakri-syote`
   on `width:100%`, joten koko leveydellä ne venyisivät satoihin pikseleihin
   ilman tätä kattoa. Kapealla ikkunalla minmax-alaraja 0 päästää ne kutistumaan
   kuten ennenkin. */
.katakri-paketti__valinta .katakri-kenttapari{grid-template-columns:repeat(2,minmax(0,240px))}
/* Lähetysnapit riviin luonnollisella leveydellään: koko sisältöleveyden
   mittainen painike on leveällä näytöllä luettavuusvirhe. Kapealla ikkunalla
   ne kiertävät riviltä toiselle ja venyvät täysleveiksi (sääntö alempana). */
.katakri-paketti__toiminnot{display:flex;flex-wrap:wrap;gap:var(--space-3)}
.katakri-paketti__toiminnot .katakri-painike{flex:0 1 auto}
.katakri-esikatselu__sivu{position:relative}
/* Esikatselun kehys on Apexin `.card`: `--card` pohja, `--line-1` viiva ja
   `--sh-card` korotus. Otsikkopalkki on `.card-h` + `--sunken`, kuten Apexin
   taulukon otsakerivi. */
.katakri-esikatselu{background:var(--card);border:var(--border-hairline) solid var(--line-1);
  border-radius:var(--radius-lg);box-shadow:var(--sh-card);overflow:hidden;min-width:0}
.katakri-esikatselu__palkki{display:flex;align-items:center;gap:10px;padding:10px 18px;background:var(--sunken);
  border-bottom:var(--border-hairline) solid var(--line-1)}
.katakri-esikatselu__sivu{padding:28px var(--space-8);display:flex;flex-direction:column;gap:22px}
.katakri-paketti__tunnisteet{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-3)}
.katakri-paketti__tunniste{display:flex;flex-direction:column;gap:6px;padding:var(--space-3) 14px;
  background:var(--sunken);border-radius:var(--radius-md);min-width:0}
/* Eheyden kaksi tilaa ovat Apexin pos/neg-pari. Veto on mukana (`--pos-ink` /
   `--neg-ink`): pehmealla pohjalla periytyva leipamuste jaisi lahes
   varittomaksi, ja juuri tama lohko on se, josta lukija lukee verdiktin.
   Reunus: negatiivisella on oma pehmea reunatokeninsa (`--neg-border`),
   positiivisella ei, joten ehjan reuna on `--pos`. Kumpikin on hiusviiva,
   eika ero jaa varin varaan — teksti kantaa saman tiedon mustavalkoisena. */
.katakri-paketti__tunniste--ehja{background:var(--pos-soft);
  border:var(--border-hairline) solid var(--pos);color:var(--pos-ink)}
.katakri-paketti__tunniste--rikki{background:var(--neg-soft);
  border:var(--border-hairline) solid var(--neg-border);color:var(--neg-ink)}
.katakri-paketti__vaatimus{display:flex;flex-direction:column;gap:var(--space-3);padding-top:18px;
  border-top:var(--border-hairline) solid var(--line-1)}
.katakri-paketti__sisalto h2{font-size:var(--text-h4)}
.katakri-paketti__sisalto h3{font-size:var(--text-body-sm)}
.katakri-paketti__sisalto code{overflow-wrap:anywhere}
.katakri-paketti__sarakkeet ul{margin:var(--space-1) 0 0;padding-left:var(--space-4);font-size:var(--text-caption)}
.katakri-paketti__sarakkeet{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-3)}
/* Rajamerkintä esikatselussa: näyttää kansilehden ylikirjoitettavuuden
 * siellä, missä se näkyy. Vain esikatselussa, ei ZIP:ssä. */
.katakri-rajamerkki{position:absolute;top:10px;right:12px;font-family:var(--font-mono);font-size:10px;
  font-weight:var(--weight-semibold);line-height:1;letter-spacing:var(--tracking-label);
  color:var(--pos);border:var(--border-hairline) solid var(--pos-ink);padding:3px 6px;border-radius:var(--radius-xs)}

/* ---------------------------------------------------------------------------
 * Responsiivisuus v2-näkymille
 * ------------------------------------------------------------------------- */
@media (max-width:1100px){
  /* `.katakri-paketti` ei ole tässä: se on pystypino jo lähtökohtaisesti
     (tehtävä 91d6b3c9), eikä sillä ole palstaa purettavaksi. */
  .katakri-ajautuma,.katakri-perustila{grid-template-columns:minmax(0,1fr)}
  .katakri-merkinta__tiedot{grid-template-columns:repeat(2,minmax(0,1fr))}
  .katakri-priorisoija__jaljitys{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:860px){
  .katakri-mittaustila{grid-template-columns:repeat(2,minmax(0,1fr))}
  .katakri-ajautumarivi,.katakri-ajautumarivi--otsake{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .katakri-ajautumarivi--otsake th:nth-child(n+3){display:none}
  .katakri-merkinta__perusteet,.katakri-paketti__tunnisteet,.katakri-paketti__sarakkeet{grid-template-columns:minmax(0,1fr)}
  .katakri-kannanotot{grid-template-columns:minmax(0,1fr)}
  /* Kapealla ikkunalla koostajan lähetysnapit ovat allekkain ja täysleveät,
     kuten ennen tehtävää 91d6b3c9. */
  .katakri-paketti__toiminnot{flex-direction:column}
  .katakri-paketti__toiminnot .katakri-painike{width:100%}
  .katakri-kannanotto + .katakri-kannanotto{border-left:0;border-top:var(--border-hairline) solid var(--border-control)}
}

/* ============ Kirjautuminen v2 — LISÄTTY LUOVUTUKSESTA 2026-09-28 ============
 * Lähde: Claude Design -luovutus kirjautuminen v2 (docs/ui/kierros-4/).
 * Laajentaa luovutus v1:n .katakri-kirjautuminen*-luokkia. Samat säännöt kuin
 * muualla: värit, fontit ja varjot tokens.css:stä, ei ulkoisia viittauksia.
 *
 * Osa A on vaihe 1 (tunnukset). Merkkaus tulee tehtävässä K4, joten osan A
 * luokat odottavat templatea samoin kuin osan B luokat.
 *
 * Osa B on kaksivaiheisen tunnistuksen ulkoasu, jota ei kytketä vielä (README
 * §6): luokat eivät vaikuta ilman merkkausta. Ne ovat täällä eivätkä poistettuna
 * siksi, että 2FA:n toteutus on luovutuksen oma jatkokohta ja README §6 on sen
 * lähtökohta — tämä ei siis ole kuittaussivun kaltaista merkkauksetonta tyyliä
 * ilman kohdetta.
 */

/* ---------------------------------------------------------------------------
 * A. Vaihe 1 — tunnukset
 * ------------------------------------------------------------------------- */

/* Oikea puoli: lomake keskellä, alapalkki kielille ja tunnistustavalle. */
.katakri-kirjautuminen__lomake{flex-direction:column;align-items:stretch;justify-content:flex-start;padding:0}
.katakri-kirjautuminen__keskio{flex:1;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:var(--space-6);padding:var(--space-12) var(--space-10)}
/* Ohjelinkki kirjautumissivuilla. Lomakkeen alla eikä ylärivissä:
   kirjautumissivu ei renderöi yläriviä, koska lukija ei ole kirjautunut. */
.katakri-kirjautuminen__ohje{width:100%;max-width:384px;font-size:var(--text-body-sm);
  color:var(--ink-3)}
.katakri-kirjautuminen__ohje a{color:var(--accent);text-decoration:none}
.katakri-kirjautuminen__ohje a:hover{text-decoration:underline}
.katakri-kirjautuminen__ohje a:focus-visible{outline:none;box-shadow:var(--shadow-focus-accent);
  border-radius:var(--radius-sm)}
/* Ylärivi Apexin aksentilla kirjautumisessa. Etusivu sai saman arvon omalla
   kiinnikkeellään (`.katakri-yleiskuva`, tiedoston lopun lohko). Perussääntö
   on tehtävän 24cd5d6c jälkeen sekin Apexilla (`--accent-on-dark`), joten
   tämä kiinnike ei enää erota kirjautumista muista näytöistä — se jää, koska
   asiakas ylikirjoittaa kirjautumisen sävyn tästä. */
.katakri-kirjautuminen .katakri-ylarivi--kaanteinen{color:var(--accent-on-dark)}
/* Lomakkeen nimike Apexin sävyllä vain kirjautumisessa. Kiinnikkeellä eikä
   paikallaan: `.katakri-kentta__nimike` on 13 muunkin templaten käytössä, ja
   päätös 2e305611 ("Apex-tokenien käyttöönotto tehdään scopattuna") kieltää
   app-laajuisen luokan muuttamisen ennen sivun omaa migraatiota. Arvo on
   Apexin oma nimikesävy (`apex/components.css`: `.field>label{color:var(--ink-3)}`). */
.katakri-kirjautuminen .katakri-kentta__nimike{color:var(--ink-3)}
/* Ensisijainen painike Apexin aksentilla kirjautumisessa ja etusivulla
   (kumpikin omalla kiinnikkeellään). Perussääntö on tehtävän 24cd5d6c
   jälkeen sekin Apexilla (`--action-primary` + `--on-shell`); nämä kolme
   riviä jäävät, koska ne antavat kirjautumiselle oman hover- ja
   fokusasunsa (`--accent-hover`, `filter:none`, aksenttihalo). */
.katakri-kirjautuminen .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-kirjautuminen .katakri-painike--ensisijainen:hover{background:var(--accent-hover);color:var(--on-shell);filter:none}
.katakri-kirjautuminen .katakri-painike--ensisijainen:focus-visible{box-shadow:var(--shadow-focus-accent)}
/* Suoritetun vaiheen numero Apexin onnistumisvärillä kirjautumisperheessä.
   Kiinnikkeellä eikä paikallaan, sama kuvio kuin ylläolevilla säännöillä:
   päätös 2e305611 ("Apex-tokenien käyttöönotto tehdään scopattuna") antoi
   Apexin arvon kiinnikkeen alla ja jätti osan B perussäännön
   (`.katakri-vaihe--valmis .katakri-vaihe__numero`) Meshly-tokenistoon
   kiinnikkeen ulkopuolella; perussääntö on tehtävän 24cd5d6c jälkeen sekin
   Apexilla (`--pos` + `--on-shell`). Sävy vaihtuu kaikilla neljällä
   kirjautumissivulla, jotka sisällyttävät `_kirjautumisen_vaiheet.html`:n,
   koska ne laajentavat runkoa, joka käärii sivun `.katakri-kirjautuminen`-
   elementtiin (`_kirjautumisen_runko.html:45`). Se on 2e305611:n omassa
   piirissä eikä sen rajauksen takana: tehtävän valmistumiskirjaus nimeää
   kirjautumisen jaetun rungon, vaiheilmaisimen ja 2FA-elementit
   muutetuikseen, ja sen rajaus ("muutos on rajattu kirjautumissivuihin")
   suojaa kirjautumisperheen ULKOPUOLISIA sivuja. Ainoa muu luokan käyttäjä
   on luovutusviite `docs/ui/kierros-4/viite/_2fa_viite.html`, joka ei ole
   näkymään kytketty sivu. */
.katakri-kirjautuminen .katakri-vaihe--valmis .katakri-vaihe__numero{background:var(--pos);
  color:var(--on-shell);border-color:var(--pos)}
/* Avoin ohjenäkymä käyttää kirjautumissivujen kehystä, mutta sen sisältö on
   kokonainen ohjesivu: se alkaa ylhäältä eikä ole pystysuunnassa keskitetty,
   ja se saa leveämmän mitan kuin lomake. */
.katakri-kirjautuminen--ohje .katakri-kirjautuminen__keskio{justify-content:flex-start;
  align-items:stretch;overflow-y:auto}
.katakri-kirjautuminen--ohje .katakri-kirjautuminen__keskio>*{width:100%;max-width:720px;
  margin:0 auto}
.katakri-kirjautuminen__keskio form{width:100%;max-width:384px;display:flex;flex-direction:column;gap:var(--space-6)}
.katakri-kirjautuminen__lomake h2{font-size:var(--text-h2);font-weight:var(--weight-black);
  line-height:var(--leading-snug);letter-spacing:var(--tracking-snug);color:var(--ink-1)}
.katakri-kirjautuminen__alapalkki{display:flex;justify-content:space-between;gap:var(--space-4);
  padding:var(--space-4) var(--space-10);border-top:var(--border-hairline) solid var(--line-1);
  font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-bold);
  line-height:1;letter-spacing:var(--tracking-label);color:var(--ink-4)}

/* Djangon AuthenticationForm renderöi kentät ilman luokkaa. Tyylitellään ne
 * rakenteesta, jotta näkymää (views.KirjautumisNakyma) ei tarvitse muuttaa. */
.katakri-kirjautuminen__lomake input[type="text"],
.katakri-kirjautuminen__lomake input[type="password"],
.katakri-kirjautuminen__lomake input[type="email"]{width:100%;height:40px;padding:0 var(--space-3);
  border-radius:var(--radius-md);border:var(--border-hairline) solid var(--line-2);
  background:var(--card);font-family:var(--font-sans);font-size:var(--text-body-md);color:var(--ink-1)}
.katakri-kirjautuminen__lomake input:focus{outline:none;border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}
.katakri-kirjautuminen__lomake input[aria-invalid="true"]{border-color:var(--neg)}

/* Virhe: form.errors. role="alert" templatessa. Apex Banner (neg). */
.katakri-kirjautumisvirhe{display:flex;gap:10px;align-items:flex-start;margin:0;padding:var(--space-3) 14px;
  background:var(--neg-soft);border:var(--border-hairline) solid var(--neg-border);
  border-left:3px solid var(--neg);border-radius:var(--radius-md);
  font-size:var(--text-body-sm);font-weight:var(--weight-medium);line-height:1.45;color:var(--neg-ink)}
.katakri-kirjautumisvirhe .katakri-ikoni{margin-top:1px}

/* ---------------------------------------------------------------------------
 * B. 2FA — vain ulkoasu, ei kytketä vielä
 * ------------------------------------------------------------------------- */

/* Vaiheilmaisin: näytetään vain, kun politiikka ei ole "pois". */
.katakri-vaiheet{margin:0;padding:0;list-style:none;display:flex;align-items:center;gap:10px}
.katakri-vaihe{display:flex;align-items:center;gap:var(--space-2);flex:1}
.katakri-vaihe:last-child{flex:0 0 auto}
.katakri-vaihe__numero{width:22px;height:22px;border-radius:var(--radius-pill);flex:none;display:inline-flex;
  align-items:center;justify-content:center;background:var(--card);color:var(--ink-3);
  border:var(--border-hairline) solid var(--line-2);
  font-family:var(--font-mono);font-size:var(--text-overline);font-weight:var(--weight-semibold);line-height:1}
.katakri-vaihe__nimi{font-size:var(--text-caption);font-weight:var(--weight-medium);line-height:1;
  color:var(--ink-3);white-space:nowrap}
.katakri-vaihe:not(:last-child)::after{content:"";flex:1;height:1px;background:var(--line-1);margin-left:var(--space-1)}
.katakri-vaihe[aria-current="step"] .katakri-vaihe__numero{background:var(--accent);color:var(--on-shell);border-color:var(--accent)}
.katakri-vaihe[aria-current="step"] .katakri-vaihe__nimi{font-weight:var(--weight-semibold);color:var(--ink-1)}
/* Valmis vaihe on Apexin `--pos`. Teksti on `--on-shell` eika `--white`:
   Apexilla ei ole valkoista omana tokeninaan, ja `--on-shell` on sen nimi
   varilliselle pinnalle tulevalle tekstille — sama arvo kuin ensisijaisen
   painikkeen tekstissa kirjautumisessa ja yleiskuvassa. */
.katakri-vaihe--valmis .katakri-vaihe__numero{background:var(--pos);color:var(--on-shell);border-color:var(--pos)}

/* Tunnistettu käyttäjä koodivaiheessa */
.katakri-tunnistettu{display:flex;align-items:center;gap:10px;padding:10px var(--space-3);
  background:var(--card);border:var(--border-hairline) solid var(--line-1);border-radius:var(--radius-md)}
.katakri-tunnistettu__nimi{flex:1;font-family:var(--font-mono);font-size:var(--text-body-sm);
  font-weight:var(--weight-medium);color:var(--ink-1)}

/* TOTP-koodi: YKSI input (autocomplete="one-time-code"). Ruudut ovat
 * pelkkä tausta: input on läpinäkyvä ja kirjainväli osuu ruutuihin.
 * Suunnitteluviitteen kuusi erillistä ruutua ovat vain kuva. */
.katakri-koodi{position:relative;height:52px}
.katakri-koodi__ruudut{position:absolute;inset:0;display:grid;
  grid-template-columns:repeat(3,1fr) 14px repeat(3,1fr);gap:var(--space-2);pointer-events:none}
.katakri-koodi__ruutu{border-radius:var(--radius-md);background:var(--card);
  border:var(--border-hairline) solid var(--line-2)}
.katakri-koodi__viiva{align-self:center;height:2px;background:var(--line-2);border-radius:var(--radius-pill)}
.katakri-koodi input{position:relative;width:100%;height:100%;border:0;background:transparent;
  text-align:center;font-family:var(--font-mono);font-size:var(--text-h2);font-weight:var(--weight-semibold);
  letter-spacing:.9em;color:var(--ink-1);caret-color:var(--accent)}
.katakri-koodi:focus-within .katakri-koodi__ruutu{border-color:var(--accent)}
/* Fokusrengas jai aiemmin Meshlyn `--shadow-focus`:iin, koska
   `.katakri-koodi` on myos tekstin seassa oleva koodimerkinta (ks. lohko
   "Koodimerkinta tekstin seassa") ja `<a class="katakri-koodi">` on
   fokusoitava elementti kirjautumisen ulkopuolella:
   locked/_dokumenttikortin_saannot.html. Tehtava 24cd5d6c kaansi sen
   Apexin halolle, joten molemmat esiintymat saavat saman renkaan; alla
   oleva kirjautumisen oma rivi on nyt sama arvo ja jaa vain siksi, etta
   asiakas ylikirjoittaa kirjautumisen renkaan erikseen. */
.katakri-koodi:focus-within{border-radius:var(--radius-md);box-shadow:var(--shadow-focus-accent)}
.katakri-kirjautuminen .katakri-koodi:focus-within{box-shadow:var(--shadow-focus-accent)}
.katakri-koodi__aika{display:flex;align-items:center;gap:10px}
.katakri-koodi__palkki{flex:1;height:4px;border-radius:var(--radius-pill);background:var(--sunken);overflow:hidden}
.katakri-koodi__palkki span{display:block;height:100%;background:var(--accent)}
.katakri-koodi__sekunnit{font-family:var(--font-mono);font-size:var(--text-caption);font-weight:var(--weight-medium);color:var(--ink-3)}

/* Käyttöönotto */
.katakri-kayttoonotto{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--space-4)}
.katakri-kayttoonotto > li{display:grid;grid-template-columns:22px minmax(0,1fr);gap:var(--space-3)}
.katakri-kayttoonotto__nro{font-family:var(--font-mono);font-size:var(--text-body-sm);font-weight:var(--weight-semibold);
  line-height:1.4;color:var(--accent)}
.katakri-qr{width:256px;max-width:100%;flex:none}
.katakri-qr img,.katakri-qr svg{width:100%;height:auto;display:block}
.katakri-avain{font-family:var(--font-mono);font-size:var(--text-caption);font-weight:var(--weight-medium);line-height:1.6;
  letter-spacing:.06em;color:var(--ink-2);background:var(--sunken);padding:6px var(--space-2);
  border-radius:var(--radius-xs);overflow-wrap:anywhere}

/* Politiikkarivi lomakkeen alla */
.katakri-politiikka{display:flex;gap:var(--space-2);align-items:flex-start;padding:10px var(--space-3);
  border-radius:var(--radius-md);background:var(--sunken);border:var(--border-hairline) solid var(--line-1);
  font-size:var(--text-caption);font-weight:var(--weight-medium);line-height:1.45;color:var(--ink-3)}
.katakri-politiikka--pakollinen{background:var(--accent-softer);border-color:var(--accent-soft);color:var(--accent-ink)}
.katakri-politiikka .katakri-ikoni{margin-top:1px}

@media (max-width:860px){
  .katakri-kirjautuminen__keskio{padding:var(--space-8) var(--space-5)}
  .katakri-kirjautuminen__alapalkki{padding:var(--space-3) var(--space-5);flex-direction:column}
}

/* ============ Dokumenttilistan taulukko (kierros 6, D2) ============
   Merkki on muualla `white-space:nowrap`, jotta lyhyt tilamerkki ei katkea
   kahdelle riville. Dokumenttilistan solu on poikkeus: `.katakri-taulukko` on
   `table-layout:fixed`, ja seitseman saraketta jakavat leveyden tasan, joten
   solua leveampi merkki ei lyhene vaan jatkaa naapurisarakkeen paalle. Pisin
   merkki on vanhenemisen ja katselmoinnin muistutus, joka kantaa lisaksi
   vuorokausimaaran ("Granskning försenad 12 dygn"). Rivittyminen on
   suunnittelupaketin ehto -- chipit ja otsikot rivittyvat, eivat katkea
   (docs/ui/kierros-6/README.md §2) -- ja sama ongelma on jo ratkaistu samoin
   ajautumarivilla. Rajaus on taulukkoon eika merkkiin, koska muualla kapeassa
   solussa olevan merkin rivittyminen ei ole sama kysymys. */
.katakri-taulukko[data-testid="dokumenttitaulukko"] .katakri-merkki{white-space:normal}

/* Sarakeleveydet ja solun suunta (kuva `p1-0-dokumenttilista.png`).
   `table-layout:fixed` jakaa leveyden tasan, kun sarakkeille ei anneta
   mittaa, joten katalogin kappaleen mittainen vaatimusteksti sai saman
   seitsemasosan kuin yksimerkkinen versionumero ja rivittyi kymmeniksi
   riveiksi. Mitattuna 1440 px:n ikkunassa F-02:n rivi oli 1718,5 px ja
   F-03:n 4486 px (audit d6209cb2). Osuudet ovat suunnittelukuvan omat:
   dokumentti ja vaatimus ovat levein pari, versio kapein. Sadasosia eika
   pikseleita, koska paaosan leveys muuttuu navin ja agenttipalstan
   taittuessa. Mitta on otsikkosolussa, koska `fixed` lukee leveyden
   ensimmaiselta rivilta. */
.katakri-sarake--dokumentti{width:23%}
.katakri-sarake--vaatimus{width:18%}
.katakri-sarake--versio{width:8%}
.katakri-sarake--rivintila{width:12%}
.katakri-sarake--hyvaksynta{width:14%}
.katakri-sarake--voimassa{width:11%}
.katakri-sarake--katselmointi{width:14%}
/* Vaakareunus on kapeampi kuin `.katakri-taulukko`n oletus. `box-sizing`
   on `border-box`, joten reunus syo saman prosenttiosuuden sisalta: 24 px
   molemmin puolin seitsemassa sarakkeessa vei 336 px siita 1140 px:sta,
   joka paaosalle jaa 1440 px:n ikkunassa (1440 - navin 236 - reunuksen
   2 x 32), eli lahes kolmanneksen. */
.katakri-taulukko[data-testid="dokumenttitaulukko"] th,
.katakri-taulukko[data-testid="dokumenttitaulukko"] td{
  padding-left:var(--space-4);padding-right:var(--space-4)}
/* Solu alkaa rivin ylareunasta. `vertical-align:middle` keskitti lyhyen
   solun korkean rivin puolivaliin, jolloin tunnus, tila ja paivamaara
   olivat satoja pikseleita sen asiakirjan nimen alapuolella, jota ne
   kuvaavat -- kaappauksessa ensimmaisen rivin dokumenttisarake nayttaa
   tyhjalta, koska sen sisalto on ruudun alapuolella. */
.katakri-taulukko[data-testid="dokumenttitaulukko"] td{vertical-align:top;
  font-size:var(--text-body-sm);line-height:var(--leading-normal)}

/* Pitkat tekstit: kaksi rivia, loput `title`-attribuutissa. Lista on
   yleiskuva ("mika asiakirja ohjaa mitakin vaatimusta ja missa tilassa se
   on"), eika yksikaan sen sarake ole paikka koko katalogitekstille -- se on
   vaatimuksen omalla sivulla, yhden siirtyman paassa. Rajaus on riveissa
   eika merkkimaarassa, jotta ruotsinkielinen pidempi asu mahtuu samaan
   korkeuteen (`docs/ui/kierros-6/README.md` §2). */
.katakri-dokumenttirivi__nimi,.katakri-dokumenttirivi__vaatimusteksti{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;
  overflow:hidden;overflow-wrap:anywhere}
.katakri-dokumenttirivi__nimi{font-size:var(--text-body-md);font-weight:var(--weight-semibold);
  color:var(--ink-1);line-height:var(--leading-snug)}
/* Puuttuva asiakirja ja hylatty vientirivi ovat himmeita eivatka otsikoita:
   kumpikaan ei ole asiakirjan nimi. Asettelu on sama, vari ei. */
.katakri-dokumenttirivi__nimi.katakri-himmea{font-weight:var(--weight-medium);
  font-size:var(--text-body-sm);color:var(--ink-3)}
/* Luokitusmerkinnat ovat solun ylin rivi ja oma lohkonsa: merkinta kuuluu
   asiakirjaan, ja nimen kanssa samalla rivilla se luettaisiin nimen osaksi. */
.katakri-taulukko[data-testid="dokumenttitaulukko"] .katakri-merkkilista{margin-bottom:var(--space-2)}
.katakri-dokumenttirivi__tunnus{display:block;margin-top:3px;height:auto;
  font-family:var(--font-mono);font-size:var(--text-caption);color:var(--ink-4);
  overflow-wrap:anywhere}
/* Vari on sivun kiinnikkeen takana eika tassa, vaikka luokka on sivun oma:
   tunnus on ankkuri, ja `.katakri-dokumenttinakymat a` (0,1,1) voittaisi
   taman (0,1,0). Ks. tiedoston lopun lohko "Dokumenttinakymat — Apex 2.2". */
.katakri-dokumenttirivi__vaatimus{display:block;font-family:var(--font-mono);
  font-size:var(--text-body-sm);font-weight:var(--weight-semibold)}
.katakri-dokumenttirivi__vaatimusteksti{margin-top:3px;font-size:var(--text-caption);
  line-height:var(--leading-normal)}
/* Paivamaara ja sen muistutusmerkki allekkain: merkki rivittyy (ks. edella),
   ja saman rivin jatkona se tyonsi lyhennetyn paivamaaran sarakkeen yli.
   `<time>` on lohko, joten merkki alkaa omalta riviltaan ilman, etta solusta
   tehdaan flex-sailiota -- `display:flex` taulukon solussa veisi silta
   solun roolin taulukon asettelussa. */
.katakri-taulukko[data-testid="dokumenttitaulukko"] time{display:block;white-space:nowrap}
.katakri-taulukko[data-testid="dokumenttitaulukko"] time + .katakri-merkki{margin-top:var(--space-1)}

/* ============ Kehikon kontrollin kartoitustaulukko (kierros 6, D10) ============
   Tama taulukko ei ollut `.katakri-taulukko` lainkaan, vaan paljas `<table>`
   `.katakri-merkintataulu`n ulkopuolella -- eli ladattujen tyylien ainoiden
   `table-layout:fixed` -saantojen (`.katakri-taulukko`,
   `.katakri-merkintataulu table`) ulkopuolella. Se latoutui siis selaimen
   automaattisella asettelulla ja ilman `width:100%`ia: kymmenen saraketta
   jakoivat leveyden sisaltonsa mukaan, ja kaksi niista kantaa kokonaisen
   katalogitekstin -- vaatimustekstin ja kartoituksen perusteen. Kumpikin
   latoutui kokonaisena kappaleena, ja sivu nayttaa katalogin tekstilta eika
   kuvan `p7-1` tiiviilta riveilta (audit d6209cb2:
   /kehikot/iso-iec-27001-2022/kontrollit/A.5.1/).

   Korjaus tuo taulukon `.katakri-taulukko`ksi -- `width:100%` ja
   `table-layout:fixed` -- ja antaa jokaiselle sarakkeelle oman mitan.
   `fixed` ilman mittoja jakaisi leveyden tasan, mika on tata vikaa vastaan
   yhta huono: katalogin kappale saisi saman kymmenesosan kuin yksimerkkinen
   versionumero. Pitkat tekstit rajataan riveihin alempana.

   Sarakkeita ei pudoteta: kartoituksen aste, asema ja peruste ovat se, mika
   erottaa suuntaa-antavan kartoituksen vaatimustenmukaisuuden vaitteesta
   (ADR 0018, templaten oma lukitusperustelu). Ne mahtuvat kapeina.

   Osuudet on mitoitettu kunkin sarakkeen pisimman *sanan* mukaan, koska sana
   on se, mika ei voi katketa luettavasti: otsikot ovat versaalilla ja
   `letter-spacing`illa. Paaosalle jaa 1440 px:n ikkunassa 1140 px, eli
   1 % = 11,4 px, ja reunus syo siita 24 px (`border-box`).

   Mitattu on vain suomi: teht. 372220ce ajoi yhden istunnon (Firefox 158,
   1440 px, tuore `pieni`-demo) ja kirjasi nelja solunsa ulkopuolelle
   piirtyvaa tekstia. Niista saa piirretyn leveyden: "VAATIMUSTUNNUS"
   110,8 px, "VASTAAVUUDEN" 95,0 px, "VERSIO" 47,5 px ja solun oma teksti
   "arvioitavissa" 72,7 px. Loput leveydet ovat arvioita, eivat mittauksia:
   kolme mitattua versaaliotsikkoa antavat saman ~7,9 px/merkki, ja muut
   otsikot on mitoitettu silla luvulla merkkimaarasta. Ruotsin- ja
   englanninkieliset asut ovat eri mittaisia ("Kravbeteckning", "Grad av
   motsvarighet"), eika niita ole mitattu lainkaan -- siksi `overflow-wrap`
   alempana on se takuu, ja nama leveydet ovat luettavuuden valinta.

   Rajatut tekstisarakkeet maksavat lisayksen: niiden korkeus on
   rivirajauksen eika leveyden varassa, joten kaventaminen ei kasvata
   rivia. */
.katakri-sarake--kartoitus-tunnus{width:12%}
.katakri-sarake--kartoitus-vaatimus{width:12%}
.katakri-sarake--kartoitus-aste{width:11%}
.katakri-sarake--kartoitus-asema{width:9%}
.katakri-sarake--kartoitus-peruste{width:12%}
.katakri-sarake--kartoitus-tila{width:9%}
.katakri-sarake--kartoitus-alkupera{width:9%}
.katakri-sarake--kartoitus-ratkaisi{width:9%}
.katakri-sarake--kartoitus-dokumentti{width:10%}
.katakri-sarake--kartoitus-versio{width:7%}
/* Kymmenella sarakkeella reunus on 12 px eika 24 px: `border-box`illa
   24 px molemmin puolin olisi vienyt 480 px eli yli 40 % kaytettavissa
   olevasta leveydesta pelkkaan tyhjaan.

   `overflow-wrap:anywhere` on solussa itsessaan eika vain tekstiluokissa.
   Ilman sita pitka yksittainen sana ei voi katketa, ja se piirtyy solunsa
   ulkopuolelle: mitattuna (teht. 372220ce) nelja tekstia vuosi solustaan --
   kolme paljasta `th`:ta ja yksi paljas `td` ("Ei arvioitavissa"), eli
   tasan ne, joilla ei ole rajattua tekstielementtia sisallaan. Leveysarvo
   ei anna samaa takuuta: sv- ja en-otsikot ovat eri mittaisia, ja
   paaosan leveys muuttuu navin ja agenttipalstan taittuessa. Sama ratkaisu
   kuin `.katakri-ajautumataulukko th`:lla ja `.katakri-tiedot-pieni dd`:lla. */
.katakri-taulukko[data-testid="vaatimustaulukko"] th,
.katakri-taulukko[data-testid="vaatimustaulukko"] td{
  padding-left:var(--space-3);padding-right:var(--space-3);overflow-wrap:anywhere}
.katakri-taulukko[data-testid="vaatimustaulukko"] td{vertical-align:top;
  font-size:var(--text-body-sm);line-height:var(--leading-normal)}
/* Kolme rivia eika kaksi: tassa teksti on solun ainoa sisalto, kun taas
   dokumenttilistan solussa sen ylla on tunnus tai nimi. */
.katakri-kartoitusrivi__teksti{display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:3;line-clamp:3;overflow:hidden;overflow-wrap:anywhere}
/* Kartoitusrivin luokat ovat vain `kehikon_kontrolli.html`:ssa, joten Apexin
   musteasteikko on tässä paikallaan: nimi `--ink-1`, aputunnus `--ink-4`
   (Apexin `.tbl .name` / `.tbl .muted` -pari). */
.katakri-kartoitusrivi__tunniste{display:block;font-family:var(--font-mono);
  font-weight:var(--weight-semibold);color:var(--ink-1)}
.katakri-kartoitusrivi__dokumentti{display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere;
  font-weight:var(--weight-semibold);color:var(--ink-1)}
.katakri-kartoitusrivi__tunnus{display:block;margin-top:3px;height:auto;
  font-family:var(--font-mono);font-size:var(--text-caption);color:var(--ink-4);
  overflow-wrap:anywhere}

/* ============ Vaatimuslistan taulukko ============
   Sama vika kuin kartoitustaulukolla ja dokumenttilistalla, kolmannella
   sivulla: `/vaatimukset/` oli paljas `<table>` ilman `.katakri-taulukko`a,
   eli ladattujen tyylien molempien `table-layout:fixed` -saantojen
   ulkopuolella. Kuusi saraketta jakoivat leveyden sisaltonsa mukaan, ja
   Vaatimus-sarake kantaa kokonaisen katalogikappaleen: se latoutui
   kokonaisena, rivi kasvoi kappaleen korkuiseksi eika lista ollut
   silmailtavissa (teht. f01083e2, liitteen kuvakaappaus F-01/F-02).

   Luokka yksin ei riita, ja se on sama pari kuin naapuritaulukoissa: `fixed`
   ilman sarakemittoja jakaisi leveyden tasan kuudesosiin, jolloin
   katalogikappale saisi saman osuuden kuin yksimerkkinen osa-alue.

   Osuudet on mitoitettu kunkin sarakkeen pisimman *sanan* mukaan -- sana on
   se, mika ei voi katketa luettavasti -- ja Vaatimus saa lopun. Paaosalle jaa
   1440 px:n ikkunassa 1140 px, eli 1 % = 11,4 px, ja reunus syo siita 48 px
   (`border-box`, `.katakri-taulukko`n oma 24 px molemmin puolin; sita ei
   kavenneta, koska kuudella sarakkeella se vie 288 px eika kolmannesta kuten
   dokumenttilistan seitsemalla).

   ARVIOITU, ei mitattu: nama leveydet. Mitta on teht. 372220ce:n samasta
   mittauksesta johdettu ~7,9 px/merkki versaaliotsikolle ja ~5,6 px/merkki
   leipatekstille (mitattu "arvioitavissa" 72,7 px / 13 merkkia) -- otsikot ja
   soluarvot ovat samat tokenit samassa taulukkotyylissa. Ruotsin- ja
   englanninkielisia asuja ei ole mitattu lainkaan; ylivuodon estaa
   `.katakri-taulukko th,td`:n `overflow-wrap:anywhere`, joka patee ilman
   mittausta, ja nama leveydet ostavat vain sen, ettei otsikko katkea kesken
   sanan. */
/* fi/sv "Vaatimustunnus"/"Kravbeteckning" 14 mk ~111 px + 48 = 159 px */
.katakri-sarake--vaatimuslista-tunnus{width:14%}
/* sv "Delområde" 9 mk ~71 px + 48 = 119 px (fi "Osa-alue" katkeaa viivasta) */
.katakri-sarake--vaatimuslista-osaalue{width:11%}
/* Katalogikappaleelle jaa loput. Kolmella rivilla se on taulukon levein
   sarake, kuten dokumenttilistalla tekstisarakkeet ovat levein pari. */
.katakri-sarake--vaatimuslista-vaatimus{width:40%}
/* Solun oma pisin arvo fi "sovellettavissa" 15 mk ~84 px + 48 = 132 px
   ("Ei sovellettavissa"); otsikko "TILA"/"STATUS" on lyhyempi. */
.katakri-sarake--vaatimuslista-tila{width:12%}
/* sv otsikko "STATUSENS" 9 mk ~71 px + 48 = 119 px; solun pisin fi
   "ulkopuolelle" 12 mk ~67 px mahtuu samaan. */
.katakri-sarake--vaatimuslista-alkupera{width:11%}
/* Hetki nakyy kanonisena ISO-asuna (`|date:"c"`, ks. vaatimuslista.html ja
   test_kirjatun_vaitteen_ika.py): 25 merkkia ~140 px katkeaa kahdelle
   riville, ja 12 % = 137 - 48 = 89 px pitaa paivaosan "2027-10-14T"
   (~62 px) ensimmaisella rivilla. */
.katakri-sarake--vaatimuslista-ratkaistu{width:12%}
/* Solu alkaa rivin ylareunasta: rivin korkeuden maaraa rajattu
   vaatimusteksti, ja `.katakri-taulukko td`:n `vertical-align:middle`
   keskittaisi sen viereiset yksiriviset solut -- tunnuksen, tilan ja
   hetken -- kolmirivisen rivin puolivaliin. */
.katakri-taulukko[data-testid="kontrollilista"] td{vertical-align:top;
  font-size:var(--text-body-sm);line-height:var(--leading-normal)}
/* Kolme rivia, kuten kartoitustaulukossa: teksti on solunsa ainoa sisalto.
   Nelja ehtoa, joista yksikaan ei nay sivulla erikseen: `-webkit-line-clamp`
   jaa vaikutuksetta ilman `display:-webkit-box`ia ja
   `-webkit-box-orient:vertical`ia, ja ilman `overflow:hidden`ia rajattu
   teksti valuu solusta ulos. */
.katakri-vaatimusrivi__teksti{display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:3;line-clamp:3;overflow:hidden;overflow-wrap:anywhere}

/* ============ Vaatimuksen dokumenttikortti (kierros 6, D1) ============
   Tilan asu tulee `.katakri-merkki--<tila>`sta eika omasta variluokastaan:
   tilan tokenit ovat jo olemassa, ja toinen kartta samoista neljasta tilasta
   voisi ajautua erilleen juuri siina, mika niissa on sama. */
.katakri-dokumenttikortti{display:flex;flex-direction:column;gap:var(--space-4)}
.katakri-dokumenttikortti__ylaosa{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--space-2);
  padding-bottom:var(--space-3);border-bottom:var(--border-hairline) solid var(--border-divider)}
.katakri-dokumenttikortti__nimike{font-size:var(--text-overline);font-weight:var(--weight-semibold);
  letter-spacing:var(--tracking-wide);text-transform:uppercase;color:var(--text-hint);flex-basis:100%}
.katakri-dokumenttikortti__ylaosa .katakri-merkki{margin-left:auto}
.katakri-dokumenttikortti__saannot{display:flex;flex-direction:column;gap:var(--space-2)}
.katakri-saantorivit{display:flex;flex-direction:column;gap:var(--space-2);list-style:none;margin:0;padding:0}
.katakri-saantorivi{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);
  padding:10px var(--space-3);border-radius:var(--radius-md);background:var(--surface-sunken);
  border:var(--border-hairline) solid var(--border-divider)}
/* Flex-alkion oletus on `min-width:auto`, eli se ei kutistu sisaltoaan
   kapeammaksi. Saantorivilla pisin alkio on saannon oma perustelukoodi
   (`turvallisuusperiaatteet_hyvaksytty`), ja asiakirjan sivun kapeassa
   sivupalstassa se tyonsi rivin ulos kortista. `min-width:0` paastaa alkion
   kutistumaan, ja `code.katakri-koodi`in asetettu `overflow-wrap` katkaisee
   tunnuksen rivin sisalla. Molempia tarvitaan: kumpikaan ei yksin riita. */
.katakri-saantorivi > *{min-width:0}
/* Otsikko ja selite omille riveilleen: ruotsinkielinen asu on pidempi, ja
   chipit ja otsikot rivittyvat (docs/ui/kierros-6/README.md §2). */
.katakri-saantorivi__otsikko{flex-basis:100%;font-weight:var(--weight-semibold);color:var(--text-heading)}
.katakri-saantorivi__selite{flex-basis:100%;font-size:var(--text-caption);color:var(--text-hint);line-height:1.45}
.katakri-dokumenttikortti__tiedot,.katakri-dokumenttikortti__tyhja{display:flex;flex-direction:column;
  gap:var(--space-2);padding-top:var(--space-3);border-top:var(--border-hairline) solid var(--border-divider)}
.katakri-dokumenttikortti__nimi{margin:0;font-size:var(--text-body-lg);font-weight:var(--weight-semibold);
  color:var(--text-heading)}
.katakri-dokumenttikortti__meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);margin:0}
/* Kortin alaosa: siirtymä asiakirjan sivulle (`p5-1`, kuvassa kortin
   alareunassa oikealla). Hiusviiva erottaa toiminnon kentistä, kuten
   yläosassa tulosmerkistä. */
.katakri-dokumenttikortti__alaosa{display:flex;flex-wrap:wrap;justify-content:flex-end;
  align-items:center;gap:var(--space-2);
  margin:0;padding-top:var(--space-3);border-top:var(--border-hairline) solid var(--border-divider)}

/* ============ Koodimerkinta tekstin seassa (kierros 6) ============
   `katakri-koodi` oli kahden eri komponentin nimi. Toinen on kirjautumisen
   kuusinumeroinen kentta (`<span class="katakri-koodi">` ruutuineen; sen oma
   lohko on alempana, `position:relative;height:52px`), toinen on tama:
   koneluettava arvo
   tekstin seassa -- tunnus, versio, dokumenttilaji, saannon perustelukoodi.
   Jalkimmaiselle ei ollut omaa saantoa, joten se peri kentan 52 px:n
   korkeuden: dokumentin sivun metarivi levisi pystysuunnassa, ja kapeassa
   sivupalstassa `turvallisuusperiaatteet_hyvaksytty` jatkui ulos kortista
   (docs/ui/kierros-6/audit-2026-10-23/document-doc-000022.png).

   Erottelu on elementilla eika uudella nimella: kentta on aina `<span>`
   (kaksi esiintymaa) ja merkinta aina `<code>` tai `<a>` (30 esiintymaa),
   joten `code`/`a` + luokka osuu tasan toiseen eika koske toiseen.
   `overflow-wrap:anywhere` on samasta syysta kuin taulukon soluissa: nama
   ovat tunnuksia eivat sanoja. */
code.katakri-koodi,a.katakri-koodi{display:inline;height:auto;position:static;
  font-family:var(--font-mono);font-size:var(--text-body-sm);
  color:var(--text-body);overflow-wrap:anywhere}
a.katakri-koodi{color:var(--accent)}

/* Hyväksyntälomake (Apex Modal) ja hyväksyntäpaikat.
   LUKITTU — locked/_hyvaksyntalomake.html (kierros 6, D4).

   Modaali on <dialog>, jonka auki-tilan palvelin renderöi (`open`), ja se
   avataan ja suljetaan linkeillä. Se ei kellu sivun päällä: ilman
   JavaScriptia `showModal()`ia ei voi kutsua, ja pelkällä CSS:llä kelluvaksi
   tehty dialogi näyttäisi modaalilta sulkematta taustaa pois
   kohdistusjärjestyksestä — se olisi näppäimistökäyttäjälle valhe. Selaimen
   oletustyylit (position:absolute, inset:0, width:fit-content, oma reunus)
   kumotaan siksi tässä, ja lomake asettuu sivulle korttina.

   Suljettuna selain piilottaa sen itse (`dialog:not([open])`), eikä sitä
   tarvitse tässä piilottaa. */
/* Apex 2.2 (tehtävä ebc2cfc3): `.katakri-modaali*`, `.katakri-hyvaksynnan-
   toiminnot`, `.katakri-paikat`, `.katakri-paikka*`, `.katakri-avaukset`,
   `.katakri-avaus*` ja `.katakri-avatar` renderöityvät vain tämän tehtävän
   kahdessa lukitussa partiaalissa (`locked/_hyvaksyntalomake.html`,
   `locked/_hyvaksyntalista.html`, `locked/_avaukset.html`), joten Apexin arvo
   on paikallaan. */
.katakri-modaali{border-top:3px solid var(--accent)}
.katakri-modaali[open]{position:static;display:flex;flex-direction:column;
  gap:var(--space-4);inset:auto;margin:0;width:auto;max-width:none;
  max-height:none;color:inherit}
.katakri-modaali__otsikko{display:flex;flex-direction:column;gap:3px;
  padding-bottom:var(--space-3);border-bottom:var(--border-hairline) solid var(--line-1)}
.katakri-modaali__otsikko h2{margin:0}
/* Otsikkorivi: otsikko vasemmalle, sulkeminen oikeaan ylänurkkaan (p1-3). */
.katakri-modaali__rivi{display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--space-3)}
.katakri-modaali__sulje{display:inline-flex;align-items:center;justify-content:center;
  flex:none;width:32px;height:32px;border-radius:var(--radius-md);
  font-size:var(--text-body-lg);line-height:1;color:var(--ink-3);text-decoration:none}
.katakri-modaali__sulje:hover{background:var(--sunken);color:var(--ink-1);
  text-decoration:none}
/* Lomakkeen avaus ja sen este samassa paikassa: kumpi tahansa on se, minkä
   kirjaaja näkee hyväksyntäkortin jälkeen. */
.katakri-hyvaksynnan-toiminnot{display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--space-3);margin:0}
.katakri-hyvaksynnan-toiminnot > p{margin:0}
.katakri-modaali__alatunniste{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3);
  padding-top:var(--space-3);border-top:var(--border-hairline) solid var(--line-1)}
.katakri-modaali__alatunniste p{flex-basis:100%;margin:0}
.katakri-modaali__alatunniste .katakri-painike--ensisijainen{margin-left:auto}

/* Paikat: kirjatut kannanotot ja odottavat paikat samassa luettelossa.
   Odottava paikka on katkoviivalla eikä poissa (ks. templaten perustelu). */
.katakri-paikat{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:var(--space-2)}
.katakri-paikka{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);
  padding:10px var(--space-3);border-radius:var(--radius-md);background:var(--sunken);
  border:var(--border-hairline) solid var(--line-1)}
.katakri-paikka .katakri-merkinta__perustelu{flex-basis:100%;margin:0;
  font-size:var(--text-caption);color:var(--ink-4);line-height:1.45}
.katakri-paikka--approved{border-left:3px solid var(--pos)}
.katakri-paikka--rejected{border-left:3px solid var(--neg)}
.katakri-paikka--odottaa{background:transparent;border-style:dashed}

/* ============ Avaukset (kierros 7, K7-12). LUKITTU — locked/_avaukset.html ============
   Sama luettelokuvio kuin hyväksyntäpaikoilla: rivit allekkain, kukin omana
   laatikkonaan. Ero on avatar, joka on rivin vasemmassa reunassa ja jonka
   vieressä teksti latoutuu kahdelle riville — tekijä ja kohde. Siksi rivi on
   `grid` eikä `flex`: flexissä molemmat tekstirivit olisivat avatarin
   sisarena, ja kohde latoutuisi sen alle eikä nimen alle.
   Oma tuorein avaus on `accent-softer`-taustalla (TOKENIT.md: "valittu versio,
   muuttuneet rivit"), ja reunaviiva kertoo saman ilman väriä. */
.katakri-avaukset{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:var(--space-2)}
.katakri-avaus{display:grid;grid-template-columns:auto minmax(0,1fr);
  align-items:start;gap:2px var(--space-3);
  padding:10px var(--space-3);border-radius:var(--radius-md);background:var(--sunken);
  border:var(--border-hairline) solid var(--line-1)}
.katakri-avaus--oma{background:var(--accent-softer);border-color:var(--accent-soft);
  box-shadow:inset 3px 0 0 var(--accent)}
/* Avatar on kahden tekstirivin korkuinen, joten se ulottuu molempien yli. */
.katakri-avatar{grid-row:span 2;display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;border-radius:var(--radius-pill);
  background:var(--accent);color:var(--on-shell);
  font-size:var(--text-caption);font-weight:var(--weight-semibold);
  letter-spacing:var(--tracking-normal);flex:none}
.katakri-avaus__tekija,.katakri-avaus__kohde{margin:0;display:flex;flex-wrap:wrap;
  align-items:center;gap:var(--space-2);min-width:0}
/* Flex-alkion oletus on `min-width:auto`: ilman tätä lyhennettykin tiiviste
   ja tapahtumatunnus työntäisivät rivin ulos kortista kapeassa palstassa,
   samoin kuin sääntörivillä (ks. `.katakri-saantorivi > *`). */
.katakri-avaus__tekija > *,.katakri-avaus__kohde > *{min-width:0}
.katakri-avaus__kohde{font-size:var(--text-caption);color:var(--ink-4)}

/* Kuittaus kirjatusta kannanotosta työjonossa. LUKITTU — tyojono.html */
.katakri-huomio--ok{background:var(--pos-soft);border-color:var(--pos);
  color:var(--ink-1)}

/* ============ Dokumenttivienti (keraajanakyma). LUKITTU — _dokumenttivienti.html ============ */
.katakri-dokumenttivienti{display:flex;flex-direction:column;gap:var(--space-5)}
/* Keruun virhe on oma kuvionsa eika varoitus: epaonnistunut vienti ei ole
   dokumentin puute, ja punainen erottaa sen hylatyn rivin keltaisesta
   (docs/ui/kierros-6/kuvat/p6-3-vienti-epaonnistui.png). */
.katakri-keruuvirhe{display:flex;flex-direction:column;gap:var(--space-2);
  padding:var(--space-4);border-radius:var(--radius-md);background:var(--neg-soft);
  border:var(--border-hairline) solid var(--neg-border)}
.katakri-keruuvirhe__otsikko{margin:0;font-weight:var(--weight-semibold);color:var(--neg-ink)}
.katakri-keruuvirhe__teksti{margin:0;font-size:var(--text-body-sm);color:var(--ink-2)}
/* Rivi sellaisenaan: nimi ja arvo rinnakkain tasalevyisella kirjasimella,
   jotta puuttuva kentta erottuu luettelosta ilman, etta sita etsitaan. */
.katakri-raakarivi{display:flex;flex-direction:column;gap:2px;margin:var(--space-2) 0 0;
  padding:var(--space-3);border-radius:var(--radius-md);background:var(--sunken)}
.katakri-raakarivi__kentta{display:grid;grid-template-columns:minmax(0,220px) minmax(0,1fr);
  gap:var(--space-3);padding:2px var(--space-2);border-radius:var(--radius-sm);
  font-family:var(--font-mono);font-size:var(--text-caption);word-break:break-all}
.katakri-raakarivi__kentta dt,.katakri-raakarivi__kentta dd{margin:0}
.katakri-raakarivi__kentta--puuttuu{background:var(--neg-soft);color:var(--neg-ink)}
/* Hylkayksen nimeama kentta, joka ei puutu: tuntemattomalla kentalla on arvo,
   ja punainen "puuttuu" vaittaisi rivilta tyhjaksi kohdan, jossa lukee jotain. */
.katakri-raakarivi__kentta--nimetty{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-raakarivi__puuttuu{color:var(--neg-ink)}
.katakri-puuttuva-kentta{padding:1px var(--space-2);border-radius:var(--radius-sm);
  background:var(--neg-soft);color:var(--neg-ink);font-family:var(--font-mono);
  font-size:var(--text-caption)}
.katakri-nimetty-kentta{padding:1px var(--space-2);border-radius:var(--radius-sm);
  background:var(--accent2-soft);color:var(--accent2-ink);font-family:var(--font-mono);
  font-size:var(--text-caption)}
/* ============ Valmistelija-agentin ehdotus (kierros 6, D6) ============
   Tilasivun merkinta M3. Katkoviivakehys ja kipinakuvake ovat se, mika erottaa
   ehdotuksen ihmisen hyvaksynnasta (M2) -- eivat tekstit. Hyvaksynnan asu
   tulee luokista `katakri-merkki--ok` (vihrea kannanotto) ja
   `katakri-navi__nimikirjaimet` (nimikirjaimet), eika tama lohko maarittele
   kumpaakaan: agentti ei hyvaksy (ADR 0051 kohta 9,
   `views/agent_suggestions.py`:n `APPROVAL_MARKERS`).

   Huomiovari on `--amber-600` eika `--state-success`: vihrea on varattu
   kannanotolle, ja huomiolla merkitty ehdotus, joka olisi samanvarinen kuin
   hyvaksynta, olisi juuri se ero, jonka tama lohko on olemassa pitamaan. */
.katakri-agenttiehdotus{display:flex;flex-direction:column;gap:var(--space-2);
  padding:var(--space-4);margin-top:var(--space-3);border-radius:var(--radius-md);
  border:var(--border-hairline) dashed var(--border-control);background:var(--surface-card)}
.katakri-agenttiehdotus__otsake{display:flex;align-items:center;gap:var(--space-2);margin:0;
  font-size:var(--text-overline);font-weight:var(--weight-semibold);
  letter-spacing:var(--tracking-wide);text-transform:uppercase;color:var(--accent2-ink)}
.katakri-agenttiehdotus__kipina{color:var(--accent2-ink)}
.katakri-agenttiehdotus__muistutus{margin:0;font-size:var(--text-body-md);
  font-weight:var(--weight-semibold);color:var(--text-heading)}
.katakri-agenttiehdotus__ratkeaa{margin:0;font-size:var(--text-body-sm);
  color:var(--text-body);line-height:1.5}
/* Ruotsinkielinen asu on pidempi: meta ja toiminnot rivittyvat
   (docs/ui/kierros-6/README.md §2). */
.katakri-agenttiehdotus__meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);
  margin:0;font-size:var(--text-caption);color:var(--text-label)}
.katakri-agenttiehdotus__toiminnot{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3)}
.katakri-agenttiehdotus__lomake{display:inline-flex;margin:0}
.katakri-agenttiehdotus__merkinta{font-size:var(--text-caption);font-weight:var(--weight-medium);
  color:var(--text-label)}
.katakri-agenttiehdotus__selite{flex-basis:100%;font-size:var(--text-caption);color:var(--text-hint)}
/* ============ Paasy asiakirjaan (kierros 7, K7-5/6/8/13) ============
   Kaksi palstaa yhdessa kortissa: vasen on tieto (tiivisteen tarkistus),
   oikea teko (asiakirjan avaus). Palstat ovat se, mika erottaa tavat
   toisistaan paikan perusteella (README §1), joten pystyviiva niiden valissa
   ei ole koriste: ilman sita kahden toiminnon ohjetekstit lukevat yhtena
   kappaleena, ja kayttajatestissa (P14) tavat erottuisivat vain sanoista.

   Ilman avausoikeutta oikeaa palstaa ei renderoida lainkaan, ja `auto-fit`
   antaa jaljelle jaavalle palstalle koko leveyden -- yksipalstainen kortti ei
   ole oma asettelunsa vaan sama ruudukko ilman toista alkiota (`p12-1`). */
.katakri-paasy__palstat{display:grid;gap:var(--space-5);align-items:start;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr))}
.katakri-paasy__palsta{display:flex;flex-direction:column;gap:var(--space-3);
  min-width:0;padding:var(--space-4) 0}
/* Erotin on palstojen valissa eika niiden ymparilla: reuna jokaisen palstan
   vasemmalla puolella piirtaisi viivan myos kortin vasempaan reunaan, jossa
   kortilla on jo oma reunansa. */
.katakri-paasy__palsta + .katakri-paasy__palsta{
  padding-left:var(--space-5);border-left:var(--border-hairline) solid var(--line-1)}
.katakri-paasy__otsake{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2);margin:0}
.katakri-paasy__nimi{font-size:var(--text-h4);font-weight:var(--weight-semibold);
  color:var(--ink-1)}
/* Kuvake erottaa tiedon teosta samalla tavalla kuin merkki: haalea harmaa
   tarkistukselle, korostusvari avaukselle (README §1:n taulukko). */
.katakri-paasy__kuvake{color:var(--ink-4)}
.katakri-paasy__kuvake--teko{color:var(--accent)}
.katakri-paasy__lomake,.katakri-paasy__toiminnot{display:flex;flex-wrap:wrap;gap:var(--space-2);margin:0}
/* Alarivi on kortin oma rivi palstojen alla: "Avaa dokumentinhallinnassa" vie
   pois sovelluksesta eika ole kummankaan palstan toiminto. */
.katakri-paasy__alarivi{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--space-3);margin:0;padding-top:var(--space-4);
  border-top:var(--border-hairline) solid var(--line-1)}
/* Tuloksen laatikko (README §3): valkoinen pohja, ohut reuna, ja vari vain
   merkissa. Pohjan varjaaminen tekisi tuloksesta luettavan vain ruudulta --
   tulostettu tai mustavalkoinen nakyma menettaisi sen eron, jonka vari kantaa,
   kun taas merkin teksti sailyy kummassakin. */
/* Apex 2.2 (tehtävä ebc2cfc3): `.katakri-tulosruutu*` renderöityy vain tämän
   tehtävän kahdessa lukitussa partiaalissa (`locked/_tarkistuksen_tulos.html`,
   `locked/_avauksen_vahvistus.html`), joten Apexin arvo on paikallaan. */
.katakri-tulosruutu{display:flex;flex-direction:column;gap:var(--space-2);
  padding:var(--space-4);border-radius:var(--radius-md);background:var(--card);
  border:var(--border-hairline) solid var(--line-1)}
.katakri-tulosruutu__ylarivi{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);margin:0}
.katakri-tulosruutu__hetki{font-size:var(--text-caption);color:var(--ink-3)}
.katakri-tulosruutu__selite{margin:0;font-size:var(--text-body-sm);color:var(--ink-2);
  line-height:var(--leading-normal)}
/* Vertailtavat arvot ovat tiivisteita: ne eivat katkea valilyonneista, joten
   `anywhere` on ainoa tapa pitaa ne palstan sisalla. */
.katakri-tulosruutu__kentat{display:flex;flex-direction:column;gap:var(--space-2);margin:0}
.katakri-tulosruutu__kentat dt{font-size:var(--text-caption);color:var(--ink-3)}
.katakri-tulosruutu__kentat dd{margin:0;font-size:var(--text-body-sm);overflow-wrap:anywhere}
/* Kapealla ruudulla palstat pinoutuvat, ja silloin erotin on vaakaviiva:
   pystyviiva pinon paalla piirtyisi tyhjaan tilaan sen sijaan, etta se
   erottaisi mitaan. Raja on sama kuin palstojen oma `minmax`-vahimmaisleveys
   kahdelle palstalle valeineen. */
@media (max-width:760px){
  .katakri-paasy__palsta + .katakri-paasy__palsta{padding-left:0;border-left:0;
    padding-top:var(--space-4);border-top:var(--border-hairline) solid var(--line-1)}
}
/* ============ Konfiguraatioehdotus (kierros 8, K8-2) ============
   Ikkuna, jossa konfiguraation osiota muokataan tekstina, verrataan voimassa
   olevaan ja ladataan tiedostona. Renderoituu `partials/_konfiguraatioehdotus
   .html`:ssa ja sen sivulla, jotka molemmat ovat `.katakri-hallintanakymat`in
   alla -- kortin, otsikoiden ja linkkien varit tulevat sielta, ja tassa on
   vain se, mita ikkuna itse on. */
.katakri-ehdotusikkuna{display:flex;flex-direction:column;gap:var(--space-4)}
.katakri-ehdotusikkuna__otsake{display:flex;flex-wrap:wrap;align-items:baseline;
  gap:var(--space-2) var(--space-3)}
.katakri-ehdotusikkuna__otsikko{margin:0}
/* Osoite on koodia: se nimeaa tiedoston ja taulun sellaisina kuin ne ovat
   konfiguraatiossa, ja suhteellinen leveys erottaa sen otsikon leipatekstista. */
.katakri-ehdotusikkuna__osoite{font-family:var(--font-mono);font-size:var(--text-caption);
  color:var(--ink-3)}
.katakri-ehdotusikkuna__lomake{display:flex;flex-direction:column;gap:var(--space-4);margin:0}
.katakri-ehdotusikkuna__nimike{font-size:var(--text-caption);font-weight:var(--weight-medium);
  color:var(--ink-3)}
/* Osionvaihto on oma GET-lomakkeensa eika osa ehdotuslomaketta (perustelu
   templatessa): se hakee valitun osion voimassa olevan tekstin, ja sen tulos
   korvaa muokkauskentan sisallon. */
.katakri-ehdotusikkuna__osiolomake{display:flex;flex-direction:column;
  gap:var(--space-2);margin:0}
/* Valitsin ja sen painike samalle riville: ne ovat yksi toiminto, ja
   allekkain painike nayttaisi koskevan alla olevaa muokkauskenttaa. */
.katakri-ehdotusikkuna__osiot{display:flex;flex-wrap:wrap;align-items:flex-end;
  gap:var(--space-2);max-width:32rem}
/* Nimike on valikon ylla, ei painikkeen: `flex-basis:100%` katkaisee rivin
   nimikkeen jalkeen, jolloin valikko ja painike jaavat samalle riville. */
.katakri-ehdotusikkuna__osiot .katakri-ehdotusikkuna__nimike{flex:1 1 100%}
/* Valikko vie jaljelle jaavan tilan, painike oman leveytensa. */
.katakri-ehdotusikkuna__osiot .katakri-syote{flex:1 1 14rem;min-width:0}
/* Ohje on valitsimen YLLA, koska se kertoo mita painike tekee: painikkeen
   jalkeen se olisi luettavissa vasta painalluksen jalkeen. */
.katakri-ehdotusikkuna__osio-ohje{margin:0}
/* Muokkauskentta on monospace ja `wrap="off"`, koska sisalto on TOML:aa:
   rivi on siina merkityksellinen yksikko, ja rivittyva pitka arvo nayttaisi
   kahdelta rivilta -- siis eri asialta kuin se, mita muutosluettelo laskee. */
/* Pinnan vari on `.katakri-hallintanakymat`-lohkossa tiedoston lopussa:
   sikalainen `.katakri-tekstialue`-saanto on (0,2,0) ja voittaisi taman. */
.katakri-ehdotusikkuna__teksti{font-family:var(--font-mono);font-size:var(--text-body-sm);
  line-height:var(--leading-normal);overflow-x:auto;white-space:pre;tab-size:2}
.katakri-ehdotusikkuna__muutokset{display:flex;flex-direction:column;gap:var(--space-2)}
.katakri-ehdotusikkuna__alaotsikko{margin:0;font-size:var(--text-body-md);
  font-weight:var(--weight-semibold);color:var(--ink-1)}
/* Muutosluettelo on laatikko valkoisella pohjalla ja vari vain merkissa ja
   rivin tekstissa (README §3:n sama periaate kuin tuloksilla): mustavalkoisena
   ja tulostettuna suunnan kantaa `-`/`+`, ei vari. */
.katakri-ehdotusdiff{display:flex;flex-direction:column;gap:2px;margin:0;padding:var(--space-3);
  list-style:none;border-radius:var(--radius-md);background:var(--card);
  border:var(--border-hairline) solid var(--line-1);font-family:var(--font-mono);
  font-size:var(--text-body-sm);line-height:var(--leading-normal);overflow-x:auto}
.katakri-ehdotusdiff__rivi{display:flex;gap:var(--space-2);white-space:pre}
.katakri-ehdotusdiff__merkki{flex:none;width:1ch;font-weight:var(--weight-semibold)}
.katakri-ehdotusdiff__rivi--poistuva{color:var(--neg-ink)}
.katakri-ehdotusdiff__rivi--tuleva{color:var(--pos-ink);background:var(--sunken)}
/* Alarivi: vasemmalla lause siita, ettei tallennusta ole, oikealla
   painikkeet. Rivittyy kapealla ruudulla, eika lausetta katkaista -- se on
   se, mika kertoo mita ikkuna ei tee. */
.katakri-ehdotusikkuna__alarivi{display:flex;flex-wrap:wrap;align-items:center;
  justify-content:space-between;gap:var(--space-3);margin:0;padding-top:var(--space-3);
  border-top:var(--border-hairline) solid var(--line-1)}
.katakri-ehdotusikkuna__selite{margin:0;flex:1 1 18rem}
.katakri-ehdotusikkuna__toiminnot{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
/* Pois kaytosta oleva "Lataa" on luettavissa muttei painettavissa: haalistettu
   painike, jota ei nay lainkaan, jattaisi kayttajan arvaamaan, mihin lataus
   katosi, kun muutoksia ei ole. */
.katakri-ehdotusikkuna__toiminnot .katakri-painike[disabled]{opacity:.55;cursor:not-allowed}
/* Katakri-kasikirjan linkki (ADR 0061 vaihe 1, tehtava e822fe9a). Kaksi
   asua samalle linkille, koska vaatimustunnus esiintyy nakymissa kahdessa
   asemassa (`templatetags/katakri_kasikirja.py`): tunnus itse on linkki
   siella, missa se on pelkkaa tekstia, ja kuvake tunnuksen vieressa siella,
   missa tunnus on jo linkki kontrollin sivulle.

   Kuvakemuoto on `inline-flex` ja `vertical-align:middle`, koska se
   sijoittuu tunnuksen peraan tekstiriville: pelkka `inline` jattaisi
   SVG:lle rivin alaosan ja nostaisi riviväliä. Vari on `--text-muted`, jotta
   kuvake ei kilpaile sen tunnuslinkin kanssa, jonka vieressa se on -- se on
   toissijainen siirtyma samalta rivilta. */
.katakri-kasikirjalinkki{color:var(--accent);text-decoration:underline;
  text-underline-offset:0.15em}
.katakri-kasikirjalinkki--kuvake{display:inline-flex;align-items:center;
  margin-left:var(--space-1);color:var(--text-label);text-decoration:none;
  vertical-align:middle}
.katakri-kasikirjalinkki--kuvake:hover,
.katakri-kasikirjalinkki--kuvake:focus-visible{color:var(--accent)}
/* Sanaston termilinkki (tehtava 6c7d04e6). Sama kaksi asua ja sama peruste
   kuin kasikirjalinkilla: termi itse on linkki siella, missa se on pelkkaa
   tekstia, ja kuvake termin vieressa siella, missa teksti on jo otsikko --
   otsikon korvaaminen linkilla veisi otsikon.

   `title` kantaa maaritelman, joten kuvake on se kohta, jossa lukija saa
   vastauksen ilman sivunvaihtoa. React-nakymissa sama vastaus avautuu
   paikallaan (`ui/src/sanasto/Termi.tsx`); Django-sivulla sita ei voi
   tehda ilman Reactia, ja linkki vie sanastoon omaan ikkunaansa. */
.katakri-sanastolinkki{color:var(--accent);text-decoration:underline;
  text-underline-offset:0.15em}
.katakri-sanastolinkki--kuvake{display:inline-flex;align-items:center;
  margin-left:var(--space-1);color:var(--text-label);text-decoration:none;
  vertical-align:middle}
.katakri-sanastolinkki--kuvake:hover,
.katakri-sanastolinkki--kuvake:focus-visible{color:var(--accent)}

/* ============ Vaatimusnäkymät — Apex 2.2 (tehtävä 38ecf4bb) ============
 * Vaatimusnäkymien jaetut komponentit Apexin tokeneilla. Kiinnike on
 * `.katakri-vaatimukset` `<main>`-elementissä, ja sen kantavat viisi
 * Django-näkymää — `vaatimuslista.html`, `vaatimus.html`,
 * `kehikon_kontrollit.html`, `kehikon_kontrolli.html`, `saanto.html` — sekä
 * niiden näyttömallit `naytot/vaatimuslista.html` ja `naytot/vaatimus.html`.
 * Laajennuspaikkojen partiaalit (`partials/_vaatimus_suodattimet.html`,
 * `partials/_kontrolli_lisatiedot.html`) renderöityvät näiden sivujen sisällä
 * ja saavat arvonsa samaa kautta.
 *
 * Miksi kiinnike eikä arvon vaihto paikallaan: päätös 2e305611
 * ("Apex-tokenien käyttöönotto tehdään scopattuna") hylkäsi kierroksen 1
 * siitä, että app-laajuista luokkaa muutettiin paikallaan ja Apexin väri
 * renderöityi sivulle, jolla ei vielä ollut omaa migraatiotehtäväänsä. Nämä
 * luokat renderöityvät monella sivulla: `.katakri-kortti` on 43 muussa
 * templatessa, `.katakri-painike*` 34:ssä, `.katakri-merkki*` 33:ssa,
 * `.katakri-taulukko` 8:ssa, `.katakri-murupolku` 21:ssä ja
 * `.katakri-ominaisuudet` 10:ssä.
 *
 * Vaatimusnäkymien OMAT luokat eivät ole tässä vaan omissa lohkoissaan
 * paikallaan vaihdettuina, koska mikään muu sivu ei lue niitä:
 * `.katakri-siru*`, `.katakri-luku`, `.katakri-ehdotus-rivi`,
 * `.katakri-varmuus*`, `.katakri-lahde*`, `.katakri-kartoitusrivi__*` ja
 * `.katakri-viite__kansiot`. Kiinnike maksaa spesifisyyttä, eikä sitä oteta
 * ilman syytä.
 *
 * Vaihdettuja ovat VAIN väri-, varjo- ja liiketokenit. Välistys, kulmat ja
 * typografia käyttävät ytimen omaa asteikkoa, kuten kehyksen (72ca7e29) ja
 * yleiskuvan (2e372620) migraatioissa: Apexilla ei ole typografian asteikkoa
 * tokeneina vaan se koodaa sen `font:`-lyhenteinä, eivätkä `--s*`/`--r-*`
 * vastaa `--space-*`:n ja `--radius-*`:n asteikkoja. Asteikot eivät siksi
 * yhdistyneet, kun Meshly-lohko poistui (teht. 24cd5d6c); molemmat ovat
 * tokens.css:ssä omina lohko-osinaan.
 * ------------------------------------------------------------------------ */

/* Sivun pinta ja leipäteksti. `--surface-page` ja `--text-body` ovat
   tehtävän 24cd5d6c jälkeen Apexin omia aliaksia (`var(--page)`,
   `var(--ink-2)`) eli sama arvo kuin tässä; kierroksella 1 ne olivat
   Meshlyn. Sääntö jää, koska kiinnike on se kohta, josta asiakas vaihtaa
   vaatimussivun pohjan ja tekstin teemallaan. */
.katakri-vaatimukset{background:var(--page);color:var(--ink-2)}
.katakri-vaatimukset h1,.katakri-vaatimukset h2,
.katakri-vaatimukset h3,.katakri-vaatimukset h4{color:var(--ink-1)}
.katakri-vaatimukset a{color:var(--accent)}
.katakri-vaatimukset a:hover{color:var(--accent-hover)}
/* Fokusrengas Apexin aksenttihalolla. Perussääntö `:focus-visible` on
   spesifisyydeltään (0,1,0) ja tämä (0,2,0), joten tämä voittaa näiden
   sivujen sisällä eikä kajoa muihin sivuihin. */
.katakri-vaatimukset :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* Murupolku: Apexin `.crumbs` on `--ink-3`, nykyinen kohta `--ink-1`.
   Erotin saa `--line-2`:n, joka on Apexin kontrollien viiva. */
.katakri-vaatimukset .katakri-murupolku{color:var(--ink-3)}
.katakri-vaatimukset .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-vaatimukset .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* Ylärivi (eyebrow) = Apexin `.t-eyebrow`, `--ink-3`. */
.katakri-vaatimukset .katakri-ylarivi{color:var(--ink-3)}

/* Kortti: Apexin `.card` on `--card` + `--line-1` + `--sh-card`. Nosto on
   `--sh-pop`, Apexin varjoasteikon seuraava askel. */
.katakri-vaatimukset .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-vaatimukset .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-vaatimukset .katakri-kortti--nostettava:hover{box-shadow:var(--sh-pop)}
.katakri-vaatimukset .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
.katakri-vaatimukset .katakri-kortti h2,
.katakri-vaatimukset .katakri-kortti h3{color:var(--ink-1)}

/* Painikkeet: Apexin `.btn-primary`, `.btn-outline` ja `.btn-ghost`.
   `filter:none` kumoaa Meshlyn `brightness(1.1)`-kirkastuksen — Apexilla
   hover on oma tokeninsa (`--accent-hover`) eikä sama väri kirkkaampana. */
.katakri-vaatimukset .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-vaatimukset .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-vaatimukset .katakri-painike--toissijainen{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-vaatimukset .katakri-painike--toissijainen:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}
.katakri-vaatimukset .katakri-painike--haamu{color:var(--ink-3)}
.katakri-vaatimukset .katakri-painike--haamu:hover{background:var(--sunken);color:var(--ink-1)}
.katakri-vaatimukset .katakri-tekstipainike{color:var(--accent)}

/* Merkki = Apexin `.chip`. Varoitus saa `--accent2-*`:n eikä `--warn`ia,
   koska Apexin `.chip.warn` on meripihkainen pehmeä pari (`--accent2-soft` /
   `--accent2-ink`); `--warn` on yksittäisväri ilman pehmeää vastinetta.
   Reunusmerkki on `.chip.line`. */
.katakri-vaatimukset .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-vaatimukset .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-vaatimukset .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-vaatimukset .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-vaatimukset .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-vaatimukset .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}

/* Taulukko = Apexin `.tbl`. Otsakerivi on `--sunken` + `--line-1` + `--ink-3`,
   solu `--ink-2` ja rivin osuma `--row-hover`. Vaatimuslistan ja kehikon
   kartoitustaulukon sarakemitat ovat omissa lohkoissaan eivätkä muutu. */
.katakri-vaatimukset .katakri-taulukko caption{color:var(--ink-3)}
.katakri-vaatimukset .katakri-taulukko th{background:var(--sunken);
  border-bottom-color:var(--line-1);color:var(--ink-3)}
.katakri-vaatimukset .katakri-taulukko td{border-bottom-color:var(--line-1);color:var(--ink-2)}
.katakri-vaatimukset .katakri-taulukko tbody tr:hover{background:var(--row-hover)}
.katakri-vaatimukset .katakri-vaatimus__nimi{color:var(--ink-1)}
.katakri-vaatimukset .katakri-vaatimus__osio{color:var(--ink-4)}
.katakri-vaatimukset .katakri-himmea{color:var(--ink-3)}

/* Tunnus: koneluettava vaatimustunnus on siirtymä, eli Apexin aksentti. */
.katakri-vaatimukset .katakri-tunnus{color:var(--accent)}

/* Edistymispalkki = Apexin `.meter`: ura `--sunken`, täyttö `--accent`. */
.katakri-vaatimukset .katakri-edistys{background:var(--sunken)}
.katakri-vaatimukset .katakri-edistys__taytto{background:var(--accent)}
.katakri-vaatimukset .katakri-edistys__taytto--ok{background:var(--pos)}
.katakri-vaatimukset .katakri-edistys__taytto--varoitus{background:var(--warn)}
.katakri-vaatimukset .katakri-edistys__nimike{color:var(--ink-3)}

/* Lomake = Apexin `.field` + `.inp`: nimike `--ink-3`, kenttä `--card`-pohja,
   `--line-2`-reunus ja `--ink-1`-teksti, vihje `--ink-4`, fokus aksentilla. */
.katakri-vaatimukset .katakri-kentta__nimike{color:var(--ink-3)}
.katakri-vaatimukset .katakri-syote{background:var(--card);border-color:var(--line-2);color:var(--ink-1)}
.katakri-vaatimukset .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-vaatimukset .katakri-syote:focus{border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}

/* Käsittelyhistoria: aika `--ink-4`, piste `--line-2`, teksti `--ink-2`. */
.katakri-vaatimukset .katakri-ketju__aika{color:var(--ink-4)}
.katakri-vaatimukset .katakri-ketju__piste{background:var(--line-2)}
.katakri-vaatimukset .katakri-ketju__teksti{color:var(--ink-2)}

/* Ominaisuuslista = Apexin `.row`-pari: erotin `--line-1`, nimi `--ink-3`,
   arvo `--ink-1`. */
.katakri-vaatimukset .katakri-ominaisuudet div{border-bottom-color:var(--line-1)}
.katakri-vaatimukset .katakri-ominaisuudet dt{color:var(--ink-3)}
.katakri-vaatimukset .katakri-ominaisuudet dd{color:var(--ink-1)}

/* Poikkeamarivi (`naytot/vaatimus.html`:n evidenssilohko): tässä vain värit,
   ei asettelua. Vakavuuden palkki on Apexin tilaväri `--neg`/`--warn`. */
.katakri-vaatimukset .katakri-poikkeama__vakavuus--korkea{background:var(--neg)}
.katakri-vaatimukset .katakri-poikkeama__vakavuus--keski{background:var(--warn)}
.katakri-vaatimukset .katakri-poikkeama__nimi{color:var(--ink-1)}
.katakri-vaatimukset .katakri-poikkeama__id{color:var(--ink-3)}
.katakri-vaatimukset .katakri-poikkeama__meta{color:var(--ink-3)}
.katakri-vaatimukset .katakri-poikkeama__maaraaika{color:var(--ink-4)}

/* Agentin ehdotus = Apexin `.banner.info`: `--accent-softer` pohja,
   `--accent-soft` reuna ja `--accent` vasen viiva. Kiinnikkeen takana eikä
   paikallaan, koska `.katakri-ehdotus` on jaettu kahden lukitun partiaalin
   kanssa (`locked/_puuttuvat_viitteet.html`, `locked/_tiivistemuutos.html`),
   jotka renderöityvät asiakirjan sivulla ja odottavat tehtävää ebc2cfc3. */
.katakri-vaatimukset .katakri-ehdotus{background:var(--accent-softer);border-color:var(--accent-soft);
  border-left-color:var(--accent)}
.katakri-vaatimukset .katakri-ehdotus__ikoni{color:var(--accent)}
.katakri-vaatimukset .katakri-ehdotus__nimike{color:var(--accent-ink)}
.katakri-vaatimukset .katakri-ehdotus__teksti{color:var(--ink-2)}

/* Koneluettava arvo tekstin seassa ja sen linkkimuoto; sanaston ja käsikirjan
   linkit samalla aksentilla. */
.katakri-vaatimukset code.katakri-koodi{color:var(--ink-2)}
.katakri-vaatimukset a.katakri-koodi{color:var(--accent)}
.katakri-vaatimukset .katakri-sanastolinkki,
.katakri-vaatimukset .katakri-kasikirjalinkki{color:var(--accent)}
.katakri-vaatimukset .katakri-sanastolinkki--kuvake,
.katakri-vaatimukset .katakri-kasikirjalinkki--kuvake{color:var(--ink-3)}
.katakri-vaatimukset .katakri-sanastolinkki--kuvake:hover,
.katakri-vaatimukset .katakri-sanastolinkki--kuvake:focus-visible,
.katakri-vaatimukset .katakri-kasikirjalinkki--kuvake:hover,
.katakri-vaatimukset .katakri-kasikirjalinkki--kuvake:focus-visible{color:var(--accent)}

/* ============ Poikkeamanäkymät — Apex 2.2 (tehtävä 08decf84) ============
 * Poikkeamien, ajautuman ja riskin hyväksynnän JAETUT komponentit Apexin
 * tokeneilla. Kiinnike on `.katakri-poikkeamanakymat` `<main>`-elementissä, ja
 * sen kantavat kolme Django-näkymää — `poikkeamat.html`, `ajautuma.html`,
 * `riskin_hyvaksynta.html` — sekä näyttömalli `naytot/poikkeamat.html`.
 * Partiaalit `_poikkeamalista.html` ja `_ajautumataulukko.html` renderöityvät
 * näiden sivujen sisällä ja saavat arvonsa samaa kautta. Kolmen templaten
 * lukitus koskee kenttiä eikä asua ("Ulkoasun saa vaihtaa"), joten luokan
 * lisääminen `<main>`-elementtiin on sallittu; yksikään niistä ei ole
 * `locked/`-hakemistossa.
 *
 * Miksi kiinnike eikä arvon vaihto paikallaan: päätös 2e305611
 * ("Apex-tokenien käyttöönotto tehdään scopattuna"). Nämä luokat renderöityvät
 * monella sivulla, joilla on oma migraatiotehtävänsä: `.katakri-kortti` on 43
 * muussa templatessa, `.katakri-merkki*` 32:ssa, `.katakri-painike*` 32:ssa,
 * `.katakri-murupolku` 20:ssä, `.katakri-syote` 13:ssa,
 * `.katakri-huomio` 25:ssä, `.katakri-poikkeama*` 6:ssa (mm.
 * `soveltuvuusrajaus.html`, `partials/_evidenssi_kortti.html`),
 * `.katakri-valintapalkki` 3:ssa, `.katakri-kontrollisiru`
 * `_paatoslokimerkinta.html`:ssä, `.katakri-vaitekoodi`
 * `_paatoslokilista.html`:ssä ja `.katakri-ajautumarivi__laji`
 * `perustila.html`:ssä.
 *
 * Näkymien OMAT luokat eivät ole tässä vaan omissa lohkoissaan paikallaan
 * vaihdettuina, koska mikään muu sivu ei lue niitä: `.katakri-mittaustila*`,
 * `.katakri-luokkamerkki*`, `.katakri-ajautumarivi` ja `--otsake`/`__kohde`,
 * `.katakri-arvopari*`, `.katakri-muutostietue*`, `.katakri-palautettu*`,
 * `.katakri-jakauma*`, `.katakri-valintapalkki__ohje` ja
 * `.katakri-navi__rooli--koodi`.
 *
 * `naytot/poikkeamat.html`:n navigaatio EI saa tästä riviäkään: `.katakri-navi*`
 * on kehyksen omaa nimiavaruutta ja migratoitiin tehtävässä 72ca7e29.
 *
 * Vastineet Apexin `components.css`:stä: `.card`, `.btn-primary`,
 * `.btn-outline`, `.chip`/`.chip.warn`/`.chip.neg`, `.field`, `.inp`,
 * `.banner.warn`, `.note-strip`, `.crumbs`, `.tbl` ja `.empty`.
 *
 * Vaihdettuja ovat VAIN väri-, varjo- ja reunavärit. Välistys, kulmat ja
 * typografia käyttävät ytimen omaa asteikkoa kuten tehtävissä 72ca7e29,
 * 2e372620 ja 38ecf4bb; asteikot eivät yhdistyneet, kun Meshly-lohko
 * poistui (teht. 24cd5d6c).
 *
 * Yksi poikkeus: lomakkeiden luokattomat `<select>`- ja `<textarea>`-kentät
 * saavat tässä myös mittansa. Niillä ei ole peruslohkon sääntöä, jonka arvo
 * voitaisiin vaihtaa — ydin antaa valikolle vain `max-width`in eikä
 * tekstialueelle mitään — joten pelkkä värin vaihto jättäisi ne selaimen
 * oletuksille. Mitat on luettu samoilta ytimen tokeneilta kuin niiden
 * `.katakri-syote`- ja `.katakri-tekstialue`-sisaruksilta, eli asteikko ei
 * muutu; vain kentät, jotka olivat sen ulkopuolella, tulevat sille.
 * ------------------------------------------------------------------------ */

/* Sivun pinta ja periytyvä leipätekstin väri. Pelkkä pohja ei riitä: edustaväri
   tulisi `body`-säännöstä (päätös 2e372620). Kierroksella 1 se oli Meshlyn
   `--ink-700`; tehtävän 24cd5d6c jälkeen `--text-body` on Apexin alias
   (`var(--ink-2)`), eli sama sävy kuin tässä. Sääntö jää, koska se on se
   kohta, josta asiakas vaihtaa näkymän musteen. */
.katakri-poikkeamanakymat{background:var(--page);color:var(--ink-2)}
.katakri-poikkeamanakymat h1,.katakri-poikkeamanakymat h2,
.katakri-poikkeamanakymat h3,.katakri-poikkeamanakymat h4{color:var(--ink-1)}
/* `a:hover` on spesifisyydeltään (0,1,1) kuten `.katakri-poikkeamanakymat a`,
   joten hover tarvitsee oman sääntönsä eikä riitä, että perustila on kirjoitettu. */
.katakri-poikkeamanakymat a{color:var(--accent)}
.katakri-poikkeamanakymat a:hover{color:var(--accent-hover)}
/* Fokusrengas Apexin aksenttihalolla. Perussääntö `:focus-visible` on (0,1,0)
   ja tämä (0,2,0), joten tämä voittaa näiden sivujen sisällä eikä kajoa muihin. */
.katakri-poikkeamanakymat :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Murupolku: Apexin `.crumbs` --------------------------------------- */
.katakri-poikkeamanakymat .katakri-murupolku{color:var(--ink-3)}
.katakri-poikkeamanakymat .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-poikkeamanakymat .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* --- Sivun otsikko: Apexin `.page-head .sub` ja `.t-eyebrow` ------------ */
.katakri-poikkeamanakymat .katakri-ylarivi{color:var(--ink-3)}
.katakri-poikkeamanakymat .katakri-johdanto{color:var(--ink-3)}

/* --- Kortti: Apexin `.card`, korostus `--accent`, tyhjä `.empty` -------- */
.katakri-poikkeamanakymat .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-poikkeamanakymat .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-poikkeamanakymat .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
.katakri-poikkeamanakymat .katakri-kortti__tyhjateksti{color:var(--ink-3)}

/* --- Merkki: Apexin `.chip`, `.chip.warn`, `.chip.neg` ------------------
   Varoitus saa `--accent2-*`:n eikä `--warn`ia, koska Apexin `.chip.warn` on
   meripihkainen pehmeä pari; `--warn` on yksittäisväri ilman pehmeää vastinetta
   (sama valinta kuin tehtävässä 38ecf4bb). */
.katakri-poikkeamanakymat .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-poikkeamanakymat .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-poikkeamanakymat .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}

/* --- Painike: Apexin `.btn-primary` ja `.btn-outline` -------------------
   `filter:none` kumoaa Meshlyn `brightness(1.1)`-kirkastuksen: Apexilla hover
   on oma tokeninsa (`--accent-hover`) eikä sama väri kirkkaampana. */
.katakri-poikkeamanakymat .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-poikkeamanakymat .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-poikkeamanakymat .katakri-painike--toissijainen{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-poikkeamanakymat .katakri-painike--toissijainen:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}

/* --- Kenttä ja syöte: Apexin `.field>label` ja `.inp` ------------------- */
.katakri-poikkeamanakymat .katakri-kentta__nimike{color:var(--ink-3)}
.katakri-poikkeamanakymat .katakri-syote{background:var(--card);border-color:var(--line-2);color:var(--ink-1)}
/* Vihjetekstille ei kirjoiteta sääntöä: yhdelläkään näiden sivujen syötteellä
   ei ole `placeholder`-attribuuttia (sama mitattu rajaus kuin 72ca7e29). */
.katakri-poikkeamanakymat .katakri-syote:focus{border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}

/* Luokattomat kentät. Avaus-, siirtymä- ja hyväksyntälomakkeen valikot ja
   tekstialueet renderöityvät ilman luokkaa (`poikkeamat.html` rivit 95, 102,
   137, 153 ja `riskin_hyvaksynta.html` rivit 54, 64), joten luokkaan nojaava
   sääntö ei tavoita niitä: ytimessä bare `select` saa vain `max-width:100%`
   eikä bare `textarea` mitään, eli ne piirtyivät selaimen oletuksilla
   kehyksen `.katakri-syote`-sisarustensa vieressä. Tyylittely on siksi
   rakenteesta, kuten päätös 02537cdd ratkaisi saman asian kirjausnäkymissä.

   `:not(.katakri-syote)` rajaa elementtisäännön pois luokallisista kentistä.
   `ajautuma.html`:n perustilavalikko on `katakri-syote katakri-syote--s`, ja
   elementtivalitsin (0,1,1) voittaisi `--s`-muunnoksen (0,1,0) korkeuden ja
   kokonsa. Tällä hetkellä se ei näkyisi — mitat on tahallaan luettu samoilta
   tokeneilta kuin `--s`:llä, joten arvot osuvat yhteen — eli rajaus pitää
   rajan paikallaan eikä korjaa nykyistä vikaa: ilman sitä valintapalkin
   kentän koon ratkaisisi lomakekenttien sääntö, ja seuraava muutos
   kumpaan tahansa niistä erottaisi ne äänettömästi. Tekstialueella on sama
   rajaus `.katakri-syote`n ja `.katakri-tekstialue`n varalta, vaikka
   kummallakaan näiden sivujen tekstialueista ei ole kumpaakaan luokkaa.
   `tests/test_ui_poikkeamanakymien_apex.py` mittaa, että voittaja on `--s`.

   Mitat ovat ytimen omalta asteikolta kuten muuallakin tässä lohkossa: valikko
   seuraa viereisten `--s`-syötteiden korkeutta (34 px) ja tekstialue ytimen
   `.katakri-tekstialue`n mittoja; vain värit, varjo ja reunaväri ovat
   Apexin (`.inp`, `textarea.inp`, `select.inp`). Leveyttä ei julisteta
   valikolle: ytimen `select{max-width:100%}` on se, joka pitää ylipitkän
   vaihtoehdon kortissa (ks. rivin 292 perustelu). */
.katakri-poikkeamanakymat select:not(.katakri-syote){height:34px;
  padding:0 var(--space-3);border-radius:var(--radius-md);
  border:var(--border-hairline) solid var(--line-2);background:var(--card);
  font-family:var(--font-sans);font-size:var(--text-body-sm);color:var(--ink-1);
  cursor:pointer}
.katakri-poikkeamanakymat select:not(.katakri-syote):focus{outline:none;
  border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}
.katakri-poikkeamanakymat textarea:not(.katakri-syote):not(.katakri-tekstialue){
  width:100%;min-height:88px;padding:10px var(--space-3);
  border-radius:var(--radius-md);
  border:var(--border-hairline) solid var(--line-2);background:var(--card);
  font-family:var(--font-sans);font-size:var(--text-body-sm);line-height:1.5;
  color:var(--ink-1);resize:vertical}
.katakri-poikkeamanakymat textarea:not(.katakri-syote):not(.katakri-tekstialue):focus{
  outline:none;border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}

/* Hyväksyntä- ja siirtymälomakkeen ohjerivi on Apexin `.field .hint`:n
   rinnakkainen muoto kortin leveydellä, eli `--ink-3`. */
.katakri-poikkeamanakymat .katakri-kuittauslomake__ohje{color:var(--ink-3)}

/* --- Huomio: Apexin `.banner.warn` ja `.note-strip` --------------------- */
.katakri-poikkeamanakymat .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
.katakri-poikkeamanakymat .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}

/* --- Valintapalkki (ajautuman GET-lomake): Apexin `.card` --------------- */
.katakri-poikkeamanakymat .katakri-valintapalkki{background:var(--card);border-color:var(--line-1)}
.katakri-poikkeamanakymat .katakri-valintapalkki__maarat{color:var(--ink-3)}

/* --- Tunnus ja määrä: siirtymä on aksentti, meta `.tbl .muted` ---------- */
.katakri-poikkeamanakymat .katakri-tunnus{color:var(--accent)}
.katakri-poikkeamanakymat .katakri-maara{color:var(--ink-3)}

/* --- Poikkeamarivi: vakavuuden palkki on Apexin tilaväri --------------- */
.katakri-poikkeamanakymat .katakri-poikkeama__vakavuus{background:var(--line-2)}
.katakri-poikkeamanakymat .katakri-poikkeama__vakavuus--korkea{background:var(--neg)}
.katakri-poikkeamanakymat .katakri-poikkeama__vakavuus--keski{background:var(--warn)}
.katakri-poikkeamanakymat .katakri-poikkeama__nimi{color:var(--ink-1)}
.katakri-poikkeamanakymat .katakri-poikkeama__id{color:var(--ink-3)}
.katakri-poikkeamanakymat .katakri-poikkeama__meta{color:var(--ink-3)}
.katakri-poikkeamanakymat .katakri-poikkeama__maaraaika{color:var(--ink-4)}

/* --- Ajautumataulukon jaetut osat --------------------------------------
   Lajiteksti on `.tbl .muted`. Kontrollisiru on Apexin `.chip.acc`:n kehys
   (`--accent-soft`) valkoisella pohjalla; sen teksti tulee linkkisäännöstä
   (`--accent`). Väitekoodi on `.note-strip`-sävyinen koodimerkintä. */
.katakri-poikkeamanakymat .katakri-ajautumarivi__laji{color:var(--ink-4)}
.katakri-poikkeamanakymat .katakri-kontrollisiru{background:var(--card);border-color:var(--accent-soft)}
.katakri-poikkeamanakymat .katakri-vaitekoodi{background:var(--sunken);color:var(--ink-2)}

/* --- Sanaston ja käsikirjan linkit ------------------------------------- */
.katakri-poikkeamanakymat .katakri-sanastolinkki,
.katakri-poikkeamanakymat .katakri-kasikirjalinkki{color:var(--accent)}
.katakri-poikkeamanakymat .katakri-sanastolinkki--kuvake,
.katakri-poikkeamanakymat .katakri-kasikirjalinkki--kuvake{color:var(--ink-3)}
.katakri-poikkeamanakymat .katakri-sanastolinkki--kuvake:hover,
.katakri-poikkeamanakymat .katakri-sanastolinkki--kuvake:focus-visible,
.katakri-poikkeamanakymat .katakri-kasikirjalinkki--kuvake:hover,
.katakri-poikkeamanakymat .katakri-kasikirjalinkki--kuvake:focus-visible{color:var(--accent)}

/* ============ Apex 2.2 — kehyksen sivujen jaetut komponentit ============
 * Tehtävä 72ca7e29. Yllä olevat lohkot migratoivat ne säännöt, jotka ovat
 * VAIN kehyksen omia (navi, ylärivi, käyttäjävalikko, agenttipaneeli,
 * priorisoija, perustila). Tässä lohkossa ovat ne komponentit, jotka kehyksen
 * sivut renderöivät mutta joita ne eivät omista: kortti, painike, merkki,
 * kenttä, syöte ja ominaisuuslista ovat samoja luokkia 30–45 muulla sivulla,
 * joiden migraatio on tehtävissä 03–12.
 *
 * Siksi app-laajuista sääntöä EI muuteta paikallaan vaan Apexin arvo annetaan
 * sivun omalla kiinnikkeellä — sama kuvio ja sama peruste kuin
 * `.katakri-kirjautuminen`illa (päätös 2e305611: kierros 1 hylättiin juuri
 * siitä, että app-laajuinen luokka muutettiin paikallaan ja Apexin väri
 * renderöityi sivulle, jota ei oltu migratoitu).
 *
 * Kiinnikkeet ovat merkkaukseen jo kirjoitettuja, koska nämä templatet ovat
 * lukittuja eikä tehtävä saa muuttaa merkkausta:
 *   `.katakri-perustila`              perustila.html (kääre sivun osioille)
 *   `[data-testid="priorisoija"]`     _priorisoija.html (juuri)
 *   `.katakri-paneeli`                _agenttipaneeli.html (juuri)
 *   `.katakri-agentti`                partials/_agenttipaneeli.html (juuri)
 *
 * Vastineet Apexin `components.css`:stä: `.card`, `.btn-primary`,
 * `.btn-outline`, `.chip`/`.chip.acc`/`.chip.pos`, `.field`, `.inp`,
 * `.banner.warn`, `.row` ja `.empty`.
 *
 * Kaksi kehyksen sivua ei saa tähän riviäkään, ja se on mitattu eikä
 * unohdettu: `403.html` ja `tyojonon_kehys.html` renderöivät kehyksen lisäksi
 * vain murupolun, otsikon ja kappaleen, eli app-laajuista peruskerrosta
 * (`body`, `h1`, `p`, `.katakri-murupolku`), joka on 21–45 sivulla eikä ole
 * kiinnitettävissä ilman merkkausmuutosta. Se migratoituu peruskerroksen
 * omassa tehtävässä. Sama koskee `partials/_ajon_rajaus.html`:ää, jolla ei
 * ole omaa luokkaa lainkaan — vain `.katakri-kortti` ja
 * `.katakri-ominaisuudet` sen sivun sisällä.
 * ================================================================== */

/* --- Kortti: Apexin `.card`, korostus `--accent` ------------------------ */
/* `:not(.katakri-paneeli--ei-kaytossa)` on kierroksen 1 hylkäyksen korjaus.
   `_agenttipaneeli.html`:n juuri kantaa kaikkia kolmea luokkaa silloin, kun
   agenttikerrosta ei ole: `katakri-kortti katakri-paneeli
   katakri-paneeli--ei-kaytossa`. Ilman rajausta tämä sääntö (0,2,0) voittaa
   muunnoksen (0,1,0, rivi 660) sekä spesifisyydellä että järjestyksellä, ja
   "ei käytössä" piirtyisi tavallisena korttina — `--card`, `--line-1` ja
   `--sh-card` vaimean `--sunken`in, vahvemman `--line-2`:n ja varjottomuuden
   tilalle. Katkoviiva jäisi, mutta se on vain toinen puoli erosta; vaimea
   pinta on toinen. Rajattuna muunnos ratkaisee kaikki kolme ominaisuutta,
   ja sen omat arvot ovat jo Apexin. */
.katakri-perustila .katakri-kortti,
[data-testid="priorisoija"].katakri-kortti,
.katakri-paneeli.katakri-kortti:not(.katakri-paneeli--ei-kaytossa){background:var(--card);
  border-color:var(--line-1);box-shadow:var(--sh-card)}
.katakri-perustila .katakri-kortti--korostus,
[data-testid="priorisoija"].katakri-kortti--korostus{border-top-color:var(--accent)}
/* Apexin `.empty` */
.katakri-perustila .katakri-kortti__tyhjateksti{color:var(--ink-3)}

/* --- Painike: Apexin `.btn-primary` ja `.btn-outline` ------------------- */
.katakri-perustila .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-perustila .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-perustila .katakri-painike--ensisijainen:focus-visible{box-shadow:var(--shadow-focus-accent)}
.katakri-agentti .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-agentti .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-agentti .katakri-painike--ensisijainen:focus-visible{box-shadow:var(--shadow-focus-accent)}
.katakri-paneeli .katakri-painike--toissijainen{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-paneeli .katakri-painike--toissijainen:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}
.katakri-paneeli .katakri-painike--toissijainen:focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Merkki: Apexin `.chip`, `.chip.acc`, `.chip.pos` ------------------- */
[data-testid="priorisoija"] .katakri-merkki--neutraali,
.katakri-paneeli .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
[data-testid="priorisoija"] .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-paneeli .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}

/* --- Kenttä ja syöte: Apexin `.field>label` ja `.inp` ------------------- */
.katakri-perustila .katakri-kentta__nimike{color:var(--ink-3)}
.katakri-perustila .katakri-syote,
.katakri-agentti .katakri-syote{border-color:var(--line-2);background:var(--card);color:var(--ink-1)}
/* Vihjeteksti on vain agenttipaneelin kentässä (`placeholder`-attribuutti
   `partials/_agenttipaneeli.html`:ssä); perustilan kahdessa kentässä ei ole
   vihjettä, joten sille ei kirjoiteta sääntöä. */
.katakri-agentti .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-perustila .katakri-syote:focus,
.katakri-agentti .katakri-syote:focus{border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}

/* --- Ominaisuuslista: Apexin `.row` ------------------------------------ */
.katakri-paneeli .katakri-ominaisuudet div{border-bottom-color:var(--line-1)}
.katakri-paneeli .katakri-ominaisuudet dt{color:var(--ink-3)}
.katakri-paneeli .katakri-ominaisuudet dd{color:var(--ink-1)}

/* --- Huomio (virhe/varoitus): Apexin `.banner.warn` -------------------- */
.katakri-perustila .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}

/* --- Tunnus, määrä ja ylärivi: Apexin linkki- ja `.t-meta`-muste ------- */
.katakri-perustila .katakri-tunnus,
[data-testid="priorisoija"] .katakri-tunnus{color:var(--accent)}
.katakri-perustila .katakri-maara,
.katakri-agentti .katakri-ylarivi{color:var(--ink-3)}

/* --- Linkit kehyksen sisällä ------------------------------------------- */
/* Kierroksen 1 hylkäyksen korjaus. Yllä oleva sääntö värittää KÄÄREEN, mutta
   linkki ei peri väriä kääreeltään: perustan `a`-sääntö (rivi 20) julistaa
   värin suoraan ankkurille. Kierroksella 1 se oli Meshlyn `--text-link`
   (`--blue-600`); tehtävä 24cd5d6c käänsi sen Apexin `--accent`iin, ja nämä
   säännöt jäävät, koska kehyksellä on oma hover-sävynsä ja koska asiakas
   ylikirjoittaa kehyksen linkit tästä. Kolme kehyksen linkkiä on juuri
   sellaisia — ne ovat
   luokattomia ankkureita värjätyn elementin sisällä:
     `_priorisoija.html:37`    `span.katakri-tunnus > a` (havainnon tunnus)
     `perustila.html:76`       `span.katakri-maara > a` (ketjutiiviste)
     `_agenttipaneeli.html`    `dd > a` riveillä 81, 127, 214 ja 255
                               (lukukelvoton tapahtuma, ehdotuksen,
                               vastaväitteen ja ajon evidenssitapahtumat)
   Apexilla ei ole omaa linkkitokenia: sen `components.css` värittää
   tunnisteen aksentilla, ja sama aksentti on `--text-link`in vastine tässä
   migraatiossa. Siksi lepotila on `--accent` ja osoitin `--accent-hover`,
   jotka vastaavat Meshlyn paria `--blue-600`/`--blue-700`. Alleviivaus tulee
   yhä perustan `a:hover`-säännöstä, joten vain väri vaihtuu.

   Rajaus on sama kuin muualla tässä lohkossa: kehyksen kiinnikkeen alla.
   `perustila.html:51` ja `_priorisoija.html:54` eivät tarvitse sääntöä —
   edellinen on `a.katakri-tunnus`, jonka yllä oleva sääntö (0,2,0) voittaa
   myös `a:hover`in (0,1,1), ja jälkimmäinen ei ole linkki lainkaan.
   `_agenttipaneeli.html:51`:n ankkuri on painike, jonka oma sääntö (0,2,0)
   voittaa tämän (0,1,2). */
[data-testid="priorisoija"] .katakri-tunnus a,
.katakri-perustila .katakri-maara a,
.katakri-paneeli dd a{color:var(--accent)}
[data-testid="priorisoija"] .katakri-tunnus a:hover,
.katakri-perustila .katakri-maara a:hover,
.katakri-paneeli dd a:hover{color:var(--accent-hover)}

/* ============ Yleiskuva — Apex 2.2 (tehtävä 2e372620) ============
 * Etusivun (`index.html` ja sen nayttomalli `naytot/index.html`) jaetut
 * komponentit Apexin tokeneilla. Kiinnike on `.katakri-yleiskuva`
 * `<main>`-elementissa: se on sivun oma luokka, ja juuri se rajaa Apexin
 * arvot taman sivun markkaukseen.
 *
 * Miksi kiinnike eika arvon vaihto paikallaan: paatos 2e305611
 * ("Apex-tokenien kayttoonotto tehdaan scopattuna") hylkasi kierroksen 1
 * siita, etta app-laajuista luokkaa muutettiin paikallaan ja Apexin vari
 * renderoityi sivulle, jolla ei viela ollut omaa migraatiotehtavaansa. Nama
 * luokat renderoituvat monella sivulla: `.katakri-kortti` 44 muussa
 * templatessa, `.katakri-painike*` 33:ssa, `.katakri-merkki*` 35:ssa,
 * `.katakri-tunnus` 13:ssa, `.katakri-murupolku` 23:ssa.
 *
 * Yleiskuvan OMAT luokat — `.katakri-banneri*`, `.katakri-kpi*`,
 * `.katakri-osaalue__nimi/__suhde`, `.katakri-porautumis*`,
 * `.katakri-sivun-alaosa` — eivat ole tassa: ne esiintyvat vain talla
 * sivulla, joten niiden arvo on vaihdettu omassa lohkossaan paikallaan.
 * Kiinnike on se, joka maksaa spesifisyyttä, eika sita oteta ilman syyta.
 *
 * Vaihdettuja ovat VAIN vari-, varjo- ja liiketokenit. Valistys, kulmat ja
 * typografia kayttavat ytimen omaa asteikkoa, kuten kehyksen migraatiossa
 * (teht. 72ca7e29): Apexilla ei ole typografian asteikkoa tokeneina, vaan se
 * koodaa sen `font:`-lyhenteina, eika `--s*`/`--r-*` vastaa `--space-*`:n ja
 * `--radius-*`:n asteikkoja. Asteikot eivat siksi yhdistyneet, kun
 * Meshly-lohko poistui (teht. 24cd5d6c).
 * ------------------------------------------------------------------------ */

/* Sivun pinta JA periytyva edustavari. `--surface-page` ja `--page` ovat
   lahes samat (#F4F6FA / #f4f5f7), mutta ero on juuri se, jonka asiakas
   vaihtaa teemallaan: ilman tata etusivun pohja tulisi perussaannosta.

   `color` on tassa samasta syysta, ja se on kierroksen 1 hylkayksen korjaus:
   pelkka pohja jatti sivun periytyvan edustavarin `body`-saannon
   `--text-body`iin, joka oli silloin Meshlyn `--ink-700` (tehtavan 24cd5d6c
   jalkeen se on Apexin alias `var(--ink-2)`). Jokainen elementti, jolla ei
   ole omaa varisaantoa, piirtyi siis yha Meshlyn musteella — nakyvimmin
   `partials/_jonon_dokumenttirivi.html`:n asiakirjaikoni
   (`.katakri-poikkeama__kuvake` > `.katakri-ikoni`), jonka veto on
   `icons.svg`:ssa `currentColor` eika silla ole omaa varisaantoa. Rivi
   renderoityy vain, kun jonossa on asiakirjoja, joten tyhja jono ei nayttanyt
   vikaa. `--ink-2` on Apexin oma leipatekstin muste: sen `components.css`
   julistaa `body{background:var(--page);color:var(--ink-2)}`. */
.katakri-yleiskuva{background:var(--page);color:var(--ink-2)}

/* Murupolku: Apexin `.crumbs` on `--ink-3`, nykyinen kohta `--ink-1`.
   Erotin saa `--line-2`:n, joka on Apexin kontrollien viiva. */
.katakri-yleiskuva .katakri-murupolku{color:var(--ink-3)}
.katakri-yleiskuva .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-yleiskuva .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* Ylarivi (eyebrow). Apexin `.t-eyebrow` on `--ink-3`; tumman bannerin
   kaanteinen asu on sama `--accent-on-dark` kuin kirjautumisessa. */
.katakri-yleiskuva .katakri-ylarivi{color:var(--ink-3)}
.katakri-yleiskuva .katakri-ylarivi--kaanteinen{color:var(--accent-on-dark)}

/* Kortti: Apexin `.card` on `--card` + `--line-1` + `--sh-card`. */
.katakri-yleiskuva .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-yleiskuva .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-yleiskuva .katakri-kortti--nostettava:hover{box-shadow:var(--sh-pop)}
.katakri-yleiskuva .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
/* `:not(.katakri-ylarivi)` on kierroksen 1 hylkayksen korjaus. KPI-kortin
   nimike on `<h2 class="katakri-ylarivi">` (`partials/_kypsyys_kpi.html`),
   eli sama elementti osuu seka taman kortin otsikkosaantoon (0,2,1) etta
   ylarivin saantoon (0,2,0) ylla. Ilman rajausta otsikko voittaa
   spesifisyydella ja kaikki nelja KPI-nimiketta piirtyvat `--ink-1`:lla,
   vaikka Apexin `.kpi .k` on `--ink-3`. Rajaus kattaa myos
   `katakri-ylarivi--kaanteinen`-muunnoksen, koska se kirjoitetaan aina
   `katakri-ylarivi`-perusluokan kanssa. */
.katakri-yleiskuva .katakri-kortti h2:not(.katakri-ylarivi),
.katakri-yleiskuva .katakri-kortti h3:not(.katakri-ylarivi){color:var(--ink-1)}
.katakri-yleiskuva .katakri-kortti__tyhjateksti{color:var(--ink-3)}
.katakri-yleiskuva .katakri-kortti__tyhjateksti a{color:var(--accent)}
.katakri-yleiskuva .katakri-maara{color:var(--ink-4)}

/* Painikkeet: Apexin `.btn-primary` ja `.btn-outline`. `filter:none` kumoaa
   Meshlyn `brightness(1.1)`-kirkastuksen — Apexilla hover on oma tokeninsa
   (`--accent-hover`) eika sama vari kirkkaampana. */
.katakri-yleiskuva .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-yleiskuva .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-yleiskuva .katakri-painike--toissijainen{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-yleiskuva .katakri-painike--toissijainen:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}
.katakri-yleiskuva .katakri-painike--haamu{color:var(--ink-3)}
.katakri-yleiskuva .katakri-painike--haamu:hover{background:var(--sunken);color:var(--ink-1)}
.katakri-yleiskuva .katakri-tekstipainike{color:var(--accent)}

/* Tunnus: koneluettava vaatimustunnus on siirtyma, eli Apexin aksentti. */
.katakri-yleiskuva .katakri-tunnus{color:var(--accent)}

/* Edistymispalkki = Apexin `.meter`: ura `--sunken`, taytto `--accent`. */
.katakri-yleiskuva .katakri-edistys{background:var(--sunken)}
.katakri-yleiskuva .katakri-edistys__taytto{background:var(--accent)}
.katakri-yleiskuva .katakri-edistys__taytto--ok{background:var(--pos)}
.katakri-yleiskuva .katakri-edistys__taytto--varoitus{background:var(--warn)}
.katakri-yleiskuva .katakri-edistys__nimike{color:var(--ink-3)}

/* Merkki = Apexin `.chip`. Varoitus saa `--accent2-*`:n eika `--warn`in,
   koska Apexin `.chip.warn` on meripihkainen pehmea pari (`--accent2-soft` /
   `--accent2-ink`); `--warn` on yksittaisvari ilman pehmeaa vastinetta. */
.katakri-yleiskuva .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-yleiskuva .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-yleiskuva .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-yleiskuva .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-yleiskuva .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-yleiskuva .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}

/* Taulukko = Apexin `.tbl`. Otsakerivi on `--sunken`, viivat `--line-1` ja
   rivin osuma `--row-hover`. */
.katakri-yleiskuva .katakri-taulukko caption{color:var(--ink-3)}
.katakri-yleiskuva .katakri-taulukko th{background:var(--sunken);
  border-bottom-color:var(--line-1);color:var(--ink-3)}
.katakri-yleiskuva .katakri-taulukko td{border-bottom-color:var(--line-1)}
.katakri-yleiskuva .katakri-taulukko tbody tr:hover{background:var(--row-hover)}
.katakri-yleiskuva .katakri-vaatimus__nimi{color:var(--ink-1)}
.katakri-yleiskuva .katakri-vaatimus__osio{color:var(--ink-4)}
.katakri-yleiskuva .katakri-luku{color:var(--ink-3)}
.katakri-yleiskuva .katakri-himmea{color:var(--ink-3)}

/* Jonon asiakirjarivi (`partials/_jonon_dokumenttirivi.html`) latoutuu
   etusivulla poikkeamariviksi: tassa vain sen varit, ei asettelua. */
.katakri-yleiskuva .katakri-poikkeama__nimi{color:var(--ink-1)}
.katakri-yleiskuva .katakri-poikkeama__id{color:var(--ink-3)}
.katakri-yleiskuva .katakri-poikkeama__meta{color:var(--ink-3)}
.katakri-yleiskuva .katakri-poikkeama__maaraaika{color:var(--ink-4)}

/* Fokusrengas Apexin aksenttihalolla. Perussaanto `:focus-visible` on
   spesifisyydeltaan (0,1,0) ja tama (0,2,0), joten tama voittaa taman sivun
   sisalla eika kajoa muihin sivuihin. */
.katakri-yleiskuva :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* ---------------------------------------------------------------------------
 * Valmistelija-agentin muistutus (`partials/_agentin_muistutus.html`).
 *
 * Ei `.katakri-yleiskuva`-kiinnikkeen alla: partiaali renderoityy asiakirjan
 * sivulla (`dokumentti.html`), ei etusivulla. Kiinnike on partiaalin oma
 * muunnosluokka `katakri-ehdotus--muistutus`, koska pelkka `.katakri-ehdotus`
 * — ja myos pari `.katakri-kortti.katakri-ehdotus` — on jaettu kahden lukitun
 * partiaalin kanssa (`locked/_puuttuvat_viitteet.html`,
 * `locked/_tiivistemuutos.html`), jotka renderoityvat samalla sivulla ja
 * odottavat omaa migraatiotehtavaansa.
 *
 * Asu on Apexin `.banner.info`: `--accent-softer` pohja, `--accent-soft`
 * reuna ja `--accent-ink` nimike. Vasen 3 px:n viiva sailyy — se on
 * `border-left`, ei varjo, eika siirra asettelua kuten reunamerkinta muualla.
 *
 * `box-shadow:none` ja `color` ovat kierroksen 1 hylkayksen korjaus. Juuri on
 * `katakri-kortti katakri-ehdotus katakri-ehdotus--muistutus`, joten se peri
 * `.katakri-kortti`:n varjon (kierroksella 1 Meshlyn `--shadow-sm`, nyt
 * Apexin `--sh-card`), jota muunnos ei kumonnut. Apexin `.banner`illa ei ole varjoa lainkaan, joten
 * oikea arvo on `none` eika toinen varjotokeni: lattea on osa sita asua.
 * `color` on sama periytymisaukko kuin yleiskuvan juuressa: ilman sita osion
 * varisaannottomat elementit (esim. `<time>` metarivilla, jos sen kaare
 * vaihtuu) tulisivat `body`n `--text-body`sta. `--ink-2` on Apexin leipamuste
 * ja sama arvo, joka `.katakri-ehdotus__teksti`illa jo on.
 * ------------------------------------------------------------------------- */
.katakri-ehdotus--muistutus{background:var(--accent-softer);border-color:var(--accent-soft);
  border-left-color:var(--accent);box-shadow:none;color:var(--ink-2)}
.katakri-ehdotus--muistutus .katakri-ehdotus__nimike{color:var(--accent-ink)}
.katakri-ehdotus--muistutus .katakri-ehdotus__teksti{color:var(--ink-2)}
.katakri-ehdotus--muistutus .katakri-ohje{color:var(--ink-3)}
.katakri-ehdotus--muistutus .katakri-ehdotus__meta{color:var(--ink-3)}
.katakri-ehdotus--muistutus code.katakri-koodi{color:var(--ink-2)}

/* ============ Kirjausnäkymät — Apex 2.2 (tehtävä 02537cdd) ============
 * `kirjaukset.html`, `kuittaukset.html`, `tapahtuma.html` ja `toiminto.html`
 * sekä kuittaussivun päätöslokipartiaalit (`_paatoslokivalinta.html`,
 * `_paatoslokimerkinta.html`, `_paatoslokilista.html`) ja tapahtumasivun
 * lukitut osat (`locked/_eheysketju.html`, `locked/_tiivisteen_tila.html`).
 *
 * Kiinnike on `.katakri-kirjausnakymat` näiden neljän näytön
 * `<main>`-elementissä. Se on tässä samasta syystä kuin yleiskuvalla: päätös
 * 2e305611 ("Apex-tokenien käyttöönotto tehdään scopattuna") hylkäsi
 * kierroksen, jossa app-laajuista luokkaa muutettiin paikallaan ja Apexin väri
 * renderöityi sivulle, jolla ei vielä ole omaa migraatiotehtäväänsä. Nämä
 * luokat renderöityvät muuallakin: `.katakri-kortti` 42 muussa templatessa,
 * `.katakri-painike` 33:ssa, `.katakri-merkki` 32:ssa, `.katakri-kentta`
 * 14:ssä, `.katakri-kuittauslomake` 5:ssä (mm. `konfiguraatio.html`,
 * `locked/_hyvaksyntalomake.html`, `riskin_hyvaksynta.html`).
 *
 * Myös päätöslokipartiaalien OMAT luokat (`.katakri-merkinta*`,
 * `.katakri-merkintataulu`, `.katakri-ajolista`, `.katakri-vastavaite`) ovat
 * kiinnikkeen takana eivätkä paikallaan: partiaalit renderöityvät myös
 * `paatoslokit.html`:ssä, joka odottaa omaa tehtäväänsä. Paikallaan ovat vain
 * ne luokat, jotka esiintyvät VAIN näiden näyttöjen omissa templateissa:
 * `.katakri-askelnumero`, `.katakri-hetket*` ja `.katakri-valvontapiste*`
 * (omissa lohkoissaan ylempänä).
 *
 * Vaihdettuja ovat VAIN väri-, varjo- ja liiketokenit. Välistys, kulmat ja
 * typografia käyttävät ytimen omaa asteikkoa kuten kehyksen (teht. 72ca7e29)
 * ja yleiskuvan (teht. 2e372620) migraatioissa; asteikot eivät yhdistyneet,
 * kun Meshly-lohko poistui (teht. 24cd5d6c).
 * ------------------------------------------------------------------------ */

/* Sivun pinta JA periytyvä edustaväri. `color` on tässä samasta syystä kuin
   yleiskuvan kiinnikkeessä: ilman sitä jokainen värisäännötön elementti —
   `tapahtuma.html`:n luokattomat `<dl>`/`<dd>`-rivit, `kirjaukset.html`:n
   kirjausketjun määritelmälistat ja `currentColor`illa vetävät `icons.svg`:n
   ikonit — perisi `body`n `--text-body`n, joka oli kierroksella 1 Meshlyn
   `--ink-700` (nyt Apexin alias `var(--ink-2)`). `--ink-2` on Apexin oma
   leipämuste (`body{color:var(--ink-2)}`). */
.katakri-kirjausnakymat{background:var(--page);color:var(--ink-2)}

/* Otsikot, linkit ja fokusrengas ovat ytimessä elementtisääntöjä
   (`h1,h2,h3,h4`, `a`, `:focus-visible`), joten ne eivät osu yhteenkään
   luokkasääntöön: ilman näitä sivun otsikot jäisivät `--text-strong`iin ja
   linkit `--text-link`iin. Spesifisyys (0,1,1) ja (0,2,0) voittaa ytimen
   (0,0,1):n ja (0,1,0):n vain tämän kiinnikkeen sisällä. */
.katakri-kirjausnakymat h1,.katakri-kirjausnakymat h2,
.katakri-kirjausnakymat h3,.katakri-kirjausnakymat h4{color:var(--ink-1)}
.katakri-kirjausnakymat a{color:var(--accent)}
.katakri-kirjausnakymat a:hover{color:var(--accent-hover)}
/* Fokus: Apexin `.inp:focus` ja `.btn:focus-visible` ovat molemmat
   `0 0 0 3px var(--accent-halo)`, jonka ydin tuntee nimellä
   `--shadow-focus-accent`. */
.katakri-kirjausnakymat :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* Murupolku ja ylärivi: Apexin `.crumbs` on `--ink-3`, nykyinen kohta
   `--ink-1`, erotin `--line-2`; `.t-eyebrow` on `--ink-3`. */
.katakri-kirjausnakymat .katakri-murupolku{color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-kirjausnakymat .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}
.katakri-kirjausnakymat .katakri-ylarivi{color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-johdanto{color:var(--ink-3)}

/* Kortti: Apexin `.card` on `--card` + `--line-1` + `--sh-card`. */
.katakri-kirjausnakymat .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-kirjausnakymat .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-kirjausnakymat .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
.katakri-kirjausnakymat .katakri-kortti__tyhjateksti{color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-maara{color:var(--ink-4)}
.katakri-kirjausnakymat .katakri-tunnus{color:var(--accent)}
.katakri-kirjausnakymat .katakri-ohje{color:var(--ink-3)}

/* Painikkeet: Apexin `.btn-primary`. `filter:none` kumoaa Meshlyn
   `brightness(1.1)`-kirkastuksen — Apexilla hover on oma tokeninsa. Perus
   `.katakri-painike` jää ilman omaa väriään kuten Apexin `.btn`, joka perii
   `--ink-2`:n; sen saa nyt kiinnikkeen juuresta. */
.katakri-kirjausnakymat .katakri-painike{transition:filter var(--duration-fast) var(--ease-standard),
  transform var(--duration-fast) var(--ease-standard),background var(--duration-fast) var(--ease-standard)}
.katakri-kirjausnakymat .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-kirjausnakymat .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-kirjausnakymat .katakri-tekstipainike{color:var(--accent)}

/* Lomakekentät = Apexin `.field` + `.inp`. Nimike `--ink-2` ja ohje
   `--ink-3`: Apexin `.field>label` on `--ink-3`, mutta näillä sivuilla sama
   `.katakri-kuittauslomake__nimike` on myös `<h3>`-otsikkona
   (`_paatoslokimerkinta.html`), joten nimike pysyy askeleen ohjetekstiä
   tummempana. */
.katakri-kirjausnakymat .katakri-kuittauslomake legend,
.katakri-kirjausnakymat .katakri-kuittauslomake__nimike,
.katakri-kirjausnakymat .katakri-kentta__nimike{color:var(--ink-2)}
.katakri-kirjausnakymat .katakri-kuittauslomake__ohje{color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-syote,
.katakri-kirjausnakymat .katakri-tekstialue{border-color:var(--line-2);background:var(--card);
  color:var(--ink-1)}
.katakri-kirjausnakymat .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-kirjausnakymat .katakri-syote:focus,
.katakri-kirjausnakymat .katakri-tekstialue:focus{border-color:var(--accent);
  box-shadow:var(--shadow-focus-accent)}
/* Kirjaussivun kentät renderöityvät ilman luokkaa (`kirjaukset.html`:n
   teksti-, luku-, päivä- ja valikkokentät), joten ne tyylitellään
   rakenteesta — sama ratkaisu kuin kirjautumisen Django-lomakkeella.
 *
 * `:not(.katakri-syote)` on rajaus eikä spesifisyyttä: samalla sivulla on
 * myös luokallisia kenttiä (`_paatoslokivalinta.html`:n rajaussuodattimet
 * ovat `katakri-syote katakri-syote--s`), ja elementtivalitsin voittaisi
 * niiden `--s`-muunnoksen korkeuden ja kokonsa. Rajattuna sääntö ei osu
 * niihin lainkaan, ja ne saavat Apexin arvot omasta säännöstään yllä.
 *
 * Radio ei ole tässä: `.katakri-kannanotto`n ja `.katakri-valvontapiste`en
 * valinta on natiivi, ja laatikkoasu peittäisi sen. `<textarea>` ei
 * myöskään: jokainen näiden sivujen tekstialue on `katakri-tekstialue`. */
.katakri-kirjausnakymat input[type="text"]:not(.katakri-syote),
.katakri-kirjausnakymat input[type="number"]:not(.katakri-syote),
.katakri-kirjausnakymat input[type="date"]:not(.katakri-syote),
.katakri-kirjausnakymat select:not(.katakri-syote){height:40px;padding:0 var(--space-3);
  border-radius:var(--radius-md);border:var(--border-hairline) solid var(--line-2);
  background:var(--card);font-family:var(--font-sans);font-size:var(--text-body-md);
  color:var(--ink-1)}
.katakri-kirjausnakymat input[type="text"]:not(.katakri-syote):focus,
.katakri-kirjausnakymat input[type="number"]:not(.katakri-syote):focus,
.katakri-kirjausnakymat input[type="date"]:not(.katakri-syote):focus,
.katakri-kirjausnakymat select:not(.katakri-syote):focus{outline:none;
  border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}

/* Kannanotto: kolme segmenttiä. Valittu segmentti on umpiväri, koska teksti
   kääntyy siinä valkoiseksi; "ei vielä kantaa" saa Apexin tumman musteen
   (`--ink-2`) samasta syystä kuin kierroksella 1 Meshlyn `--ink-700`. */
.katakri-kirjausnakymat .katakri-kannanotot{border-color:var(--line-2)}
.katakri-kirjausnakymat .katakri-kannanotto{background:var(--card);color:var(--ink-2)}
/* Myös `border-top-color`: kapealla näytöllä (`max-width:860px`) segmentit
   pinoutuvat ja perussääntö vaihtaa erottimen vasemmalta yläreunaan
   (`border-top:… var(--border-control)`). Pelkkä `border-left-color` jätti
   sen Meshlyn tokeniin — se oli ainoa Meshly-jäännös, jonka
   `tests/test_ui_meshly_tokenit.py` vielä löysi `kirjaukset.html`:sta ja
   `kuittaukset.html`:sta. Leveällä näytöllä yläreunan leveys on 0, joten
   väri ei näy siellä. */
.katakri-kirjausnakymat .katakri-kannanotto + .katakri-kannanotto{border-left-color:var(--line-2);
  border-top-color:var(--line-2)}
.katakri-kirjausnakymat .katakri-kannanotto:has(input:focus-visible){box-shadow:inset var(--shadow-focus-accent)}
.katakri-kirjausnakymat .katakri-kannanotto--accepted:has(input:checked){background:var(--pos);color:var(--on-shell)}
.katakri-kirjausnakymat .katakri-kannanotto--rejected:has(input:checked){background:var(--neg);color:var(--on-shell)}
.katakri-kirjausnakymat .katakri-kannanotto--deferred:has(input:checked){background:var(--ink-2);color:var(--on-shell)}

/* Huomiolaatikot = Apexin `.banner`. Varoitus on `.banner.neg`, koska näillä
   sivuilla se on validointivirhe eikä varoitus: `kirjausvirhe`,
   `kuittausvirhe`, `merkintavirhe` ja `jaksovirhe` ovat sen ainoat esiintymät
   (kolme omaa templatea + `_paatoslokivalinta.html`). Neutraali on Apexin
   `.note-strip`. Perusmuodolle Apexilla ei ole `.banner.pos`-vastinetta, joten
   pohja ja reuna ovat sama `--pos-soft`: lattea on tässä oikein, koska
   Apexilla ei ole positiivista reunatokenia eikä literaalia saa kirjoittaa. */
.katakri-kirjausnakymat .katakri-huomio{background:var(--pos-soft);border-color:var(--pos-soft);
  color:var(--pos-ink)}
.katakri-kirjausnakymat .katakri-huomio .katakri-ikoni{color:var(--pos-ink)}
.katakri-kirjausnakymat .katakri-huomio--varoitus{background:var(--neg-soft);
  border-color:var(--neg-border);color:var(--neg-ink)}
/* Huomautus jää meripihkaiseksi myös täällä: `aluetyypin-varoitus` on varoitus
   eikä validointivirhe — kirjaus menee läpi "Lähetä silti" -painikkeesta
   (kierros 8, K8-8) — joten se on Apexin `.banner.warn` eikä `.banner.neg`.
   Oma julistuksensa, jotta kiinnikkeen `--varoitus`-sääntö ei vie sitä
   negatiiviseksi. */
.katakri-kirjausnakymat .katakri-huomio--huomautus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
.katakri-kirjausnakymat .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}

/* Merkki = Apexin `.chip`. Varoitus saa `--accent2-*`:n kuten yleiskuvassa:
   Apexin `.chip.warn` on meripihkainen pehmeä pari. */
.katakri-kirjausnakymat .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-kirjausnakymat .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-kirjausnakymat .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-kirjausnakymat .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-kirjausnakymat .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}

/* Taulukko = Apexin `.tbl`: otsakerivi `--sunken`, viivat `--line-1`, rivin
   osuma `--row-hover`. Sama asu molemmilla taulukoilla, tapahtumasivun
   `.katakri-taulukko`lla ja päätöslokin `.katakri-merkintataulu`lla. */
.katakri-kirjausnakymat .katakri-taulukko caption{color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-taulukko th{background:var(--sunken);
  border-bottom-color:var(--line-1);color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-taulukko td{border-bottom-color:var(--line-1)}
.katakri-kirjausnakymat .katakri-taulukko tbody tr:hover{background:var(--row-hover)}
.katakri-kirjausnakymat .katakri-merkintataulu th{background:var(--sunken);color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-merkintataulu td{border-top-color:var(--line-1)}
.katakri-kirjausnakymat .katakri-merkintataulu td[data-testid="rivin-rooli"],
.katakri-kirjausnakymat .katakri-merkintataulu td[data-testid="rivin-hetki"]{color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-merkintataulu tr[aria-current="true"] td{background:var(--accent-soft)}
.katakri-kirjausnakymat .katakri-merkintataulu tr[aria-current="true"] td:first-child{
  box-shadow:inset 3px 0 0 var(--accent)}

/* Ominaisuuslistat (tapahtuman tiedot, päätöslokin merkintä, pienet
   tietoparit): nimike `--ink-3`, arvo `--ink-1`, erotin `--line-1` — Apexin
   `.row>dt` / `.row>dd`. */
.katakri-kirjausnakymat .katakri-ominaisuudet div{border-bottom-color:var(--line-1)}
.katakri-kirjausnakymat .katakri-ominaisuudet dt,
.katakri-kirjausnakymat .katakri-merkinta__tiedot dt,
.katakri-kirjausnakymat .katakri-tiedot-pieni dt,
.katakri-kirjausnakymat .katakri-valintapalkki__maarat{color:var(--ink-3)}
.katakri-kirjausnakymat .katakri-ominaisuudet dd,
.katakri-kirjausnakymat .katakri-merkinta__tiedot dd,
.katakri-kirjausnakymat .katakri-tiedot-pieni dd,
.katakri-kirjausnakymat .katakri-merkinta__perustelu{color:var(--ink-1)}
.katakri-kirjausnakymat .katakri-merkinta__perusteet,
.katakri-kirjausnakymat .katakri-merkintalista__ajot{border-top-color:var(--line-1)}
.katakri-kirjausnakymat .katakri-vaitekoodi{color:var(--ink-2);background:var(--sunken)}

/* Vastaväite: vasen 3 px:n viiva kertoo lopputuloksen, ja neutraali on
   Apexin kontrolliviiva `--line-2`. */
.katakri-kirjausnakymat .katakri-vastavaite{border-color:var(--line-1);border-left-color:var(--line-2)}
.katakri-kirjausnakymat .katakri-vastavaite[data-lopputulos="upheld"],
.katakri-kirjausnakymat .katakri-vastavaite[data-kannanotto="accepted"]{border-left-color:var(--pos)}
.katakri-kirjausnakymat .katakri-vastavaite[data-lopputulos="rebutted"],
.katakri-kirjausnakymat .katakri-vastavaite[data-kannanotto="rejected"]{border-left-color:var(--neg)}

/* Valintapalkki, kontrollisiru ja katkoviivaiset "ei käytössä" -laatikot. */
.katakri-kirjausnakymat .katakri-valintapalkki{background:var(--card);border-color:var(--line-1)}
.katakri-kirjausnakymat .katakri-kontrollisiru{border-color:var(--accent-soft);background:var(--card)}
.katakri-kirjausnakymat .katakri-priorisoija--pois,
.katakri-kirjausnakymat .katakri-ajolista > li{background:var(--sunken);border-color:var(--line-2)}

/* Koodilohko (tapahtuman JSON): Apexin tumma pinta `--shell-1` ja sen teksti
   `--on-shell-2`. Kopiointipainike on sen vieressä leipätekstin musteella. */
.katakri-kirjausnakymat .katakri-koodilohko{background:var(--shell-1);color:var(--on-shell-2)}
.katakri-kirjausnakymat .katakri-kopioi{color:var(--ink-4)}
.katakri-kirjausnakymat .katakri-kopioi:hover{color:var(--accent)}
.katakri-kirjausnakymat .katakri-kopioi[data-kopioitu]{color:var(--pos)}
/* ============ Ohjeistonäkymät — Apex 2.2 (tehtävä 0d9d475f) ============
 * Käsikirja (`kasikirja.html`), sen päivitys (`kasikirjan_paivitys.html`),
 * sanasto (`sanasto.html`), ohjekeskus (`ohje.html`) ja kirjautumisen avoin
 * ohje (`kirjautumisohje.html`) Apexin tokeneilla. Kiinnike on
 * `.katakri-ohjeistonakymat`: neljällä ensimmäisellä se on
 * `<main class="katakri-paaosa">`issa, viidennellä sivun juuressa, joka on
 * kirjautumisen kehys.
 *
 * NÄMÄ VIISI NÄKYMÄÄ OVAT REACTIA, eivät Django-merkkausta. Template on vain
 * nipun kiinnityskohta (ADR 0061 kohta 5), ja sivun sisällön piirtää
 * `katakri-ui.js` elementtiin `#katakri-ui`, joka on kiinnikkeen sisällä.
 * Sisällön tyylit ovat nipun omissa tiedostoissa (`ui/src/**.css`), ja ne
 * ladataan `katakri.css`:n JÄLKEEN.
 *
 * SIDONTALOHKO ON POISTETTU (tehtävä 24cd5d6c). Tässä oli lohko
 * `.katakri-ohjeistonakymat{--text-body:var(--ink-2); …}`, joka määritteli
 * Meshlyn alias­nimet uudelleen Apexin arvoihin kiinnikkeen alla: nippu
 * viittasi Meshlyn nimiin, ja periytyvä custom property vei Apexin arvon
 * koko alipuuhun ilman spesifisyyskamppailua. Sidonta oli kiertotie, ja
 * lohkon oma muistiinpano nimesi sen ehdon, jolla se purkautuu: "Tehtävä
 * 09c9ad32 määrittelee ne [neljä aliasta], kun Meshly-lohko poistuu — ja
 * silloin tämä sidontalohko voi kadota kokonaan."
 *
 * Ehto täyttyi. `tokens.css` on nyt Apexin oma semantic.css kokonaisuudessaan
 * (myös `--surface-page`, `--surface-card`, `--surface-sunken`,
 * `--text-body`), eikä nipun tarvitse nimetä Meshlyä: `ui/src/**.css` viittaa
 * suoraan Apexin aliaksiin (`--text-label`, `--border-divider`,
 * `--action-primary`, `--status-neg`). Nipun oma mittari
 * `ui/tyokalut/tokenit.test.ts` vartioi tätä: jokainen nipun tunnus on
 * `tokens.css`:ssä, eikä yksikään ole paletin tunnus, jolle Apex nimeää
 * aliaksen.
 *
 * Jäljelle jäävät alla vain ne säännöt, jotka ovat OIKEASTI sivukohtaisia:
 * murupolun sävyt, ohjenäkymän leipäkoko ja linkin osoitinasu. Välistys,
 * kulmat ja typografia ovat ytimen asteikkoa (`--space-*`, `--radius-*`,
 * `--text-*`), ei Meshlyä; Apexilla ei ole niille vastinetta.
 * ---------------------------------------------------------------------- */
/* Pinta ja periytyvä edustaväri. Pelkkä pohja ei riitä: ilman `color`ia
   jokainen värisäännötön elementti — myös `icons.svg`:n `currentColor` —
   piirtyisi `body`n väristä. Sääntö jää, vaikka `body` on nyt sekin
   Apexilla: kiinnike on se kohta, jossa näkymän pinta on päätetty, ja
   asiakas ylikirjoittaa sen tästä. */
.katakri-ohjeistonakymat{background:var(--page);color:var(--ink-2)}

/* Murupolku: Apexin `.crumbs` on `--ink-3`, nykyinen kohta `--ink-1` ja
   erotin kontrollien viiva `--line-2`. Samat arvot kuin yleiskuvalla; ne
   kirjoitetaan tähän eikä sidota `--text-subtle`-aliaksen kautta, koska
   Meshlyn murupolku on `--text-subtle` (`--ink-400`) ja Apexin `.crumbs`
   `--ink-3`, eivätkä ne ole saman asteikon sama askel. */
.katakri-ohjeistonakymat .katakri-murupolku{color:var(--ink-3)}
.katakri-ohjeistonakymat .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-ohjeistonakymat .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* Ohjenäkymän leipäkoko. Nimitörmäys, ei Apex-asia, mutta se osuu juuri
   sisältötypografiaan: `.katakri-ohje` on SEKÄ tämän tiedoston yleinen
   vihjeteksti (12 px, `--text-caption`) ETTÄ ohjekeskuksen näkymäjuuri
   (`ui/src/ohje/ohje.css`). Nipun sääntö voittaa värin ja kirjainperheen —
   se ladataan myöhemmin, sama spesifisyys — mutta `font-size` on vain
   täällä, joten koko ohjekeskus ja avoin ohje latoutuivat 12 pikselillä.
   Mitattu: sama ohjesivu renderöityy ohjepaneelissa 15 px:llä (paneeli ei
   ole `.katakri-ohje`n sisällä) ja lukualueella 12 px:llä.

   Korjaus on rajattu kiinnikkeeseen eikä kirjoitettu nipun puolelle: nipun
   näkymäjuuri ei julista kokoa tahallaan — se perii sivun leipäkoon — ja
   yleinen vihjeteksti pysyy 12 px:nä kaikkialla muualla, myös
   `.katakri-ehdotus--muistutus`in sisällä. */
.katakri-ohjeistonakymat .katakri-ohje{font-size:var(--text-body-md)}

/* Linkin osoitinasu. Perussäännön `a:hover` oli Meshlyn `--blue-700`,
   paletin tunnus eikä alias, joten sitä ei voitu sitoa aliaksen kautta ja
   se vaihdettiin säännöllä. Tehtävä 24cd5d6c käänsi perussäännön Apexin
   `--accent-hover`iin, eli samaan arvoon kuin tässä; sääntö jää, koska
   asiakas ylikirjoittaa ohjeistonäkymien linkit tästä. */
.katakri-ohjeistonakymat a:hover{color:var(--accent-hover)}

/* Ensisijainen painike Apexin aksentilla, kuten kirjautumisessa ja
   yleiskuvassa. `filter:none` kumoaa Meshlyn `brightness(1.1)`-kirkastuksen:
   Apexilla hover on oma tokeninsa eikä sama väri kirkkaampana. Kiinnike on
   tässä, koska `.katakri-painike--ensisijainen` on 33 muussa templatessa. */
.katakri-ohjeistonakymat .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-ohjeistonakymat .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}

/* Toissijainen painike = Apexin `.btn-outline`. Tämän kiinnikkeen alla ovat
   käsikirjan, sanaston ja ohjekeskuksen hakulomakkeiden painikkeet (tehtävä
   05f08f7e) JA käsikirjan vaatimuspaneelin sulkupainike
   (`ui/src/kasikirja/Paneeli.tsx:129`, renderöityy `kasikirja.html`in
   kiinnikkeen sisälle, rivi 49). Työjonon samat luokat EIVÄT ole: sen kehys
   ei kanna kiinnikettä (päätös 2e305611), ja ero on mitattu
   `tests/test_ui_paneelin_ja_tyojonon_asu.py`:ssä.
   Kirjoitettu säännöksi eikä sidonnaksi,
   koska perussäännön `.katakri-painike--toissijainen` muste on `--ink-700`
   — Meshlyn PALETIN tunnus, ei aliasta, jonka kiinnike voisi määritellä
   uudelleen. Sama ratkaisu kuin yleiskuvalla (teht. 2e372620) ja
   dokumenttinäkymillä. */
.katakri-ohjeistonakymat .katakri-painike--toissijainen{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-ohjeistonakymat .katakri-painike--toissijainen:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}

/* Lomakekenttä = Apexin `.inp`: kontrollien viiva `--line-2`, kortin pinta
   ja otsikkomuste, vihjeteksti `--ink-4`, fokus aksentilla ja sen halolla.
   Perussääntö lukee `--border-default`in, `--border-focus`in ja
   `--text-subtle`n; ne jäisivät Meshlyyn, koska kiinnikkeen sidontalohko
   sitoo vain ne aliakset, joihin NIPUN tyylit viittaavat — eivätkä nämä
   kolme ole niiden joukossa. Sama sääntömuoto kuin kirjausnäkymillä. */
.katakri-ohjeistonakymat .katakri-syote{border-color:var(--line-2);background:var(--card);
  color:var(--ink-1)}
.katakri-ohjeistonakymat .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-ohjeistonakymat .katakri-syote:focus{border-color:var(--accent);
  box-shadow:var(--shadow-focus-accent)}

/* ============ Tunnistautumisnäytöt — Apex 2.2 (tehtävä e9990199) ============
 * Kolme kirjautumisperheen sivua (`kirjautuminen_toinen_tekija.html`,
 * `kirjautuminen_varakoodi.html`, `kirjautuminen_kayttoonotto.html`) ja
 * yllapitajan nollaussivu (`toisen_tekijan_nollaus.html`).
 *
 * Perheen OMAT luokat ovat Apexilla jo yllaolevassa "Kirjautuminen v2"
 * -lohkossa paikallaan: `.katakri-vaihe*`, `.katakri-tunnistettu*`,
 * `.katakri-koodi*`, `.katakri-kayttoonotto*`, `.katakri-qr`,
 * `.katakri-avain`, `.katakri-politiikka*` ja `.katakri-kirjautumisvirhe`
 * esiintyvat vain naissa templateissa (mitattu `grep`illa koko
 * templatepuusta), joten niiden arvo on vaihdettu siella eika kiinnikkeen
 * takana.
 *
 * Tassa ovat vain JAETUT komponentit, jotka renderoityvat myos sivuilla,
 * joilla ei viela ole omaa migraatiotehtavaansa: `.katakri-ohje`,
 * `.katakri-kentta__nimike`, `.katakri-tekstipainike`, `.katakri-painike*`,
 * `.katakri-huomio*`, `.katakri-kortti*`, `.katakri-murupolku`,
 * `.katakri-johdanto`, `.katakri-tunnus` ja `.katakri-syote`. Kiinnike on se,
 * joka rajaa Apexin arvon naihin sivuihin — paatos 2e305611 ("Apex-tokenien
 * kayttoonotto tehdaan scopattuna") hylkasi kierroksen, jossa app-laajuista
 * luokkaa muutettiin paikallaan.
 *
 * KAKSI KIINNIKETTA, EI YHTA. Kirjautumisperheen kolme sivua perivat
 * `_kirjautumisen_runko.html`:n `.katakri-kirjautuminen`-kaareen, ja paatos
 * "2e305611:n piiri on koko kirjautumisperhe" nimeaa sen koko perheen
 * kiinnikkeeksi — uutta ei tarvita. Nollaussivu ei ole kirjautumisvaihe vaan
 * kirjautuneen yllapitajan sivu sovelluskehyksessa, joten se ei ole sen
 * kaareen sisalla; sen kiinnike on `katakri-toisen-tekijan-nollaus`
 * `<main>`-elementissa. Kehyksen oma asu (navi, ylarivi) EI ole tassa: se on
 * tehtavan 72ca7e29 ala, eika se ole viela landannut.
 *
 * Vaihdettuja ovat vain vari- ja varjotokenit. Valistys, kulmat ja typografia
 * kayttavat ytimen omaa asteikkoa, kuten yleiskuvan ja kehyksen
 * migraatiossa.
 * ------------------------------------------------------------------------ */

/* --- Kirjautumisperhe: toinen tekija, varakoodi, kayttoonotto ------------ */

/* Pikkuteksti ja kentan nimike. Apexin `.field .hint` on `--ink-4` ja
   `.field>label` `--ink-3`; `.katakri-ohje` on talla sivujoukolla molemmissa
   rooleissa (koodikentan vihje ja otsikon alla oleva johdanto), joten se saa
   yhden arvon — Apexin yleisen vaimean musteen. */
.katakri-kirjautuminen .katakri-ohje{color:var(--ink-3)}
.katakri-kirjautuminen .katakri-kentta__nimike{color:var(--ink-3)}

/* Tekstilinkki lomakkeessa ("vaihda kayttaja", "kayta varakoodia") = Apexin
   aksentti, sama kuin yleiskuvan `.katakri-tekstipainike`. */
.katakri-kirjautuminen .katakri-tekstipainike{color:var(--accent)}

/* Haamupainike = Apexin `.btn-ghost`: lepotilassa `--ink-3`, osoittimella
   `--sunken` + `--ink-1`. Renderoityy vain kayttoonotossa ja vain silloin,
   kun ohitus on sallittu ("Ohita toistaiseksi"). */
.katakri-kirjautuminen .katakri-painike--haamu{color:var(--ink-3)}
.katakri-kirjautuminen .katakri-painike--haamu:hover{background:var(--sunken);color:var(--ink-1)}

/* Kayttoonoton "pida koodit tallessa" -huomio. Apexin `.banner`illa ei ole
   myonteista muunnosta — se tuntee vain `warn`, `info` ja `neg` — joten asu
   on `.chip.pos`:n pari bannerin muodossa: `--pos-soft` pohja ja `--pos-ink`
   teksti. Reuna saa saman `--pos-soft`:n, koska Apexissa ei ole myonteista
   reunatokenia (`--neg-border` ja `--accent2-border` ovat sen ainoat
   vastineet) eika tama paketti tuo uusia tokeneita. Ikoni seuraa tekstia
   kuten Apexin `.banner .i`, joka perii varinsa bannerilta. */
.katakri-kirjautuminen .katakri-huomio{background:var(--pos-soft);border-color:var(--pos-soft);
  color:var(--pos-ink)}
.katakri-kirjautuminen .katakri-huomio .katakri-ikoni{color:var(--pos-ink)}

/* Fokusrengas Apexin aksenttihalolla koko perheelle. Perussaanto
   `:focus-visible` on spesifisyydeltaan (0,1,0) ja tama (0,2,0), joten tama
   voittaa naiden sivujen sisalla eika kajoa muihin. Ennen tata vain
   ensisijainen painike, ohjelinkki ja koodikentta saivat Apexin renkaan;
   haamupainike ja tekstilinkit jaivat Meshlyn `--shadow-focus`:iin. */
.katakri-kirjautuminen :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Yllapitajan nollaussivu --------------------------------------------- */

/* Sivun pinta JA periytyva edustavari, sama pari kuin yleiskuvan
   kiinnikkeessa: ilman `color`ia varisaannottomat elementit — nostojen
   ikonit etunenassa — perisivat `body`n `--text-body`n. */
.katakri-toisen-tekijan-nollaus{background:var(--page);color:var(--ink-2)}

.katakri-toisen-tekijan-nollaus h1{color:var(--ink-1)}
.katakri-toisen-tekijan-nollaus .katakri-johdanto{color:var(--ink-3)}

/* Murupolku: Apexin `.crumbs` on `--ink-3`, nykyinen kohta `--ink-1`,
   erotin `--line-2`. */
.katakri-toisen-tekijan-nollaus .katakri-murupolku{color:var(--ink-3)}
.katakri-toisen-tekijan-nollaus .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-toisen-tekijan-nollaus .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* Virhe ja kirjaamattomien tapahtumien rivi = Apexin `.banner.warn`:
   `--accent2-soft` pohja, `--accent2-border` reuna ja `--accent2-ink`
   teksti. Ikonille on oma saanto, koska perussaanto
   `.katakri-huomio .katakri-ikoni` on pidempi valitsin kuin muunnos ja
   maalaisi kilven vihreaksi keltaisella pohjalla. */
.katakri-toisen-tekijan-nollaus .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
.katakri-toisen-tekijan-nollaus .katakri-huomio--varoitus .katakri-ikoni{color:var(--accent2-ink)}

/* Kortti = Apexin `.card`: `--card` + `--line-1` + `--sh-card`. */
.katakri-toisen-tekijan-nollaus .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-toisen-tekijan-nollaus .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-toisen-tekijan-nollaus .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
.katakri-toisen-tekijan-nollaus .katakri-kortti h2,
.katakri-toisen-tekijan-nollaus .katakri-kortti h3{color:var(--ink-1)}
.katakri-toisen-tekijan-nollaus .katakri-kortti__tyhjateksti{color:var(--ink-3)}

/* Tilitunnus luettelossa on koneluettava tunnus, eli Apexin aksentti — sama
   arvo kuin yleiskuvan vaatimustunnuksella. */
.katakri-toisen-tekijan-nollaus .katakri-tunnus{color:var(--accent)}

/* Kentta = Apexin `.field` + `.inp`. */
.katakri-toisen-tekijan-nollaus .katakri-kentta__nimike{color:var(--ink-3)}
.katakri-toisen-tekijan-nollaus .katakri-syote{background:var(--card);border-color:var(--line-2);
  color:var(--ink-1)}
.katakri-toisen-tekijan-nollaus .katakri-syote:focus{border-color:var(--accent);
  box-shadow:var(--shadow-focus-accent)}

/* Painike = Apexin `.btn-primary`. `filter:none` kumoaa Meshlyn
   `brightness(1.1)`-kirkastuksen; Apexilla hover on oma tokeninsa. */
.katakri-toisen-tekijan-nollaus .katakri-painike--ensisijainen{background:var(--accent);
  color:var(--on-shell)}
.katakri-toisen-tekijan-nollaus .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}

.katakri-toisen-tekijan-nollaus :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* ============ Evidenssi ja auditointipaketti — Apex 2.2 (teht. 6b08a81b) ====
 * Perheen jaetut komponentit Apexin tokeneilla. Kiinnike on
 * `.katakri-evidenssinakymat` ja se on kahden sivun `<main>`-elementissa:
 * `auditointipaketti.html` (koostajan sivu esikatseluineen) ja
 * `naytot/evidenssi.html` (evidenssikirjasto). Nimi noudattaa perheittaisten
 * kiinnikkeiden kuviota, joka on jo kaytossa kirjausnakymissa
 * (`.katakri-kirjausnakymat`, teht. 02537cdd) ja poikkeamanakymissa
 * (`.katakri-poikkeamanakymat`, teht. 08decf84).
 *
 * Miksi kiinnike eika arvon vaihto paikallaan: paatos 2e305611
 * ("Apex-tokenien kayttoonotto tehdaan scopattuna") hylkasi kierroksen, jossa
 * app-laajuista luokkaa muutettiin paikallaan ja Apexin vari renderoityi
 * sivulle, jolla ei viela ollut omaa migraatiotehtavaansa. Nama luokat
 * renderoituvat laajalti: `.katakri-kortti` 44 muussa templatessa,
 * `.katakri-painike*` 33:ssa, `.katakri-merkki*` 35:ssa, `.katakri-himmea`
 * 19:ssa, `.katakri-huomio--varoitus` 15:ssa, `.katakri-murupolku` 23:ssa.
 *
 * Perheen OMAT luokat eivat ole tassa, vaan ne on vaihdettu paikallaan omissa
 * lohkoissaan: `.katakri-paketti*`, `.katakri-esikatselu*`,
 * `.katakri-rajamerkki`, `.katakri-vaatimusryhma` (lohko "Auditointipaketti"),
 * `.katakri-evidenssi*` (lohko "Evidenssikortti") ja agenttiajon tiivistelman
 * askeleet (lohko "Agenttiajo"). Kiinnike maksaa spesifisyytta, eika sita
 * oteta ilman syyta.
 *
 * TYPOGRAFIA. Tama perhe saa Apexin kirjainperheen `--font-sans` (Inter,
 * vendoroitu teht. 9b143dc1:ssa ja julistettu fonts.css:ssa) — tehtavan oma
 * toteutuskohta pyytaa esikatselulle ja kansilehdelle Apexin typografian.
 * Vaihdettu on VAIN perhe. Koot, paksuudet ja kirjainvali jaavat
 * ytimen omalle asteikolle kuten kehyksen ja yleiskuvan migraatioissa (teht.
 * 72ca7e29, 2e372620), koska Apexilla ei ole typografian asteikkoa tokeneina
 * vaan se koodaa sen `font:`-lyhenteina; asteikot eivat yhdistyneet, kun
 * Meshly-lohko poistui (teht. 24cd5d6c). `--font-mono` ei vaihdu: tokens.css pitaa tieten JetBrains
 * Monon, koska tiivisteiden 0/O- ja 1/l-ero luetaan merkki kerrallaan.
 * ------------------------------------------------------------------------ */

/* Sivun pinta, periytyva edustavari JA kirjainperhe. `color` on tassa samasta
   syysta kuin yleiskuvan juuressa: ilman sita jokainen elementti, jolla ei ole
   omaa varisaantoa, piirtyisi `body`n `--text-body`lla -- kierroksella 1
   Meshlyn musteella, tehtavan 24cd5d6c jalkeen Apexin aliaksella.
   `--ink-2` on Apexin oma leipateksti
   (`components.css`: `body{background:var(--page);color:var(--ink-2)}`). */
.katakri-evidenssinakymat{background:var(--page);color:var(--ink-2);
  font-family:var(--font-sans)}
/* Otsikot julistavat `font-family:var(--font-sans)` omassa saannossaan
   (0,0,1), joten perhe ei periydy niihin juuresta — se on annettava erikseen. */
.katakri-evidenssinakymat h1,.katakri-evidenssinakymat h2,
.katakri-evidenssinakymat h3,.katakri-evidenssinakymat h4{font-family:var(--font-sans)}

/* Otsikoiden muste on Apexin `h1,h2,h3,h4{color:var(--ink-1)}`.

   Esikatselun otsikko on `<h2 class="katakri-ylarivi">`
   (`auditointipaketti.html`), eli sama elementti osuu seka tahan etta
   ylarivin saantoon ylla. Se saa ylarivin varin, koska tama on
   kiinnike+tyyppi (0,1,1) ja ylarivi kiinnike+luokka (0,2,0). Siksi tassa EI
   ole `:not(.katakri-ylarivi)`-rajausta: se olisi rajaus ansaan, jota talla
   valitsinmuodolla ei ole. Yleiskuvan kierros 1 hylattiin tasta ansasta,
   mutta siella kilpailija oli kortin otsikkosaanto
   `.katakri-yleiskuva .katakri-kortti h2` (0,2,1), joka todella voittaa
   ylarivin — talla perheella ei ole yhtaan kolmiosaista otsikkovalitsinta.
   `tests/test_ui_evidenssinakymien_apex.py` ratkaisee taman kaskadissa. */
.katakri-evidenssinakymat h1,.katakri-evidenssinakymat h2,
.katakri-evidenssinakymat h3,.katakri-evidenssinakymat h4{color:var(--ink-1)}

/* Kasikirjan ja sanaston linkit. Perheen markkauksessa ei ole yhtaan
   luokatonta `<a>`:ta (mitattu renderoidysta sivusta), joten tassa ei ole
   paljasta `a`-saantoa: se voittaisi spesifisyydella (0,1,1) naiden
   luokkasaannot (0,1,0) ja varjaisi kuvakkeen aksentilla. Kuvakkeen vaimeus
   ON sen suunnittelun ehto — se on toissijainen siirtyma sen tunnuslinkin
   vierella, jonka kanssa se ei saa kilpailla (ks. luokkien oma lohko). Siksi
   teksti saa `--accent`in ja kuvake `--ink-3`:n, ja jarjestys on sama kuin
   perussaannoissa: muunnos viimeisena. */
.katakri-evidenssinakymat .katakri-kasikirjalinkki,
.katakri-evidenssinakymat .katakri-sanastolinkki{color:var(--accent)}
.katakri-evidenssinakymat .katakri-kasikirjalinkki--kuvake,
.katakri-evidenssinakymat .katakri-sanastolinkki--kuvake{color:var(--ink-3)}
.katakri-evidenssinakymat .katakri-kasikirjalinkki--kuvake:hover,
.katakri-evidenssinakymat .katakri-kasikirjalinkki--kuvake:focus-visible,
.katakri-evidenssinakymat .katakri-sanastolinkki--kuvake:hover,
.katakri-evidenssinakymat .katakri-sanastolinkki--kuvake:focus-visible{color:var(--accent)}

/* Ylarivi (eyebrow) on Apexin `.t-eyebrow`, eli `--ink-3`. */
.katakri-evidenssinakymat .katakri-ylarivi{color:var(--ink-3)}
.katakri-evidenssinakymat .katakri-johdanto{color:var(--ink-3)}

/* Murupolku: Apexin `.crumbs` on `--ink-3`, nykyinen kohta `--ink-1`, erotin
   `--line-2`. */
.katakri-evidenssinakymat .katakri-murupolku{color:var(--ink-3)}
.katakri-evidenssinakymat .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-evidenssinakymat .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* Kortti = Apexin `.card`: `--card` + `--line-1` + `--sh-card`. */
.katakri-evidenssinakymat .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-evidenssinakymat .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-evidenssinakymat .katakri-kortti--nostettava:hover{box-shadow:var(--sh-pop)}
.katakri-evidenssinakymat .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}

/* Painikkeet: Apexin `.btn-primary` ja `.btn-outline`. `filter:none` kumoaa
   Meshlyn `brightness(1.1)`-kirkastuksen — Apexilla hover on oma tokeninsa. */
.katakri-evidenssinakymat .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-evidenssinakymat .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-evidenssinakymat .katakri-painike--toissijainen{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-evidenssinakymat .katakri-painike--toissijainen:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}
.katakri-evidenssinakymat .katakri-painike--haamu{color:var(--ink-3)}
.katakri-evidenssinakymat .katakri-painike--haamu:hover{background:var(--sunken);color:var(--ink-1)}
.katakri-evidenssinakymat .katakri-tekstipainike{color:var(--accent)}

/* Merkki = Apexin `.chip`. Varoitus saa `--accent2-*`:n eika `--warn`in, koska
   Apexin `.chip.warn` on meripihkainen pehmea pari; `--warn` on
   yksittaisvari ilman pehmeaa vastinetta. Sama ratkaisu kuin yleiskuvassa. */
.katakri-evidenssinakymat .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-evidenssinakymat .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-evidenssinakymat .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-evidenssinakymat .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-evidenssinakymat .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-evidenssinakymat .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}
/* Merkin sisalla oleva linkki perii merkin oman varin (Apexin `.chip a`):
   ilman tata evidenssikortin vaatimuskytkenta piirtyisi `--accent`illa
   neutraalin sirun sisalla, eli toisella varilla kuin se siru, joka sen
   kantaa. Kytkennat ovat kortin lukittua aluetta, ja juuri niiden luettavuus
   on se, mita lukitus suojaa. */
.katakri-evidenssinakymat .katakri-merkki a{color:inherit}

/* Tunnus: koneluettava vaatimustunnus on siirtyma, eli Apexin aksentti. */
.katakri-evidenssinakymat .katakri-tunnus{color:var(--accent)}

/* Himmea teksti ja koneluettavat maarat. Apexin `.tbl .muted` on `--ink-3`,
   `.t-meta` sama; `.kpi .s`:n kaltainen toissijainen meta on `--ink-4`. */
.katakri-evidenssinakymat .katakri-himmea{color:var(--ink-3)}
.katakri-evidenssinakymat .katakri-maara{color:var(--ink-4)}
.katakri-evidenssinakymat .katakri-poikkeama__meta{color:var(--ink-3)}

/* Lomakekentat = Apexin `.field` ja `.inp`: nimike `--ink-3`, kentan reuna
   `--line-2`, fokus `--accent` + aksenttihalo. */
.katakri-evidenssinakymat .katakri-kentta__nimike{color:var(--ink-3)}
.katakri-evidenssinakymat .katakri-syote{background:var(--card);border-color:var(--line-2);
  color:var(--ink-1);font-family:var(--font-sans)}
.katakri-evidenssinakymat .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-evidenssinakymat .katakri-syote:focus{border-color:var(--accent);
  box-shadow:var(--shadow-focus-accent)}

/* Huomiolaatikot. `--varoitus` on Apexin `.banner.warn` (`--accent2-*`, reunus
   omalla tokenillaan `--accent2-border`), `--neutraali` sen `.note-strip`
   (`--sunken` pohja, `--line-1` reuna, `--ink-3` veto). Perusluokan vihrealle
   asulle ei ole saantoa tassa: kumpikin muunnos vaihtaa pohjan, reunan ja
   vedon, eika perheen markkauksessa ole paljasta `.katakri-huomio`ta. */
.katakri-evidenssinakymat .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
.katakri-evidenssinakymat .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}

/* Raportin kansilehti (`partials/_auditointipaketin_kansilehti.html`). Kansi
   renderoityy perheessa esikatselun sisalla; sen toinen esiintyma
   `naytot/raportti.html` jaa raporttinakymien omaan tehtavaansa, ja juuri
   siksi varit ovat kiinnikkeen takana eivatka paikallaan. Alleviivaus on
   Apexin tummin muste `--ink-1`. */
.katakri-evidenssinakymat .katakri-raportti__kansi{border-bottom-color:var(--ink-1)}

/* Agenttiajon tiivistelman kuvake (`locked/_agenttiajo_tiivistelma.html`) ei
   ole tassa: partiaali renderoityy etusivun nayttomallissa
   (`naytot/index.html`), ei taman perheen sivuilla. Sen kiinnike on sen oman
   sivun `.katakri-yleiskuva`, ks. lohko sen jalkeen. */

/* Fokusrengas Apexin aksenttihalolla. Perussaanto `:focus-visible` on
   spesifisyydeltaan (0,1,0) ja tama (0,2,0), joten tama voittaa taman perheen
   sisalla eika kajoa muihin sivuihin. */
.katakri-evidenssinakymat :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* ---------------------------------------------------------------------------
 * Agenttiajon tiivistelma (`locked/_agenttiajo_tiivistelma.html`), teht.
 * 6b08a81b. Partiaali on LUKITTU, joten se migratoidaan vain CSS:lla — sen
 * markkaukseen ei lisata luokkaa.
 *
 * Kiinnike on `.katakri-yleiskuva` eika perheen oma: partiaalin ainoa
 * esiintyma on etusivun nayttomalli `naytot/index.html`, jossa tuo kiinnike on
 * jo `<main>`-elementissa (teht. 2e372620). Kortti, merkki, edistyspalkki,
 * painike ja himmea teksti saivat siella Apexin arvot jo silloin; tassa on se,
 * mika jai: kuvakkeen veto.
 *
 * `.katakri-agentti__ikoni` on jaettu agenttipaneelin kanssa
 * (`partials/_agenttipaneeli.html`), joka kuuluu kehyksen tehtavaan 72ca7e29,
 * joten arvoa ei voi vaihtaa paikallaan.
 * ------------------------------------------------------------------------- */
.katakri-yleiskuva .katakri-agentti__ikoni{color:var(--accent)}

/* ============ Dokumenttinäkymät — Apex 2.2 (tehtävä 7a65ed19) ============
 * Dokumenttilistan (`dokumentit.html`) ja asiakirjan sivun
 * (`dokumentti.html`) jaetut komponentit Apexin tokeneilla, seka
 * keraajanakyman kaksi dokumenttiosiota (`_dokumenttilahteet.html`,
 * `_dokumenttivienti.html`).
 *
 * KOLME KIINNIKETTA, ei yhta, koska naiden templateiden markkaus latoutuu
 * kolmelle eri sivulle:
 *
 *   `.katakri-dokumenttinakymat`   sivun oma luokka `<main>`-elementissa
 *                                  kummassakin dokumenttisivussa.
 *   `.katakri-dokumenttilahteet`   osion oma juuriluokka. Osio renderoityy
 *   `.katakri-dokumenttivienti`    `keraajat.html`:lla, jonka muut osiot
 *                                  odottavat tehtavaa 9c73b57c. Molemmat
 *                                  templatet ovat lukittuja, joten niihin ei
 *                                  voi lisata kiinniketta -- eika tarvitse:
 *                                  niiden juuri on jo oma luokkansa.
 *
 * Miksi kiinnike eika arvon vaihto paikallaan: paatos 2e305611
 * ("Apex-tokenien kayttoonotto tehdaan scopattuna") hylkasi kierroksen, jossa
 * app-laajuista luokkaa muutettiin paikallaan ja Apexin vari renderoityi
 * sivulle, jolla ei viela ollut omaa migraatiotehtavaansa. Nama luokat
 * renderoituvat laajalti: `.katakri-kortti` 44 templatessa,
 * `.katakri-painike*` 32:ssa, `.katakri-merkki*` 31:ssa,
 * `.katakri-murupolku` 21:ssa, `.katakri-taulukko` 9:ssa.
 *
 * Paikallaan vaihdettuja ovat vain ne luokat, jotka EIVAT esiinny muualla --
 * ei muissa templateissa, ei luovutusnaytoissa (`naytot/`) eika React-nipussa
 * (`ui/src/`). Ne ovat `.katakri-dokumenttirivi__*` (vain
 * `_dokumenttitaulukko.html`), `.katakri-paasy*` ja `.katakri-tulosruutu*`
 * (vain asiakirjan sivu) seka vientiosion omat `.katakri-keruuvirhe*`,
 * `.katakri-raakarivi*`, `.katakri-puuttuva-kentta` ja
 * `.katakri-nimetty-kentta`.
 *
 * `.katakri-saantorivi*` ja `.katakri-dokumenttikortti__nimike` EIVAT ole
 * niiden joukossa, vaikka ne tulevat talle sivulle lukitusta partiaalista
 * (`locked/_dokumenttikortin_saannot.html`): sama markkaus on React-nipun
 * `Saannot.tsx`:ssa ja `Dokumenttikortti.tsx`:ssa, ja se renderoityy
 * vaatimuksen sivulla (`vaatimus.html`, `#katakri-ui`), joka odottaa
 * tehtavaa 38ecf4bb. Paikallaan vaihdettuna Apexin vari olisi siella.
 *
 * Vaihdettuja ovat VAIN vari-, varjo- ja liiketokenit. Valistys, kulmat,
 * reunusten leveydet ja typografia kayttavat ytimen omaa asteikkoa, kuten
 * kehyksen (teht. 72ca7e29) ja yleiskuvan (teht. 2e372620) migraatiossa:
 * Apexilla ei ole typografian asteikkoa tokeneina, eivatka `--s*`/`--r-*`
 * vastaa `--space-*`:n ja `--radius-*`:n asteikkoja. Asteikot eivat siksi
 * yhdistyneet, kun Meshly-lohko poistui (teht. 24cd5d6c).
 * ------------------------------------------------------------------------ */

/* Sivun pinta JA periytyva edustavari. `color` on tassa samasta syysta kuin
   yleiskuvan juuressa (ks. sen lohko): ilman sita jokainen varisaannoton
   elementti -- esimerkiksi Paasy-kortin `currentColor`-kuvakkeet
   (`icons.svg`) -- perisi `body`n `--text-body`n, joka oli kierroksella 1
   Meshlyn `--ink-700` ja on nyt Apexin alias `var(--ink-2)`.
   `--ink-2` on Apexin leipatekstin muste: sen `components.css`
   julistaa `body{background:var(--page);color:var(--ink-2)}`. */
.katakri-dokumenttinakymat{background:var(--page);color:var(--ink-2)}
/* Keraajanakyman kaksi osiota eivat saa pohjaa -- sivun pohja on tehtavan
   9c73b57c asia -- mutta edustavari niilla on samasta syysta: ilman sita
   osioiden varisaannottomat solut (raakarivin kentat, taulukon luvut)
   perisivat `body`n musteen -- kierroksella 1 Meshlyn -- keskella muuten
   Apexilla piirrettya osiota. */
.katakri-dokumenttilahteet,
.katakri-dokumenttivienti{color:var(--ink-2)}

/* Otsikot. Perustan `h1,h2,h3,h4` (rivi 14) oli `--text-strong`, eli Meshlyn
   `--ink-900`; tehtava 24cd5d6c kaansi sen Apexin `--text-heading`iin
   (`var(--ink-1)`), eli samaan musteeseen kuin tassa. Spesifisyys on (0,1,1), eli
   se havia jokaiselle luokkasaannolle (0,2,0) tassa lohkossa -- juuri niille,
   joilla otsikko on jotain muuta kuin otsikko: `.katakri-ylarivi` (nimike) ja
   `.katakri-dokumenttikortti__nimike` (kortin yliviiva), jotka molemmat
   saavat alla `--ink-3`:n. `.katakri-tiedot-pieni` EI ole niiden joukossa:
   silla ei ole omaa varisaantoa, ja raakarivin `<h4>` on otsikko. */
.katakri-dokumenttinakymat h1,
.katakri-dokumenttinakymat h2,
.katakri-dokumenttinakymat h3,
.katakri-dokumenttinakymat h4,
.katakri-dokumenttilahteet h2,
.katakri-dokumenttivienti h2,
.katakri-dokumenttivienti h3,
.katakri-dokumenttivienti h4{color:var(--ink-1)}

/* Luokattomat ankkurit. Linkki ei peri varia kaareeltaan: perustan
   `a`-saanto (rivi 20) julistaa `color:var(--accent)` suoraan ankkurille.
   Naita on dokumenttisivuilla toistakymmenta -- murupolku, "Avaa vaatimus",
   version tapahtuma, keruutapahtuma, kehikon kontrolli, jaljityslenkin
   osoite ja "Avaa dokumentinhallinnassa". Apexilla ei ole omaa
   linkkitokenia: sen `components.css` varittaa tunnisteen aksentilla, joten
   lepotila on `--accent` ja osoitin `--accent-hover`, kuten kehyksen
   migraatiossa (teht. 72ca7e29).

   Saanto on (0,1,1) ja osuu myos luokallisiin ankkureihin. Se on tarkoitus
   siella, missa luokan oma arvo on sama siirtyman aksentti: `a.katakri-koodi`
   (saantorivin saantolinkki) ja muunnokseton `a.katakri-painike`
   (rajauksen tyhjennys), jotka molemmat olivat kierroksella 1 Meshlyn
   `--text-link`.
   Ne nelja, joilla se EI ole, kumotaan luokkasaannolla (0,2,0), joka voittaa
   taman: `.katakri-painike--ensisijainen`, `.katakri-painike--toissijainen`,
   `.katakri-dokumenttirivi__vaatimus` ja `.katakri-kasikirjalinkki--kuvake`. */
.katakri-dokumenttinakymat a{color:var(--accent)}
.katakri-dokumenttinakymat a:hover{color:var(--accent-hover)}

/* Murupolku: Apexin `.crumbs` on `--ink-3`, nykyinen kohta `--ink-1`.
   Erotin saa `--line-2`:n, joka on Apexin kontrollien viiva. */
.katakri-dokumenttinakymat .katakri-murupolku{color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-dokumenttinakymat .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* Ylarivi (eyebrow) ja himmea aputeksti: Apexin `.t-eyebrow` ja `.t-muted`
   ovat molemmat `--ink-3`. */
.katakri-dokumenttinakymat .katakri-ylarivi,
.katakri-dokumenttinakymat .katakri-himmea,
.katakri-dokumenttinakymat .katakri-ohje,
.katakri-dokumenttilahteet .katakri-himmea,
.katakri-dokumenttivienti .katakri-himmea{color:var(--ink-3)}

/* Kortti: Apexin `.card` on `--card` + `--line-1` + `--sh-card`. */
.katakri-dokumenttinakymat .katakri-kortti,
.katakri-dokumenttivienti .katakri-kortti{background:var(--card);
  border-color:var(--line-1);box-shadow:var(--sh-card)}
.katakri-dokumenttinakymat .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-dokumenttinakymat .katakri-kortti--nostettava:hover{box-shadow:var(--sh-pop)}
.katakri-dokumenttinakymat .katakri-kortti__otsikko,
.katakri-dokumenttivienti .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
.katakri-dokumenttinakymat .katakri-kortti__tyhjateksti{color:var(--ink-3)}

/* Painikkeet: Apexin `.btn-primary` ja `.btn-outline`. `filter:none` kumoaa
   Meshlyn `brightness(1.1)`-kirkastuksen — Apexilla hover on oma tokeninsa
   (`--accent-hover`) eika sama vari kirkkaampana. */
.katakri-dokumenttinakymat .katakri-painike--ensisijainen{background:var(--accent);
  color:var(--on-shell)}
.katakri-dokumenttinakymat .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-dokumenttinakymat .katakri-painike--toissijainen{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-dokumenttinakymat .katakri-painike--toissijainen:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}
.katakri-dokumenttinakymat .katakri-painike--haamu{color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-painike--haamu:hover{background:var(--sunken);color:var(--ink-1)}

/* Merkki = Apexin `.chip`. Varoitus saa `--accent2-*`:n eika `--warn`in,
   koska Apexin `.chip.warn` on meripihkainen pehmea pari (`--accent2-soft` /
   `--accent2-ink`); `--warn` on yksittaisvari ilman pehmeaa vastinetta. */
.katakri-dokumenttinakymat .katakri-merkki--neutraali,
.katakri-dokumenttilahteet .katakri-merkki--neutraali,
.katakri-dokumenttivienti .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-dokumenttinakymat .katakri-merkki--ok,
.katakri-dokumenttivienti .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-dokumenttinakymat .katakri-merkki--varoitus,
.katakri-dokumenttilahteet .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-dokumenttinakymat .katakri-merkki--vaara,
.katakri-dokumenttivienti .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-dokumenttinakymat .katakri-merkki--reunus,
.katakri-dokumenttilahteet .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}

/* Taulukko = Apexin `.tbl`. Otsakerivi on `--sunken`, viivat `--line-1` ja
   rivin osuma `--row-hover`. */
.katakri-dokumenttinakymat .katakri-taulukko caption,
.katakri-dokumenttivienti .katakri-taulukko caption{color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-taulukko th,
.katakri-dokumenttilahteet .katakri-taulukko th,
.katakri-dokumenttivienti .katakri-taulukko th{background:var(--sunken);
  border-bottom-color:var(--line-1);color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-taulukko td,
.katakri-dokumenttilahteet .katakri-taulukko td,
.katakri-dokumenttivienti .katakri-taulukko td{border-bottom-color:var(--line-1)}
.katakri-dokumenttinakymat .katakri-taulukko tbody tr:hover,
.katakri-dokumenttilahteet .katakri-taulukko tbody tr:hover,
.katakri-dokumenttivienti .katakri-taulukko tbody tr:hover{background:var(--row-hover)}

/* Rajauslomake ja sen kentat = Apexin `.toolbar` ja `.field`. Kentan reuna on
   `--line-2` (Apexin kontrolliviiva) eika `--line-1`: jalkimmainen on
   erottimen viiva, ja kenttaa se ei erottaisi pohjasta. */
.katakri-dokumenttinakymat .katakri-valintapalkki{background:var(--card);border-color:var(--line-1)}
.katakri-dokumenttinakymat .katakri-valintapalkki__ohje,
.katakri-dokumenttinakymat .katakri-valintapalkki__maarat{color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-kentta__nimike{color:var(--ink-2)}
.katakri-dokumenttinakymat .katakri-syote{background:var(--card);border-color:var(--line-2);
  color:var(--ink-1)}
.katakri-dokumenttinakymat .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-dokumenttinakymat .katakri-syote:focus{border-color:var(--accent);
  box-shadow:var(--shadow-focus-accent)}

/* Huomiolaatikot. `--neutraali` on Apexin `.note-strip` (`--sunken` pohja,
   `--line-1` reuna, `--ink-3` veto) ja `--varoitus` sen `.banner.warn`
   (`--accent2-*`, reunus omalla tokenillaan `--accent2-border`) -- samat kuin
   evidenssinakymissa (teht. 6b08a81b).

   Perusluokan vihrealle asulle on saanto tassa, toisin kuin siella: asiakirjan
   sivulla on paljas `.katakri-huomio` ("Tila paivana" -valinnan syy,
   `dokumentti.html`). Apexilla ei ole `--pos-border`ia -- `--neg`illa on --
   joten reuna saa saman `--pos-soft`in kuin pohja. Apexin pehmeat tilat ovat
   reunattomia siella, missa niille ei ole omaa reunatokenia, ja arvo
   kirjoitetaan nakyviin, jotta peruslohkon oma pehmea vihrea ei jaa
   voimaan (kierroksella 1 Meshlyn `--green-100`, nyt `--pos-soft`). */
.katakri-dokumenttinakymat .katakri-huomio{background:var(--pos-soft);
  border-color:var(--pos-soft);color:var(--pos-ink)}
.katakri-dokumenttinakymat .katakri-huomio--neutraali,
.katakri-dokumenttilahteet .katakri-huomio--neutraali,
.katakri-dokumenttivienti .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}

/* Ominaisuuslista = Apexin `.kv`: nimike `--ink-3`, arvo `--ink-1`, rivien
   valiviiva `--line-1`. Lista on asiakirjan tiedoissa ja jaljitysketjussa. */
.katakri-dokumenttinakymat .katakri-ominaisuudet div{border-bottom-color:var(--line-1)}
.katakri-dokumenttinakymat .katakri-ominaisuudet dt{color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-ominaisuudet dd{color:var(--ink-1)}

/* Koodimerkinta tekstin seassa: arvo on leipatekstia (`--ink-2`), linkitetty
   arvo siirtyma (`--accent`). Koodilohko on Apexin tumma shell-pinta. */
.katakri-dokumenttinakymat code.katakri-koodi,
.katakri-dokumenttilahteet code.katakri-koodi,
.katakri-dokumenttivienti code.katakri-koodi{color:var(--ink-2)}
.katakri-dokumenttinakymat a.katakri-koodi{color:var(--accent)}
.katakri-dokumenttinakymat .katakri-koodilohko,
.katakri-dokumenttivienti .katakri-koodilohko{background:var(--shell-1);color:var(--on-shell-2)}

/* Jaljitysketju = Apexin `.timeline`: piste `--line-2`, teksti `--ink-2`.
   Kiinnikkeen takana eika paikallaan, koska `.katakri-ketju*` renderoityy myos
   luovutusnaytoilla `naytot/vaatimus.html` ja `naytot/raportti.html`. */
.katakri-dokumenttinakymat .katakri-ketju__piste{background:var(--line-2)}
.katakri-dokumenttinakymat .katakri-ketju__teksti{color:var(--ink-2)}
.katakri-dokumenttinakymat .katakri-ketju__aika{color:var(--ink-3)}

/* Dokumenttikortin saantorivit (`locked/_dokumenttikortin_saannot.html`).
   Rivi on Apexin vaimea laatikko: `--sunken` pohja ja `--line-1` reuna. */
.katakri-dokumenttinakymat .katakri-dokumenttikortti__nimike{color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-saantorivi{background:var(--sunken);border-color:var(--line-1)}
.katakri-dokumenttinakymat .katakri-saantorivi__otsikko{color:var(--ink-1)}
.katakri-dokumenttinakymat .katakri-saantorivi__selite{color:var(--ink-3)}

/* Viite ja sen kopiointipainike (`partials/_viite.html`). Kopioitu-tila on
   Apexin `--pos`: se on kuittaus eika pysyva tila, ja pehmea pari olisi
   kuvakkeelle nakymaton. */
.katakri-dokumenttinakymat .katakri-viite__kansiot{border-left-color:var(--line-1)}
.katakri-dokumenttinakymat .katakri-kopioi{color:var(--ink-4)}
.katakri-dokumenttinakymat .katakri-kopioi:hover{color:var(--accent)}
.katakri-dokumenttinakymat .katakri-kopioi[data-kopioitu]{color:var(--pos)}

/* Fokusrengas Apexin aksenttihalolla. Perussaanto `:focus-visible` on
   spesifisyydeltaan (0,1,0) ja tama (0,2,0), joten tama voittaa naiden
   sivujen sisalla eika kajoa muihin sivuihin. */
.katakri-dokumenttinakymat :focus-visible,
.katakri-dokumenttilahteet :focus-visible,
.katakri-dokumenttivienti :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* Dokumenttilistan rivin vaatimustunnus. Sen muut sisarukset
   (`.katakri-dokumenttirivi__nimi`, `__tunnus`) saivat Apexin arvon
   paikallaan omassa lohkossaan, koska ne renderoituvat vain talla sivulla.
   Tunnus ei voi: se on ankkuri, joten `.katakri-dokumenttinakymat a` (0,1,1)
   voittaisi paikallaan kirjoitetun luokkasaannon (0,1,0) ja piirtaisi sen
   aksentilla. Tunnus on sarakkeen otsikko eika sen siirtyma -- siirtyma on
   koko rivi -- joten se pysyy tummana musteena, ja saanto on kiinnikkeen
   takana (0,2,0) voittaakseen ankkurisaannon. */
.katakri-dokumenttinakymat .katakri-dokumenttirivi__vaatimus{color:var(--ink-1)}

/* Kasikirjan kuvakelinkki (`templatetags/katakri_kasikirja.py`) on samasta
   syysta tassa: se on luokallinen ankkuri, jonka oma saanto on (0,1,0).
   Kuvake on tieten toissijainen siirtyma eika kilpaile sen tunnuslinkin
   kanssa, jonka vieressa se on (ks. sen oma lohko), joten lepotila on
   `--ink-3` eika aksentti -- ja osoitin on aksentti kuten muillakin. */
.katakri-dokumenttinakymat .katakri-kasikirjalinkki--kuvake{color:var(--ink-3)}
.katakri-dokumenttinakymat .katakri-kasikirjalinkki--kuvake:hover,
.katakri-dokumenttinakymat .katakri-kasikirjalinkki--kuvake:focus-visible{color:var(--accent)}

/* Tekstipainike on `<button>` eika ankkuri (`partials/_viite.html`), joten
   ankkurisaanto ei osu siihen. Talla sivulla se on aina kopiointipainike,
   jonka `.katakri-kopioi` ylla voittaa -- saanto on silti tassa, jotta
   nakyman oma linkkivari on kirjoitettu nakyviin, jos pari joskus
   purkautuu. Kierroksella 1 perussaanto oli Meshlyn `--text-link`. */
.katakri-dokumenttinakymat .katakri-tekstipainike{color:var(--accent)}

/* Puuttuvan viitteen muistutuksen kuittaus (kierros 8, K8-19). Hylkaa-painike
   on pois kaytosta niin kauan kuin perustelu on tyhja. Ehto luetaan kentan
   omasta tilasta (`:valid`, kun `textarea` on `required`) eika skriptista:
   Django-templateissa ei ole JS:aa kierrosten 6-8 kriteerien mukaan, eika
   `disabled`-attribuuttia voi asettaa palvelimella, koska palvelin ei nae
   kentan sisaltoa ennen lahetysta. `pointer-events:none` ottaa painikkeen
   pois hiirelta ja kosketukselta; nappaimistolla siihen yha paasee, ja
   silloin lomakkeen oma `required`-tarkistus pysayttaa lahetyksen. Molempien
   takana on sama ehto kolmannen kerran palvelimella
   (`advisory.ACK_REASON_REQUIRED`, `views.viitemuistutuksen_kuittaus`): CSS on
   esitys, eika este saa olla vain siina. */
.katakri-kuittaus:not(:has(.katakri-kuittaus__perustelu:valid)) .katakri-kuittaus__hylkaa{
  opacity:.5;pointer-events:none}
/* ============ Audit trail -perhe — Apex 2.2 (tehtävä ebc2cfc3) ============
 * Paatoslokit, hyvaksynnat ja jaljitettavyys Apexin tokeneilla. Perhe ei ole
 * sivu vaan templatejoukko: yksi sivutemplate ja seitsemantoista partiaalia,
 * joista kaksitoista on `locked/`-hakemistossa. Lukitut partiaalit
 * renderoityvat muidenkin tehtavien sivuilla (asiakirja 7a65ed19, tapahtuma
 * ja kirjaukset 02537cdd, auditointipaketti 6b08a81b), joten tassa on kaksi
 * kiinnikelajia eika yhta.
 *
 * 1. SIVUN KIINNIKE `.katakri-paatoslokit` (`paatoslokit.html`:n
 *    <main>-elementissa). Sen takana ovat app-laajuiset komponentit --
 *    kortti, painike, syote, merkki, murupolku, huomio --, joita paatos
 *    2e305611 ("Apex-tokenien kayttoonotto tehdaan scopattuna") kieltaa
 *    muuttamasta paikallaan: `.katakri-kortti` on 44 muussa templatessa,
 *    `.katakri-merkki*` 35:ssa, `.katakri-huomio*` 29:ssa. `kuittaukset.html`
 *    EI saa kiinniketta, vaikka se sisallyttaa samat kolme paatosloki-
 *    partiaalia: se on tehtavan 02537cdd sivu, ja sen oma migraatio antoi
 *    kiinnikkeen. Siihen asti partiaalit piirtyivat siella Meshlylla -- sama
 *    valivaihe kuin jokaisessa muussakin perheessa. Tehtavan 24cd5d6c
 *    jalkeen jaetut luokat ovat Apexilla myos ilman kiinniketta, ja
 *    kiinnike on se, josta asiakas ylikirjoittaa perheen oman asun.
 *
 * 2. PARTIAALIN KIINNIKE lukituille partiaaleille. Niiden sisalla olevat
 *    jaetut komponentit saavat Apexin arvon VAIN siina partiaalissa, joten
 *    saman sivun muu, viela migratoimaton sisalto ei vaihdu. `locked/`-
 *    templateja ei muokata (ADR 0036, `views/template_boundary.py`), joten
 *    kiinnike on se, mika partiaalissa jo on: oma luokka silloin kun
 *    sellainen on (`.katakri-tulosruutu`, `.katakri-modaali`), muuten
 *    partiaalin juuren `data-testid`. Jalkimmainen ei ole uusi kuvio vaan
 *    sama kuin taulukoilla ylla (`.katakri-taulukko[data-testid=
 *    "dokumenttitaulukko"]`), ja se on nimenomaan lukitun partiaalin
 *    sopimusta: `data-testid` on se, mita sen omat testit lukevat, joten se
 *    ei vaihdu ulkoasun mukana.
 *
 * Perheen OMAT luokat -- `.katakri-merkinta*`, `.katakri-merkintataulu`,
 * `.katakri-merkintalista__ajot`, `.katakri-ajolista`, `.katakri-vastavaite`,
 * `.katakri-paikat`, `.katakri-paikka*`, `.katakri-avaukset`,
 * `.katakri-avaus*`, `.katakri-avatar`, `.katakri-tulosruutu*`,
 * `.katakri-modaali*` -- eivat ole taalla: ne renderoityvat vain taman
 * tehtavan templateissa, joten niiden arvo on vaihdettu paikallaan omassa
 * lohkossaan. Kiinnike maksaa spesifisyytta, eika sita oteta ilman syyta.
 *
 * Vaihdettuja ovat VAIN vari-, varjo- ja fonttiperhetokenit. Valistys,
 * kulmat ja typografian asteikko ovat ytimen omaa asteikkoa kuten kehyksen
 * (72ca7e29) ja yleiskuvan (2e372620) migraatioissa; asteikot eivat
 * yhdistyneet, kun Meshly-lohko poistui (teht. 24cd5d6c).
 * ------------------------------------------------------------------------ */

/* --- Ketjut ja tiivisteet: monospace ja `--sunken` ------------------------
 * Taman perheen arvot luetaan merkki kerralla -- eheystiiviste, ketjutiiviste,
 * jarjestysnumero, viite, kieliversio --, ja juuri siksi ne ovat
 * `--font-mono`lla ja upotetulla pohjalla: upotus kertoo silmalle, mihin arvo
 * alkaa ja mihin se loppuu, kun kaksi 64 merkin tiivistetta on allekkain.
 *
 * Valitsimet osoittavat ARVON PAIKKAAN (`dd`, ketjun lenkki, tiivisteen oma
 * `<details>`) eivatka jokaiseen `<code>`-elementtiin kiinnikkeen alla. Ero on
 * mitattu, ei periaatteellinen: paatoslokin merkinnassa on myos lauseen
 * sisaisia koodeja ("Vaite kumoutui (`rebutted`)"), ja upotettu pohja
 * tapytyksineen repi niista lauseen rikki -- sulkumerkkien ja sanan valiin
 * jai rako. Lauseen seassa oleva koodi on `code.katakri-koodi`, jolla on jo
 * oma asunsa, ja se jaa siihen. */
[data-testid="tapahtuman-eheys"] .katakri-ominaisuudet dd code,
[data-testid="kansilehti-jaljitettavyys"] dd code,
[data-testid="jaljitettavyysketju"] dd,
[data-testid="tiivistemuutos"] .katakri-tiiviste code,
.katakri-tulosruutu__kentat dd code{font-family:var(--font-mono);
  font-size:var(--text-body-sm);color:var(--ink-1);background:var(--sunken);
  border-radius:var(--radius-xs);padding:1px 5px;overflow-wrap:anywhere}
/* Jaljitettavyysketjun lenkki (`locked/_jaljitettavyysketju.html`): kentat
   renderoidaan sellaisinaan, joten lenkki on laatikko eika nimetty rivisto. */
[data-testid="jaljitettavyysketju"] li{padding:var(--space-3);margin-bottom:var(--space-2);
  background:var(--sunken);border:var(--border-hairline) solid var(--line-1);
  border-radius:var(--radius-md);color:var(--ink-2)}
[data-testid="jaljitettavyysketju"] dt,
[data-testid="kansilehti-jaljitettavyys"] dt{font-size:var(--text-caption);color:var(--ink-3)}
[data-testid="kansilehti-jaljitettavyys"] dd{margin:0;color:var(--ink-1)}
[data-testid="jaljitettavyysketju"] h2{color:var(--ink-1)}

/* --- Tiivisteen tila: liikennevalo (`locked/_tiivisteen_tila.html`) -------
 * Merkki renderoityy seitsemalla sivulla, eika `.katakri-merkki--ok` ole
 * taman perheen oma luokka. `[data-avain]` on se, mika erottaa juuri taman
 * merkin: attribuutti on vain `_tiivisteen_tila.html`:ssa ja
 * `_tarkistuksen_tulos.html`:ssa, jotka molemmat ovat tata tehtavaa, eika
 * yhdessakaan muun tehtavan merkissa. Savyjoukko on suljettu
 * (`DIGEST_STATUS_TONES`, `DIGEST_RESULT_TONES`): ok, vaara, varoitus,
 * neutraali. Varoitus saa `--accent2-*`:n eika `--warn`in samasta syysta kuin
 * yleiskuvassa: Apexin `.chip.warn` on meripihkainen pehmea pari.
 *
 * Spesifisyys on (0,3,0) eika (0,2,0) tahallaan. Liikennevalo renderoityy
 * kolmen muun taman perheen partiaalin SISALLA (`_avaukset.html`,
 * `_hyvaksyntalomake.html`, `_tarkistuksen_tulos.html`), ja niiden omat
 * `<kiinnike> .katakri-merkki` -saannot ovat (0,2,0). Matalammalla
 * spesifisyydella kaareen merkkisaanto voittaisi ja vihrea tiiviste piirtyisi
 * kaareen savylla -- juuri se, mita templaten lukitus kieltaa ("esitys, joka
 * nayttaisi vihreaa siella missa ydin sanoo punaista"). Kolmas luokkapaino
 * tulee merkin omasta perusluokasta, ei keksitysta valitsimesta. */
.katakri-merkki[data-avain].katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-merkki[data-avain].katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-merkki[data-avain].katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-merkki[data-avain].katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}

/* --- Eheysketjun tulos (`locked/_eheysketju.html`) -----------------------
 * Merkilla ei ole savymuunnosta merkkauksessa: todennuksen tulos on
 * `data-tulos`issa (`ehja` / `rikki`, `views/collection_event.py`). Ilman
 * tata se piirtyy pohjattomana ja ero nakyy vain luettuna -- ja juuri tama
 * merkki on se, josta auditoija lukee, onko tapahtumaa muutettu kirjaamisen
 * jalkeen. Attribuutti on vain tassa partiaalissa `.katakri-merkki`illa.
 * Kolmas luokkapaino tulee merkin omista luokista samasta syysta kuin
 * liikennevalolla: tulos ei saa vaihtua kaareen mukana. */
.katakri-merkki.katakri-merkki--s[data-tulos="ehja"]{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-merkki.katakri-merkki--s[data-tulos="rikki"]{background:var(--neg-soft);color:var(--neg-ink)}

/* --- Luokitusmerkinnat (`locked/_luokitusmerkinnat.html`) -----------------
 * Reunamerkki ja "ei luovutusrajoitteita" -teksti. Merkinnat renderoityvat
 * asiakirjan kortilla, taulukossa ja hyvaksyntalomakkeessa, joten kiinnike on
 * partiaalin oma juuri eika `.katakri-merkki--reunus` (6 templatea). */
[data-testid="luokitusmerkinnat"] .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}
[data-testid="luokitusmerkinnat"] .katakri-himmea{color:var(--ink-3)}

/* --- Eheysketju (`locked/_eheysketju.html`, tapahtuman sivu) ------------- */
[data-testid="tapahtuman-eheys"]{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card);color:var(--ink-2)}
[data-testid="tapahtuman-eheys"] h2{color:var(--ink-1)}
[data-testid="tapahtuman-eheys"] .katakri-ohje{color:var(--ink-3)}
[data-testid="tapahtuman-eheys"] .katakri-huomio{background:var(--pos-soft);
  border-color:var(--pos);color:var(--pos-ink)}
[data-testid="tapahtuman-eheys"] .katakri-huomio .katakri-ikoni{color:var(--pos)}
[data-testid="tapahtuman-eheys"] .katakri-ominaisuudet div{border-bottom-color:var(--line-1)}
[data-testid="tapahtuman-eheys"] .katakri-ominaisuudet dt{color:var(--ink-3)}
[data-testid="tapahtuman-eheys"] .katakri-ominaisuudet dd{color:var(--ink-1)}
[data-testid="tapahtuman-eheys"] .katakri-tekstipainike{color:var(--ink-4)}
[data-testid="tapahtuman-eheys"] .katakri-tekstipainike:hover{color:var(--accent)}
[data-testid="tapahtuman-eheys"] :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Hyvaksyntalista (`locked/_hyvaksyntalista.html`, asiakirjan sivu) ---- */
[data-testid="hyvaksyntalista"]{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card);color:var(--ink-2)}
[data-testid="hyvaksyntalista"] h2{color:var(--ink-1)}
[data-testid="hyvaksyntalista"] .katakri-ohje{color:var(--ink-3)}
[data-testid="hyvaksyntalista"] .katakri-himmea{color:var(--ink-3)}
[data-testid="hyvaksyntalista"] code.katakri-koodi{color:var(--ink-2)}
[data-testid="hyvaksyntalista"] .katakri-merkki{background:var(--sunken);color:var(--ink-3)}
[data-testid="hyvaksyntalista"] .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
[data-testid="hyvaksyntalista"] :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Avaukset (`locked/_avaukset.html`, asiakirjan sivu) ------------------ */
[data-testid="avaukset"]{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card);color:var(--ink-2)}
[data-testid="avaukset"] h2{color:var(--ink-1)}
[data-testid="avaukset"] .katakri-ohje{color:var(--ink-3)}
[data-testid="avaukset"] .katakri-himmea{color:var(--ink-3)}
[data-testid="avaukset"] code.katakri-koodi{color:var(--ink-2)}
[data-testid="avaukset"] a{color:var(--accent)}
[data-testid="avaukset"] .katakri-merkki{background:var(--accent-soft);color:var(--accent-ink)}
[data-testid="avaukset"] :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Tulosruutu (`locked/_tarkistuksen_tulos.html`,
 * `locked/_avauksen_vahvistus.html`). Kiinnike on partiaalien oma luokka,
 * joten `data-testid`ia ei tarvita. --------------------------------------- */
.katakri-tulosruutu code.katakri-koodi{color:var(--ink-2)}
.katakri-tulosruutu a{color:var(--accent)}
.katakri-tulosruutu strong{color:var(--ink-1)}
.katakri-tulosruutu .katakri-paasy__nimi{color:var(--ink-1)}
.katakri-tulosruutu :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Puuttuvat viitteet ja tiivistemuutos (asiakirjan sivun muistutukset) --
 * Molempien juuri on `katakri-kortti katakri-ehdotus`, eli sama pari kuin
 * `partials/_agentin_muistutus.html`:lla. Se sai yleiskuvan migraatiossa oman
 * muunnosluokkansa (`katakri-ehdotus--muistutus`) juuri siksi, etta paljas
 * pari on naiden kahden lukitun partiaalin kanssa jaettu. Nyt ne saavat saman
 * Apexin `.banner.info`-asun, mutta kumpikin oman juurensa kautta. */
[data-testid="puuttuvat-viitteet"],
[data-testid="tiivistemuutos"]{background:var(--accent-softer);border-color:var(--accent-soft);
  border-left-color:var(--accent);box-shadow:none;color:var(--ink-2)}
[data-testid="puuttuvat-viitteet"] .katakri-ehdotus__nimike,
[data-testid="tiivistemuutos"] .katakri-ehdotus__nimike{color:var(--accent-ink)}
[data-testid="puuttuvat-viitteet"] .katakri-ohje,
[data-testid="tiivistemuutos"] .katakri-ohje,
[data-testid="puuttuvat-viitteet"] .katakri-himmea,
[data-testid="tiivistemuutos"] .katakri-himmea{color:var(--ink-3)}
[data-testid="puuttuvat-viitteet"] code.katakri-koodi,
[data-testid="tiivistemuutos"] code.katakri-koodi{color:var(--ink-2)}
[data-testid="puuttuvat-viitteet"] .katakri-ominaisuudet div,
[data-testid="tiivistemuutos"] .katakri-ominaisuudet div{border-bottom-color:var(--line-1)}
[data-testid="puuttuvat-viitteet"] .katakri-ominaisuudet dt,
[data-testid="tiivistemuutos"] .katakri-ominaisuudet dt{color:var(--ink-3)}
[data-testid="puuttuvat-viitteet"] .katakri-ominaisuudet dd,
[data-testid="tiivistemuutos"] .katakri-ominaisuudet dd{color:var(--ink-1)}
[data-testid="puuttuvat-viitteet"] .katakri-huomio--neutraali,
[data-testid="tiivistemuutos"] .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}
[data-testid="tiivistemuutos"] .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
[data-testid="puuttuvat-viitteet"] .katakri-kortti--tiivis{background:var(--card);
  border-color:var(--line-1);box-shadow:var(--sh-card)}
[data-testid="puuttuvat-viitteet"] .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
[data-testid="tiivistemuutos"] .katakri-valinta{background:var(--card);border-color:var(--line-1)}
[data-testid="tiivistemuutos"] .katakri-valinta::before{border-color:var(--line-2);background:var(--card)}
[data-testid="tiivistemuutos"] .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
[data-testid="tiivistemuutos"] .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
[data-testid="tiivistemuutos"] .katakri-tiiviste summary{color:var(--ink-2)}
/* Eheysketjun lyhennetty sormenjalki on monospace, tiivistemuutoksen ei.
   Ero on tarkoitettu, ja se seuraa siita, mihin arvoa kaytetaan. Taalla
   auditoija vertaa merkkeja: saman kentan avattu arvo on monospace
   (`[data-testid="tapahtuman-eheys"] .katakri-ominaisuudet dd code`), ja
   kaksi eri kirjasinta samasta tiivisteesta rikkoisi juuri sen vertailun.
   Tiivistemuutoksessa omistaja tunnistaa, onko muutos hanen
   (`locked/_tiivistemuutos.html`), eika lue arvoa merkeittain. */
[data-testid="tapahtuman-eheys"] .katakri-tiiviste summary{color:var(--ink-2);
  font-family:var(--font-mono);font-size:var(--text-body-sm);cursor:pointer}
[data-testid="tapahtuman-eheys"] .katakri-tiiviste summary{color:var(--ink-2);
  font-family:var(--font-mono);font-size:var(--text-body-sm);cursor:pointer}
[data-testid="puuttuvat-viitteet"] a,
[data-testid="tiivistemuutos"] a{color:var(--accent)}
[data-testid="puuttuvat-viitteet"] :focus-visible,
[data-testid="tiivistemuutos"] :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Hyvaksyntalomake (`locked/_hyvaksyntalomake.html`) -------------------
 * Kaksi juurta: avauspainike esteineen (`[data-testid="hyvaksynnan-
 * toiminnot"]`) ja itse <dialog>, jolla on oma luokka `.katakri-modaali`. */
[data-testid="hyvaksynnan-toiminnot"] .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
[data-testid="hyvaksynnan-toiminnot"] .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
[data-testid="hyvaksynnan-toiminnot"] .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
[data-testid="hyvaksynnan-toiminnot"] .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}
[data-testid="hyvaksynnan-toiminnot"] :focus-visible{box-shadow:var(--shadow-focus-accent)}
.katakri-modaali{background:var(--card);border-color:var(--line-1);box-shadow:var(--sh-modal)}
/* `color` on `[open]`-valitsimella eika paljaalla luokalla: lomakkeen auki-tila
   on `.katakri-modaali[open]`, ja sen oma saanto ylla julistaa `color:inherit`
   (0,2,0). Paljaalla luokalla (0,1,0) Apexin muste haviaisi sille, ja auki
   oleva lomake perisi asiakirjan sivun `body`-musteen -- sama periytymisaukko,
   josta yleiskuvan kierros 1 hylattiin. */
.katakri-modaali[open]{color:var(--ink-2)}
.katakri-modaali h2,.katakri-modaali h3{color:var(--ink-1)}
.katakri-modaali .katakri-himmea{color:var(--ink-3)}
.katakri-modaali code.katakri-koodi{color:var(--ink-2)}
.katakri-modaali a{color:var(--accent)}
.katakri-modaali .katakri-ominaisuudet div{border-bottom-color:var(--line-1)}
.katakri-modaali .katakri-ominaisuudet dt{color:var(--ink-3)}
.katakri-modaali .katakri-ominaisuudet dd{color:var(--ink-1)}
.katakri-modaali .katakri-merkki{background:var(--sunken);color:var(--ink-3)}
.katakri-modaali .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-modaali .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
.katakri-modaali .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}
.katakri-modaali .katakri-kuittauslomake legend,
.katakri-modaali .katakri-kuittauslomake__nimike{color:var(--ink-1)}
.katakri-modaali .katakri-kuittauslomake__ohje{color:var(--ink-3)}
.katakri-modaali .katakri-kannanotot{border-color:var(--line-2)}
.katakri-modaali .katakri-kannanotto{background:var(--card);color:var(--ink-2)}
.katakri-modaali .katakri-kannanotto + .katakri-kannanotto{border-left-color:var(--line-2)}
.katakri-modaali .katakri-kannanotto--accepted:has(input:checked){background:var(--pos);color:var(--on-shell)}
.katakri-modaali .katakri-kannanotto--rejected:has(input:checked){background:var(--neg);color:var(--on-shell)}
.katakri-modaali .katakri-kannanotto--deferred:has(input:checked){background:var(--ink-2);color:var(--on-shell)}
.katakri-modaali .katakri-kannanotto:has(input:focus-visible){box-shadow:inset var(--shadow-focus-accent)}
.katakri-modaali .katakri-tekstialue{background:var(--card);border-color:var(--line-2);color:var(--ink-1)}
.katakri-modaali .katakri-tekstialue:focus{border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}
.katakri-modaali .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-modaali .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-modaali :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* --- Paatoslokien sivu: kiinnike `.katakri-paatoslokit` -------------------
 * `color` on pohjan rinnalla samasta syysta kuin yleiskuvalla (teht. 2e372620
 * kierros 2): pelkka `background` jattaisi sivun periytyvan edustavarin
 * `body`n `--text-body`iin -- kierroksella 1 Meshlyn musteeseen -- ja jokainen varisaannoton
 * elementti -- `<strong>`, `<time>`, `<dd>`, `currentColor`-ikoni -- piirtyisi
 * sita myoten. `--ink-2` on Apexin leipamuste. */
.katakri-paatoslokit{background:var(--page);color:var(--ink-2)}
.katakri-paatoslokit h1{color:var(--ink-1)}
.katakri-paatoslokit .katakri-murupolku{color:var(--ink-3)}
.katakri-paatoslokit .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-paatoslokit .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}
.katakri-paatoslokit a{color:var(--accent)}
.katakri-paatoslokit a:hover{color:var(--accent-hover)}
.katakri-paatoslokit .katakri-ylarivi{color:var(--ink-3)}
.katakri-paatoslokit .katakri-maara{color:var(--ink-4)}
.katakri-paatoslokit .katakri-johdanto{color:var(--ink-3)}
.katakri-paatoslokit .katakri-himmea{color:var(--ink-3)}

/* Kortti = Apexin `.card`. Sama `:not(.katakri-ylarivi)`-rajaus kuin
   yleiskuvalla: merkinnan otsikko on `<h2 class="katakri-ylarivi">`
   (`_paatoslokimerkinta.html`), ja ilman rajausta kortin otsikkosaanto
   voittaisi spesifisyydella ja piirtaisi sen `--ink-1`:lla. */
.katakri-paatoslokit .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-paatoslokit .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-paatoslokit .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
.katakri-paatoslokit .katakri-kortti h2:not(.katakri-ylarivi),
.katakri-paatoslokit .katakri-kortti h3:not(.katakri-ylarivi){color:var(--ink-1)}
.katakri-paatoslokit .katakri-kortti__tyhjateksti{color:var(--ink-3)}
.katakri-paatoslokit .katakri-kortti__tyhjateksti a{color:var(--accent)}

/* Rajauspalkki ja sen kentat = Apexin `.field` ja `.input`. */
.katakri-paatoslokit .katakri-valintapalkki{background:var(--card);border-color:var(--line-1)}
.katakri-paatoslokit .katakri-valintapalkki__maarat{color:var(--ink-3)}
.katakri-paatoslokit .katakri-kentta__nimike{color:var(--ink-2)}
.katakri-paatoslokit .katakri-syote{background:var(--card);border-color:var(--line-2);color:var(--ink-1)}
.katakri-paatoslokit .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-paatoslokit .katakri-syote:focus{border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}

/* Painike = Apexin `.btn-primary`. `filter:none` kumoaa Meshlyn
   `brightness(1.1)`-kirkastuksen: Apexilla hover on oma tokeninsa. */
.katakri-paatoslokit .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-paatoslokit .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-paatoslokit .katakri-tekstipainike{color:var(--accent)}

/* Merkki = Apexin `.chip`; tunnus ja vaitekoodi = koneluettava arvo. */
.katakri-paatoslokit .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-paatoslokit .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-paatoslokit .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-paatoslokit .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-paatoslokit .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-paatoslokit .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}
.katakri-paatoslokit .katakri-tunnus{color:var(--accent)}
.katakri-paatoslokit .katakri-vaitekoodi{background:var(--sunken);color:var(--ink-2)}
.katakri-paatoslokit .katakri-kontrollisiru{background:var(--card);border-color:var(--accent-soft);
  color:var(--accent-ink)}
.katakri-paatoslokit .katakri-tiedot-pieni dt{color:var(--ink-3)}
.katakri-paatoslokit .katakri-tiedot-pieni dd{color:var(--ink-1)}
.katakri-paatoslokit .katakri-kuittauslomake__nimike{color:var(--ink-1)}

/* Huomio = Apexin `.banner`. Varoitus on meripihkainen pehmea pari, neutraali
   upotettu harmaa -- sama jako kuin merkeilla. */
.katakri-paatoslokit .katakri-huomio{background:var(--pos-soft);border-color:var(--pos);color:var(--pos-ink)}
.katakri-paatoslokit .katakri-huomio .katakri-ikoni{color:var(--pos)}
.katakri-paatoslokit .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
.katakri-paatoslokit .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}
.katakri-paatoslokit .katakri-priorisoija--pois{background:var(--sunken);border-color:var(--line-2)}

/* Fokusrengas Apexin aksenttihalolla. Perussaanto `:focus-visible` on
   spesifisyydeltaan (0,1,0) ja tama (0,2,0), joten tama voittaa taman sivun
   sisalla eika kajoa muihin sivuihin. */
.katakri-paatoslokit :focus-visible{box-shadow:var(--shadow-focus-accent)}

/* ============ Hallintanäkymät — Apex 2.2 (tehtävä 9c73b57c) ============
 * Keraajanakyman (`keraajat.html` osioineen `_dokumenttilahteet.html` ja
 * `_dokumenttivienti.html`), konfiguraationakyman (`konfiguraatio.html`),
 * soveltuvuusrajauksen (`soveltuvuusrajaus.html`) ja lahdejarjestelmalistan
 * (`partials/_integraatiolista.html` sen ainoassa latojassa
 * `naytot/asetukset.html`) jaetut komponentit Apexin tokeneilla.
 *
 * Kiinnike on `.katakri-hallintanakymat` naiden neljan sivun
 * `<main>`-elementissa. Nelja sivua yhdella kiinnikkeella eika neljalla:
 * kiinnike ei rajaa sivua vaan sen, mille markkaukselle Apexin arvot
 * annetaan, ja naiden sivujen joukko on yksi ja sama -- kaikki neljä ovat
 * yllapitajan hallintasivuja (`SCHEDULE_COLLECTORS`, `MANAGE_CONFIGURATION`,
 * soveltuvuusrajauksen paatokset, asetusnakyman malli). Sama ratkaisu kuin
 * evidenssinakymilla (teht. 6b08a81b), joissa yksi kiinnike kattaa kaksi
 * templatea.
 *
 * Miksi kiinnike eika arvon vaihto paikallaan: paatos 2e305611
 * ("Apex-tokenien kayttoonotto tehdaan scopattuna"). Nama luokat
 * renderoityvat laajasti muualla — `.katakri-kortti` 43 muussa templatessa,
 * `.katakri-merkki*` 32:ssa, `.katakri-painike*` 34:ssa, `.katakri-taulukko`
 * 9:ssa — eivatka ne sivut ole viela migratoituja.
 *
 * Mika EI ole tassa:
 *
 * - Kehys (`.katakri-navi*`, `.katakri-ylapalkki*`) on oma tehtavansa
 *   (72ca7e29) ja renderoityy jokaisella sivulla. Sita ei oteta tanne, vaikka
 *   se on naidenkin sivujen reunoilla.
 * - `_moduulikartta.html` on teht. 9c73b57c:n templateluettelossa, mutta sen
 *   koko sisalto on `<script type="importmap">`: se ei piirra pikselia eika
 *   kanna yhtaan luokkaa, joten silla ei ole Apex-asua. Teht. 10:n kuvaus
 *   odotti siita nakyvaa moduulikarttaa (`--accent`/`--line-2`); sellaista
 *   ei ytimessa ole.
 *
 * Vaihdettuja ovat VAIN vari-, varjo- ja liiketokenit. Valistys, kulmat ja
 * typografia kayttavat ytimen omaa asteikkoa kuten yleiskuvassa (2e372620)
 * ja kehyksessa (72ca7e29); asteikot eivat yhdistyneet, kun Meshly-lohko
 * poistui (teht. 24cd5d6c).
 * ------------------------------------------------------------------------ */

/* Sivun pinta JA periytyva edustavari. `color` on tassa samasta syysta kuin
   yleiskuvalla: ilman sita jokainen varisaannoton elementti perii `body`n
   `--text-body`n, joka oli kierroksella 1 Meshlyn `--ink-700`.
   `--ink-2` on Apexin leipamuste. */
.katakri-hallintanakymat{background:var(--page);color:var(--ink-2)}

/* Otsikot: Apexin `.t-h*` on `--ink-1`. Luokaton `h1..h4` riittaa — nailla
   sivuilla yksikaan otsikko ei kanna `katakri-ylarivi`-luokkaa, ja ylarivin
   oma saanto alla on silti suurempaa spesifisyytta (0,2,0 vs 0,1,1). */
.katakri-hallintanakymat h1,.katakri-hallintanakymat h2,
.katakri-hallintanakymat h3,.katakri-hallintanakymat h4{color:var(--ink-1)}

/* Linkit Apexin aksentilla. Taulukon solulinkki sailyy periytyvana: perussaanto
   `.katakri-taulukko a{color:inherit}` on samaa spesifisyytta kuin alla oleva
   kiinnikkeen `a`-saanto (0,1,1) mutta tiedostossa aiemmin, joten se haviaisi
   lahdejarjestyksessa ja solulinkki vaihtaisi varia keskella riviaan. Siksi se
   toistetaan tassa kiinnikkeen alla. */
.katakri-hallintanakymat a{color:var(--accent)}
.katakri-hallintanakymat a:hover{color:var(--accent-hover)}
.katakri-hallintanakymat .katakri-taulukko a{color:inherit}

/* Murupolku: Apexin `.crumbs`. Erotin saa kontrollien viivan `--line-2`. */
.katakri-hallintanakymat .katakri-murupolku{color:var(--ink-3)}
.katakri-hallintanakymat .katakri-murupolku li:not(:last-child)::after{color:var(--line-2)}
.katakri-hallintanakymat .katakri-murupolku [aria-current="page"]{color:var(--ink-1)}

/* Ylarivi (eyebrow) = Apexin `.t-eyebrow`. */
.katakri-hallintanakymat .katakri-ylarivi{color:var(--ink-3)}

/* Kortti = Apexin `.card`. */
.katakri-hallintanakymat .katakri-kortti{background:var(--card);border-color:var(--line-1);
  box-shadow:var(--sh-card)}
.katakri-hallintanakymat .katakri-kortti--korostus{border-top-color:var(--accent)}
.katakri-hallintanakymat .katakri-kortti__otsikko{border-bottom-color:var(--line-1)}
.katakri-hallintanakymat .katakri-kortti__tyhjateksti{color:var(--ink-3)}

/* Taulukko = Apexin `.tbl`: otsakerivi `--sunken`, viivat `--line-1`,
   rivin osuma `--row-hover`. */
.katakri-hallintanakymat .katakri-taulukko caption{color:var(--ink-3)}
.katakri-hallintanakymat .katakri-taulukko th{background:var(--sunken);
  border-bottom-color:var(--line-1);color:var(--ink-3)}
.katakri-hallintanakymat .katakri-taulukko td{border-bottom-color:var(--line-1)}
.katakri-hallintanakymat .katakri-taulukko tbody tr:hover{background:var(--row-hover)}

/* Merkki = Apexin `.chip`. Varoitus saa `--accent2-*`:n eika `--warn`in samasta
   syysta kuin yleiskuvassa: Apexin `.chip.warn` on meripihkainen pehmea pari. */
.katakri-hallintanakymat .katakri-merkki--neutraali{background:var(--sunken);color:var(--ink-3)}
.katakri-hallintanakymat .katakri-merkki--info{background:var(--accent-soft);color:var(--accent-ink)}
.katakri-hallintanakymat .katakri-merkki--ok{background:var(--pos-soft);color:var(--pos-ink)}
.katakri-hallintanakymat .katakri-merkki--varoitus{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-hallintanakymat .katakri-merkki--vaara{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-hallintanakymat .katakri-merkki--reunus{border-color:var(--line-2);color:var(--ink-3)}

/* Painikkeet: Apexin `.btn-primary` ja `.btn-outline`. `filter:none` kumoaa
   Meshlyn `brightness(1.1)`-kirkastuksen; Apexilla hover on oma tokeninsa.

   Perusluokka ensin ja muunnokset sen jalkeen: molemmat ovat kiinnikkeen alla
   (0,2,0), joten lahdejarjestys ratkaisee. Perusluokka on tassa siksi, etta
   `konfiguraatio.html`:n lahetyspainike on pelkka `katakri-painike` ilman
   muunnosta, eika perussaanto julista sille pintaa lainkaan -- se piirtyi
   selaimen oman painikkeen harmaalla keskella migratoitua sivua. Apexin
   muunnokseton `.btn` on sama kuin `.btn-outline`, ja sen se nyt saa.

   Siksi `--toissijainen`illa EI ole omaa saantoa: perusluokka antaa sille jo
   saman asun, ja kahdesti kirjoitettuna ne ajautuisivat erilleen. `--haamu`
   sen sijaan on tassa, vaikka se ei renderoidy naille neljalle sivulle:
   perusluokan pinta (0,2,0) voittaisi sen `background:transparent`in (0,1,0),
   eli kiinnike litistaisi haamupainikkeen umpinaiseksi heti kun joku latoo
   sellaisen talle sivulle. Rajaus on halvempi kuin se vika. */
.katakri-hallintanakymat .katakri-painike{background:var(--card);
  border-color:var(--line-2);color:var(--ink-2)}
.katakri-hallintanakymat .katakri-painike:hover{background:var(--row-hover);
  border-color:var(--ink-4);color:var(--ink-1)}
.katakri-hallintanakymat .katakri-painike--ensisijainen{background:var(--accent);color:var(--on-shell)}
.katakri-hallintanakymat .katakri-painike--ensisijainen:hover{background:var(--accent-hover);
  color:var(--on-shell);filter:none}
.katakri-hallintanakymat .katakri-painike--haamu{background:transparent;
  border-color:transparent;color:var(--ink-3)}
.katakri-hallintanakymat .katakri-painike--haamu:hover{background:var(--sunken);
  border-color:transparent;color:var(--ink-1)}

/* Kentat = Apexin `.inp`: reuna `--line-2`, fokusrengas aksenttihalolla. */
.katakri-hallintanakymat .katakri-kentta__nimike{color:var(--ink-2)}
.katakri-hallintanakymat .katakri-syote{background:var(--card);border-color:var(--line-2);
  color:var(--ink-1)}
.katakri-hallintanakymat .katakri-syote::placeholder{color:var(--ink-4)}
.katakri-hallintanakymat .katakri-syote:focus{border-color:var(--accent);
  box-shadow:var(--shadow-focus-accent)}
.katakri-hallintanakymat .katakri-tekstialue{background:var(--card);border-color:var(--line-2);
  color:var(--ink-1)}
.katakri-hallintanakymat .katakri-tekstialue:focus{border-color:var(--accent);
  box-shadow:var(--shadow-focus-accent)}
/* Konfiguraatioehdotuksen muokkauskentta on upotettu pinta (`--sunken`) eika
   kortin pinta: se on tiedoston tekstia kortin paalla, ja sama vari kuin
   kortilla hukuttaisi sen rajan. Saanto on tassa eika komponenttilohkossa,
   koska `.katakri-hallintanakymat .katakri-tekstialue` (0,2,0) voittaa
   komponentin oman luokkasaannon (0,1,0) -- mitattu kaskadista, ei
   paateltu valitsimesta. */
.katakri-hallintanakymat .katakri-ehdotusikkuna__teksti{background:var(--sunken)}

/* Luokattomat kentat rakenteesta. `soveltuvuusrajaus.html` latoo nelja
   `<select>`:a ja kaksi `<textarea>`:a ilman luokkaa, ja ilman tata ne
   piirtyvat selaimen omalla kromilla keskella migratoitua sivua — vari, jota
   yksikaan tokeni ei anna. Sama ratkaisu kuin poikkeamanakymissa (08decf84).
   Vain asu, ei mittoja: `width` jaa asettamatta, jotta valikon vieressa oleva
   painike pysyy samalla rivilla. `:not(.katakri-tekstialue)` jattaa
   konfiguraation luokitellun tekstialueen sen omaan saantoon ylla —
   luokaton valitsin (0,1,1) voittaisi muuten luokkasaannon (0,1,0). */
.katakri-hallintanakymat select,
.katakri-hallintanakymat textarea:not(.katakri-tekstialue){padding:8px var(--space-3);
  border:var(--border-hairline) solid var(--line-2);border-radius:var(--radius-md);
  background:var(--card);font-family:var(--font-sans);font-size:var(--text-body-sm);
  color:var(--ink-1)}
.katakri-hallintanakymat select:focus,
.katakri-hallintanakymat textarea:not(.katakri-tekstialue):focus{outline:none;
  border-color:var(--accent);box-shadow:var(--shadow-focus-accent)}

/* Kannanotot (konfiguraation kuittausmalli) = Apexin segmentoitu kontrolli. */
.katakri-hallintanakymat .katakri-kannanotot{border-color:var(--line-2)}
.katakri-hallintanakymat .katakri-kannanotto{background:var(--card);color:var(--ink-2)}
.katakri-hallintanakymat .katakri-kannanotto + .katakri-kannanotto{border-left-color:var(--line-2)}
.katakri-hallintanakymat .katakri-kannanotto:has(input:focus-visible){box-shadow:inset var(--shadow-focus-accent)}

/* Kuittauslomakkeen nimike ja ohje. */
.katakri-hallintanakymat .katakri-kuittauslomake legend,
.katakri-hallintanakymat .katakri-kuittauslomake__nimike{color:var(--ink-1)}
.katakri-hallintanakymat .katakri-kuittauslomake__ohje{color:var(--ink-3)}

/* Valintanappi ja kytkin (asetusnakyman autonomiataso, lahdejarjestelmat). */
.katakri-hallintanakymat .katakri-valinta{background:var(--card);border-color:var(--line-1)}
.katakri-hallintanakymat .katakri-valinta[aria-checked="true"]{background:var(--accent-softer);
  border-color:var(--accent)}
.katakri-hallintanakymat .katakri-valinta::before{background:var(--card);border-color:var(--line-2)}
.katakri-hallintanakymat .katakri-valinta[aria-checked="true"]::before{border-color:var(--accent)}
.katakri-hallintanakymat .katakri-valinta__nimi{color:var(--ink-1)}
.katakri-hallintanakymat .katakri-valinta__kuvaus{color:var(--ink-3)}
.katakri-hallintanakymat .katakri-kytkin{background:var(--line-2)}
.katakri-hallintanakymat .katakri-kytkin[aria-checked="true"]{background:var(--accent)}
.katakri-hallintanakymat .katakri-kytkin::after{background:var(--card)}

/* Lahdejarjestelmien lista (`partials/_integraatiolista.html`). */
.katakri-hallintanakymat .katakri-integraatio{border-bottom-color:var(--line-1)}
.katakri-hallintanakymat .katakri-integraatio__nimi{color:var(--ink-1)}
.katakri-hallintanakymat .katakri-integraatio__meta{color:var(--ink-3)}

/* Huomiopalkit = Apexin `.banner`. Perussaanto ensin, muunnokset sen jalkeen:
   molemmat ovat kiinnikkeen alla (0,2,0), joten lahdejarjestys ratkaisee. */
.katakri-hallintanakymat .katakri-huomio{background:var(--pos-soft);border-color:var(--pos-soft);
  color:var(--pos-ink)}
.katakri-hallintanakymat .katakri-huomio .katakri-ikoni{color:var(--pos)}
.katakri-hallintanakymat .katakri-huomio--varoitus{background:var(--accent2-soft);
  border-color:var(--accent2-border);color:var(--accent2-ink)}
.katakri-hallintanakymat .katakri-huomio--neutraali{background:var(--sunken);
  border-color:var(--line-1);color:var(--ink-3)}

/* Keruun virhe = Apexin `.banner.neg`. Punainen erottaa sen hylatyn rivin
   meripihkaisesta; kierroksen 6 ero (p6-3) sailyy Apexin pareilla. */
.katakri-hallintanakymat .katakri-keruuvirhe{background:var(--neg-soft);border-color:var(--neg-border)}
.katakri-hallintanakymat .katakri-keruuvirhe__otsikko{color:var(--neg-ink)}
.katakri-hallintanakymat .katakri-keruuvirhe__teksti{color:var(--ink-2)}

/* Hylatyn rivin kentat ja rivi sellaisenaan. */
.katakri-hallintanakymat .katakri-raakarivi{background:var(--sunken)}
.katakri-hallintanakymat .katakri-raakarivi__kentta--puuttuu{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-hallintanakymat .katakri-raakarivi__kentta--nimetty{background:var(--accent2-soft);color:var(--accent2-ink)}
.katakri-hallintanakymat .katakri-raakarivi__puuttuu{color:var(--neg-ink)}
.katakri-hallintanakymat .katakri-puuttuva-kentta{background:var(--neg-soft);color:var(--neg-ink)}
.katakri-hallintanakymat .katakri-nimetty-kentta{background:var(--accent2-soft);color:var(--accent2-ink)}

/* Koodi. Koodilohko on Apexilla upotettu vaalea pinta (`--sunken`) eika tumma
   kaanteinen: se on luettava ote konfiguraatiosta tai keruun syysta, ei
   paatelohko. Monospace tulee jo perussaannosta (`--font-mono`). */
.katakri-hallintanakymat .katakri-koodilohko{background:var(--sunken);color:var(--ink-2)}
.katakri-hallintanakymat code.katakri-koodi{color:var(--ink-2)}
.katakri-hallintanakymat a.katakri-koodi{color:var(--accent)}

/* Rajausjonon ja rajauslistan rivit (`soveltuvuusrajaus.html`). */
.katakri-hallintanakymat .katakri-poikkeama__vakavuus{background:var(--line-2)}
.katakri-hallintanakymat .katakri-poikkeama__vakavuus--korkea{background:var(--neg)}
.katakri-hallintanakymat .katakri-poikkeama__vakavuus--keski{background:var(--warn)}
.katakri-hallintanakymat .katakri-poikkeama__id{color:var(--ink-3)}
.katakri-hallintanakymat .katakri-poikkeama__nimi{color:var(--ink-1)}
.katakri-hallintanakymat .katakri-poikkeama__meta{color:var(--ink-3)}
.katakri-hallintanakymat .katakri-poikkeama__maaraaika{color:var(--ink-4)}
.katakri-hallintanakymat .katakri-valintapalkki__maarat{color:var(--ink-3)}
.katakri-hallintanakymat .katakri-himmea{color:var(--ink-3)}

/* Kasikirja- ja sanastolinkki: tunnus on siirtyma (aksentti), kuvake sen
   vieressa toissijainen (`--ink-3`) — sama tyonjako kuin perussaannoissa. */
.katakri-hallintanakymat .katakri-kasikirjalinkki,
.katakri-hallintanakymat .katakri-sanastolinkki{color:var(--accent)}
.katakri-hallintanakymat .katakri-kasikirjalinkki--kuvake,
.katakri-hallintanakymat .katakri-sanastolinkki--kuvake{color:var(--ink-3)}
.katakri-hallintanakymat .katakri-kasikirjalinkki--kuvake:hover,
.katakri-hallintanakymat .katakri-kasikirjalinkki--kuvake:focus-visible,
.katakri-hallintanakymat .katakri-sanastolinkki--kuvake:hover,
.katakri-hallintanakymat .katakri-sanastolinkki--kuvake:focus-visible{color:var(--accent)}

/* Fokusrengas Apexin aksenttihalolla. Perussaanto `:focus-visible` on (0,1,0)
   ja tama (0,2,0), joten tama voittaa vain naiden sivujen sisalla. */
.katakri-hallintanakymat :focus-visible{box-shadow:var(--shadow-focus-accent)}
