/* ==========================================================================
   0. Type — Oswald (signage) over Barlow (text). Both OFL, self-hosted in
   fonts/ with their licences. swap = text is readable before the font lands.
   -------------------------------------------------------------------------- */
@font-face { font-family: "Oswald"; src: url("fonts/oswald-var.woff2") format("woff2"); font-weight: 200 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Barlow"; src: url("fonts/barlow-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Barlow"; src: url("fonts/barlow-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Barlow"; src: url("fonts/barlow-600.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Barlow"; src: url("fonts/barlow-700.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }

/* ==========================================================================
   1. Tokens — every colour is semantic. A client's brand is one accent swap;
   light and dark are both authored, never auto-inverted.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* ── EDIT PER CLIENT: the one brand colour everything themes off ── */
  /* The logo's own green is #508828 and stays that way in the logo itself. On the
     page it is taken deeper and away from lime — a bottle green that sits with a
     barbershop rather than a sports brand — and each surface gets the shade that
     clears WCAG AA there. */
  --brand:         #508828;   /* the logo's own green — never used for text */
  --accent:        #1e5c2e;   /* small text on light — 7.2:1 */
  --accent-bright: #23663a;   /* buttons, with white text — 6.9:1 */
  --on-accent:     #ffffff;   /* text sitting on the accent */

  /* Semantic — light */
  --bg:            #f4f5f3;
  --bg-alt:        #e9ece8;
  --surface:       #ffffff;
  --border:        #d8ddd8;
  --border-strong: #b9c1b9;
  --text:          #0e120f;
  --text-muted:    #4f5852;

  /* The black band (hero, footer, CTA) */
  --band-bg:      #0a0c0a;
  --band-surface: #151a16;
  --band-text:    #eff3ef;
  --band-muted:   #9daaa1;
  --band-accent:  #4aa066;   /* the band is black in both themes, so it needs its own accent */
  --band-border:  rgba(226, 240, 231, .16);

  --shadow-sm: 0 1px 2px rgba(8, 14, 10, .07), 0 2px 8px rgba(8, 14, 10, .06);
  --shadow-md: 0 4px 12px rgba(8, 14, 10, .09), 0 12px 32px rgba(8, 14, 10, .10);
  --shadow-lg: 0 8px 24px rgba(8, 14, 10, .13), 0 32px 64px rgba(8, 14, 10, .18);

  --container: 1080px;
  /* Squared off. A barbershop is not a fintech app. */
  --r-sm: 2px;
  --r-md: 3px;
  --r-lg: 4px;
  --header-h: 72px;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --brand:         #508828;
  --accent:        #4aa066;   /* lifted just enough to pass AA on the dark bg — 5.9:1 */
  --accent-bright: #3d9558;
  --on-accent:     #08160a;

  --bg:            #0b0e0c;
  --bg-alt:        #121613;
  --surface:       #141916;
  --border:        rgba(206, 228, 214, .13);
  --border-strong: rgba(206, 228, 214, .26);
  --text:          #eff3ef;
  --text-muted:    #a6b2aa;

  --band-bg:      #060806;
  --band-surface: #121713;
  --band-text:    #eff3ef;
  --band-muted:   #a6b2aa;
  --band-accent:  #4aa066;
  --band-border:  rgba(206, 228, 214, .13);

  --shadow-sm: 0 1px 2px rgba(0,0,0,.4), 0 2px 8px rgba(0,0,0,.3);
  --shadow-md: 0 4px 12px rgba(0,0,0,.45), 0 12px 32px rgba(0,0,0,.35);
  --shadow-lg: 0 8px 24px rgba(0,0,0,.5), 0 32px 64px rgba(0,0,0,.45);
}

@media (prefers-contrast: more) {
  :root { --border: var(--border-strong); --text-muted: var(--text); }
}

/* ==========================================================================
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

body {
  margin: 0;
  font-family: "Barlow", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 1.0625rem;      /* rem-based so browser text-size settings work */
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
img, svg { max-width: 100%; }
img { display: block; height: auto; }
p { margin: 0; }
a { color: inherit; }
h1, h2, h3 { margin: 0; line-height: 1.14; letter-spacing: -.021em; font-weight: 680; }
[id] { scroll-margin-top: calc(var(--header-h) + 16px); }

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: 20px; }
.section { padding-block: clamp(56px, 8vw, 104px); }
.section--alt { background: var(--bg-alt); }
.center { text-align: center; }

