/* ==========================================================================
   Brooklin Barber - homepage
   Direction: "Tungsten, full-screen" (direction.md, APPROVED DIRECTION V2 2026-08-26)

   Theme lock:   dark. Warm near-black ground. Two bone daylight bands (price,
                 visit) carry the practical content so the dark never reads exclusive.
   Shape system: buttons full-pill · media + map 24px · full-bleed hero/shave 0px.
   Accent rule:  oxblood is never a button, link, border or heading colour. It only
                 appears as a small full-fill uppercase tag (one per viewport) and as
                 one full-fill climax word in the Book band. Bone-white ink on oxblood
                 clears 7:1. CTAs are bone-white pills with near-black text.
   Contrast:     secondary #8B8378 on #121110 is ~5:1 (AA body). Bone ink on the bone
                 bands is near-black. Oxblood is used as a fill only, never as text.
   ========================================================================== */

:root {
  --ground:      #121110;   /* warm true near-black */
  --ground-2:    #1A1917;   /* one step up, for section value change on dark */
  --bone:        #EDE7DC;   /* daylight band */
  --ink-dark:    #F4F0E8;   /* ink on dark */
  --ink-light:   #16130F;   /* ink on light */
  --sec-dark:    #8B8378;   /* secondary on dark */
  --sec-light:   #5B554C;   /* secondary on the bone bands */
  --oxblood:     #96271F;
  --hair-dark:   rgba(244, 240, 232, 0.16);
  --hair-light:  rgba(22, 19, 15, 0.16);
  --bone-press:  #DBD3C4;

  --display: 'Big Shoulders Display', 'Archivo', Impact, 'Haettenschweiler', sans-serif;
  --sans: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  /* 8px ladder */
  --s1: 8px;  --s2: 16px; --s3: 24px; --s4: 32px;
  --s5: 48px; --s6: 64px; --s7: 88px; --s8: 128px; --s9: 160px;

  /* Vertical rhythm for section bands. Tightened from the old 160px so dark/bone
     bands do not read as tall empty expanses. 104px = 13 steps on the 8px ladder. */
  --section-y: 104px;

  --shell: 1320px;
  --margin: 64px;
  --header-h: 76px;

  --r-pill: 999px;
  --r-photo: 24px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------- reset */

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

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-color: rgba(244, 240, 232, 0.24) var(--ground);
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink-dark);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.7;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3, p, figure, blockquote, table { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

a { color: inherit; }

::selection { background: var(--oxblood); color: var(--ink-dark); }

:focus-visible {
  outline: 2px solid var(--ink-dark);
  outline-offset: 3px;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

.skip-link {
  position: fixed; left: var(--s2); top: -100px; z-index: 60;
  background: var(--bone); color: var(--ink-light);
  padding: 12px var(--s3); border-radius: var(--r-pill);
  font-size: 15px; font-weight: 500; text-decoration: none;
  transition: top 200ms var(--ease);
}
.skip-link:focus { top: var(--s2); }

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

.shell {
  width: 100%;
  max-width: calc(var(--shell) + var(--margin) * 2);
  margin-inline: auto;
  padding-inline: var(--margin);
}

.section { padding-block: var(--section-y); }

/* The bone daylight bands. Value + hue change, never a rule, marks a section. */
.band {
  background: var(--bone);
  color: var(--ink-light);
}

/* Sticky header clearance for in-page anchors. */
main [id] { scroll-margin-top: calc(var(--header-h) + var(--s3)); }

.section__head { max-width: 26ch; margin-bottom: 40px; }

.section__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(48px, 6.4vw, 96px);
  letter-spacing: -0.01em;
  line-height: 0.9;
  text-transform: uppercase;
  text-wrap: balance;
}

.section__lede {
  margin-top: var(--s3);
  max-width: 56ch;
  color: var(--sec-dark);
  text-wrap: pretty;
}
.band .section__lede { color: var(--sec-light); }

.muted { color: var(--sec-dark); }
.band .muted { color: var(--sec-light); }

.label {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sec-dark);
}
.band .label { color: var(--sec-light); }

/* Oxblood full-fill tag. Bone ink on oxblood clears 7:1. One per viewport. */
.tag {
  display: inline-block;
  padding: 6px 12px;
  background: var(--oxblood);
  color: var(--ink-dark);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  padding: 15px var(--s4);
  border: 0;
  border-radius: var(--r-pill);
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 220ms var(--ease), color 220ms var(--ease);
}

