/* ═══════════════════════════════════════════════════════════════════════
   NORDEVO · loppu. The footer, the same on every page (2026-09-15, round 2
   on 2026-09-16 after Anton's notes).
   Built from Anton's wireframe "footer-final" (README-footer-concepts,
   set 2): the page is a slab lying on the footer and scrolling lifts it
   away; the footer arrives dark; one ticker knows the scroll's speed;
   the cursor is a dot that inverts what it covers, the big line leans
   toward it, links roll to their italic twin, the kohde links carry a
   print; the pill unfolds into the panel you write on. The wireframe's
   inversion trick (a difference layer, "no dark theme exists") is staged
   with the site's own dark room instead, because the negative of warm
   paper is cool blue, the negative of mint is purple and the negative of
   the gold seal is blue: the footer paints the passage ground, cream type,
   mint accent, and the lift edge is the paper page's own bottom.

   Mechanism: <footer class="loppu"> is a plain wrapper and one stacking
   context (z-index 5, under the nav's 90). Inside it .laatikko is the
   100vh box with clip-path:inset(0) and .laatta the sheet, position:fixed
   to the viewport bottom: the clip shows exactly the part of the fixed
   sheet that lies inside the box, so as the box scrolls up from the floor
   the sheet is revealed under the page's edge. No z-index on the page, no
   backgrounds elsewhere. The panel, the cursor dot and the print live
   OUTSIDE the clipped box (fixed to the viewport, still inside the
   footer), so the panel can grow from the pill to the top of the window
   while the footer is only half revealed (Anton 2026-09-16).
   Under 861px, short windows, no-JS and the print freezes (.kiinni) the
   sheet is static. Loaded after nordevo.css on every page; script /loppu.js.
   ═══════════════════════════════════════════════════════════════════════ */

footer.loppu { --lmaa:#0b0906; --lmuste:var(--cream); --lhimmea:rgba(242,236,221,.56);
  --lhiuksen:rgba(242,236,221,.22);
  position:relative; z-index:5; isolation:isolate; color:var(--lmuste); }
.laatikko { position:relative; height:100vh; clip-path:inset(0); background:var(--lmaa); }
.laatta { position:fixed; left:0; right:0; bottom:0; height:100vh; background:var(--lmaa); }
.laatta, .lpaneeli { cursor:none; }
.loppu.kiinni .laatikko, .no-js .laatikko { height:auto; clip-path:none; }
.loppu.kiinni .laatta, .no-js .laatta { position:relative; height:auto; cursor:auto; }
/* the billing lines, opened, can outgrow a window-sized sheet (loppu.js adds .venyy when
   they do): the sheet then lies in the page and grows, never shorter than the window */
.loppu.venyy .laatikko { height:auto; clip-path:none; }
.loppu.venyy .laatta { position:relative; height:auto; min-height:100vh; }
.loppu.venyy .lsis { min-height:100vh; }
.loppu input, .loppu textarea { cursor:text; }

/* the sheet: five rows in the window, the ticker floating in the air
   between the call and the columns. The top row sits well under the nav. */
/* the ticker's row takes the air that is left but never less than the ticker itself: the
   strip clips its overflow, so a bare 1fr let the row collapse to nothing under a tall
   column and the ticker ran over the call above it and the mark below */
.lsis { height:100%; display:grid; grid-template-rows:auto auto minmax(min-content,1fr) auto auto;
  padding:15vh 12vw 5vh; }

/* ── the big line: the tagline, one line on the full measure. The
   letters are wrapped by the script and lean toward the cursor. ── */
.lotsikko { margin:0; font-family:var(--disp); font-weight:500; letter-spacing:-.03em;
  font-size:clamp(44px,9vw,152px); line-height:.95; white-space:nowrap; }
.lotsikko .lk { position:relative; display:inline-block; }
.lotsikko .lc { display:inline-block; transform-origin:50% 100%; will-change:transform; }

/* the call: the pill under the line's start, the sentence hanging right */
.lkutsu { display:flex; justify-content:space-between; align-items:baseline; gap:4vw;
  margin-top:3.6vh; }
