/* ------------------------------------------------------------------
   Luxury Basecamp Levi — site styles
   One stylesheet for the whole site. No frameworks, no build step.

   Brand palette (from the brand theme):
     Midnight Blue  #0B1622 / #10202F
     Gold Accent    #C8A96A
     Snow White     #F4F7FA

   Display face: Cormorant Garamond 500 + 500 italic, latin subset, self-hosted
   (assets/fonts/, OFL.txt beside them). Only for h1, h2 and the display
   elements listed under "type"; h3, body text and labels stay on system fonts
   (the sans: a second serif under a Cormorant h2 read as a mismatch).
   The latin subset has no right arrow (U+2192): keep &rarr; out of display text.
   ------------------------------------------------------------------ */

@font-face {
  font-family: "Cormorant Garamond";
  src: url("fonts/cormorant-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("fonts/cormorant-500i.woff2") format("woff2");
  font-weight: 500; font-style: italic; font-display: swap;
}

:root {
  --midnight:      #0B1622;
  --midnight-soft: #10202F;
  --midnight-card: #14283A;
  --gold:          #C8A96A;
  --gold-bright:   #DCC08A;
  --snow:          #F4F7FA;
  --snow-dim:      #B9C6D3;
  --line:          rgba(200, 169, 106, 0.22);

  --serif: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino,
           "Book Antiqua", Charter, Georgia, serif;
  --sans:  -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto,
           "Helvetica Neue", Arial, sans-serif;
  --display: "Cormorant Garamond", var(--serif);

  --wide: 1140px;
  --text: 720px;

  /* The page gutter, widened to the notch / rounded corners when a phone is in
     landscape (the viewport meta has viewport-fit=cover). In portrait both are
     20px. A full-bleed strip inside .wrap uses
     margin-inline: calc(-1 * var(--pad-l)) calc(-1 * var(--pad-r)). */
  --pad-l: max(20px, env(safe-area-inset-left, 0px));
  --pad-r: max(20px, env(safe-area-inset-right, 0px));
}

*, *::before, *::after { box-sizing: border-box; }

/* Smooth scrolling only while an in-page link is under the pointer or finger (a chip,
   "See the gym", a facts link), so a page opened at #facts or #gym from another page
   lands at once instead of animating across several thousand pixels on load.
   (html:focus-within does not work for this: Chrome blurs the clicked link before
   the fragment scroll starts.) */
html { -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: no-preference) {
  html:has(a[href^="#"]:hover) { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--midnight);
  color: var(--snow);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; height: auto; }

a { color: var(--gold-bright); text-decoration-color: var(--line); text-underline-offset: 3px; }
a:hover { color: var(--snow); }
a, summary, label { -webkit-tap-highlight-color: rgba(200, 169, 106, 0.18); }

/* ---------- type ---------- */

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0 0 0.5em;
}
/* h3 is the system sans, not the system serif: ui-serif (New York, Palatino...)
   right under a Cormorant h2 was a second, clashing serif on every page. */
h3 { font-family: var(--sans); font-weight: 600; font-size: 1.08rem; line-height: 1.35; letter-spacing: 0; }

/* The display face. Cormorant has a small x-height, so h1/h2 run about 10-20%
   larger than the old system-serif sizes, with tighter leading. */
h1, h2,
.tagline, .num, .pull blockquote, .proof-quote blockquote, .score b, .reel h3,
.review blockquote, .price-value {
  font-family: var(--display);
  font-weight: 500;
}
h1, h2 { text-wrap: balance; }
h1 { font-size: clamp(2.5rem, 3.6vw + 1.4rem, 4.6rem); line-height: 1.04; letter-spacing: -0.015em; }
h2 { font-size: clamp(1.95rem, 2.2vw + 1.2rem, 3rem); line-height: 1.1; }
/* Long Finnish compounds must never push the page sideways at display sizes. */
:lang(fi) h1, :lang(fi) h2 { overflow-wrap: break-word; }
:lang(fi) h2 { hyphens: auto; }
/* No automatic hyphenation in an h1: it split the brand on the FI home ("Luxury Ba- /
   secamp Levi") at most desktop widths. A word too long for the line still wraps. */
:lang(fi) h1 { hyphens: manual; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

.lead { font-size: clamp(1.1rem, 0.35vw + 1rem, 1.25rem); line-height: 1.55; color: var(--snow); }
.muted { color: var(--snow-dim); }
.small { font-size: 0.92rem; }

/* Small gold label above a heading (was .page-head .kicker only). */
.kicker {
  font: 600 0.76rem/1.3 var(--sans);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 14px;
}

/* A single right-aligned onward link under a block ("... &rarr;"). */
p.more-link { margin: 18px 0 0; text-align: right; font-size: 0.95rem; }
p.more-link a { display: inline-block; padding: 11px 0; text-underline-offset: 5px; }
p.more-link a:hover { text-decoration-color: var(--gold); }

/* ---------- layout ---------- */

.wrap { width: 100%; max-width: var(--wide); margin: 0 auto; padding: 0 20px; }
/* Written out rather than through var(--pad-l): a browser without max()/env()
   drops these two lines and keeps the 20px above. */
.wrap {
  padding-left: max(20px, env(safe-area-inset-left, 0px));
  padding-right: max(20px, env(safe-area-inset-right, 0px));
}
.narrow { max-width: var(--text); }
/* A heading that follows body text (the story, guest info) gets air above it, so it
   reads as the start of what follows rather than the end of the paragraph before. */
.narrow > h2:not(:first-child) { margin-top: clamp(40px, 5vw, 64px); }

section { padding: clamp(64px, 7.5vw, 112px) 0; }
section.tight { padding: 40px 0; }
.alt { background: var(--midnight-soft); }
/* An in-page link (#gym, #facts ...) lands below the sticky header. */
main [id] { scroll-margin-top: 76px; }

hr.rule {
  border: 0; height: 1px; background: var(--line);
  margin: 48px 0;
}

/* ---------- header ---------- */

.site-header {
  border-bottom: 1px solid var(--line);
  background: rgba(11, 22, 34, 0.92);
  position: sticky; top: 0; z-index: 20;
  backdrop-filter: saturate(140%) blur(8px);
}
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; padding-top: 14px; padding-bottom: 14px;
}
.brand {
  font-family: var(--serif);
  font-size: 1.12rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--snow);
  text-decoration: none;
  white-space: nowrap;
}
.brand span { color: var(--gold); }

.head-right { display: flex; align-items: center; gap: 12px; order: 3; }

nav.main {
  display: flex; align-items: center; gap: 22px;
  flex-wrap: wrap;
  font-size: 0.93rem;
  order: 2;
}
nav.main a {
  color: var(--snow-dim);
  text-decoration: none;
  white-space: nowrap;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
}
nav.main a:hover { color: var(--snow); }
nav.main a[aria-current="page"] { color: var(--snow); border-bottom-color: var(--gold); }

