/* Hallmark · genre: editorial · macrostructure: Marquee Hero · theme: Garden
 * enrichment: E8 hero photography (full-bleed plate, below the fold)
 * nav: N9 edge-aligned minimal · footer: Ft1 mast-headed
 *
 * ── 2026-08-14 · enrichment pass ────────────────────────────────
 * Macrostructure, theme, nav and footer are deliberately UNCHANGED —
 * this pass added the business's own photography to the existing
 * build, so the diversification rule does not apply.
 *
 * · Plate (E8): kuvat/kai-hoitohuone.jpg, full-bleed, replaces the
 *   rule-thick divider. Width-driven height, not vh — a vh-based band
 *   letterboxed a 3:2 source to 3.8:1 and lost both face and hands.
 * · Gift card: kuvat/lahjakortti.jpg. Lahjakortit was promoted from a
 *   clause inside Maksutavat to its own column; the band is 3-up above
 *   68rem so a tall figure no longer leaves a tall gap beside it.
 * · Photo tone: saturate(0.92) via --photo-tone. No parallax, no Ken
 *   Burns, no scroll-scrub — motion primitives unchanged at two.
 * · FIXED (pre-existing): at 320 px the nav wordmark + CTA needed
 *   348 px of row and got 305, so overflow-x: clip was amputating the
 *   primary CTA with no scrollbar to reveal it. The previous stamp
 *   claimed 320 px passed; it did not.
 * · Real contact data recovered from the supplied images and wired in;
 *   schema.org locality corrected Turku → Littoinen, Turku reach moved
 *   to areaServed. Four values remain .puuttuu — genuinely unknown.
 * H1 Marquee knobs: size=xl, alignment=left-bias, underlay=rule-below
 * F3 Spec-sheet knobs: columns=3, rules=every-row, numbers=tabular
 * T4 Stat-strip knobs: layout=2-up, weight=display, qualifier=under
 * C1 Chip knobs: shape=slab, density=spacious, adornment=arrow
 * C4 Sticky-bar knobs: reveal=after-fold, anchored=bottom, shadow=hairline
 * Ft1 knobs: wordmark=display-2xl, tagline=roman-body, links=inline
 * tone: soft-editorial · audience: local Turku clients · use: drive bookings
 * theme axes: light paper / roman-serif display / chromatic-green accent
 * Hallmark · pre-emit critique: P5 H5 E5 S4 R5 V5
 *
 * slop test: 58/58 · contrast: pass (40–41, computed sRGB via canvas,
 *   all new text nodes; lowest .gift__cap 4.92:1 against 4.5 floor)
 * nav/footer/hero: pass (42–45) · honest: pass (46) · chrome: pass (47)
 * tokens: pass (48) · responsive: pass (49) · icons: pass (30)
 * mobile: pass (34, 49, 50–57) — re-verified rendered at 320/375/414/768
 *   in same-origin iframes; zero horizontal overflow, zero clickable
 *   text wrapping to two line boxes (measured by Range.getClientRects)
 */

/* ─────────────────────────────────────────────────────────────
   Base
   ───────────────────────────────────────────────────────────── */

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

/* clip, never hidden — hidden makes a scroll container and kills sticky */
html, body { overflow-x: clip; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink-2);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--lh-normal);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  padding-inline: max(0px, env(safe-area-inset-left));
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-style: var(--display-style);   /* roman — never italic on a header */
  color: var(--color-ink);
  margin: 0;
  /* Finnish compounds are long: jäsenkorjaus, kinesioteippaus,
     hyvinvointietuudet. Let them break inside the word rather than
     push the layout past the viewport. */
  overflow-wrap: anywhere;
  min-width: 0;
}

p, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a { color: inherit; }

/* Inline text link — phone numbers, the booking address. Underlined
   rather than coloured, because on a green-inked page an accent-green
   link is nearly invisible against the body colour. The underline is
   the affordance; hover moves the colour, not the decoration. */
.link {
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: 0.22em;
  /* muted, not rule-2: rule-2 measures 2.88:1 on this paper, which is
     too faint for the mark that carries the affordance. muted clears
     5.65:1 and still sits below the ink of the text it underlines. */
  text-decoration-color: var(--color-muted);
  overflow-wrap: anywhere;   /* suomalainenkai.avoinna24.fi at 320 px */
  transition: color var(--dur-micro) var(--ease-out),
              text-decoration-color var(--dur-micro) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .link:hover {
    color: var(--color-accent);
    text-decoration-color: var(--color-accent);
  }
}

