/* Taustakoristeet (renkaat, ristit, pisteet) pois KAIKILTA leveyksilta.
   Ne olivat geometriaa brandissa joka on kasin piirrettya kuvitusta — kaksi eri
   kielta samalla sivulla. Vyohykevarit ja hahmot kantavat taustan yksinaan.
   Decor-komponentti jaa paikalleen: se on kaytossa mm. kultaisessa footer-
   bandissa, ja saannon voi kumota yhdesta paikasta jos linja muuttuu. */
.il-decor{display:none !important}

/* idunian.com — sivuston yhteiset tyylit.
   Jaettu kaikkien sivujen kesken (index / privacy / opettajille): yksi
   paikka jossa vyohykkeet, liike ja responsiivisuus maaritellaan. */
html{overflow-x:hidden}body{margin:0;background:var(--blue-dark);overflow-x:clip}
.il-bleed{position:relative;overflow-x:clip;overflow-y:visible}
/* Edge figures need room outside the 1200px column: shrink, then drop out. */
@media (max-width:1340px){.il-edge{height:240px !important;width:auto !important}}
@media (max-width:1100px){.il-edge{display:none !important}}@media (max-width:900px){section>div>div[style*="grid-template-columns"],div[style*="grid-template-columns"][style*="1.35fr"]{grid-template-columns:1fr !important}}
/* Section eyebrows. The DS token size (0.875rem) is calibrated for in-game UI,
   where an eyebrow sits inches from the eye on a small screen. Here each one is
   the only label saying which section you're in, and at that size in a muted
   zone colour they read as fine print. Bigger, plus a bar in currentColor so it
   carries on navy, gold, sand and green alike. */
/* No leading rule. It was added to make the eyebrows findable, and it did —
   but on a page with this many sections it turned every heading into a bulleted
   list item and the dashes were the first thing the eye landed on. The size and
   tracking do the job on their own; the label should be quiet. */
.il-eyebrow{font-size:1.0625rem;letter-spacing:.15em}

/* ── Responsive ────────────────────────────────────────────────────────────
   The two-column layouts are inline grids of the form
   `minmax(380px,1.3fr) minmax(220px,.7fr)`. Below 900px the minimums no
   longer fit side by side, so the browser overflows the viewport instead of
   wrapping. Collapse exactly those to one column — `repeat(auto-fit,…)`
   grids already reflow on their own and `auto 1fr` icon+text pairs must
   stay two columns at every width. */
