/* Oma Tienoo showcase — visual identity in one file.
 *
 * Moss is the brief: a forest-floor dark for the hero and footer, a pale
 * lichen (green-tinted, deliberately not cream) for the body, and chanterelle
 * gold as the single accent — a find on moss.
 *
 * Three voices carry the page: Fraunces for display, IBM Plex Sans for
 * reading, and a tracked-uppercase cut of Plex for the labels, captions and
 * credits. Fraunces is the register of an old Finnish sieniopas: an old-style
 * serif with an optical-size axis, so the headlines get the high-contrast cut
 * of a printed plate title while the small sizes stay sturdy. Its WONK axis
 * is on for display and off for text, which is where the hand-cut quality
 * comes from.
 *
 * Fonts are self-hosted (vendored by scripts/vendor-showcase-fonts.mjs, via
 * `make showcase-fonts`) because the page tells the reader there is no
 * third-party tracking on it, and a font CDN would make that untrue.
 *
 * The signature is the species key in the sienikartat section. It is the
 * app's own layer list, drawn as the legend it already is, and the six
 * habitat rules are the ones the model runs on. Everything around it stays
 * quiet so the key is what the page is remembered by. */

:root {
  --humus: #161c12;        /* wet forest floor — hero, footer, euro band */
  --moss-deep: #202d18;    /* the frame around a screenshot */
  --moss: #3e5527;         /* borders on dark */
  --moss-soft: #a9b694;    /* muted text on dark */
  --lichen: #ecefe0;       /* page background */
  --lichen-2: #dfe6cb;     /* the one tinted panel that is left */
  --ink: #1c2614;          /* text on light */
  --ink-soft: #46543a;     /* muted text on light */
  --rule: #c4cfae;         /* hairline on light */
  --gold: #dfa22e;         /* kanttarelli — accent on dark, buttons */
  --gold-deep: #8a6410;    /* accent that keeps contrast on light */
  --on-dark: #e7ecda;

  --serif: "Fraunces", "Palatino Nova", Palatino, "Book Antiqua", Georgia, serif;
  --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --measure: 34rem;
  --wrap: 68rem;
  --pad: clamp(1.25rem, 5vw, 3rem);
  /* Bands pad both edges, so the gap between two of them is twice this.
     Kept small for that reason; the dark bands set their own. */
  --band-y: clamp(2.25rem, 4.5vw, 3.5rem);
  --overhang: clamp(1.5rem, 5vw, 4.5rem);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--lichen);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* WONK on for display: the angled, hand-cut terminals are the whole reason
   this face is here. Text-size Fraunces elsewhere leaves it off. */
h1, h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-variation-settings: "WONK" 1;
  letter-spacing: -0.02em;
}

a { color: var(--gold-deep); text-underline-offset: 3px; }

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}

img { max-width: 100%; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* ---- the three shared voices ---------------------------------------- */

/* the utility voice: labels, captions, credits, scale marks */
.label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-soft);
  margin: 0 0 0.9rem;
}
.label-gold { color: var(--gold); }

.btn {
  display: inline-block;
  background: var(--gold);
  color: var(--humus);
  font-weight: 600;
  text-decoration: none;
  padding: 0.8rem 1.6rem;
  border-radius: 999px;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.btn:hover { transform: translateY(-1px); box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35); }

.cta-note { font-size: 0.9rem; color: var(--moss-soft); }
.cta-note a { color: var(--gold); }

.cta-row {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
}

/* ---- band rhythm ----------------------------------------------------- */

.wrap {
  position: relative;
  max-width: var(--wrap);
  margin: 0 auto;
  padding-left: var(--pad);
  padding-right: var(--pad);
}

.band { padding: var(--band-y) 0; }

.band h2 {
  font-size: clamp(2rem, 4.4vw, 3rem);
  line-height: 1.06;
  margin: 0 0 1rem;
}

.lede-light {
  max-width: var(--measure);
  color: var(--ink-soft);
  margin: 0 0 clamp(2rem, 4vw, 3rem);
}

/* the moss grain, faint on purpose */
.hero::before, .euro::before, .foot::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23m)'/%3E%3C/svg%3E");
  opacity: 0.05;
  pointer-events: none;
}

/* ---- site nav --------------------------------------------------------- */

/* Every page carries the same bar, and it is dark on all of them: the hero
   is dark, so a light bar would only be a seam above it, and on the light
   pages the dark bar is the one thing that says which site you are on.
   The markup is duplicated per page on purpose — this site has no build
   step — so a change here is a change in every page's <header>. */