.eyebrow {
  font-size: .76rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 13px;
}
.h2 { font-size: clamp(1.8rem, 4vw, 2.5rem); }
.lede { font-size: clamp(1.02rem, 1.6vw, 1.16rem); color: var(--text-muted); max-width: 60ch; }
.section-head { max-width: 64ch; margin-bottom: clamp(32px, 5vw, 52px); }
.section-head.center { margin-inline: auto; }
.section-head.center .lede { margin-inline: auto; }

/* ── Accessibility ── */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--accent-bright); color: #241c11; padding: 12px 20px;
  border-radius: 0 0 var(--r-sm) 0; font-weight: 700; text-decoration: none;
}
.skip:focus { left: 0; }
:focus-visible { outline: 3px solid var(--accent-bright); outline-offset: 3px; border-radius: 4px; }
.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

h1, h2, h3, .brand, .ticker-track span, .eyebrow, .price {
  font-family: "Oswald", "Barlow", ui-sans-serif, system-ui, sans-serif;
}
/* Signage, not a landing page: caps, tight, and no single colour-picked word */
.hero h1 { text-transform: uppercase; letter-spacing: -.005em; line-height: .96; }
.h2 { letter-spacing: -.01em; }

/* ── Buttons ── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font: inherit; font-weight: 650; font-size: .97rem; padding: 13px 24px;
  border-radius: 3px; border: 1.5px solid transparent; text-decoration: none; cursor: pointer;
  white-space: nowrap;
  transition: transform .18s var(--ease), background-color .18s var(--ease),
              border-color .18s var(--ease), color .18s var(--ease), box-shadow .18s var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary { background: var(--accent-bright); color: #241c11; box-shadow: var(--shadow-sm); }
.btn-primary:hover { filter: brightness(1.06); box-shadow: var(--shadow-md); }
.btn-outline { background: transparent; color: var(--text); border-color: var(--border-strong); }
.btn-outline:hover { background: var(--surface); border-color: var(--text); }
.btn-on-band { background: transparent; color: var(--band-text); border-color: var(--band-border); }
.btn-on-band:hover { background: rgba(230,215,180,.1); border-color: rgba(230,215,180,.55); }

/* ==========================================================================
   3. Preview ribbon — only on a mock-up. Delete the element (and .has-ribbon)
   to ship the live version.
   -------------------------------------------------------------------------- */
