/* ==========================================================================
   KOUKKU TAITURI — KÄYTTÖÖNOTTODOKUMENTAATION KUORI
   Yksi tyylitiedosto kaikille /kayttoonotto/-sivuille. Sivut sisältävät vain
   sisältöä; kaikki ulkoasu on täällä ja kaikki käyttäytyminen docs.js:ssä.
   Tarkoitus: sivun lisääminen on sisällön kirjoittamista, ei tyylin
   kopiointia — muuten viides sivu ajautuu ensimmäisestä erilleen.
   ========================================================================== */

:root {
  --pinta: #ffffff;
  --tausta: #f6f7f9;
  --teksti: #14161a;
  --himmea: #5a6472;
  /* Oli #8a93a0 = 2,89 : 1 sivun taustaa vasten. Se on WCAG AA -rike, ja se
     osui sivuston jokaiseen pikkutekstiin: yläpalkin "Käyttöönotto",
     sivupalkin ryhmäotsikko, "Tällä sivulla", "Päivitetty", edellinen/
     seuraava-suunnat. Nyt 4,61 : 1 taustaa ja 4,94 : 1 valkoista vasten.
     Hierarkia leipätekstiin (--himmea) tehdään koolla, versaalilla ja
     harvennuksella — ei enää haalistamalla lukukelvottomaksi. */
  --hyvin-himmea: #68717e;
  --viiva: #e4e7ec;
  --viiva-vahva: #d3d8e0;
  --brandi: #c81e24;
  --brandi-tumma: #a3161b;

  /* ---- Osavärit ----------------------------------------------------------
     Viisi osiota, viisi sävyä. Sävykulma etenee osajärjestyksessä (358° → 30°
     → 171° → 212° → 277°), joten väri koodaa myös lukujärjestyksen eikä vain
     aihepiiriä. Brändipunainen on osa 1, koska se on sisääntulo.

     JOKAINEN on valittu kantamaan VALKOISTA leipätekstiä: mitattu kontrasti
     valkoiseen on 5,73 / 6,16 / 6,50 / 6,63 / 7,55 : 1, ja korttien
     geometrisen kuvion (valkoinen 9 %) kanssa pahimmillaan 5,06 : 1.
     Vaatimus on 4,5 : 1. Suhde on (L1+0,05)/(L2+0,05) sRGB:n suhteellisista
     luminansseista.

     axe EI vahdi näitä: se merkitsee korttien 15 tekstisolmua
     "incomplete"-tilaan, koska ::before-gradientin takia se ei osaa päätellä
     taustaa — color-contrast-sääntö ei siis aja niille lainkaan. Todistettu:
     sävy 2,95 : 1:een vaalennettuna axe-portti näytti yhä vihreää.

     Siksi kontrasti mitataan pikseleistä omassa portissaan:
     e2e/a11y.spec.js → "käyttöönoton osakortit (leveä/kapea ruutu)". Se
     kuvaa kortin teksti piilotettuna ja etsii jokaisen tekstilaatikon alta
     pahimman taustapikselin. Jos muutat näitä viittä arvoa, aja se testi —
     pelkkä axe-ajo näyttää vihreää myös rikkinäisenä. */
  --osa-1: #c81e24;  /* punainen  — Mitä asennetaan (brändi, sisääntulo)   */
  --osa-2: #94500b;  /* pronssi   — Jakelu (käsityö koneella, lämmin)      */
  --osa-3: #0c6a5c;  /* petroli   — Lisensointi (hallinto, kylmenee)       */
  --osa-4: #1f5da5;  /* meri      — Suljettu verkko (infra, eristys)       */
  --osa-5: #733a97;  /* luumu     — Vaatimustenmukaisuus (päätepiste)      */

  --koodi-tausta: #14161a;
  --koodi-teksti: #e8eaed;
  --sivupalkki: 264px;
  --sisallys: 216px;
  --ylapalkki: 56px;
  --radius: 10px;
  --varjo: 0 1px 2px rgba(20, 22, 26, .04), 0 4px 12px -4px rgba(20, 22, 26, .06);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--ylapalkki) + 20px); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--tausta);
  color: var(--teksti);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  /* Suomen yhdyssana on pisin rivielementti tällä sivustolla, ja
     tekstizoomissa se ei enää mahdu riville: 200 %:n zoomilla 375 px:n
     ruudulla "Vaatimustenmukaisuus"-otsikko työnsi KOKO SIVUN 240 px
     vaakavieritykseen (WCAG 1.4.4/1.4.10). break-word katkaisee sanan VAIN
     kun se ei muuten mahdu — normaalikoossa mikään ei muutu. Ominaisuus
     periytyy, joten yksi sääntö kattaa otsikot, leipätekstin ja kortit;
     white-space: pre (koodilohkot) ja nowrap (taulukon otsikot) ohittavat
     sen omissa kohdissaan. */
  overflow-wrap: break-word;
}

a { color: var(--brandi); text-decoration: none; font-weight: 550; }
a:hover { color: var(--brandi-tumma); text-decoration: underline; }
:focus-visible { outline: 2px solid var(--brandi); outline-offset: 2px; border-radius: 4px; }

