/* =====================================================
   Starter — the parametric flagship theme
   -----------------------------------------------------
   NO colors or fonts live in this file. Every value comes
   from the CSS custom properties that layouts/layout.twig
   renders out of config.yml > tokens/fonts. Change config,
   the whole site re-dresses itself — this file never needs
   an edit for a restyle.
   ===================================================== */

:root {
  /* Derived tones — computed from the injected tokens so a palette swap
     keeps every tint in step automatically. */
  --primary-soft: color-mix(in srgb, var(--primary) 10%, var(--bg));
  /* Hover must be visible on EVERY palette, so it moves toward --ink: the one
     colour guaranteed to contrast with the background, because that is what
     --ink is for. Deriving hover from --primary looked fine on light themes
     and vanished on dark-brand ones — a black shadow on a black page, a 10%
     black tint on a near-black background. Reported live: buttons and the
     language switcher had no visible hover at all. */
  --hover-lift: color-mix(in srgb, var(--primary) 82%, var(--ink));
  --hover-wash: color-mix(in srgb, var(--bg) 88%, var(--ink));
  --tint: color-mix(in srgb, var(--primary) 5%, var(--bg));
  --body-text: color-mix(in srgb, var(--ink) 80%, var(--bg));
  --accent-soft: color-mix(in srgb, var(--accent) 14%, var(--bg));
  --danger: #b3423f;
  --danger-soft: #f7e8e7;
  --container: 1140px;
}

* { box-sizing: border-box; }

/* Type scale the multiplier belongs on the ROOT, not
   on body. Headings and most text are sized in rem — and rem resolves against
   <html> — so a body-level scale moved almost nothing (found live: "Text size"
   looked broken). 16px is the browser default this theme was drawn against. */
html {
  scroll-behavior: smooth;
  font-size: calc(16px * var(--font-scale, 1));
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--body-text);
  font-family: var(--font-body);
  font-size: 1.03rem; /* 16.5px at scale 1 — now inherits the root scale */
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
  line-height: 1.15;
  margin: 0 0 .5em;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(2.4rem, 5vw, 3.6rem); }
h2 { font-size: clamp(1.8rem, 3.4vw, 2.5rem); }
h3 { font-size: 1.35rem; }

p { margin: 0 0 1em; }

a { color: inherit; text-decoration: none; }

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

.container--narrow { max-width: 860px; }

.lead {
  font-size: 1.16rem;
  color: var(--body-text);
  max-width: 620px;
}

.kicker, .eyebrow {
  display: block;
  text-transform: uppercase;
  letter-spacing: .22em;
  font-size: .76rem;
  font-weight: 600;
  color: var(--mark, var(--primary));
  margin-bottom: 1rem;
}

/* ---------- Buttons & links ---------- */
.btn {
  display: inline-block;
  padding: .95rem 2.1rem;
  border-radius: 999px;
  background: var(--primary);
  color: var(--primary-ink);
  font-weight: 600;
  font-size: .95rem;
  border: 1.5px solid var(--mark, var(--primary));
  cursor: pointer;
  font-family: var(--font-body);
  transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
}

.btn:hover { transform: translateY(-2px); background: var(--hover-lift); box-shadow: 0 10px 24px -14px var(--ink); }

.btn-ghost { background: transparent; color: var(--mark, var(--primary)); }
.btn-ghost:hover { background: var(--hover-wash); border-color: var(--ink); color: var(--ink); box-shadow: none; }

.btn-light, .btn-inverse { background: var(--bg); border-color: var(--bg); color: var(--ink); }

.btn-small { padding: .55rem 1.3rem; font-size: .85rem; }

.link-arrow {
  font-weight: 600;
  color: var(--mark, var(--primary));
  white-space: nowrap;
}
.link-arrow::after { content: ' →'; transition: margin .2s ease; }
.link-arrow:hover::after { margin-left: 4px; }

.link-back {
  display: inline-block;
  color: var(--muted);
  font-size: .9rem;
  margin-bottom: 2rem;
}
.link-back:hover { color: var(--mark, var(--primary)); }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 78px;
  gap: 1.5rem;
}

.logo {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  white-space: nowrap;
}

.logo-dot {
  width: .62em;
  height: .62em;
  border-radius: 50%;
  background: var(--primary);
  display: inline-block;
}

.logo-mark { display: inline-flex; color: var(--ink); }
.logo-mark svg { width: 34px; height: 34px; display: block; }

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.8rem;
}

.nav-link {
  font-size: .93rem;
  font-weight: 500;
  color: var(--body-text);
  padding: .3rem 0;
  border-bottom: 2px solid transparent;
  transition: color .2s ease;
}

.nav-link:hover { color: var(--mark, var(--primary)); }
.nav-link.is-active { color: var(--mark, var(--primary)); border-bottom-color: var(--mark, var(--primary)); }

.lang-switch {
  display: flex;
  gap: .6rem;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .06em;
}
.lang-switch a { color: var(--muted); }
.lang-switch a.is-active { color: var(--mark, var(--primary)); }
/* --ink, not --mark: on a dark palette the derived readable colour
   lands in the same grey as --muted, so hover changed nothing you could see. */
.lang-switch a:hover { color: var(--ink); }

.nav-checkbox { display: none; }
.nav-toggle { display: none; }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  padding: clamp(4.5rem, 10vw, 8rem) 0 clamp(4rem, 9vw, 7rem);
  border-bottom: 1px solid var(--line);
}

.hero--split .hero-inner {
  display: grid;
  grid-template-columns: 1.2fr .8fr;
  gap: 3rem;
  align-items: center;
}

.hero--centered .hero-inner { text-align: center; }
.hero--centered .hero-title, .hero--centered .lead { margin-left: auto; margin-right: auto; }
.hero--centered .hero-actions { justify-content: center; }
.hero--centered .hero-stats { justify-content: center; }

/* --- hero photo -----------------------------------------------------------
   `background` covers the whole section; `side` puts the photo where the drawn
   mark otherwise sits. Both keep the section's own padding and grid, so the
   layout knobs stay in charge of shape and only the surface changes.

   The scrim is a LITERAL colour on purpose — it is not a brand colour, no token
   expresses "darken whatever is underneath", and tinting it with --primary
   would stain every photo with the palette. `auto` resolves through
   color-mix against --bg, which is the only thing that knows whether this theme
   is light or dark. */
.hero--media-background {
  background-size: cover;
  background-position: center;
  border-bottom: 0;
}
/* A GRADIENT, not a flat wash. An even 78% veil is safe and pointless: it
   makes the photograph read as a faint texture, so the hero costs a download
   and a decision and gains nothing a plain background would not have given.
   The copy sits on the left, so that is the only side that needs covering —
   the far side can open up and let the picture actually be a picture. */
.hero--media-background::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(100deg,
    color-mix(in srgb, var(--bg) 90%, transparent) 0%,
    color-mix(in srgb, var(--bg) 84%, transparent) 46%,
    color-mix(in srgb, var(--bg) 34%, transparent) 100%);
}
.hero--media-background.hero--overlay-none::before { background: none; }
.hero--media-background.hero--overlay-light::before { background: rgba(255, 255, 255, .72); }
.hero--media-background.hero--overlay-dark::before  { background: rgba(0, 0, 0, .58); }