.lkutsu .llede { margin:0; font-family:"Newsreader",Georgia,serif; font-weight:400;
  font-size:clamp(17px,1.45vw,22px); line-height:1.5; color:var(--lhimmea);
  text-align:right; max-width:34ch; }
.lkutsu .nappi { --nacc:var(--sun); color:var(--lmuste); flex:none; }
.lkutsu .nappi:hover, .lkutsu .nappi:focus-visible { color:var(--ink); }

/* ── the ticker: kohteet drifting across the full width, faster and
   leaning while the page scrolls, settling to a slow drift. Two copies
   of the list make the loop seamless. ── */
.nauha { align-self:center; overflow:hidden; margin:0 -12vw; padding:1.6vh 0; }
.nrata { display:flex; width:max-content; will-change:transform; }
.nlista { display:flex; list-style:none; margin:0; padding:0; }
.nkohde { display:inline-flex; align-items:baseline; gap:.55em; padding:0 2.6vw 0 0;
  font-family:var(--disp); font-weight:500; font-size:clamp(26px,3.4vw,58px);
  letter-spacing:-.025em; line-height:1.15; color:var(--lmuste); text-decoration:none;
  white-space:nowrap; }
/* the brand period as the separator between kohteet: a flex item with no
   baseline of its own sits on the text baseline, like the wordmark's dot
   and the button's (.npiste) */
.nkohde::before { content:""; flex:none; width:.2em; height:.2em; border-radius:50%;
  background:var(--sun); margin-right:2.6vw; }
.nkohde .npaikka { font-family:var(--sans); font-weight:500; font-size:.29em; letter-spacing:.16em;
  text-transform:uppercase; color:var(--lhimmea); transition:color .4s ease; }
.nkohde:hover .npaikka, .nkohde:focus-visible .npaikka { color:var(--sun); }

/* ── the columns: the mark as the signature, then the route, the group
   and the house ── */
.lsarakkeet { display:grid; grid-template-columns:1.4fr .8fr 1.35fr 1fr; gap:4vh 3vw;
  align-items:start; margin-top:2vh; }
.lmerkki { color:var(--lmuste); --dot:var(--sun); width:min(27vw,350px); padding-top:.2vh; }
.lmerkki svg { display:block; width:100%; height:auto; overflow:visible; }
.lkick { margin:0 0 1.7vh; font-family:var(--sans); font-weight:500; font-size:10.5px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--lhimmea); }
.lsarake ul { list-style:none; margin:0; padding:0; }
.lsarake li { line-height:1.6; }
.losoite { font-style:normal; font-family:var(--disp); font-weight:400;
  font-size:clamp(15px,1.15vw,18px); line-height:1.6; color:var(--lmuste); }
.lsarake .lrivit { margin-top:1.4vh; }
/* the group column carries the billing lines under each company, folded
   until the Laskutustiedot word opens them (Anton 2026-09-16: under the
   names, but openable, less space). Height animates through grid rows. */
.lyhtiot li { margin-bottom:.3vh; }
.ltunnus { display:grid; grid-template-rows:0fr; margin-top:0; font-family:var(--sans);
  font-size:clamp(11px,.84vw,13px); letter-spacing:.04em; line-height:1.55; color:var(--lhimmea);
  font-variant-numeric:tabular-nums; transition:grid-template-rows .6s cubic-bezier(.22,1,.36,1),
  margin-top .6s cubic-bezier(.22,1,.36,1), opacity .5s ease; opacity:0; }
.ltunnus > span { display:block; overflow:hidden; min-height:0; }
.ltunnus[hidden] { display:grid; }
.lsarake.auki .ltunnus { grid-template-rows:1fr; opacity:1; margin-top:3px; }
.lsarake.auki li .ltunnus { margin-bottom:1.1vh; }
.lavaa { margin-top:1.6vh; color:var(--lhimmea); }
.lsarake.auki .lavaa { color:var(--lmuste); }
.lvalittaja { max-width:30ch; }
.lsarake.auki .lvalittaja { margin-top:.6vh; }
.no-js .ltunnus { grid-template-rows:1fr; opacity:1; margin-top:3px; }
.no-js .lavaa { display:none; }

