/*
  Tarjouslohko — hero-hintakortti, sticky-CTA ja tarjousnauha.

  Miksi oma tiedosto: nämä tyylit ovat sivun ainoa kohta joka saa
  tarkoituksella rikkoa muun sivun väri- ja kokohierarkian. Jos ne olisivat
  style.css:ssä muiden korttien seassa, seuraava "yhtenäistetään badget"
  -siivous söisi ne huomaamatta.

  Ladataan style.css:n JÄLKEEN, joten .hero-visual .price-* -säännöt
  ohittavat perustyylit ilman !importantia.

  Mittaus 4.8.2026 ennen muutosta: -50 % -badge oli 12,16 px ja 498 € 40 px
  samassa kortissa — alennusmerkki oli 30 % siitä numerosta jota sen piti
  kehystää, ja samassa vaaleanvihreässä pillerissä kuin sivun kuusi muuta
  badgea. Alennus luki pienpränttinä, ei tarjouksena.
*/

/* -------------------- Hero: hintarivi tekstisarakkeessa -------------------- */

/*
  Hinta luetaan kuvauksen alla, ei omassa kortissaan.

  Kaksi aiempaa versiota latoi hinnan ja kupongin samaan korttiin: ensin
  päällekkäin, sitten kahtena puoliskona vierekkäin. Kumpikin kasvatti kortin
  560x276 pikseliin, jolloin se kilpaili itse laitekuvan kanssa, eikä kahden
  luvun rinnakkaisuus poistunut mihinkään.

  Tekstisarakkeessa hinta on siinä kohdassa jossa kävijä sitä kysyy: heti kun
  hän on lukenut mitä saa. Se ei tarvitse omaa laatikkoa erottuakseen, koska
  ympärillä on leipätekstiä eikä toista lukua.
*/
.hero-hinta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 10px;
  margin: -10px 0 26px;
}

/* Otsikkorivi omalla rivillään hinnan yläpuolella (flex-basis: 100 %).
   Se on se sana joka tekee kortin kupongista löydön eikä yleisalennuksesta:
   vasen puoli on listahinta, kortti rajallinen kuponki. */
.hero-hinta-otsikko {
  flex-basis: 100%;
  margin-bottom: 3px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-2);
}

/* Lunastettuna otsikko on brändinvärinen: se on ainoa kohta vasemmassa
   sarakkeessa joka kertoo että hinta on nyt eri kuin muilla. */
.hero-hinta-otsikko-ale {
  color: var(--brand);
}

.hero-hinta s {
  font-family: "Clash Display", system-ui, sans-serif;
  font-size: 1.15rem;
  font-weight: 500;
  color: var(--text-2);
  text-decoration-thickness: 2px;
  text-decoration-color: rgba(24, 24, 24, 0.4);
}

.hero-hinta-luku {
  font-family: "Clash Display", system-ui, sans-serif;
  font-size: 1.85rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--text);
}

.hero-hinta-alv {
  font-size: 0.9rem;
  color: var(--text-2);
}

/* Oma rivinsä: selite on tarkennus lukuun, ei osa sitä. */
.hero-hinta-selite {
  flex-basis: 100%;
  margin-top: 3px;
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--text-2);
}

/* -------------------- Hero: kuponkikortti -------------------- */

/*
  Kortti kertoo VAIN kampanjan, ei hintaa.

  Pohja on valkoinen. Kaksi aiempaa versiota kokeili ensin tummaa ja sitten
  vaaleaa limensävyä; molemmat tekivät kortista oman värilaatikkonsa, joka
  veti katseen tarjouksesta laatikon reunaan. Valkoinen kortti erottuu
  pehmeällä varjolla eikä värillä, jolloin ainoa värillinen asia kortissa on
  se mistä siinä on kyse: -50 %.

  Erottelu on varjossa ja hiusviivassa, ei täytössä. Sama --shadow-card
  jota sivun muut kortit käyttävät, joten kortti kuuluu samaan perheeseen
  eikä ole poikkeus.

  Leveys on 300 px eikä 560: kortin ainoa tehtävä on kertoa alennus ja
  tarjota lunastus, ja se mahtuu kapeaan pystysuuntaiseen muotoon.
*/
.hero-visual .kuponkikortti {
  position: relative;
  width: min(100%, 300px);
  margin: 0 auto 32px;
  padding: 24px 22px 22px;
  text-align: left;
  background: #fff;
  border: 1px solid rgba(24, 24, 24, 0.06);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.kk-sisus {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.kk-arvo {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-family: "Clash Display", system-ui, sans-serif;
  font-weight: 600;
  font-size: 2.6rem;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--brand);
}

.kk-merkki {
  width: 0.6em;
  height: 0.6em;
  flex-shrink: 0;
}

.kk-nimi {
  margin: 6px 0 0;
  font-size: 0.84rem;
  line-height: 1.35;
  color: var(--text-2);
  text-wrap: pretty;
}

/* Paikkatilanne. Ilman JS:ää tämä on piilossa ja kortissa lukee vain
   -50 %, joten mitään ei jää roikkumaan tyhjänä. */
.kk-maara {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 12px 0 0;
  padding: 7px 12px;
  border-radius: var(--radius-pill);
  /* Pehmeä limensävy ilman reunusta: valkoisella kortilla reunallinen
     pilleri olisi toinen laatikko laatikon sisällä. */
  background: var(--brand-tint);
  color: var(--brand-dark);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1;
}

.kk-maara[hidden] {
  display: none;
}

.kk-piste {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand);
  flex-shrink: 0;
  animation: kk-piste-pulssi 1.8s ease-out infinite;
}