.lang {
  font-size: 0.82rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--gold); text-decoration: none; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 12px;
}
.lang:hover { background: var(--gold); color: var(--midnight); }
.lang .short { display: none; }
@media (max-width: 1023px) {
  .brand { font-size: 0.98rem; letter-spacing: 0.05em; }
  .lang .full { display: none; }
  .lang .short { display: inline; }
  .lang { padding: 5px 10px; }
  /* The pill keeps its look; an invisible frame round it makes the tap target
     at least 44x44. */
  .lang { position: relative; }
  .lang::after { content: ""; position: absolute; inset: -6px -5px; }
  .site-header .wrap { gap: 10px; padding-top: 11px; padding-bottom: 11px; }
}
/* 320px wide (iPhone SE with Display Zoom): keep brand, pill and menu on one row. */
@media (max-width: 374px) {
  .brand { font-size: 0.82rem; letter-spacing: 0.03em; }
  .head-right { gap: 8px; }
}

/* Desktop "Check dates": the header is sticky, so booking is one click from
   anywhere. Phones have the sticky bottom bar instead; between the two there is
   no room in the header row. */
.btn.head-book { display: none; }
@media (min-width: 1100px) {
  .btn.head-book { display: inline-flex; padding: 6px 16px; font-size: 0.85rem; }
}
/* At 1100px the row is full (brand, six links, button, pill); a little less
   between the links leaves room for wider system fonts than macOS's. */
@media (min-width: 1100px) and (max-width: 1239px) {
  .site-header nav.main { gap: 17px; }
}

/* mobile menu: a checkbox, no JavaScript.
   The header collapses to the menu button below 1024px: between 821px and ~965px
   the six links, the brand and the pill no longer fit one row, and the header
   used to wrap to two rows (106px tall) on tablets such as an iPad Pro in portrait. */
.nav-toggle { position: absolute; opacity: 0; pointer-events: none; }
.nav-btn { display: none; }

@media (max-width: 1023px) {
  .nav-btn {
    display: flex; flex-direction: column; justify-content: center; gap: 5px;
    width: 44px; height: 44px; padding: 0 10px; cursor: pointer;
    border: 1px solid var(--line); border-radius: 3px;
  }
  .nav-btn span { display: block; height: 2px; background: var(--gold); border-radius: 2px; transition: transform 0.2s, opacity 0.2s; }
  .nav-toggle:checked ~ .head-right .nav-btn span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle:checked ~ .head-right .nav-btn span:nth-child(2) { opacity: 0; }
  .nav-toggle:checked ~ .head-right .nav-btn span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .nav-toggle:focus-visible ~ .head-right .nav-btn { outline: 2px solid var(--gold); outline-offset: 2px; }

  nav.main {
    display: none;
    order: 4; width: 100%; flex-direction: column; align-items: stretch; gap: 0;
    padding-top: 6px; margin-top: 4px; border-top: 1px solid var(--line);
  }
  nav.main a { padding: 13px 4px; border-bottom: 1px solid rgba(255,255,255,0.06); font-size: 1.02rem; }
  nav.main a[aria-current="page"] { border-bottom-color: rgba(255,255,255,0.06); color: var(--gold); }
  .nav-toggle:checked ~ nav.main { display: flex; }
}

/* ---------- page head ---------- */

.page-head { padding: clamp(64px, 8vw, 120px) 0 clamp(36px, 4.5vw, 64px); border-bottom: 1px solid var(--line); }
/* .kicker itself is global now (see "type"). */

/* ---------- buttons ---------- */

.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--sans); font-size: 0.95rem; font-weight: 600;
  letter-spacing: 0.02em;
  padding: 13px 24px; border-radius: 3px;
  text-decoration: none; border: 1px solid var(--gold);
  color: var(--midnight); background: var(--gold);
  transition: background 0.15s ease, color 0.15s ease;
}
.btn:hover { background: var(--gold-bright); color: var(--midnight); }
.btn.ghost { background: transparent; color: var(--gold); }
.btn.ghost:hover { background: var(--gold); color: var(--midnight); }

/* ---------- cards ---------- */

.grid { display: grid; gap: 22px; }
.grid.three { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
/* The apartment's "The practical side": eight cards. Two columns on a tablet; three
   on a desktop, where the last card (it points at the full list) spans two, so no
   ninth cell is left empty. */
@media (min-width: 701px) { .grid.practical { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) {
  .grid.practical { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid.practical > :last-child { grid-column: span 2; }
}

.card {
  background: var(--midnight-card);
  border: 1px solid rgba(255,255,255,0.05);
  border-radius: 4px;
  padding: 26px 24px;
}
.card h3 { color: var(--snow); margin-bottom: 0.4em; }
.card p { color: var(--snow-dim); font-size: 0.97rem; }

/* ---------- split (image + text) ----------
   Used by the apartment page only. The markup already puts each photo on its
   side: .split is text then photo (photo right), .split.reverse is photo then
   text (photo left), so the sections alternate. (An `order` rule used to push
   every reverse photo to the right too, so they never did.) The photos keep a
   portrait 4:5 frame; the old fixed height cut the 3:4 portraits to a letterbox.
   Phones: one column, every photo first and full bleed. */

.split {
  display: grid; align-items: center;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 32px clamp(34px, 5vw, 72px);
}
.split.reverse { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); }
.split > img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; max-height: 620px;
  object-fit: cover; border-radius: 2px; background: var(--midnight-card);
}
/* A text column that outgrows its photo (the kitchen, inventory open) keeps the
   photo in view, below the header and the apartment chip nav. */
@media (min-width: 701px) {
  .split > img {
    align-self: start; position: sticky; top: 140px;
    max-height: min(620px, calc(100vh - 180px));
  }
}
@media (max-width: 700px) {
  .split, .split.reverse { grid-template-columns: minmax(0, 1fr); }
  .split > img {
    order: -1; max-width: none; border-radius: 0;
    width: calc(100% + var(--pad-l) + var(--pad-r));
    margin-left: calc(-1 * var(--pad-l));
    max-height: 70vh; max-height: 70svh;
  }
}

/* ---------- lists ---------- */

ul.ticks { list-style: none; padding: 0; margin: 0 0 1.1em; }
ul.ticks li {
  position: relative; padding-left: 22px; margin-bottom: 8px; color: var(--snow-dim);
}
ul.ticks li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 7px; height: 7px; background: var(--gold); border-radius: 50%;
}

ul.plain, ol.plain { margin: 0 0 1.1em; padding-left: 20px; color: var(--snow-dim); }
ul.plain li, ol.plain li { margin-bottom: 6px; }

/* Numbered steps: the count is the point, so it gets the gold and a little air. */
ol.steps { padding-left: 24px; margin-bottom: 1.4em; }
ol.steps li { margin-bottom: 12px; padding-left: 6px; }
ol.steps li::marker { color: var(--gold); font-family: var(--serif); font-size: 1.05em; }

.cols-2 { columns: 2; column-gap: 34px; }
.cols-2 li { break-inside: avoid; }
@media (max-width: 640px) { .cols-2 { columns: 1; } }

/* ---------- details / FAQ ---------- */

/* The padding sits on the summary, not on details, so the whole row answers a tap
   (at least 48px tall), not just the line of text. */
details {
  border-bottom: 1px solid var(--line);
  padding: 0;
}
details summary {
  cursor: pointer; list-style: none;
  font-family: var(--sans); font-weight: 500; font-size: 1.05rem; line-height: 1.4; color: var(--snow);
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 14px 0; min-height: 48px;
}
details summary::-webkit-details-marker { display: none; }
details summary::after { content: "+"; color: var(--gold); font-size: 1.25rem; line-height: 1; }
details[open] summary::after { content: "–"; }
details .answer { padding: 0 0 18px; color: var(--snow-dim); }