/* Above the scrim. Without this the copy sits under it and the whole thing
   looks like a fogged window. */
.hero--media-background .hero-inner { position: relative; z-index: 1; }

.hero-visual--photo { pointer-events: auto; }
.hero-visual--photo img {
  width: 100%;
  height: 100%;
  max-height: 420px;
  object-fit: cover;
  border-radius: var(--radius);
  display: block;
}

.hero-visual {
  color: var(--mark, var(--primary));
  pointer-events: none;
}
.hero-visual svg { width: 100%; max-width: 460px; height: auto; margin-left: auto; }

.hero-title { max-width: 780px; margin-bottom: 1.2rem; }

.hero .lead { margin-bottom: 2.4rem; }

.hero-actions { display: flex; gap: .9rem; flex-wrap: wrap; }

.hero-stats {
  display: flex;
  gap: 2.6rem;
  margin: 2.6rem 0 0;
  padding-top: 1.8rem;
  border-top: 1px solid var(--line);
}
.hero-stats > div { display: flex; flex-direction: column; }
.hero-stats dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.7rem;
  font-weight: 600;
  color: var(--ink);
}
.hero-stats dt { font-size: .82rem; color: var(--muted); }

/* ---------- Sections ---------- */
.section { padding: clamp(3.8rem, 8vw, 6.5rem) 0; }

.section--alt, .section-tinted {
  background: var(--tint);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.section-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 2rem;
  margin-bottom: 2.6rem;
}
.section-head h2 { margin-bottom: 0; }

.page-head {
  padding: clamp(3.6rem, 7vw, 5.5rem) 0 0;
}
.page-head h1 { max-width: 720px; }
.page-head .lead { margin-bottom: 0; }

/* ---------- Feature cards (sections/features) ---------- */
.features-grid { display: grid; gap: 1.4rem; }
.features-grid--2 { grid-template-columns: repeat(2, 1fr); }
.features-grid--3 { grid-template-columns: repeat(3, 1fr); }
.features-grid--4 { grid-template-columns: repeat(4, 1fr); }

.feature-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.8rem;
}

.feature-index {
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--accent);
  display: block;
  margin-bottom: 1rem;
}

.feature-card h3 { font-size: 1.15rem; margin-bottom: .4rem; }
.feature-card p { font-size: .95rem; margin: 0; }

/* ---------- Service cards ---------- */
.cards-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
}

.card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.8rem;
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.card:hover {
  transform: translateY(-4px);
  border-color: var(--mark, var(--primary));
  box-shadow: 0 18px 34px -24px color-mix(in srgb, var(--ink) 35%, transparent);
}

.card-index {
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--muted);
  margin-bottom: 1.1rem;
}

.card h3 { margin-bottom: .5rem; }
.card p { font-size: .95rem; flex: 1; }

.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.2rem;
}

.price-chip {
  background: var(--accent-soft);
  color: color-mix(in srgb, var(--accent) 75%, var(--ink));
  font-weight: 600;
  font-size: .85rem;
  padding: .3rem .8rem;
  border-radius: 999px;
  white-space: nowrap;
}

/* Duration sits next to the price and reads as secondary to it — a booking
   detail, not the offer. */
.meta-chip {
  color: var(--muted);
  font-size: .85rem;
  white-space: nowrap;
}

.card-media { display: none; }
.card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------- Pricing list (sections/pricing) ---------- */
.rate-list { list-style: none; margin: 0; padding: 0; }

.rate-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding: 1.3rem 0;
  border-bottom: 1px dashed var(--line);
}
.rate-row:last-child { border-bottom: none; }

.rate-name { font-family: var(--font-display); font-size: 1.15rem; font-weight: 600; color: var(--ink); }
.rate-name:hover { color: var(--mark, var(--primary)); }
.rate-desc { font-size: .9rem; color: var(--muted); margin: .2rem 0 0; max-width: 46ch; }
.rate-price { font-weight: 600; color: var(--ink); white-space: nowrap; }

/* ---------- About strip / values / steps ---------- */
.about-strip {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3.5rem;
  align-items: start;
}
.about-strip h2 { margin-bottom: 0; }

.values-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.5rem;
}

.value-num {
  font-family: var(--font-display);
  font-size: 2.6rem;
  color: var(--mark, var(--primary));
  display: block;
  margin-bottom: .6rem;
}

.steps {
  margin: 0;
  padding: 0 0 0 1.2rem;
  display: grid;
  gap: .9rem;
}
.steps li::marker { color: var(--mark, var(--primary)); font-weight: 700; }

/* ---------- Posts ---------- */
.posts-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
}

.post-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.post-card:hover {
  transform: translateY(-4px);
  border-color: var(--mark, var(--primary));
  box-shadow: 0 18px 34px -24px color-mix(in srgb, var(--ink) 35%, transparent);
}

.post-card img,
.post-ph {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
}

.post-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--primary-soft), var(--tint));
  color: var(--mark, var(--primary));
  font-family: var(--font-display);
  font-size: 3.4rem;
  font-weight: 600;
}

.post-body { padding: 1.3rem 1.5rem 1.6rem; display: block; }

.post-date {
  display: block;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted);
  margin-bottom: .5rem;
}

.post-body h3 { font-size: 1.15rem; margin-bottom: .4rem; }
.post-body p { font-size: .92rem; margin: 0; color: var(--body-text); }

/* ---------- Category chips ---------- */
.chip-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.4rem; }

.chip {
  padding: .4rem 1rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-size: .85rem;
  font-weight: 500;
  color: var(--body-text);
  transition: all .2s ease;
}
.chip:hover { border-color: var(--mark, var(--primary)); color: var(--mark, var(--primary)); }
.chip.is-active { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); }

/* ---------- Article ---------- */
.article { padding: clamp(3rem, 6vw, 5rem) 0; }

.article-narrow { max-width: 760px; }

.article-photo {
  border-radius: var(--radius);
  margin: 2rem 0;
}

.prose { color: var(--body-text); }
.prose h2 { font-size: 1.6rem; margin-top: 2.2rem; }
.prose h3 { margin-top: 1.8rem; }
.prose ul, .prose ol { padding-left: 1.3rem; }
.prose li { margin-bottom: .4rem; }
.prose li::marker { color: var(--mark, var(--primary)); }
.prose img { border-radius: var(--radius); margin: 1.5rem 0; }
.prose a { color: var(--mark, var(--primary)); text-decoration: underline; text-underline-offset: 3px; }
.prose blockquote {
  margin: 1.8rem 0;
  padding: .3rem 0 .3rem 1.4rem;
  border-left: 3px solid var(--mark, var(--primary));
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--ink);
}

/* ---------- Buy box ---------- */
.buy-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-top: 2.5rem;
  padding: 1.6rem 1.8rem;
  background: var(--tint);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

/* Facts column: price is the headline, duration the supporting line. Both
   render without any commerce feature being on. */
