/* ==========================================================================
   Francisco Hair Salon — Landing Page
   Mobile-first CSS. Breakpoints: ~375px (base) -> 768px (tablet) ->
   1024px (header nav switches from hamburger to inline, per 02-wireframe) ->
   1280px (notebook grids/hero split) -> 1440px (desktop, container caps at 1240px).
   Design tokens/typography per 02-wireframe-ux-ui.md, "Identidade visual da página".
   ========================================================================== */

/* ---------- Self-hosted fonts (latin subset only) ----------
   Both files are the real variable fonts from Google Fonts, downloaded and served from this
   origin — no third-party request, no render-blocking stylesheet on another host.
   Only the latin subset ships: the site is English-only, so latin-ext/vietnamese would be
   bytes nobody renders. Fraunces is pinned to optical size 48 rather than carrying the full
   9..144 opsz axis, which alone cost 33 KB — 48 is what the browser's automatic optical
   sizing would pick for the h1 anyway (3rem = 48px), so headings look the same.
   font-weight ranges are declared so the variable axis still interpolates 400-600 / 400-700.
   swap: text paints immediately in the fallback and re-renders when the font lands. */
@font-face {
  font-family: "Fraunces";
  src: url("../assets/fonts/fraunces-latin.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Manrope";
  src: url("../assets/fonts/manrope-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- Design tokens ---------- */
:root {
  --cream: #FAF6F0;
  --bg-alt: #F2EAD9;
  --surface: #FFFDF8;
  --text: #241C15;
  --text-dim: #675A4A;
  --accent: #8A6423;
  --accent-dark: #5C4419;
  --accent-text: #7A5619;
  --specialty: #6B2E3A;
  --line: #E4D8C2;
  /* Star gold for the Google Reviews block — same family as --accent, lifted just enough to
     read as gold rather than bronze against white cards (contrast checked on #fff). */
  --gold: #B4893C;

  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --space-1: .5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
  --space-6: 4rem;
  --space-7: 6rem;
  --space-8: 8rem;

  --radius-sm: .5rem;
  --radius-md: .75rem;
  --radius-pill: 999px;

  --shadow-btn: 0 14px 28px rgba(36, 28, 21, .22);
  --shadow-card: 0 10px 30px rgba(36, 28, 21, .08);

  --section-pad-y: 4rem;
  --header-h: 4.5rem;

  /* Page grid, consumed by .container and by the hero's desktop grid (see .hero at 80rem). */
  --container-max: 77.5rem; /* 1240px */
  --container-pad: 1.25rem;

  /* .whatsapp-float geometry, also consumed by .site-footer's padding-bottom below (both the
     <1024px and the >=1024px rule) — single source of truth so the footer's clearance can
     never silently drift out of sync with the float's real size/position again (see the two
     BUG FIX comments on .site-footer). --whatsapp-rest is the float's resting `bottom` (used
     >=1024px, where .is-lifted never applies — see js/main.js); --whatsapp-lift is its lifted
     `bottom`, above the mobile sticky-cta-bar (used <1024px). */
  --whatsapp-size: 3.5rem;
  --whatsapp-rest: 1.25rem;
  --whatsapp-lift: 4.75rem;
}

@media (min-width: 48rem) { :root { --section-pad-y: 5.5rem; } }
@media (min-width: 80rem) { :root { --section-pad-y: 7rem; } }

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + 1rem); }
body {
  margin: 0;
  background: var(--cream);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden; /* safety net only — every element below is built to fit the container */
}
img { max-width: 100%; display: block; }
ul, ol { list-style: none; margin: 0; padding: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1, h2, h3, p, dl, dd, figure { margin: 0; }

/* ---------- Typography ---------- */
h1, h2, h3 { font-family: var(--font-display); font-weight: 600; color: var(--text); }
h1 { font-size: clamp(2rem, 5.5vw, 3.5rem); line-height: 1.1; letter-spacing: -.01em; }
h2 { font-size: clamp(1.75rem, 3.4vw, 2.5rem); line-height: 1.15; letter-spacing: -.01em; }
h3 { font-size: 1.3rem; line-height: 1.3; }
p { color: var(--text); }

/* ---------- Layout ---------- */
/* --container-max/--container-pad are read back by the hero's desktop grid so its copy column
   can reproduce this exact centring offset — keep the three in sync here, not by hand. */
.container { max-width: var(--container-max); margin: 0 auto; padding: 0 var(--container-pad); } /* 1240px cap */
.container--narrow { max-width: 46rem; }
.center { text-align: center; }
.section { padding-block: var(--section-pad-y); }
.section--surface { background: var(--surface); }
.section__head { max-width: 40rem; margin-bottom: var(--space-5); }
.section__head.center, .center .section__head { margin-inline: auto; text-align: center; }
.section__intro { margin-top: var(--space-2); color: var(--text-dim); font-size: 1.05rem; }
.section__cta { margin-top: var(--space-5); text-align: center; }
.section__cta p { font-family: var(--font-display); font-size: 1.3rem; margin-bottom: var(--space-2); }

/* ---------- Accessibility helpers ---------- */
.skip-link {
  position: absolute; left: 1rem; top: -3rem;
  background: var(--text); color: var(--cream);
  padding: .75rem 1.25rem; border-radius: var(--radius-sm);
  z-index: 1000; transition: top .2s ease;
}
.skip-link:focus { top: 1rem; }

:focus-visible { outline: 3px solid var(--accent-text); outline-offset: 2px; border-radius: 4px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Scroll reveal (progressive enhancement; precedent: rs-lymphatic-universe) ---------- */
.reveal { opacity: 1; transform: none; }
html.has-js .reveal { opacity: 0; transform: translateY(16px); transition: opacity .5s ease, transform .5s ease; }
html.has-js .reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html.has-js .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- Placeholder badge (visible but tasteful) ---------- */
.placeholder-badge {
  position: absolute; left: .625rem; bottom: .625rem; z-index: 3;
  background: rgba(36, 28, 21, .72); color: var(--cream);
  font-size: .625rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: .3rem .6rem; border-radius: var(--radius-pill);
  backdrop-filter: blur(2px);
  pointer-events: none;
}
.placeholder-badge--compare { left: auto; right: .625rem; bottom: .625rem; }

/* ---------- Buttons ---------- */
.btn {
  position: relative; overflow: hidden; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 2.75rem; padding: 1rem 2rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body); font-weight: 600; font-size: .95rem; line-height: 1;
  white-space: nowrap;
  transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease, color .18s ease;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.btn::after {
  content: ""; position: absolute; z-index: -1; inset: 0;
  background: linear-gradient(105deg,transparent 30%,rgba(255,255,255,.26) 48%,transparent 66%);
  transform: translateX(-115%); transition: transform .48s ease;
}
.btn:active { transform: scale(.975); }
.btn:active::after { transform: translateX(115%); transition-duration: .3s; }
@media (hover:hover) { .btn:hover::after { transform: translateX(115%); } }
.btn--solid {
  background: linear-gradient(135deg, var(--accent), var(--accent-dark));
  color: var(--cream);
}
.btn--solid:hover { transform: translateY(-2px); box-shadow: var(--shadow-btn); }
.btn--solid:active { transform: none; box-shadow: none; }

.btn--outline {
  background: transparent; color: var(--text); border: 1.5px solid var(--text);
}
.btn--outline:hover { background: var(--text); color: var(--cream); }

.btn--whatsapp-solid { background: var(--text); color: var(--cream); }
.btn--whatsapp-solid:hover { transform: translateY(-2px); box-shadow: var(--shadow-btn); }

.btn--icon {
  min-height: 2.75rem; min-width: 2.75rem; padding: 0; border-radius: 50%;
  color: var(--text);
}
.btn--icon:hover { background: var(--bg-alt); }

.btn--lg { padding: 1.1rem 2.5rem; font-size: 1rem; }
.btn--block { width: 100%; }
.btn--inverted { background: var(--cream); color: var(--accent-dark); }
.btn--inverted:hover { background: var(--surface); box-shadow: 0 14px 28px rgba(0,0,0,.18); }

/* ---------- Badges ---------- */
.badge { display: inline-block; }
.badge--eyebrow {
  text-transform: uppercase; letter-spacing: .14em; font-size: .75rem; font-weight: 700;
  color: var(--accent-text); margin-bottom: .5rem;
}
/* No white pill here. Two reasons: on the ivory hero the near-white capsule read as a stray
   white bar, and inside .hero__content's flex column an inline-block badge is stretched to the
   full column width — so the capsule spanned the whole hero instead of hugging its text.
   align-self:flex-start kills the stretch; the rest matches the eyebrow every other section uses. */
.badge--hero {
  align-self: flex-start;
  text-transform: uppercase; letter-spacing: .14em; font-size: .75rem; font-weight: 700;
  color: var(--accent-text); margin-bottom: var(--space-2);
}
.badge--specialty {
  position: absolute; top: .75rem; left: .75rem; z-index: 2;
  background: var(--specialty); color: var(--cream);
  padding: .4rem .85rem; border-radius: var(--radius-pill);
  font-size: .7rem; font-weight: 700; letter-spacing: .04em;
}

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--header-h);
}
/* Official logo — two variants, both with a transparent field so the artwork sits directly
   on whatever surface it lands on, never as a visible rectangle:
     logo-francisco-on-light  dark + gold lettering  -> header, mobile nav (light surfaces)
     logo-francisco-on-dark   white + gold lettering -> footer (the one dark surface)
   Same artwork in both; only the lettering flips, because black type would vanish on the
   dark footer and white type would vanish on the cream header. Height is fixed and width
   is auto, so the 877:646 artwork can never stretch or crop. */
.brand { display: inline-flex; align-items: center; }
.brand__logo {
  height: 2.9rem; width: auto; object-fit: contain;
}
.brand__logo--sm { height: 2.5rem; }
@media (min-width: 64rem) { .brand__logo { height: 3.15rem; } }

.main-nav { display: none; }
.main-nav__list { display: flex; gap: var(--space-4); }
.main-nav__list a { color: var(--text-dim); font-weight: 500; font-size: .95rem; transition: color .15s ease; }
.main-nav__list a:hover { color: var(--text); }

.site-header__ctas { display: none; align-items: center; gap: .5rem; }

.hamburger {
  display: flex; flex-direction: column; justify-content: center; gap: .3rem;
  width: 2.75rem; height: 2.75rem; align-items: center;
}
.hamburger__bar { width: 1.5rem; height: 2px; background: var(--text); border-radius: 2px; transition: transform .2s ease, opacity .2s ease; }

/* Mobile off-canvas nav */
.mobile-nav-overlay {
  position: fixed; inset: 0; background: rgba(36, 28, 21, .45); z-index: 199;
}
.mobile-nav {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 200;
  width: min(20rem, 85vw);
  background: var(--surface);
  padding: var(--space-3);
  display: flex; flex-direction: column; gap: var(--space-4);
  overflow-y: auto;
  box-shadow: -10px 0 30px rgba(36,28,21,.15);
}
/* The [hidden] attribute is how JS toggles this panel — without this rule, the
   author-stylesheet `display: flex` above wins over the UA's default
   `[hidden]{display:none}` (author rules beat UA rules regardless of
   specificity), leaving the panel in the layout and intercepting clicks even
   while "closed". Caught via automated Playwright test on 2026-07-28. */
.mobile-nav[hidden] { display: none; }
.mobile-nav__top { display: flex; align-items: center; justify-content: space-between; }
.mobile-nav__close { width: 2.75rem; height: 2.75rem; display: flex; align-items: center; justify-content: center; }
.mobile-nav__list { display: flex; flex-direction: column; gap: var(--space-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding-block: var(--space-3); }
.mobile-nav__list a { font-family: var(--font-display); font-size: 1.4rem; display: block; padding: .25rem 0; }
.mobile-nav__ctas { display: flex; flex-direction: column; gap: var(--space-2); }

@media (min-width: 64rem) { /* 1024px — header nav switches from hamburger to inline, per wireframe */
  .main-nav { display: block; }
  .site-header__ctas { display: flex; }
  .hamburger { display: none; }
  .mobile-nav, .mobile-nav-overlay { display: none !important; }
}

/* ---------- Hero ---------- */
.hero { display: flex; flex-direction: column; }
.hero__media { position: relative; padding: var(--space-3) var(--space-2) 0; }
/* The hero photo is a 4:5 portrait. The frame carries that exact ratio at every
   breakpoint, so object-fit never has anything to crop and the whole shot —
   including the client's neck and shoulders — stays in frame.
   On phones the full-bleed 4:5 would eat ~56% of the viewport, so it is capped and
   centred as an editorial portrait card instead, using the site's card language. */
.hero__img {
  display: block; width: 100%; height: auto; aspect-ratio: 1122 / 1402; object-fit: cover;
  max-width: 18rem; margin-inline: auto;
  border-radius: var(--radius-md); box-shadow: var(--shadow-card);
}

@media (min-width: 48rem) { /* 768px — more room, so the portrait can breathe */
  .hero__img { max-width: 22rem; }
}
.hero__content { padding-block: var(--space-5); text-align: left; }
.hero__title { margin-bottom: var(--space-2); }
.hero__subtitle { color: var(--text-dim); font-size: 1.1rem; max-width: 38rem; margin-bottom: var(--space-2); }
.hero__credential { color: var(--text-dim); font-size: .9rem; font-weight: 600; margin-bottom: var(--space-3); }
.hero__ctas { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.hero-copy--desktop { display: none; }
.hero-copy--mobile { display: inline; }
@media (max-width: 47.99rem) {
  .hero__credential { color: var(--text); font-size: .88rem; letter-spacing: .01em; }
}
@media (min-width: 48rem) {
  .hero-copy--desktop { display: inline; }
  .hero-copy--mobile { display: none; }
}

@media (min-width: 80rem) { /* 1280px — editorial split, photo column sized by the 4:5 portrait */
  /* Grid, not the old row-reverse flex row, for two reasons the flex version could not solve:

     1. Alignment. The copy has to start on the site's own left gutter — the same x as the
        header logo and every section below — while the photo still bleeds to the viewport's
        right edge. Column 1 reproduces .container's centring exactly: (100% - container) / 2
        plus .container's own padding. The percentage resolves against .hero's width, which is
        the very box .container centres inside, so the two can never drift. (A padding-left on
        a flex row would have to use 100vw, which includes the scrollbar and lands ~8px off.)
        Before this, .hero__content was a .container inside a flex item, so it centred inside
        the leftover space instead — at 1792px the h1 sat at x=41 while the rest of the page
        started at x=288.
     2. Proportion. Column 3 grows with the viewport (34%, floor 24rem, ceiling 40rem) instead
        of being capped at 31rem. The old cap meant that past ~1460px the photo stopped growing
        and simply detached itself against the right edge, leaving ~800px of empty ivory
        between the copy and the picture.

     align-items:center, and no min-height: the row is exactly as tall as the photo (or the
     copy, whichever wins). A floor taller than the portrait left ivory slivers above and
     below it, and stretch would force object-fit to crop the 4:5 back to the row's ratio. */
  .hero {
    display: grid;
    grid-template-columns:
      /* NOT `100% - --container-pad * 2` in the min(): box-sizing is border-box globally, so
         .container's max-width already includes its own padding. Subtracting it again made the
         copy sit up to 7.5px right of every other section whenever the viewport was narrow
         enough for 100% to win the min() — i.e. below ~1295px, a live band since this grid
         starts at 1280px. Above that the 1240px cap wins either way and the bug is invisible. */
      calc((100% - min(var(--container-max), 100%)) / 2 + var(--container-pad))
      minmax(0, 1fr)
      clamp(24rem, 34%, 40rem);
    align-items: center;
  }
  /* grid-row is explicit because .hero__media comes first in the DOM (it is the LCP image and
     is preloaded); without it, auto-placement would put the two on separate rows. */
  .hero__media { grid-column: 3; grid-row: 1; min-width: 0; max-width: none; padding: 0; }
  /* Overrides the .container it also carries: the grid owns the offset now, and the right
     padding is what keeps the h1 off the photo's edge. */
  .hero__content {
    grid-column: 2; grid-row: 1;
    max-width: none; margin: 0; padding: 0 var(--space-5) 0 0;
  }
  /* Full-bleed against the right edge here, so the card treatment is dropped. */
  .hero__img { max-width: none; border-radius: 0; box-shadow: none; }
}

/* ---------- Checklist (About) ---------- */
.checklist { display: flex; flex-direction: column; gap: .75rem; margin-top: var(--space-3); }
.checklist li { display: flex; align-items: flex-start; gap: .6rem; color: var(--text); }
/* Explicit width/height is required here: these inline SVGs have no HTML
   width/height attribute, and without a CSS size either, browsers fall back
   to an oversized default replaced-element box (~300px) that blew out the
   layout width on every breakpoint. Caught via automated Playwright test. */
.checklist__icon { flex: none; width: 1.125rem; height: 1.125rem; color: var(--accent); margin-top: .15rem; }

/* ---------- About ---------- */
.about__grid { display: grid; gap: var(--space-4); }
.about__media { position: relative; border-radius: var(--radius-md); overflow: hidden; }
.about__media img { border-radius: var(--radius-md); width: 100%; height: auto; aspect-ratio: 4/5; object-fit: cover; }
.about__text p { color: var(--text-dim); margin-bottom: var(--space-2); }

@media (min-width: 64rem) {
  .about__grid { grid-template-columns: 1fr 1fr; align-items: center; gap: var(--space-6); }
}

/* ---------- Service cards ---------- */
/* Flex, not grid: with 7 cards a 3-column grid leaves the last one alone against two empty
   tracks, and CSS grid has no way to centre a partial final row. Flex wrapping with the same
   computed column widths lays out identically when a row is full, and centres the leftovers
   when it is not. The featured card sits outside this container and is unaffected. */
.services__grid { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3); margin-top: var(--space-4); }
.services__grid > .service-card { flex: 1 1 100%; }
.service-card {
  background: var(--surface); border-top: 3px solid var(--accent);
  border-radius: var(--radius-md); padding: var(--space-3);
  box-shadow: var(--shadow-card);
  display: flex; flex-direction: column; gap: .5rem;
  position: relative;
}
.service-card__icon { width: 2rem; height: 2rem; color: var(--accent); margin-bottom: .25rem; } /* see .checklist__icon comment above — same oversized-default-SVG issue */
.service-card h3 { font-size: 1.15rem; }
.service-card p { color: var(--text-dim); font-size: .95rem; flex: 1; }
.service-card__cta { color: var(--accent-text); font-weight: 600; font-size: .9rem; margin-top: .25rem; }
.service-card__cta:hover { text-decoration: underline; }

.service-card--featured {
  border-top: 3px solid var(--specialty);
  margin-top: var(--space-4);
  padding: 0; overflow: hidden;
  display: block;
}
.service-card--featured .service-card__media { position: relative; }
/* height:auto is load-bearing: the <img> carries a height="576" attribute, which counts as a
   definite height and makes the browser ignore aspect-ratio entirely — the card rendered
   335x576 on mobile (a 16:9 photo squeezed into a portrait box) instead of 335x188. */
.service-card--featured .service-card__media img { width: 100%; height: auto; aspect-ratio: 16/9; object-fit: cover; }
.service-card--featured .service-card__body { padding: var(--space-3); }
.service-card--featured h3 { font-family: var(--font-display); font-size: 1.5rem; margin-bottom: .5rem; }
.service-card--featured p { color: var(--text-dim); }

@media (min-width: 48rem) { .services__grid > .service-card { flex: 0 1 calc((100% - var(--space-3)) / 2); } }
@media (min-width: 80rem) { .services__grid > .service-card { flex: 0 1 calc((100% - 2 * var(--space-3)) / 3); } }

/* ---------- Before & After compare slider ---------- */
/* 28rem, not 30rem: the Precision Cut pair comes from a 718px-wide source, so its panels are only
   303px across natively — the narrowest of the three. Capping the frame near the other pairs'
   native width (448/457px) keeps that one from being upscaled further than it already is. */
.compare-carousel { max-width: 28rem; margin: 0 auto; }
.compare-track { position: relative; }
.compare-pair[hidden] { display: none; }
.compare-frame {
  position: relative; aspect-ratio: 4/5; border-radius: var(--radius-md); overflow: hidden;
  --pos: 50%;
  box-shadow: var(--shadow-card);
}
.compare-layer {
  position: absolute; inset: 0; display: flex; align-items: flex-end; padding: var(--space-2);
}
.compare-layer span {
  color: var(--cream); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; font-size: .75rem;
  background: rgba(36,28,21,.45); padding: .35rem .75rem; border-radius: var(--radius-pill);
}
/* BUG FIX (2026-07-29, found via real Playwright screenshot review while implementing Correction 1):
   .compare-layer's default flex alignment puts every label at the bottom-LEFT of its own full-size
   box. .compare-layer--after is clipped to the left `--pos`% (its label correctly stays inside that
   visible region), but .compare-layer--before is never clipped — its true *visible* area is the
   RIGHT side (`--pos`% to 100%, wherever --after doesn't cover it), so a bottom-left label was
   always rendered underneath the opaque --after layer, invisible at any slider position. This
   affected all 3 pairs already (including "Hair Systems", untouched by this edit) — not something
   introduced here, just made newly visible while re-testing this section. Anchored top-right instead
   of bottom-right specifically to clear .placeholder-badge--compare, which already occupies the
   frame's bottom-right corner (the two were overlapping there in an earlier version of this fix). */
.compare-layer--before { background: linear-gradient(160deg, #C9B79A, var(--text-dim)); align-items: flex-start; justify-content: flex-end; }
.compare-layer--after { clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
/* Real client transformations, all supplied by the salon from its own posts (2026-07-31/08-01).
   Each pair's two panels are cropped from one source image, from the regions carrying no text
   overlay or trading-name banner, so the slider's own Before/After labels are the only ones.
   Every panel is cropped to exactly 4:5, matching .compare-frame, so `cover` has nothing to
   slice off — it just fills the frame edge to edge. The earlier panels were ~0.51 wide-to-tall
   and had to use `contain`, which left the photo floating in the middle of the frame with wide
   bars beside it and made the whole comparison read as small. */
.compare-layer--photo { background-size: cover; background-position: center; background-repeat: no-repeat; }
.compare-layer--cut-before {
  background-color: #5C4E4D;
  background-image: image-set(url("../assets/photos/cut-before.webp") type("image/webp"), url("../assets/photos/cut-before.jpg") type("image/jpeg"));
}
.compare-layer--cut-after {
  background-color: #6E5556;
  background-image: image-set(url("../assets/photos/cut-after.webp") type("image/webp"), url("../assets/photos/cut-after.jpg") type("image/jpeg"));
}
.compare-layer--transform-before {
  background-color: #D0D1CB;
  background-image: image-set(url("../assets/photos/transformation-before.webp") type("image/webp"), url("../assets/photos/transformation-before.jpg") type("image/jpeg"));
}
.compare-layer--transform-after {
  background-color: #C8C9C4;
  background-image: image-set(url("../assets/photos/transformation-after.webp") type("image/webp"), url("../assets/photos/transformation-after.jpg") type("image/jpeg"));
}
.compare-layer--beard-before {
  background-color: #623C2F;
  background-image: image-set(url("../assets/photos/beard-before.webp") type("image/webp"), url("../assets/photos/beard-before.jpg") type("image/jpeg"));
}
.compare-layer--beard-after {
  background-color: #865F52;
  background-image: image-set(url("../assets/photos/beard-after.webp") type("image/webp"), url("../assets/photos/beard-after.jpg") type("image/jpeg"));
}
.compare-divider { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 2px; background: var(--surface); transform: translateX(-1px); z-index: 4; pointer-events: none; }
.compare-input {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; z-index: 5;
  appearance: none; -webkit-appearance: none; background: transparent; cursor: ew-resize;
}
.compare-input::-webkit-slider-runnable-track { -webkit-appearance: none; background: transparent; height: 100%; }
.compare-input::-moz-range-track { background: transparent; height: 100%; border: 0; }
.compare-input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 2.75rem; height: 2.75rem; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--accent);
  box-shadow: var(--shadow-btn); cursor: ew-resize;
  margin-top: 0;
}
.compare-input::-moz-range-thumb {
  width: 2.75rem; height: 2.75rem; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--accent);
  box-shadow: var(--shadow-btn); cursor: ew-resize;
}
.compare-caption { text-align: center; margin-top: var(--space-2); font-weight: 600; color: var(--text-dim); }

.compare-nav { display: flex; align-items: center; justify-content: center; gap: var(--space-3); margin-top: var(--space-3); }
.compare-arrow {
  width: 2.75rem; height: 2.75rem; border-radius: 50%; background: var(--surface);
  display: flex; align-items: center; justify-content: center; box-shadow: var(--shadow-card);
  color: var(--text);
}
.compare-arrow:hover { background: var(--bg-alt); }
.compare-dots { display: flex; gap: .5rem; }
.compare-dot { width: .6rem; height: .6rem; border-radius: 50%; background: var(--line); padding: 0; min-height: auto; }
.compare-dot.is-active { background: var(--accent); }

/* ---------- Google Reviews ----------
   Black / white / subtle gold, on the site's existing cream canvas. Mobile is a real
   scroll-snap carousel (native touch swipe, no JS needed to move); >=48rem it becomes a
   plain grid and the dots hide themselves. Cards are equal-height via flex so the author
   line always sits on the baseline regardless of quote length. */
.reviews__grid {
  display: grid; grid-template-columns: 1fr; gap: var(--space-3);
  margin: 0; padding: 0; list-style: none;
}
.review-card {
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--line);
  border-radius: 1rem; padding: var(--space-3);
  box-shadow: var(--shadow-card);
  transition: transform .25s ease, box-shadow .25s ease;
}
@media (hover: hover) {
  .review-card:hover { transform: translateY(-3px); box-shadow: 0 18px 40px rgba(36, 28, 21, .13); }
}
.review-card__top { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; }
.review-card__source {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .78rem; font-weight: 700; letter-spacing: .04em;
  color: var(--text-dim); text-transform: uppercase;
}
.g-mark { width: 1rem; height: 1rem; flex: none; }
.review-card__tag {
  font-size: .68rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent-text); background: var(--bg-alt);
  padding: .25rem .55rem; border-radius: var(--radius-pill);
}
.review-card__stars { display: flex; gap: .18rem; color: var(--gold); margin: var(--space-2) 0; }
.review-card__stars .star { width: 1.05rem; height: 1.05rem; }
.review-card__body { margin: 0; display: flex; flex-direction: column; flex: 1; }
.review-card__body blockquote { margin: 0; flex: 1; }
.review-card__body blockquote p { color: var(--text-dim); font-size: .95rem; line-height: 1.7; }
.review-card__author {
  display: flex; align-items: center; gap: .6rem;
  margin-top: var(--space-3); padding-top: var(--space-2);
  border-top: 1px solid var(--line);
}
.review-card__avatar {
  display: grid; place-items: center; flex: none;
  width: 2.25rem; height: 2.25rem; border-radius: 50%;
  background: var(--text); color: var(--cream);
  font-family: var(--font-display); font-size: 1rem; line-height: 1;
}
.review-card__name { font-weight: 600; font-size: .92rem; color: var(--text); }