/* Language switch: a slim strip of its own above the nav. As a fifth nav
   item it wrapped the whole bar into two cramped lines on a phone. */
.langbar {
  background: var(--moss-deep);
}
.langbar-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0.3rem var(--pad);
  display: flex;
  justify-content: flex-end;
  font-size: 0.78rem;
}
/* Both languages, the current one filled: a lone link to the other language
   says where you can go and not where you are. Same shape as the toggle in
   the app. */
.langpill {
  display: flex;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--moss-soft) 45%, transparent);
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.langpill > * {
  padding: 0.15rem 0.6rem;
  line-height: 1.5;
}
.langbar a {
  color: var(--moss-soft);
  text-decoration: none;
}
.langbar a:hover {
  color: var(--on-dark);
  background: color-mix(in srgb, var(--on-dark) 14%, transparent);
}
.langpill .on {
  background: var(--on-dark);
  color: var(--moss-deep);
}

.sitenav {
  position: relative;
  background: var(--humus);
  color: var(--on-dark);
}

.sitenav-inner {
  position: relative;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0.85rem var(--pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.sitenav .wordmark {
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--on-dark);
  text-decoration: none;
  white-space: nowrap;
}

.sitenav nav {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 3vw, 1.75rem);
  font-size: 0.9rem;
}

.sitenav nav a {
  color: var(--moss-soft);
  text-decoration: none;
  padding: 0.25rem 0;
  border-bottom: 1px solid transparent;
}

.sitenav nav a:hover { color: var(--on-dark); }

/* The page you are on, marked with aria-current so the styling and the
   accessibility name say the same thing. */
.sitenav nav a[aria-current="page"] {
  color: var(--on-dark);
  border-bottom-color: var(--gold);
}

/* The link colour above is more specific than .btn's own, so the CTA needs
   its ink stated here or it renders lichen-on-gold and reads as disabled. */
.sitenav nav a.btn {
  color: var(--humus);
  padding: 0.4rem 0.95rem;
  font-size: 0.85rem;
}

/* ---- the Kartta menu --------------------------------------------------- */

/* A <details> in the nav row. The nav grew past what a flat bar could hold:
   fourteen pages behind three links meant the site looked smaller than it
   is, and the map pages in particular were reachable only by guessing that
   a hub existed. The menu shows the whole map section at once, which is the
   overview a flat bar cannot give. */
.sitenav .mega { position: static; }

.sitenav .mega summary {
  list-style: none;
  cursor: pointer;
  color: var(--moss-soft);
  padding: 0.25rem 0;
  border-bottom: 1px solid transparent;
}
.sitenav .mega summary::-webkit-details-marker { display: none; }
.sitenav .mega summary::after {
  content: "";
  display: inline-block;
  width: 0.36em; height: 0.36em;
  margin-left: 0.4em;
  vertical-align: 0.15em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.15s;
}
.sitenav .mega[open] summary::after { transform: rotate(-135deg); }
.sitenav .mega summary:hover { color: var(--on-dark); }
.sitenav .mega summary[aria-current="page"] {
  color: var(--on-dark);
  border-bottom-color: var(--gold);
}

/* Anchored to the bar, not to the summary, so the panel spans the page and
   the columns line up with the content below it. */
.mega-panel {
  position: absolute;
  left: 0; right: 0;
  top: 100%;
  z-index: 30;
  background: var(--humus);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
  padding: 1.25rem 0 1.5rem;
}

.mega-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1.25rem 2rem;
}

.mega-col h3 {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 0.5rem;
}

.mega-col ul { list-style: none; margin: 0; padding: 0; }
.mega-col li { margin-bottom: 0.35rem; }

.sitenav .mega-col a {
  color: var(--on-dark);
  font-size: 0.9rem;
  border-bottom: 0;
}
.sitenav .mega-col a:hover { color: var(--gold); }

/* The way back to the hub page itself, since the summary above is a
   disclosure control rather than a link. */
.sitenav .mega-all {
  display: inline-block;
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  border-bottom: 0;
  color: var(--gold);
  font-size: 0.85rem;
  width: 100%;
}
.sitenav .mega-all:hover { color: var(--on-dark); }
.sitenav .mega-all::after { content: " \2192"; }

/* On a phone the bar already wraps, and an absolutely positioned panel would
   sit over the page with nothing to anchor it. Let it push the content down
   instead: a menu that covers what you were reading is worse than a long one. */