/* Primary CTA everywhere: bone-white pill, near-black ink. Colour change only. */
.btn--bone { background: var(--bone); color: var(--ink-light); }
.btn--bone:hover,
.btn--bone:focus-visible { background: #FFFFFF; color: var(--ink-light); }
.btn--bone:active { background: var(--bone-press); color: var(--ink-light); }

/* Ink pill for use on a bone band (Visit). */
.btn--ink { background: var(--ink-light); color: var(--bone); }
.btn--ink:hover,
.btn--ink:focus-visible { background: #000000; color: #FFFFFF; }
.btn--ink:active { background: #2A2620; color: #FFFFFF; }

.link {
  display: inline-block;
  color: var(--ink-dark);
  font-size: 16px;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(244, 240, 232, 0.4);
  transition: text-decoration-color 200ms var(--ease), color 200ms var(--ease);
}
.link:hover, .link:focus-visible { text-decoration-color: currentColor; }
.band .link { color: var(--ink-light); text-decoration-color: rgba(22, 19, 15, 0.4); }

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

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  background: transparent;
  transition: background-color 300ms var(--ease);
}
/* Solid warm-black bar once the hero has scrolled past. Never a blur. */
.site-header.is-solid { background: var(--ground); }

.site-header__inner {
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--s4);
}

/* Brand: the real logo image, bone + gold recolour on the dark header. */
.brand {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  text-decoration: none;
  transition: opacity 200ms var(--ease);
}
.brand:hover, .brand:focus-visible { opacity: 0.78; }
.brand picture { display: contents; }
.brand__logo {
  display: block;
  height: 50px;
  width: auto;
}

.site-nav { margin-inline: auto; }

.site-nav__list {
  display: flex;
  align-items: center;
  gap: var(--s5);
}

.site-nav__list a {
  font-size: 16px;
  font-weight: 400;
  text-decoration: none;
  color: var(--ink-dark);
  transition: opacity 200ms var(--ease);
}
.site-nav__list a:hover, .site-nav__list a:focus-visible { opacity: 0.66; }

.site-nav__phone,
.site-nav__book { display: none; }

.site-nav__phone { font-size: 16px; color: var(--ink-dark); transition: opacity 200ms var(--ease); }
.site-nav__phone:hover, .site-nav__phone:focus-visible { opacity: 0.66; }

.site-header__actions { display: flex; align-items: center; gap: var(--s2); }
.site-header__actions .btn { padding: 12px var(--s3); }

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--hair-dark);
  border-radius: var(--r-pill);
  cursor: pointer;
  color: var(--ink-dark);
  transition: background-color 200ms var(--ease), border-color 200ms var(--ease);
}
.nav-toggle:hover, .nav-toggle:focus-visible { background: rgba(244, 240, 232, 0.08); border-color: rgba(244, 240, 232, 0.3); }

.nav-toggle__bars { display: block; width: 18px; }
.nav-toggle__bars span {
  display: block; height: 1.5px; background: currentColor; border-radius: 2px;
  transition: transform 200ms var(--ease), opacity 200ms var(--ease);
}
.nav-toggle__bars span + span { margin-top: 5px; }

.site-header.is-open .nav-toggle__bars span:first-child { transform: translateY(3.25px) rotate(45deg); }
.site-header.is-open .nav-toggle__bars span:last-child { transform: translateY(-3.25px) rotate(-45deg); }

/* --------------------------------------------------------------- hero */

/* Centered emblem lockup over a full-bleed dark photograph. A flat rgba overlay
   (never a gradient) buys legibility for the scissors mark and the wordmark. */
.hero {
  position: relative;
  min-height: 76vh;
  min-height: 76dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--ground);
  text-align: center;
}

.hero picture { display: contents; }

.hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  background: var(--ground);
}

/* Flat dark fill, no gradient. Pushes the busy photo down so the emblem reads. */
.hero__overlay {
  position: absolute;
  inset: 0;
  background: rgba(18, 17, 16, 0.62);
}

.hero__emblem {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-block: var(--s6);
}

/* The real logo is the hero's hero. Preserve aspect ratio, never stretch. */
.hero__logo-wrap { margin: 0; line-height: 0; }
.hero__logo-wrap picture { display: contents; }
.hero__logo {
  display: block;
  width: min(560px, 78vw);
  height: auto;
  filter: drop-shadow(0 6px 40px rgba(0, 0, 0, 0.55));
}