.buy-facts { display: flex; flex-direction: column; gap: .15rem; }

.buy-duration {
  font-size: .9rem;
  color: var(--muted);
}

.buy-label {
  display: block;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted);
}

.buy-price {
  font-family: var(--font-display);
  font-size: 1.9rem;
  font-weight: 600;
  color: var(--ink);
}

.buy-form { display: flex; align-items: center; gap: .8rem; }

.buy-qty {
  width: 74px;
  height: 48px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  background: var(--surface);
}
.buy-qty:focus { outline: none; border-color: var(--mark, var(--primary)); }

.cta-inline {
  margin-top: 2.5rem;
  padding: 1.6rem 1.8rem;
  background: var(--primary-soft);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.2rem;
}
.cta-inline p { margin: 0; color: var(--ink); font-weight: 500; }

/* ---------- Booking box (pages/service) ---------- */
.book-box {
  margin-top: 2.5rem;
  padding: 1.8rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.book-box h2 { font-size: 1.5rem; }
.book-hint { font-size: .92rem; color: var(--muted); }

.book-date-form { margin: 1.2rem 0; display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.book-label { font-size: .85rem; font-weight: 600; color: var(--ink); }

.book-date-form input[type='date'] {
  padding: .7rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .95rem;
}
.book-date-form input[type='date']:focus { outline: none; border-color: var(--mark, var(--primary)); }

.slot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
  gap: .55rem;
  margin-bottom: 1.4rem;
}

.slot input { position: absolute; opacity: 0; pointer-events: none; }

.slot span {
  display: block;
  text-align: center;
  padding: .6rem 0;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-small);
  font-size: .92rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: all .15s ease;
}

.slot:hover span { border-color: var(--mark, var(--primary)); }
.slot input:checked + span {
  background: var(--primary);
  border-color: var(--mark, var(--primary));
  color: var(--primary-ink);
}
.slot input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: 2px; }

.book-fields { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: .8rem; margin-bottom: .9rem; }

.book-fields input, .book-notes {
  width: 100%;
  padding: .85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .95rem;
}
.book-fields input:focus, .book-notes:focus { outline: none; border-color: var(--mark, var(--primary)); }

.book-notes { display: block; margin-bottom: 1.2rem; resize: vertical; }

.book-empty {
  padding: 1.2rem;
  background: var(--tint);
  border-radius: var(--radius-small);
  color: var(--muted);
  text-align: center;
}

/* ---------- Testimonials (sections/testimonials) ---------- */
.quotes-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.4rem;
}

.quote-card {
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.8rem;
}

.quote-card blockquote {
  margin: 0 0 1.2rem;
  font-family: var(--font-display);
  font-size: 1.12rem;
  color: var(--ink);
  line-height: 1.5;
}
.quote-card blockquote::before { content: '\201C'; color: var(--accent); margin-right: .15em; }

.quote-card figcaption {
  display: flex;
  align-items: center;
  gap: .7rem;
  font-size: .9rem;
  font-weight: 600;
  color: var(--muted);
}

.quote-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--mark, var(--primary));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
}

/* ---------- FAQ (sections/faq) ---------- */
.faq-list { display: grid; gap: .6rem; }

.faq-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  padding: 0 1.3rem;
}

.faq-item summary {
  cursor: pointer;
  list-style: none;
  padding: 1.05rem 0;
  font-weight: 600;
  color: var(--ink);
  position: relative;
  padding-right: 2rem;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: '+';
  position: absolute;
  right: .2rem;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--mark, var(--primary));
  transition: transform .2s ease;
}
.faq-item[open] summary::after { transform: translateY(-50%) rotate(45deg); }

.faq-item p { margin: 0; padding: 0 0 1.2rem; color: var(--body-text); font-size: .96rem; }

/* ---------- Team (sections/team) ---------- */
.team-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.4rem;
}

.team-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.8rem 1.5rem;
  text-align: center;
}

.team-avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  margin: 0 auto 1rem;
  background: linear-gradient(135deg, var(--primary-soft), var(--accent-soft));
  color: var(--mark, var(--primary));
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 1.8rem;
  font-weight: 600;
}

.team-card h3 { font-size: 1.08rem; margin-bottom: .2rem; }
.team-card p { margin: 0; font-size: .88rem; color: var(--muted); }

/* ---------- Gallery (sections/gallery) ---------- */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .9rem;
}

.gallery-item {
  margin: 0;
  border-radius: var(--radius-small);
  overflow: hidden;
  aspect-ratio: 1;
}

.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .3s ease;
}
.gallery-item:hover img { transform: scale(1.04); }

/* ---------- CTA section (sections/cta) ---------- */
.cta--band {
  background: var(--primary);
  color: var(--primary-ink);
  padding: clamp(3.5rem, 7vw, 5.5rem) 0;
}
.cta--band .cta-inner h2 { color: var(--primary-ink); }
.cta--band .cta-inner p { color: color-mix(in srgb, var(--primary-ink) 82%, transparent); margin-bottom: 2rem; }

.cta--plain { padding: clamp(3rem, 6vw, 5rem) 0; }
.cta--plain .cta-inner p { color: var(--body-text); margin-bottom: 2rem; }

.cta-inner { text-align: center; max-width: 640px; margin: 0 auto; }

/* legacy alias (about page band) */
.cta-band {
  background: var(--primary);
  color: var(--primary-ink);
  padding: clamp(3.5rem, 7vw, 5.5rem) 0;
}
.cta-band .cta-inner h2 { color: var(--primary-ink); }
.cta-band .cta-inner p { color: color-mix(in srgb, var(--primary-ink) 82%, transparent); margin-bottom: 2rem; }

/* ---------- Contact cards (sections/contacts) ---------- */
.contact-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
}

.contact-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem 1.8rem;
  display: flex;
  flex-direction: column;
  gap: .3rem;
}

.contact-label {
  font-size: .76rem;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--muted);
}
.contact-value { font-weight: 600; color: var(--ink); }
a.contact-value:hover { color: var(--mark, var(--primary)); }

/* ---------- Contact page ---------- */
.contact-grid {
  display: grid;
  grid-template-columns: .8fr 1.2fr;
  gap: 3.5rem;
  align-items: start;
}

.info-item { padding: 1.1rem 0; border-bottom: 1px solid var(--line); }
.info-item a:hover { color: var(--mark, var(--primary)); }

.info-label {
  display: block;
  font-size: .76rem;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--muted);
  margin-bottom: .25rem;
}

.contact-form-wrap label {
  display: block;
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: .4rem;
}

.contact-form-wrap input,
.contact-form-wrap textarea {
  width: 100%;
  padding: .85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .97rem;
  margin-bottom: .35rem;
}

.contact-form-wrap input:focus,
.contact-form-wrap textarea:focus {
  outline: none;
  border-color: var(--mark, var(--primary));
  box-shadow: 0 0 0 3px var(--primary-soft);
}

.contact-form-wrap textarea { resize: vertical; min-height: 130px; }

.contact-form-wrap .btn { margin-top: .8rem; }

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; }