.ribbon {
  position: fixed; inset: 0 0 auto 0; z-index: 300;
  background: repeating-linear-gradient(135deg, #7a1f1f, #7a1f1f 14px, #6a1a1a 14px, #6a1a1a 28px);
  color: #fff; text-align: center; font-size: .8rem; font-weight: 650;
  padding: 7px 44px 7px 16px; line-height: 1.4;
}
.ribbon b { font-weight: 800; }
/* The ribbon wraps to two or three lines on a phone, so its height can't be a fixed
   number — JS measures it into --ribbon-h. The media query is the JS-off fallback. */
body.has-ribbon { padding-top: var(--ribbon-h, 34px); }
@media (max-width: 560px) { body.has-ribbon { --ribbon-h: 66px; } }
.ribbon-close {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  width: 26px; height: 26px; display: grid; place-items: center;
  background: rgba(0,0,0,.22); border: 0; border-radius: 999px; color: #fff; cursor: pointer; font-size: 1rem;
}

/* ==========================================================================
   4. Header
   -------------------------------------------------------------------------- */
.header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: saturate(160%) blur(12px); -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--border);
}
body.has-ribbon .header { top: var(--ribbon-h, 34px); }
.header-in { display: flex; align-items: center; gap: 12px; height: var(--header-h); }
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; color: var(--text); font-weight: 800; font-size: 1.08rem; letter-spacing: -.02em; }
.brand-mark { width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; background: var(--accent-bright); color: #241c11; flex: 0 0 auto; }
.brand i { font-style: normal; color: var(--accent); }

.nav { display: none; margin-left: auto; align-items: center; gap: 2px; }
.nav a { text-decoration: none; color: var(--text-muted); font-size: .94rem; font-weight: 560; padding: 9px 13px; border-radius: var(--r-sm); transition: color .16s, background-color .16s; }
.nav a:hover { color: var(--text); background: var(--bg-alt); }

.header-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.nav + .header-actions { margin-left: 10px; }
.header-cta { display: none; }

.theme-toggle {
  width: 40px; height: 40px; display: inline-grid; place-items: center; border-radius: 999px;
  border: 1.5px solid var(--border); background: transparent; color: var(--text); cursor: pointer; flex: 0 0 auto;
  transition: background-color .16s, border-color .16s;
}
.theme-toggle:hover { background: var(--bg-alt); border-color: var(--border-strong); }
.theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

.burger { display: inline-flex; flex-direction: column; justify-content: center; gap: 5px; width: 42px; height: 40px; padding: 0 9px; background: transparent; border: 1.5px solid var(--border); border-radius: var(--r-sm); cursor: pointer; flex: 0 0 auto; }
.burger span { display: block; height: 2px; background: var(--text); border-radius: 2px; transition: transform .2s var(--ease), opacity .2s; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-nav { display: none; background: var(--surface); border-bottom: 1px solid var(--border); padding: 8px 0 16px; }
.mobile-nav.open { display: block; }
.mobile-nav a { display: block; text-decoration: none; color: var(--text); font-weight: 600; padding: 13px 20px; }
.mobile-nav a:hover { background: var(--bg-alt); }
.mobile-nav .btn { margin: 12px 20px 0; width: calc(100% - 40px); }

@media (min-width: 900px) {
  .nav { display: flex; }
  .header-cta { display: inline-flex; }
  .burger { display: none; }
  .mobile-nav { display: none !important; }
}

/* ==========================================================================
   5. Hero
   -------------------------------------------------------------------------- */
.hero { position: relative; overflow: hidden; background: var(--band-bg); color: var(--band-text); padding-block: clamp(52px, 8vw, 92px); }
.hero::before {
  content: ""; position: absolute; inset: 0;
  background-image: linear-gradient(rgba(74,160,102,.07) 1px, transparent 1px), linear-gradient(90deg, rgba(74,160,102,.07) 1px, transparent 1px);
  background-size: 52px 52px;
  -webkit-mask-image: radial-gradient(ellipse 85% 65% at 78% 28%, #000 0%, transparent 72%);
  mask-image: radial-gradient(ellipse 85% 65% at 78% 28%, #000 0%, transparent 72%);
}
.hero::after { content: ""; position: absolute; width: 600px; height: 600px; right: -190px; top: -250px; border-radius: 50%; background: radial-gradient(circle, rgba(30,92,46,.26) 0%, transparent 68%); }
.hero-in { position: relative; z-index: 1; }
/* Photo behind the hero, same treatment as the MAS Salvage site: the shop's own interior with
   the band colour laid over the text side so the headline stays readable, thinning to the
   photo on the right. Fades in after first paint. If hero.jpg is missing the band colour
   simply shows — nothing breaks. The grid and glow decorations sit underneath it. */
.hero-bg {
  position: absolute; inset: 0; z-index: 0;
  background:
    linear-gradient(100deg, color-mix(in srgb, var(--band-bg) 94%, transparent) 0%, color-mix(in srgb, var(--band-bg) 82%, transparent) 30%, color-mix(in srgb, var(--band-bg) 38%, transparent) 58%, color-mix(in srgb, var(--band-bg) 6%, transparent) 100%),
    url(img/hero.jpg) center / cover no-repeat;
  opacity: 0; animation: heroFade 1.4s var(--ease) .1s forwards;
}
@keyframes heroFade { to { opacity: 1; } }
@media (max-width: 899px) {
  .hero-bg { background:
    linear-gradient(180deg, color-mix(in srgb, var(--band-bg) 88%, transparent) 0%, color-mix(in srgb, var(--band-bg) 74%, transparent) 45%, color-mix(in srgb, var(--band-bg) 30%, transparent) 100%),
    url(img/hero.jpg) center / cover no-repeat; }
}
@media (prefers-reduced-motion: reduce) { .hero-bg { animation: none; opacity: 1; } }
.hero-badge {
  display: inline-flex; align-items: center; gap: 9px; padding: 0; border-radius: 0;
  background: none; border: 0; margin-bottom: 22px;
  font-family: "Oswald", sans-serif; text-transform: uppercase; letter-spacing: .18em;
  font-size: .82rem; font-weight: 600;
  /* It sits on the black band, so it takes the band accent — the page accent is
     tuned for the light background and fails against black. */
  color: var(--band-accent);
}
.dot { width: 8px; height: 8px; border-radius: 0; background: var(--band-accent); flex: 0 0 auto; }
.hero h1 { font-size: clamp(2.1rem, 5.4vw, 3.5rem); letter-spacing: -.03em; max-width: 16ch; }
/* The headline is one voice — a single word tinted in the accent is the oldest
   template tell there is. The typeface does the work instead. */
.hero h1 em { font-style: normal; color: inherit; }
.hero-sub { font-size: clamp(1.04rem, 1.9vw, 1.2rem); color: var(--band-muted); max-width: 48ch; margin-top: 18px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.chips { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 30px; }
.chip { display: inline-flex; align-items: center; gap: 7px; font-size: .74rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; color: var(--band-muted); background: none; border: 0; border-left: 2px solid var(--band-accent); padding: 2px 0 2px 11px; border-radius: 0; }
.chip svg { color: var(--accent-bright); flex: 0 0 auto; }

/* ==========================================================================
   6. Services
   -------------------------------------------------------------------------- */
.grid { display: grid; gap: 18px; }
@media (min-width: 640px) { .grid.cols-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 940px) { .grid.cols-3 { grid-template-columns: repeat(3, 1fr); } }

.svc {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 22px 22px; box-shadow: var(--shadow-sm);
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
}
.svc h3 { font-size: 1.06rem; }
.svc p { color: var(--text-muted); font-size: .92rem; margin-top: 4px; }
.svc .price { font-weight: 750; color: var(--accent); white-space: nowrap; font-size: 1.02rem; }
.svc .price.tbc { color: var(--text-muted); font-weight: 600; font-size: .86rem; }

.note {
  margin-top: 26px; background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--r-md); padding: 15px 18px; font-size: .9rem; color: var(--text);
}
.note b { color: var(--text); }

/* ==========================================================================
   7. Gallery — honest placeholders until real photos land
   -------------------------------------------------------------------------- */
.gallery { display: grid; gap: 14px; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 760px) { .gallery { grid-template-columns: repeat(4, 1fr); } }
.shot {
  aspect-ratio: 4 / 5; border-radius: var(--r-md); overflow: hidden;
  background: linear-gradient(150deg, var(--band-surface), var(--band-bg));
  border: 1px solid var(--border); display: grid; place-items: center; color: var(--band-muted); position: relative;
}
.shot span { font-size: .74rem; font-weight: 600; letter-spacing: .04em; display: inline-flex; align-items: center; gap: 6px; opacity: .8; }
.gallery.cols-2 { grid-template-columns: repeat(2, 1fr); }

/* ==========================================================================
   8. About + Visit
   -------------------------------------------------------------------------- */
.split { display: grid; gap: clamp(32px, 5vw, 56px); }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; align-items: start; } }
/* About with a real photo: the photo sits at its natural 4:5 so a ~575px source is never
   upscaled on desktop, and stacks above the words on a phone. */
.about-photo { margin: 0; }
.about-photo img {
  display: block; width: 100%; height: auto; aspect-ratio: 574 / 620; object-fit: cover;
  /* No frame. The edges feather into the section surface on all four sides (two linear
     masks intersected) so the photo reads as part of the page, not a picture dropped on it.
     A mask reveals the real background, so it works in both themes with no extra colour. */
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 22%, #000 78%, transparent),
    linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent, #000 22%, #000 78%, transparent),
    linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  mask-composite: intersect;
}
@media (min-width: 900px) { .split--about { align-items: center; } }
/* About without a photo: one column, held to a readable line length. */
.about-solo { max-width: 46rem; }
.prose p + p { margin-top: 14px; color: var(--text-muted); }
.prose p { color: var(--text-muted); }

.visit-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: clamp(24px, 3vw, 32px); box-shadow: var(--shadow-sm); }
.hours { list-style: none; margin: 8px 0 0; padding: 0; }
.hours li { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--border); font-size: .96rem; }
.hours li:last-child { border-bottom: 0; }
.hours .day { font-weight: 620; }
.hours .time { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.visit-meta { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 13px; }
.visit-meta li { display: flex; gap: 12px; align-items: flex-start; font-size: .96rem; }
.visit-meta svg { flex: 0 0 auto; margin-top: 3px; color: var(--accent); }
.visit-meta a { text-underline-offset: 3px; }

/* ==========================================================================
   9. CTA band + footer
   -------------------------------------------------------------------------- */
.cta-band { background: var(--band-bg); color: var(--band-text); text-align: center; }
.cta-band h2 { font-size: clamp(1.7rem, 3.6vw, 2.3rem); max-width: 20ch; margin-inline: auto; }
.cta-band p { color: var(--band-muted); margin-top: 14px; max-width: 44ch; margin-inline: auto; }
.cta-band .hero-actions { justify-content: center; }

.footer { background: var(--band-bg); color: var(--band-muted); border-top: 1px solid var(--band-border); padding-block: 40px 30px; font-size: .9rem; }
.footer-grid { display: grid; gap: 26px; padding-bottom: 26px; border-bottom: 1px solid var(--band-border); }
@media (min-width: 720px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer h4 { color: var(--band-text); font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; margin: 0 0 12px; }
.footer .brand { color: var(--band-text); }
.footer .brand i { color: var(--band-accent); }
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.footer a { color: var(--band-muted); text-decoration: none; }
.footer a:hover { color: var(--band-text); text-decoration: underline; }
.footer-note { padding-top: 20px; display: flex; flex-wrap: wrap; gap: 10px 22px; justify-content: space-between; align-items: center; }
.credit { color: var(--band-muted); }
/* Band element, so it takes the band accent — the page accent is tuned for the
   light background and can fail against black. */
.credit a { color: var(--band-accent); text-decoration: none; font-weight: 600; }
.credit a:hover { text-decoration: underline; }

/* ==========================================================================
   9. Motion
   Every rule here is decoration. The page is complete and readable without it:
   with JS off the .anim class is never set, and the reduced-motion block above
   flattens the lot for anyone who has asked their device for less movement.
   -------------------------------------------------------------------------- */

/* ── Scroll reveal ── */
.anim .reveal { opacity: 0; transform: translateY(18px); }
.anim .reveal { transition: opacity .7s var(--ease), transform .7s var(--ease); }
.anim .reveal.in { opacity: 1; transform: none; }
/* Cards arrive in sequence rather than as a block — reads as deliberate, not laggy */
.anim .svc.reveal:nth-child(2), .anim .shot.reveal:nth-child(2) { transition-delay: .07s; }
.anim .svc.reveal:nth-child(3), .anim .shot.reveal:nth-child(3) { transition-delay: .14s; }
.anim .svc.reveal:nth-child(4), .anim .shot.reveal:nth-child(4) { transition-delay: .21s; }
.anim .svc.reveal:nth-child(5) { transition-delay: .28s; }
.anim .svc.reveal:nth-child(6) { transition-delay: .35s; }

/* ── Hero entrance. Pure CSS, so it runs whether or not JS loads. ── */
@keyframes rise { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
.hero-badge, .hero h1, .hero-sub, .hero-actions, .chips { animation: rise .8s var(--ease) both; }
.hero h1      { animation-delay: .08s; }
.hero-sub     { animation-delay: .16s; }
.hero-actions { animation-delay: .24s; }
.chips        { animation-delay: .32s; }

/*
/* ── Header settles onto the page once you scroll ── */
.header { transition: box-shadow .25s var(--ease), background-color .25s var(--ease); }
.header.scrolled { box-shadow: var(--shadow-sm); background: color-mix(in srgb, var(--bg) 97%, transparent); }

/* ── Section eyebrows draw their rule ── */
.eyebrow { display: inline-flex; align-items: center; gap: 10px; }
.eyebrow::after {
  content: ""; height: 1px; width: 0; background: currentColor; opacity: .55;
  transition: width .7s var(--ease) .15s;
}
.reveal.in .eyebrow::after { width: 30px; }
/* No JS, no reveal event — so the rule is simply drawn from the start */
html:not(.anim) .eyebrow::after { width: 30px; }

/* ── Service rows lift on hover, and on keyboard focus too ── */
.svc { transition: transform .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease); }
.svc:hover, .svc:focus-within { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: color-mix(in srgb, var(--accent) 42%, var(--border)); }
.svc:hover .price, .svc:focus-within .price { color: var(--accent); }

/* ── A light sweeps across the main button on hover ── */
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::after {
  content: ""; position: absolute; inset: 0 auto 0 -60%; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.55), transparent);
  transform: skewX(-18deg); opacity: 0; pointer-events: none;
}
.btn-primary:hover::after { animation: sweep .65s var(--ease) forwards; }
@keyframes sweep { from { left: -60%; opacity: 1; } to { left: 120%; opacity: 1; } }