.hero__tagline {
  margin-top: var(--s4);
  max-width: 40ch;
  font-size: clamp(16px, 1.9vw, 20px);
  font-weight: 400;
  color: var(--ink-dark);
  text-shadow: 0 1px 24px rgba(0, 0, 0, 0.65);
}

.hero__actions {
  margin-top: var(--s5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
}
.hero__link { color: var(--ink-dark); text-decoration-color: rgba(244, 240, 232, 0.5); }

.hero__trust {
  margin-top: var(--s3);
  font-size: 15px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  color: var(--ink-dark);
  text-shadow: 0 1px 20px rgba(0, 0, 0, 0.7);
}

/* Gentle fade-up on load. Static under reduced motion (block below is opt-in). */
@media (prefers-reduced-motion: no-preference) {
  .hero__logo-wrap,
  .hero__tagline,
  .hero__actions,
  .hero__trust {
    opacity: 0;
    transform: translateY(16px);
    animation: emblem-rise 800ms var(--ease) forwards;
  }
  .hero__logo-wrap { animation-delay: 60ms; }
  .hero__tagline { animation-delay: 220ms; }
  .hero__actions { animation-delay: 340ms; }
  .hero__trust { animation-delay: 440ms; }
}

@keyframes emblem-rise {
  to { opacity: 1; transform: none; }
}

/* --------------------------------------------------------- positioning strip */

.strip {
  background: var(--ground-2);
  padding-block: var(--s7);
}
.strip__inner {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--s6);
  align-items: center;
}
.strip__lead {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(24px, 3vw, 40px);
  line-height: 1.02;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  color: var(--ink-dark);
  text-wrap: balance;
}
.strip__facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s4);
}
.strip__facts li { display: flex; flex-direction: column; gap: 4px; }
.strip__fig {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(22px, 2.4vw, 34px);
  line-height: 1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--ink-dark);
}
.strip__cap {
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sec-dark);
}

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

/* Dead-space fix: the bone band opens tight to the strip above and the header sits
   close to the cards, so there is no wide empty band over the card images at any width.
   The section keeps clear top air without the old 104px band and 40px header margin. */
#services { padding-top: var(--s6); }
.section__head--split { margin-bottom: var(--s3); }

/* Editorial two-part section header: the big title anchors the left, the lede fills what
   was empty top-right space, both top-aligned in a clean 2-column header (not a floating
   corner paragraph). Below 1025px it collapses to the default single stacked column
   (title, then lede, then cards) with no overflow. */
@media (min-width: 1025px) {
  .section__head--split {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    column-gap: var(--s8);
    align-items: end;
  }
  .section__head--split .section__lede {
    margin-top: 0;
    max-width: 42ch;
    padding-bottom: 6px;
  }
}

/* One flush transition between the two bone bands (services grid + full menu). */
.band--top-flush { padding-top: 0; }

.cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s4);
}
.card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--hair-light);   /* full four-sided border, never a stripe */
  background: transparent;
  overflow: hidden;                       /* keeps the photo inside the card edges */
}
/* 3:4 portrait photo at the top of the card, top corners match the card radius (0). */
.card__media {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--ground-2);            /* placeholder tone before the image paints */
}
.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.card__body {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  flex: 1 1 auto;
  padding: var(--s4);
}
.card__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(24px, 2.2vw, 32px);
  line-height: 0.98;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  color: var(--ink-light);
}
.card__line { font-size: 15px; line-height: 1.5; color: var(--sec-light); text-wrap: pretty; }
.card__from {
  margin-top: auto;
  padding-top: var(--s2);
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--sec-light);
}
.card__price {
  font-family: var(--display);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  color: var(--ink-light);
}

/* Progressive disclosure. Each card reveals its category's full price list on click.
   The toggle is a real <button> shown only when JS runs; with JS off the toggle is
   hidden and the panel stays open, so every price is still readable (graceful no-JS). */
.card__toggle {
  display: none;                       /* JS-only affordance, revealed by .js below */
  align-items: center;
  gap: var(--s1);
  margin-top: var(--s2);
  padding: 0;
  background: none;
  border: 0;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-light);
  cursor: pointer;
  transition: opacity 200ms var(--ease);
}
.js .card__toggle { display: inline-flex; }
.card__toggle:hover,
.card__toggle:focus-visible { opacity: 0.62; }