b { font-weight: 700; }

/* Focus is instant and always visible. Never transitioned. */
:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-input);
}

.skip {
  position: absolute;
  left: var(--space-md);
  top: var(--space-md);
  z-index: var(--z-modal);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-paper);
  border: var(--rule-fine) solid var(--color-ink);
  border-radius: var(--radius-input);
  font-size: var(--text-sm);
  white-space: nowrap;
  transform: translateY(-200%);
}
.skip:focus-visible { transform: none; }

/* Placeholder marker. Every one of these is a fact Hallmark refused to
   invent. Fill the value in, then delete the class.

   Styled for a client-facing preview, not for the workshop: the dashed
   box and the "täydennä:" prefix read as debug output to someone who
   didn't build the page. An em-dash is how a printed table has always
   said "no value here" — it reads as a question waiting on an answer
   rather than as something broken. muted clears 5.65:1, so the row is
   still legible rather than greyed into illegibility. */
.puuttuu {
  color: var(--color-muted);
  font-size: 0.95em;
}

.puuttuu::before {
  content: "— ";
  /* The dash is the mark that carries the meaning, so it is real text
     in a real colour — not a decorative hairline nobody can see. */
  color: var(--color-muted);
}

/* ─────────────────────────────────────────────────────────────
   Nav · N9 Edge-aligned minimal
   Wordmark hard-left, one CTA hard-right, empty middle.
   Adding links to the middle turns this into N1 with extra steps.
   ───────────────────────────────────────────────────────────── */

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md) var(--page-gutter);
  background: var(--color-paper);
}

.nav__mark {
  display: grid;
  gap: var(--space-3xs);
  text-decoration: none;
  line-height: var(--lh-tight);
}

.nav__kicker {
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

.nav__name {
  font-family: var(--font-display);
  font-size: var(--text-md);
  color: var(--color-ink);
  white-space: nowrap;
}

/* At 320 px the wordmark (155 px, nowrap) and the chip (137 px, nowrap)
   need 348 px of row and get 305. Neither flex item can shrink, so the
   chip used to run under the right edge and be silently amputated by
   the root overflow-x: clip — the CTA lost its arrow and part of its
   border with no scrollbar to reveal the damage.

   The row is bought back rather than the CTA dropped: booking is the
   page's one job, and the sticky bar only appears after the fold, so
   hiding the chip here would leave the smallest phones with no visible
   action on load. Tighter gap, tighter chip padding, no arrow, and one
   step down on the wordmark. min-height: 44px on .chip is untouched,
   so the tap target stays full size. */
@media (max-width: 23rem) {
  .nav { gap: var(--space-xs); }

  .nav__name { font-size: var(--text-base); }

  .nav__cta { padding-inline: var(--space-sm); }

  /* Decorative and already aria-hidden — the first thing to go. */
  .nav__cta span { display: none; }
}

/* Sticky only from the layout breakpoint up. Below it the mobile
   sticky bar carries the CTA — one persistent action per viewport. */
@media (min-width: 60rem) {
  .nav {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky-nav);
    border-bottom: var(--rule-hair) solid var(--color-rule);
  }
}

/* ─────────────────────────────────────────────────────────────
   Chip · C1 Outlined chip — slab, spacious, arrow
   ───────────────────────────────────────────────────────────── */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 44px;
  padding: var(--space-sm) var(--space-lg);
  border: var(--rule-fine) solid var(--color-ink);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-ink);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;          /* an affordance is a one-line object */
  transition:
    border-color var(--dur-micro) var(--ease-out),
    background-color var(--dur-micro) var(--ease-out),
    transform var(--dur-micro) var(--ease-out);
}

.chip--lg {
  font-size: var(--text-base);
  padding: var(--space-md) var(--space-xl);
}

/* One signal on hover — the chip lights up. Not a lift AND a scale
   AND a shadow AND a colour change. Text stays ink so contrast holds. */