/* Carousel dots (mobile only) */
.reviews__dots { display: flex; justify-content: center; gap: .5rem; margin-top: var(--space-3); }
.reviews__dots[hidden] { display: none; }
.reviews__dot {
  width: .5rem; height: .5rem; border-radius: 50%; padding: 0; min-height: auto;
  background: var(--line); transition: background .2s ease, transform .2s ease;
}
.reviews__dot.is-active { background: var(--gold); transform: scale(1.35); }

/* <48rem: horizontal swipe carousel */
@media (max-width: 47.99rem) {
  .reviews__grid {
    display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
    gap: var(--space-2); padding-bottom: .5rem;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .reviews__grid::-webkit-scrollbar { display: none; }
  .review-card { flex: 0 0 86%; scroll-snap-align: center; }
}

@media (min-width: 48rem) { .reviews__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .reviews__grid { grid-template-columns: repeat(3, 1fr); } }

/* ---------- Reviews page (reviews.html) ---------- */
.reviews-hero { padding-bottom: var(--space-4); }
.reviews-hero h1 { margin-top: var(--space-2); }
.breadcrumb { font-size: .85rem; color: var(--text-dim); margin-bottom: var(--space-3); }
.breadcrumb a { color: var(--accent-text); font-weight: 600; }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb span[aria-hidden] { margin: 0 .4rem; color: var(--line); }

/* The full list is 7 cards, so it stays a vertical stack on mobile instead of a 7-step
   swipe: the carousel is for the 3-card teaser on the home page, where swiping is a
   feature — here it would bury five reviews behind gestures. */
.reviews__grid--page { display: grid; }
@media (max-width: 47.99rem) {
  .reviews__grid--page { display: grid; grid-template-columns: 1fr; gap: var(--space-3); overflow: visible; }
  .reviews__grid--page .review-card { flex: initial; }
}
.review-card--featured { border-color: var(--gold); box-shadow: 0 14px 36px rgba(180, 137, 60, .18); }

/* ---------- FAQ ---------- */
.faq-list { display: flex; flex-direction: column; gap: var(--space-2); }
.faq-item {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}
.faq-item summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  font-family: var(--font-display); font-size: 1.05rem; font-weight: 500;
  min-height: 2.75rem; padding-block: .5rem;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item .plus { flex: none; width: 1.125rem; height: 1.125rem; color: var(--accent); transition: transform .2s ease; } /* see .checklist__icon comment above — same oversized-default-SVG issue */
.faq-item[open] .plus { transform: rotate(45deg); }
.faq-item p { color: var(--text-dim); padding-top: .5rem; padding-bottom: .5rem; }
.faq__link { text-align: center; margin-top: var(--space-3); }
.faq__link a { color: var(--text-dim); font-size: .9rem; }
.faq__link a:hover { text-decoration: underline; }

/* ---------- Booking ---------- */
.booking { background: var(--bg-alt); }
.booking-steps { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-5); }
.booking-steps li { display: flex; gap: var(--space-2); align-items: flex-start; }
.booking-steps__num {
  flex: none; width: 2.5rem; height: 2.5rem; border-radius: 50%;
  background: var(--accent); color: var(--cream); font-family: var(--font-display); font-weight: 600;
  display: flex; align-items: center; justify-content: center;
}
.booking-steps h3 { font-size: 1.1rem; margin-bottom: .2rem; }
.booking-steps p { color: var(--text-dim); font-size: .95rem; }
.booking-cta { text-align: center; }
.booking-cta__note { color: var(--text-dim); font-size: .85rem; margin-top: var(--space-2); }
.calendar-preview {
  margin-top: var(--space-5);
  border: 2px dashed var(--text-dim); border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-3);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  color: var(--text-dim); text-align: center;
}
.booking-secondary { text-align: center; margin-top: var(--space-4); }