/* ── Chips and gallery placeholders breathe, very slightly ── */
.chip { transition: transform .18s var(--ease), border-color .18s var(--ease); }
.chip:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent-bright) 55%, var(--band-border)); }
@keyframes breathe { 50% { opacity: .45; } }
.shot span { animation: breathe 4.5s ease-in-out infinite; }
.shot:nth-child(2) span { animation-delay: .6s; }
.shot:nth-child(3) span { animation-delay: 1.2s; }
.shot:nth-child(4) span { animation-delay: 1.8s; }

/* ── Theme changes crossfade instead of snapping ── */
body, .header, .section, .footer, .cta-band, .hero, .visit-card, .svc, .shot {
  transition-property: background-color, color, border-color;
  transition-duration: .35s; transition-timing-function: var(--ease);
}

/* ==========================================================================
   10. Ambient motion — things that keep moving
   All of it is decorative and all of it is switched off, or removed entirely,
   for anyone who asks for reduced motion.
   -------------------------------------------------------------------------- */

/* ── Scroll progress, drawn as a barber stripe ── */
.progress {
  position: fixed; left: 0; right: 0; height: 3px; z-index: 400;
  top: 0; transform-origin: 0 50%; transform: scaleX(var(--p, 0));
  background: repeating-linear-gradient(115deg,
    var(--accent-bright) 0 9px, #f2f6f2 9px 18px);
  pointer-events: none;
}
body.has-ribbon .progress { top: var(--ribbon-h, 34px); }
html:not(.anim) .progress { display: none; }

/* ── The ticker: services running past, the way a shop board would ── */
.ticker {
  background: var(--band-bg); color: var(--band-text);
  border-block: 1px solid var(--band-border);
  overflow: hidden; padding-block: 13px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.ticker-track {
  display: flex; align-items: center; gap: 26px; width: max-content;
  animation: ticker 34s linear infinite;
}
.ticker:hover .ticker-track { animation-play-state: paused; }
.ticker-track span {
  font-size: .84rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  white-space: nowrap;
}
.ticker-track svg { color: var(--accent-bright); flex: 0 0 auto; }
@keyframes ticker { to { transform: translateX(-50%); } }

/* ── Barber-stripe rule: a moving band between sections ── */
.stripe-rule {
  height: 10px;
  background: repeating-linear-gradient(115deg,
    var(--accent-bright) 0 12px, #f2f6f2 12px 24px, var(--band-bg) 24px 36px);
  background-size: 200% 100%;
  animation: stripe-slide 3.2s linear infinite;
}
@keyframes stripe-slide { to { background-position: -72px 0; } }


/* ── The hero lights up under the pointer ── */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%),
    color-mix(in srgb, var(--accent-bright) 16%, transparent), transparent 70%);
  opacity: 0; transition: opacity .5s var(--ease);
}
.hero.lit::after { opacity: 1; }


