/* Site 6, "Kokko". Light theme, built to the fable-prompt-6 brief.
 *
 * Kokko is the midsummer bonfire. The page is built around two things that
 * campsite has and a stylesheet can carry: smoke, which rises and breaks one
 * section from the next, and water, which is the colour everything sits on.
 *
 * Display is Geist, body is IBM Plex Sans, anything you read off rather than
 * read is IBM Plex Mono. The brief asked for Geist and it was not in the
 * project, so it is downloaded and self hosted with the rest. No CDN.
 *
 * The smoke here is CSS, not WebGL. That is deliberate and it is the one real
 * difference from the other six: this page carries no canvas at all, so it
 * costs a phone nothing and can never sit on top of the words.
 */

@font-face {
  font-family: "Geist";
  src: url("../assets/fonts/Geist.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

/* Kokko's own palette, written in the shared roles so another one can be
   dropped on top of it. See assets/css/teema.css for what each role is.

   Every value below was measured against every surface it can land on, and
   the worst case is --syva, not --pohja. Measured on --syva:
   otsikko 11.4  teksti 8.5  teksti-2 5.8  teksti-3 4.6
   liekki-ink 4.6  sammal-ink 4.6, and those two are derived against the
   darkest light surface of every palette, not only of this one

   The brief's campfire orange is #d47a3a. It measures 2.92 on the page and
   cannot carry text at any size, so it is split in two: --korostus is the
   fill, and --liekki-ink is the same hue walked down until it passes. Text
   that sits ON the orange is --korostus-ink, near black at 5.18, because
   white on that orange is 3.16 and fails. */
:root {
  --pohja: #f7f6f1;      --pohja-rgb: 247 246 241;
  --pinta: #efede6;      --pinta-rgb: 239 237 230;
  --syva: #e6e3da;
  --viiva: #d8d4c8;
  --otsikko: #1f2a35;
  --teksti: #2d3e50;
  --teksti-2: #4a5763;
  --teksti-3: #5d656f;
  --korostus: #d47a3a;
  --korostus-ink: #1b2028;
  --jalka-pohja: #1f2a35;  --jalka-rgb: 31 42 53;
  --jalka-otsikko: #f7f6f1;
  --jalka-teksti: #e8e9e6;
  --jalka-teksti-2: #b6bec6;
  --jalka-teksti-3: #98a2ac;
  --jalka-korostus: #e79355;
  --usva-a: 222 224 224;  --usva-b: 200 205 208;
  --usva-c: 172 180 186;  --usva-d: 150 160 168;
  --usva-voima: 0.5;
}

.kokko {
  /* Read by the swatch in the palette switcher, which has to show Kokko's
     own colours while another palette is in force at :root. */
  --oma-pohja: #f7f6f1;
  --oma-korostus: #d47a3a;

  /* Site specific, not part of the shared contract. The ornaments take
     --viiva and --teksti-3 instead of these, so they follow whichever
     palette is in force; only the flame itself stays orange. */
  --liekki-ink: #874a1e;
  --sammal: #6b8e6f;
  --sammal-ink: #485f4b;
  --savu: #9b9b99;
  --lauta: #e9e4d8;
  --lauta-viiva: #cdc6b4;
  /* The wildflowers, in every palette: a yellowish gold. */
  --kukka: #d4a72c;
  --kukka-ink: #b8891a;

  background: var(--pohja);
  color: var(--teksti);
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.62;
  overflow-x: hidden;
}

::selection { background: var(--korostus); color: var(--korostus-ink); }

h1, h2, h3 {
  font-family: "Geist", system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.028em;
  color: var(--otsikko);
  text-wrap: balance;
}
p { text-wrap: pretty; }

/* Anything read off rather than read. */
.nauha, .merkki, .ryhma h3, .rivi dd b, .rivi dd span,
.piirre-numero, .palaute-nimi, .ylin-puh, .luku {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}

.tunnus-nimi { font-family: "Geist", system-ui, sans-serif; font-weight: 500; }

/* ===========================================================================
   SAVU, the smoke
   One puff is a blurred radial gradient. A cluster of them with different
   sizes, offsets and durations reads as smoke; any one of them alone reads as
   a grey circle, which is why they are never used alone.
   =========================================================================== */

.savu {
  position: relative;
  height: clamp(4.5rem, 11vh, 8rem);
  pointer-events: none;
  overflow: hidden;
  /* A quiet haze that is always there, under the delight animation below:
     the puffs rise once and are gone, but the seam between two backgrounds
     should not go hard again the moment they have. Where a divider bridges
     an actual colour change, an explicit background on that one element
     (see the markup) overrides this with the real two colours; this is the
     fallback for the rest. */
  background:
    radial-gradient(65% 140% at 50% 0%, color-mix(in srgb, var(--savu) 18%, transparent) 0%, transparent 75%),
    radial-gradient(65% 140% at 50% 100%, color-mix(in srgb, var(--savu) 18%, transparent) 0%, transparent 75%);
}
.savu span {
  position: absolute;
  bottom: -30%;
  left: 50%;
  width: var(--w, 13rem);
  height: calc(var(--w, 13rem) * 1.3);
  margin-left: calc(var(--w, 13rem) / -2);
  translate: var(--x, 0) 0;
  background:
    radial-gradient(58% 44% at 40% 60%, color-mix(in srgb, var(--savu) 42%, transparent) 0%, transparent 70%),
    radial-gradient(50% 38% at 64% 38%, color-mix(in srgb, var(--savu) 32%, transparent) 0%, transparent 74%);
  opacity: 0;
  filter: blur(20px);
}

/* The cluster only rises once, when the divider comes into view. It does not
   loop: smoke that repeats on a timer reads as a loading spinner. */
@media (prefers-reduced-motion: no-preference) {
  .savu.nousee span {
    animation: savu-nousu var(--kesto, 2600ms) cubic-bezier(0.22, 0.61, 0.36, 1) var(--viive, 0ms) both;
  }
}
@keyframes savu-nousu {
  0%   { opacity: 0;    transform: translateY(0) scale(0.55); }
  22%  { opacity: 0.62; }
  100% { opacity: 0;    transform: translateY(-165%) scale(1.5); }
}

/* The hero carries its own, slower and permanent, because a fire that is
   actually burning does not stop. */
.kansi-savu {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 62%;
  pointer-events: none;
  overflow: hidden;
  z-index: 2;
}
.kansi-savu span {
  position: absolute;
  bottom: -18%;
  left: var(--l, 50%);
  width: var(--w, 16rem);
  height: calc(var(--w, 16rem) * 1.35);
  margin-left: calc(var(--w, 16rem) / -2);
  /* Two offset gradients rather than one centred circle. One circle blurred
     is a soft disc no matter how much blur is on it; two of them off centre
     from each other lose the outline, which is the whole point. */
  background:
    radial-gradient(60% 46% at 38% 62%, rgba(236, 231, 220, 0.26) 0%, rgba(236, 231, 220, 0) 68%),
    radial-gradient(52% 40% at 66% 40%, rgba(236, 231, 220, 0.20) 0%, rgba(236, 231, 220, 0) 72%);
  filter: blur(26px);
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .kansi-savu span {
    animation: kansi-savu var(--kesto, 17s) linear var(--viive, 0s) infinite;
  }
}
@keyframes kansi-savu {
  0%   { opacity: 0;    transform: translateY(10%)  translateX(0)     scale(0.7); }
  18%  { opacity: 0.85; }
  70%  { opacity: 0.45; }
  100% { opacity: 0;    transform: translateY(-120%) translateX(18%)  scale(1.7); }
}

/* ===========================================================================
   REUNUS, the side rails
   A plank each side with wildflowers growing up it. Desktop only: below
   80rem there is no room for anything that is not the content, and the same
   ornament comes back as a horizontal divider instead.
   =========================================================================== */

.reunus {
  position: absolute;
  top: 0; bottom: 0;
  width: 3.4rem;
  pointer-events: none;
  /* Behind the reading column, never over it, and never over the hero: the
     first version of this was fixed to the window and read as browser chrome
     rather than as part of the page. */
  z-index: 0;
  display: none;
  /* Sawn plank. Warmer than the page, with a few uneven grain lines and a
     soft edge each side so it sits in the gutter rather than ruling it off. */
  background:
    linear-gradient(to right,
      rgb(var(--pohja-rgb) / 0) 0%, var(--lauta) 30%, var(--lauta) 70%, rgb(var(--pohja-rgb) / 0) 100%),
    repeating-linear-gradient(to right,
      transparent 0 6px,
      color-mix(in srgb, var(--lauta-viiva) 70%, transparent) 6px 7px,
      transparent 7px 17px,
      color-mix(in srgb, var(--lauta-viiva) 40%, transparent) 17px 18px,
      transparent 18px 29px);
}
.reunus-vasen { left: 0; }
.reunus-oikea { right: 0; transform: scaleX(-1); }

.reunus .kukka {
  position: absolute;
  left: 50%;
  width: 2.5rem;
  margin-left: -1.25rem;
  color: var(--kukka-ink);
  opacity: 0.75;
}
@media (prefers-reduced-motion: no-preference) {
  .reunus .kukka { animation: kukka-huoju 9s ease-in-out var(--viive, 0s) infinite; transform-origin: 50% 100%; }
}
@keyframes kukka-huoju {
  0%, 100% { transform: rotate(-3.5deg); }
  50%      { transform: rotate(3.5deg); }
}

/* main is the rails' containing block, and everything in it sits above them.
   The rails are excluded by the selector rather than corrected afterwards:
   `main > *` outranks `.reunus`, so it was overriding position: absolute
   with relative and collapsing both planks to zero height. */
.kokko main { position: relative; }
.kokko main > :not(.reunus) { position: relative; z-index: 1; }

@media (min-width: 80rem) {
  .reunus { display: block; }
  /* The column steps in so the planks are beside the text, not under it.
     The reviews are the exception: that section is full bleed on purpose so
     the row can run off the edge, so its children step in instead of it. */
  .kokko main > section:not(.palaute), .kokko main > .kukkarivi {
    padding-left: max(var(--sivu), 5.5rem);
    padding-right: max(var(--sivu), 5.5rem);
  }
  .palaute-yla, .palaute-huom {
    padding-left: max(var(--sivu), 5.5rem);
    padding-right: max(var(--sivu), 5.5rem);
  }
  .palaute-rivi:not(.liikkuu) {
    padding-left: max(var(--sivu), 5.5rem);
    padding-right: max(var(--sivu), 5.5rem);
  }
}

/* Below the rails' breakpoint the flowers come back as a divider. */
.kukkarivi {
  display: flex;
  justify-content: center;
  gap: clamp(1.5rem, 6vw, 3rem);
  padding: 0.5rem 0 0;
  color: var(--kukka);
  opacity: 0.7;
}
.kukkarivi svg { width: 1.9rem; height: auto; }
@media (min-width: 80rem) { .kukkarivi { display: none; } }

/* ===========================================================================
   KANSI, the hero
   =========================================================================== */

.kansi {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  overflow: hidden;
  isolation: isolate;
}
.kansi-kuva, .kansi-varjo {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
}
.kansi-kuva {
  object-fit: cover; object-position: 50% 56%; z-index: 0;
  opacity: 0; transition: opacity 1.1s ease;
  filter: brightness(1.14) saturate(1.22) contrast(1.04);
}
.kansi-kuva.on { opacity: 1; }
.kansi-varjo {
  z-index: 1;
  /* The heading sits bottom left over bright, busy photos (birches, white
     caravans), so that corner is shaded from both the bottom and the left. */
  background:
    linear-gradient(to right,
      rgba(14, 19, 24, 0.62) 0%, rgba(14, 19, 24, 0.40) 32%,
      rgba(14, 19, 24, 0.10) 58%, rgba(14, 19, 24, 0) 74%),
    linear-gradient(to top,
      rgba(14, 19, 24, 0.82) 0%, rgba(14, 19, 24, 0.56) 28%,
      rgba(14, 19, 24, 0.14) 56%, rgba(14, 19, 24, 0) 72%,
      rgba(14, 19, 24, 0.26) 90%, rgba(14, 19, 24, 0.52) 100%);
}
.kansi > .ylin, .kansi > .kansi-teksti, .kansi > .vieritys { position: relative; z-index: 4; }

.ylin {
  display: flex;
  align-items: center;
  gap: 1rem 2rem;
  min-height: 78px;
  padding: 0 var(--sivu);
  color: #f4f2ec;
}
.tunnus { margin-right: auto; }
.tunnus-alanimi { color: #e7b78c; opacity: 1; }
.valikko ul { list-style: none; display: flex; gap: 1.45rem; }
.valikko a {
  font-size: 0.9375rem; font-weight: 500; text-decoration: none;
  padding: 0.3rem 0; border-bottom: 2px solid transparent;
}
.valikko a:hover { border-bottom-color: var(--korostus); }
.ylin-puh { font-size: 1rem; font-weight: 500; }
.ylin-puh a { text-decoration: none; border-bottom: 2px solid var(--korostus); }

.kansi-teksti {
  grid-row: 2;
  align-self: end;
  padding: 0 var(--sivu) clamp(1.5rem, 4vh, 2.5rem);
  color: #f4f2ec;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.25rem 2rem;
}
.kansi h1 {
  font-size: clamp(2.5rem, 1.2rem + 5.2vw, 5.75rem);
  font-weight: 600;
  line-height: 0.98;
  letter-spacing: -0.04em;
  max-width: 16ch;
  color: #f8f6f1;
  text-shadow: 0 2px 22px rgba(8, 12, 16, 0.55), 0 1px 3px rgba(8, 12, 16, 0.4);
}
/* The emphasis is italic of the same face, not a second typeface dropped in
   for contrast. Leading is opened and the line given reserve, because
   Karijarven has a j and a descender clipped by leading-none is the tell. */
.kansi h1 em {
  font-style: italic;
  font-weight: 500;
  line-height: 1.1;
  padding-bottom: 0.06em;
  color: #f0c49b;
}
.kansi .alle {
  margin-top: 1.35rem;
  max-width: 42ch;
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.1875rem);
  color: #efede7;
  text-shadow: 0 1px 12px rgba(8, 12, 16, 0.7), 0 1px 2px rgba(8, 12, 16, 0.5);
}

/* The one filled surface on the page. Everywhere else an action is a word
   with a coloured rule under it; here it is a button, because it is the
   single thing this screen actually wants pressed. */
.varaa-nappi {
  display: inline-flex;
  align-items: center;
  margin-top: 1.65rem;
  padding: 0.85rem 1.7rem;
  background: var(--korostus);
  border: 1px solid var(--korostus);
  color: var(--korostus-ink);
  font-weight: 600;
  font-size: 1rem;
  text-decoration: none;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.varaa-nappi:hover { background: var(--liekki-ink); border-color: var(--liekki-ink); color: #f7f6f1; }
.varaa-nappi:active { transform: translateY(1px); }

/* A word and, instead of a line pulsing like every other site's scroll
   cue, a few sparks doing what sparks off this particular fire do. */
.vieritys {
  grid-row: 3;
  justify-self: start;
  padding: 0 var(--sivu) clamp(1.75rem, 5vh, 3rem);
  display: flex;
  align-items: center;
  gap: 0.8rem;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #cfccc4;
}
.kipinat {
  position: relative;
  width: 1rem;
  height: 1.6rem;
  flex-shrink: 0;
}
.kipinat span {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0.1875rem;
  height: 0.1875rem;
  margin-left: -0.09375rem;
  background: var(--jalka-korostus);
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .kipinat span { animation: kipina-nousu 2.4s ease-in var(--viive, 0s) infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .kipinat span { opacity: 0.7; }
}
@keyframes kipina-nousu {
  0%   { opacity: 0;    transform: translate(0, 0) scale(1); }
  16%  { opacity: 0.9; }
  55%  { opacity: 0.5; }
  100% { opacity: 0;    transform: translate(var(--x, 0.3rem), -1.5rem) scale(0.35); }
}

/* Hero photo controls. Same light-on-photo palette as the rest of the
   hero, orange the one place something can be pressed. */
.kansi-ohjaus { display: flex; align-items: center; gap: 0.85rem; flex-shrink: 0; }
.kansi-nuoli {
  display: flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem;
  padding: 0;
  background: rgba(18, 24, 30, 0.36);
  border: 1px solid rgba(244, 242, 236, 0.3);
  color: #f4f2ec;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.kansi-nuoli svg { width: 1.2rem; height: 1.2rem; }
.kansi-nuoli:hover { border-color: var(--korostus); color: var(--korostus); }
.kansi-nuoli:active { transform: translateY(1px); }

.kansi-tahdit { display: flex; align-items: center; gap: 0.45rem; }
.kansi-tahti {
  width: 0.125rem; height: 1.1rem;
  padding: 0;
  background: rgba(244, 242, 236, 0.32);
  border: 0;
  cursor: pointer;
  transition: background 0.2s ease, height 0.2s ease;
}
.kansi-tahti:hover { background: rgba(244, 242, 236, 0.6); }
.kansi-tahti.on { background: var(--korostus); height: 1.45rem; }

/* ===========================================================================
   NAUHA, the running strip of amenities
   Two identical tracks side by side, the pair slid left by exactly half its
   width, so the seam never shows. Pauses on hover and does not run at all
   under reduced motion, where it becomes an ordinary wrapped list.
   =========================================================================== */

.nauha {
  position: relative;
  overflow: hidden;
  padding: 0.9rem 0;
  background: var(--jalka-pohja);
  color: var(--jalka-teksti);
  border-block: 1px solid color-mix(in srgb, rgb(var(--jalka-rgb)) 70%, var(--korostus));
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* The strip is decoration over content that is already in the page below;
     it is read out once, by the list in .palvelut. */
  user-select: none;
}
.nauha-raita { display: flex; width: max-content; }
.nauha-jono {
  display: flex;
  align-items: center;
  gap: 2.2rem;
  padding-right: 2.2rem;
  flex: none;
}
.nauha-jono > * { flex: none; }
.nauha .merkki { display: inline-flex; width: 1.15rem; height: 1.15rem; color: var(--korostus); }
.nauha .merkki svg { width: 100%; height: 100%; }

@media (prefers-reduced-motion: no-preference) {
  .nauha-raita { animation: nauha-veto 46s linear infinite; }
  .nauha:hover .nauha-raita, .nauha:focus-within .nauha-raita { animation-play-state: paused; }
}
@keyframes nauha-veto {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .nauha { overflow: visible; padding: 1rem var(--sivu); }
  .nauha-raita { width: auto; flex-wrap: wrap; }
  .nauha-jono { flex-wrap: wrap; gap: 0.9rem 1.6rem; }
  .nauha-jono:nth-child(2) { display: none; }
}

/* ===========================================================================
   Sections
   =========================================================================== */

.kerros {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  padding: clamp(3.5rem, 9vh, 6rem) var(--sivu);
}
.kerros.kaanteinen .kerros-teksti { order: 2; }

h2 {
  font-size: clamp(1.875rem, 1.35rem + 2.2vw, 3rem);
  line-height: 1.04;
}
/* The small line above a heading that says what kind of thing follows. */
.yla {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.9rem;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--liekki-ink);
}
.yla .merkki { display: inline-flex; width: 1rem; height: 1rem; color: var(--korostus); }
.yla .merkki svg { width: 100%; height: 100%; }

.iso-teksti {
  margin-top: 1.15rem;
  font-size: clamp(1.125rem, 1rem + 0.7vw, 1.4375rem);
  font-weight: 300;
  line-height: 1.38;
  max-width: 36ch;
  color: var(--otsikko);
}
.kerros p:not(.iso-teksti):not(.huomio):not(.inventaario):not(.varaa) {
  margin-top: 1.05rem; color: var(--teksti-2); max-width: 56ch;
}

.inventaario { margin-top: 1.05rem; max-width: 56ch; color: var(--teksti-2); }
.inventaario b { font-weight: 600; color: var(--liekki-ink); font-variant-numeric: tabular-nums; }

.huomio {
  margin-top: 1.6rem;
  padding: 0.9rem 1.15rem;
  background: var(--pinta);
  border-left: 3px solid var(--korostus);
  max-width: 48ch;
  color: var(--teksti-2);
}

.varaa { margin-top: 1.6rem; font-weight: 500; }
.varaa a { text-decoration: none; border-bottom: 2px solid var(--korostus); white-space: nowrap; }

/* Photographs sit on a plank, which is the same material as the side rails. */
.kehys { margin: 0; }
.kehys-levy {
  position: relative;
  padding: clamp(0.5rem, 1vw, 0.8rem);
  background: var(--syva);
  box-shadow: 0 22px 48px -26px rgb(var(--jalka-rgb) / 0.55);
}
.kehys-levy img { display: block; width: 100%; }
figcaption { margin-top: 0.55rem; font-size: 0.8125rem; color: var(--teksti-3); }

/* ===========================================================================
   PIIRTEET, the feature cards
   =========================================================================== */

.piirteet { padding: clamp(3rem, 8vh, 5rem) var(--sivu); }
.piirteet-yla { max-width: 32rem; }
.piirteet-ruudukko {
  margin-top: clamp(2rem, 5vh, 3rem);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.2vw, 1.75rem);
}
/* A short last row stretches its last card instead of leaving a hole. */
.piirre:last-child:nth-child(3n+2) { grid-column: span 2; }
.piirre {
  position: relative;
  padding: clamp(1.4rem, 2.4vw, 2rem);
  background: var(--pinta);
  overflow: hidden;
}
/* The wildflower growing in the corner of each card. The first version of
   this was a gradient and a mask, which read as a grey smudge; it is the
   same flower as the one on the planks instead. */
.piirre-kukka {
  position: absolute;
  right: 0.35rem;
  bottom: -0.2rem;
  width: 4.75rem;
  height: auto;
  color: var(--kukka);
  opacity: 0.5;
  pointer-events: none;
}
.piirre-merkki {
  display: inline-flex;
  width: 2.1rem; height: 2.1rem;
  color: var(--korostus);
}
.piirre-merkki svg { width: 100%; height: 100%; }
.piirre h3 { margin-top: 0.9rem; font-size: 1.1875rem; font-weight: 600; letter-spacing: -0.015em; }
.piirre p { margin-top: 0.45rem; font-size: 0.9375rem; color: var(--teksti-2); position: relative; max-width: 30ch; }
.piirre-numero {
  display: block;
  margin-top: 0.8rem;
  font-size: 1.75rem;
  font-weight: 500;
  line-height: 1;
  color: var(--liekki-ink);
}

/* ===========================================================================
   PALAUTE, the reviews
   Without JavaScript, or under reduced motion, a scroll-snapped row you drag.
   With it, kokko.js doubles the cards and adds .liikkuu, and the row runs
   slowly on a loop like the amenities strip. It stops under the pointer or
   focus, so a quote can still be read to the end.
   =========================================================================== */

.palaute { padding: clamp(3rem, 8vh, 5rem) 0; background: var(--pinta); }
.palaute-yla { padding: 0 var(--sivu); max-width: 32rem; }
.palaute-rivi {
  margin-top: clamp(1.75rem, 4vh, 2.5rem);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(min(21rem, 78vw), 1fr);
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 0.35rem var(--sivu) 1.25rem;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}
/* The two wrappers exist for the loop; in the static row they step aside
   and the cards sit straight in the grid. */
.palaute-raita, .palaute-jono { display: contents; }

.palaute-rivi.liikkuu {
  display: block;
  overflow: hidden;
  scroll-snap-type: none;
  padding-left: 0;
  padding-right: 0;
}
.liikkuu .palaute-raita {
  display: flex;
  width: max-content;
  animation: nauha-veto 60s linear infinite;
}
.liikkuu:hover .palaute-raita,
.liikkuu:focus-within .palaute-raita { animation-play-state: paused; }
.liikkuu .palaute-jono { display: flex; gap: 1rem; padding-right: 1rem; flex: none; }
/* Same size the static row gives them: three across the page on a wide
   screen, most of the width on a phone. */
.liikkuu .kortti {
  width: max(min(21rem, 78vw), calc((100vw - 2 * var(--sivu) - 2rem) / 3));
  flex: none;
}

.kortti {
  scroll-snap-align: start;
  padding: clamp(1.3rem, 2.4vw, 1.8rem);
  background: var(--pohja);
  border-top: 2px solid var(--korostus);
  display: flex;
  flex-direction: column;
}
.kortti blockquote { margin: 0; font-size: 1.0625rem; line-height: 1.5; color: var(--teksti); }
.kortti blockquote p { text-wrap: pretty; }
.palaute-nimi {
  margin-top: auto;
  padding-top: 1.1rem;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teksti-3);
}
.tahdet { display: flex; gap: 0.15rem; margin-bottom: 0.9rem; color: var(--korostus); }
.tahdet svg { width: 0.95rem; height: 0.95rem; }

/* This section ships with its text still to be written, and says so rather
   than carrying invented quotes under a real family's name. */
.paikanpitaja { border-top-color: var(--viiva); }
.paikanpitaja blockquote { color: var(--teksti-3); font-style: italic; }
.paikanpitaja .tahdet { color: var(--viiva); }
.palaute-huom {
  margin-top: 0.5rem;
  padding: 0 var(--sivu);
  font-size: 0.8125rem;
  color: var(--teksti-3);
}
.palaute-huom a { color: inherit; text-underline-offset: 0.2em; }
.palaute-huom a:hover { color: var(--teksti); }

/* ===========================================================================
   HINNASTO
   =========================================================================== */

.hinnasto { padding: clamp(3.5rem, 9vh, 6rem) var(--sivu); }
.maksut { margin-top: 0.8rem; color: var(--teksti-3); font-size: 0.9375rem; }
.hinnat-ryhmat {
  margin-top: clamp(2.25rem, 5vh, 3.5rem);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.75rem, 3.5vw, 3rem);
}
.ryhma h3 {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--liekki-ink);
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--viiva);
}
.ryhma dl { margin-top: 0.9rem; }
.rivi { padding: 0.55rem 0; }
.rivi dt { font-size: 0.9375rem; color: var(--teksti); }
.rivi dd { margin: 0.2rem 0 0; }
.rivi dd b { display: block; font-weight: 500; font-size: 0.9375rem; white-space: nowrap; color: var(--otsikko); }
.rivi dd span { display: block; margin-top: 0.12rem; font-size: 0.75rem; color: var(--teksti-3); }