@media (max-width:900px){
  [style*="minmax"]:not([style*="auto-fit"]){grid-template-columns:1fr !important}
  /* Figures anchored to negative offsets have no room left once the column
     is the whole screen; the .il-edge rule already drops the edge ones. */
  section{padding-left:20px !important;padding-right:20px !important}
}
@media (max-width:900px){
  /* The dashed rail joining the three steps is drawn at left:42% of a
     two-column row. In one column it runs through the middle of the cards. */
  ol > span[aria-hidden="true"]{display:none !important}
  /* In one column the numeral is anchored to a full-width cell, so left:-4%
     pushes it off the screen where `overflow-x: clip` eats it. Pinned inside
     the column and moved up out from behind the card instead. */
  .il-stepnum{left:0 !important;right:auto !important;top:0 !important;
    transform:translateY(-18%) !important;-webkit-text-stroke-width:3px !important}
  /* Six villains standing shoulder to shoulder need ~900px. Below that they
     overflow rather than shrink, because each is capped by height. Drop to a
     centred trio — a line-up of three still reads as a line-up. */
  .il-villain-row{justify-content:center !important;gap:0 !important;padding:0 !important}
  .il-villain-row > :nth-child(n+4){display:none !important}
  /* Same for the food row above the footer. */
  .il-food-row > :nth-child(n+4){display:none !important}
  /* The section's lead figure is capped at 500px tall; in a narrow column
     nothing else limits it and it swallows the screen. */
  .il-figure-xl{max-height:300px !important;margin-left:-8% !important;margin-bottom:-40px !important}

  /* "Pahis poydalla" -paneelin SISEMPI ruudukko. Ulompi romahtaa oikein
     yhteen sarakkeeseen, mutta sisempi on `auto 1fr`, jossa `auto` on kortin
     luontainen 170 px — mitattu 390 px:ssa tekstisarakkeeksi jai 61 px ja
     otsikko katkesi muotoon KOV / A / VAT / SA. Kortti ylos ja keskelle,
     teksti alle koko leveydelle. Huom: paneelin tunnisterivit ovat myos
     `auto 1fr` eivatka kaanny — 52 px:n ikoni ja teksti mahtuvat rinnakkain
     kapeallakin, ja pystyyn kaannettyna rivit hajoaisivat. */
  .il-fp-card{grid-template-columns:1fr !important}
  .il-fp-card > :first-child{justify-self:center !important}

  /* In one column the villain used to sit BELOW its own name, quote and
     button, so you scrolled past a wall of text to meet it. Anchored to the
     top-right of that block it stands beside the name instead — the figure
     starts level with "KOVA KAKKA" and runs down from there. The column
     reserves room on the right so the text never runs under it. */
  /* Varattu kaista ja hahmon leveys on sidottava TOISIINSA. Aiemmin vain
     korkeus oli katkaistu (max-height:250px) ja leveys jai kuvan luontaiseksi:
     mitattu 390 px:ssa hahmo oli 290 px levea ja ulottui x 209 -> 499, eli se
     meni nimen ja repliikin paalle JA valui 140 px ruudun ulkopuolelle, missa
     `overflow-x:clip` leikkasi siita puolet pois. Nyt leveys on osuus samasta
     sarakkeesta jonka padding varaa, ja `right:-6%` on nollattu — kapealla ei
     ole marginaalia josta roikkua. */
  /* Varattu korkeus ja hahmon korkeus ovat SAMA arvo, jotta hahmo ei voi
     ylittaa omaa kaistaansa milla tahansa kuvasuhteella: kiintea 240 px jatti
     kapealla 120 px tyhjaa kultaa, ja pelkka pienennys olisi paastanyt
     pystymallisen hahmon korttien paalle. */
  .il-villain-col{position:relative !important;padding-right:44% !important;
    min-height:min(34vw,250px)}
  .il-villain-col .il-figure-xl{position:absolute !important;right:0 !important;top:0 !important;
    margin:0 !important;max-height:min(34vw,250px) !important;max-width:40% !important;
    height:auto !important}
  /* The card and its counters are the section's proof; centred they read as a
     pair, left-aligned they drifted against a centred heading block. */
  .il-villain-cards{justify-items:center !important;padding-bottom:var(--space-6) !important}
  .il-villain-pair{justify-content:center !important;width:100%}
}
@media (max-width:560px){
  .il-villain-row > :nth-child(n+3){display:none !important}
  .il-food-row > :nth-child(n+3){display:none !important}
  .il-figure-xl{max-height:230px !important;margin-left:0 !important}
}
@media (max-width:820px){
  /* The header is absolutely positioned over the hero so the navy runs to the
     top of the page. Below ~820px the four nav labels wrap to three rows,
     which — being out of flow — land on top of the hero's own eyebrow and
     push the buy button off the right edge. Put it back in flow and drop the
     inline nav; every one of those links is repeated in the footer. */
  /* The bar STAYS FIXED on phones too: the menu has to be reachable from
     anywhere on a 12 000px page, and that is the whole point of the burger.
     Made relative it also stopped sitting over the hero, so it rendered as a
     separate dark slab above the navy — which is what made the top of the
     page look broken. Over the hero and transparent, it disappears into the
     zone until you scroll, at which point the stuck background takes over. */
  header nav{display:none !important}
  #root > div > section:first-of-type{padding-top:88px !important}
  /* Bigger touch targets, and the flag at the size the game's menu uses. */
  .il-header .il-lang > button{min-height:52px !important;padding:8px 18px !important;
    font-size:var(--text-base) !important;gap:10px !important}
  .il-header .il-lang svg{width:34px !important;height:23px !important;border-radius:4px !important}
  .il-burger{width:52px !important;height:52px !important}
  .il-burger > span{width:24px !important;height:3px !important}

  /* The handover runs on phones too — same --il-p, same shrink-into-the-bar
     move as on desktop. What was broken before was not the handover but the
     BAR LAYOUT: with the logo invisible, flex left its empty box on the left
     and pushed the language pill and burger into a floating cluster. Fixed by
     taking the pill out of the flow and centring it, and pinning the burger
     right — so the row reads logo · language · menu at every scroll position,
     whether or not the logo has faded in yet. */
  /* Kielipilleri OLI absoluuttisesti keskitetty, jotta palkki lukisi
     logo - kieli - valikko myos silloin kun logo on viela nakymaton. Kapealla
     se meni logon paalle: mitattu 390 px, vieritys 1200 px (stuck-tila) ->
     logon oikea reuna 156 px, pillerin vasen reuna 129 px, eli 27 px
     paallekkain. Absoluuttinen elementti ei osallistu flexin kutistumiseen,
     joten mikaan shrink-saato ei olisi voinut estaa sita. Takaisin riviin ja
     oikeaan reunaan: nyt leveydet lasketaan yhteen eika paallekkaisyys ole
     enaa mahdollinen missaan vierityskohdassa. */
  .il-header > div{position:relative}
  .il-lang{margin-left:auto !important}
  /* The hero lockup keeps its own line and never exceeds the column. */
  .il-herologo{max-width:min(340px,84%) !important}
}
@media (max-width:900px){
  /* In one column the hero figure is still absolutely positioned and 600px
     tall, so it rises out of its own box and lands on the headline. Put the
     whole cast back in the flow as one centred group — hero AND carrot, who
     belong together and were the pair the layout was built around. */
  .il-herofig{min-height:0 !important;display:flex !important;align-items:flex-end;
    justify-content:center;gap:0;margin-top:var(--space-4)}
  .il-herohero{position:relative !important;right:auto !important;bottom:auto !important;
    margin:0 !important;max-height:300px !important;max-width:70% !important;order:2}
  /* The carrot is tagged .il-edge, which drops every edge figure below 1100px
     — correct for figures anchored to the page edge, wrong for this one: it is
     the hero's companion, not decoration at the margin. Shown, scaled down and
     placed beside them instead. */
  /* height:auto is load-bearing: the general .il-edge rule at ≤1340px sets
     `height:240px !important`, and pinning a width here as well would fix BOTH
     axes and squash the carrot. One axis is set, the other must be free. */
  .il-herofig .il-edge{display:block !important;position:relative !important;
    left:auto !important;bottom:auto !important;
    width:78px !important;height:auto !important;max-height:none !important;
    margin:0 -14px -6px 0 !important;order:1;transform:rotate(-8deg) !important}
  /* The text column reserves 120px of bottom padding for a figure that, in one
     column, is no longer beside it — that is the gap that pushed the hero far
     down the page. Tighter leading on the lead paragraph too: five slack lines
     of body copy is what actually pushes the cast off the first screen. */
  .il-herotext{padding-bottom:0 !important}
  .il-herotext > p{line-height:1.45 !important}
  /* Both routes into the game side by side, as on desktop. Stacked they read
     as a primary action with an afterthought under it; the browser version is
     the lower-friction one and must not look secondary. `nowrap` on the labels
     is what forced the wrap, so it is lifted here and the buttons share the
     row instead. */
  .il-herocta{flex-wrap:nowrap !important;gap:var(--space-3) !important;align-items:stretch !important}
  .il-herocta > a,.il-herocta > button{flex:1 1 0;min-width:0;white-space:normal !important;
    padding-left:var(--space-3) !important;padding-right:var(--space-3) !important;
    text-align:center;font-size:var(--text-sm) !important;
    /* One label wraps to two lines and the other does not; stretched and
       centred they still end up the same height and share a baseline. */
    display:flex !important;align-items:center;justify-content:center;line-height:1.2}
  /* KAUPPAMERKKI EI OLE NAPPI. Saannot ylla on kirjoitettu kahdelle
     tekstinapille: ne venyttavat lapsen taydelle leveydelle ja pakottavat
     `display:flex`, jolloin Play-lockup ja sen alle kuuluva kehotus asettuivat
     vierekkain ja valkoinen laatikko taytti koko palstan. Merkki on pystyyn
     ladottu kuva + teksti, joten se pitaa oman ruudukkonsa ja oman leveytensa. */
  .il-herocta > .il-storebadge{flex:0 0 auto !important;display:grid !important;
    padding-left:22px !important;padding-right:22px !important;font-size:inherit !important}

}
@media (max-width:620px){
  h1{font-size:clamp(2rem,9.5vw,2.75rem) !important}
  h2{font-size:clamp(1.6rem,7.5vw,2.25rem) !important}
  section{padding-left:16px !important;padding-right:16px !important}
  /* One column, so the brand centres over the content rather than hugging a
     left edge that no longer means anything. */
  .il-herologo{display:block !important;margin-left:auto !important;margin-right:auto !important;
    transform-origin:center top !important}
  /* Palkin oma reunus on inline-tyylissa (18px/10px 24px), joten se on
     kumottava tasta. Ilman tata rivi logo + kielipilleri + valikko on 373 px
     levea eika mahdu 360 px:n puhelimeen. */
  .il-header{padding-left:16px !important;padding-right:16px !important}
  .il-header > div{gap:var(--space-3) !important}
}