/* ── Gallery placeholders shimmer, so an empty frame reads as "photo coming" ── */
.shot { position: relative; overflow: hidden; }
.shot::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--band-text) 9%, transparent) 50%, transparent 80%);
  transform: translateX(-100%);
  animation: shimmer 3.4s var(--ease) infinite;
}
.shot:nth-child(2)::after { animation-delay: .5s; }
.shot:nth-child(3)::after { animation-delay: 1s; }
.shot:nth-child(4)::after { animation-delay: 1.5s; }
@keyframes shimmer { to { transform: translateX(100%); } }

/* ── The brand scissors snip when you point at them ── */
.brand:hover .brand-mark svg, .brand:focus-visible .brand-mark svg { animation: snip .5s var(--ease) 2; }
@keyframes snip { 50% { transform: rotate(-16deg) scale(.92); } }

/* Anything that only exists to move is removed outright for reduced motion —
   a frozen ticker or a stalled stripe looks broken rather than calm. */
@media (prefers-reduced-motion: reduce) {
  .ticker, .progress { display: none; }
  .stripe-rule { animation: none; }
  .shot::after { display: none; }
}

/* ── Gallery: real photos vs. spaces still waiting for one ── */
.shot--wide { grid-column: 1 / -1; aspect-ratio: 5 / 3; }
@media (min-width: 760px) {
  /* The empty main slot stays wide but shallow — a hole shouldn't dominate the page */
  .shot--wide { aspect-ratio: 3 / 1; }
  /* Two examples, half the row each, rather than four thumbnails */
  .shot--photo { grid-column: span 2; aspect-ratio: 4 / 3; }
}
/* Bias the crop up a little — the interior shot has its subject above centre */
.shot--photo img { object-position: center 42%; }
/* <figure> carries a default 40px side margin from the browser — without this the
   photo sits shrunken inside its own frame. */