/* ===========================================================================
   AJO
   =========================================================================== */

.ajo { padding: clamp(3.5rem, 9vh, 6rem) var(--sivu); }
.ajo-suunnat {
  margin-top: clamp(1.75rem, 4vh, 2.5rem);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  max-width: 62rem;
}
.suunta h3 { font-size: 1.0625rem; font-weight: 600; }
.suunta p { margin-top: 0.5rem; color: var(--teksti-2); font-size: 0.9375rem; }
.kartta-linkki { margin-top: 1.25rem; font-weight: 500; grid-column: 1 / -1; }
.kartta-linkki a { text-decoration: none; border-bottom: 2px solid var(--korostus); }
.ajo-kartta { margin-top: clamp(1.75rem, 4vh, 2.5rem); max-width: 42rem; }
/* A map to glance at, not a map to live in: wide and short, and the link
   above it opens the real one. */
.ajo-kartta .kartta { aspect-ratio: 16 / 9; max-height: 20rem; }
@media (max-width: 46rem) {
  .ajo-kartta .kartta { aspect-ratio: 4 / 3; max-height: 16rem; }
}
/* The map before it is asked for: the same box, quiet, with one button. */
.kartta-odottaa {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1rem;
  padding: clamp(1.25rem, 4vw, 2.25rem);
  background: var(--syva);
  border: 1px solid var(--viiva);
  filter: none;
}
.kartta-odottaa p { max-width: 42ch; font-size: 0.9375rem; color: var(--teksti-2); }
.kartta-odottaa a { color: var(--otsikko); text-underline-offset: 0.2em; }
.kartta-nappi {
  padding: 0.7rem 1.2rem;
  min-height: 2.75rem;
  background: var(--otsikko);
  color: var(--pohja);
  border: 0;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.kartta-nappi:hover { background: var(--liekki-ink); }
.kartta-nappi:focus-visible { outline: 2px solid var(--korostus); outline-offset: 2px; }

.ehdot-osio { padding: 0 var(--sivu) clamp(3.5rem, 9vh, 6rem); max-width: 68ch; }
.ehdot-osio p { margin-top: 1.05rem; color: var(--teksti-2); }

/* ===========================================================================
   JALKA
   The one dark surface on the page: the fire seen from across the field.
   =========================================================================== */

.jalka {
  position: relative;
  padding: clamp(3rem, 8vh, 5rem) var(--sivu) clamp(4rem, 11vh, 7rem);
  background: var(--jalka-pohja);
  color: var(--jalka-teksti);
  overflow: hidden;
}
.jalka h2 {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem; font-weight: 400; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--jalka-teksti-3);
}
.nimet { margin-top: 1.2rem; font-family: "Geist", system-ui, sans-serif; font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.125rem); font-weight: 500; color: var(--jalka-otsikko); }
.osoite { margin-top: 0.35rem; color: var(--jalka-teksti-2); }
.numero {
  margin-top: 1.4rem;
  font-family: "Geist", system-ui, sans-serif;
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
  font-weight: 500; font-variant-numeric: tabular-nums;
  color: var(--jalka-otsikko);
}
.numero a { text-decoration: none; border-bottom: 3px solid var(--jalka-korostus); }
.posti { margin-top: 0.85rem; }
.posti a, .ehdot a { color: var(--jalka-teksti-2); text-underline-offset: 3px; }
.ehdot { margin-top: 1.4rem; font-size: 0.9375rem; }
/* Footer links to these pages, on every guest page. */
.jalka .oikeudelliset { margin-top: 0.5rem; font-size: 0.875rem; }
.jalka .oikeudelliset a { color: var(--jalka-teksti-2); text-underline-offset: 3px; }
.jalka .oikeudelliset a + a { margin-left: 1.25rem; }