.field-error { min-height: 1.1rem; font-size: .82rem; color: var(--danger); margin-bottom: .6rem; }

.form-success, .form-error {
  padding: 1rem 1.2rem;
  border-radius: var(--radius-small);
  font-weight: 500;
  margin-bottom: 1.4rem;
}
.form-success { background: var(--primary-soft); color: var(--mark, var(--primary)); }
.form-error { background: var(--danger-soft); color: var(--danger); }

/* ---------- Auth pages (account/login, account/register) ---------- */
.auth-inner { max-width: 460px; margin: 0 auto; }

.auth-form label {
  display: block;
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: .4rem;
}

.auth-form input[type='email'],
.auth-form input[type='password'],
.auth-form input[type='text'] {
  width: 100%;
  padding: .85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .97rem;
  margin-bottom: .35rem;
}

.auth-form input:focus {
  outline: none;
  border-color: var(--mark, var(--primary));
  box-shadow: 0 0 0 3px var(--primary-soft);
}

.auth-remember {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .9rem;
  margin: .6rem 0 1.2rem;
  cursor: pointer;
}
.auth-remember input { accent-color: var(--mark, var(--primary)); }

.auth-form .btn { width: 100%; }

.auth-switch { margin-top: 1.6rem; text-align: center; font-size: .92rem; color: var(--muted); }
.auth-switch a { color: var(--mark, var(--primary)); font-weight: 600; }

/* ---------- Account page ---------- */
.account-grid { display: grid; gap: 2.2rem; max-width: 760px; }

.account-block h2 { font-size: 1.4rem; margin-bottom: 1rem; }

.account-list { list-style: none; margin: 0; padding: 0; }

.account-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.4rem;
  padding: 1rem 1.2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--surface);
  margin-bottom: .6rem;
}

.account-row-title { display: block; font-weight: 600; color: var(--ink); }
.account-row-sub { display: block; font-size: .85rem; color: var(--muted); }
.account-row-side { display: flex; align-items: center; gap: .9rem; flex-shrink: 0; }
.account-row-price { font-weight: 600; color: var(--ink); }

.account-cancel { font-size: .85rem; color: var(--danger); }
.account-cancel:hover { text-decoration: underline; }

.status {
  font-size: .76rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  padding: .3rem .7rem;
  border-radius: 999px;
  background: var(--tint);
  color: var(--muted);
}
.status--confirmed, .status--paid { background: var(--primary-soft); color: var(--mark, var(--primary)); }
.status--new { background: var(--accent-soft); color: color-mix(in srgb, var(--accent) 75%, var(--ink)); }
.status--cancelled { background: var(--danger-soft); color: var(--danger); }

.account-actions { padding-top: .5rem; }

/* ---------- Thanks ---------- */
.thanks-inner { text-align: center; max-width: 560px; padding-top: 2rem; margin: 0 auto; }

.thanks-mark {
  width: 64px;
  height: 64px;
  margin: 0 auto 1.6rem;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--mark, var(--primary));
  display: flex;
  align-items: center;
  justify-content: center;
}
.thanks-mark svg { width: 30px; height: 30px; }

.thanks-inner .lead { margin: 0 auto 2.2rem; }

/* ---------- Empty state ---------- */
.empty-state {
  text-align: center;
  padding: 3.5rem 1.5rem;
  border: 1.5px dashed var(--line);
  border-radius: var(--radius);
  color: var(--muted);
}

/* ---------- Pagination (partials/pagination.twig) ---------- */
.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: .45rem;
  margin-top: 3.2rem;
}

.page-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 .7rem;
  border-radius: var(--radius-small);
  border: 1.5px solid var(--line);
  background: var(--surface);
  font-size: .92rem;
  font-weight: 600;
  color: var(--body-text);
  transition: all .2s ease;
}

a.page-btn:hover {
  border-color: var(--ink);
  color: var(--ink);
  transform: translateY(-1px);
  box-shadow: 0 8px 18px -12px var(--ink);
}

.page-btn.is-current {
  background: var(--primary);
  border-color: var(--mark, var(--primary));
  color: var(--primary-ink);
}

.page-btn.is-gap { border-color: transparent; color: var(--muted); }

.page-arrow { font-size: 1.05rem; }
.page-arrow.is-disabled { opacity: .35; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--tint);
  border-top: 1px solid var(--line);
  padding: 3.5rem 0 0;
  margin-top: 0;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 2.5rem;
  padding-bottom: 2.5rem;
}

.footer-about { font-size: .92rem; color: var(--muted); margin-top: 1rem; max-width: 320px; }

.footer-title {
  display: block;
  font-size: .76rem;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--muted);
  margin-bottom: 1rem;
}

.footer-nav, .footer-contacts { display: flex; flex-direction: column; gap: .55rem; font-size: .95rem; }
.footer-nav a:hover, .footer-contacts a:hover { color: var(--mark, var(--primary)); }

.footer-bottom {
  border-top: 1px solid var(--line);
  padding-top: 1.4rem;
  padding-bottom: 1.6rem;
  font-size: .85rem;
  color: var(--muted);
}

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .cards-grid, .posts-grid, .values-grid, .contact-cards, .team-grid, .gallery-grid,
  .features-grid--3, .features-grid--4 { grid-template-columns: repeat(2, 1fr); }
  .quotes-grid { grid-template-columns: 1fr; }
  .about-strip, .contact-grid { grid-template-columns: 1fr; gap: 2rem; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .hero--split .hero-inner { grid-template-columns: 1fr; }
  /* The drawn mark is decoration and goes; a PHOTOGRAPH is content and stays.
     This rule predates hero photos, so it hid them too — and the builder's own
     preview pane is narrower than this breakpoint, which meant an owner who had
     just been given a hero image saw no image at all while looking straight at
     the site. Shorter here, because it now sits under the copy instead of
     beside it. */
  .hero-visual:not(.hero-visual--photo) { display: none; }
  .hero-visual--photo img { max-height: 280px; }
  /* The copy stops being a left column here and spans the whole width, so it
     lands on the open side of the gradient — measured at 6.2:1 on a mid-tone
     photo, and a darker one goes under the line. No far side to spare means
     an even veil, which is the one place the flat wash is the right answer. */
  .hero--media-background::before {
    background: color-mix(in srgb, var(--bg) 86%, transparent);
  }
  .book-fields { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .cards-grid, .posts-grid, .values-grid, .contact-cards, .form-row, .footer-grid, .team-grid,
  .features-grid--2, .features-grid--3, .features-grid--4 { grid-template-columns: 1fr; }
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }

  .section-head { flex-direction: column; align-items: start; gap: .8rem; }

  .hero-stats { flex-wrap: wrap; gap: 1.4rem 2.2rem; }

  .account-row { flex-direction: column; align-items: flex-start; gap: .6rem; }
  .account-row-side { width: 100%; justify-content: space-between; }

  .rate-row { flex-direction: column; gap: .3rem; }

  /* Mobile nav: checkbox-driven, no JS */
  .nav-toggle {
    display: flex;
    flex-direction: column;
    gap: 5px;
    cursor: pointer;
    padding: 6px 2px;
  }
  .nav-toggle span {
    width: 22px;
    height: 2px;
    background: var(--ink);
    border-radius: 2px;
    transition: transform .25s ease, opacity .25s ease;
  }

  .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.1rem;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    padding: 1.4rem 24px 1.8rem;
  }

  .nav-checkbox:checked ~ .site-nav { display: flex; }
  .nav-checkbox:checked ~ .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-checkbox:checked ~ .nav-toggle span:nth-child(2) { opacity: 0; }
  .nav-checkbox:checked ~ .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}