.shot--photo { margin: 0; padding: 0; display: block; position: relative; }
.shot--photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Only an empty frame shimmers — a real photo is not "loading" */
.shot--photo::after { display: none; }
.shot-tag {
  position: absolute; left: 10px; bottom: 10px; z-index: 2;
  font-family: "Oswald", sans-serif; text-transform: uppercase; letter-spacing: .14em;
  font-size: .62rem; font-weight: 600; color: #fff;
  background: rgba(6, 10, 7, .82); border: 1px solid rgba(255,255,255,.24);
  padding: 5px 9px; border-radius: 2px;
}

/* ── Scroll cue. A real link, so it works by keyboard and actually goes somewhere. ── */
.scroll-cue {
  display: inline-flex; flex-direction: column; align-items: flex-start; gap: 10px;
  margin-top: clamp(28px, 4vw, 44px); text-decoration: none;
  font-family: "Oswald", sans-serif; text-transform: uppercase; letter-spacing: .2em;
  font-size: .7rem; font-weight: 500; color: var(--band-muted);
  transition: color .2s var(--ease), opacity .4s var(--ease), transform .4s var(--ease);
}
.scroll-cue:hover { color: var(--band-text); }
.scroll-cue-line { position: relative; display: block; width: 1px; height: 46px; background: var(--band-border); overflow: hidden; }
/* A dot runs down the line */
.scroll-cue-line::after {
  content: ""; position: absolute; left: -1.5px; top: 0; width: 4px; height: 12px;
  background: var(--band-accent); animation: cue-run 1.9s var(--ease) infinite;
}
@keyframes cue-run {
  0%   { transform: translateY(-14px); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: translateY(46px); opacity: 0; }
}
/* Once the visitor has started scrolling the prompt has done its job */
.is-scrolled .scroll-cue { opacity: 0; transform: translateY(8px); pointer-events: none; }