@media (max-width: 52rem) {
  .mega-panel {
    position: static;
    box-shadow: none;
    padding: 0.75rem 0 0.25rem;
  }
  /* The nav row has to be allowed to wrap and the menu to shrink, or the
     panel sets the width of the whole bar: a flex item will not go below its
     content's minimum, so three auto-fit columns of 11rem made a 616px bar
     inside a 393px phone and the page scrolled sideways. */
  .sitenav nav { flex-wrap: wrap; justify-content: center; }
  .sitenav .mega { width: 100%; min-width: 0; }
  .sitenav .mega summary { text-align: center; }
  .mega-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem 1.25rem;
  }
}

/* The hero sits directly under the bar, so it loses its own top padding. */
.sitenav + .hero .hero-inner { padding-top: clamp(2rem, 5vw, 3.5rem); }

@media (max-width: 34rem) {
  .sitenav-inner { flex-wrap: wrap; justify-content: center; gap: 0.5rem 1rem; }
  .sitenav .wordmark { font-size: 0.95rem; width: 100%; text-align: center; }
  .sitenav nav { gap: 0.9rem; font-size: 0.85rem; }
}

/* ---- breadcrumbs ------------------------------------------------------- */

/* Where you are, on every page below the front page. The last item is the
   page itself and carries no link, so the trail says "you are here" rather
   than offering a link to nowhere. */
.crumbs {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0 0 1rem;
}
.crumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
}
.crumbs li::after { content: "›"; margin-left: 0.35rem; color: var(--rule); }
.crumbs li:last-child::after { content: ""; }
.crumbs a { color: var(--ink-soft); }
.crumbs a:hover { color: var(--gold-deep); }
.crumbs [aria-current="page"] { color: var(--ink); }

/* ---- content pages ---------------------------------------------------- */

/* Everything that is not the one-pager: the sienikartat pages, ohjeet,
   tietosuoja, metsähakkuut. One column, one measure, and the same type
   sizes as the bands, so a subpage reads as the same site rather than as
   documentation bolted on. */
.page { padding: var(--band-y) 0 clamp(3rem, 6vw, 5rem); }

.page h1 {
  font-family: var(--serif);
  font-size: clamp(2.1rem, 5vw, 3.2rem);
  line-height: 1.05;
  margin: 0 0 1rem;
  max-width: 20ch;
}

.prose { max-width: var(--measure); }
.prose h2 {
  font-size: clamp(1.3rem, 3vw, 1.7rem);
  margin: 2.25rem 0 0.6rem;
}
.prose h3 { font-size: 1.05rem; margin: 1.5rem 0 0.35rem; }
.prose p { margin: 0 0 1rem; }
.prose ul { margin: 0 0 1rem; padding-left: 1.15rem; }
.prose li { margin-bottom: 0.5rem; }
.prose a { color: var(--gold-deep); }

/* Facts with names: the habitat rule, the data behind a layer. Two columns
   on anything wider than a phone, one on a phone. */
.facts { margin: 1.25rem 0 1.75rem; }
.facts div {
  display: grid;
  grid-template-columns: minmax(7.5rem, 12rem) 1fr;
  gap: 0.35rem 1rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--rule);
}
.facts dt { font-weight: 600; }
.facts dd { margin: 0; color: var(--ink-soft); }

@media (max-width: 32rem) {
  .facts div { grid-template-columns: 1fr; gap: 0.15rem; }
  .facts div[data-species] .kausi { grid-column: 1; }
}

/* The layer's own screenshot: above the text on narrow windows, floated
   into the free right half of the wrap on wide ones. The negative right
   margin pulls it out of the measure entirely, so the text never wraps
   around a squeezed column — that was the bug this replaces. */
.page-figure {
  width: min(18rem, 100%);
  margin: 0.5rem 0 1.5rem;
}
.page-figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 20px;
  border: 6px solid var(--moss-deep);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.22);
}
.page-figure figcaption {
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin-top: 0.5rem;
}

@media (min-width: 64rem) {
  .page-figure {
    float: right;
    width: 19rem;
    margin: 0 calc(-19rem - 4rem) 1.5rem 2rem;
  }
}

/* The other five species, at the foot of each species page. */
.sisarukset {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}
.sisarukset a {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 0.35rem 0.8rem;
  font-size: 0.88rem;
  text-decoration: none;
  color: var(--ink);
}
.sisarukset a:hover { border-color: var(--gold-deep); }
.sisarukset .dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; background: var(--dot); }

/* ---- hero ------------------------------------------------------------ */

.hero {
  position: relative;
  background: var(--humus);
  color: var(--on-dark);
}

.hero-inner {
  position: relative;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: clamp(3.5rem, 9vw, 6rem) var(--pad) 0;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: end;
}

.hero-copy { padding-bottom: clamp(3.5rem, 8vw, 6rem); }