/* Plus mark that folds to a minus when open. Functional +/- affordance, not decoration. */
.card__toggle-icon {
  position: relative;
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
}
.card__toggle-icon::before,
.card__toggle-icon::after {
  content: "";
  position: absolute;
  background: currentColor;
  transition: transform 240ms var(--ease), opacity 240ms var(--ease);
}
.card__toggle-icon::before { left: 0; right: 0; top: 50%; height: 1.5px; transform: translateY(-50%); }
.card__toggle-icon::after  { top: 0; bottom: 0; left: 50%; width: 1.5px; transform: translateX(-50%); }
.card__toggle[aria-expanded="true"] .card__toggle-icon::after { opacity: 0; transform: translateX(-50%) rotate(90deg); }

/* Disclosed price list. Direct child of the card, not the gapped body, so a collapsed
   panel adds no height. Left/right padding matches the card body; the list carries its
   own top and bottom spacing. Name left, price pinned right, tabular figures. */
.card__panel { padding: 0 var(--s4); }
.card__panel .pricelist {
  display: grid;
  row-gap: 10px;
  padding-top: var(--s2);
  padding-bottom: var(--s4);
}
.pricelist__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s2);
}
.pricelist__name {
  font-size: 15px;
  line-height: 1.4;
  color: var(--ink-light);
  text-wrap: pretty;
}
.pricelist__price {
  flex: 0 0 auto;
  font-size: 15px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink-light);
}

/* Collapse only when JS runs. visibility:hidden pulls the collapsed panel out of the
   tab order and the accessibility tree; the button's aria-expanded carries the state. */
.js .card__panel {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  transition: max-height 380ms var(--ease), opacity 260ms var(--ease), visibility 0s linear 380ms;
}
.js .card__panel.is-open {
  max-height: 520px;
  opacity: 1;
  visibility: visible;
  transition: max-height 420ms var(--ease), opacity 320ms var(--ease), visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .js .card__panel,
  .js .card__panel.is-open { transition: none; }
}

/* --------------------------------------------------------------- prices */

/* Integrated editorial menu. The heading + lede sit at the top of the LEFT column;
   the RIGHT service list starts level with them and the LEFT service list begins below
   the heading, so the left column carries fewer rows than the right and both columns
   finish at roughly the same height. Below 1025px .menu-layout is one stacked column and
   the DOM order (heading, left group, right group) reads straight down as services 1..12.
   .menu-layout owns the two-column split; each .menu is a single vertical stack of rows. */
.menu-layout {
  display: grid;
  grid-template-columns: 1fr;
  row-gap: var(--s4);
}
.menu-layout .section__head { margin-bottom: 0; }

/* Each menu list is a single column of rows. Icon + name on the left (the name wraps
   freely to as many lines as it needs), price pinned to the FIRST baseline of the name on
   the right, description on its own line below. No leader line: a clean name/price row
   stays locked together at every width and never leaves a floating stub when a long name
   wraps. A small type icon keys each row to a service family (icon-sprite, defined once at
   the top of the section). --menu-icon is the single source of truth for the icon's
   rendered size, reused for the description indent below. */
.menu {
  --menu-icon: 20px;
  display: grid;
  grid-template-columns: 1fr;
  row-gap: var(--s4);
}

/* Hidden sprite sheet: <symbol> defs are never rendered directly, only through
   <use>, so this is offscreen rather than display:none for broad reliability. */
.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.menu__row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Top line: icon + name flow together on the left, price pinned right. Baseline
   alignment ties the icon, the name's first line and the price to one baseline, so
   the price never drops when the name wraps to 2-3 lines. */
.menu__top {
  display: flex;
  align-items: baseline;
  gap: var(--s1);
}

.menu__icon {
  flex: 0 0 auto;
  width: var(--menu-icon);
  height: var(--menu-icon);
  /* SVG aligns by its bottom edge on the baseline; nudge so the mark sits on the
     name's first line rather than floating above it. */
  transform: translateY(3px);
  color: var(--sec-light);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Name takes the remaining width and is allowed to wrap to as many lines as it
   needs; min-width:0 lets it actually shrink and wrap inside the flex row. */
.menu__name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 20px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink-light);
  text-wrap: pretty;
}

/* Price is fixed-width, sits on the name's first baseline, never wraps or drops. */
.menu__price {
  flex: 0 0 auto;
  margin-left: var(--s2);
  font-size: 20px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink-light);
}

/* Description sits on its own line below, indented to align under the name
   (icon width + the icon-to-name gap), never under the icon. */
.menu__desc {
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.45;
  color: var(--sec-light);
  text-wrap: pretty;
  padding-left: calc(var(--menu-icon) + var(--s1));
}