/* ---------- the gym (build.py gym_block) ---------- */

.gym-head {
  display: grid; gap: 8px 56px; align-items: start;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
}
.gym-head h2 { margin: 0; }
@media (max-width: 800px) { .gym-head { grid-template-columns: 1fr; } .gym-head h2 { margin-bottom: 0.4em; } }

/* The confirmed kit (facts.py GYM_KIT). Qualified as ul.kit on purpose: the facts
   sheet's div.kit is a different block. */
ul.kit { list-style: none; margin: 24px 0 0; padding: 0; columns: 2; column-gap: 32px; }
ul.kit li { break-inside: avoid; padding: 10px 0; border-bottom: 1px solid var(--line); color: var(--snow); }
ul.kit li::before { content: "\2014"; color: var(--gold); margin-right: 12px; }
@media (max-width: 360px) { ul.kit { columns: 1; } }

.gym-grid {
  display: grid; gap: 6px; margin-top: clamp(36px, 5vw, 56px);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: clamp(150px, 16vw, 240px);
  grid-auto-flow: dense;
}
.gym-grid a { position: relative; display: block; overflow: hidden; background: var(--midnight-card); }
.gym-grid .big { grid-column: span 2; grid-row: span 2; }
.gym-grid .wide { grid-column: span 2; }
.gym-grid img { width: 100%; height: 100%; object-fit: cover; }
/* A gold hairline inside each frame, and a little weight at the bottom: the photos
   are bright white rooms, and this is what seats them on midnight. No grading. */
.gym-grid a::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(200, 169, 106, 0.16);
  background: linear-gradient(0deg, rgba(11, 22, 34, 0.45), rgba(11, 22, 34, 0) 40%);
}
.gym-grid a:focus-visible { outline-offset: -3px; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .gym-grid img { transition: transform 0.8s cubic-bezier(0.2, 0.6, 0.2, 1); }
  .gym-grid a:hover img { transform: scale(1.03); }
}
/* Phones: a sideways strip, the next photo peeking in. The files are 4:3, so the
   tiles are too and nothing is cropped away. */
@media (max-width: 700px) {
  .gym-grid {
    grid-auto-flow: column; grid-template-columns: none;
    grid-auto-columns: 84%; grid-auto-rows: auto;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: 20px;
    margin-inline: -20px; padding: 0 20px 10px;
    scrollbar-width: thin; scrollbar-color: var(--line) transparent;
  }
  .gym-grid a, .gym-grid .big, .gym-grid .wide { grid-column: auto; grid-row: auto; scroll-snap-align: start; }
  .gym-grid img { height: auto; aspect-ratio: 4 / 3; }
}

/* ---------- gallery (content_en2.py / content_fi2.py CHAPTERS) ----------
   Chapters of photos in a dense 4-column grid (2 on phones). One row is 0.7 of a
   column, so a portrait tile (.p, 1 x 2) shows at about 3:4, a landscape (.l, 1 x 1)
   and a feature (.f, 2 x 2) at about 4:3, and a portrait feature (.f.tall, 2 x 4)
   at about 3:4 again: every photo keeps close to its own shape. The row is derived
   from the column width (100cqw of .wrap), with a viewport fallback. Captions live in
   the lightbox and the alt text, so the grid itself is only photographs. */

.g-nav .n {
  margin-left: 7px; font-size: 0.76rem; color: var(--gold);
  font-variant-numeric: tabular-nums;
}
@media (hover: hover) { .g-nav a:hover .n { color: inherit; } }

/* Chapters sit close together (one page, one essay); the chip nav lands each one
   with its own top padding as air under the bar. */
.g-chapter { padding: clamp(28px, 3.5vw, 48px) 0 clamp(32px, 4vw, 56px); }
.g-chapter .wrap { container-type: inline-size; }
.g-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  margin: 0 0 clamp(18px, 2.4vw, 28px); padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.g-head h2 { margin: 0; }
.g-count {
  margin: 0; white-space: nowrap;
  font: 600 0.72rem/1.3 var(--sans); letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold);
}

.g-grid {
  --gap: 8px;
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-flow: dense;
  grid-auto-rows: calc((min(100vw, 1140px) - 40px - 3 * var(--gap)) / 4 * 0.7);
  grid-auto-rows: calc((100cqw - 3 * var(--gap)) / 4 * 0.7);
}
.g-grid figure { margin: 0; min-width: 0; }
.g-grid .p { grid-row: span 2; }
.g-grid .f { grid-column: span 2; grid-row: span 2; }
.g-grid .f.tall { grid-row: span 4; }
.g-grid a {
  position: relative; display: block; height: 100%; overflow: hidden;
  background: var(--midnight-card);
}
.g-grid img { width: 100%; height: 100%; object-fit: cover; }
/* The same gold hairline as the gym tiles. */
.g-grid a::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(200, 169, 106, 0.16);
}
.g-grid a:focus-visible { outline-offset: -3px; }
/* The floor plan is line art: shown whole, on a snow mat, never cropped. */
.g-grid .mat a { background: var(--snow); }
.g-grid .mat img { object-fit: contain; padding: 10px; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .g-grid img { transition: transform 0.8s cubic-bezier(0.2, 0.6, 0.2, 1); }
  .g-grid a:hover img { transform: scale(1.03); }
  .g-grid .mat a:hover img { transform: none; }
}
@media (max-width: 600px) {
  .g-grid {
    --gap: 6px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: calc((100vw - 40px - var(--gap)) / 2 * 0.7);
    grid-auto-rows: calc((100cqw - var(--gap)) / 2 * 0.7);
  }
  .g-grid .mat img { padding: 6px; }
}

/* CSS-only lightbox, one per photo (#v-<file stem>). Close and the backdrop go back
   to the chapter (#c-<slug>); prev/next stay inside it. The <img> is lazy, so a
   hidden lightbox fetches nothing until :target shows it. */
.lightbox {
  position: fixed; inset: 0; z-index: 50;
  background: #070E16;
  display: none; align-items: center; justify-content: center;
  padding: 64px 80px 92px;
  overscroll-behavior: contain;
}
.lightbox:target { display: flex; }
body:has(.lightbox:target) { overflow: hidden; }
/* While a lightbox is open, everything behind it is hidden from the tab order and
   the accessibility tree too (it is covered anyway): Tab cycles close, prev and next
   instead of reaching the booking buttons under the overlay. The lightboxes are
   direct children of <main>. Layout is untouched, so closing lands where it should. */
