/* ── Self-hosted fonts ──────────────────────────────────────── */
@font-face {
  font-family: 'Cormorant Garamond';
  src: url('../assets/fonts/cormorant-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Oswald';
  src: url('../assets/fonts/oswald-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Oswald';
  src: url('../assets/fonts/oswald-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('../assets/fonts/montserrat-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('../assets/fonts/montserrat-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../assets/fonts/inter-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --black: #0c0c0c;
  --surface: #151515;
  --surface-2: #202020;
  --surface-3: #303030;
  --gold: #c9a84c;
  --gold-light: #e4c766;
  --text: #f8f7f3;
  --muted: #c9c9c9;
  --quiet: #969696;
  /* 4.5:1 is the minimum contrast for text below 18.7px. This value clears it
     on both dark grounds: 5.30:1 on --black, 4.95:1 on --surface. */
  --dim: #858585;
  --max: 1120px;
  --nav-h: 64px;
  /* Vertical section rhythm. --section-slice is the height of the diagonal on
     the grey sections; every edge that meets one loses half that height, which
     --section-pad-compensated adds back. */
  --section-pad-block: 60px;
  --section-slice: 40px;
  --section-pad-compensated: calc(var(--section-pad-block) + var(--section-slice) / 2);
  /* Top margin of the section heading. The label's own line contributes a
     further 16px of leading, so the visible gap is about 37px. */
  --space-label-heading: 10px;
  --font-brand: "Cormorant Garamond", serif;
  --font-head: "Oswald", sans-serif;
  --font-ui: "Montserrat", sans-serif;
  --font-copy: "Inter", sans-serif;
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--black);
  color: var(--text);
  font-family: var(--font-copy);
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: radial-gradient(ellipse 80% 40% at 50% 0%, rgba(201, 168, 76, 0.04) 0%, transparent 70%);
  pointer-events: none;
  z-index: 0;
}

/* Scroll lock for the open menu and the open gallery dialog. overflow:hidden on
   the body alone is ignored by iOS Safari, which keeps scrolling the page behind
   an overlay, so the body is pinned as well. js/site.js writes the offset into
   body.style.top and scrolls back to it on release. */
html.is-locked,
html.is-locked body {
  overflow: hidden;
}
html.is-locked body {
  position: fixed;
  inset-inline: 0;
  width: 100%;
}

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

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

button {
  font: inherit;
}

:focus-visible {
  outline: 2px solid var(--gold-light);
  outline-offset: 4px;
}

.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 999;
  transform: translateY(-160%);
  background: var(--gold);
  color: var(--black);
  padding: 10px 14px;
  font-family: var(--font-ui);
  font-weight: 800;
}

.skip-link:focus {
  transform: translateY(0);
}

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  min-height: var(--nav-h);
  background: rgba(12, 12, 12, 0.97);
  border-bottom: 1px solid #1f1f1f;
  transition: background-color 200ms ease;
  overflow: hidden;
}

/* No backdrop-filter here, deliberately. It made the header a containing block
   for its position:fixed children, so the header's own overflow:hidden clipped
   the open nav menu away: on a phone, scrolling past the hero added .is-scrolled
   and the menu became invisible while the body was still scroll-locked. At 97%
   opacity the blur was invisible anyway, and dropping it also spares the phone a
   full-width filter pass on every scroll frame. */
header.is-scrolled {
  background-color: rgba(12, 12, 12, 0.97);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}

.nav {
  width: 100%;
  max-width: 1240px;
  min-height: var(--nav-h);
  margin: 0 auto;
  padding: 0 72px 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  position: relative;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.brand img {
  width: 48px;
  height: 36px;
  object-fit: contain;
}

.brand-text {
  display: grid;
  line-height: 1;
}

.brand-name {
  font-family: var(--font-brand);
  font-size: 25px;
  letter-spacing: 0.035em;
  text-transform: uppercase;
}

.brand-sub {
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

.nav-toggle {
  position: absolute;
  right: 16px;
  top: 10px;
  width: 44px;
  height: 44px;
  border: 1px solid var(--surface-3);
  background: transparent;
  color: var(--gold);
  display: inline-grid;
  place-items: center;
  cursor: pointer;
}

.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  width: 21px;
  height: 2px;
  display: block;
  background: currentColor;
  transition: transform 160ms ease, opacity 160ms ease;
}

.nav-toggle-bars {
  position: relative;
}

.nav-toggle-bars::before,
.nav-toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-toggle-bars::before {
  top: -7px;
}

.nav-toggle-bars::after {
  top: 7px;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bars {
  background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after {
  transform: translateY(-7px) rotate(-45deg);
}

.nav-menu {
  position: fixed;
  top: var(--nav-h);
  left: 0;
  right: 0;
  display: grid;
  gap: 10px;
  padding: 14px 16px 18px;
  /* Fully opaque, not 0.99: the last percent let the page underneath ghost
     through the open menu, measurably by two levels out of 255. */
  background: #0c0c0c;
  border-bottom: 1px solid #1f1f1f;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 300ms ease, opacity 200ms ease;
}

.nav-menu.is-open {
  max-height: 520px;
  opacity: 1;
}

.nav-link {
  position: relative;
  min-height: 44px;
  display: flex;
  align-items: center;
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.nav-link::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--gold);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 200ms ease;
}
.nav-link:hover::after,
.nav-link.is-active::after {
  transform: scaleX(1);
}

.nav-link:hover,
.nav-link.is-active {
  color: var(--gold);
}

.nav-cta {
  display: none;
}

.btn,
.btn-outline,
.btn-dark {
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border-radius: 2px;
  padding: 12px 18px;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.13em;
  text-align: center;
  text-transform: uppercase;
  transition: background 160ms ease, color 160ms ease, border-color 160ms ease, transform 160ms ease;
  width: 100%;
  white-space: normal;
  min-width: 0;
  overflow-wrap: anywhere;
  cursor: pointer;
}

.btn {
  position: relative;
  overflow: hidden;
  background: var(--gold);
  color: var(--black);
  border: 1px solid var(--gold);
  box-shadow: 0 0 24px rgba(201, 168, 76, 0.16);
}

.btn:hover {
  background: var(--gold-light);
  border-color: var(--gold-light);
}

.btn-outline {
  color: var(--gold);
  border: 1px solid var(--gold);
  background: rgba(12, 12, 12, 0.38);
}

.btn-outline:hover {
  background: var(--gold);
  color: var(--black);
}

.btn-dark {
  color: var(--muted);
  border: 1px solid var(--surface-3);
  background: var(--surface);
}

.btn-dark:hover {
  border-color: var(--gold);
  color: var(--gold);
}

.btn:active,
.btn-outline:active,
.btn-dark:active {
  transform: scale(0.98);
}

.btn::after {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 60%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);
  transform: skewX(-20deg);
  transition: left 400ms ease;
}
.btn:hover::after {
  left: 150%;
}

/* ── Hero ───────────────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: 100svh;
  padding: calc(var(--nav-h) + 26px) 20px 48px;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center right;
}

.hero__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    #0c0c0c 0%,
    #0c0c0c 30%,
    rgba(12, 12, 12, 0.75) 50%,
    transparent 70%
  );
}

@media (max-width: 767px) {
  .hero {
    min-height: 100svh;
    align-items: flex-start;
  }
  .hero__bg img {
    object-position: 70% top;
  }

  .hero__bg::after {
    background: linear-gradient(
      to bottom,
      rgba(12, 12, 12, 0.92) 0%,
      rgba(12, 12, 12, 0.75) 55%,
      rgba(12, 12, 12, 0.50) 100%
    );
  }
}

.hero-inner {
  width: min(100%, 370px);
  position: relative;
  z-index: 1;
}

.eyebrow,
.section-label {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.eyebrow::before,
.section-label::before {
  content: "";
  width: 28px;
  height: 1px;
  background: rgba(201, 168, 76, 0.48);
}

.hero h1 {
  margin: 18px 0 0;
  font-family: var(--font-head);
  font-size: clamp(2.85rem, 12vw, 5.25rem);
  line-height: 0.9;
  letter-spacing: 0;
  text-transform: uppercase;
  max-width: 100%;
}

.hero h1 span {
  display: block;
  color: var(--gold);
  font-size: 0.62em;
  margin-top: 0.14em;
}

.hero-copy {
  width: min(100%, 620px);
  margin: 20px 0 0;
  color: var(--muted);
  font-family: var(--font-copy);
  font-size: 15px;
}

.hero-actions,
.cta-row {
  display: grid;
  gap: 10px;
  margin-top: 22px;
}

.trust-strip {
  display: grid;
  gap: 10px;
  margin-top: 22px;
}

.stars {
  color: var(--gold);
  letter-spacing: 0.08em;
  white-space: nowrap;
}

.hero__brand-name {
  font-family: var(--font-ui);
  font-size: 0.8rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.5rem;
  margin-bottom: 1rem;
}

/* ── Hero entrance animation ────────────────────────────────── */
@keyframes heroFadeUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
  .hero__eyebrow   { animation: heroFadeUp 500ms ease-out 0ms   both; }
  .hero__heading   { animation: heroFadeUp 500ms ease-out 150ms both; }
  .hero__brand-name { animation: heroFadeUp 500ms ease-out 200ms both; }
  .hero__sub       { animation: heroFadeUp 500ms ease-out 300ms both; }
  .hero__actions   { animation: heroFadeUp 500ms ease-out 450ms both; }
  .hero__trust     { animation: heroFadeUp 500ms ease-out 550ms both; }
}

/* ── Scroll reveal ──────────────────────────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  .js-reveal {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 400ms ease-out, transform 400ms ease-out;
  }
  .js-reveal.is-visible {
    opacity: 1;
    transform: none;
  }
  .js-reveal:nth-child(2) { transition-delay: 80ms; }
  .js-reveal:nth-child(3) { transition-delay: 160ms; }
  .js-reveal:nth-child(4) { transition-delay: 240ms; }
}

/* ── Section heading underline animation ──────────────────── */
/* Block rather than inline-block: as an inline-block a short heading shares
   the line with its label instead of sitting below it, which made one section
   differ from all the others. fit-content keeps the underline at text width
   rather than full column width. */
.section-heading {
  position: relative;
  display: block;
  width: fit-content;
  max-width: 100%;
}
.section-heading::after {
  content: '';
  position: absolute;
  bottom: -6px;
  left: 0;
  height: 2px;
  width: 100%;
  background: var(--gold);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 500ms ease-out;
}
.section-heading.is-visible::after {
  transform: scaleX(1);
}

.section {
  padding-block: var(--section-pad-block);
  padding-inline: 20px;
}

.section.alt {
  background: var(--surface);
  position: relative;
  z-index: 1;
  clip-path: polygon(0 var(--section-slice), 100% 0, 100% calc(100% - var(--section-slice)), 0 100%);
  margin-block: calc(-1 * var(--section-slice));
  padding-block: var(--section-pad-compensated);
}

/* A grey section sits over its neighbour with a negative margin and clips half
   the slice height off it, so every edge meeting a diagonal gets the same
   compensation. Measured from the middle of the diagonal both sides then show
   --section-pad-block. Straight edges (hero to services, FAQ to footer) need
   no compensation and keep the base value. */
.section.alt + .section {
  padding-top: var(--section-pad-compensated);
}

.section:has(+ .section.alt) {
  padding-bottom: var(--section-pad-compensated);
}

.section-inner {
  width: min(100%, var(--max));
  margin: 0 auto;
}

.section-head {
  max-width: 760px;
  margin-bottom: 24px;
}

.section-head.compact {
  max-width: 660px;
}

.section h2,
.page h1 {
  margin: var(--space-label-heading) 0 10px;
  font-family: var(--font-head);
  font-size: clamp(2.45rem, 11vw, 4.2rem);
  line-height: 0.96;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* "Datenschutzerklärung" is a single 20-character word that Oswald sets 381px wide
   even at the smallest step, so in a 280px content column it pushed the whole page
   into a sideways scroll below roughly 400px. The break itself comes from a soft
   hyphen at the compound seam in the markup rather than from hyphens: auto, which
   picked "Datenschutzer-" instead. This is only the fallback for any other long
   word, and only on the legal pages so no heading on the start page changes. */
.page h1 {
  overflow-wrap: break-word;
}

/* Oswald places the dots of a capital umlaut about 0.24em above cap height.
   Combined with line-height 0.96 the glyph overflows its line box and crowds
   the label above it, while headings without one sit correctly. Belongs on any
   heading whose first line carries a capital umlaut. */
.section h2.has-umlaut,
.page h1.has-umlaut {
  margin-top: calc(var(--space-label-heading) + 0.26em);
}

/* :where() keeps this at element specificity, so component classes such as
   .section-intro or .hours-status still win with a single class. Written as
   .section p it outranked all of them and their colours never applied. */
:where(.section, .page) p {
  color: var(--quiet);
}

/* Deliberately in surface colour rather than gold; gold stays reserved for
   calls to action. Both chips share a minimum height so the text chip and the
   logo chip line up. */
.payment-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px 20px;
  margin-top: 20px;
  padding: 14px 20px;
  background: var(--surface);
  border: 1px solid var(--surface-2);
  border-radius: 4px;
}

.payment-strip__label {
  font-family: var(--font-ui);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--quiet);
}