/* ── Motion ────────────────────────────────────────────────────────────────
   Reveal on scroll plus press/hover feedback. Everything sits behind
   prefers-reduced-motion: this is a children's product and the zones are
   already saturated — motion is the seasoning, not the meal. */
@media (prefers-reduced-motion: no-preference){
  /* `translate`/`scale` as their own properties, never the `transform`
     shorthand: cards carry an inline `transform: rotate(…)` tilt and tiles a
     deliberate 0.7deg skew. A transform-based animation would silently
     straighten them at the end of the transition. */
  .il-rise{opacity:0;translate:0 26px;transition:opacity .55s cubic-bezier(.22,.61,.36,1),translate .55s cubic-bezier(.22,.61,.36,1)}
  .il-rise.il-in{opacity:1;translate:0 0}
  /* Stagger siblings so a row of cards arrives as a wave, not a block. */
  .il-rise.il-d1{transition-delay:.08s}.il-rise.il-d2{transition-delay:.16s}
  .il-rise.il-d3{transition-delay:.24s}.il-rise.il-d4{transition-delay:.32s}

  /* Chunky buttons: the DS gives them a hard `0 Npx 0` shadow, so the press
     is a real vertical move — lift on hover, sink on click. */
  .il-press{transition:translate .16s ease,filter .16s ease}
  .il-press:hover{translate:0 -3px;filter:brightness(1.04)}
  .il-press:active{translate:0 2px}
  /* Cards lift — they are clickable (they open the zoom). */
  .il-card-hover{transition:translate .2s cubic-bezier(.22,.61,.36,1),scale .2s cubic-bezier(.22,.61,.36,1)}
  .il-card-hover:hover{translate:0 -8px;scale:1.03}

  /* Character idle — the game's own `villainIdle`, keyframe for keyframe
     (packages/app/src/ui.css), including its 4.6s period: the figures on this
     page must breathe at the same rate as the ones on the card in the app.
     cqw swapped for px since there is no container query context here, and
     `transform-origin: center bottom` so they rise from their feet.
     Separate translate/rotate/scale properties, never `transform` — several
     of these figures carry an inline rotate() and one carries scaleX(-1). */
  @keyframes ilIdle{
    0%   {translate:0 0;      rotate:0deg;    scale:1 1}
    30%  {translate:0 -7px;   rotate:-0.7deg; scale:1.01 1.016}
    55%  {translate:0 -10px;  rotate:0deg;    scale:1.014 1.022}
    80%  {translate:0 -5px;   rotate:0.7deg;  scale:1.008 1.01}
    100% {translate:0 0;      rotate:0deg;    scale:1 1}
  }
  .il-breathe{animation:ilIdle 4.6s ease-in-out infinite;transform-origin:center bottom;will-change:translate}

  /* Edge figures slide in from the side they are anchored to, as if peeking
     round the edge of the page when you reach them. It runs on the same
     `translate` property the idle uses, so the two must never be live at
     once: JS adds .il-breathe only after the slide has finished. Until then
     the animation simply does not exist on the element and the transition
     owns the property. */
  /* Distance and duration are both up (72→120px, .62→.85s): at the old values
     the slide was over before the figure had cleared the bottom of the
     viewport, so it was always already in place by the time you looked at it.
     The trigger moved too — see the observer's rootMargin. */
  .il-peek{opacity:0;transition:opacity .55s var(--ease-out),translate .85s cubic-bezier(.19,.72,.3,1)}
  .il-peek.il-from-left{translate:-120px 0}
  .il-peek.il-from-right{translate:120px 0}
  .il-peek.il-in{opacity:1;translate:0 0}

  /* The floating control gets a slower, shallower version of the same idle so
     it reads as alive without pulling the eye off the page content. */
  .il-totop--on > img{animation:ilIdle 5.4s ease-in-out infinite;transform-origin:center bottom}
  .il-totop{transition:opacity .25s var(--ease-out),translate .25s var(--ease-out),scale .18s var(--ease-out)}
  .il-totop:hover{scale:1.06}
  .il-totop:active{scale:.96}
  .il-srclink:hover{text-decoration:underline;text-underline-offset:3px}
}
/* Eight tags divide evenly at 4 and at 2; three columns would strand two. */
@media (max-width:820px){.il-powergrid{grid-template-columns:repeat(2,1fr) !important}}