body:has(.lightbox:target) :is(.skip, .site-header, .site-footer, .sticky-cta, main > :not(.lightbox)) {
  visibility: hidden;
}
.lightbox .lb-bg { position: absolute; inset: 0; }
.lightbox img {
  position: relative; z-index: 1;
  width: auto; height: auto; max-width: min(1400px, 100%); max-height: 100%;
  object-fit: contain; border-radius: 2px; background: var(--midnight-card);
}
.lightbox .close, .lightbox .nav {
  position: absolute; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  color: var(--snow); text-decoration: none; line-height: 1;
}
.lightbox .close {
  top: max(8px, env(safe-area-inset-top, 0px));
  right: max(8px, env(safe-area-inset-right, 0px));
  width: 48px; height: 48px; border-radius: 50%; font-size: 2rem;
}
.lightbox .nav {
  top: 50%; transform: translateY(-50%);
  width: 52px; height: 64px; border-radius: 3px; font-size: 2.6rem;
  background: rgba(11, 22, 34, 0.55);
}
.lightbox .prev { left: max(14px, env(safe-area-inset-left, 0px)); }
.lightbox .next { right: max(14px, env(safe-area-inset-right, 0px)); }
@media (hover: hover) {
  .lightbox .nav:hover, .lightbox .close:hover { background: var(--gold); color: var(--midnight); }
}
.lightbox .lb-cap {
  position: absolute; left: 0; right: 0; margin: 0; padding: 0 80px;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  text-align: center; color: var(--snow); font-size: 0.95rem; line-height: 1.4;
}
.lightbox .lb-count {
  display: block; margin-top: 5px;
  font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold);
}
/* Phones: the photo takes the full width, and the arrows move to the bottom corners,
   in thumb reach, either side of the caption. */
@media (max-width: 700px) {
  .lightbox { padding: 60px 0 112px; }
  .lightbox img { max-width: 100%; border-radius: 0; }
  .lightbox .nav {
    top: auto; transform: none; width: 56px; height: 52px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  }
  .lightbox .prev { left: max(8px, env(safe-area-inset-left, 0px)); }
  .lightbox .next { right: max(8px, env(safe-area-inset-right, 0px)); }
  .lightbox .lb-cap { padding: 0 72px; font-size: 0.88rem; bottom: calc(22px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------- reviews ---------- */

.review-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 12px 24px; margin-bottom: 26px; }
.review-head h2 { margin: 0; }
/* "on Airbnb and Booking.com": a small-caps line under the display h2, like a
   kicker. Inline, a large sans run beside Cormorant sat on a different baseline,
   and on a phone its first word dangled at the end of the h2's line. */
.review-head h2 .muted {
  display: block; margin-top: 12px;
  font: 600 0.74rem/1.3 var(--sans); letter-spacing: 0.2em; text-transform: uppercase;
}
.rating { display: flex; flex-wrap: wrap; gap: 8px; }
.rating span {
  font-size: 0.8rem; letter-spacing: 0.06em; color: var(--gold);
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 11px; white-space: nowrap;
}
.rating span:first-child { background: var(--gold); color: var(--midnight); border-color: var(--gold); font-weight: 700; }
.reviews { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-bottom: 18px; }
.review { margin: 0; background: var(--midnight-card); border: 1px solid rgba(255,255,255,0.05); border-radius: 4px; padding: 22px 22px 18px; display: flex; flex-direction: column; gap: 12px; }
.review blockquote { margin: 0; font-size: 1.18rem; line-height: 1.42; color: var(--snow); }
.review blockquote::before { content: "\201C"; color: var(--gold); font-size: 1.6em; line-height: 0; margin-right: 4px; vertical-align: -0.3em; }
.review figcaption { font-size: 0.85rem; color: var(--snow-dim); margin-top: auto; }

/* ---------- price card ---------- */

.price-card {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  background: var(--midnight-card); border: 1px solid var(--line); border-radius: 4px;
  overflow: hidden; margin-bottom: 30px;
}
.price-main, .price-side { padding: 22px 24px; display: flex; flex-direction: column; gap: 4px; }
.price-main { border-right: 1px solid var(--line); }
.price-label { font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold); }
.price-value { font-size: 2.1rem; color: var(--snow); line-height: 1.1; }
.price-side .price-value { font-size: 1.55rem; }
/* Says what "Included" means. It sits inside the card on purpose: read apart from the
   two columns above it, "Included" invites the question "included in what?", and the
   answer -- one all-in number for the whole stay, quoted live for the guest's own
   dates -- is the only price claim this site makes. There is no figure here any more;
   see CLAUDE.md, "The headline price is gone". */
.price-note {
  grid-column: 1 / -1; margin: 0; padding: 14px 24px;
  border-top: 1px solid var(--line);
  font-size: 0.9rem; line-height: 1.55; color: var(--snow-dim);
}
.price-incl {
  grid-column: 1 / -1; list-style: none; margin: 0; padding: 14px 24px;
  border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 6px 22px;
  font-size: 0.9rem; color: var(--snow-dim);
}
.price-incl li::before { content: "✓"; color: var(--gold); margin-right: 7px; }
@media (max-width: 560px) {
  .price-card { grid-template-columns: 1fr; }
  .price-main { border-right: 0; border-bottom: 1px solid var(--line); }
}

/* ---------- on-this-page contents ---------- */

.toc { padding: 0 0 8px; }
.toc-label { font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); margin: 0 0 8px; }
.toc-links { display: flex; flex-wrap: wrap; gap: 8px; }
.toc-links a {
  font-size: 0.88rem; text-decoration: none; color: var(--snow-dim);
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px;
}
@media (max-width: 820px) { .toc-links a { padding: 10px 14px; } }
.toc-links a:hover { color: var(--midnight); background: var(--gold); border-color: var(--gold); }
h2[id] { scroll-margin-top: 84px; }

/* ---------- story banner ---------- */

.banner { padding-top: 34px; }
/* exterior.jpg is 16:9 and the banner is up to about 2.6:1: frame it low, so the lift
   station in front of the building (the ski-in/ski-out) stays in. */
.banner img { width: 100%; height: clamp(220px, 34vw, 420px); object-fit: cover; object-position: 50% 85%; border-radius: 4px; }

/* ---------- sticky mobile call to action ---------- */

.sticky-cta { display: none; }
@media (max-width: 700px) {
  .sticky-cta {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    display: flex; gap: 10px; padding: 10px 16px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    padding-left: max(16px, env(safe-area-inset-left, 0px));
    padding-right: max(16px, env(safe-area-inset-right, 0px));
    background: rgba(11,22,34,0.94); border-top: 1px solid var(--line);
    backdrop-filter: saturate(140%) blur(8px);
  }
  .sticky-cta .btn { flex: 1; justify-content: center; padding: 12px 10px; }
  /* The bar is 72px plus the home-indicator inset; reserve both, or the footer's
     last line ends up under it. */
  body.has-sticky { padding-bottom: 72px; padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------- contact block ---------- */

.contact-row { display: flex; flex-wrap: wrap; gap: 14px 34px; margin-top: 8px; }
.contact-row a { font-size: 1.02rem; }
@media (max-width: 820px) {
  .contact-row { gap: 4px 34px; }
  .contact-row a { display: inline-block; padding: 10px 0; }
}

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

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--midnight-soft);
  padding: 44px 0 34px;
  font-size: 0.92rem;
  color: var(--snow-dim);
}
.site-footer .cols {
  display: grid; gap: 28px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin-bottom: 30px;
}
/* h2 in the markup (the heading order no longer jumps from h2 to h4), styled as
   the small label it always was, never as a display heading. */