.hero h1 {
  font-size: clamp(2.6rem, 6.2vw, 4.4rem);
  line-height: 1.02;
  margin: 0 0 1.2rem;
}

.lede {
  max-width: var(--measure);
  color: var(--moss-soft);
  font-size: 1.125rem;
  margin: 0 0 2rem;
}

/* The real app, overhanging the band edge: the screenshot is the hero image,
   and the map inside it carries the texture. */
.hero-shot {
  margin-bottom: calc(-1 * var(--overhang));
  justify-self: center;
  max-width: 20rem;
  width: 100%;
}

.hero-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 26px;
  border: 7px solid var(--moss-deep);
  box-shadow: 0 22px 50px rgba(0, 0, 0, 0.45);
}

/* ---- sienikartat: the centre of gravity ------------------------------ */

.kartat { padding-top: calc(var(--band-y) + var(--overhang)); }

.kartat-main { margin-bottom: clamp(2.5rem, 5vw, 4rem); }

/* the species key — a legend, drawn as a legend */
/* Rows flow across, so each grid row is one height in both columns and the
   container's closing rule lands flat under the last of them. */
.key {
  margin: 0;
  display: grid;
  /* min() so a track floor wider than the viewport cannot force a scrollbar */
  grid-template-columns: repeat(auto-fit, minmax(min(23rem, 100%), 1fr));
  column-gap: clamp(2rem, 5vw, 4rem);
  border-bottom: 1px solid var(--rule);
}

.key-row {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: 0.3rem 1.4rem;
  align-items: baseline;
  padding: 1rem 0;
  border-top: 1px solid var(--rule);
}


.key dt {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.2rem;
  letter-spacing: -0.01em;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

.key dd {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.dot {
  flex: none;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--dot);
  transform: translateY(-0.05em);
}

/* the season indicator, drawn into the key rows by /kausi.js.
 *
 * The app's visual language, borrowed intact: the word is the calendar's and
 * is said once per species, the three meters are the wash, and a meter drains
 * toward grey below the peak rather than disappearing. Never a percentage —
 * the meter exists so "how close to good" can be a smooth thing while the
 * words stay the app's five.
 *
 * Everything here starts absent. Without the script or without the published
 * file the key is the legend it was before, and nothing on the page refers to
 * a season indicator that is not there. */
.kausi {
  grid-column: 2;
  margin-top: 0.55rem;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem 0.9rem;
}

.kausi-word {
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  flex: none;
}

.kausi-zones {
  flex: 1 1 13rem;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 0.7rem;
}

.kausi-zone {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.kausi-zn,
.kausi-note {
  font-size: 0.68rem;
  line-height: 1.35;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Holds the line so the three meters stay level when only one zone has
   something to report. */
.kausi-note:empty::before { content: "\00a0"; }

.kausi-meter {
  display: block;
  height: 0.3rem;
  border-radius: 999px;
  background: var(--rule);
  overflow: hidden;
}

.kausi-meter i {
  display: block;
  height: 100%;
  /* --dot is the species colour, set on .key-row: the meter is the same hue
     as the layer it describes, which is the whole point of the key. */
  background: var(--dot);
  border-radius: inherit;
}

/* Off-season and edge drain toward grey and fade, the two properties
   SEASON_PAINT moves in the app. Never to nothing: a meter that vanished
   would read as a missing measurement rather than a quiet week. */
.kausi-zone[data-level="edge"] .kausi-meter i { filter: saturate(0.45); opacity: 0.7; }
.kausi-zone[data-level="off"] .kausi-meter i { filter: saturate(0.12); opacity: 0.5; }
.kausi-zone[data-level="rare"] .kausi-zn,
.kausi-zone[data-level="off"] .kausi-zn { opacity: 0.65; }
.kausi-zone[data-level="rare"] .kausi-note { font-style: italic; }

/* The provenance line under the key: the two dates, then the link out to the
   page that explains what weights what. */
.kausi-foot {
  margin: 0.9rem 0 0;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

.kausi-foot a { color: var(--gold-deep); }

.kausi-lead { display: block; }

/* the provenance, kept as reference material and weighted like it */
.note {
  background: var(--lichen-2);
  border-radius: 12px;
  padding: 1.5rem 1.6rem;
  max-width: 48rem;
}

.note p { color: var(--ink-soft); margin: 0 0 0.9rem; font-size: 0.95rem; }
.note .label { color: var(--ink); }
.note .credits { font-size: 0.78rem; opacity: 0.85; margin: 0; }

/* ---- features ------------------------------------------------------- */

/* Three features have a capture; two cannot be shown by one phone screen
   and stay as text below. The split is the reason the section has both. */
.shots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: clamp(1.5rem, 4vw, 2.5rem);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.shots figure { margin: 0; }

.shots img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 20px;
  border: 6px solid var(--moss-deep);
  box-shadow: 0 12px 30px rgba(22, 28, 18, 0.18);
  margin-bottom: 1.1rem;
}

/* The gallery is also used for plain captured figures, not only the
   etusivu's h3+p cards. */
.shots figcaption {
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin-top: -0.6rem;
}

.shots h3 {
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.35rem;
}

.shots p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

/* the two without a capture: a ruled list, quieter than the row above */

.featlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  gap: 0 clamp(2rem, 5vw, 4rem);
}

.featlist li {
  padding: 1.2rem 0;
  border-top: 1px solid var(--rule);
}

.featlist h3, .steps h3 {
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.35rem;
}

.featlist p, .steps p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
  max-width: 30rem;
}

/* ---- steps: a real sequence, so it is numbered ---------------------- */

.steps ol {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: 1.6rem 2.2rem;
}

.steps li {
  counter-increment: step;
  border-top: 2px solid var(--ink);
  padding-top: 1rem;
}

.steps li::before {
  content: counter(step);
  font-family: var(--serif);
  font-size: 1.9rem;
  line-height: 1;
  color: var(--gold-deep);
  display: block;
  margin-bottom: 0.5rem;
}

/* ---- euro band ------------------------------------------------------- */

/* The dark bands and the pull-quote carry their own air, since --band-y is
   sized for the light bands that sit against each other. */
.euro {
  position: relative;
  background: var(--humus);
  color: var(--on-dark);
  padding-block: clamp(3.5rem, 8vw, 5.5rem);
}

.euro-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
  gap: clamp(1.5rem, 4vw, 4rem);
}