@media (hover: hover) and (pointer: fine) {
  .chip:hover {
    border-color: var(--color-accent);
    background: var(--tint-moss);
  }
}

.chip:active { transform: translateY(1px); }

/* Present in code so the state exists the day this is wired to a
   real booking system and a slot can be unavailable. */
.chip[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  border-color: var(--color-rule);
  pointer-events: none;
}

/* ─────────────────────────────────────────────────────────────
   Hero · H1 Marquee — the fold is one statement, bottom-left.
   No subhead, no CTA. That withholding is the archetype.
   ───────────────────────────────────────────────────────────── */

.hero {
  min-height: min(72dvh, 40rem);
  display: grid;
  align-content: end;
  gap: var(--space-md);
  /* Bottom-heavy: the marquee is bottom-aligned, and weighting the
     lower padding pulls the fold into the next section's rhythm
     instead of letting it float. */
  padding: var(--space-2xl) var(--page-gutter) var(--space-3xl);
  max-width: var(--page-max);
  margin-inline: auto;
  width: 100%;
}

.hero__display {
  font-size: var(--text-marquee);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-display);
  max-width: 16ch;
}

/* At 320–360 px "jäsenkorjaus." is wider than the column, and
   overflow-wrap: anywhere would break it as "jäsenkorja / us."
   Step the marquee down so the compound stays whole. */
@media (max-width: 22.5rem) {
  .hero__display { font-size: var(--text-2xl); }
}

/* Body face, not the mono outlier. The outlier holds two slots only —
   the nav kicker and the hinnasto figures — and a third would make it
   a de facto third body font. */