.site-footer .foot-h {
  font-family: var(--sans); font-size: 0.76rem; font-weight: 700; line-height: 1.3;
  letter-spacing: 0.16em; text-transform: uppercase; text-wrap: wrap;
  color: var(--gold); margin: 0 0 12px;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 7px; }
.site-footer a { color: var(--snow-dim); text-decoration: none; }
.site-footer a:hover { color: var(--snow); }
/* Touch: each link is a 44px row instead of a 17px line with 7px between. */
@media (max-width: 820px) {
  .site-footer li { margin-bottom: 0; }
  .site-footer li a { display: inline-block; padding: 10px 0; }
}
.site-footer .legal {
  border-top: 1px solid rgba(255,255,255,0.07);
  padding-top: 18px; display: flex; flex-wrap: wrap; gap: 8px 24px;
  justify-content: space-between; font-size: 0.85rem;
}

/* ---------- focus ---------- */

a:focus-visible, .btn:focus-visible, summary:focus-visible, .nav-btn:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 2px;
}

/* ---------- print (guest info) ---------- */

@media print {
  body { background: #fff; color: #111; font-size: 11.5pt; }
  .site-header, .site-footer, .sticky-cta, .toc, .actions, .split img, .banner { display: none !important; }
  section, .alt { background: none; padding: 12px 0; }
  h1, h2, h3, .lead, .card h3, .price-value { color: #111; }
  .muted, .small, ul.ticks li, ul.plain, .card p { color: #333; }
  .card { border: 1px solid #ccc; }
  a { color: #111; text-decoration: none; }
}

/* ---------- misc ---------- */

.skip {
  position: absolute; left: -9999px;
}
.skip:focus {
  left: 12px; top: 12px; position: fixed; z-index: 99;
  background: var(--gold); color: var(--midnight); padding: 10px 16px; border-radius: 3px;
}

@media (max-width: 560px) {
  body { font-size: 16px; }
  section { padding: 56px 0; }
  .site-header .wrap { gap: 10px; }
  nav.main { gap: 16px; font-size: 0.88rem; }
}

/* Reduced motion switches off animations too, not only transitions, so nothing a
   later section adds can slip past the setting. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ==================================================================
   HOME PAGE (index.html, fi/index.html)
   Written by build/content_en.py and content_fi.py. Nothing here is used by
   another page, and nothing above this block was changed for it.
   Top to bottom: cover, numbers ribbon, location mosaic + pull quote, the
   room reel, the gym (rail override), reviews (featured variant), "Not only
   winter", the closing band over the aurora.
   "Phones" below means 900px and narrower, where the cover photo comes first
   and the reel and the gym tiles become sideways rails.
   The only motion is the 1.03 hover zoom the gym tiles already have.
   ================================================================== */

/* ---------- home: cover ----------
   Phones: the photo first, at 4:5 (at most 72% of the screen), fading into
   midnight; the kicker and the h1 are pulled up onto its dark foot. The frame
   sits low in the photo and the fade starts late, so the lit tub (the subject,
   in the lower half of the file) stays bright instead of going under the fade.
   Desktop: text 5fr, photo 7fr (58vw, the `sizes` the preload uses), the photo
   bleeding off the right edge, the text column lined up with .wrap. */
.cover { display: flex; flex-direction: column; background: var(--midnight); }
.cover-photo {
  position: relative; order: -1; margin: 0; overflow: hidden;
  background: var(--midnight-soft);
  height: min(125vw, 72vh); height: min(125vw, 72svh);
  /* Whole pixels: a fractional height left a 1px grey row of the photo under the
     fade at the figure's foot (390x844). */
  height: round(down, min(125vw, 72svh), 1px);
}
.cover-photo img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 82%;
}
.cover-photo::after {
  content: ""; position: absolute; inset: 0 0 -1px 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(11, 22, 34, 0) 58%, rgba(11, 22, 34, 0.85) 86%, var(--midnight) 100%);
}
.cover-photo figcaption { display: none; }
.cover-text {
  position: relative; z-index: 1; margin-top: -52px;
  padding: 0 var(--pad-r) 8px var(--pad-l);
}
/* No orphan in the kicker on a narrow phone ("... THE FRONT / SLOPES"). */
.cover .kicker { text-wrap: balance; }
.cover h1 { margin-bottom: 0.22em; }
.cover .tagline {
  font-style: italic; color: var(--gold);
  font-size: clamp(1.3rem, 1.1vw + 0.95rem, 1.75rem); line-height: 1.3;
  margin: 0 0 1.1em;
}
.cover .lead { max-width: 34em; }
.cover-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 24px;
  margin-top: 28px;
}
.text-link {
  display: inline-block; padding: 11px 0;
  color: var(--snow-dim); text-decoration-color: var(--line); text-underline-offset: 5px;
}
.text-link:hover { color: var(--snow); text-decoration-color: var(--gold); }
/* Where the sticky bottom bar shows (700px and below) it carries the same two
   actions, always in view. The cover's own pair would only ever sit half behind it
   (a gold button peeking out under the gold bar on a 390x844 or 393x852 phone). */
@media (max-width: 700px) {
  .cover-actions { display: none; }
}

@media (min-width: 901px) {
  .cover {
    display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    min-height: min(88vh, 920px);
    min-height: min(calc(100svh - 65px), 920px);
    container-type: inline-size;
  }
  .cover-photo { grid-column: 2; grid-row: 1; order: 0; height: auto; }
  .cover-photo img { object-position: 50% 58%; }
  .cover-photo::after {
    background:
      linear-gradient(90deg, var(--midnight) 0%, rgba(11, 22, 34, 0) 18%),
      linear-gradient(0deg, rgba(11, 22, 34, 0.6) 0%, rgba(11, 22, 34, 0) 22%);
  }
  /* Bottom left, on the dark terrace floor: bottom right is the tub's lit badge. */
  .cover-photo figcaption {
    display: block; position: absolute; z-index: 1; left: 20%; right: auto; bottom: 16px; max-width: 76%;
    margin: 0;
    font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--snow-dim);
  }
  .cover-text {
    grid-column: 1; grid-row: 1; align-self: end; margin: 0;
    /* Lined up with .wrap: 100vw first, 100cqw (the cover's own width, which
       leaves out a desktop scrollbar) where container units exist. */
    padding: 72px clamp(24px, 4vw, 64px) clamp(48px, 8vh, 96px)
             max(20px, calc((100vw - var(--wide)) / 2 + 20px));
    padding-left: max(var(--pad-l), calc((100cqw - var(--wide)) / 2 + 20px));
  }
}

/* ---------- home: numbers ribbon ---------- */
.ribbon { padding: clamp(40px, 5vw, 72px) 0 clamp(56px, 6.5vw, 96px); }
ul.numbers {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
ul.numbers li {
  display: flex; flex-direction: column; gap: 12px; min-width: 0;
  padding: 26px 16px 24px 22px; border-left: 1px solid var(--line);
}
ul.numbers li:nth-child(4n+1) { border-left: 0; padding-left: 0; }
ul.numbers li:nth-child(n+5) { border-top: 1px solid var(--line); }
.num {
  font-size: clamp(2.6rem, 4.6vw, 3.8rem); line-height: 0.9; letter-spacing: -0.01em;
  color: var(--snow); font-variant-numeric: lining-nums;
}
.num small {
  font: 600 0.3em/1 var(--sans); letter-spacing: 0.08em; color: var(--gold);
  margin-left: 0.3em;
}
.lab { font-size: 0.9rem; line-height: 1.4; color: var(--snow-dim); overflow-wrap: break-word; }
.ribbon .more-link { text-wrap: balance; }
@media (max-width: 900px) {
  ul.numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  ul.numbers li { padding: 20px 10px 20px 18px; }
  ul.numbers li:nth-child(odd) { border-left: 0; padding-left: 0; }
  ul.numbers li:nth-child(n+3) { border-top: 1px solid var(--line); }
}

/* ---------- home: location mosaic (.m-loc) ----------
   One grid, source order text, a, b, pull quote. Phones: a (full bleed) first,
   then the text, b (narrower, to the right), the quote. Desktop, 12 columns:
   a | text on the first row, the quote | b on the second. */
.m-loc { display: grid; gap: 32px; }
.m-loc figure { margin: 0; }
.m-loc img { width: 100%; height: auto; object-fit: cover; border-radius: 2px; }
.m-loc .a { order: -1; margin-inline: calc(-1 * var(--pad-l)) calc(-1 * var(--pad-r)); }
.m-loc .a img { aspect-ratio: 4 / 5; max-height: 72vh; max-height: 72svh; object-position: 50% 68%; border-radius: 0; }
.m-loc .b { width: 72%; max-width: 420px; margin-left: auto; }
.m-loc .b img { aspect-ratio: 4 / 5; }
.m-loc .b figcaption {
  padding-top: 10px; text-align: right;
  font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--snow-dim);
}
.m-loc h2 { margin-bottom: 0.6em; }

dl.distances { margin: 26px 0 22px; border-top: 1px solid var(--line); }
dl.distances div {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
  gap: 2px 16px; padding: 11px 0; border-bottom: 1px solid var(--line);
}
dl.distances dt { color: var(--snow); }
dl.distances dd { margin: 0 0 0 auto; color: var(--snow-dim); text-align: right; }
.m-loc .text .small { margin-bottom: 0.6em; }

/* Pull quote: a guest's words, verbatim from REVIEWS (build.py). */
.pull { margin: 8px 0 0; text-align: center; }
.pull blockquote {
  margin: 0; font-style: italic; color: var(--snow);
  font-size: clamp(1.55rem, 1.6vw + 1.05rem, 2.35rem); line-height: 1.24;
  text-wrap: balance;
}
.pull blockquote::before {
  content: "\201C"; display: block; height: 0.5em;
  color: var(--gold); font-size: 2.3em; line-height: 1; font-style: normal;
}
.pull figcaption {
  margin-top: 18px; font-size: 0.72rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--snow-dim);
}

