/* NOX Visual v3 — tarkoitukselliset tuotantopoikkeamat prototyypistä (ADR 0010 §2).
   Käsin kirjoitettu ja jo skoopattu. Jokaisella säännöllä on perustelu. Ladataan generoitujen
   tiedostojen jälkeen (scripts/nv3/port-css.mjs kopioi tämän hashatulla nimellä). */

/* JS-portti. Prototyypissä [data-reveal] on ehdottomasti piilossa ja moottori paljastaa sen.
   Jos JS ei lataudu, sivu jäisi tyhjäksi (vikaluokka: staging-seinä 1.7.–5.9.). Piilotus on
   voimassa vain html.nv-motion-luokan kanssa: boot-skripti asettaa sen ennen maalausta ja
   poistaa sen failsafella, jos moottori ei ilmoita valmistumisesta. */
html.theme-nox-visual-v3:not(.nv-motion) [data-reveal] { opacity: 1; transform: none; }

/* Latautuessa from-animoidut elementit (sanapaljastus, H1-rivit, herokuva) pysyvät näkymättöminä,
   kunnes moottori on asettanut lähtötilan (html.nv-ready). Prototyypissä moduuliskripti ajetaan
   ennen ensimmäistä maalausta, tuotannossa hydraation jälkeen; ilman tätä teksti välähtäisi
   valmiina ennen animaatiota. visibility (ei opacity/transform), jotta GSAP:n from lukee
   oikean lopputilan. */
html.theme-nox-visual-v3.nv-motion:not(.nv-ready) :is([data-split], .p-h1, .p-hero-photo, .p-wire) {
  visibility: hidden;
}

/* Tailwindin .container-utility antaa max-widthin breakpointeittain; prototyypin .container ei
   rajaa leveyttä (width: min(1440px, 100%)). Ainoa prototyypin luokka, joka törmää utilityyn
   (kartoitettu 2.10.: container, sr-only — jälkimmäinen on samaa tarkoitusta). */
html.theme-nox-visual-v3 .container { max-width: none; }

/* Prototyyppi on rakennettu selaimen oletustyylien päälle; alusta lataa Tailwindin preflightin
   (@layer base), joka nollaa marginaalit, välit ja rivikorkeuden (html: 1.5 vs. normal). Ero
   kertyi lomakkeessa ~3 px per fieldset. Kehyksen sisällä palautetaan selaimen oletukset:
   nollaspesifisyys häviää jokaiselle prototyypin säännölle, mutta kerrostamattomana voittaa
   preflightin. Alustan Tailwind-komponentit (chat, evästebanneri) ovat kehyksen ulkopuolella.
   Palautus on kohdennettu tageittain preflightin (node_modules/tailwindcss/preflight.css) mukaan,
   ei universaalina `all: revert` -sääntönä: universaali sääntö osui jokaiseen elementtiin kahdella
   esivanhempikävelyllä jokaisessa tyylilaskennassa (0,8 s / 16 s vieritystä, nykimisen osasyy,
   TICKETS 3.10.). box-sizing ei kuulu listaan: prototyyppi asettaa itse `* { box-sizing: border-box }`,
   mutta ei pseudoelementeille → niille palautetaan preflightin border-box (11 pseudoa mitoittaa
   reunat leveyden sisään). */