/* ── Map embed ── */
.map {
  border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden;
  box-shadow: var(--shadow-sm); background: var(--bg-alt); min-height: 268px;
}
.map iframe { display: block; width: 100%; height: 100%; min-height: 268px; border: 0; }
/* Google's tiles are light in both themes; a slight knock-back stops them glaring
   out of a dark page without making the map hard to read. */
:root[data-theme="dark"] .map iframe { filter: brightness(.88) contrast(1.04); }

/* ==========================================================================
   11. Inner page heads — the compact band that replaces the hero away from home
   -------------------------------------------------------------------------- */
.page-head { position: relative; overflow: hidden; background: var(--band-bg); color: var(--band-text); padding-block: clamp(40px, 6vw, 68px); }
.page-head h1 { font-size: clamp(2rem, 5.4vw, 3.3rem); text-transform: uppercase; line-height: .98; letter-spacing: -.005em; }
.page-head p { color: var(--band-muted); margin-top: 14px; max-width: 54ch; font-size: 1.02rem; }
.page-head .hero-badge { margin-bottom: 16px; }
.crumb { color: var(--band-muted); font-size: .8rem; letter-spacing: .13em; text-transform: uppercase; font-family: "Oswald", sans-serif; }
/* Colour alone is not enough to mark a link inside a line of text (WCAG 1.4.1) */
.crumb a { color: var(--band-accent); text-decoration: underline; text-underline-offset: 3px; }
.crumb a:hover { text-decoration: underline; }
.nav a[aria-current="page"], .mobile-nav a[aria-current="page"] { color: var(--text); box-shadow: inset 0 -2px 0 var(--accent); }


/* ==========================================================================
   12. Refinement pass
   Fewer effects, more space, sharper type. Premium here means restraint:
   hairlines instead of shadows, one accent used sparingly, slower motion.
   -------------------------------------------------------------------------- */