@media (min-width: 901px) {
  .m-loc {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: clamp(20px, 2.6vw, 32px); row-gap: clamp(36px, 4.5vw, 56px);
    align-items: start;
  }
  /* The aerial fills the height of the text beside it: 3:4 where the column is
     wide enough, a narrower centre crop of the same photo where it is not. */
  .m-loc .a { order: 0; grid-column: 1 / 8; grid-row: 1; margin: 0; align-self: stretch; }
  .m-loc .a img { height: 100%; max-height: none; aspect-ratio: 3 / 4; object-position: 50% 50%; border-radius: 2px; }
  .m-loc .text { grid-column: 8 / 13; grid-row: 1; padding-left: clamp(0px, 1.6vw, 20px); }
  .m-loc .pull { grid-column: 1 / 8; grid-row: 2; align-self: center; text-align: left; margin: 0; padding-right: clamp(0px, 3vw, 48px); }
  .m-loc .b { grid-column: 9 / 13; grid-row: 2; width: auto; max-width: none; margin: 0; }
}

/* ---------- home: the room reel ("What's inside") ----------
   3 x 2 on desktop. Phones: a sideways strip that snaps, the next card
   peeking in (44% wide on a tablet, 78% on a phone). */
.inside h2 { margin-bottom: clamp(28px, 3.5vw, 44px); }
.reel {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(40px, 4.5vw, 56px) clamp(18px, 2vw, 26px);
}
.reel-item { min-width: 0; }
.reel-item img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover;
  border-radius: 2px; background: var(--midnight-card);
}
.reel h3 { font-size: 1.55rem; line-height: 1.15; margin: 18px 0 8px; color: var(--snow); }
.reel p { color: var(--snow-dim); font-size: 0.97rem; margin-bottom: 0.6em; }
.reel p.reel-link { margin: 0; }
.reel-link a { display: inline-block; padding: 11px 0; }
@media (max-width: 900px) {
  .reel {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 44%;
    gap: 18px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: var(--pad-l) var(--pad-r);
    margin-inline: calc(-1 * var(--pad-l)) calc(-1 * var(--pad-r));
    padding: 0 var(--pad-r) 14px var(--pad-l);
    scrollbar-width: thin; scrollbar-color: var(--line) transparent;
  }
  .reel-item { scroll-snap-align: start; }
}
@media (max-width: 700px) {
  .reel { grid-auto-columns: 78%; gap: 14px; }
  .reel h3 { font-size: 1.4rem; }
}

/* ---------- home: the gym ----------
   build.py gym_block(), wrapped in div.home-gym on this page only. The block's
   own rules make it a rail at 700px and below; here the 701-900px range gets
   the same rail, two tiles and a peek wide, so every phone-and-tablet width
   on the home page swipes. */
@media (min-width: 701px) and (max-width: 900px) {
  .home-gym .gym-grid {
    grid-auto-flow: column; grid-template-columns: none;
    grid-auto-columns: 44%; grid-auto-rows: auto;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: var(--pad-l) var(--pad-r);
    margin-inline: calc(-1 * var(--pad-l)) calc(-1 * var(--pad-r));
    padding: 0 var(--pad-r) 10px var(--pad-l);
    scrollbar-width: thin; scrollbar-color: var(--line) transparent;
  }
  .home-gym .gym-grid a { grid-column: auto; grid-row: auto; scroll-snap-align: start; }
  .home-gym .gym-grid img { height: auto; aspect-ratio: 4 / 3; }
}

/* ---------- home: reviews, featured variant (build.py reviews_block featured=) ---------- */
.proof {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 36px clamp(32px, 5vw, 72px); align-items: center;
  margin: 10px 0 clamp(40px, 5vw, 64px);
}
.proof-quote { margin: 0; }
.proof-quote blockquote {
  margin: 0; color: var(--snow);
  font-size: clamp(1.6rem, 1.7vw + 1.05rem, 2.5rem); line-height: 1.22;
}
.proof-quote blockquote::before {
  content: "\201C"; display: block; height: 0.5em;
  color: var(--gold); font-size: 2.2em; line-height: 1;
}
.proof-quote figcaption {
  margin-top: 20px; font-size: 0.74rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--snow-dim);
}
.scores {
  display: flex; flex-direction: column; gap: 26px;
  border-left: 1px solid var(--line); padding-left: clamp(28px, 4vw, 56px);
}
.score { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.score b { font-size: clamp(3rem, 4.6vw, 4.4rem); line-height: 0.9; color: var(--gold); font-variant-numeric: lining-nums; }
.score span, .honours {
  font-size: 0.74rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--snow-dim);
}
.honours { margin: 0; color: var(--gold); }
@media (max-width: 900px) {
  .proof { grid-template-columns: minmax(0, 1fr); }
  .scores {
    flex-direction: row; flex-wrap: wrap; gap: 22px 44px;
    border-left: 0; padding-left: 0; border-top: 1px solid var(--line); padding-top: 26px;
  }
  .honours { flex-basis: 100%; }
}