@media (min-width: 48rem) {
  .booking-steps { flex-direction: row; }
  .booking-steps li { flex: 1; flex-direction: column; text-align: center; align-items: center; }
}

/* ---------- WhatsApp / Contact ---------- */
.whatsapp-contact p { color: var(--text-dim); margin-block: var(--space-2) var(--space-4); }

/* ---------- Location & Contact ---------- */
.location__grid { display: grid; gap: var(--space-4); }
.location__info p { color: var(--text-dim); margin-block: var(--space-2) var(--space-3); }
.contact-list__row { display: flex; align-items: center; gap: .75rem; padding-block: .5rem; border-bottom: 1px solid var(--line); }
.contact-list__row:last-child { border-bottom: 0; }
.contact-list__row dt { color: var(--accent); flex: none; display: flex; }
.contact-list__row dd a { font-weight: 600; }
.contact-list__row dd a:hover { text-decoration: underline; }
.location__cta { margin-top: var(--space-3); }
/* The button carries an icon + label, so it needs to lay them out inline like .btn--icon does. */
.location__cta .btn { display: inline-flex; align-items: center; gap: .5rem; }
.location__map { position: relative; border-radius: var(--radius-md); overflow: hidden; height: 15rem; }
.location__map iframe { width: 100%; height: 100%; border: 0; }
/* Real pin drawn in CSS at the exact center of the map — the iframe below uses ll= (coordinate-centered,
   no info card) instead of q= (address-driven info card) specifically to avoid Google's own mislabeled city
   name for this address (see the HTML comment above the iframe). Centering guarantees accuracy without
   depending on Google's reverse-geocoded text at all. */