.euro h2 { margin: 0; }
.euro-body p { color: var(--moss-soft); max-width: var(--measure); margin: 0 0 1rem; }
.euro-body p:last-child { margin-bottom: 0; }

/* ---- privacy --------------------------------------------------------- */

/* This used to be a centred pull-quote. A slogan is the weakest thing a
   privacy section can say, so the four claims it was gesturing at do the
   work instead: each one is specific enough to be checked. */
.privacy { padding-block: clamp(3.5rem, 8vw, 5.5rem); }

.privacy-lead {
  font-family: var(--serif);
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0 0 clamp(1.75rem, 3vw, 2.5rem);
}

.facts {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(23rem, 100%), 1fr));
  column-gap: clamp(2rem, 5vw, 4rem);
  border-bottom: 1px solid var(--rule);
}

.fact-row {
  display: grid;
  grid-template-columns: minmax(0, 8rem) minmax(0, 1fr);
  gap: 0.3rem 1.4rem;
  align-items: baseline;
  padding: 0.9rem 0;
  border-top: 1px solid var(--rule);
}

.facts dt { font-weight: 600; font-size: 0.95rem; }

.facts dd {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* ---- footer ---------------------------------------------------------- */

.foot {
  position: relative;
  background: var(--humus);
  color: var(--moss-soft);
}

.foot-inner { padding-top: clamp(2.5rem, 6vw, 4rem); padding-bottom: clamp(2.5rem, 6vw, 4rem); }

.foot-cta-line {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
  margin: 0 0 1.6rem;
}

.foot-note {
  font-size: 0.9rem;
  max-width: var(--measure);
  margin: 0 0 1.6rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--moss);
}

.foot-small { font-size: 0.85rem; margin: 0; }
.foot-small a { color: var(--moss-soft); }

/* ---- narrow screens -------------------------------------------------- */

@media (max-width: 760px) {
  .hero-inner, .euro-inner { grid-template-columns: 1fr; }
  .key-row, .fact-row { grid-template-columns: 1fr; }
  .key-row .kausi { grid-column: 1; }

  /* Buy back enough height that the phone clears the fold rather than
     showing as a cropped sliver. */
  .hero-inner { padding-top: 3rem; }
  .hero-copy { padding-bottom: 1.75rem; }
  .hero h1 { font-size: 2.4rem; margin-bottom: 1rem; }
  .lede { font-size: 1.0625rem; margin-bottom: 1.5rem; }
  .hero-shot { max-width: 15rem; }
}

/* ---- motion: one orchestrated arrival, and nothing else -------------- */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }

  .hero-copy, .hero-shot { animation: rise 700ms ease-out both; }
  .hero-shot { animation-delay: 120ms; }

  @keyframes rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
  }
}