.payment-methods {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.payment-method {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 0 14px;
  background: var(--black);
  border: 1px solid var(--surface-3);
  border-radius: 3px;
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

.payment-method__icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--gold);
}

/* The TWINT logo stays in its brand colours and unaltered. */
.payment-method__logo {
  display: block;
  width: auto;
  height: 18px;
}

/* Must be inline-block; the global img { display: block } would otherwise
   force the logo onto its own line below the text. */
.payment-inline-logo {
  display: inline-block;
  width: auto;
  height: 15px;
  vertical-align: -2px;
  margin-left: 3px;
}

.services-grid,
.faq-grid,
.contact-grid,
.parking-grid {
  display: grid;
  gap: 12px;
}

/* Flexbox rather than grid: with an odd number of cards the last row centres
   itself instead of hanging to the left. The flex bases are calculated to add
   up exactly alongside gap: 12px. The selector stays identical across all
   breakpoints so specificity does not shift. */
.services-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
}

.services-grid > .service-card {
  flex: 1 1 100%;
  max-width: 100%;
}

.service-card,
.faq-item,
.contact-card,
.legal-card,
.parking-card {
  background: var(--surface);
  border: 1px solid var(--surface-2);
  border-radius: 4px;
}

.service-card {
  min-height: 150px;
  padding: 16px;
  display: grid;
  /* minmax(0, 1fr) rather than 1fr lets the text column shrink below its
     min-content floor. Otherwise the non-wrapping price pushes the card past
     its track on narrow viewports and the whole document scrolls sideways. */
  grid-template-columns: 64px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  /* 120ms rather than 200: the card was reading as sluggish on the first touch.
     Only transform and border-color are animated, both cheap. The shadow is
     switched, not tweened, because animating a blur radius costs a repaint on
     every frame and was the expensive half of the old transition. */
  transition: transform 120ms ease, border-color 120ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .service-card:hover {
    transform: translateY(-4px);
    border-color: rgba(201, 168, 76, 0.45);
    box-shadow: 0 8px 24px rgba(201, 168, 76, 0.15);
  }
}