/* Per-row progressive disclosure. Mirrors the services-card toggle/panel: a real
   <button> shown only when JS runs, revealing appointment duration + a Book online
   link. Toggle and panel are indented to align under the name column (icon width +
   gap), matching .menu__desc, so nothing hangs under the icon. With JS off the toggle
   is hidden and the panel stays open, so duration + link are always readable. */
.menu__toggle {
  display: none;                       /* JS-only affordance, revealed by .js below */
  align-items: center;
  gap: var(--s1);
  margin-top: 2px;
  padding: 0;
  padding-left: calc(var(--menu-icon) + var(--s1));
  background: none;
  border: 0;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sec-light);
  cursor: pointer;
  transition: opacity 200ms var(--ease);
}
.js .menu__toggle { display: inline-flex; }
.menu__toggle:hover,
.menu__toggle:focus-visible { opacity: 0.62; }

/* Plus mark that folds to a minus when open. Functional +/- affordance, not decoration. */
.menu__toggle-icon {
  position: relative;
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
}
.menu__toggle-icon::before,
.menu__toggle-icon::after {
  content: "";
  position: absolute;
  background: currentColor;
  transition: transform 240ms var(--ease), opacity 240ms var(--ease);
}
.menu__toggle-icon::before { left: 0; right: 0; top: 50%; height: 1.5px; transform: translateY(-50%); }
.menu__toggle-icon::after  { top: 0; bottom: 0; left: 50%; width: 1.5px; transform: translateX(-50%); }
.menu__toggle[aria-expanded="true"] .menu__toggle-icon::after { opacity: 0; transform: translateX(-50%) rotate(90deg); }

/* Disclosed detail: duration line + Book online link, indented under the name. */
.menu__panel {
  display: grid;
  row-gap: 6px;
  padding-left: calc(var(--menu-icon) + var(--s1));
}
.menu__meta {
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink-light);
  font-variant-numeric: tabular-nums;
}
.menu__book { justify-self: start; font-size: 15px; }

/* Collapse only when JS runs. visibility:hidden pulls the collapsed panel out of the
   tab order and the accessibility tree; the button's aria-expanded carries the state. */
.js .menu__panel {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  transition: max-height 380ms var(--ease), opacity 260ms var(--ease), visibility 0s linear 380ms;
}
.js .menu__panel.is-open {
  max-height: 160px;
  opacity: 1;
  visibility: visible;
  transition: max-height 420ms var(--ease), opacity 320ms var(--ease), visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .js .menu__panel,
  .js .menu__panel.is-open { transition: none; }
}

.prices__foot {
  margin-top: var(--s6);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
}

/* Desktop: heading anchors the top-left, right list fills the top-right. The heading is
   row 1 of column 1, the left service list is row 2 of column 1, and the right service
   list spans both rows of column 2 so it starts level with the top of the heading.
   align-items:start keeps every cell top-aligned. */
@media (min-width: 1025px) {
  .menu-layout {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--s8);
    row-gap: 0;
    align-items: start;
  }
  .menu-layout .section__head {
    grid-column: 1;
    grid-row: 1;
    max-width: none;
    margin-bottom: var(--s5);
  }
  .menu--left  { grid-column: 1; grid-row: 2; }
  .menu--right { grid-column: 2; grid-row: 1 / 3; }
}

/* --------------------------------------------------------------- hot shave */

.shave {
  position: relative;
  min-height: 78vh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--ground);
}
.shave picture { display: contents; }
.shave__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 60% center;
}
.shave__content {
  position: relative;
  z-index: 2;
  padding-block: var(--s7);
}
.shave__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(40px, 5.4vw, 84px);
  line-height: 0.92;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--ink-dark);
  max-width: 18ch;
  margin-top: var(--s3);
  text-shadow: 0 2px 40px rgba(0, 0, 0, 0.5);
}
.shave__price {
  margin-top: var(--s3);
  font-size: 19px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ink-dark);
  text-shadow: 0 1px 24px rgba(0, 0, 0, 0.6);
}
.shave__actions { margin-top: var(--s4); }

/* --------------------------------------- craft: before/after comparison */

.craft { background: var(--ground); }

/* Asymmetric feature: heading sits beside the slider on desktop, stacks above it
   on mobile. Constrained so the band carries no dead space. */