/* rolling links: the word and its italic twin in one clipped box, the
   letters stepping up one after another on hover */
.rulla { display:inline-block; position:relative; overflow:hidden; vertical-align:top;
  font-family:var(--disp); font-weight:400; font-size:clamp(15px,1.15vw,18px); line-height:1.35;
  color:var(--lmuste); text-decoration:none; background:none; border:0; padding:0; margin:0;
  cursor:inherit; text-align:left; }
.rulla .rt { display:block; white-space:nowrap; }
.rulla .rt2 { position:absolute; left:0; top:100%; font-style:italic; }
.rulla .lc { display:inline-block; will-change:transform; }
@media (hover:hover) and (prefers-reduced-motion:no-preference) {
  .rulla .lc { transition:transform .5s cubic-bezier(.22,1,.36,1); transition-delay:calc(var(--i, 0) * 16ms); }
  .rulla:hover .lc, .rulla:focus-visible .lc { transform:translateY(-100%); }
}
.rulla:focus-visible { outline:2px solid var(--sun); outline-offset:3px; }
.lpaneeli .rulla { color:var(--ink); }

/* ── the floor: the seal on the left, the legal line right ── */
.lpohja { display:flex; justify-content:space-between; align-items:flex-end; gap:4vw;
  margin-top:4vh; }
.lserti { display:block; width:clamp(176px,15vw,240px); height:auto; }
.loikeus { margin:0; font-family:var(--sans); font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--lhimmea); line-height:1.8; text-align:right; }
.loikeus a { color:inherit; text-decoration:none;
  background:linear-gradient(90deg,var(--sun),var(--sun)) no-repeat 0 100%/0 1px;
  transition:color .4s ease, background-size .5s cubic-bezier(.22,1,.36,1); }
.loikeus a:hover, .loikeus a:focus-visible { color:var(--lmuste); background-size:100% 1px; }

/* ── the panel: paper unfolding out of the pill (or the billing link)
   over the whole window. The script sets the clip to the trigger's
   rectangle and lets it open; the light arrives in the dark room. ── */
.lpaneeli { --lylareuna:max(11vh,104px);      /* clears the fixed nav bar */
  position:fixed; inset:0; z-index:5; background:transparent; color:var(--ink);
  padding:var(--lylareuna) 12vw 5vh; overflow:auto; }
.lpaneeli.valmis { background:var(--paper); }
/* the paper: a circle laid over the trigger's centre, sized to cover the
   whole window, scaled down to the pill's height at the start and let
   grow. A transform, so the compositor does it and the edge stays smooth
   (the clip-path version repainted the sheet every frame; Anton: "should
   be smooth", 2026-09-16). */
.lpaperi { position:absolute; left:0; top:0; border-radius:50%; background:var(--paper);
  transform-origin:50% 50%; will-change:transform; pointer-events:none;
  transition:transform 1.15s cubic-bezier(.5,0,.15,1); }
.lpaneeli.valmis .lpaperi { display:none; }
.lpaneeli[hidden] { display:none; }
.lsulje { position:absolute; top:var(--lylareuna); right:12vw; font-family:var(--sans); font-size:11.5px;
  letter-spacing:.18em; text-transform:uppercase; color:var(--faded); background:none; border:0;
  padding:6px 0; cursor:inherit;
  background:linear-gradient(90deg,var(--sun),var(--sun)) no-repeat 0 100%/0 1px;
  transition:color .4s ease, background-size .5s cubic-bezier(.22,1,.36,1); }
.lsulje:hover, .lsulje:focus-visible { color:var(--ink); background-size:100% 1px; outline:none; }
.lnakyma { display:none; grid-template-columns:1fr 1.25fr; gap:5vh 6vw; align-items:start;
  opacity:0; transform:translateY(12px);
  transition:opacity .7s cubic-bezier(.22,1,.36,1) .55s, transform .7s cubic-bezier(.22,1,.36,1) .55s; }