/* Touch has no hover, so the press itself is the feedback and it lands on the
   same frame as the finger. */
.service-card:active {
  transform: translateY(-2px);
  border-color: rgba(201, 168, 76, 0.45);
}

.service-card img {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: 50%;
  border: 2px solid var(--surface-3);
}

.service-title {
  margin: 0 0 4px;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 900;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.service-desc {
  margin: 0;
  font-size: 13px;
  overflow-wrap: break-word;
}

.price-block {
  min-width: 0;
  display: grid;
  gap: 4px;
  justify-items: end;
  text-align: right;
}

.price {
  color: var(--gold);
  font-family: var(--font-head);
  /* Fluid rather than a fixed 28px: the price must not wrap, so it has to
     shrink on narrow viewports instead of breaking out of the card. */
  font-size: clamp(1.25rem, 1rem + 1.2vw, 1.75rem);
  font-weight: 800;
  line-height: 1;
  white-space: nowrap;
}


.legal-card,
.parking-card,
.contact-card {
  padding: 18px;
}

.parking-card {
  transition: transform 200ms ease;
}
.parking-card:hover {
  transform: translateY(-2px);
}

.contact-card h3,
.legal-card h2,
.parking-card h3 {
  margin: 0 0 8px;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 900;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.legal-card p,
.legal-card li,
.parking-card p {
  margin: 0;
  color: var(--quiet);
  font-size: 14px;
}

.parking-card span {
  display: block;
  margin-bottom: 8px;
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Card height is driven centrally by --faq-q-lines, set per breakpoint in the
   media queries further down. Sizes in rem so the cards scale with browser
   zoom. */
.faq-grid {
  --faq-q-size: 1rem;
  --faq-q-leading: 1.45;
  --faq-q-lines: 3;
  --faq-pad-y: 18px;
  --faq-pad-x: 18px;
  align-items: start;
}

.faq-item {
  border: 1px solid var(--surface-2);
  border-radius: 6px;
  background: var(--surface);
  transition: border-color 200ms ease;
}
.faq-item:hover {
  border-color: rgba(201, 168, 76, 0.35);
}
.faq-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: var(--faq-pad-y) var(--faq-pad-x);
  /* Reserves the line count of the longest question in the current band so
     every card is exactly the same height regardless of its text. */
  min-height: calc(
    var(--faq-q-lines) * var(--faq-q-size) * var(--faq-q-leading) + 2 * var(--faq-pad-y)
  );
  cursor: pointer;
  list-style: none;
  font-family: var(--font-ui);
  color: var(--text);
}
.faq-question-text {
  margin: 0;
  font-size: var(--faq-q-size);
  font-weight: 600;
  line-height: var(--faq-q-leading);
  letter-spacing: 0.01em;
  color: inherit;
  overflow-wrap: break-word;
}
.faq-summary::-webkit-details-marker { display: none; }
.faq-summary::marker { display: none; }
.faq-chevron {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--gold);
  transition: transform 250ms ease;
}
.faq-item[open] .faq-chevron {
  transform: rotate(180deg);
}
.faq-answer {
  padding: 0 var(--faq-pad-x) var(--faq-pad-y);
  color: var(--muted);
  font-family: var(--font-copy);
  line-height: 1.65;
}

.faq-item[open] {
  box-shadow: inset 3px 0 0 var(--gold);
}

.faq-cta {
  margin-top: 2.5rem;
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--surface-2);
  border-radius: 4px;
  text-align: center;
}

.faq-cta__heading {
  margin: 0 0 18px;
  font-family: var(--font-head);
  font-size: clamp(1.3rem, 4vw, 1.8rem);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text);
}

.faq-cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
}

.faq-cta__actions .btn,
.faq-cta__actions .btn-outline {
  width: auto;
  min-width: 200px;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}

[data-gallery-item] {
  position: relative;
  overflow: hidden;
  border-radius: 4px;
}
[data-gallery-item]::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(12, 12, 12, 0);
  transition: background 200ms ease;
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  [data-gallery-item]:hover::after {
    background: rgba(12, 12, 12, 0.25);
  }
}

.gallery-item {
  min-height: 160px;
  padding: 0;
  overflow: hidden;
  border: 1px solid #242424;
  position: relative;
  background: var(--surface-2);
  cursor: zoom-in;
  /* Grid, so the picture below gets a definite height to resolve height:100%
     against. A button is inline-block by default and <picture> is inline, which
     left the percentage indefinite: the image then fell back to its intrinsic
     height while the tile kept the row height. That is the bar under image 4,
     the only one sharing a row with a taller neighbour (1080x1350 next to
     1080x1440). Chromium happened to resolve it, Safari did not. */
  display: grid;
}