/* ===========================================================================
   KUVAT, the photo mosaic and the gallery page
   On the front page: one large photo and four small, two rows exactly, so it
   never leaves a hole. On /kuvat/ the same tiles run as a longer grid, and a
   tile marked .leve takes two columns; that is set by hand in the markup,
   because only the full-size photos can stand being shown that big.
   =========================================================================== */

.kuvat { padding: clamp(3.5rem, 9vh, 6rem) var(--sivu) clamp(2rem, 5vh, 3rem); }
.kuvat-yla {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 2rem;
}
.kuvat-yla > div { max-width: 36rem; }
.kuvat-kaikki { font-weight: 500; }
.kuvat-kaikki a { text-decoration: none; border-bottom: 2px solid var(--korostus); white-space: nowrap; }

.kuvat-ruudukko {
  list-style: none;
  margin-top: clamp(1.75rem, 4vh, 2.5rem);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: clamp(9rem, 15vw, 14rem);
  gap: clamp(0.6rem, 1.2vw, 1rem);
}
.kuvat-ruudukko.mosaiikki > li:first-child { grid-column: span 2; grid-row: span 2; }
.kuvat-ruudukko:not(.mosaiikki) { grid-auto-flow: dense; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: clamp(11rem, 20vw, 17rem); }
.kuvat-ruudukko > li.leve { grid-column: span 2; }