/* ---------- Layout knobs ----------
   Body classes rendered from config.yml `layout:` — see layouts/layout.twig.
   Every rule keys on tokens, so palettes keep working under any frame. */

/* width: wide — the container token cascades from body */
body.width-wide { --container: 1320px; }

/* header: solid — opaque, in-flow (no sticky, no blur) */
body.header-solid .site-header {
  position: static;
  background: var(--bg);
  backdrop-filter: none;
}

/* header: transparent — floats over the hero, no ground of its own */
body.header-transparent .site-header {
  position: absolute;
  left: 0;
  right: 0;
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
}
body.header-transparent main { padding-top: 0; }

/* footer: minimal — just the legal line, no link grid */
body.footer-minimal .footer-grid { display: none; }
body.footer-minimal .site-footer { padding-top: 0; }

/* nav: left — desktop sidebar; below 960px the burger takes over as usual */
@media (min-width: 960px) {
  body.nav-left {
    display: grid;
    grid-template-columns: 264px minmax(0, 1fr);
  }
  body.nav-left .site-header {
    grid-row: 1 / span 2;
    position: sticky;
    top: 0;
    height: 100vh;
    border-bottom: 0;
    border-right: 1px solid var(--line);
    background: var(--bg);
    backdrop-filter: none;
  }
  body.nav-left .header-inner {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    min-height: 0;
    height: 100%;
    padding-top: 30px;
    padding-bottom: 30px;
    gap: 2.2rem;
  }
  body.nav-left .site-nav {
    flex-direction: column;
    align-items: flex-start;
    gap: .4rem;
    width: 100%;
  }
  body.nav-left .site-nav .btn.btn-small { margin-top: .6rem; }
  body.nav-left .lang-switch { margin-top: auto; }
  body.nav-left main,
  body.nav-left .site-footer { grid-column: 2; min-width: 0; }
}

/* ---------- Section variants ----------
   Deliberately near the END of the file, right before their media
   queries. Variant classes carry the same specificity as the base
   `.cards-grid` / `.quotes-grid` they override, so at equal weight the
   later rule wins — defined up beside the base grids, the spotlight
   column count silently lost and rendered two columns instead of three.
   Keep the whole variant layer down here. */

/* ---------- Services variants ----------
   One markup shape, three layouts. Everything below re-arranges the SAME
   elements the cards variant uses — no variant owns markup or copy of its
   own, which is what keeps the translation-key scan whole. */

/* list — one row per service, price and link pushed to the right edge. Reads
   as a price list, which is what a salon or a workshop actually wants. */
.cards-grid--list { grid-template-columns: 1fr; gap: 0; }

.cards-grid--list .card {
  flex-direction: row;
  align-items: center;
  gap: 1.5rem;
  border-radius: 0;
  border-width: 0 0 1px;
  padding: 1.4rem .4rem;
}
.cards-grid--list .card:first-child { border-top: 1px solid var(--line); }
.cards-grid--list .card:hover {
  transform: none;
  border-color: var(--line);
  box-shadow: none;
  background: var(--surface);
}
.cards-grid--list .card-body { flex: 1; min-width: 0; }
.cards-grid--list .card-index {
  margin-bottom: 0;
  margin-right: .2rem;
  display: inline-block;
}
.cards-grid--list .card h3 { display: inline; margin: 0; }
.cards-grid--list .card p {
  margin: .35rem 0 0;
  color: var(--muted);
  font-size: .9rem;
}
.cards-grid--list .card-foot { margin-top: 0; flex: 0 0 auto; }

/* alternating — image beside text, sides swapping row to row.

   Grid, not flex-direction: row-reverse. Reversing the row flips ALL three
   children, so on even rows the price and the "Details" link detached from
   their own text and floated to the far left of the card — the layout read as
   two unrelated columns. Explicit placement moves only the image, which is the
   one thing that is supposed to alternate. */
.cards-grid--alternating { grid-template-columns: 1fr; gap: 1.2rem; }

.cards-grid--alternating .card {
  display: grid;
  grid-template-columns: minmax(0, 34%) minmax(0, 1fr);
  grid-template-rows: auto auto;
  align-items: center;
  gap: .5rem 2rem;
  padding: 1.4rem;
}
.cards-grid--alternating .card-media {
  display: block;
  grid-row: 1 / 3;
  grid-column: 1;
  aspect-ratio: 3 / 2;
  max-height: 14rem;
  border-radius: var(--radius);
  overflow: hidden;
}
.cards-grid--alternating .card-body {
  grid-row: 1;
  grid-column: 2;
  align-self: end;
  min-width: 0;
}
.cards-grid--alternating .card-body p { margin-bottom: 0; }
.cards-grid--alternating .card-foot {
  grid-row: 2;
  grid-column: 2;
  align-self: start;
  justify-content: flex-start;
  margin-top: .4rem;
}

/* Swap the TRACKS as well as the placement: moving the image to column 2
   without this leaves it floating in the wide text track with dead space
   beside it, and squeezes the copy into the narrow one. */
.cards-grid--alternating .card:nth-child(even) {
  grid-template-columns: minmax(0, 1fr) minmax(0, 34%);
}
.cards-grid--alternating .card:nth-child(even) .card-media { grid-column: 2; }
.cards-grid--alternating .card:nth-child(even) .card-body,
.cards-grid--alternating .card:nth-child(even) .card-foot { grid-column: 1; }

/* A record without a photo gets the full width instead of an empty column —
   a half-illustrated area is the normal state, not an edge case. */
.cards-grid--alternating .card:not(:has(.card-media)) { grid-template-columns: minmax(0, 1fr); }
.cards-grid--alternating .card:not(:has(.card-media)) .card-body,
.cards-grid--alternating .card:not(:has(.card-media)) .card-foot { grid-column: 1; }

/* ---------- Testimonials variants ---------- */

/* spotlight — the first quote carries the section, the rest support it. */
.quotes-grid--spotlight { grid-template-columns: repeat(3, 1fr); }
.quotes-grid--spotlight .quote-card:first-child {
  grid-column: 1 / -1;
  padding: 2.4rem;
  text-align: center;
}
.quotes-grid--spotlight .quote-card:first-child blockquote {
  font-size: 1.6rem;
  line-height: 1.4;
  max-width: 46ch;
  margin-inline: auto;
}
.quotes-grid--spotlight .quote-card:first-child figcaption { justify-content: center; }

/* strip — one horizontal row, scroll-snapped. Deliberately NOT an
   auto-playing marquee: text that slides away mid-sentence is unreadable,
   and an animation nobody can pause is an accessibility problem. */