.location__map__pin {
  position: absolute; top: 50%; left: 50%; z-index: 2;
  transform: translate(-50%, -100%);
  color: var(--specialty);
  filter: drop-shadow(0 3px 5px rgba(36, 28, 21, .45));
  pointer-events: none;
}

@media (min-width: 64rem) {
  .location__grid { grid-template-columns: 40% 1fr; align-items: stretch; }
  .location__map { height: auto; }
}

/* ---------- Instagram ---------- */
.instagram-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; }
.instagram-tile { display: block; aspect-ratio: 1/1; overflow: hidden; border-radius: var(--radius-sm); }
.instagram-tile img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
.instagram-tile:hover img { transform: scale(1.05); }
.instagram__link { text-align: center; margin-top: var(--space-4); }
.instagram__link a { color: var(--accent-text); font-weight: 600; }
.instagram__link a:hover { text-decoration: underline; }

@media (min-width: 48rem) { .instagram-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 80rem) { .instagram-grid { grid-template-columns: repeat(6, 1fr); } }

/* ---------- Final CTA band ---------- */
.cta-final {
  padding-block: var(--space-6);
  background: linear-gradient(135deg, var(--accent), var(--accent-dark));
  color: var(--cream);
}
.cta-final h2 { color: var(--cream); margin-bottom: var(--space-2); }
.cta-final p { color: rgba(250, 246, 240, .85); margin-bottom: var(--space-3); }
.cta-final__secondary { margin-top: var(--space-3); }
.cta-final__secondary a { color: var(--cream); text-decoration: underline; font-size: .9rem; }