.gallery-item > picture {
  display: block;
  grid-area: 1 / 1;
  min-width: 0;
  min-height: 0;
}

.gallery-item.wide {
  grid-column: span 2;
  min-height: 210px;
}

.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 220ms ease;
}

/* Only where a real pointer can hover. On a touch screen :hover sticks after a
   tap until the visitor taps something else, which reads as a laggy highlight. */
@media (hover: hover) and (pointer: fine) {
  .gallery-item:hover img {
    transform: scale(1.03);
  }
}

.gallery-item:focus-visible img {
  transform: scale(1.03);
}

.gallery-actions {
  margin-top: 14px;
}

.gallery-caption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 4px 8px;
  background: rgba(0,0,0,0.55);
  color: #fff;
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity 160ms ease;
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  .gallery-item:hover .gallery-caption {
    opacity: 1;
  }
}

.gallery-item:focus-visible .gallery-caption {
  opacity: 1;
}

/* Without a pointer there is no hover to reveal the caption, so it would never
   be readable on a phone. Show it permanently there instead. */
@media (hover: none) {
  .gallery-caption {
    opacity: 1;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0));
    padding-top: 18px;
  }
}

/* About section */
.about-grid {
  display: grid;
  gap: 32px;
}

@media (min-width: 768px) {
  .about-grid {
    /* A rem ceiling rather than a plain percentage ties the image width to the
       font size, so it keeps growing under heavy zoom once the viewport rather
       than --max bounds the container. The percentage and the sizes attribute
       in index.html have to stay in sync. */
    grid-template-columns: minmax(0, 1fr) clamp(15rem, 44%, 26rem);
    align-items: center;
  }
}

/* The top and bottom fade run parallel to the diagonal of the grey sections
   above and below, so the portrait sits in the same rhythm as the rest of the
   page. A gradient's colour bands are perpendicular to its direction, so an
   edge rising to the right needs 180deg minus the section angle rather than
   plain `to bottom`. The angle of the section diagonal is
   atan(--section-slice / viewport width) and therefore changes with the
   viewport; 5deg matches roughly 457px, the 3deg below roughly 1220px. Close
   enough to read as parallel, and deliberately subtle. */
/* Top and bottom are cut, not faded. The grey sections are clipped to a
   polygon whose edges rise to the right by atan(--section-slice / viewport
   width); the portrait uses the same polygon, so its edges are the same angle
   and read as one shape language.

   A gradient cannot do this job. The tilt only gains about 20px across the
   image while a fade needs roughly 50px to stay inside the frame, so the slope
   dissolves inside the soft band and the edge looks drawn with a ruler.

   --about-slice is that same angle expressed over the image's own width rather
   than the viewport's, which is why it changes at the breakpoints: below 768px
   the image is nearly viewport wide, from 768px it sits in the narrow column,
   and from 1152px it stops growing at 26rem while the viewport keeps going. */
.about-img {
  --about-slice: 36px;
  /* Softens the cut without hiding it. The angle matches the cut so the fade
     stays parallel to it. A gradient's 0% line runs through the corner with
     the smallest projection on its direction, which here is the top left, so
     the band would sit entirely above the cut and get clipped away: the stops
     are therefore offset inward by --about-slice, which lands the start of the
     fade exactly on the cut. Kept to a few pixels; any longer and the slope
     dissolves into the soft band again, which is what made the earlier
     gradient-only attempt read as a straight edge. */
  --about-fade-angle: 173.5deg;
  --about-fade: 12px;
  display: block;
  width: 100%;
  object-fit: cover;
  clip-path: polygon(0 var(--about-slice), 100% 0, 100% calc(100% - var(--about-slice)), 0 100%);
  -webkit-mask-image:
    linear-gradient(var(--about-fade-angle),
      transparent var(--about-slice),
      #000 calc(var(--about-slice) + var(--about-fade)),
      #000 calc(100% - var(--about-slice) - var(--about-fade)),
      transparent calc(100% - var(--about-slice))),
    linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(var(--about-fade-angle),
      transparent var(--about-slice),
      #000 calc(var(--about-slice) + var(--about-fade)),
      #000 calc(100% - var(--about-slice) - var(--about-fade)),
      transparent calc(100% - var(--about-slice))),
    linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
  mask-composite: intersect;
}

/* Below 768px the portrait is nearly viewport wide, so its width runs from
   280px to 727px and the cut angle with it, from 7.3deg down to 2.8deg. The
   cut follows the sections on its own because both scale with the viewport,
   but a gradient angle is a fixed number and cannot. Left on one value the
   fade drifts off the cut on the wider phones and collapses to a hard edge at
   one end, so the angle is stepped through the range. */
@media (min-width: 400px) {
  .about-img {
    --about-fade-angle: 175deg;
  }
}
@media (min-width: 520px) {
  .about-img {
    --about-fade-angle: 176.1deg;
  }
}
@media (min-width: 640px) {
  .about-img {
    --about-fade-angle: 176.9deg;
  }
}

/* From 768px the portrait moves into the narrow grid column. Its width tracks
   the viewport closely enough that a single value holds the angle to under a
   tenth of a degree all the way to 1151px. */
@media (min-width: 768px) {
  .about-img {
    --about-slice: 26px;
    --about-fade-angle: 175.8deg;
  }
}

/* From 1152px the image stops growing at its 26rem cap while the viewport
   carries on, so the section diagonal keeps flattening and the cut follows. */
@media (min-width: 1152px) {
  .about-img {
    --about-slice: 19px;
    /* The image is fixed at its 26rem cap here, so the cut angle is constant
       at 2.62deg and the fade can match it exactly. */
    --about-fade-angle: 177.38deg;
  }
}