/* ---------- home: "Not only winter" ----------
   summer.jpg is only 599px wide, so it stays a 4:5 portrait of at most
   420 x 525 and is never blown up on a 1x screen. It is framed from the
   bottom, so the grill and the chair lead rather than the brick wall above. */
.winter {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 36px clamp(32px, 5vw, 72px); align-items: center;
}
.winter figure { margin: 0; justify-self: end; width: 100%; max-width: 420px; }
.winter img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; max-height: 560px;
  object-fit: cover; object-position: 50% 100%; border-radius: 2px;
}
@media (max-width: 900px) {
  .winter { grid-template-columns: minmax(0, 1fr); }
  .winter figure { justify-self: start; max-width: 360px; }
}

/* ---------- home: closing band over the aurora (CTA_HOME) ----------
   <picture>: aurora-wide.jpg in a landscape window, the portrait
   northern-lights.jpg in a portrait one. Landscape: the text sits in the
   middle, darkened just behind it, and the aurora is left bright round it;
   the top and bottom fade into the midnight-soft neighbours. Portrait: the
   photo starts a third of the way down, so the heading and the lead sit on
   plain midnight and the aurora glows behind the buttons. The ghost buttons
   get a dark fill so their gold text never sits on bright green.
   Other pages keep the plain CTA. */
.band.cta {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: min(80vh, 740px); min-height: min(80svh, 740px);
  padding: clamp(88px, 11vw, 136px) 0;
  background: var(--midnight);
}
.band.cta picture { position: absolute; inset: 0; z-index: -2; }
.band.cta img {
  width: 100%; height: 100%; max-width: none;
  object-fit: cover; object-position: 50% 42%;
}
.band.cta::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(ellipse 46% 42% at 50% 52%, rgba(11, 22, 34, 0.7) 0%, rgba(11, 22, 34, 0.5) 60%, rgba(11, 22, 34, 0.14) 100%),
    linear-gradient(180deg, var(--midnight-soft) 0%, rgba(16, 32, 47, 0) 18%, rgba(16, 32, 47, 0) 80%, var(--midnight-soft) 100%);
}
.band.cta .wrap { position: relative; }
.band.cta h2 { font-size: clamp(2.3rem, 2.6vw + 1.5rem, 3.6rem); }
.band.cta h2, .band.cta .lead { text-shadow: 0 1px 3px rgba(11, 22, 34, 0.6), 0 0 26px rgba(11, 22, 34, 0.85); }
.band.cta .lead { max-width: 34em; margin-left: auto; margin-right: auto; }
.band.cta .actions { justify-content: center; }
.band.cta .btn.ghost { background: rgba(11, 22, 34, 0.72); }
.band.cta .btn.ghost:hover { background: var(--gold); }
@media (orientation: portrait) {
  .band.cta {
    align-items: flex-start;
    min-height: max(640px, min(150vw, 92vh)); min-height: max(640px, min(150vw, 92svh));
    padding-top: clamp(64px, 12vw, 112px);
  }
  .band.cta picture { top: 30%; }
  .band.cta img { object-position: 50% 20%; }
  .band.cta::before {
    background: linear-gradient(180deg, var(--midnight) 0%, var(--midnight) 30%, rgba(11, 22, 34, 0.4) 44%, rgba(11, 22, 34, 0.08) 62%, rgba(11, 22, 34, 0.35) 88%, var(--midnight-soft) 100%);
  }
}

@media print {
  .cover-photo, .m-loc figure, .reel-item img, .home-gym .gym-grid, .band.cta picture { display: none !important; }
  .cover-text { margin: 0; padding: 0; }
  .reel { display: block; }
  .band.cta { min-height: 0; padding: 12px 0; text-align: left; }
  .band.cta h2, .band.cta .lead { text-shadow: none; }
}

/* ==================================================================
   APARTMENT PAGE (apartment.html, fi/huoneisto.html)
   Written by build/content_en.py and content_fi.py (apartment / huoneisto),
   plus the facts sheet markup of build/facts.py fact_sheet(). Nothing here is
   used by another page. Top to bottom: the split page head, the sticky chip
   nav, the sauna diptych, the facts & equipment sheet. .split is under
   "split" above; the gym is build.py gym_block(), under "the gym".
   Site header heights this block relies on (measured by the GLOBAL stage):
   67px below 1024px, 61px at 1024-1099px, 65px from 1100px.
   ================================================================== */

/* ---------- apartment: page head ----------
   The laid dining table (dining.jpg, a 3:4 portrait). Phones and tablets: the
   photo first, full bleed, cropped to 4:3 round the glasses and plates, then
   the words. Desktop: words 7fr (the h1 on two lines), photo 5fr at 4:5. The
   photo is the page's LCP image: fetchpriority="high", never lazy
   (content_en.py _eager). */
.apt-head { padding-top: 0; }
.apt-head .wrap { display: flex; flex-direction: column; }
.apt-head-photo {
  order: -1; margin: 0 0 clamp(28px, 5vw, 44px);
  margin-left: calc(-1 * var(--pad-l)); margin-right: calc(-1 * var(--pad-r));
}
.apt-head-photo img {
  width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover;
  object-position: 50% 64%;
  max-height: 62vh; max-height: 62svh;
  background: var(--midnight-card);
}
.apt-head-text .lead { max-width: 34em; }
@media (min-width: 901px) {
  .apt-head { padding-top: clamp(48px, 5.5vw, 88px); }
  .apt-head .wrap {
    display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: clamp(36px, 5vw, 72px); align-items: end;
  }
  .apt-head-text { padding-bottom: 8px; }
  .apt-head-photo { order: 0; margin: 0; }
  .apt-head-photo img {
    aspect-ratio: 4 / 5; object-position: 50% 50%;
    max-height: min(640px, calc(100vh - 200px)); border-radius: 2px;
  }
}

/* ---------- apartment: chip nav ----------
   Sticky just under the site header, tucked 1px beneath its border. Each pill
   is 32px to the eye and 44px to a thumb: ::before draws the pill inside a
   taller link. Where the seven chips don't fit, the row scrolls sideways and
   fades out at the right edge. Any page can reuse it: nav.chipnav > .wrap > a. */
.chipnav {
  position: sticky; top: 66px; z-index: 15;
  background: rgba(11, 22, 34, 0.94);
  -webkit-backdrop-filter: saturate(140%) blur(8px);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 1024px) { .chipnav { top: 60px; } }