/* ---------- Footer ---------- */
.site-footer { background: var(--text); color: var(--cream); padding-block: var(--space-5); }
/* BUG FIX (2026-07-29, qa-auditor-final — found via real Playwright getBoundingClientRect() at 375px,
   scrolled to the end of the page): below 1024px, both .sticky-cta-bar AND .whatsapp-float.is-lifted
   stay fixed over the bottom of the viewport. The previous padding here (var(--space-5) + a guessed
   4.5rem) only budgeted for the sticky bar's own height — but once lifted, the WHATSAPP FLOAT is the
   taller of the two: its top edge sits at var(--whatsapp-lift) + var(--whatsapp-size) = 8.25rem above
   the viewport bottom, while the old padding only cleared 7.5rem, so the float's bottom ~12px silently
   overlapped the footer's last line ("© 2026 Francisco Hair Salon..."). Fixed by deriving this padding
   directly from the float's own geometry (--whatsapp-lift/--whatsapp-size in :root) instead of an
   independent guess, plus --space-2 of real breathing room above the float's top edge — the two values
   can never drift apart again because they share the same source. */
@media (max-width: 63.99rem) {
  .site-footer {
    padding-bottom: calc(var(--whatsapp-lift) + var(--whatsapp-size) + var(--space-2) + env(safe-area-inset-bottom, 0px));
  }
}
/* BUG FIX (2026-07-29, lp-auditor revalidation of the fix above — never actually tested
   >=1024px, where every prior screenshot/evidence was <1024px): .is-lifted only ever applies
   below 63.99rem (js/main.js's `stickyBarActive` check) because .sticky-cta-bar itself is
   display:none from 64rem up — so at >=1024px .whatsapp-float sits at its RESTING position
   instead (bottom: var(--whatsapp-rest) = 1.25rem), needing --whatsapp-rest + --whatsapp-size
   = 4.75rem of clearance. The base padding-block above only reserves var(--space-5) = 3rem at
   this width (nothing overrode it here), a ~28px deficit — the exact same class of bug as the
   mobile one above, just unnoticed because it was never tested past 1024px. Same fix: derive
   the clearance from the float's own geometry instead of leaving it to the un-overridden base
   value, so the two can never drift apart again. */