.about-text p {
  margin-bottom: 12px;
  line-height: 1.7;
  color: var(--text-2, #ccc);
}

.about-text p:last-child {
  margin-bottom: 0;
}

/* fit-content, so the frame is exactly as wide as the picture inside it and no
   background shows beside a portrait shot. A zoom view must never crop, so the
   box adapts to the image rather than the image to the box. */
.gallery-dialog {
  width: fit-content;
  max-width: min(92vw, 940px);
  padding: 0;
  border: 1px solid rgba(201, 168, 76, 0.45);
  background: #070707;
  color: var(--text);
  /* Vertical drags still scroll nothing behind, horizontal ones are ours. */
  touch-action: pan-y;
}

.gallery-preload {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

[data-gallery-dialog] {
  opacity: 0;
  transition: opacity 200ms ease;
}
[data-gallery-dialog][open] {
  opacity: 1;
}

.gallery-dialog::backdrop {
  background: rgba(0, 0, 0, 0.82);
}

.gallery-dialog picture {
  display: block;
  grid-area: 1 / 1;
}

/* auto width against the two maxima: the box then carries the image's own ratio,
   so object-fit never has anything left to letterbox. */
.gallery-dialog img {
  display: block;
  width: auto;
  height: auto;
  max-width: min(92vw, 940px);
  max-height: 78vh;
  object-fit: contain;
  background: #070707;
}

/* width:0 with min-width:100% keeps the caption out of the fit-content
   calculation above, otherwise a long line would widen the frame past the
   image and put the background back beside it. */
.gallery-dialog p {
  width: 0;
  min-width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 12px 54px 16px;
  color: var(--muted);
  font-size: 14px;
  text-align: center;
}

.dialog-close,
.dialog-nav {
  position: absolute;
  z-index: 2;
  border: 1px solid rgba(201, 168, 76, 0.5);
  background: rgba(12, 12, 12, 0.82);
  color: var(--gold);
  cursor: pointer;
}

.dialog-close {
  top: 10px;
  right: 10px;
  width: 44px;
  height: 44px;
  font-size: 28px;
  line-height: 1;
}

.dialog-nav {
  top: 50%;
  width: 44px;
  height: 54px;
  transform: translateY(-50%);
  font-size: 38px;
  line-height: 1;
}

.dialog-nav.prev {
  left: 10px;
}

.dialog-nav.next {
  right: 10px;
}

.hours-card {
  display: grid;
  gap: 4px;
  max-width: 620px;
}

.hours-row {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  padding: 9px 0;
  border-bottom: 1px solid var(--surface-2);
}

.hours-row:last-child {
  border-bottom: 0;
}

.hours-day {
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 800;
}

.hours-time {
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 800;
  text-align: right;
  white-space: nowrap;
}

.hours-time.closed {
  color: var(--dim);
}

.hours-today {
  background: rgba(201, 168, 76, 0.08);
}
.hours-today .hours-day {
  color: var(--gold-light);
  font-weight: 700;
}
.hours-today .hours-time {
  color: var(--gold-light);
  font-weight: 700;
}

.contact-list {
  display: grid;
  gap: 8px;
  margin: 16px 0 0;
}

.contact-list a,
.contact-list span {
  color: var(--muted);
}

/* Filled and revealed by the script. Without JavaScript the element stays
   hidden and the table of hours speaks for itself. */
.hours-status {
  margin: 0 0 12px;
  padding: 8px 12px;
  border: 1px solid var(--surface-3);
  border-left: 3px solid var(--quiet);
  background: var(--surface);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--muted);
}

.hours-status--open {
  border-left-color: var(--gold);
  color: var(--gold-light);
}

/* Contact details on the legal pages are a list, not a sentence, so the inline
   exception in WCAG 2.5.8 does not apply and the links need a full 24px target.
   The remaining source links do sit in running text and stay as they are. */
.legal-contact {
  line-height: 2.1;
}

.legal-contact a {
  display: inline-block;
  min-height: 24px;
  padding-block: 3px;
}

/* WCAG 2.2 AA, criterion 2.5.8: controls need at least 24 x 24 CSS pixels.
   This enlarges the hit area, not the type. */
.icon-line,
.footer-links a,
.footer-contact-line a,
.contact-line a,
.grw-cta {
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  vertical-align: middle;
}
.icon--gold { color: var(--gold); }

.contact-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.icon-line .icon:not(svg) {
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  display: inline-grid;
  place-items: center;
  color: var(--gold);
  border: 1px solid rgba(201, 168, 76, 0.38);
  border-radius: 50%;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 900;
}

.map-consent {
  min-height: 300px;
  display: grid;
  place-items: center;
  margin-top: 18px;
  padding: 18px;
  text-align: center;
  /* The first declaration is the fallback for browsers without image-set().
     From the set the browser takes the first format it recognises: AVIF, then
     WebP, then JPEG. */
  background:
    linear-gradient(rgba(12, 12, 12, 0.74), rgba(12, 12, 12, 0.9)),
    url("../assets/gallery/baerbershop_store.jpg") center / cover;
  background:
    linear-gradient(rgba(12, 12, 12, 0.74), rgba(12, 12, 12, 0.9)),
    image-set(
      url("../assets/gallery/baerbershop_store.avif") type("image/avif"),
      url("../assets/gallery/baerbershop_store.webp") type("image/webp"),
      url("../assets/gallery/baerbershop_store.jpg") type("image/jpeg")
    ) center / cover;
  border: 1px solid var(--surface-2);
}

.map-consent iframe {
  width: 100%;
  height: 450px;
  border: 0;
  display: block;
}

.map-consent p {
  max-width: 520px;
  margin: 0 auto 16px;
}

.sticky-actions {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: #050505;
  border-top: 1px solid #262626;
}

.sticky-actions a {
  min-height: 54px;
  display: grid;
  place-items: center;
  color: var(--black);
  background: var(--gold);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.sticky-actions a:last-child {
  color: var(--gold);
  background: var(--surface);
}

.site-footer {
  padding-top: 3.5rem;
  padding-bottom: 2rem;
  padding-left: 16px;
  padding-right: 16px;
  background: #080808;
  border-top: 1px solid #1f1f1f;
}

.footer-grid {
  width: min(100%, var(--max));
  margin: 0 auto;
  display: grid;
  gap: 24px;
}

.footer-title {
  margin: 0 0 10px;
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.footer-links {
  display: grid;
  gap: 8px;
  color: var(--dim);
  font-size: 13px;
}

.footer-links a:hover {
  color: var(--gold);
}

.footer-logo-link { display: inline-block; margin-bottom: 12px; }
.footer-logo-link img { max-width: 110px; height: auto; }
.footer-tagline {
  font-family: var(--font-head);
  font-size: 0.85rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 6px;
}
.footer-desc {
  font-size: 0.82rem;
  color: var(--dim);
  line-height: 1.5;
  max-width: 220px;
}

.footer-contact-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 0.875rem;
  color: var(--muted);
}

/* Brand colours, hence an image rather than an icon. Height matched to the
   13px line of the footer links. */
.footer-payment-logo {
  display: block;
  width: auto;
  height: 16px;
}

.footer-bottom {
  border-top: 1px solid rgba(201, 168, 76, 0.18);
  margin-top: 2rem;
  padding-top: 1.25rem;
  color: var(--dim);
  font-size: 0.8rem;
  padding-left: 0;
  padding-right: 0;
}

.footer-bottom-inner {
  width: min(100%, var(--max));
  margin: 0 auto;
}

.page {
  padding: calc(var(--nav-h) + 38px) 20px 64px;
}

.page-inner {
  width: min(100%, 860px);
  margin: 0 auto;
}

/* Error page. Kept here rather than as style attributes in 404.html so the
   Content-Security-Policy can do without 'unsafe-inline' for style-src. */
.page-inner--centered {
  text-align: center;
}

.error-lead {
  max-width: 480px;
  margin: 1.25rem auto 2.5rem;
}

.legal-card {
  margin-top: 14px;
}

.legal-date {
  color: var(--dim);
  font-size: 0.8rem;
  margin-top: 2rem;
}

.legal-card ul {
  margin: 10px 0 0;
  padding-left: 20px;
}

.legal-card li + li {
  margin-top: 7px;
}

@media (max-width: 560px) {
  .brand-name {
    font-size: 22px;
  }

  .hero h1 {
    font-size: 2.25rem;
  }

  .section h2,
  .page h1 {
    font-size: 2.2rem;
  }

  .btn,
  .btn-outline,
  .btn-dark {
    font-size: 11px;
    letter-spacing: 0.09em;
  }

  .eyebrow,
  .section-label {
    font-size: 9px;
    letter-spacing: 0.16em;
  }

  .service-card {
    /* minmax(0, ...) here too, otherwise the text column reclaims its
       min-content floor and the card breaks out of its track at 320px. */
    grid-template-columns: 56px minmax(0, 1fr) auto;
    min-height: 110px;
    padding: 14px 12px;
  }

  .price-block {
    min-width: 0;
  }

  .sticky-actions a {
    font-size: 10px;
    letter-spacing: 0.09em;
  }
}

/* Three columns stop working somewhere below 360px. At 320px the avatar, the
   two gaps, the padding and the price leave the text 101px: a one-sentence
   description wraps into nine lines, and the two long titles run 25 and 33px
   into the price. Dropping the price onto its own row is the same move the
   card already makes from 1024px up, and it takes the text from 101 to 184px at
   320px and from 140 to 224px at 360px. */
@media (max-width: 360px) {
  .service-card {
    grid-template-columns: 56px minmax(0, 1fr);
  }

  /* Column 2 explicitly: auto-placement would otherwise drop the price under
     the avatar, into the empty cell of the second row. */
  .price-block {
    grid-column: 2;
    justify-items: start;
  }
}

@media (min-width: 560px) {
  .hero-inner {
    width: min(100%, var(--max));
    margin: 0 auto;
  }

  .hero-actions,
  .cta-row {
    display: flex;
    flex-wrap: wrap;
  }

  .btn,
  .btn-outline,
  .btn-dark {
    width: fit-content;
  }

  .parking-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 768px) {
  :root {
    --section-pad-block: 76px;
    --section-slice: 64px;
  }

  .nav {
    padding: 0 28px;
  }

  .hero {
    padding-left: 40px;
    padding-right: 40px;
  }

  .hero-copy {
    font-size: 18px;
  }

  .trust-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }

  /* Inline padding only: the block padding comes from the tokens above, and
     the padding shorthand would overwrite the diagonal compensation. */
  .section {
    padding-inline: 40px;
  }

  /* The legal pages need their own inline padding from 768px up. */
  .page {
    padding-left: 40px;
    padding-right: 40px;
  }


  .price-block {
    justify-items: center;
    text-align: center;
  }

  .gallery-grid {
    grid-template-columns: 1.25fr repeat(3, 1fr);
  }

  .gallery-item,
  .gallery-item.wide {
    min-height: 220px;
  }

  .gallery-item.wide {
    grid-row: span 2;
    grid-column: auto;
    min-height: 448px;
  }

  .contact-grid {
    grid-template-columns: 0.9fr 1.1fr;
    align-items: stretch;
  }

  .site-footer {
    padding-bottom: 2rem;
  }

  /* Up to 1023px the four text groups form a 2x2 block beside the brand
     column. Five columns would leave roughly 120px each and wrap the address
     over four lines; four would strand one group alone in the second row. */
  .footer-grid {
    grid-template-columns: 1.2fr 0.9fr 0.9fr;
    align-items: start;
  }

  .footer-brand {
    grid-row: span 2;
  }
}

@media (min-width: 1024px) {
  .footer-grid {
    grid-template-columns: 1.2fr repeat(4, 0.9fr);
  }

  .footer-brand {
    grid-row: auto;
  }
}

/* The horizontal menu bar starts at 900px. Below that the logo and the first
   item come within 8px of each other and two entries wrap onto a second line,
   so the burger menu stays in place up to 900px. */
@media (min-width: 900px) {
  :root {
    --nav-h: 72px;
  }

  .nav-toggle {
    display: none;
  }

  .nav-menu {
    position: static;
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 0;
    background: transparent;
    border: 0;
    max-height: none;
    overflow: visible;
    opacity: 1;
    transition: none;
  }

  .nav-link {
    min-height: var(--nav-h);
    font-size: 11px;
  }

  .nav-cta {
    display: inline-flex;
    min-height: 40px;
    padding: 9px 16px;
  }

}

@media (min-width: 900px) and (max-width: 1150px) {
  .nav {
    padding: 0 12px;
    gap: 8px;
  }
  .nav-menu {
    gap: 10px;
  }
  .nav-link {
    font-size: 10px;
    letter-spacing: 0.1em;
  }
  .nav-cta {
    padding: 8px 10px;
    font-size: 10px;
    letter-spacing: 0.06em;
    min-height: 36px;
  }
  .brand-name {
    font-size: 21px;
  }
}

@media (min-width: 1024px) {
  .hero-inner {
    padding-top: 22px;
  }

  /* All five services in one continuous row. A single row has one height, one
     top edge and one bottom edge, and flexbox stretches every card to match.
     Basis: (100% - 4 * 12px gap) / 5 = 20% - 9.6px. */
  .services-grid > .service-card {
    flex: 1 1 calc(20% - 9.6px);
    max-width: calc(20% - 9.6px);
  }

  /* Three rows: image, text, price. The middle row takes the free space, so
     the price always sits at the bottom edge and all five prices align,
     however long the description is. */
  .service-card {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto;
    justify-items: center;
    /* start rather than the inherited center: otherwise the text block centres
       in its track and a heading above longer text drifts upward. The image
       and price tracks are auto-height, where start changes nothing. */
    align-items: start;
    text-align: center;
    min-height: 250px;
    padding: 18px 12px;
  }
}

@media (max-width: 359px) {
  .hero h1,
  .hero__heading {
    font-size: 1.9rem;
  }
}

@media (min-width: 560px) and (max-width: 767px) {
  .gallery-grid {
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }
}

.sticky-actions {
  padding: 10px 16px;
  gap: 10px;
}
.sticky-actions a {
  border-radius: 6px;
  font-size: 0.875rem;
  min-height: 44px;
}

/* The bar is fixed and would cover the copyright line at the end of the page.
   The offset on body keeps the footer clear; env() additionally accounts for
   the home indicator zone on edge-to-edge devices. From 900px the bar is gone
   and so is the offset. :has() limits the offset to pages that actually carry
   the bar, so the legal pages get no dead space below their footer. */
@media (max-width: 899px) {
  body:has(.sticky-actions) {
    padding-bottom: calc(65px + env(safe-area-inset-bottom, 0px));
  }
}

@media (min-width: 900px) {
  .sticky-actions {
    display: none;
  }
}

.section-intro {
  color: var(--muted);
  max-width: 52ch;
  line-height: 1.6;
  margin-bottom: 2rem;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    transition: none !important;
  }
}