/* ── Air. The single biggest difference between cheap and considered. ── */
.section  { padding-block: clamp(76px, 10vw, 150px); }
.hero     { padding-block: clamp(92px, 13vw, 176px); }
.page-head{ padding-block: clamp(64px, 9vw, 112px); }
.section-head { margin-bottom: clamp(40px, 5.5vw, 68px); }
.hero-in  { padding-right: 0; }

/* ── Type: more contrast between display and text ── */
.hero h1 { font-size: clamp(2.9rem, 7.4vw, 5.6rem); line-height: .93; }
.h2 { font-size: clamp(2rem, 4.4vw, 3rem); line-height: 1.02; }
.lede { font-size: clamp(1.06rem, 1.5vw, 1.2rem); line-height: 1.65; max-width: 54ch; }
.hero-sub { font-size: clamp(1.06rem, 1.7vw, 1.22rem); line-height: 1.62; max-width: 44ch; margin-top: 24px; }
.prose p { line-height: 1.75; }

/* ── Buttons: set like signage, and no drop shadow ── */
.btn {
  font-family: "Oswald", sans-serif; text-transform: uppercase;
  letter-spacing: .13em; font-size: .8rem; font-weight: 500; padding: 16px 28px;
}
.btn-primary { box-shadow: none; }
.btn-primary:hover { filter: none; background: var(--accent); }

/* ── Chips: a quiet hairline row, not a stack of tags ── */
.chips { gap: 0; margin-top: 40px; row-gap: 10px; }
.chip { border-left: 1px solid var(--band-border); padding: 2px 20px; margin: 0; font-size: .68rem; letter-spacing: .18em; }
.chip:first-child { padding-left: 0; border-left: 0; }

/* ── The menu, typeset as a price list ── */
.menu-list { border-top: 1px solid var(--border); }
.menu-list .svc {
  display: flex; align-items: baseline; justify-content: space-between; gap: 28px;
  background: none; border: 0; border-bottom: 1px solid var(--border);
  border-radius: 0; box-shadow: none; padding: clamp(22px, 2.8vw, 34px) 0;
}
.menu-list .svc:hover, .menu-list .svc:focus-within { transform: none; box-shadow: none; border-color: var(--border); }
.menu-list h3 { font-size: clamp(1.2rem, 2.1vw, 1.55rem); font-weight: 500; letter-spacing: .005em; }
.menu-list p { margin-top: 7px; max-width: 44ch; }
.menu-list .price { font-size: clamp(1.05rem, 1.7vw, 1.3rem); font-variant-numeric: tabular-nums; }

/* ── Surfaces: hairlines, not shadows ── */
.visit-card { box-shadow: none; }
.map { box-shadow: none; }

/* ── Gallery: calm empty frames. A shimmer on a hole reads as broken. ── */
.shot { background: var(--bg-alt); border-color: var(--border); color: var(--text-muted); }
.shot::after { display: none; }
.shot span { font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; opacity: 1; animation: none; }

/* ── The ticker steps back: smaller, slower, quieter ── */
.ticker { padding-block: 16px; }
.ticker-track { animation-duration: 52s; gap: 34px; }
.ticker-track span { font-size: .72rem; letter-spacing: .22em; font-weight: 500; color: var(--band-muted); }
.ticker-track svg { opacity: .5; }

/* ── Motion: slower and shorter travel, so it reads as poise not bounce ── */
.anim .reveal { transform: translateY(11px); transition-duration: .95s; }
.stripe-rule { height: 6px; animation-duration: 5s; }

/* ── The shop's own logo ──────────────────────────────────────────────────
   It was drawn as black and green ink on a light ground, so its black lines
   vanish on a dark background. Everywhere it appears it sits on a light tile,
   which is how it was designed to be seen — in both themes. */
/* Header logo, added on the client's request (2026-09-25). The crest is detailed, so it
   sits on the same pale disc as the About crest (black stars would vanish on the dark
   header) and the wordmark stays beside it — the crest's own lettering is not readable
   at this size, so the wordmark carries the name. Header grows 66→72px to fit it. */
.brand-logo {
  width: 48px; height: 48px; flex: 0 0 auto; box-sizing: border-box;
  background: #eceeec; border-radius: 50%; padding: 4px;
}
.footer .brand-logo { width: 40px; height: 40px; }
.crest {
  display: block; width: clamp(112px, 15vw, 158px); height: auto;
  background: #eceeec; border-radius: 50%; padding: 10px; margin-bottom: 26px;
}