.quotes-grid--strip {
  display: flex;
  gap: 1.4rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: .6rem;
  scrollbar-width: thin;
}
.quotes-grid--strip .quote-card {
  flex: 0 0 min(23rem, 78vw);
  scroll-snap-align: start;
}


/* ---------- Features variants ---------- */

/* numbered — the figure carries the eye, the card chrome gets out of the way. */
.features-grid--numbered .feature-card {
  background: none;
  border: 0;
  padding: 0 1.4rem 0 0;
}
.features-grid--numbered .feature-index {
  font-size: 2.4rem;
  line-height: 1;
  color: color-mix(in srgb, var(--primary) 35%, var(--bg));
  margin-bottom: .6rem;
}

/* checkerboard — alternating tint instead of borders; reads denser and less
   "three boxes in a row". */
.features-grid--checkerboard { gap: 0; }
.features-grid--checkerboard .feature-card {
  border: 0;
  border-radius: 0;
  background: var(--bg);
  padding: 1.9rem;
}
.features-grid--checkerboard .feature-card:nth-child(odd) { background: var(--tint); }

/* ---------- Team variants ---------- */

/* list — avatar left, name and role beside it. Suits a long roster where the
   grid of faces turns into wallpaper. */
.team-grid--list { grid-template-columns: 1fr; gap: 0; }
.team-grid--list .team-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  align-items: center;
  gap: .1rem 1.2rem;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 1.1rem .2rem;
}
.team-grid--list .team-avatar { grid-row: 1 / 3; margin: 0; width: 56px; height: 56px; }
.team-grid--list .team-card h3 { grid-column: 2; margin: 0; }
.team-grid--list .team-card p { grid-column: 2; margin: 0; color: var(--muted); font-size: .92rem; }

/* strip — one scrolling row of faces; scroll-snap, no autoplay. */
.team-grid--strip {
  display: flex;
  gap: 1.2rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: .6rem;
}
.team-grid--strip .team-card { flex: 0 0 min(15rem, 60vw); scroll-snap-align: start; }

/* ---------- FAQ variants ---------- */

/* columns — everything expanded in two columns. The template also renders the
   `open` attribute for this variant: a closed <details> cannot be forced open
   from CSS, and faking it with height tricks breaks the built-in semantics
   screen readers rely on. */
.faq-list--columns {
  columns: 2;
  column-gap: 2.4rem;
}
.faq-list--columns .faq-item {
  break-inside: avoid;
  border-bottom: 0;
  margin-bottom: 1.4rem;
}
.faq-list--columns .faq-item summary { cursor: default; list-style: none; pointer-events: none; }
.faq-list--columns .faq-item summary::-webkit-details-marker { display: none; }
.faq-list--columns .faq-item summary::after { content: none; }

/* ---------- Gallery variants ---------- */

/* masonry — natural heights instead of a uniform crop; portrait shots stop
   losing their tops and bottoms. */
.gallery-grid--masonry {
  display: block;
  columns: 4;
  column-gap: 1rem;
}
.gallery-grid--masonry .gallery-item {
  break-inside: avoid;
  margin: 0 0 1rem;
}
.gallery-grid--masonry .gallery-item img { height: auto; aspect-ratio: auto; }

/* strip — one scrolling row. */
.gallery-grid--strip {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: .6rem;
}
.gallery-grid--strip .gallery-item { flex: 0 0 min(20rem, 70vw); scroll-snap-align: start; }

/* ---------- Pricing variants ---------- */

/* cards — a tile per rate, for short menus where rows look thin. */
.rate-list--cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.2rem;
}
.rate-list--cards .rate-row {
  flex-direction: column;
  align-items: flex-start;
  gap: .6rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem;
}
.rate-list--cards .rate-price {
  font-size: 1.5rem;
  color: var(--mark, var(--primary));
}

/* ---------- Hero: minimal ----------
   Typography only. No visual, no stats row — for a business whose first
   screen should say one thing. */
.hero--minimal { padding: clamp(3.5rem, 7vw, 5.5rem) 0; }
.hero--minimal .hero-inner { text-align: center; }
.hero--minimal .hero-visual { display: none; }
.hero--minimal .hero-stats { display: none; }
.hero--minimal .hero-title,
.hero--minimal .lead { margin-left: auto; margin-right: auto; }
.hero--minimal .hero-actions { justify-content: center; }
.hero--minimal .eyebrow { letter-spacing: .3em; }

/* ---------- Density ----------
   A body-level knob, like the other layout knobs. Section rhythm and
   card padding change together — the same blocks in a tighter or airier grid
   read as a different site, which is the cheapest variety there is. */
body.density-compact .section { padding: clamp(2.4rem, 5vw, 4rem) 0; }
body.density-compact .section-head { margin-bottom: 1.7rem; }
body.density-compact .card,
body.density-compact .feature-card,
body.density-compact .quote-card,
body.density-compact .team-card { padding: 1.2rem; }
body.density-compact .cards-grid,
body.density-compact .features-grid,
body.density-compact .quotes-grid,
body.density-compact .team-grid { gap: .9rem; }

body.density-airy .section { padding: clamp(5rem, 11vw, 9rem) 0; }
body.density-airy .section-head { margin-bottom: 3.6rem; }
body.density-airy .card,
body.density-airy .feature-card,
body.density-airy .quote-card,
body.density-airy .team-card { padding: 2.4rem; }
body.density-airy .cards-grid,
body.density-airy .features-grid,
body.density-airy .quotes-grid,
body.density-airy .team-grid { gap: 2rem; }

/* ---------- Header layouts ----------
   The header is the first thing anyone sees and the one block every page
   shares, so a single composition made every site look related. Four layouts
   re-arrange the SAME two groups the markup ships — .nav-links (the pages)
   and .nav-utils (contact, account, language) — with no variant owning markup
   or copy of its own.

   Deliberately below the base header rules and above the responsive block:
   equal specificity means source order decides, and everything here is undone
   at mobile width where the burger takes over. */

.nav-links,
.nav-utils {
  display: inline-flex;
  align-items: center;
  gap: inherit;
}

/* classic — logo left, everything else right (the original). Nothing to do. */

/* split — logo in the middle, pages on the left, utilities on the right.
   The most "designed" of the four; wants a short nav, which is why the
   catalog structures keep 4–5 items. */