/* ── FAQ: equal card heights per breakpoint ──
   --faq-q-lines is the number of lines the longest question needs in the
   narrowest column of each band. While the value is correct, every card is
   exactly the same height regardless of its text. If a question grows longer,
   raise the value for the affected band.
   Two columns only from 900px: below that the columns get narrow enough that
   the longest question needs three lines instead of two, making every card
   needlessly tall. */

/* Small phones: slightly smaller question type and tighter padding so the
   longest question still fits the reserved three lines at 320px, without
   relying on hyphenation, which is not available in every engine. */
@media (max-width: 360px) {
  .faq-grid {
    --faq-q-size: 0.9375rem;
    --faq-pad-x: 14px;
  }
}

/* Two lines only from 430px. With the 20px inline padding of the sections the
   longest question still wraps onto three lines at 414px. */
@media (min-width: 430px) {
  .faq-grid {
    --faq-q-lines: 2;
  }
}

@media (min-width: 900px) {
  .faq-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}


/* ── Payment strip: more compact on narrow displays ── */
@media (max-width: 560px) {
  .payment-strip {
    flex-direction: column;
    gap: 10px;
    padding: 14px;
  }
  .payment-method {
    font-size: 0.78rem;
    padding: 0 12px;
  }
}

/* ── Map consent: separate the two buttons ── */
.map-consent-btns {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  margin-top: 4px;
}
.map-consent-btns .btn,
.map-consent-btns .btn-dark {
  min-width: 200px;
}