.craft__layout {
  display: grid;
  grid-template-columns: minmax(0, 34ch) minmax(340px, 440px);
  justify-content: center;
  gap: var(--s6);
  align-items: center;
}
.craft__intro { max-width: 30ch; }
.craft__intro .section__lede { margin-top: var(--s3); }

/* The comparison unit. One framed 3:4 area, not two photos. */
.ba { width: 100%; }
.ba__frame {
  --pos: 50%;
  position: relative;
  width: 100%;
  max-width: 440px;
  margin-inline: auto;
  aspect-ratio: 3 / 4;
  border-radius: var(--r-photo);
  overflow: hidden;
  background: var(--ground-2);
  touch-action: none;            /* pointer drag owns horizontal gestures */
}
.ba__pane { position: absolute; inset: 0; }
.ba__pane picture,
.ba__pane img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
}
.ba__pane--after { z-index: 1; }
/* BEFORE overlays the AFTER base, revealed from the left edge to the handle. */
.ba__pane--before {
  z-index: 2;
  clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}

/* Corner tags. Solid dark chip + off-white type = AA on any part of the images. */
.ba__tag {
  position: absolute;
  top: var(--s2);
  z-index: 4;
  padding: 6px 10px;
  border-radius: 6px;
  background: rgba(18, 17, 16, 0.82);
  color: var(--ink-dark);
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  pointer-events: none;
}
.ba__tag--before { left: var(--s2); }
.ba__tag--after  { right: var(--s2); }

/* Handle: a thin vertical bar with a round grabber carrying a left/right hint. */
.ba__handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  z-index: 3;
  width: 2px;
  margin-left: -1px;
  background: var(--ink-dark);
  cursor: ew-resize;
}
.ba__grip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: var(--ink-dark);
  color: var(--ink-light);
  display: grid;
  place-items: center;
  box-shadow: 0 2px 14px rgba(0, 0, 0, 0.5);
}
.ba__grip svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ba__handle:focus-visible {
  outline: none;
}
.ba__handle:focus-visible .ba__grip {
  outline: 2px solid var(--ink-dark);
  outline-offset: 3px;
}

/* JS-off fallback: the inline head script adds .js the moment scripting runs, so
   without it the panes render as a flush, labelled diptych. No broken slider. */
.craft__layout .ba__frame { aspect-ratio: auto; }
.ba__frame { display: grid; grid-template-columns: 1fr 1fr; column-gap: 2px; background: var(--hair-dark); }
.ba__pane { position: static; aspect-ratio: 3 / 4; }
.ba__pane--before { clip-path: none; order: 0; }   /* before on the left, matching its tag */
.ba__pane--after  { order: 1; }                     /* after on the right */
.ba__handle { display: none; }

/* Slider mode (scripting available) */
.js .ba__frame { display: block; aspect-ratio: 3 / 4; background: var(--ground-2); }
.js .ba__pane { position: absolute; inset: 0; aspect-ratio: auto; }
.js .ba__pane--before { clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.js .ba__handle { display: block; }

@media (max-width: 900px) {
  .craft__layout { grid-template-columns: 1fr; gap: var(--s5); }
  .craft__intro { max-width: none; }
}

/* --------------------------------------------------------------- proof */

.proof { background: var(--ground); }

.proof__figure {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(120px, 20vw, 300px);
  line-height: 0.82;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-dark);
}
.proof__of {
  display: block;
  margin-top: var(--s2);
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(28px, 3.4vw, 52px);
  line-height: 1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--sec-dark);
}

.quotes {
  margin-top: var(--s6);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s6);
}

.quote { display: flex; flex-direction: column; }

.quote blockquote p {
  font-size: 22px;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--ink-dark);
  text-wrap: pretty;
}

.quote figcaption {
  margin-top: auto;
  padding-top: var(--s3);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sec-dark);
}

/* --------------------------------------------------------------- the shop */

.shop { background: var(--ground); }

.shop__grid {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: var(--s7);
  align-items: center;
}

.shop__text p { margin-top: var(--s3); max-width: 52ch; color: var(--sec-dark); text-wrap: pretty; }
.shop__text .section__title { margin-bottom: var(--s2); }

.photo {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-photo);
  background: var(--ground-2);
}
.shop__photo { aspect-ratio: 4 / 5; }
.shop__photo img { width: 100%; height: 100%; object-fit: cover; }

/* --------------------------------------------------------------- visit */

.visit {
  margin-top: var(--s5);
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: var(--s7);
  align-items: start;
}

.visit__details {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5) var(--s5);
}