.lpaneeli.sulkeutuu .lnakyma.esilla { opacity:0; transform:translateY(12px); transition-delay:0s; transition-duration:.3s; }
.lnakyma.esilla { display:grid; }
.lpaneeli.auki .lnakyma.esilla { opacity:1; transform:none; }
.lnakyma .kick { color:var(--muted); }
.lnakyma h3 { margin-top:2.4vh; font-family:var(--disp); font-weight:500; letter-spacing:-.025em;
  font-size:clamp(28px,3.2vw,48px); line-height:1.1; max-width:14ch; }
.lnakyma .lselite { margin-top:2.6vh; font-family:"Newsreader",Georgia,serif;
  font-size:clamp(15.5px,1.3vw,18px); line-height:1.7; color:var(--faded); max-width:38ch; }
.lnakyma .lselite a { color:var(--ink); text-decoration:none;
  background:linear-gradient(90deg,var(--sun),var(--sun)) no-repeat 0 100%/100% 1px; }

/* the writing lines: a small caps label and a line on the paper, the sun
   rule drawing along it on focus (Ota yhteyttä's grammar) */
.llomake { padding-top:1vh; }
.lkentta { display:grid; grid-template-columns:clamp(110px,10vw,160px) minmax(0,1fr);
  gap:0 2vw; align-items:baseline; padding:1.9vh 0; }
.lkentta .kl { font-family:var(--sans); font-size:10.5px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--muted); transition:color .35s ease; }
.lkentta:focus-within .kl { color:var(--ink); }
.lkentta input, .lkentta textarea { width:100%; border:0; border-radius:0; background:none;
  font-family:"Newsreader",Georgia,serif; font-size:clamp(17px,1.4vw,21px); line-height:1.5;
  color:var(--ink); padding:2px 0 8px; resize:none;
  background:linear-gradient(90deg,var(--sun),var(--sun)) no-repeat 0 100%/0 1px,
    linear-gradient(90deg,rgba(34,28,18,.28),rgba(34,28,18,.28)) no-repeat 0 100%/100% 1px;
  transition:background-size .55s cubic-bezier(.22,1,.36,1); }
.lkentta input:focus, .lkentta textarea:focus { outline:none;
  background-size:100% 1px, 100% 1px; }
.lkentta textarea { min-height:2.9em; }
.llomake .laheta { margin-top:3.2vh; display:flex; align-items:center; gap:3vw; flex-wrap:wrap; }
.llomake .lhuom, .llomake .lkiitos { margin-top:2vh; font-family:"Newsreader",Georgia,serif;
  font-size:15px; line-height:1.6; color:var(--faded); max-width:44ch; }
.llomake .lfine { margin-top:3vh; font-family:"Newsreader",Georgia,serif; font-size:13.5px;
  line-height:1.65; color:var(--muted); max-width:52ch; }
.llomake .lfine a { color:var(--faded); text-decoration:underline; text-underline-offset:3px;
  text-decoration-thickness:1px; text-decoration-color:var(--sun); }

/* ── the cursor: a cream dot that inverts whatever it covers; the print
   that follows the pointer over a kohde. Both fixed, outside the clip. ── */
.lkursori { position:fixed; left:0; top:0; z-index:30; width:14px; height:14px; border-radius:50%;
  background:var(--cream); mix-blend-mode:difference; pointer-events:none; opacity:0;
  transform:translate(-50%,-50%); transition:opacity .35s ease, width .35s cubic-bezier(.22,1,.36,1),
  height .35s cubic-bezier(.22,1,.36,1); }
.lkursori.nakyy { opacity:1; }
.lkursori.iso { width:44px; height:44px; }
.lesikatselu { position:fixed; left:0; top:0; z-index:20; width:clamp(150px,14vw,230px); margin:0;
  pointer-events:none; opacity:0; transform:translate(-50%,-50%); transition:opacity .4s ease;
  will-change:transform; }
.lesikatselu.nakyy { opacity:1; }
.lesikatselu img { display:block; width:100%; height:auto; }