@media (min-width: 64rem) {
  .site-footer {
    padding-bottom: calc(var(--whatsapp-rest) + var(--whatsapp-size) + var(--space-2));
  }
}
.site-footer__inner { display: flex; flex-direction: column; gap: var(--space-2); text-align: center; }
/* Footer is the one dark surface on the page, so it gets logo-francisco-on-dark (white +
   gold lettering, transparent field) — it sits directly on the dark brown with no card
   behind it. No shadow/radius: there is no box to shape, only the artwork. */
.site-footer__logo {
  height: 5.25rem; width: auto; object-fit: contain; margin: 0 auto;
}
@media (min-width: 64rem) { .site-footer__logo { margin: 0; } }
.site-footer__brand p { color: rgba(250, 246, 240, .7); font-size: .85rem; margin-top: .25rem; }
.site-footer__nap { color: rgba(250, 246, 240, .8); font-size: .9rem; }
.site-footer__nap a:hover { text-decoration: underline; }
.site-footer__copy { color: rgba(250, 246, 240, .5); font-size: .8rem; }

@media (min-width: 48rem) {
  .site-footer__inner { flex-direction: row; align-items: center; justify-content: space-between; text-align: left; }
}

/* ---------- Sticky mobile CTA bar + WhatsApp float ---------- */
.sticky-cta-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  background: var(--surface); border-top: 1px solid var(--line);
  padding: .75rem 1.25rem; padding-bottom: max(.75rem, env(safe-area-inset-bottom));
  transform: translateY(100%); transition: transform .25s ease;
}
.sticky-cta-bar.is-visible { transform: translateY(0); }

.whatsapp-float {
  position: fixed; right: var(--whatsapp-rest); bottom: var(--whatsapp-rest); z-index: 95;
  width: var(--whatsapp-size); height: var(--whatsapp-size); border-radius: 50%;
  background: var(--text); color: var(--cream);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-btn);
  opacity: 0; pointer-events: none; transform: scale(.85);
  transition: transform .2s ease, opacity .2s ease, bottom .25s ease;
}
.whatsapp-float.is-visible { opacity: 1; pointer-events: auto; transform: scale(1); }
.whatsapp-float:hover { transform: scale(1.06); }
/* When the sticky bar is visible on mobile, the float lifts above it so neither is covered (see
   02-wireframe, "Colisão a evitar"). --whatsapp-lift is also consumed by .site-footer's mobile
   padding-bottom (see the BUG FIX comment there) so the two can never drift out of sync again. */
.whatsapp-float.is-lifted { bottom: calc(var(--whatsapp-lift) + env(safe-area-inset-bottom, 0px)); }

@media (min-width: 64rem) {
  .sticky-cta-bar { display: none; } /* desktop/notebook: header CTA is always visible already */
}

/* ==========================================================================
   Booking page (booking.html)
   Reuses the site's tokens, buttons and header so the flow never feels like
   it left the salon's site — the single biggest drop-off risk when a booking
   step is visually a different product.
   ========================================================================== */
.booking-page { background: var(--bg-alt); }
.booking-header__aside { font-size: .9rem; color: var(--text-dim); margin-left: auto; }
.booking-header__aside a { font-weight: 600; color: var(--accent-text); }
.booking-header__aside a:hover { text-decoration: underline; }
@media (max-width: 30rem) { .booking-header__aside { display: none; } } /* the WhatsApp CTA repeats below */

.booking-main { padding-block: var(--space-5) var(--space-6); }
.booking-panel {
  background: var(--surface); border-radius: var(--radius-md);
  box-shadow: var(--shadow-card); padding: var(--space-4);
}
@media (min-width: 48rem) { .booking-panel { padding: var(--space-5); } }
.booking-panel:focus { outline: none; } /* focused programmatically after booking, not by tabbing */

#booking-form-panel { padding: 0; overflow: hidden; }
.booking-banner {
  position: relative; min-height: 9.5rem;
  overflow: hidden; background: #1c1713; color: var(--cream);
}
.booking-banner picture { position: absolute; inset: 0; }
.booking-banner img {
  width: 100%; height: 100%; object-fit: cover; object-position: center center;
}
.booking-banner::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(23,18,15,.97) 0%, rgba(23,18,15,.64) 34%, rgba(23,18,15,.08) 52%);
}
.booking-banner__copy {
  position: absolute; z-index: 1; inset: 0 58% 0 0;
  display: grid; place-content: center; justify-items: center;
  padding: 1rem .55rem; text-align: center;
}
.booking-banner__copy span {
  color: #d2b674; font-size: .56rem; font-weight: 800;
  letter-spacing: .11em; text-transform: uppercase;
}
.booking-banner__copy h1 {
  margin: .35rem 0 0; color: white;
  font-size: clamp(1.08rem, 5vw, 1.45rem); line-height: 1.02;
}
#booking-form-panel .booking-intro,
#booking-form-panel form { padding-inline: var(--space-4); }
#booking-form-panel form { padding-bottom: var(--space-4); }

.booking-intro { margin: 1rem 0 1.15rem; }
.booking-intro h1 { font-size: clamp(1.6rem, 4.5vw, 2.2rem); margin-top: .25rem; }
.booking-intro .section__intro { margin-bottom: 0; font-size: .9rem; }
.booking-trust {
  display: flex; flex-wrap: wrap; gap: .45rem 1rem; margin-top: var(--space-2);
  color: var(--text-dim); font-size: .82rem;
}
.booking-trust li { display: inline-flex; align-items: center; gap: .4rem; }
.booking-trust li::before {
  content: ""; width: .42rem; height: .42rem; flex: none;
  border-radius: 50%; background: var(--gold);
}