.header-layout--split .header-inner { position: relative; }
.header-layout--split .logo {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
.header-layout--split .site-nav {
  flex: 1;
  justify-content: space-between;
}

/* utility-bar — a thin top row for language and account, the main row below
   with the pages and the contact button. Reads as a business that expects to
   be phoned: the utilities stop competing with navigation. */
.header-layout--utility-bar .header-inner {
  flex-wrap: wrap;
  align-items: center;
  padding-top: 0;
  padding-bottom: 0;
  min-height: 0;
  row-gap: 0;
}
/* `.site-nav` dissolves so its two groups become children of .header-inner —
   otherwise `width: 100%` on the utility strip measures the nav box and the
   "two rows" collapse back into one (which is exactly what happened first
   time round, and only geometry showed it). */
.header-layout--utility-bar .site-nav { display: contents; }
.header-layout--utility-bar .nav-utils {
  order: -1;
  width: 100%;
  justify-content: flex-end;
  gap: 1.1rem;
  padding: .45rem 0;
  border-bottom: 1px solid var(--line);
  font-size: .85rem;
}
.header-layout--utility-bar .nav-links {
  flex: 1;
  justify-content: flex-end;
  gap: 1.8rem;
  min-height: 64px;
}
/* The contact button stays IN the strip rather than the main row: it lives
   inside .nav-utils, and CSS cannot lift a child out of its group — the first
   attempt "moved" it by hiding it, which simply lost the call to action.
   Contact + account + language together read as one coherent utility strip
   anyway, with the pages left alone below. */
.header-layout--utility-bar .nav-utils .btn.btn-small {
  padding: .35rem 1rem;
  font-size: .8rem;
}

/* centered — logo on its own line, navigation centred beneath it. Editorial
   and calm; suits portfolios and restaurants more than a service business. */
.header-layout--centered .header-inner {
  flex-direction: column;
  gap: .2rem;
  padding-top: 1.1rem;
  padding-bottom: .8rem;
  min-height: 0;
}
.header-layout--centered .site-nav {
  width: 100%;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.4rem;
}
.header-layout--centered .logo-mark svg { width: 40px; height: 40px; }

/* ---------- Language switcher looks ----------
   Same markup — a flat list of codes — dressed four ways. It sits in the
   header next to everything else that repeats site to site, and two letters
   in the corner are exactly the kind of detail people register without
   noticing. */

/* plain — bare codes, active in the brand colour (the original). */

/* pills — each code its own chip; the active one filled. Reads deliberate,
   suits sites where the language choice actually matters to visitors. */
.lang-switch--pills { gap: .35rem; }
.lang-switch--pills a {
  padding: .2rem .55rem;
  border-radius: 999px;
  line-height: 1.5;
}
.lang-switch--pills a:hover { background: var(--hover-wash); color: var(--ink); }
.lang-switch--pills a.is-active {
  background: var(--primary);
  color: var(--primary-ink);
}

/* divided — codes split by a hairline, the quietest way to group them. */
.lang-switch--divided { gap: .5rem; }
.lang-switch--divided a + a { position: relative; padding-left: .6rem; }
.lang-switch--divided a + a::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: .9em;
  background: var(--line);
}

/* boxed — one segmented control. The most "app-like" of the four; good when
   the header is otherwise sparse and needs an anchor on the right. */
.lang-switch--boxed {
  gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-small, 8px);
  overflow: hidden;
}
.lang-switch--boxed a {
  padding: .2rem .6rem;
  line-height: 1.6;
}
.lang-switch--boxed a + a { border-left: 1px solid var(--line); }
.lang-switch--boxed a.is-active {
  background: var(--primary);
  color: var(--primary-ink);
}

/* ---------- Contact page layouts ----------
   The form is where a visitor actually acts, and one arrangement everywhere
   made every site's most important page identical. Same markup — an info
   column and a form column — arranged four ways. */

/* split — info left, form right (the original). */

/* form-first — the form leads and takes the width; details sit beside it.
   For businesses whose visitors already know they want to write. */
.contact-grid--form-first { grid-template-columns: 1.2fr .8fr; }
.contact-grid--form-first .contact-info { order: 2; }
.contact-grid--form-first .contact-form-wrap { order: 1; }

/* stacked — details as one quiet row on top, full-width form below. The
   calmest option and the one that reads best on a narrow screen. */
.contact-grid--stacked { grid-template-columns: 1fr; gap: 2.4rem; }
.contact-grid--stacked .contact-info {
  display: flex;
  flex-wrap: wrap;
  gap: 0 2.6rem;
}
.contact-grid--stacked .info-item {
  border-bottom: 0;
  padding: 0;
  min-width: 12rem;
}

/* card — the form raised on the section tint; details centred above it.
   Draws the eye to the form without moving anything else. */
.section--contact-card { background: var(--tint); }
.contact-grid--card { grid-template-columns: 1fr; gap: 2.2rem; max-width: 720px; margin-inline: auto; }
.contact-grid--card .contact-info {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 2.4rem;
  text-align: center;
}
.contact-grid--card .info-item { border-bottom: 0; padding: .4rem 0; }
.contact-grid--card .contact-form-wrap {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 2rem;
}

/* ---------- Contact strip (home) looks ---------- */

/* inline — no card chrome, one row split by hairlines. */
.contact-cards--inline {
  grid-template-columns: 1fr;
  display: flex;
  flex-wrap: wrap;
  gap: 0;
}
.contact-cards--inline .contact-card {
  flex: 1 1 12rem;
  background: none;
  border: 0;
  border-left: 1px solid var(--line);
  border-radius: 0;
  padding: .4rem 1.6rem;
}
.contact-cards--inline .contact-card:first-child { border-left: 0; padding-left: 0; }

/* banner — one tinted band, details centred. Reads as a closing statement
   rather than a list of fields. */
.section--contacts-banner { background: var(--tint); }
.contact-cards--banner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem 3rem;
}
.contact-cards--banner .contact-card {
  background: none;
  border: 0;
  padding: 0;
  text-align: center;
}

/* ---------- Footer layouts ----------
   The footer carries every page too, and `layout.footer` only ever switched
   the whole grid on or off. These arrange the SAME three blocks — brand, menu,
   contacts — four ways. */

/* columns — brand wide, menu and contacts beside it (the original). */

/* brand-split — brand on the left, the two link groups pushed right together.
   Reads as a company signature rather than a sitemap. */
.footer-layout--brand-split .footer-grid {
  grid-template-columns: 1fr auto auto;
  gap: 3.5rem;
}

/* centered — one column, everything centred. Quiet close to a short site. */
.footer-layout--centered .footer-grid {
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: center;
  gap: 1.8rem;
}
.footer-layout--centered .footer-about { margin-inline: auto; }
.footer-layout--centered .footer-nav,
.footer-layout--centered .footer-contacts {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  gap: .5rem 1.4rem;
}
.footer-layout--centered .footer-title { width: 100%; }

/* bar — one compact line: brand, links, contacts. No titles, minimal height;
   for sites whose footer is a formality, not a directory. */
.footer-layout--bar { padding-top: 1.6rem; }
.footer-layout--bar .footer-grid {
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 2rem;
  padding-bottom: 1.4rem;
}
.footer-layout--bar .footer-title { display: none; }
.footer-layout--bar .footer-about { display: none; }
/* flex-direction is spelled out because the base rule sets `column` — without
   it the "single bar" rendered four stacked links, which is the one thing this
   layout is not. */
.footer-layout--bar .footer-nav,
.footer-layout--bar .footer-contacts {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: .4rem 1.3rem;
  font-size: .9rem;
}
.footer-layout--bar .footer-nav { justify-content: center; }
.footer-layout--bar .footer-contacts { justify-content: flex-end; }

/* ---------- Steps variants ---------- */

/* timeline — a horizontal run with a connecting rule; the numbers become the
   spine of the process instead of four separate tiles. */