:where(html.theme-nox-visual-v3),
:where(html.theme-nox-visual-v3 body),
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat, .cursor-label, #bg-gl)) {
  all: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(h1, h2, h3, h4, h5, h6) {
  margin: revert; padding: revert; border: revert; font-size: revert; font-weight: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat))
  :where(p, blockquote, figure, dl, dd, ol, ul, menu, pre, fieldset, legend, dialog, address, table, caption, th, td) {
  margin: revert; padding: revert; border: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(hr) {
  margin: revert; padding: revert; border: revert; height: revert; color: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(ol, ul, menu) { list-style: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(a) { color: revert; text-decoration: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(b, strong) { font-weight: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(code, kbd, samp, pre) {
  font-family: revert; font-size: revert; font-feature-settings: revert; font-variation-settings: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(small) { font-size: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(sub, sup) {
  font-size: revert; line-height: revert; position: revert; vertical-align: revert; top: revert; bottom: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(abbr[title]) { text-decoration: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(table) {
  text-indent: revert; border-color: revert; border-collapse: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(progress) { vertical-align: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(summary) { display: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(button, input, select, optgroup, textarea) {
  margin: revert; padding: revert; border: revert; font: revert; font-feature-settings: revert; font-variation-settings: revert;
  letter-spacing: revert; color: revert; border-radius: revert; background-color: revert; opacity: revert; appearance: revert;
}
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(textarea) { resize: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat)) :where(input, textarea)::placeholder { opacity: revert; color: revert; }
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat) *)::before,
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat) *)::after { box-sizing: revert; }
/* Mediat (img, video, canvas, iframe) eivät ole listalla: revert hävittäisi myös width/height-attribuuttien
   esitysvihjeet, jolloin kuvalla ei ole kuvasuhdetta ennen latausta → laiska kuva jäi 0 px korkeaksi eikä
   koskaan latautunut (työnäytteiden palstoitus 2.10.). Prototyyppi nollaa kuvat itse samoin kuin preflight
   (style.css: img, video { display: block; max-width: 100% }), joten preflight saa jäädä. */
/* SVG: SVG2:ssa d, cx, cy, r, x, y ym. ovat CSS-ominaisuuksia, joten all-palautus nollaisi
   esitysattribuutit (karttapolun d tyhjeni 2.10.). Preflight koskee SVG:stä vain näitä. */
:where(html.theme-nox-visual-v3 :is(main, .nav, .menu, .footer, .nv-home, .chat) svg) {
  display: revert;
  vertical-align: revert;
}

/* Alustan Tailwind-komponentit (evästebanneri, chat-nappi, latausindikaattori) lukevat brändivärit
   teematokeneista. Ilman näitä ne putosivat oletusteemaan (vihreä banneri, havaittu 2.10.).
   Samat arvot kuin v2:n .theme-nox-visual (sama paletti, Nordic Light), kunnes chat ja
   evästeasetukset siirretään prototyypistä. */
html.theme-nox-visual-v3 {
  --brand-bg: #f5f5f3;
  --brand-surface: #ffffff;
  --brand-surface-raised: #edeeea;
  --brand-border: #e2e4df;
  --brand-text: #0e2038;
  --brand-text-muted: #4e5d6e;
  --brand-accent: #0a1b31;
  --brand-accent-dim: #14294a;
  --brand-accent-contrast: #ffffff;
  --brand-radius: 14px;
  --cc-panel: #0a1b31;
  --cc-text: #ffffff;
  --cc-text-muted: rgb(255 255 255 / 70%);
  --cc-accent: #9dbfe8;
  --cc-accent-contrast: #0a1b31;
  --cc-border: rgb(255 255 255 / 14%);
  --cc-radius: 14px;
}

/* CMS-kovennus: lukittu otsikkorivi on nowrap. Ilman tätä leveä rivi venyttää grid-palstan
   (min-width: auto = min-content) ja koko heropalsta leikkautuu ruudun yli (havaittu 2.10.:
   "Ilman aloitusmaksua." 390 px:llä). Palsta pysyy suunnitellun levyisenä, ja runtime
   (fitHeadings) pienentää ylittävän rivin fonttia. Hyväksytyillä otsikoilla ei muutosta. */
html.theme-nox-visual-v3 .p-hero-copy { min-width: 0; }

/* Etusivun kerrokset (intro, 3D-canvasit, reunavalo, etenemä) renderöi kehys kaikille sivuille,
   koska layout ei tunne sivua. Ne näkyvät vain etusivulla (boot asettaa body[data-page] ennen
   kerroksia); display: contents → kerrokset käyttäytyvät kuin prototyypin bodyn lapset. */
html.theme-nox-visual-v3 .nv-home { display: none; }
html.theme-nox-visual-v3 body[data-page='home'] .nv-home { display: contents; }

/* Etusivun intro (navy-peite) näkyy heti CSS:llä ja moottori piirtää sen. Jos intro on jo nähty
   tässä istunnossa (moottori ohittaa sen) tai moottori ei käynnisty (varmistus poisti nv-motionin),
   peite ei saa jäädä ruudulle. */
html.theme-nox-visual-v3.nv-intro-skip #intro,
html.theme-nox-visual-v3:not(.nv-motion) #intro { display: none; }

/* Heron latausanimaatio: kun intro näytetään, otsikko piirretään intron peitteen alle (LCP
   kirjautuu heti). Ilman introa (jo nähty) from-animoidut osat odottavat moottoria kuten alasivuilla. */
html.theme-nox-visual-v3.nv-motion.nv-intro-skip:not(.nv-ready) :is(.hero-title, .hero-lead, .hero-ctas, .progress, body[data-page='home'] .nav) {
  visibility: hidden;
}

/* Prototyyppi varaa piilotetulle elementille tilan (`[hidden] { display: inline-block; visibility:
   hidden }`), mutta Tailwindin preflight pakottaa `[hidden]` → `display: none !important` @layer
   basessa, ja kerroksellinen !important voittaa kerroksettoman. Sama kerros + korkeampi spesifisyys.
   Home Heroesin "Lukitse holvi uudelleen" (holvi-osio oli 59 px matalampi, havaittu 3.10.). */
@layer base {
  html.theme-nox-visual-v3 .hh-relock[hidden] { display: inline-block !important; }
}

/* The standalone root has no Tailwind preflight. Its remaining consumers already use
   prototype classes (including sr-only and the native Turnstile wrapper). The prototype
   references no .js class or next/font variables. Keep the consent boot's pre-paint gate
   local, and protect hidden controls from author display rules without a global reset. */
html.theme-nox-visual-v3.nv3-entry[data-cc='ok'] .cc[data-cc-banner] { display: none; }
html.theme-nox-visual-v3.nv3-entry .cc [hidden] { display: none; }

/* A compact v3 404: the same heading, body and link vocabulary as page.css. */
html.theme-nox-visual-v3 .nv-not-found { min-height: 65vh; }
html.theme-nox-visual-v3 .nv-not-found .p-h1 { margin: 24px 0; }
html.theme-nox-visual-v3 .nv-not-found-links { display: flex; flex-wrap: wrap; align-items: center; gap: 24px; margin-top: 32px; }

/* NvImg emits intrinsic width/height attributes. The old entry's preflight supplied
   height:auto plus block/middle media defaults; preserve precisely these in the new
   entry so a responsive image does not retain its original pixel height. Zero specificity
   lets every prototype size/position rule win, just as it did over @layer base. SVG stays
   excluded: its presentation attributes are intentionally preserved above. */
:where(html.theme-nox-visual-v3.nv3-entry) :where(img, video) { height: auto; }
:where(html.theme-nox-visual-v3.nv3-entry) :where(img, video, canvas, audio, iframe, embed, object) {
  display: block; vertical-align: middle;
}

/* v3 chat: real bot links and inline lead form, absent from the canned prototype.
   Keep the approved card geometry; only harden dynamic content and focus states. */
html.theme-nox-visual-v3 .chat .chat-log { min-height: 0; overscroll-behavior: contain; }
html.theme-nox-visual-v3 .chat .msg { white-space: pre-line; overflow-wrap: anywhere; }
html.theme-nox-visual-v3 .chat .chat-links { display: flex; flex-wrap: wrap; gap: 8px; }
html.theme-nox-visual-v3 .chat .chip { height: auto; min-height: 36px; padding-block: 8px; }
html.theme-nox-visual-v3 .chat .chip-link { display: inline-flex; align-items: center; text-decoration: none; color: var(--navy); }
html.theme-nox-visual-v3 .chat :is(button, a, input, textarea):focus-visible { outline: 2px solid var(--blue-300); outline-offset: 3px; }
html.theme-nox-visual-v3 .chat :is(button, input):disabled { cursor: default; opacity: 0.5; }
html.theme-nox-visual-v3 .chat .chat-lead { display: grid; gap: 10px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
html.theme-nox-visual-v3 .chat .chat-lead-field { display: grid; gap: 4px; color: var(--ink); font-size: 14px; }
html.theme-nox-visual-v3 .chat .chat-lead :is(input, textarea) { box-sizing: border-box; width: 100%; min-width: 0; min-height: 40px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); color: var(--navy); font: 400 16px 'General Sans', sans-serif; transition: border-color 0.25s var(--ease-out); }
html.theme-nox-visual-v3 .chat .chat-lead textarea { min-height: 80px; resize: vertical; }
html.theme-nox-visual-v3 .chat .chat-lead-note { font-size: 12px; line-height: 1.5; color: var(--ink-2); }
@media (prefers-reduced-motion: reduce) {
  html.theme-nox-visual-v3 .chat *, html.theme-nox-visual-v3 .chat *::before, html.theme-nox-visual-v3 .chat *::after { animation: none !important; transition: none !important; }
}

/* Chat (NvChat) ilman asettelusiirtymiä (Lighthouse CLS 4.10.): ensimmäinen näkyvä tila asettuu ilman
   avatarin koko-transitiota, ja kirjoitettava viesti varaa lopullisen tilansa näkymättömällä loppuosalla. */
html.theme-nox-visual-v3 .chat:not([data-settled]) .chat-avatar { transition: none; }
html.theme-nox-visual-v3 .chat .msg-rest { visibility: hidden; }
html.theme-nox-visual-v3 .chat .msg-pending { position: relative; }
html.theme-nox-visual-v3 .chat .msg-pending > .typing { position: absolute; left: 0; top: 0; }