@media (max-width: 47.99rem) {
  .booking-page { --header-h: 3.9rem; }
  .booking-page .brand__logo { height: 2.55rem; }
  .booking-main {
    flex: 1; display: flex; width: 100%;
    padding-block: .65rem .65rem;
  }
  .booking-main > .container { flex: 1; display: flex; min-height: 0; }
  #booking-form-panel[hidden],
  #booking-confirm-panel[hidden],
  #booking-offline-panel[hidden] { display: none !important; }
  #booking-form-panel {
    width: 100%; display: flex; flex-direction: column;
  }
  .booking-confirm, .booking-offline { width: 100%; }
  .booking-banner { height: 6.5rem; min-height: 0; }
  .booking-banner__copy { padding: .45rem; }
  .booking-banner__copy span { font-size: .49rem; }
  .booking-banner__copy h1 { font-size: .94rem; }
  #booking-form-panel .booking-intro,
  #booking-form-panel form { padding-inline: .85rem; }
  #booking-form-panel form {
    flex: 1; display: grid; grid-template-columns: 1fr;
    align-content: space-between;
    gap: .4rem; padding-top: .65rem; padding-bottom: .8rem;
  }
  #booking-form-panel .field { min-width: 0; margin-bottom: 0; }
  #booking-form-panel .field label,
  #booking-form-panel .field__label { margin-bottom: .08rem; font-size: .68rem; }
  #booking-form-panel .field input,
  #booking-form-panel .field select {
    min-height: 2.55rem; padding: .5rem .7rem;
    border-radius: .42rem; font-size: .76rem;
  }
  #booking-form-panel .select-wrap select { padding-right: 1.8rem; }
  #booking-form-panel .select-wrap__chev { right: .55rem; }
  #booking-form-panel .btn--block { min-height: 2.65rem; margin-top: .08rem; }
  #booking-form-panel .booking-help { margin-top: 0; font-size: .68rem; line-height: 1.2; }
  .booking-page .site-footer { padding-block: .65rem; }
  .booking-page .site-footer .container {
    display: flex; align-items: center; justify-content: center;
    gap: .75rem; text-align: center;
  }
  .booking-page .site-footer p { margin: 0; }
}

/* Booking and confirmation fill one screen on phones and tablets when the form
   fits, but must scroll when it doesn't: a day with many time slots makes the
   form taller than the viewport, and a hard `overflow: hidden` lock hid the
   "Confirm appointment" button with no way to reach it. */
@media (max-width: 63.99rem) {
  html:has(.booking-page),
  .booking-page { height: auto; overflow-y: auto; }
  .booking-page { min-height: 100svh; }
  .booking-page .booking-main { min-height: 0; }
}

@media (min-width: 48rem) and (max-width: 63.99rem) {
  .booking-page { --header-h: 4.4rem; }
  .booking-page .brand__logo { height: 2.8rem; }
  .booking-main { flex: 1; display: flex; width: 100%; padding-block: .7rem; }
  .booking-main > .container { flex: 1; display: flex; min-height: 0; }
  #booking-form-panel[hidden],
  #booking-confirm-panel[hidden],
  #booking-offline-panel[hidden] { display: none !important; }
  #booking-form-panel { width: 100%; display: flex; flex-direction: column; }
  .booking-banner { height: 8rem; min-height: 0; }
  .booking-banner__copy { padding: .6rem; }
  #booking-form-panel form {
    flex: 1; display: grid; grid-template-columns: repeat(2,minmax(0,1fr));
    align-content: center; gap: .55rem .8rem;
    padding: .8rem 1.25rem 1rem;
  }
  #booking-form-panel .field { min-width: 0; margin: 0; }
  #booking-form-panel .field label,
  #booking-form-panel .field__label { margin-bottom: .16rem; font-size: .78rem; }
  #booking-form-panel .field input,
  #booking-form-panel .field select { min-height: 2.75rem; padding: .55rem .75rem; font-size: .82rem; }
  #times-field,
  #booking-form-panel .form-error,
  #booking-form-panel .booking-help { grid-column: 1 / -1; }
  #booking-form-panel .btn--block { align-self: end; min-height: 2.75rem; margin: 0; }
  #booking-form-panel .booking-help { margin: 0; font-size: .72rem; line-height: 1.2; }
  .booking-page .site-footer { padding-block: .65rem; }
  .booking-page .site-footer .container { display: flex; align-items: center; justify-content: center; gap: .8rem; }

  .booking-confirm {
    width: 100%; align-self: stretch; display: flex; flex-direction: column;
    padding: 0 1.25rem .8rem; overflow: hidden;
  }
  .confirm-banner { min-height: 7.5rem; margin: 0 -1.25rem; border-radius: var(--radius-md) var(--radius-md) 0 0; }
  .confirm-banner__copy { min-height: 7.5rem; }
  .confirm-intro-row { display: flex; align-items: center; justify-content: center; gap: .65rem; margin: .85rem 0 .35rem; }
  .confirm-intro-row .section__intro { margin: 0; text-align: left; }
  .confirm-mark--details { width: 2.5rem; height: 2.5rem; flex: 0 0 2.5rem; margin: 0; }
  .confirm-list {
    display: grid; grid-template-columns: repeat(2,minmax(0,1fr));
    gap: .35rem .65rem; margin: .3rem 0 .45rem;
  }
  .confirm-list__row {
    min-width: 0; flex-direction: column; align-items: center; justify-content: center;
    gap: .05rem; padding: .35rem .4rem; text-align: center;
    border: 1px solid var(--line); border-radius: .45rem;
  }
  .confirm-list__row:last-child { grid-column: 1 / -1; border: 1px solid var(--line); }
  .confirm-list dt { font-size: .75rem; }
  .confirm-list dd { font-size: .9rem; text-align: center; }
  .confirm-note,.confirm-support { margin-top: .3rem; font-size: .76rem; line-height: 1.25; }
  .confirm-actions { flex-wrap: nowrap; gap: .5rem; margin-top: .55rem; }
  .confirm-actions .btn { min-height: 2.55rem; padding-block: .5rem; }
  .booking-confirm .booking-reassure { margin-top: .35rem; font-size: .75rem; }
}

.booking-footer__inner { align-items: center; justify-content: center; }
.booking-page .site-footer__nap a {
  color: rgba(250, 246, 240, .88); text-decoration: underline;
  text-underline-offset: .16em;
}
.booking-footer__instagram {
  width: 2.1rem; height: 2.1rem; flex: 0 0 2.1rem;
  display: grid; place-items: center; border-radius: 50%;
  color: var(--cream); border: 1px solid rgba(250, 246, 240, .65);
}
.booking-footer__instagram svg {
  width: 1.15rem; height: 1.15rem; fill: none;
  stroke: currentColor; stroke-width: 1.7;
}
.booking-footer__instagram-dot { fill: currentColor; stroke: none; }

@media (min-width: 48rem) {
  .booking-banner { grid-template-columns: 56% 44%; min-height: 12rem; }
  #booking-form-panel .booking-intro,
  #booking-form-panel form { padding-inline: var(--space-5); }
  #booking-form-panel form { padding-bottom: var(--space-5); }
}

/* ---------- Fields ---------- */
.field { margin-bottom: var(--space-3); }
.field label, .field__label { display: block; font-weight: 600; font-size: .95rem; margin-bottom: .4rem; }
.field input, .field select {
  width: 100%; font: inherit; color: var(--text);
  background: var(--cream); border: 1.5px solid var(--line);
  border-radius: var(--radius-sm); padding: .85rem 1rem;
  min-height: 3rem; /* comfortable tap target */
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field input:focus, .field select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(138, 100, 35, .18);
}
.field input[aria-invalid="true"] { border-color: #A33B3B; }
.field__hint { font-size: .85rem; color: var(--text-dim); margin-top: .35rem; }
.field__error { font-size: .85rem; color: #A33B3B; font-weight: 600; margin-top: .35rem; }
.field__status { font-size: .9rem; color: var(--text-dim); margin-top: .5rem; }

/* Native select arrows differ wildly between engines; hide and draw our own. */
.select-wrap { position: relative; }
.select-wrap select { appearance: none; -webkit-appearance: none; padding-right: 2.75rem; }
.select-wrap__chev {
  position: absolute; right: 1rem; top: 50%; transform: translateY(-50%);
  color: var(--text-dim); pointer-events: none;
}
/* Safari renders date inputs at their own intrinsic width and vertically
   off-centre without this. */
.field input[type="date"] { -webkit-appearance: none; appearance: none; min-width: 0; }

/* ---------- Time slots ---------- */
.slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(6.25rem, 1fr)); gap: .5rem; }
.slot {
  border: 1.5px solid var(--line); background: var(--cream); color: var(--text);
  border-radius: var(--radius-sm); padding: .7rem .5rem; min-height: 2.75rem;
  font-weight: 600; font-size: .9rem; text-align: center;
  transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}