.detail--wide { grid-column: 1 / -1; }

.detail__value { margin-top: var(--s1); font-variant-numeric: tabular-nums; color: var(--ink-light); }
.detail__value a { display: inline-block; padding-block: 3px; text-decoration: underline; text-underline-offset: 4px; transition: opacity 200ms var(--ease); }
.detail__value a:hover, .detail__value a:focus-visible { opacity: 0.66; }

.hours {
  margin-top: var(--s2);
  width: 100%;
  max-width: 440px;
  border-collapse: collapse;
}
.hours th, .hours td {
  padding-block: 10px;
  border-bottom: 1px solid var(--hair-light);
  font-size: 17px;
  font-weight: 400;
  text-align: left;
  color: var(--ink-light);
}
.hours td { text-align: right; font-variant-numeric: tabular-nums; color: var(--sec-light); }
.hours tr:last-child th, .hours tr:last-child td { border-bottom: 0; }

.plain-list { margin-top: var(--s2); }
.plain-list li { color: var(--sec-light); }

.visit__actions {
  margin-top: var(--s1);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s4);
}

.visit__map { position: sticky; top: calc(var(--header-h) + var(--s3)); }
.visit__map iframe {
  width: 100%;
  height: 540px;
  border: 0;
  border-radius: var(--r-photo);
  background: var(--ground-2);
}
.visit__map figcaption { margin-top: var(--s2); font-size: 15px; color: var(--sec-light); }

/* --------------------------------------------------------------- book */

.book { background: var(--ground); text-align: center; }

.book__inner { max-width: 980px; margin-inline: auto; }
.book__inner .section__lede { margin-inline: auto; color: var(--sec-dark); }

.book__title { text-wrap: balance; }
/* The one oxblood full-fill climax word. Bone ink on oxblood clears 7:1. */
.climax {
  color: var(--ink-dark);
  background: var(--oxblood);
  padding: 0 0.12em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.book__actions {
  margin-top: var(--s6);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s4);
}

.policy { margin-top: var(--s7); }
.policy .label { color: var(--sec-dark); }
.policy .muted { margin-top: var(--s1); max-width: 62ch; margin-inline: auto; font-size: 15px; text-wrap: pretty; }

/* --------------------------------------------------- book online page */

/* book.html only. The homepage no longer carries this markup, so these rules are inert
   there; they render the dedicated Book Online page's embedded DaySmart tool at a large
   size. The section sits on the dark ground under the fixed (solid) header, so it needs
   top clearance equal to the header height plus normal band air. */
.book-tool {
  background: var(--ground);
  padding-top: calc(var(--header-h) + var(--s6));
  padding-bottom: var(--section-y);
  text-align: center;
}
.book-tool__head { max-width: 980px; margin-inline: auto; }
.book-tool__head .section__lede { margin-inline: auto; color: var(--sec-dark); }

/* One clean white card holding the widget. No cream frame around it (the widget is
   already white), so it reads as a single surface on the dark ground, not a box-in-a-box. */
.book__widget {
  margin-top: var(--s6);
  margin-inline: auto;
  max-width: 980px;
  padding: 0;
  background: #FFFFFF;
  border-radius: var(--r-photo);
  overflow: hidden;
}

/* The DaySmart iframe, held large so the real booking UI has room and scrolls internally.
   min-height hardening stops the frame collapsing before the third-party UI paints. The
   parent clips the corners, so the frame itself is square. */
.book__frame {
  display: block;
  width: 100%;
  height: 1450px;
  min-height: 1450px;
  border: 0;
  background: #FFFFFF;
}

.book-tool__foot { margin-top: var(--s4); }
.book-tool .policy { margin-top: var(--s7); }
.book-tool .policy .label { color: var(--sec-dark); }
.book-tool .policy .muted { margin-top: var(--s1); max-width: 62ch; margin-inline: auto; font-size: 15px; text-wrap: pretty; }

@media (max-width: 768px) {
  .book__frame { height: 1350px; min-height: 1350px; }
}

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

.site-footer { padding-block: var(--s7) var(--s5); background: var(--ground); }

.site-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) repeat(4, auto);
  gap: var(--s5);
  align-items: start;
}

.site-footer__brand picture { display: contents; }
.site-footer__logo {
  display: block;
  width: 165px;
  height: auto;
  max-width: 100%;
}