.hero__place {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

/* The one hard divider between the fold and everything after it.
   Retained as a utility — the plate now performs this job on the
   home page, but the rule is the fallback for any page without a
   photograph. */
.rule-thick {
  height: 2px;
  margin: 0;
  border: 0;
  background: var(--color-rule-2);
}

/* ─────────────────────────────────────────────────────────────
   Plate · E8 Hero photography — full-bleed, below the fold

   The plate is the divider. It runs edge to edge while every
   other band is held to --page-max, so the photograph reads as a
   register change rather than as a card sitting on the page.
   Its caption, by contrast, snaps back to the page grid — which
   is what tells the eye the image belongs to this document and
   isn't a banner.

   No parallax, no Ken Burns, no scroll-scrub. Editorial pages are
   motion-default-off, and a slowly drifting photograph of a real
   treatment room would read as a stock-video ad.
   ───────────────────────────────────────────────────────────── */

.plate {
  margin: 0;
  border-block: var(--rule-hair) solid var(--color-rule-2);
}

.plate__img {
  display: block;
  width: 100%;
  height: var(--plate-height);
  object-fit: cover;
  /* The frame's two subjects — Kai's face and the hands on the
     treatment table — sit far apart vertically, so the crop is
     biased upward to hold the face and the working hands together
     and let the table edge fall away at the bottom. */
  object-position: 40% 30%;
  filter: var(--photo-tone);
  background: var(--photo-fallback);
}

/* Caption returns to the page grid — same voice as .hero__place, so
   the label above the plate and the caption below it rhyme. Body
   face, not the mono outlier: the outlier holds two slots only. */
.plate__cap {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: var(--space-sm) var(--page-gutter) 0;
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

/* ─────────────────────────────────────────────────────────────
   Sections — deliberately uneven vertical rhythm
   ───────────────────────────────────────────────────────────── */

.section {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
  width: 100%;
}

.section--hinnasto { padding-block: var(--space-3xl) var(--space-2xl); }
.section--tiedot   { padding-block: var(--space-3xl) var(--space-lg); }
.section--varaa    { padding-block: var(--space-2xl) var(--space-4xl); }

.section--tinted {
  max-width: none;
  background: var(--tint-moss);
  border-block: var(--rule-hair) solid var(--color-rule);
  padding-block: var(--space-2xl);
}

/* Section head · S2 Hanging — negative space, no rule, no eyebrow,
   single column at every width. */
.head {
  display: grid;
  gap: var(--space-sm);
  margin-bottom: var(--section-head-gap);
}

.head__title {
  font-size: var(--text-2xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}

.head__lede {
  color: var(--color-muted);
  font-size: var(--text-sm);
  max-width: var(--measure);
}

/* ─────────────────────────────────────────────────────────────
   Hinnasto · F3 Tabular spec sheet
   Two columns: identity | rates. Hairline between every treatment.
   Rates use a dotted leader — the register of a printed price list,
   which is what hinnasto.jpg actually is.
   ───────────────────────────────────────────────────────────── */

.hoidot { border-top: var(--rule-fine) solid var(--color-rule); }

.hoito {
  display: grid;
  gap: var(--space-md);
  padding-block: var(--space-lg);
  border-bottom: var(--rule-fine) solid var(--color-rule);
}

@media (min-width: 48rem) {
  .hoito {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: var(--space-xl);
    align-items: start;
    padding-block: var(--space-xl);
  }
}

.hoito__name {
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
}

.hoito__note {
  margin-top: var(--space-2xs);
  color: var(--color-muted);
  font-size: var(--text-sm);
  max-width: 48ch;
}

.rates {
  display: grid;
  gap: var(--space-xs);
  font-variant-numeric: tabular-nums;
}

.rate {
  display: grid;
  grid-template-columns: auto minmax(var(--space-lg), 1fr) auto;
  align-items: baseline;
  gap: var(--space-xs);
  font-family: var(--font-label);
  font-size: var(--text-sm);
  color: var(--color-ink-2);
}

.rate__leader {
  border-bottom: var(--rule-fine) dotted var(--color-rule);
  transform: translateY(-0.28em);
}

.rate__hinta {
  font-weight: 500;
  color: var(--color-ink);
  white-space: nowrap;
}

.rate__kesto { white-space: nowrap; }

/* ─────────────────────────────────────────────────────────────
   Sarjakortit & maksutavat · T4 Numbered stat strip, 2-up
   Both percentages are taken from hinnasto.jpg. Nothing here
   is a figure Hallmark invented.
   ───────────────────────────────────────────────────────────── */

.band {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
  display: grid;
  gap: var(--space-xl);
}

@media (min-width: 48rem) {
  .band {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-2xl);
  }
}

/* Three topics, three columns — but only once there is room for the
   gift-card figure to sit at a third of the width without shrinking
   to a thumbnail. Below this the third column wraps to its own row. */
@media (min-width: 68rem) {
  .band {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.9fr);
    gap: var(--space-xl);
  }
}

.band__title {
  font-size: var(--text-md);
  margin-bottom: var(--space-md);
}

.stats {
  display: grid;
  gap: var(--space-lg);
}

@media (min-width: 30rem) {
  .stats { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* Back to a single column once the band goes 3-up: two figures side by
   side in a third of the width squeezes the qualifier under 20ch, and
   stacking them also gives this column height to answer the figure
   in the third one. */
@media (min-width: 68rem) {
  .stats { grid-template-columns: minmax(0, 1fr); gap: var(--space-md); }
}

.stat { display: grid; gap: var(--space-2xs); }

/* Display face, not the mono outlier: in a monospaced face the
   non-breaking space Finnish requires before % occupies a full cell
   and reads as a typo ("5   %"). Keeping the outlier to its two
   slots — the nav kicker and the hinnasto figures. */
.stat__num {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-2xl);
  line-height: var(--lh-tight);
  color: var(--color-accent);
}

.stat__qual {
  font-size: var(--text-sm);
  color: var(--color-muted);
  max-width: 22ch;
}

.band__body {
  font-size: var(--text-sm);
  max-width: var(--measure);
}

.band__body + .band__body { margin-top: var(--space-md); }

.band__body--clay { color: var(--color-accent-2-ink); }

/* Gift card — sits directly under the sentence that mentions it, at
   a deliberately modest size. It is evidence, not a hero: capped at
   26rem so it illustrates the copy instead of competing with the
   stat figures across the band. */
.gift {
  margin: var(--space-md) 0 0;
  max-width: 26rem;
}

.gift__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-card);
  filter: var(--photo-tone);
  background: var(--photo-fallback);
}

.gift__cap {
  margin-top: var(--space-sm);
  font-size: var(--text-xs);
  line-height: var(--lh-normal);
  color: var(--color-muted);
  max-width: 40ch;
}

/* ─────────────────────────────────────────────────────────────
   Käytännön tiedot
   ───────────────────────────────────────────────────────────── */