@keyframes kk-piste-pulssi {
  0% { box-shadow: 0 0 0 0 rgba(74, 122, 16, 0.45); }
  100% { box-shadow: 0 0 0 9px rgba(74, 122, 16, 0); }
}

/* Nappiteksti pysyy yhdellä rivillä: kortin sisäleveys on 258 px, ja
   "Lunasta kuponki" vie siitä 150 px. */
.kuponkikortti .btn {
  margin-top: 16px;
  width: 100%;
  padding-inline: 18px;
  white-space: nowrap;
}

.kk-ehto {
  margin: 10px 0 0;
  font-size: 0.73rem;
  line-height: 1.45;
  color: var(--text-2);
  text-wrap: pretty;
}

.kk-lunastettu .kk-ehto strong {
  color: var(--text);
  font-weight: 600;
}

/* Kampanja loppuunmyyty: nappi katoaa (css/kuponki.css), joten lunastusehto
   lupaisi 30 minuuttia toiminnolle jota ei voi tehdä. Tilalle tulee syy. */
.kk-loppu {
  display: none;
}

body.kuponki-loppu .kk-sisus.kuponki-normaali .kk-ehto {
  display: none;
}

body.kuponki-loppu .kk-sisus.kuponki-normaali .kk-loppu {
  display: block;
}

@media (min-width: 860px) {
  .hero-visual .kuponkikortti {
    /* Kortti on kapea, joten se asetetaan laitekuvan oikeaan alakulmaan
       eikä keskelle: keskitettynä se kelluisi irrallaan laitteen alla.

       Nosto on -126px eikä -96px: luottamuslistan poiston jälkeen vasen
       sarake päättyy 828 px:n kohdalle, ja kortti roikkui 63 px sen alle
       venyttäen heroa turhaan. Enempää ei voi nostaa peittämättä
       puhelinmockupin näyttöä — laitekuva itse (563 px) määrää tästä
       eteenpäin heron korkeuden. */
    margin: -126px 0 0 auto;
  }
}

/* Mobiilissa .hero-text on display: contents, joten hintarivi on suora
   grid-item ja tarvitsee oman järjestyslukunsa. Sama luku kuin
   .hero-sub:lla (6), jolloin DOM-järjestys ratkaisee ja hinta jää
   kuvauksen alle. Ilman tätä se saisi oletuksen 0 ja hyppäisi badgen
   yläpuolelle pinon huipulle. */
@media (max-width: 859.98px) {
  /* PAKOLLINEN. Kortti peri aiemmin järjestyslukunsa style.css:n
     .hero-visual .price-card -säännöstä (order: 5). Kun luokka vaihtui
     .kuponkikortiksi, sääntö lakkasi osumasta ja kortti sai oletuksen 0
     eli hyppäsi koko pinon huipulle badgen yläpuolelle. Vika näkyi vain
     mobiilissa, koska työpöydällä pino ei ole käytössä. */
  .hero-visual .kuponkikortti {
    order: 5;
    justify-self: center;
    margin: 0 auto 32px;
  }

  .hero-hinta {
    order: 6;
    justify-self: center;
    justify-content: center;
    text-align: center;
    margin: 0 0 24px;
  }

  .hero-hinta-selite {
    text-align: center;
  }
}

/* -------------------- Kupongin lento koriin -------------------- */

/*
  Lunastus on siirto, ei pelkkä tilanvaihto. Kuponki lentää napista alapalkin
  koriin, ja hinta vaihtuu 498 €:ksi vasta kun se osuu (js/kuponki.js pidättää
  tilan lennon ajan). Ilman lentoa kävijä klikkaa nappia ja sivun toisessa
  reunassa muuttuu luku jota hän ei sillä hetkellä katso — tapahtuma jää
  huomaamatta juuri siltä kävijältä joka sen ansaitsi.

  Alapalkki nostetaan esiin samalla, koska hero on sivun yläreunassa eikä
  palkki ole vielä näkyvissä (js/tarjous.js näyttää sen vasta heron jälkeen).
  Kori jonka näkee vasta myöhemmin ei ole kori.
*/
.kuponki-lento {
  position: fixed;
  z-index: 200;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 14px;
  border-radius: var(--radius-pill);
  background: var(--ink-deep);
  color: var(--lime);
  font-family: "Clash Display", system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 18px 38px -16px rgba(24, 24, 24, 0.7);
  will-change: transform, opacity;
}