/* ── Trust strip: equal-width pills on mobile ── */
@media (max-width: 559px) {
  .trust-strip {
    display: grid;
  }
  .google-widget-badge {
    width: 100%;
    box-sizing: border-box;
  }
}

/* ── Hours row: ensure badge in day label looks right ── */
.hours-row {
  padding: 10px 0;
}

/* ── Google widget badge (hero trust strip) ─────────────── */
.google-widget-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: rgba(14, 14, 14, 0.94);
  border: 1px solid rgba(201, 168, 76, 0.3);
  border-radius: 6px;
  transition: border-color 160ms ease, background 160ms ease, transform 160ms ease, box-shadow 160ms ease;
  min-width: 0;
  width: fit-content;
  text-decoration: none;
}
.google-widget-badge:hover {
  border-color: rgba(201, 168, 76, 0.65);
  background: rgba(14, 14, 14, 1);
  transform: translateY(-1px);
  box-shadow: 0 4px 18px rgba(201, 168, 76, 0.12);
}
.gwb-glogo {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}
.gwb-content {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gwb-label {
  font-family: var(--font-ui);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--quiet);
  white-space: nowrap;
}
.gwb-row {
  display: flex;
  align-items: center;
  gap: 5px;
}
.gwb-stars {
  color: var(--gold);
  font-size: 12px;
  letter-spacing: 0.06em;
  line-height: 1;
}
.gwb-count {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* Trust strip: same height for both pills */
.trust-strip {
  align-items: stretch;
}
/* ── Mobile: equalize google badge and address pill height ── */
@media (max-width: 559px) {
  .google-widget-badge {
    min-height: 60px;
    align-items: center;
  }
}

/* ── Footer membership badge (Coiffure Suisse) ──────────── */
.footer-membership {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  margin-top: 14px;
  padding: 8px 10px 6px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  text-decoration: none;
  transition: border-color 160ms ease, background 160ms ease;
  width: fit-content;
}
.footer-membership:hover {
  border-color: rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.05);
}
.footer-membership-label {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.footer-membership-logo {
  display: block;
  width: 130px;
  height: auto;
  mix-blend-mode: screen;
}

/* ── Footer Google reviews badge ────────────────────────── */
.footer-google-badge {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  margin-top: 0;
  padding: 8px 10px 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.03);
  text-decoration: none;
  transition: border-color 160ms ease, background 160ms ease;
  width: fit-content;
}
.footer-google-badge:hover {
  border-color: rgba(201, 168, 76, 0.45);
  background: rgba(255, 255, 255, 0.05);
}
.fgb-label {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.fgb-row {
  display: flex;
  align-items: center;
  gap: 6px;
}
.fgb-glogo {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.fgb-score {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 800;
  color: var(--text);
}
.fgb-stars {
  font-family: var(--font-ui);
  color: var(--gold);
  font-size: 11px;
  letter-spacing: 0.05em;
  line-height: 1;
}

/* ── Footer badge pair wrapper ───────────────────────────── */
.footer-badges {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

@media (min-width: 768px) {
  .footer-badges {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
  }
}

/* ── Google Reviews Widget (bewertungen section) ─────────── */
.grw {
  max-width: 480px;
}
.grw-card {
  background: var(--surface);
  border: 1px solid var(--surface-2);
  border-radius: 10px;
  padding: 24px;
  display: grid;
  gap: 20px;
}
.grw-header {
  display: flex;
  align-items: center;
  gap: 14px;
}
.grw-glogo {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
}
.grw-header-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.grw-biz-name {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--text);
}
.grw-verified {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  color: var(--quiet);
}
.grw-check-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.grw-score-area {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 0;
  border-top: 1px solid var(--surface-2);
  border-bottom: 1px solid var(--surface-2);
}
.grw-big-score {
  font-family: var(--font-head);
  font-size: 52px;
  font-weight: 800;
  color: var(--gold);
  line-height: 1;
}
.grw-score-right {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.grw-big-stars {
  color: var(--gold);
  font-size: 22px;
  letter-spacing: 0.08em;
  line-height: 1;
}
.grw-review-count {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.grw-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transition: color 160ms ease, gap 160ms ease;
}
.grw-cta:hover {
  color: var(--gold-light);
  gap: 12px;
}
.grw-cta .icon {
  width: 14px;
  height: 14px;
  color: inherit;
}

/* ── SVG sprite holder ───────────────────────────────────────
   Carries <symbol> definitions only. Kept out of flow rather than
   display:none, which would stop some browsers rendering the <use>. */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* ── Kundenstimmen: score card beside the quotes ─────────────
   One column up to 900px, two from there: the score card holds the left
   column, the three Google quotes stack in the right one. */
.rev-layout {
  display: grid;
  /* minmax(0, 1fr) rather than an implicit auto track: the slider's flex row
     of three cards has a very wide max-content size, and an auto track sizes
     itself from that, which pushed the whole column past the viewport on
     narrow screens. An explicit zero minimum keeps the track shrinkable. */
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
}
/* One quote at a time, swiped horizontally. Scroll snap does the work; the
   dots and arrows only drive scrollLeft, so touch, trackpad, keyboard and
   the buttons all converge on the same state. */
.rev-slider {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  /* While stacked above the quotes, the slider takes the score card's own
     480px measure so the column has a single right edge instead of two. */
  max-width: 480px;
}
.rev-viewport {
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* The dots and arrows are the affordance, so the native bar can go. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  border-radius: 10px;
}
.rev-viewport::-webkit-scrollbar {
  display: none;
}
.rev-viewport:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}
.rev-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 16px;
  /* stretch, so every card is as tall as the longest quote and the slider
     keeps its height while paging */
  align-items: stretch;
}
.rev-item {
  flex: 0 0 100%;
  min-width: 0;
  scroll-snap-align: start;
}

.rev-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.rev-dots {
  display: flex;
  align-items: center;
  gap: 8px;
}
.rev-dot {
  position: relative;
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--surface-3);
  cursor: pointer;
  transition: background 160ms ease, transform 160ms ease;
}
/* The visible dot is 8px, far under a comfortable touch target, so the hit
   area is widened without moving the dot itself. */