.kuva-ruutu {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: var(--syva);
  overflow: hidden;
  cursor: zoom-in;
  box-shadow: 0 18px 40px -26px rgb(var(--jalka-rgb) / 0.55);
}
.kuva-ruutu img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), filter 0.3s ease;
}
.kuva-ruutu:hover img { transform: scale(1.04); filter: saturate(1.08); }
.kuva-ruutu:focus-visible { outline: 3px solid var(--korostus); outline-offset: 3px; }

/* The gallery page's header is the hero cut down: same photo treatment and
   top bar, a third of the height, no carousel. */
.kansi.kansi-lyhyt { min-height: clamp(20rem, 52svh, 34rem); }
.murut ol { list-style: none; display: flex; gap: 0.5rem; font-size: 0.875rem; color: #dcdad3; }
.murut li + li::before { content: "/"; margin-right: 0.5rem; opacity: 0.6; }
.murut a { color: inherit; text-underline-offset: 3px; }
.valikko a[aria-current="page"] { border-bottom-color: var(--korostus); }

/* The lightbox is the footer's dark, so a photo is looked at the way the
   fire is: from the dark side of the field. */
.valokaappi {
  padding: 0;
  border: 0;
  max-width: min(94vw, 72rem);
  max-height: 92vh;
  background: var(--jalka-pohja);
  color: var(--jalka-teksti);
}
.valokaappi::backdrop { background: rgb(12 16 20 / 0.86); }
.valokaappi[open] { display: flex; flex-direction: column; }
.valokaappi-sulje, .valokaappi-nuoli {
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  background: rgb(var(--jalka-rgb) / 0.6);
  border: 1px solid rgb(247 246 241 / 0.3);
  color: var(--jalka-otsikko);
  cursor: pointer;
}
.valokaappi-sulje { align-self: flex-end; margin: 0.75rem 0.75rem 0; width: 2.5rem; height: 2.5rem; }
.valokaappi-sulje svg { width: 1.1rem; height: 1.1rem; }
.valokaappi-sulje:hover, .valokaappi-nuoli:hover { border-color: var(--jalka-korostus); color: var(--jalka-korostus); }
.valokaappi-runko {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  min-height: 0;
  padding: 0.5rem clamp(1rem, 4vw, 3rem) clamp(1rem, 3vh, 1.75rem);
}
.valokaappi-kuva { display: block; max-width: 100%; max-height: 70vh; }
.valokaappi-teksti {
  margin: 0 clamp(1rem, 4vw, 3rem) clamp(1rem, 3vh, 1.5rem);
  text-align: center;
  font-size: 0.9375rem;
  color: var(--jalka-teksti-2);
}
.valokaappi-nuoli {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 2.75rem; height: 2.75rem;
}
.valokaappi-nuoli svg { width: 1.25rem; height: 1.25rem; }
.valokaappi-edellinen { left: clamp(0.25rem, 1.5vw, 1rem); }
.valokaappi-seuraava { right: clamp(0.25rem, 1.5vw, 1rem); }

@media (max-width: 46rem) {
  .kuvat-ruudukko, .kuvat-ruudukko:not(.mosaiikki) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: clamp(8rem, 34vw, 12rem);
  }
  .kuvat-ruudukko.mosaiikki > li:first-child { grid-row: span 1; }
  /* Four wide tiles and seven single ones leave one cell over in two
     columns; the last photo takes it rather than leaving a hole. */
  .kuvat-ruudukko:not(.mosaiikki) > li:last-child { grid-column: span 2; }
  .valokaappi-kuva { max-height: 58vh; }
}