/* Mode-card header: the character group must never push the label out of the
   card. It shrinks before anything else and can never exceed the card. */
.il-modechars img{max-width:100%;height:auto}
.il-modehead > div{min-width:0}

/* ── Gameplay carousel ─────────────────────────────────────────────────────
   Wide: three phones in a row, controls hidden. Narrow: one phone at a time
   with arrows and dots. Same markup both ways — the container switches. */
.il-carousel-nav{display:none}
@media (max-width:820px){
  /* Window clips, track moves — never the same element (see GameLook.jsx). */
  .il-carousel-view{overflow:hidden}
  .il-carousel{display:grid !important;grid-auto-flow:column;grid-auto-columns:100%;
    gap:0 !important;flex-wrap:nowrap !important;
    /* --i is set inline by React; the slide is a transform on the track. */
    translate:calc(var(--i,0) * -100%) 0;transition:translate .38s cubic-bezier(.22,.61,.36,1)}
  .il-carousel > figure{width:100% !important;display:grid;justify-items:center;padding:0 4px}
  .il-carousel > figure > video,.il-carousel > figure > img{width:min(268px,80%) !important}
  .il-carousel > figure > figcaption{text-align:center;max-width:34ch}
  .il-carousel-nav{display:flex;align-items:center;justify-content:center;gap:var(--space-4);
    margin-top:var(--space-5)}
  .il-carousel-nav > button{width:52px;height:52px;border-radius:999px;cursor:pointer;
    border:2px solid rgba(243,237,227,.35);background:transparent;color:var(--ink);font-size:20px}
  .il-carousel-nav > button:disabled{opacity:.3;cursor:default}
  .il-dots{display:flex;gap:10px}
  .il-dots > button{width:12px;height:12px;padding:0;border-radius:999px;cursor:pointer;
    border:none;background:rgba(243,237,227,.32)}
  .il-dots > button.is-on{background:var(--gold);scale:1.25}
}
@media (prefers-reduced-motion:reduce){.il-carousel{transition:none !important}}