/* ── stills: no-JS, reduced motion, the print freezes ── */
.no-js .lpaneeli { display:block; position:static; padding:6vh 12vw 0; overflow:visible;
  background:var(--lmaa); color:var(--lmuste); }
.no-js .lpaperi { display:none; }
.no-js .lpaneeli .rulla, .no-js .lnakyma h3, .no-js .lnakyma .lselite a { color:var(--lmuste); }
.no-js .lnakyma .lselite, .no-js .lnakyma .kick { color:var(--lhimmea); }
.no-js .lkentta input, .no-js .lkentta textarea { color:var(--lmuste);
  background:linear-gradient(90deg,var(--lhiuksen),var(--lhiuksen)) no-repeat 0 100%/100% 1px; }
.no-js .lkentta .kl, .no-js .llomake .lfine, .no-js .llomake .lfine a { color:var(--lhimmea); }
.no-js .llomake .nappi { color:var(--lmuste); }
.no-js .lsulje { display:none; }
.no-js .lnakyma { display:grid; opacity:1; transform:none; margin-top:6vh; padding-bottom:6vh; }
.no-js .lkursori, .no-js .lesikatselu, .static .lkursori, .static .lesikatselu { display:none; }
.no-js .nlista + .nlista { display:none; }
@media (prefers-reduced-motion:reduce) {
  .ltunnus, .lpaperi, .lnakyma, .lkursori, .lesikatselu, .lkentta input, .lkentta textarea { transition:none; }
  .nrata { transform:none !important; }
  .lotsikko .lc { transform:none !important; }
}

/* ── short windows and phones: the footer is a page again ── */
@media (max-height:640px) {
  .laatikko { height:auto; clip-path:none; }
  .laatta { position:relative; height:auto; }
  .lsis { height:auto; display:block; padding-bottom:6vh; }
  .nauha { margin-top:5vh; margin-bottom:5vh; }
}
@media (max-width:860px) {
  .laatikko { height:auto; clip-path:none; }
  .laatta { position:relative; height:auto; cursor:auto; }
  .lpaneeli { cursor:auto; }
  .lsis { height:auto; display:block; padding:12vh 7vw 6vh; }
  .lotsikko { font-size:clamp(40px,12.6vw,88px); white-space:normal; }
  .lkutsu { flex-direction:column-reverse; align-items:flex-start; gap:2.6vh; margin-top:3vh; }
  .lkutsu .llede { text-align:left; }
  .nauha { margin:6vh -7vw; padding:1vh 0; }
  .nkohde { font-size:clamp(24px,7vw,40px); padding-right:6vw; }
  .nkohde::before { margin-right:6vw; }
  .lsarakkeet { grid-template-columns:1fr 1fr; gap:5vh 6vw; margin-top:0; }
  .lmerkki { grid-column:1 / -1; width:min(70vw,320px); }
  .lpohja { flex-direction:column; align-items:flex-start; gap:3.5vh; margin-top:7vh; }
  .lserti { width:min(60vw,220px); }
  .loikeus { text-align:left; }
  .lpaneeli { --lylareuna:max(12vh,92px); padding:var(--lylareuna) 7vw 6vh; }
  .lsulje { right:7vw; }
  .lnakyma { grid-template-columns:1fr; gap:4vh 0; }
  .lkentta { grid-template-columns:1fr; gap:8px 0; }
  .lkursori, .lesikatselu { display:none; }
  .no-js .lpaneeli { padding:6vh 7vw 0; }
}
@media (max-width:520px) {
  .lsarakkeet { grid-template-columns:1fr; gap:4.5vh 0; }
}

/* Words remain intact; the individual letters keep their pointer choreography. */
.lotsikko .lword { display:inline-block; white-space:nowrap; }
@media (max-width:520px) {
  .lotsikko { font-size:clamp(38px,12.6vw,66px); line-height:1.04; }
  .lotsikko .lword { display:block; }
  .lotsikko .lspace { display:none; }
}

.lkentta .kl, .lkick { font-size:12px; letter-spacing:.14em; }
.lhuom { color:var(--ink); }