/* ===========================================================================
   Scroll reveals
   Plain rise for most things; the two column sections come in from the side
   they sit on, which is what the brief asked for.
   =========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  [data-nouse] {
    opacity: 0;
    translate: 0 20px;
    transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1) var(--viive, 0ms),
                translate 700ms cubic-bezier(0.16, 1, 0.3, 1) var(--viive, 0ms);
  }
  [data-nouse="vasen"] { translate: -26px 0; }
  [data-nouse="oikea"] { translate: 26px 0; }
  [data-nouse].nakyy { opacity: 1; translate: 0 0; }
}

/* ===========================================================================
   Narrow
   =========================================================================== */

@media (max-width: 64rem) {
  .kerros { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  .kerros.kaanteinen .kerros-teksti { order: 0; }
  .piirteet-ruudukko { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .piirre:last-child:nth-child(3n+2) { grid-column: auto; }
  .piirre:last-child:nth-child(odd) { grid-column: span 2; }
  .hinnat-ryhmat { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 46rem) {
  .ylin { flex-wrap: wrap; padding-top: 0.85rem; padding-bottom: 0.85rem; min-height: 0; }
  .tunnus { margin-right: 0; }
  .ylin-puh { margin-left: auto; }
  .valikko { order: 3; width: 100%; }
  .valikko ul { flex-wrap: wrap; gap: 0.35rem 1.1rem; }
  .piirteet-ruudukko { grid-template-columns: minmax(0, 1fr); }
  .piirre:last-child:nth-child(odd) { grid-column: auto; }
  .hinnat-ryhmat { grid-template-columns: minmax(0, 1fr); }
  .ajo-suunnat { grid-template-columns: minmax(0, 1fr); }
  .kansi h1 { max-width: 13ch; }
  /* Finnish compounds are long and the column is narrow. */
  .kerros p, .piirre p, .suunta p, .ehdot-osio p { hyphens: auto; }
  .savu { height: 3.5rem; }
  .kansi-ohjaus { width: 100%; justify-content: space-between; }
}

/* ===========================================================================
   Under the two dark palettes the ground goes dark and the two darkened inks
   derived above stop working, because they were derived against an off-white
   page. Those palettes carry a light accent, so the accent itself is legible
   there and the derived inks step aside for it.
   =========================================================================== */

:root[data-teema="kuusikko"] .kokko,
:root[data-teema="kesayo"] .kokko,
:root[data-teema="hamara"] .kokko,
:root[data-teema="nuotio"] .kokko {
  --liekki-ink: var(--korostus);
  --sammal-ink: var(--korostus);
  --savu: #8f9aa2;
  --lauta: color-mix(in srgb, var(--pinta) 82%, var(--teksti-3));
  --lauta-viiva: var(--viiva);
}

/* The three newer light palettes carry an accent dark
   enough to be text (measured in teema.css), so the orange-derived inks give
   way to it: the small labels and figures take the palette's colour instead
   of staying Kokko's brown. */
:root[data-teema="sammal"] .kokko,
:root[data-teema="mustikka"] .kokko,
:root[data-teema="selkea"] .kokko {
  --liekki-ink: var(--korostus);
  --sammal-ink: var(--korostus);
  --lauta: color-mix(in srgb, var(--pinta) 82%, var(--teksti-3));
  --lauta-viiva: var(--viiva);
}