.rev-dot::before {
  content: "";
  position: absolute;
  inset: -9px;
}
.rev-dot:hover {
  background: var(--dim);
}
.rev-dot[aria-current="true"] {
  background: var(--gold);
  transform: scale(1.35);
}
.rev-dot:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 4px;
}

.rev-arrows {
  display: flex;
  gap: 8px;
}
.rev-arrow {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--surface-2);
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  transition: color 160ms ease, border-color 160ms ease;
}
.rev-arrow svg {
  width: 16px;
  height: 16px;
}
.rev-arrow:hover:not(:disabled) {
  color: var(--gold);
  border-color: rgba(201, 168, 76, 0.45);
}
.rev-arrow:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}
.rev-arrow:disabled {
  opacity: 0.35;
  cursor: default;
}
.rev-card {
  margin: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  /* Top aligned on purpose. The quotes differ by a factor of four in length,
     so centring them looked tidier on a single card but moved the avatar, the
     name, the stars and the Google mark to a different height on every slide,
     which is very visible while paging. A fixed anchor beats balanced
     whitespace here: the slack goes to the bottom of the short cards. */
  justify-content: flex-start;
  gap: 14px;
  padding: 20px;
  background: var(--surface);
  border: 1px solid var(--surface-2);
  border-radius: 10px;
}
.rev-head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.rev-avatar {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(201, 168, 76, 0.12);
  border: 1px solid rgba(201, 168, 76, 0.28);
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 800;
  line-height: 1;
}
.rev-ident {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
  margin-right: auto;
}
.rev-name {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--text);
}
.rev-stars {
  color: var(--gold);
  font-size: 13px;
  letter-spacing: 0.08em;
  line-height: 1;
}
.rev-glogo {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  align-self: flex-start;
}
.rev-quote {
  margin: 0;
  font-family: var(--font-copy);
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--muted);
}
.rev-quote p {
  margin: 0;
}

/* On the narrowest phones the longest name wrapped to a second line, which
   made that one header taller and pushed its quote below the others. Slightly
   tighter type and gaps keep every name on one line, so the header stays the
   same height on every slide. */
@media (max-width: 380px) {
  .rev-head {
    gap: 10px;
  }
  .rev-name {
    font-size: 12px;
    letter-spacing: 0.02em;
  }
}

/* 900px, not a tablet width: below that the two tracks cannot both stay
   readable. A 360px score card, the 28px gap and a quote column wide enough
   for about 50 characters per line need roughly 890px of viewport; under
   that the stacked layout gives the quotes a better measure. */
@media (min-width: 900px) {
  /* A percentage rather than a fixed track, so the score card keeps its
     proportion on a wide screen. The 360px floor is what the card needs to
     hold "aus 130+ Google Bewertungen" on one line beside the 5.0. */
  .rev-layout {
    grid-template-columns: minmax(360px, 36%) minmax(0, 1fr);
    gap: 28px;
    align-items: start;
  }
  .rev-layout .grw {
    max-width: none;
  }
  .rev-slider {
    max-width: none;
  }
  /* The right column runs wider than the stacked measure, so the card is
     capped to keep the line length readable. The controls take the same cap,
     otherwise the arrows sit past the card's right edge. */
  .rev-card,
  .rev-controls {
    max-width: 640px;
  }
  .rev-quote {
    font-size: 15.5px;
  }
}

/* ── Print ───────────────────────────────────────────────────
   The legal pages, the address and the opening hours do get printed or filed
   as PDF. On paper: no dark ground, no controls, and external link targets
   spelled out. */
@media print {
  :root {
    --black: #ffffff;
    --surface: #ffffff;
    --surface-2: #ffffff;
    --surface-3: #cccccc;
    --text: #000000;
    --muted: #222222;
    --quiet: #333333;
    --dim: #444444;
    --gold: #705500;
    --gold-light: #705500;
  }

  html { scroll-behavior: auto; }

  body {
    background: #fff;
    color: #000;
    padding-bottom: 0;
  }

  body::before { display: none; }

  .site-header,
  .nav-toggle,
  .sticky-actions,
  .skip-link,
  .gallery-grid,
  .gallery-actions,
  .gallery-dialog,
  .map-consent,
  .cta-row,
  .faq-cta,
  .hero__bg,
  .payment-strip { display: none !important; }

  /* No offset surfaces on paper: the diagonal, the negative margins and the
     matching padding compensation all fall away. !important because
     .section.alt and .section:has(+ .section.alt) are more specific. */
  .section,
  .section.alt,
  .page {
    padding: 0 0 1.5rem !important;
    margin-block: 0 !important;
    clip-path: none !important;
    page-break-inside: avoid;
  }

  .service-card,
  .faq-item,
  .contact-card,
  .legal-card,
  .parking-card {
    border: 1px solid #999;
    page-break-inside: avoid;
  }

  /* Expand every FAQ answer, otherwise the content is missing on paper */
  .faq-item .faq-answer { display: block !important; }
  .faq-chevron { display: none; }

  /* Spell out external link targets; there is no clicking on paper */
  main a[href^="http"]::after,
  footer a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }
  a[href^="tel:"]::after,
  a[href^="#"]::after { content: ""; }

  .js-reveal { opacity: 1 !important; transform: none !important; }
}