@media (min-width: 1100px) { .chipnav { top: 64px; } }
.chipnav .wrap {
  display: flex; gap: 4px; padding-top: 2px; padding-bottom: 2px;
  overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
}
.chipnav .wrap::-webkit-scrollbar { display: none; }
.chipnav .wrap::after { content: ""; flex: 0 0 24px; }
.chipnav a {
  position: relative; z-index: 0; flex: none;
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 15px;
  font-size: 0.86rem; white-space: nowrap;
  color: var(--snow-dim); text-decoration: none;
}
.chipnav a::before {
  content: ""; position: absolute; z-index: -1; inset: 6px 0;
  border: 1px solid var(--line); border-radius: 999px;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.chipnav a:focus-visible { outline-offset: -3px; border-radius: 999px; }
.chipnav a:active::before { background: rgba(200, 169, 106, 0.18); }
@media (hover: hover) {
  .chipnav a:hover { color: var(--midnight); }
  .chipnav a:hover::before { background: var(--gold); border-color: var(--gold); }
}
@media (max-width: 900px) {
  .chipnav .wrap {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
  }
}
/* A chapter link lands exactly under the chip nav (its top + its 49px), so the
   chapter starts flush below the bar, whatever the header measures. */
.chipnav ~ [id] { scroll-margin-top: 115px; }
@media (min-width: 1024px) { .chipnav ~ [id] { scroll-margin-top: 109px; } }
@media (min-width: 1100px) { .chipnav ~ [id] { scroll-margin-top: 113px; } }

/* ---------- apartment: sauna and hot tub ----------
   sauna.jpg and jacuzzi.jpg edge to edge (the pair capped at 1600px wide),
   a 4px midnight seam between them, flush with the top of the section; the
   words follow in two columns. Phones: the two photos stack. */
.sauna { padding-top: 0; }
.diptych {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4px;
  max-width: 1600px; margin: 0 auto; background: var(--midnight);
}
.diptych img {
  width: 100%; max-width: none; object-fit: cover;
  height: min(62.5vw, 78vh, 760px); height: min(62.5vw, 78svh, 760px);
  background: var(--midnight-card);
}
.diptych img:first-child { object-position: 50% 62%; }  /* benches and heater */
.diptych img:last-child { object-position: 50% 42%; }   /* the tub and the lit slope */
.apt-chapter {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 8px clamp(32px, 5vw, 72px); align-items: start;
  margin-top: clamp(48px, 6vw, 88px);
}
.apt-chapter h2 { margin: 0; }
/* House rules sit in the normal .wrap, lined up with the sections around them;
   only the text keeps a reading width. */
#rules .wrap > * { max-width: var(--text); }
.apt-chapter p { max-width: 38em; }
@media (max-width: 800px) {
  .apt-chapter { grid-template-columns: minmax(0, 1fr); }
  .apt-chapter h2 { margin-bottom: 0.4em; }
}
@media (max-width: 700px) {
  .diptych { grid-template-columns: minmax(0, 1fr); }
  .diptych img { height: auto; aspect-ratio: 4 / 5; max-height: 70vh; max-height: 70svh; }
}

/* "The space" shows living-room-r.jpg: living-room.jpg cropped from the right and
   below the ceiling (the pendant lamp, the TV and posters, the end of the sofa).
   The full photo's left window shows a figure, likely the photographer reflected in
   the glass, and its top edge a bright half-disc ceiling lamp; the crop leaves both
   out. The file is shown whole, at its own 1040:1100, so nothing else is cropped. */
.split > img.frame-right { aspect-ratio: 1040 / 1100; object-position: 50% 50%; max-height: none; }

/* The kitchen inventory sits in the text column of a .split; below 1000px that
   column is too narrow for two columns of it. */
@media (max-width: 1000px) { .split .cols-2 { columns: 1; } }

/* ---------- apartment: facts & equipment (build/facts.py fact_sheet) ----------
   Dark, like a hotel fact card: the key facts as a spec list with gold
   small-caps terms, then the equipment groups in columns (1 on phones, 2 on
   tablets and small desktops, 3 from 1100px), every list always open so
   find-in-page lands on "hair dryer". The floor plan sits on a small snow mat
   (the drawing has a white ground) and stays in view beside the lists on a
   desktop. Tablets: plan beside the key facts, the groups full width below.
   Two elements carry the class "kit": this DIV.kit and the gym's UL.kit, so
   every rule here says div.kit. */
.facts-head { max-width: 40em; margin-bottom: clamp(36px, 4.5vw, 60px); }
.facts-head h2 { margin-bottom: 0.35em; }
.facts-grid {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px;
  align-items: start;
}
.plan { margin: 0; max-width: 340px; }
.plan img {
  width: 100%; height: auto; padding: 16px; border-radius: 3px;
  background: var(--snow); object-fit: contain;
}
.plan figcaption {
  padding-top: 12px; font-size: 0.72rem; line-height: 1.5;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--snow-dim);
}

dl.spec {
  display: grid; grid-template-columns: max-content minmax(0, 1fr);
  margin: 0; border-top: 1px solid var(--line);
}
dl.spec dt, dl.spec dd {
  margin: 0; padding: 13px 0; line-height: 24px;
  border-bottom: 1px solid var(--line);
}
dl.spec dt {
  padding-top: 14px; padding-right: 28px;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--gold);
}
dl.spec dd { font-size: 1rem; color: var(--snow); }

div.kit { columns: 1; margin-top: clamp(40px, 5vw, 60px); }
.kit-group { break-inside: avoid; margin: 0 0 30px; }
.kit-group h3 {
  margin: 0; padding-bottom: 10px; border-bottom: 1px solid var(--line);
  font: 600 0.72rem/1.4 var(--sans); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--gold);
}
.kit-group ul { list-style: none; margin: 0; padding: 0; }
.kit-group li {
  padding: 8px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.93rem; line-height: 1.45; color: var(--snow-dim);
}
.kit-group li a { color: var(--gold-bright); text-underline-offset: 3px; }
.kit-group li a:hover { color: var(--snow); }

/* Phones: key facts stacked, term above value. */
@media (max-width: 560px) {
  dl.spec { grid-template-columns: minmax(0, 1fr); }
  dl.spec dt { padding: 14px 0 0; border-bottom: 0; line-height: 1.4; }
  dl.spec dd { padding-top: 3px; }
}
@media (min-width: 701px) {
  div.kit { columns: 2; column-gap: 36px; }
}
/* Tablets: plan beside the key facts, the equipment groups full width below. */
@media (min-width: 701px) and (max-width: 900px) {
  .facts-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 0 36px; }
  .facts-body { display: contents; }
  .plan { grid-column: 1; grid-row: 1; max-width: none; }
  dl.spec { grid-column: 2; grid-row: 1; }
  div.kit { grid-column: 1 / -1; }
}
/* Desktop: the plan stays in view while the lists scroll past. */
@media (min-width: 901px) {
  .facts-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: clamp(40px, 5vw, 64px); }
  .plan { position: sticky; top: 140px; max-width: none; }
  .plan img { max-height: calc(100vh - 230px); }
}
@media (min-width: 1100px) {
  div.kit { columns: 3; column-gap: 28px; }
}

@media print {
  .apt-head-photo, .chipnav, .diptych, .plan { display: none !important; }
  .apt-head .wrap { display: block; }
  .sauna { padding-top: 12px; }
  .apt-chapter, .facts-grid { display: block; }
  dl.spec dt, .kit-group h3 { color: #333; }
  dl.spec dd, .kit-group li { color: #111; }
  div.kit { columns: 2; }
}