.site-footer__col p { font-size: 15px; line-height: 1.7; color: var(--sec-dark); }
.site-footer__col a { display: inline-block; padding-block: 3px; text-decoration: underline; text-underline-offset: 4px; color: var(--ink-dark); transition: opacity 200ms var(--ease); }
.site-footer__col a:hover, .site-footer__col a:focus-visible { opacity: 0.66; }
.site-footer__col--book .link { font-size: 15px; }

.site-footer__legal {
  margin-top: var(--s6);
  font-size: 15px;
  color: var(--sec-dark);
}

/* --------------------------------------------------------------- reveal */

/* Reveal only hides when JS is running, so no-JS and deep-link loads never blank a section. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ==========================================================================
   Responsive. Breakpoints: 1100 / 900 / 768 / 480
   ========================================================================== */

@media (max-width: 1100px) {
  :root { --margin: 40px; --section-y: 96px; --s8: 96px; }
  .site-nav__list { gap: var(--s4); }
  .quotes { gap: var(--s5); }
  .visit { gap: var(--s6); }
  .strip__inner { gap: var(--s5); }
}

@media (max-width: 900px) {
  .site-nav { display: none; }
  .nav-toggle { display: inline-flex; }
  .site-header__actions { margin-left: auto; }

  .strip__inner { grid-template-columns: 1fr; gap: var(--s5); }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }

  /* Full panel below the header so page content never shows through it. */
  .site-header.is-open { background: var(--ground); }
  .site-header.is-open .site-nav {
    display: block;
    position: fixed;
    left: 0; right: 0; top: var(--header-h);
    height: calc(100dvh - var(--header-h));
    overflow-y: auto;
    background: var(--ground);
    padding: var(--s5) var(--margin) var(--s6);
    margin: 0;
  }
  .site-header.is-open .site-nav__list { flex-direction: column; align-items: flex-start; gap: var(--s3); }
  .site-header.is-open .site-nav__list a { font-family: var(--display); font-size: 34px; font-weight: 700; text-transform: uppercase; letter-spacing: 0; }
  .site-header.is-open .site-nav__phone {
    display: inline-block;
    margin-top: var(--s4);
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 5px;
  }

  .shop__grid { grid-template-columns: 1fr; gap: var(--s5); }
  .quotes { grid-template-columns: 1fr; gap: var(--s5); }
  .visit { grid-template-columns: 1fr; }
  .visit__map { position: static; }
  .visit__map iframe { height: 420px; }

  .site-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4) var(--s5); }
  .site-footer__brand { grid-column: 1 / -1; }
}

@media (max-width: 600px) {
  .site-header__actions > .btn { display: none; }
  .site-header.is-open .site-nav__book {
    display: inline-flex;
    width: 100%;
    margin-top: var(--s4);
  }
}

/* Below the full desktop width (handled by the min-width:1025px rule above) the whole
   menu is already one stacked column: heading, then the left group, then the right group,
   which reads as services 1..12 in order. A clean 1-column list beats a cramped 2-column
   one for the long service names. Nothing extra is needed here. */

@media (max-width: 768px) {
  :root { --margin: 24px; --section-y: 80px; --s8: 64px; --s7: 56px; --header-h: 64px; }

  /* Tighten the row rhythm at mobile, both between the two stacked groups and the rows
     inside each group. */
  .menu-layout { row-gap: var(--s3); }
  .menu { row-gap: var(--s3); }

  .visit__details { grid-template-columns: 1fr; gap: var(--s5); }
  .hours { max-width: none; }

  .site-footer__grid { grid-template-columns: 1fr; gap: var(--s4); }
}

@media (max-width: 560px) {
  .cards { grid-template-columns: 1fr; }
  .strip__facts { grid-template-columns: 1fr; gap: var(--s3); }
  .strip__facts li { flex-direction: row; align-items: baseline; gap: var(--s2); }
}

@media (max-width: 480px) {
  :root { --margin: 20px; }
  body { font-size: 16px; }
  .menu__name, .menu__price { font-size: 18px; }
  .quote blockquote p { font-size: 20px; }
  .book__actions .btn { flex: 1 1 auto; }
  .hero__actions .btn { flex: 1 1 auto; }
}

@media (max-width: 390px) {
  .site-header__actions .btn { padding: 11px var(--s2); font-size: 14px; }
  .site-header__inner { gap: var(--s2); }
  .wordmark { font-size: 22px; }
}

/* ==========================================================================
   Reduced motion. No pin, no push-in, no cut, no reveal. Static state 2.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  [data-reveal] { opacity: 1; transform: none; }
}