/* ── Card zoom ─────────────────────────────────────────────────────────────
   Ported from the game's cardZoom.css, values unchanged where they carry a
   decision: the 380px cap, the height-derived third term (7rem = button +
   gaps), the panel being exactly card-width in portrait, and the direction
   split — stacked scrolls as one column, side-by-side scrolls the panel only.
   Measured in the game at 1366×768: a 548px-tall card leaves no room for the
   teaching text below it, which is the text the whole feature exists for. */
.il-zoom{
  --cz-w:min(84vw,380px,calc((100dvh - 7rem) * 192 / 277));
  position:fixed;inset:0;z-index:60;padding:1rem;
  background:rgba(23,18,47,.86);
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.il-zoom__inner{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:1rem;max-width:100%;max-height:100%;overflow:auto}
.il-zoom__col{display:flex;flex-direction:column;align-items:center;gap:1rem;flex:0 0 auto}
/* .tcard is position:absolute; inset:0 — it needs a sized, positioned box, and
   container-type so its own cqw units resolve against the card, not the
   viewport (that bug once made the card border 4.6x too wide). */
.il-zoom__card{position:relative;flex:0 0 auto;width:var(--cz-w);aspect-ratio:192/277;
  container-type:inline-size;filter:drop-shadow(0 18px 30px rgba(0,0,0,.5))}
.il-zoom__edu{position:relative;z-index:1;border:none;border-radius:999px;padding:.65rem 1.5rem;
  background:linear-gradient(180deg,#f4b942,#d9992a);color:#3a2600;font-family:var(--font-display);
  font-weight:800;font-size:1.05rem;cursor:pointer;box-shadow:0 4px 12px rgba(0,0,0,.45)}
.il-zoom__edu:active{scale:.96}
.il-zoom__panel{position:relative;z-index:1;width:var(--cz-w);background:#fff;border-radius:16px;
  padding:1.1rem 1.25rem;box-shadow:0 12px 30px rgba(0,0,0,.4);text-align:left}
.il-zoom__title{margin:0 0 .55rem;font-size:1.15rem;font-weight:900;color:#b8442f}
.il-zoom__text{margin:0;color:#2a2340;font-size:1rem;line-height:1.5}
.il-zoom__source{margin:.75rem 0 0;font-size:.8125rem;font-style:italic;color:#6b6480}
.il-zoom__close{position:fixed;top:1rem;right:1rem;width:48px;height:48px;border-radius:999px;
  border:none;background:rgba(255,255,255,.16);color:#f3ede3;font-size:20px;cursor:pointer}
@media (min-width:900px){
  .il-zoom__inner{flex-direction:row;align-items:center;gap:1.5rem}
  .il-zoom__panel{width:min(30rem,42vw);max-height:calc(100dvh - 4rem);overflow-y:auto}
}

/* ── Logo handover ─────────────────────────────────────────────────────────
   One lockup visible at a time. At the top of the page it is the big one in
   the hero; as you scroll it shrinks towards the bar and the header mark
   takes over, so the brand is never absent and never doubled.

   Driven by --il-p (0→1 over the first 220px, set on <html> by the scroll
   handler) rather than by a class toggle: a continuous value makes the
   handover track the scroll instead of snapping at a threshold. */
.il-herologo{
  transform-origin:left top;
  scale:calc(1 - .52 * var(--il-p,0));
  opacity:calc(1 - 1.35 * var(--il-p,0));
  translate:0 calc(-28px * var(--il-p,0));
  /* Once faded it must not keep reserving its full height. */
  margin-bottom:calc(var(--space-5) - 78px * var(--il-p,0));
}
.il-header .il-logo{
  opacity:var(--il-p,0);
  scale:calc(.72 + .28 * var(--il-p,0));
  transform-origin:left center;
  /* Non-interactive while invisible, so it cannot swallow clicks aimed at the
     hero lockup underneath it. */
  pointer-events:calc(var(--il-p,0));
}
.il-header .il-logo{pointer-events:auto}
html[data-top="1"] .il-header .il-logo{pointer-events:none}
@media (prefers-reduced-motion:reduce){
  .il-herologo,.il-header .il-logo{transition:none}
}

/* Evening sky in the hero — the game's own MenuView.css `.menu-sky` and
   `.star-dot`, values unchanged: 26% of the zone's height, masked out towards
   the bottom, 3.2s twinkle. Outside the motion query on purpose: with reduced
   motion the stars stay lit rather than disappearing. */
.il-sky{position:absolute;top:0;left:0;right:0;height:44%;overflow:hidden;
  background:linear-gradient(180deg,rgba(8,6,24,.72) 0%,rgba(8,6,24,.30) 52%,transparent 92%);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 58%,transparent 97%);
  mask-image:linear-gradient(180deg,#000 0%,#000 58%,transparent 97%)}
.il-star{position:absolute;border-radius:50%;background:#fff;box-shadow:0 0 5px rgba(255,255,255,.8);opacity:.6}
@media (prefers-reduced-motion:no-preference){
  .il-star{animation:ilTwinkle 3.2s ease-in-out infinite}
  @keyframes ilTwinkle{0%,100%{opacity:.22}50%{opacity:1}}
}

/* Anchor targets clear the sticky bar. Without this every nav link lands with
   the section's heading tucked underneath it. */
section[id]{scroll-margin-top:96px}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
/* The burger replaces the inline nav at exactly the width the nav is hidden. */
.il-burger{display:none !important}
@media (max-width:820px){
  .il-burger{display:flex !important}
  .il-drawer{display:grid !important}
}
@media (max-width:620px){
  /* Measured, not guessed: at 430px the logo + language pill + buy button +
     burger overflow the bar, and the burger ends up off-screen behind the buy
     button — the menu becomes unreachable exactly where it matters most. The
     buy action is repeated in the hero and the footer; the menu is not. */
  .il-buy{display:none !important}
  .il-logo img,.il-logo svg{max-width:132px !important;height:auto !important}
}

/* ── Kolme askelta: kortin kaannos, viuhkan avautuminen ja kukistuksen tahdet ──
   Ajoitukset ovat pelin omia (packages/app/src/ui.css): `villainReveal` kaantaa
   pahiskortin perspektiivissa pienella yliheilahduksella, `starPop` on
   voittoruudun tahtien ilmestyminen. Sivu kertoo saman tarinan samalla
   liikkeella kuin peli. */
.il-flip{position:relative;perspective:1200px}
.il-flip__inner{position:relative;width:100%;height:100%;transform-style:preserve-3d;
  transform:rotateY(180deg) scale(.94);
  transition:transform .95s cubic-bezier(.2,.75,.25,1.05)}
.il-flip.is-flipped .il-flip__inner{transform:rotateY(0deg) scale(1)}
.il-flip__side{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  display:grid;place-items:center}
.il-flip__front{transform:rotateY(0deg)}
.il-flip__back{transform:rotateY(180deg)}

/* Viuhka: kortit ovat aluksi keskimmaisen takana pinossa (--dx) ja liukuvat
   omille paikoilleen. `translate` erillisena ominaisuutena, koska korteilla on
   inline `transform` (nosto ja kallistus) jota ei saa ylikirjoittaa. */
.il-fan__card{translate:var(--dx,0) 0;opacity:.35;
  transition:translate .7s cubic-bezier(.2,.75,.25,1.05),opacity .5s ease}
.il-fan.is-open .il-fan__card{translate:0 0;opacity:1}
.il-fan__card:nth-child(1){transition-delay:.06s}
.il-fan__card:nth-child(3){transition-delay:.12s}

/* Kukistuksen tahdet kortin paalle. */
.il-burst{position:absolute;inset:0;display:flex;align-items:flex-start;justify-content:center;
  gap:14px;padding-top:8%;pointer-events:none;z-index:6}
.il-burst__star{font-size:2.4rem;color:var(--gold);opacity:0;
  text-shadow:0 2px 0 rgba(0,0,0,.35),0 0 18px rgba(244,185,66,.75)}
.il-burst.is-on .il-burst__star{animation:ilStarPop .55s cubic-bezier(.2,.9,.3,1.6) both;animation-delay:var(--d)}
@keyframes ilStarPop{
  0%{transform:scale(0) rotate(-45deg);opacity:0}
  70%{transform:scale(1.35) rotate(10deg);opacity:1}
  100%{transform:scale(1) rotate(0);opacity:1}
}
@media (prefers-reduced-motion:reduce){
  .il-flip__inner{transform:none !important;transition:none}
  .il-flip__back{display:none}
  .il-fan__card{translate:0 0 !important;opacity:1 !important;transition:none}
  .il-burst{display:none}
}

/* ── Supervoimataulun ikonien kaanto ────────────────────────────────────────
   Ikonit ovat aluksi karahtaneet: vihrea kiekko ja pelin oma valkoinen
   supervoimatahti (assets/icons/supervoima.png). Kun taulu tulee nakyviin, ne
   kaantyvat jarjestyksessa vasemmalta oikealle — sama liike ja sama merkki
   kuin kortin Voimat-rivilla. Vihrea on --card-food, ruokakortin oma vari. */
.il-tagflip{position:relative;display:block;perspective:800px}
.il-tagflip__face{position:absolute;inset:0;display:grid;place-items:center;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;border-radius:999px}
.il-tagflip__front{transform:rotateY(180deg)}
.il-tagflip__back{transform:rotateY(0deg);background:var(--card-food);
  box-shadow:inset 0 0 0 2px rgba(255,255,255,.35)}
.il-tagflip__back img{width:60%;height:60%;object-fit:contain;display:block}
/* Kaanto tapahtuu kaarella, ei koko elementille kerralla: face-parit pyorivat
   yhdessa kun asetamme kierron itse kehykselle. */
/* Hitaampi ja selvemmin porrastettu: .7s/.09s oli niin nopea etta kahdeksan
   ikonia kaantyi kaytannossa yhtena valahdyksena eika sarjana. Nyt yksittainen
   kaanto kestaa 1,1 s ja porras on .22 s, jolloin viimeinen lahtee noin 1,5 s
   ensimmaisen jalkeen ja liike ehtii nakya. */
.il-tagflip{transform-style:preserve-3d;transition:transform 1.1s cubic-bezier(.22,.7,.28,1.02);
  transition-delay:calc(var(--i,0) * .22s)}
.il-tagflip.is-on{transform:rotateY(180deg)}
@media (prefers-reduced-motion:reduce){
  .il-tagflip{transform:rotateY(180deg) !important;transition:none}
}


/* Alasivuilla (tietosuoja, opettajille) valikkologo on AINA nakyvissa: siella
   ei ole hero-lockupia jolle luovuttaa, joten --il-p:n ohjaama haivytys jattaisi
   sivun kokonaan ilman logoa ja ilman paluulinkkia etusivulle. */
html[data-sub="1"] .il-header .il-logo{opacity:1 !important;scale:1 !important;pointer-events:auto !important}


/* Pitkat yhdyssanat kaikissa otsikoissa. Saksa ja suomi tuottavat sanoja jotka
   eivat katkea itsestaan (GESUNDHEITSSCHURKEN, VARHAISKASVATUS), ja ilman tata
   ne valuvat palstansa ulkopuolelle — kuvituksen alle tai ulos kortista.
   `hyphens:auto` toimii, koska i18n.js asettaa <html lang>:n valitun kielen
   mukaan; ilman oikeaa kielimaaritysta selain ei osaa tavuttaa. */
/* hyphens ENSIN, break-word vasta viimeisena keinona: break-word yksin
   katkaisee sanan mielivaltaisesta kohdasta ilman tavuviivaa
   (GESUNDHEITSSC / HURKEN), kun taas tavutus katkaisee oikeasta kohdasta ja
   merkitsee sen. Toimii koska i18n.js asettaa <html lang>:n. */
h1, h2, h3 { hyphens: auto; }
h2, h3 { overflow-wrap: break-word; }


/* Tietosuojasivun sisallysluettelo (PrivacyPage). Kahdessa sarakkeessa
   `position:sticky` on oikein: luettelo seuraa mukana kun selostetta
   vierittaa. Yhdessa sarakkeessa se on vaarin, ja syy on sticky-elementin
   rajauksessa — selain rajaa sen RUUDUKKOSAILIOON, ei sen omaan soluun,
   joten luettelo irtoaa omasta lohkostaan ja jaa leijumaan koko selosteen
   ajan. Mitattu 390 px: sivupalkki jumittuu kohtaan top 104 px ja artikkeli
   liukuu sen ALTA (top -15 px, -639 px) — teksti kulkee luettelon takaa.
   Kapealla luettelo jaa siis paikalleen sisallon ylapuolelle, omaan
   lohkoonsa ensimmaiseksi, ja vierii pois normaalisti. */
@media (max-width:900px){
  .il-doc-side{position:static !important}
}