/* Ohita navigaatio -linkki: näppäimistökäyttäjä pääsee suoraan sisältöön. */
.ohita {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: var(--teksti); color: #fff; padding: .7rem 1.1rem;
  border-radius: 0 0 var(--radius) 0; font-weight: 600;
}
.ohita:focus { left: 0; color: #fff; text-decoration: none; }

/* ---------- Yläpalkki ---------- */
.docs-ylapalkki {
  position: sticky; top: 0; z-index: 40;
  height: var(--ylapalkki);
  background: rgba(255, 255, 255, .88);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--viiva);
  display: flex; align-items: center; gap: 1rem;
  padding: 0 1.25rem;
}
.docs-merkki { display: flex; align-items: center; gap: .6rem; font-weight: 700; color: var(--teksti); font-size: .95rem; }
.docs-merkki:hover { text-decoration: none; color: var(--teksti); }
.docs-merkki .piste { width: 22px; height: 22px; border-radius: 6px; background: var(--brandi); color: #fff; display: grid; place-items: center; font-size: .78rem; font-weight: 800; }
.docs-merkki .osa { color: var(--hyvin-himmea); font-weight: 500; }
.docs-ylapalkki .oikea { margin-left: auto; display: flex; align-items: center; gap: 1rem; font-size: .85rem; }
.docs-ylapalkki .oikea a { color: var(--himmea); font-weight: 500; }
.docs-ylapalkki .oikea a:hover { color: var(--teksti); }

/* Valikkopainike näkyy vain kapealla ruudulla. */
.docs-valikkonappi {
  display: none; align-items: center; gap: .45rem;
  background: none; border: 1px solid var(--viiva-vahva); border-radius: 8px;
  padding: .35rem .7rem; font: inherit; font-size: .85rem; font-weight: 600;
  color: var(--teksti); cursor: pointer;
}

/* ---------- Asettelu ---------- */
.docs-kehys {
  display: grid;
  grid-template-columns: var(--sivupalkki) minmax(0, 1fr) var(--sisallys);
  gap: 2.5rem;
  max-width: 1400px; margin: 0 auto;
  padding: 0 1.5rem;
  align-items: start;
}

/* ---------- Sivupalkki ---------- */
.docs-sivupalkki {
  position: sticky; top: var(--ylapalkki);
  max-height: calc(100vh - var(--ylapalkki));
  overflow-y: auto;
  padding: 2rem .5rem 3rem 0;
}
.docs-sivupalkki .ryhma { font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--hyvin-himmea); padding: 0 .75rem; margin-bottom: .6rem; }
.docs-sivupalkki ol { list-style: none; }
.docs-sivupalkki li { margin-bottom: 1px; }
.docs-sivupalkki .linkki {
  display: flex; gap: .7rem; align-items: baseline;
  padding: .5rem .75rem; border-radius: 8px;
  color: var(--himmea); font-weight: 500; font-size: .9rem; line-height: 1.4;
}
.docs-sivupalkki .linkki:hover { background: #eef0f3; color: var(--teksti); text-decoration: none; }
.docs-sivupalkki .linkki .nro { color: var(--hyvin-himmea); font-size: .78rem; font-weight: 600; font-variant-numeric: tabular-nums; flex: none; }
.docs-sivupalkki .linkki[aria-current="page"] { background: #fdeaea; color: var(--brandi-tumma); font-weight: 650; }
.docs-sivupalkki .linkki[aria-current="page"] .nro { color: var(--brandi); }
.docs-sivupalkki .erotin { height: 1px; background: var(--viiva); margin: 1.25rem .75rem; }
.docs-sivupalkki .lisa { display: block; padding: .4rem .75rem; font-size: .86rem; color: var(--himmea); font-weight: 500; }
.docs-sivupalkki .lisa:hover { color: var(--teksti); text-decoration: none; }

/* ---------- Sisältö ---------- */
.docs-sisalto { padding: 2.5rem 0 4rem; min-width: 0; }

.docs-otsikko { margin-bottom: 2rem; }
.docs-otsikko .kicker {
  display: flex; align-items: center; gap: .6rem;
  font-size: .76rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--osa, var(--brandi));
}
/* Sävypalkki kickerin edessä sitoo alasivun siihen korttiin, josta lukija
   tuli: osa 3 on petrolinvihreä kortilla JA sivun otsikossa. Etusivulla
   sävyä ei ole, jolloin palkki on brändinpunainen. */
.docs-otsikko .kicker::before {
  content: ''; flex: none; width: 1.5rem; height: 3px; border-radius: 2px;
  background: currentColor;
}
.docs-otsikko h1 { font-size: clamp(1.85rem, 3.2vw, 2.4rem); font-weight: 700; letter-spacing: -.025em; line-height: 1.15; margin: .45rem 0 0; text-wrap: balance; }
.docs-otsikko .kuvaus { margin-top: .85rem; font-size: 1.06rem; color: var(--himmea); max-width: 62ch; text-wrap: pretty; }
.docs-otsikko .paivitetty { margin-top: .9rem; font-size: .82rem; color: var(--hyvin-himmea); }

/* Alasivun sävy. Attribuutti on <html>-elementissä, jotta muuttuja on
   käytettävissä myös docs.js:n rakentamassa sivupalkissa. */
html[data-osa="1"] { --osa: var(--osa-1); }
html[data-osa="2"] { --osa: var(--osa-2); }
html[data-osa="3"] { --osa: var(--osa-3); }
html[data-osa="4"] { --osa: var(--osa-4); }
html[data-osa="5"] { --osa: var(--osa-5); }

/* ---- Etusivun otsikko: mittasuhde, joka ohjaa katseen ----
   Suhde otsikko : korttiotsikko on 50 px : 21 px ≈ 2,4×. Ilman sitä sivun
   iso otsikko ja viisi korttiotsikkoa kilpailevat samasta huomiosta eikä
   mikään kerro mistä aloittaa. Osioiden väliotsikot asettuvat väliin
   (29 px), jolloin porrastus on otsikko → osio → kortti. */
.docs-otsikko--etu { margin-bottom: 2.4rem; }
.docs-otsikko--etu h1 {
  font-size: clamp(2.1rem, 4.6vw, 3.15rem);
  font-weight: 600; letter-spacing: -.034em; line-height: 1.07;
  margin-top: .7rem;
}
.docs-otsikko--etu .kuvaus { font-size: 1.13rem; max-width: 48ch; margin-top: 1rem; }
.docs-otsikko--etu ~ section > h2 { font-size: 1.8rem; font-weight: 600; letter-spacing: -.026em; margin-top: 3.5rem; }

/* Etusivun aloitusnosto ei ole "vinkki" vaan sivun teesi. Vihreä
   onnistumislaatikko antoi sille väärän merkityksen ja vei huomion juuri
   siitä kohdasta, jossa katseen pitää siirtyä otsikosta kortteihin —
   siksi se on tässä hiljainen. Sisältö on ennallaan. */
.docs-otsikko--etu + .hyva {
  background: var(--pinta); border: 1px solid var(--viiva);
  border-left: 3px solid var(--brandi);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 1.1rem 1.3rem; max-width: 62ch;
}
.docs-otsikko--etu + .hyva p { color: var(--himmea); }
.docs-otsikko--etu + .hyva strong { color: var(--teksti); font-weight: 640; }

/* Sivupalkin numerot ovat sivuston värilegenda: sama sävy kuin kortilla.
   Kaikki sävyt yltävät ≥ 5,0 : 1 valkoista sivupalkkia vasten. */
.docs-sivupalkki ol li:nth-child(1) .nro { color: var(--osa-1); }
.docs-sivupalkki ol li:nth-child(2) .nro { color: var(--osa-2); }
.docs-sivupalkki ol li:nth-child(3) .nro { color: var(--osa-3); }
.docs-sivupalkki ol li:nth-child(4) .nro { color: var(--osa-4); }
.docs-sivupalkki ol li:nth-child(5) .nro { color: var(--osa-5); }
/* Auki oleva sivu saa oman sävynsä myös korostuksena — muuten petrolinvihreä
   osa 3 istuisi vaaleanpunaisella pohjalla. Punainen jää varalle selaimille,
   jotka eivät tunne color-mixiä. */
html[data-osa] .docs-sivupalkki .linkki[aria-current="page"] {
  background: #fdeaea;
  background: color-mix(in srgb, var(--osa) 9%, #fff);
  color: var(--osa);
}
html[data-osa] .docs-sivupalkki .linkki[aria-current="page"] .nro { color: var(--osa); }

/* Ankkurikohteen etäisyys navista. 🔴 KOSKEE MYÖS h3[id]:tä: docs.js tekee
   ankkurilinkin jokaiseen h3[id]-otsikkoon, mutta suoja oli vain sectionilla.
   Mitattu 320 px:llä: yläpalkki venyy siinä kolmelle riville (144 px), kun
   scroll-padding-top lupaa vain 108 px — lisensointi.html:n yhdeksän h3-
   ankkuria laskeutuivat 36 px navin ALLE (WCAG 2.4.11). Sectionit selvisivät
   vain siksi, että niillä oli tämä sääntö. */
.docs-sisalto section,
.docs-sisalto h3[id] { scroll-margin-top: calc(var(--ylapalkki) + 24px); }
.docs-sisalto section { padding-top: .5rem; }
.docs-sisalto h2 {
  font-size: 1.4rem; font-weight: 680; letter-spacing: -.02em;
  margin: 2.75rem 0 .5rem; padding-top: .5rem;
  position: relative;
}
.docs-sisalto section:first-of-type h2 { margin-top: 1rem; }
.docs-sisalto h3 { font-size: 1.05rem; font-weight: 650; margin: 1.9rem 0 .4rem; }
.docs-sisalto p { color: var(--himmea); margin-bottom: .85rem; max-width: 68ch; text-wrap: pretty; }
.docs-sisalto strong { color: var(--teksti); font-weight: 620; }
.docs-sisalto ul, .docs-sisalto ol { color: var(--himmea); margin: 0 0 1rem 1.35rem; max-width: 66ch; }
.docs-sisalto li { margin-bottom: .45rem; }
.docs-sisalto li::marker { color: var(--hyvin-himmea); }

/* Osion aloittava tiivistys — lukija näkee heti mitä osiossa tehdään. */
.tiivis {
  font-size: .97rem; color: var(--himmea);
  border-left: 3px solid var(--viiva-vahva); padding: .1rem 0 .1rem .9rem;
  margin: 0 0 1.1rem !important;
}
.tiivis em, .tiivis i { font-style: normal; }

/* Ankkurilinkki otsikon perässä (docs.js lisää). */
.ankkuri { opacity: 0; margin-left: .5rem; font-weight: 400; color: var(--hyvin-himmea); font-size: .85em; }
h2:hover .ankkuri, h3:hover .ankkuri, .ankkuri:focus { opacity: 1; text-decoration: none; }

/* ---------- Laatikot ---------- */
.huomio, .hyva {
  border-radius: var(--radius); padding: 1rem 1.15rem; margin: 1.25rem 0;
  border: 1px solid; font-size: .95rem; max-width: 68ch;
}
.huomio { background: #fffbeb; border-color: #fde68a; }
.huomio p, .huomio li { color: #8a5a06; }
.hyva { background: #f0fdf4; border-color: #bbf7d0; }
.hyva p, .hyva li { color: #065f46; }
.huomio p:last-child, .hyva p:last-child { margin-bottom: 0; }
.huomio strong, .hyva strong { color: inherit; font-weight: 700; }

/* ---------- Koodi ---------- */
code {
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  font-size: .86em;
  background: #eef0f3; border: 1px solid var(--viiva);
  border-radius: 5px; padding: .1em .38em; color: var(--teksti);
  overflow-wrap: break-word;
}
/* Vierivä säiliö on PRE ITSE — ei docs.js:n lisäämä .koodilohko-kääre.
   Kääreeseen sidottuna overflow-x jäi kokonaan pois ympäristössä, jossa
   JavaScript on estetty: komentorivi vuoti ulos laatikostaan ja vieritti
   KOKO SIVUA vaakasuunnassa (mitattu 596 px jakelu.html ja 649 px
   vaatimustenmukaisuus.html, 375 px:n ruudulla). Kunnan työasemakäytäntö
   saa estää skriptit — sivun asettelu ei saa hajota siitä. Kääre on enää
   kopiointipainikkeen ankkuri. */
.docs-sisalto pre {
  background: var(--koodi-tausta); color: var(--koodi-teksti);
  border-radius: var(--radius); padding: 1.05rem 1.15rem; overflow-x: auto;
  font-size: .86rem; line-height: 1.6;
  margin: 1rem 0 1.35rem; max-width: 68ch;
}
.docs-sisalto pre code { background: none; border: 0; padding: 0; color: inherit; font-size: 1em; }
.koodilohko { position: relative; margin: 1rem 0 1.35rem; max-width: 68ch; }
.koodilohko pre { margin: 0; max-width: none; }
.kopioi {
  position: absolute; top: .55rem; right: .55rem;
  background: rgba(255, 255, 255, .1); color: #cfd4da;
  border: 1px solid rgba(255, 255, 255, .16); border-radius: 7px;
  padding: .32rem .6rem; font: inherit; font-size: .76rem; font-weight: 600;
  cursor: pointer; transition: background .15s, color .15s; opacity: 0;
}
.koodilohko:hover .kopioi, .kopioi:focus { opacity: 1; }
.kopioi:hover { background: rgba(255, 255, 255, .2); color: #fff; }
.kopioi[data-tila="ok"] { opacity: 1; background: #16a34a; border-color: #16a34a; color: #fff; }

/* ---------- Taulukot ---------- */
.taulukko { overflow-x: auto; margin: 1rem 0 1.5rem; border: 1px solid var(--viiva); border-radius: var(--radius); background: var(--pinta); }
/* docs.js tekee vierivistä alueista näppäimistöllä tavoitettavia. Yleinen
   :focus-visible pyöristäisi ne 4 px:iin kesken fokuksen — säilytetään muoto. */
.taulukko:focus-visible, .docs-sisalto pre:focus-visible { border-radius: var(--radius); outline-offset: 2px; }
.taulukko table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.taulukko th, .taulukko td { text-align: left; padding: .75rem .9rem; border-bottom: 1px solid var(--viiva); vertical-align: top; }
.taulukko tr:last-child td { border-bottom: 0; }
.taulukko th { background: #fafbfc; font-weight: 650; color: var(--teksti); white-space: nowrap; }
.taulukko td { color: var(--himmea); }
.taulukko code { font-size: .82em; }

/* ---------- Ympäristövalitsin ----------
   Napit rakentaa docs.js. Ilman skriptiä laatikko jää tyhjäksi — tyhjä
   reunustettu laatikko olisi pelkkä hämmennys, joten se ei renderöidy. */
.ymparisto:empty { display: none; }
.ymparisto {
  background: var(--pinta); border: 1px solid var(--viiva);
  border-radius: var(--radius); padding: 1.1rem 1.25rem; margin: 0 0 2rem;
  box-shadow: var(--varjo); max-width: 68ch;
}
.ymparisto .kysymys { font-weight: 650; color: var(--teksti); margin-bottom: .25rem; }
.ymparisto .apu { font-size: .88rem; color: var(--himmea); margin-bottom: .85rem; }
.ymparisto .napit { display: flex; flex-wrap: wrap; gap: .5rem; }
.ymparisto button {
  font: inherit; font-size: .89rem; font-weight: 600;
  background: var(--pinta); color: var(--himmea);
  border: 1px solid var(--viiva-vahva); border-radius: 8px;
  padding: .5rem .9rem; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.ymparisto button:hover { border-color: var(--hyvin-himmea); color: var(--teksti); }
.ymparisto button[aria-pressed="true"] { background: var(--brandi); border-color: var(--brandi); color: #fff; }
[data-ymparisto] { display: block; }
[data-ymparisto].piilossa { display: none; }

/* ---------- Sisällysluettelo oikealla ---------- */
.docs-sisallys {
  position: sticky; top: var(--ylapalkki);
  max-height: calc(100vh - var(--ylapalkki));
  overflow-y: auto; padding: 2.9rem 0 3rem;
  font-size: .85rem;
}
.docs-sisallys .otsikko { font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--hyvin-himmea); margin-bottom: .7rem; }
.docs-sisallys ul { list-style: none; border-left: 1px solid var(--viiva); }
.docs-sisallys a { display: block; padding: .32rem 0 .32rem .9rem; margin-left: -1px; border-left: 2px solid transparent; color: var(--himmea); font-weight: 500; line-height: 1.45; }
.docs-sisallys a:hover { color: var(--teksti); text-decoration: none; }
.docs-sisallys a[aria-current="true"] { color: var(--brandi); border-left-color: var(--brandi); font-weight: 600; }

/* ---------- Sivunavigointi alhaalla ---------- */
/* minmax(0, 1fr), ei auto eikä 1fr: ruudukkorata ei saa venyä sisällön
   VÄHIMMÄISLEVEYTEEN. 200 %:n tekstizoomilla sana "Lisensointi" ei mahtunut
   301 px:n sisältösarakkeeseen, rata venyi sen mittaiseksi ja koko sivu vieri
   81 px vaakasuunnassa (ilmavali.html @375). Huom: bodyn overflow-wrap:
   break-word EI yksin riitä tähän — se estää rivin ylivuodon mutta ei pienennä
   min-content-kokoa, joka ruudukkoradan mitoittaa. Siksi rata on nollattava. */
.docs-seuraava {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem;
  margin-top: 3.5rem; padding-top: 2rem; border-top: 1px solid var(--viiva);
}
@media (min-width: 640px) { .docs-seuraava { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.docs-seuraava a {
  border: 1px solid var(--viiva); border-radius: var(--radius); padding: .9rem 1.1rem;
  background: var(--pinta); display: block;
}
.docs-seuraava a:hover { border-color: var(--viiva-vahva); text-decoration: none; box-shadow: var(--varjo); }
.docs-seuraava .suunta { font-size: .76rem; color: var(--hyvin-himmea); font-weight: 600; }
.docs-seuraava .nimi { color: var(--teksti); font-weight: 650; margin-top: .15rem; }
.docs-seuraava .edellinen { text-align: left; }
.docs-seuraava .seuraava { text-align: right; }
.docs-seuraava .seuraava:only-child { grid-column: 2; }

.docs-alatunniste { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--viiva); font-size: .87rem; color: var(--himmea); max-width: 68ch; }

/* ==========================================================================
   ETUSIVUN OSAKORTIT
   Kortti EI ole valkoinen laatikko harmaalla reunuksella. Se on täysvärinen
   pinta, jonka ainoa erottava tekijä on sävy — ei reunusta, ei varjoa, ei
   ikonia. Näin viisi korttia eroaa toisistaan yhdellä silmäyksellä eikä
   lukijan tarvitse lukea otsikoita erottaakseen ne.

   KAIKKI korttiteksti on puhdasta valkoista. Se on tarkoituksellista: heti
   kun osa tekstistä olisi läpinäkyvää valkoista, jokainen sävy pitäisi
   mitata erikseen jokaisella läpinäkyvyysasteella. Hierarkia tehdään
   koolla, paksuudella ja harvennuksella — ei himmentämällä.
   ========================================================================== */

.docs-kortit { display: grid; gap: 1rem; margin: 1.75rem 0 0; }

.docs-kortti {
  --siirto: 0rem;
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--osa); color: #fff;
  border: 0; border-radius: 14px;
  padding: 1.35rem 1.4rem 2.9rem;
  transform: translateY(var(--siirto));
  transition: transform .18s ease, box-shadow .18s ease;
}
.docs-kortit > :nth-child(1) { --osa: var(--osa-1); }
.docs-kortit > :nth-child(2) { --osa: var(--osa-2); }
.docs-kortit > :nth-child(3) { --osa: var(--osa-3); }
.docs-kortit > :nth-child(4) { --osa: var(--osa-4); }
.docs-kortit > :nth-child(5) { --osa: var(--osa-5); }

/* Osanumero: ei himmennystä vaan harvennus ja sitä jatkava hiusviiva.
   Sama luettavuus kuin otsikolla, eri tekstuuri. */
.docs-kortti .nro {
  display: flex; align-items: center; gap: .6rem;
  font-size: .76rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: #fff;
}
.docs-kortti .nro::after {
  content: ''; flex: 1 1 auto; height: 1px; max-width: 3.5rem;
  background: rgba(255, 255, 255, .55);
}
.docs-kortti h2 {
  font-size: 1.32rem !important; font-weight: 620; letter-spacing: -.018em;
  line-height: 1.24; color: #fff; text-wrap: balance;
  margin: .7rem 0 .5rem !important; padding: 0 !important;
}
.docs-kortti p {
  font-size: .93rem; line-height: 1.55; color: #fff; margin: 0;
  max-width: 40ch;
}

/* Geometrinen kuviointi: pelkkää CSS-gradienttia, ei kuvatiedostoja —
   sisältöturvakäytäntö estää ulkoiset varat. Jokaisella kortilla on OMA
   kuvionsa, koska viisi kertaa sama kuvio on sama vika kuin viisi kertaa
   sama harmaa reunus. Valkoisen enimmäispeitto on 9 %, ja kontrasti on
   mitattu sen kanssa (heikoin 5,06 : 1). */
.docs-kortti::before {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  right: -12%; bottom: -22%; width: 78%; height: 86%;
  opacity: .95; transition: opacity .18s ease;
}
.docs-kortit > :nth-child(1)::before {   /* samankeskiset kaaret */
  background: repeating-radial-gradient(circle at 78% 92%,
    transparent 0 27px, rgba(255, 255, 255, .09) 27px 29px);
}
.docs-kortit > :nth-child(2)::before {   /* vino viivoitus */
  background: repeating-linear-gradient(48deg,
    transparent 0 14px, rgba(255, 255, 255, .085) 14px 16px);
}
.docs-kortit > :nth-child(3)::before {   /* ristikko */
  background:
    repeating-linear-gradient(0deg, transparent 0 22px, rgba(255, 255, 255, .05) 22px 23px),
    repeating-linear-gradient(90deg, transparent 0 22px, rgba(255, 255, 255, .05) 22px 23px);
}
.docs-kortit > :nth-child(4)::before {   /* renkaat + vaakaviivasto */
  background:
    repeating-radial-gradient(circle at 22% 88%, transparent 0 19px, rgba(255, 255, 255, .075) 19px 21px),
    repeating-linear-gradient(0deg, transparent 0 11px, rgba(255, 255, 255, .04) 11px 12px);
}
.docs-kortit > :nth-child(5)::before {   /* sisäkkäiset neliöt */
  background: repeating-conic-gradient(from 45deg at 88% 96%,
    rgba(255, 255, 255, .075) 0 25%, transparent 0 50%);
  background-size: 46px 46px;
}

/* Kulmanuoli: reunuksista taitettu, ei merkkiä eikä ikonifonttia — mikään
   ruudunlukija ei lue sitä, koska sisältöä ei ole. */
.docs-kortti::after {
  content: ''; position: absolute; right: 1.5rem; bottom: 1.45rem;
  width: 9px; height: 9px;
  border: 2px solid #fff; border-left: 0; border-bottom: 0;
  transform: rotate(45deg); opacity: .9;
  transition: transform .18s ease, opacity .18s ease;
}

.docs-kortti:hover { text-decoration: none; color: #fff; }
@media (hover: hover) {
  .docs-kortti:hover {
    transform: translateY(calc(var(--siirto) - 3px));
    /* Varjo kortin OMASSA sävyssä, ei geneerinen harmaa. Neutraali varjo
       ensin, jotta vanha selain ilman color-mixiä saa silti nostovihjeen. */
    box-shadow: 0 16px 34px -14px rgba(20, 22, 26, .38);
    box-shadow: 0 16px 34px -14px color-mix(in srgb, var(--osa) 72%, #000);
  }
  .docs-kortti:hover::after { transform: translateX(4px) rotate(45deg); opacity: 1; }
  .docs-kortti:hover::before { opacity: 1; }
}
/* Fokusrengas: brändipunainen ei näy punaisella kortilla. Valkoinen sisään,
   tumma ulos — erottuu sekä kortista että sivun taustasta. */
.docs-kortti:focus-visible {
  outline: 3px solid #fff; outline-offset: -7px;
  box-shadow: 0 0 0 3px var(--teksti);
}
@media (prefers-reduced-motion: reduce) {
  .docs-kortti, .docs-kortti::after, .docs-kortti::before { transition: none; }
  .docs-kortti:hover { transform: translateY(var(--siirto)); }
  .docs-kortti:hover::after { transform: rotate(45deg); }
}

/* ---- Kaksi saraketta: osat 1–4 pareina, osa 5 päätepalkkina ---- */
@media (min-width: 700px) {
  .docs-kortit { grid-template-columns: 1fr 1fr; gap: 1.25rem; }
  .docs-kortti { min-height: 15.5rem; padding: 1.5rem 1.6rem 3rem; }
  /* Osa 5 on eri laji: se ei ole asennusvaihe vaan se aineisto, joka
     luovutetaan hankinnalle. Siksi se on leveä päätepalkki eikä viides
     yhtä suuri ruutu — ja samalla katoaa orpo kortti ruudukon nurkasta. */
  .docs-kortit > :nth-child(5) {
    grid-column: 1 / -1; min-height: 0;
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    column-gap: 2.5rem; align-items: start;
    padding: 1.6rem 1.8rem 1.75rem;
  }
  .docs-kortit > :nth-child(5) .nro { grid-column: 1; grid-row: 1; }
  .docs-kortit > :nth-child(5) h2 { grid-column: 1; grid-row: 2; margin: .55rem 0 0 !important; }
  .docs-kortit > :nth-child(5) p { grid-column: 2; grid-row: 1 / span 2; max-width: 48ch; }
  .docs-kortit > :nth-child(5)::before { width: 42%; height: 150%; bottom: -40%; }
  .docs-kortit > :nth-child(5)::after { bottom: 1.7rem; right: 1.8rem; }
}

/* ---- Porrastus: oikea sarake laskeutuu ----
   Toteutus on transform eikä margin, jotta ruudukon rivikorkeudet pysyvät
   ennallaan — marginaali kasvattaisi rivirataa ja repisi epätasaiset raot
   korttien väliin. Porrastus on VAIN leveällä ruudulla: kapealla se olisi
   pelkkää hukkatilaa, joten se katoaa tarkoituksella. */
@media (min-width: 900px) {
  .docs-kortit > :nth-child(even) { --siirto: 2.6rem; }
  .docs-kortit > :nth-child(5) { margin-top: 2.6rem; }
}

/* ---- Kapea ruutu: porrastus pois, pino jäljelle ----
   Mitattu 375 px:llä. Kortit ovat lohkoja yhden sarakkeen ruudukossa, joten
   vaakavieritystä ei synny; pitkät yhdyssanat ("Vaatimustenmukaisuus")
   mahtuvat 1,32 rem:llä kortin sisäleveyteen. Koko kortti on linkki, joten
   kosketuskohde on satoja pikseleitä — nuoli on pelkkä vihje. */
@media (max-width: 699px) {
  .docs-kortit { gap: .9rem; margin-top: 1.4rem; }
  .docs-kortti { padding: 1.25rem 1.3rem 2.7rem; border-radius: 12px; }
  .docs-kortti h2 { font-size: 1.22rem !important; }
  .docs-kortti p { max-width: none; }
  .docs-otsikko--etu .kuvaus { font-size: 1.05rem; }
  .docs-otsikko--etu ~ section > h2 { font-size: 1.45rem; margin-top: 2.75rem; }
}

/* ---------- Kapea ruutu ---------- */
@media (max-width: 1180px) {
  .docs-kehys { grid-template-columns: var(--sivupalkki) minmax(0, 1fr); gap: 2rem; }
  .docs-sisallys { display: none; }
}
@media (max-width: 860px) {
  .docs-kehys { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 0 1.15rem; }
  .docs-valikkonappi { display: inline-flex; }
  .docs-sivupalkki {
    position: fixed; inset: var(--ylapalkki) auto 0 0; width: min(300px, 84vw);
    background: var(--pinta); border-right: 1px solid var(--viiva);
    padding: 1.25rem 1rem 2rem; z-index: 35;
    transform: translateX(-102%); transition: transform .2s ease;
    box-shadow: 0 12px 40px -12px rgba(20, 22, 26, .2);
  }
  .docs-sivupalkki.auki { transform: none; }
  .docs-sisalto { padding-top: 1.75rem; }
  .docs-otsikko h1 { font-size: 1.75rem; }
  /* Etusivun otsikko pysyy kortteja selvästi isompana myös puhelimessa
     (32 px vs. 19,5 px ≈ 1,6×) — muuten pinotut kortit kilpailevat sen
     kanssa eikä sivun aloituskohta erotu. */
  .docs-otsikko--etu h1 { font-size: 2rem; }
}
@media (prefers-reduced-motion: reduce) { .docs-sivupalkki { transition: none; } }

/* Tulostus: navigaatio pois, sisältö täyteen leveyteen. */
@media print {
  .docs-ylapalkki, .docs-sivupalkki, .docs-sisallys, .docs-seuraava, .kopioi, .ohita, .ymparisto .napit { display: none !important; }
  body { background: #fff; }
  .docs-kehys { grid-template-columns: 1fr; padding: 0; }
  .docs-sisalto p, .docs-sisalto ul { max-width: none; }
  [data-ymparisto].piilossa { display: block !important; }
  .docs-sisalto pre { background: #f4f4f5; color: #14161a; border: 1px solid #d4d4d8; }
  /* 🔴 Paperia ei voi vierittää. overflow-x: auto jäi tulostuksessa päälle,
     joten jokainen laatikkoaan pidempi komento KATKESI kesken — mitattu
     8 lohkoa jakelu.html-sivulla ja 1 lisensointi.html-sivulla A4:llä.
     Juuri ne komennot ovat se syy, jonka takia sivu tulostetaan hankinnan
     liitteeksi. Rivitetään sen sijaan, ja katkaistaan pitkä polku mistä
     tahansa kohtaa jos muuta ei ole. */
  .docs-sisalto pre {
    overflow-x: visible !important;
    white-space: pre-wrap; overflow-wrap: anywhere; max-width: none;
  }
  .koodilohko { display: block !important; max-width: none; }
  code { overflow-wrap: anywhere; }
  .taulukko { overflow-x: visible !important; }
  /* Tulostimet jättävät taustavärit yleensä pois — valkoinen teksti
     valkoisella paperilla katoaisi. Kortit muuttuvat tulostettaessa
     mustavalkoisiksi lohkoiksi, joissa sävy on vain reunaviivana. */
  .docs-kortit { grid-template-columns: 1fr !important; gap: .6rem !important; }
  .docs-kortti {
    background: #fff !important; color: #14161a !important;
    border: 1px solid #d4d4d8 !important; border-left: 4px solid var(--osa) !important;
    border-radius: 0 !important; min-height: 0 !important;
    padding: .7rem .9rem !important; transform: none !important;
    margin-top: 0 !important; display: block !important;
    break-inside: avoid;
  }
  .docs-kortti .nro { color: var(--osa) !important; }
  .docs-kortti .nro::after { background: #d4d4d8 !important; }
  .docs-kortti h2, .docs-kortti p { color: #14161a !important; max-width: none !important; }
  .docs-kortti::before, .docs-kortti::after { display: none !important; }
}

/* ==========================================================================
   MOBIILIOPTIMOINTI — mitattu Playwrightilla 360 / 375 / 414 / 768 px
   Periaate: mitään ei piiloteta mahtumisen vuoksi.
   ========================================================================== */

/* ---------- Yläpalkki: ei vaakavieritystä ----------
   Mitattu ennen: 360 px:n ruudulla palkin sisältö oli 416 px leveä, jolloin
   selain levitti asettelun 416 px:iin ja koko sivu vieri sivusuunnassa.
   Alle 560 px palkki rivittyy kahdelle riville — mikään linkki ei katoa. */
@media (max-width: 860px) {
  .docs-ylapalkki { gap: .6rem; padding: 0 .9rem; }
  /* min-width: 0 antaa merkin kutistua, mutta yhdellä rivillä teksti vuotaa
     silloin ulos laatikostaan (mitattu +16 px 200 %:n tekstizoomilla).
     Sallitaan rivitys: merkki kasvaa korkeussuunnassa, ei ulos ruudulta. */
  .docs-merkki { font-size: .9rem; min-width: 0; flex-wrap: wrap; row-gap: 0; }
  .docs-ylapalkki .oikea { gap: .75rem; }
}
@media (max-width: 560px) {
  :root { --ylapalkki: 88px; }
  .docs-ylapalkki {
    height: auto; min-height: var(--ylapalkki);
    flex-wrap: wrap; align-content: center;
    padding: .35rem .9rem; row-gap: 0;
  }
  .docs-ylapalkki .oikea { margin-left: 0; width: 100%; gap: 1.25rem; }
}

/* ---------- Kosketuskohteet 44x44 px (WCAG 2.5.5) ---------- */
@media (max-width: 860px) {
  .docs-valikkonappi { min-height: 44px; padding: .35rem .8rem; }
  .docs-merkki { min-height: 44px; }
  .docs-ylapalkki .oikea a,
  .docs-sivupalkki .linkki,
  .docs-sivupalkki .lisa,
  .ymparisto button,
  .kopioi,
  .docs-sisallys a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .docs-sivupalkki .linkki,
  .docs-sivupalkki .lisa { display: flex; }
  .docs-sivupalkki .linkki { align-items: center; }
}

/* ---------- Kopiointipainike näkyviin kosketuslaitteella ----------
   .kopioi paljastui vain :hoverilla, joten sormella koodilohkoa ei voinut
   kopioida lainkaan — toiminto oli tosiasiassa poissa mobiilista.

   🔴 Painike EI saa maata koodin päällä kosketuslaitteella. Kelluvana se
   peitti lyhyen komentolohkon oikean laidan, ja siitä alkanut sormiveto ei
   vierittänyt lohkoa lainkaan: mitattu lisensointi.html @375, lohko jonka
   sisältö on 499 px ja laatikko 317 px, scrollLeft 0 → 0. Käyttäjä ei
   päässyt komennon loppuun millään eleellä. Muissa lohkoissa sama veto
   toimi (0 → 122…135), joten ero oli nimenomaan painike kosketuspisteen
   alla. Nyt painike on omalla rivillään koodin yläpuolella — se ei peitä
   riviäkään eikä ole vedon tiellä. */
@media (hover: none), (pointer: coarse) {
  .kopioi { opacity: 1; }
  .koodilohko { display: flex; flex-direction: column; align-items: flex-end; }
  .koodilohko pre { align-self: stretch; }
  .kopioi {
    position: static; order: -1; margin-bottom: .35rem;
    background: #eef0f3; color: var(--teksti);
    border-color: var(--viiva-vahva);
  }
  .kopioi:hover { background: #e4e7ec; color: var(--teksti); }
}

/* ---------- "Tällä sivulla" -sisällys myös kapealla ----------
   Oli display:none alle 1180 px, eli sivun osioluettelo katosi kokonaan
   mobiilissa ja tabletissa. Nyt se näkyy sisällön yläpuolella tiiviinä
   linkkiryhmänä — sama tieto, vähemmän pystytilaa. */
@media (max-width: 1180px) {
  .docs-sisallys {
    display: block;
    position: static; order: -1;
    max-height: none; overflow: visible;
    margin: 1.6rem 0 0; padding: .85rem 1rem;
    background: var(--pinta); border: 1px solid var(--viiva);
    border-radius: var(--radius);
  }
  /* Yksi rivi, joka vierii omassa laatikossaan: pystysuunnassa tämä vie
     ~70 px eikä puolta ruutua, ja jokainen osio on yhä tavoitettavissa.

     🔴 EI scroll-snappia. Mitattu lisensointi.html @375: selaimen oma
     "vieritä fokusoitu elementti näkyviin" EI toimi tällä rivillä — Tab
     jätti sirun "Sanasto, jos termit…" 179 px rivin oikean reunan taakse
     scrollLeft pysyessä nollassa, eli fokusrengasta ei näkynyt lainkaan
     (WCAG 2.4.7). docs.js vierittää sirun siksi itse, ja snap kumoaisi juuri
     sen ohjelmallisen vierityksen napsauttamalla rivin takaisin lähimpään
     sirunalkuun. Snap oli koriste; fokuksen näkyminen ei ole. */
  .docs-sisallys ul {
    border-left: 0; display: flex; flex-wrap: nowrap; gap: .4rem;
    overflow-x: auto;
    padding-bottom: .25rem; -webkit-overflow-scrolling: touch;
  }
  .docs-sisallys li { flex: none; }
  .docs-sisallys a {
    display: inline-flex; align-items: center; min-height: 44px;
    margin-left: 0; padding: .35rem .8rem; white-space: nowrap;
    border-left: 0; border-radius: 999px; background: #f2f4f7;
  }
  .docs-sisallys a[aria-current="true"] { background: #fdeaea; border-left: 0; }
}
@media (max-width: 1180px) and (min-width: 861px) {
  .docs-sisallys { grid-column: 2; }
}

/* ---------- Tekstikoko, rivitys ja kosketusleveys ----------
   🔴 EHTO OLI SIDOTTU VÄÄRÄÄN AVAIMEEN. Lattia kirjoitettiin aikanaan
   `max-width: 768px` -kyselyyn, mutta puhelin VAAKA-ASENNOSSA on 812 px
   leveä: siinä asennossa jokainen näistä säännöistä katosi. Mitattu
   812 × 375: koodi 12,07 px, "Tällä sivulla" 11,52 px, päivitysleima
   13,12 px ja yläpalkin "Hinnat" 41,4 px leveä (WCAG 2.5.5 vaatii 44).
   Avaimessa on nyt myös osoitinlaji: karkea osoitin = sormi, ruudun
   leveydestä riippumatta.

   Lattia koskee myös kuoren pikkutekstejä (kicker, osanumerot, sivupalkin
   ryhmäotsikko, kopiointipainike): mitattuna ne olivat 11,52–13,76 px
   jokaisella puhelinleveydellä. Hierarkia tehdään versaalilla,
   harvennuksella ja paksuudella — ei koolla luettavan rajan alta. */
@media (max-width: 768px), (pointer: coarse) {
  .docs-otsikko .paivitetty,
  .docs-alatunniste,
  .taulukko table { font-size: .875rem; }
  /* max() antaa 14 px:n lattian rikkomatta suhteellista kokoa isommilla. */
  code { font-size: max(.875rem, .9em); }
  .taulukko code { font-size: max(.875rem, 1em); }
  .docs-sisalto pre, .docs-sisalto pre code { font-size: .875rem; }
  /* Pitkät rekisteripolut ja avaimet rivittyvät leipätekstissä. */
  .docs-sisalto p code, .docs-sisalto li code { overflow-wrap: anywhere; }

  .docs-valikkonappi,
  .docs-ylapalkki .oikea a,
  .docs-sivupalkki .ryhma,
  .docs-sivupalkki .linkki .nro,
  .docs-sivupalkki .lisa,
  .docs-sisallys .otsikko,
  .docs-sisallys a,
  .docs-otsikko .kicker,
  .docs-kortti .nro,
  .docs-seuraava .suunta,
  .kopioi { font-size: .875rem; }

  /* Yläpalkin oikeat linkit: korkeus oli jo 44, leveys 41. */
  .docs-ylapalkki .oikea a { min-width: 44px; justify-content: center; }
}