.steps-grid--timeline { position: relative; gap: 1rem; }
.steps-grid--timeline::before {
  content: '';
  position: absolute;
  top: 1.15rem;
  left: 8%;
  right: 8%;
  height: 2px;
  background: var(--line);
}
.steps-grid--timeline .feature-card {
  background: none;
  border: 0;
  padding: 0 .8rem;
  text-align: center;
}
.steps-grid--timeline .feature-index {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.3rem;
  height: 2.3rem;
  margin-bottom: 1rem;
  border-radius: 999px;
  background: var(--primary);
  color: var(--primary-ink);
  font-size: .95rem;
}

/* stacked — a vertical ladder, one step per row. Best when steps carry real
   sentences rather than three words. */
.steps-grid--stacked { grid-template-columns: 1fr; gap: 0; }
.steps-grid--stacked .feature-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: .2rem 1.4rem;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 1.3rem .2rem;
}
.steps-grid--stacked .feature-index {
  grid-row: 1 / 3;
  align-self: center;
  margin: 0;
  font-size: 1.9rem;
  color: color-mix(in srgb, var(--primary) 40%, var(--bg));
}

/* ---------- Stats variants ---------- */

/* cards — each figure in its own tile. */
.stats-row--cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1.2rem;
  border-top: 0;
  padding-top: 0;
}
.stats-row--cards > div {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem;
  align-items: center;
  text-align: center;
}

/* band — a tinted full-width strip; the numbers become a statement. */
.section--stats-band { background: var(--tint); }
.stats-row--band {
  justify-content: space-around;
  border-top: 0;
  padding-top: 0;
  text-align: center;
}
.stats-row--band dd { font-size: 2.4rem; }

/* ---------- Story variants ---------- */

/* narrow — a centred reading column; the calmest way to tell it. */
.story-inner--narrow { max-width: 680px; text-align: center; }
.story-inner--narrow .lead { margin-inline: auto; }

/* quote — the opening paragraph set as a pull quote. For a founder's line or
   a promise worth slowing down for. */
.story-inner--quote .lead {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.6vw, 1.9rem);
  line-height: 1.45;
  color: var(--ink);
  border-left: 3px solid var(--mark, var(--primary));
  padding-left: 1.6rem;
  max-width: 46ch;
}

/* ---------- Section-variant responsiveness ----------
   Deliberately LAST in the file. The shared breakpoints above reset
   `.cards-grid` / `.quotes-grid` to 2 and 1 columns, and they carry the same
   specificity as the variant classes — so at equal weight the later rule
   wins, and anything placed next to the variant definitions further up would
   quietly lose on tablet. Keep these here. */

@media (max-width: 960px) {
  /* Both variants are single-column by design; the shared reset would put
     them back into a two-column grid. */
  .cards-grid--list,
  .cards-grid--alternating { grid-template-columns: 1fr; }

  .quotes-grid--spotlight { grid-template-columns: repeat(2, 1fr); }
  .gallery-grid--masonry { columns: 3; }
  .quotes-grid--strip { display: flex; }
}

@media (max-width: 640px) {
  .cards-grid--list,
  .cards-grid--alternating { grid-template-columns: 1fr; }

  /* Image over text: side-by-side at phone width leaves neither enough room,
     and the alternating rhythm is invisible in one column anyway. */
  .cards-grid--alternating .card,
  .cards-grid--alternating .card:not(:has(.card-media)) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    gap: .9rem;
  }
  .cards-grid--alternating .card-media,
  .cards-grid--alternating .card:nth-child(even) .card-media {
    grid-row: 1;
    grid-column: 1;
    max-height: 11rem;
  }
  .cards-grid--alternating .card-body,
  .cards-grid--alternating .card:nth-child(even) .card-body { grid-row: 2; grid-column: 1; }
  .cards-grid--alternating .card-foot,
  .cards-grid--alternating .card:nth-child(even) .card-foot { grid-row: 3; grid-column: 1; }

  /* The list row keeps its shape but lets the price wrap under the title
     rather than squeezing the name into two characters. */
  .cards-grid--list .card { flex-wrap: wrap; gap: .8rem; }
  .cards-grid--list .card-foot { width: 100%; justify-content: flex-start; }

  .quotes-grid--spotlight { grid-template-columns: 1fr; }

  /* Footer and step layouts collapse on a phone: three columns of links do
     not fit, and a horizontal timeline becomes a line of crushed words. */
  .footer-layout--brand-split .footer-grid,
  .footer-layout--bar .footer-grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .footer-layout--bar .footer-nav,
  .footer-layout--bar .footer-contacts { justify-content: flex-start; }

  .steps-grid--timeline::before { content: none; }
  .steps-grid--timeline .feature-card { text-align: left; padding: 0; }

  .stats-row--band { justify-content: flex-start; }

  /* Contact layouts all collapse to one column on a phone — a two-column
     form is unusable there whichever side it started on. */
  .contact-grid--form-first,
  .contact-grid--stacked,
  .contact-grid--card { grid-template-columns: 1fr; }
  .contact-grid--form-first .contact-info { order: 1; }
  .contact-grid--form-first .contact-form-wrap { order: 2; }
  .contact-cards--inline .contact-card {
    border-left: 0;
    border-top: 1px solid var(--line);
    padding: .9rem 0;
  }

  /* Below the burger breakpoint every header layout collapses to the same
     thing — logo + toggle, everything else inside the dropdown. Leaving a
     variant active here produced an absolutely-positioned logo over the
     menu button, which is the kind of break only a phone shows. */
  .header-layout--split .logo,
  .header-layout--centered .logo { position: static; transform: none; }
  .header-layout--split .header-inner,
  .header-layout--centered .header-inner,
  .header-layout--utility-bar .header-inner {
    flex-direction: row;
    flex-wrap: wrap;
    padding-top: 0;
    padding-bottom: 0;
    min-height: 78px;
  }
  .header-layout--utility-bar .nav-utils {
    order: 0;
    width: auto;
    border-bottom: 0;
    padding: 0;
  }

  /* `.site-nav` must go back to being a real box: it IS the dropdown the
     burger toggles, and `display: contents` leaves nothing to position — the
     menu items scattered into the header bar instead. Desktop-only trick,
     undone here. */
  .header-layout--utility-bar .site-nav { display: none; }
  .nav-checkbox:checked ~ .header-layout--utility-bar .site-nav,
  .header-layout--utility-bar .nav-checkbox:checked ~ .site-nav { display: flex; }

  .nav-links, .nav-utils { display: contents; }

  /* The multi-column variants collapse to one column on a phone; `columns`
     and CSS `columns:` both need saying, they are different properties. */
  .faq-list--columns { columns: 1; }
  .gallery-grid--masonry { columns: 2; }
  .rate-list--cards { grid-template-columns: 1fr; }
  .features-grid--numbered .feature-card { padding-right: 0; }
  .quotes-grid--spotlight .quote-card:first-child { padding: 1.6rem; }
  .quotes-grid--spotlight .quote-card:first-child blockquote { font-size: 1.25rem; }
}