.slot:hover { border-color: var(--accent); }
.slot.is-selected { background: var(--accent); border-color: var(--accent); color: var(--cream); }

/* ---------- Submit ---------- */
.btn--block { width: 100%; margin-top: var(--space-2); }
.btn[disabled] { opacity: .65; cursor: progress; }
.btn__spinner {
  width: 1rem; height: 1rem; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: btn-spin .7s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn__spinner { animation-duration: 2s; } }

.form-error {
  margin-top: var(--space-2); padding: .85rem 1rem;
  background: #FBEAEA; border-left: 4px solid #A33B3B; border-radius: var(--radius-sm);
  color: #7A2A2A; font-weight: 600; font-size: .9rem;
}
.booking-reassure { margin-top: var(--space-2); text-align: center; font-size: .875rem; color: var(--text-dim); }
.booking-reassure a { font-weight: 600; color: var(--accent-text); }
.booking-reassure a:hover { text-decoration: underline; }
.booking-help {
  margin-top: var(--space-2); text-align: center; font-size: .875rem;
  line-height: 1.55; color: var(--text-dim);
}
.booking-help a { font-weight: 700; color: var(--accent-text); text-decoration: underline; text-underline-offset: .16em; }

/* ---------- Confirmation ---------- */
.booking-confirm { text-align: center; }
.confirm-banner {
  position: relative; min-height: 7rem; overflow: hidden;
  margin: calc(-1 * var(--space-4)) calc(-1 * var(--space-4)) 0;
  color: var(--cream); text-align: left;
}
.confirm-banner picture { position: absolute; inset: 0; }
.confirm-banner img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
.confirm-banner::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(23,18,15,.96), rgba(23,18,15,.62) 40%, rgba(23,18,15,.05) 65%);
}
.confirm-banner__copy {
  position: relative; z-index: 1; min-height: 7rem;
  display: grid; align-content: center; justify-items: start;
  padding: .75rem 1rem; max-width: 62%;
}
.confirm-banner__copy span {
  color: #d2b674; font-size: .58rem; font-weight: 800;
  letter-spacing: .11em; text-transform: uppercase;
}
.confirm-banner__copy h1 { margin: .18rem 0 0; color: white; line-height: 1.03; }
.confirm-mark {
  width: 4rem; height: 4rem; margin: 0 auto var(--space-3);
  border-radius: 50%; background: var(--accent); color: var(--cream);
  display: flex; align-items: center; justify-content: center;
}
.booking-confirm h1 { font-size: clamp(1.6rem, 4.5vw, 2.2rem); }
.confirm-list { margin: var(--space-4) 0 var(--space-3); text-align: left; }
.confirm-list__row {
  display: flex; gap: var(--space-2); justify-content: space-between;
  padding-block: .7rem; border-bottom: 1px solid var(--line);
}
.confirm-list__row:last-child { border-bottom: 0; }
.confirm-list dt { color: var(--text-dim); font-size: .9rem; flex: none; }
.confirm-list dd { font-weight: 600; text-align: right; }
/* The booking page can be very short — a confirmation, or the "call us"
   panel — which otherwise leaves the footer floating mid-screen with bare
   background under it. Scoped to this page so the long pages are untouched. */
.booking-page { min-height: 100vh; display: flex; flex-direction: column; }
.booking-page > footer { margin-top: auto; }

.booking-offline { text-align: center; }
.booking-offline .confirm-actions { margin-top: var(--space-3); }
/* A lone button should not stretch to fill a two-button row. */
.confirm-actions--single .btn { flex: 0 1 auto; min-width: 15rem; }
.confirm-note {
  margin-top: var(--space-2); font-size: .9rem; line-height: 1.55;
  color: var(--text-dim); text-align: center;
}
.confirm-support {
  margin: var(--space-3) auto 0; max-width: 34rem;
  color: var(--text); font-size: .95rem; line-height: 1.55; text-align: center;
}
/* The booking still stands when this shows — amber, not red: nothing failed
   that the customer has to act on. */
.confirm-note--warn {
  color: #7A5A16; background: #FDF6E3; border: 1px solid #EBD9A8;
  border-radius: var(--radius-sm); padding: .7rem .9rem; text-align: left;
}
.confirm-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; margin-top: var(--space-3); }
.confirm-actions .btn { flex: 1 1 13rem; }

@media (max-width: 47.99rem) {
  .booking-confirm {
    align-self: stretch; display: flex; flex-direction: column;
    padding: 0 .85rem .65rem; overflow: hidden;
  }
  .confirm-banner {
    min-height: 5.7rem; margin: 0 -.85rem;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
  }
  .confirm-banner__copy { min-height: 5.7rem; padding: .55rem .8rem; max-width: 58%; }
  .confirm-banner__copy h1 { font-size: 1.28rem; }
  .confirm-mark {
    width: 1.75rem; height: 1.75rem; margin: 0 0 .22rem;
  }
  .confirm-mark--details {
    width: 2.15rem; height: 2.15rem; flex: 0 0 2.15rem; margin: 0;
  }
  .confirm-intro-row {
    display: flex; align-items: center; justify-content: center;
    gap: .55rem; margin: 1.65rem 0 .1rem;
  }
  .confirm-intro-row .section__intro {
    margin: 0; font-size: 1rem; text-align: left;
  }
  .confirm-list {
    flex: 1; display: grid; align-content: center;
    gap: .22rem; min-height: 0; margin: .25rem 0;
  }
  .confirm-list__row {
    flex-direction: column; align-items: center; justify-content: center;
    padding-block: .27rem; gap: .06rem; text-align: center;
  }
  .confirm-list dt { font-size: .86rem; line-height: 1.15; }
  .confirm-list dd { font-size: 1rem; line-height: 1.2; text-align: center; }
  .confirm-note { margin-top: .35rem; font-size: .72rem; line-height: 1.25; }
  .confirm-support { margin-top: .35rem; font-size: .74rem; line-height: 1.25; }
  .confirm-actions { flex-wrap: nowrap; gap: .4rem; margin-top: .5rem; }
  .confirm-actions .btn {
    flex: 1 1 0; min-height: 2.3rem; padding: .5rem .35rem;
    font-size: .72rem; gap: .3rem;
  }
  .confirm-actions .btn svg { width: 1.05rem; height: 1.05rem; }
  .booking-confirm .booking-reassure { margin-top: .4rem; font-size: .72rem; }
}