.kuponki-lento svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

/* Osuma. Hehku on box-shadowissa eikä transformissa, koska palkin oma
   näyttö/piilotus ajaa transformia (translateY / translate(-50%)). */
.sticky-cta.on-osuma {
  animation: sticky-osuma 700ms ease-out;
}

@keyframes sticky-osuma {
  0% {
    box-shadow: 0 -8px 28px -14px rgba(24, 24, 24, 0.28), 0 0 0 0 rgba(168, 232, 75, 0.6);
  }
  100% {
    box-shadow: 0 -8px 28px -14px rgba(24, 24, 24, 0.28), 0 0 0 18px rgba(168, 232, 75, 0);
  }
}

.sticky-cta.on-osuma .sticky-cta-price {
  animation: sticky-hinta-pomppu 520ms cubic-bezier(0.2, 0.9, 0.3, 1.25);
}

@keyframes sticky-hinta-pomppu {
  0% { transform: scale(1); }
  38% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

@media (min-width: 860px) {
  @keyframes sticky-osuma {
    0% { box-shadow: var(--shadow-card), 0 0 0 0 rgba(168, 232, 75, 0.6); }
    100% { box-shadow: var(--shadow-card), 0 0 0 18px rgba(168, 232, 75, 0); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .sticky-cta.on-osuma,
  .sticky-cta.on-osuma .sticky-cta-price,
  .kk-piste {
    animation: none;
  }
}

/* -------------------- Sticky CTA -------------------- */

/*
  Sivu on pitkä (mittaus 4.8.2026: 23 486 px ennen tiivistystä), joten
  päänappi on poissa ruudulta lähes koko vierityksen ajan. Sticky-palkki
  antaa toiminnon siihen hetkeen jossa päätös syntyy, oli se missä kohtaa
  tahansa. Contentsquaren 58M istunnon aineistossa sticky-CTA tuotti
  mobiilissa +31 % konversiota.

  Näytetään vasta kun hero on ohitettu (js/tarjous.js lisää .is-visible),
  jottei palkki peitä heron omaa nappirivia heti latauksessa.
*/
.sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  backdrop-filter: blur(18px) saturate(180%);
  border-top: 1px solid var(--border);
  box-shadow: 0 -8px 28px -14px rgba(24, 24, 24, 0.28);
  transform: translateY(110%);
  transition: transform 260ms ease;
}

.sticky-cta.is-visible {
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .sticky-cta {
    transition: none;
  }
}

.sticky-cta-text {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.3;
  color: var(--text-2);
}

.sticky-cta-price {
  display: block;
  font-family: "Clash Display", system-ui, sans-serif;
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--text);
}

.sticky-cta-price s {
  font-size: 0.82em;
  font-weight: 500;
  color: var(--text-2);
  margin-right: 5px;
}

/* Lunastettu kuponki jää palkkiin näkyviin: kori jonka sisältö katoaa heti
   ei ole kori. Korvaa "Ilmainen vedos ennen tilausta" -rivin, ei tule sen
   lisäksi — palkissa on tilaa yhdelle riville hinnan alla. */
.sticky-cta-kuponki {
  align-items: center;
  gap: 5px;
  color: var(--brand-dark);
  font-weight: 600;
}

.sticky-cta-kuponki svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}

.sticky-cta .btn {
  flex: 0 0 auto;
  padding: 12px 18px;
  white-space: nowrap;
}

.sticky-cta-phone {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  color: var(--text);
}

.sticky-cta-phone svg {
  width: 20px;
  height: 20px;
}

/* Alle 420 px teksti veisi napilta tilan — jätetään vain hinta ja nappi. */
@media (max-width: 419.98px) {
  .sticky-cta-text {
    display: none;
  }

  .sticky-cta .btn {
    flex: 1 1 auto;
    text-align: center;
  }
}

@media (min-width: 860px) {
  .sticky-cta {
    left: 50%;
    right: auto;
    bottom: 20px;
    transform: translate(-50%, 200%);
    width: min(680px, calc(100vw - 40px));
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    padding: 10px 10px 10px 22px;
    box-shadow: var(--shadow-card);
  }

  .sticky-cta.is-visible {
    transform: translate(-50%, 0);
  }
}