.tiedot {
  display: grid;
  gap: 0;
  border-top: var(--rule-fine) solid var(--color-rule);
}

.tieto {
  display: grid;
  gap: var(--space-2xs);
  padding-block: var(--space-md);
  border-bottom: var(--rule-fine) solid var(--color-rule);
}

@media (min-width: 40rem) {
  .tieto {
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    gap: var(--space-lg);
    align-items: baseline;
  }
}

.tieto__key {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

.tieto__val { font-size: var(--text-base); }

/* ─────────────────────────────────────────────────────────────
   Ajanvaraus — the close. One action, not two.
   ───────────────────────────────────────────────────────────── */

.varaa__title {
  font-size: var(--text-3xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}

.varaa__body {
  margin-block: var(--space-md) var(--space-lg);
  max-width: 46ch;
  font-size: var(--text-md);
  color: var(--color-ink-2);
}

.varaa__how {
  margin-bottom: var(--space-xl);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* ─────────────────────────────────────────────────────────────
   Footer · Ft1 Mast-headed
   ───────────────────────────────────────────────────────────── */

.foot {
  border-top: var(--rule-fine) solid var(--color-rule-2);
  background: var(--color-paper-2);
  padding: var(--space-2xl) var(--page-gutter) var(--space-xl);
  padding-bottom: max(var(--space-xl), env(safe-area-inset-bottom));
}

.foot > * {
  max-width: var(--page-max);
  margin-inline: auto;
}

.foot__mark {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  line-height: var(--lh-snug);
  color: var(--color-ink);
  overflow-wrap: anywhere;
}

.foot__tagline {
  margin-top: var(--space-2xs);
  color: var(--color-muted);
  font-size: var(--text-sm);
  max-width: var(--measure);
}

.foot__addr  { margin-top: var(--space-lg); font-size: var(--text-sm); }
.foot__links { margin-top: var(--space-xs); font-size: var(--text-sm); }

.foot__links a {
  white-space: nowrap;          /* footer affordances stay one line */
  text-decoration-thickness: from-font;
  text-underline-offset: 0.25em;
  transition: color var(--dur-micro) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .foot__links a:hover { color: var(--color-accent); }
}

/* rule-2 measured 2.88:1 here — too faint for a visible glyph even
   though the separator is aria-hidden. muted clears 5.16:1. */
.foot__sep { color: var(--color-muted); padding-inline: var(--space-2xs); }

.foot__fine {
  margin-top: var(--space-lg);
  font-size: var(--text-xs);
  color: var(--color-muted);
}

/* ─────────────────────────────────────────────────────────────
   Sticky booking bar · C4 — below 60 rem only
   ───────────────────────────────────────────────────────────── */

.stickybar { display: none; }

@media (max-width: 59.999rem) {
  .stickybar {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: var(--z-sticky-nav);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--page-gutter);
    padding-bottom: max(var(--space-sm), env(safe-area-inset-bottom));
    background: var(--color-paper);
    border-top: var(--rule-fine) solid var(--color-rule-2);
  }

  .stickybar[hidden] { display: none; }

  .stickybar__label {
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Keep the page's last section clear of the fixed bar. */
  .foot { padding-bottom: calc(var(--space-4xl)); }
}

/* Below 26 rem (320 px minus gutters) the label is dead weight —
   drop it and let the action have the row. */
@media (max-width: 26rem) {
  .stickybar__label { display: none; }
  .stickybar { justify-content: stretch; }
  .stickybar__cta { flex: 1; justify-content: center; }
}

/* ─────────────────────────────────────────────────────────────
   Motion — two primitives, total:
     1. one orchestrated page-load reveal (hero only)
     2. hover / active state shifts on affordances
   Editorial pages are motion-default-off. Stillness is the brand.
   ───────────────────────────────────────────────────────────── */

.reveal {
  opacity: 0;
  transform: translateY(10px);
  animation: reveal var(--dur-long) var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 90ms);
}

@keyframes reveal {
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 150ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 150ms !important;
  }
  .reveal { animation: reveal-reduced 150ms linear forwards; }
  @keyframes reveal-reduced { to { opacity: 1; transform: none; } }
  .chip:active { transform: none; }
}
