/* ===========================================================
   Apple Nailed It Spa — Impact Web Solutions
   PALETTE: every brand color is a variable in :root below.
   To match their existing brand, change ONLY those 8 values.
   =========================================================== */

:root {
  /* --- BRAND — sampled directly from their logo + live site --- */
  --brand:        #C22749;   /* crimson — their "Book Now" + headings. PRIMARY ACTION */
  --brand-dark:   #9E1D3A;   /* crimson hover */
  --brand-light:  #E0748C;   /* soft crimson */
  --accent:       #84C441;   /* apple green — the logo green. IDENTITY */
  --accent-deep:  #4A7522;   /* green as TEXT. #5C8F2B was here and claimed to
                                pass contrast; it measured 3.5:1 on the soft band
                                and 3.9:1 on white, both below AA. This is 5.0:1
                                and up everywhere it is used. */
  --accent-soft:  #EEF9DC;   /* pale lime wash (from their gradient) */
  --green-deep:   #2C4318;   /* deep leaf — dark sections + hero */
  --cream:        #FCFCF8;   /* page background */
  --ink:          #242424;   /* body text (their existing top bar) */
  --ink-soft:     #5F6058;   /* secondary text */
  --band:         #F3F6EA;   /* soft section band — brand green, heavily diluted */
  --band-warm:    #FBF6F1;   /* warm alternative band */
  --star:         #F2A83B;   /* review stars only — reads as 'rating' universally */

  /* --- derived --- */
  --white: #fff;
  --line: rgba(36,36,36,.13);
  --shadow-sm: 0 1px 3px rgba(36,36,36,.07), 0 1px 2px rgba(36,36,36,.04);
  --shadow-md: 0 4px 16px rgba(36,36,36,.10);
  --shadow-lg: 0 12px 40px rgba(36,36,36,.14);
  --radius: 14px;
  --radius-sm: 8px;
  --maxw: 1180px;
  --gut: clamp(1.15rem, 4vw, 2.5rem);

  --sans: "Jost", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--cream); color: var(--ink);
  font-family: var(--sans); font-size: 17px; line-height: 1.72;
  font-weight: 350; overflow-x: hidden;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: 3px; }

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 600; line-height: 1.16; margin: 0 0 .5em; letter-spacing: -.01em; }
h1 { font-size: clamp(2.3rem, 5.4vw, 3.9rem); }
h2 { font-size: clamp(1.7rem, 3.4vw, 2.55rem); }
h3 { font-size: clamp(1.24rem, 2vw, 1.55rem); }
p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut); }
.narrow { max-width: 820px; }
.center { text-align: center; }
.eyebrow {
  font-family: var(--sans); font-size: .74rem; font-weight: 600;
  letter-spacing: .19em; text-transform: uppercase; color: var(--accent-deep);
  margin: 0 0 .9rem;
}
.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  font-family: var(--sans); font-size: .93rem; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; text-decoration: none;
  padding: 1.02rem 2.1rem; border-radius: 100px; border: 1.5px solid transparent;
  cursor: pointer; transition: all .22s ease; white-space: nowrap;
}
.btn-primary { background: var(--brand); color: var(--white); box-shadow: var(--shadow-md); }
.btn-primary:hover { background: var(--brand-dark); transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.btn-green { background: var(--accent); color: #1C2A0F; box-shadow: var(--shadow-md); }
.btn-green:hover { background: #93D24E; transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.btn-ghost { background: transparent; color: var(--white); border-color: rgba(255,255,255,.5); }
.btn-ghost:hover { background: var(--white); color: var(--brand); border-color: var(--white); }
.btn-outline { background: transparent; color: var(--brand); border-color: var(--brand); }
.btn-outline:hover { background: var(--brand); color: var(--white); }

/* ---------- top bar ---------- */
.topbar {
  background: var(--ink); color: rgba(255,255,255,.9);
  font-size: .82rem; letter-spacing: .02em;
}
.topbar .wrap { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 42px; flex-wrap: wrap; }
.topbar a { color: inherit; text-decoration: none; }
.topbar a:hover { color: var(--accent); }
.topbar-hours { opacity: .85; }
.topbar-rating { display: inline-flex; align-items: center; gap: .4rem; font-weight: 500; }
.topbar-rating .stars { color: var(--star); letter-spacing: .08em; }

/* ---------- header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 90;
  background: rgba(252,252,248,.98);
  /* no backdrop-filter: the header is sticky, so a blur here forces the
     browser to recomposite everything behind it on every scroll frame. At
     98% opacity the blur was invisible anyway. */
  border-bottom: 1px solid var(--line);
}
/* The logo is the tallest thing in the header, so the bar's height is set
   from it: the logo plus the breathing room either side, and never less.
   min-height alone let the two fight when the logo grew. */
.site-header .wrap { display: flex; align-items: center; gap: 1.5rem;
  padding-top: 5px; padding-bottom: 5px; min-height: 98px; }
.logo { display: flex; align-items: center; gap: .7rem; text-decoration: none; margin-right: auto; flex-shrink: 0; }
.logo img { height: 88px; width: auto; max-width: 100%; }
@media (max-width: 900px) { .site-header .wrap { min-height: 81px; } .logo img { height: 71px; } }
/* Below 860px the mobile pass takes over the header entirely — a second rule
   here would only be dead weight that looks like it is doing something. */
.logo-text { font-family: var(--serif); font-size: 1.42rem; font-weight: 600; color: var(--brand); line-height: 1.05; }
.logo-text small { display: block; font-family: var(--sans); font-size: .6rem; font-weight: 500; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-soft); }

.nav { display: flex; align-items: center; gap: .3rem; }
.nav > li { position: relative; list-style: none; }
.nav ul { list-style: none; margin: 0; padding: 0; }
.nav > li > a {
  display: block; padding: .65rem .85rem; font-size: .9rem; font-weight: 500;
  color: var(--ink); text-decoration: none; border-radius: var(--radius-sm);
  transition: color .18s, background .18s;
}
.nav > li > a:hover, .nav > li.current > a { color: var(--brand); background: rgba(132,196,65,.14); }
.nav > li.current > a { font-weight: 600; }
.has-sub > a::after { content: "▾"; margin-left: .35rem; font-size: .7em; opacity: .6; }
.submenu {
  position: absolute; top: calc(100% + 6px); left: 0; min-width: 285px;
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: .5rem; opacity: 0; visibility: hidden;
  transform: translateY(-6px); transition: all .2s ease;
}
.has-sub:hover .submenu, .has-sub:focus-within .submenu { opacity: 1; visibility: visible; transform: translateY(0); }
.submenu a {
  display: block; padding: .6rem .8rem; font-size: .87rem; color: var(--ink);
  text-decoration: none; border-radius: var(--radius-sm); transition: all .16s;
}
.submenu a:hover { background: var(--accent-soft); color: var(--brand-dark); }
.header-cta { flex-shrink: 0; }
.header-cta .btn { padding: .8rem 1.5rem; font-size: .82rem; }

.nav-toggle {
  /* flex: 0 0 44px, not width: 44px. As a flex item in the header row it was
     shrinkable, and at 390px the logo alone is 263px wide — so the bars got
     squeezed to 8px and the hamburger read as three dots. A control must never
     be the thing that gives way. */
  display: none; background: none; border: 0; cursor: pointer; padding: .5rem;
  flex: 0 0 44px; width: 44px; height: 44px; box-sizing: border-box;
  flex-direction: column; justify-content: center; align-items: stretch; gap: 5px;
}
.nav-toggle span { width: 100%; }
.nav-toggle span { display: block; height: 2px; background: var(--ink); border-radius: 2px; transition: all .25s; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* 1100, not 1040. Adding Gallery took the nav to five links plus the booking
   button; at 1041px the logo (351px), nav (473px) and CTA (132px) came to more
   than the container and the header scrolled sideways. The hamburger takes
   over before it gets tight rather than after. */
@media (max-width: 1100px) {
  .nav-toggle { display: flex; }
  .header-cta { display: none; }
  .nav {
    /* --nav-top is the real bottom edge of the header, measured in site.js.
       It was hardcoded at 82px, which is right on a plain page and wrong the
       moment anything sits above the header — signed in to the editor the
       admin bar is ~150px tall, so the flyout opened underneath it. 82px
       stays as the fallback for JS-off. */
    position: fixed; inset: var(--nav-top, 82px) 0 auto 0;
    flex-direction: column; align-items: stretch;
    gap: 0; background: var(--white); border-bottom: 1px solid var(--line);
    padding: 1rem var(--gut) 2rem; overflow-y: auto;
    max-height: calc(100dvh - var(--nav-top, 82px));
    box-shadow: var(--shadow-lg); display: none;
  }
  .nav.open { display: flex; }
  .nav > li > a { padding: .95rem .4rem; border-bottom: 1px solid var(--line); border-radius: 0; }
  .submenu {
    position: static; opacity: 1; visibility: visible; transform: none; box-shadow: none;
    border: 0; border-left: 2px solid var(--accent-soft); border-radius: 0;
    margin: 0 0 .5rem .6rem; padding: .25rem 0 .25rem .5rem; min-width: 0;
  }
  .has-sub > a::after { float: right; }
}

/* ---------- hero ---------- */
.hero {
  position: relative; background: var(--green-deep); color: var(--white);
  padding: clamp(4rem, 11vw, 8rem) 0 clamp(3.5rem, 9vw, 6.5rem); overflow: hidden;
}
.hero::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 80% 95% at 88% 8%, rgba(132,196,65,.42), transparent 60%),
    radial-gradient(ellipse 70% 60% at 6% 96%, rgba(132,196,65,.20), transparent 62%);
}
.hero > * { position: relative; }
.hero h1 { color: var(--white); max-width: 15ch; }
.hero.page-hero h1 { max-width: 22ch; }
.hero-lede { font-size: clamp(1.05rem, 1.9vw, 1.28rem); max-width: 56ch; color: rgba(255,255,255,.9); margin-bottom: 2.2rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .9rem; }
.hero .eyebrow { color: var(--accent); }
.section-brand .eyebrow { color: var(--accent); }
.hero-trust {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1.6rem;
  margin-top: 2.8rem; padding-top: 1.8rem; border-top: 1px solid rgba(255,255,255,.18);
  font-size: .88rem; color: rgba(255,255,255,.82);
}
.hero-trust strong { color: var(--white); font-weight: 600; }
.hero-trust .stars { color: var(--star); letter-spacing: .1em; }

.crumbs { font-size: .8rem; color: rgba(255,255,255,.62); margin-bottom: 1.1rem; }
/* Underlined, not just a different shade of white: a link inside a line
   of text has to be findable without relying on color. Caught by the
   accessibility sweep on every interior page. */
.crumbs a { color: rgba(255,255,255,.82); text-decoration: underline;
            text-underline-offset: .18em; text-decoration-thickness: 1px; }
.crumbs a:hover { color: var(--accent); }
.crumbs span { margin: 0 .45rem; opacity: .5; }

/* ---------- sections ---------- */
.section { padding: clamp(3.5rem, 8vw, 6.5rem) 0; }
.section-tight { padding: clamp(2.5rem, 5vw, 4rem) 0; }
/* was plain white, which is indistinguishable from the page behind it —
   the alternation did nothing and long stretches read as empty. */
.section-alt { background: var(--band); }

.section-brand { background: var(--green-deep); color: var(--white); }
.section-brand h2, .section-brand h3 { color: var(--white); }

.section-head { max-width: 720px; margin: 0 auto clamp(2.4rem, 5vw, 3.6rem); text-align: center; }
.section-head p { color: var(--ink-soft); font-size: 1.06rem; }
.section-brand .section-head p { color: rgba(255,255,255,.85); }

/* ---------- service tiles ---------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1.4rem; }
.tile {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 260px; padding: 1.6rem; border-radius: var(--radius);
  background: var(--green-deep); color: var(--white); text-decoration: none;
  overflow: hidden; box-shadow: var(--shadow-md); transition: transform .28s, box-shadow .28s;
}
.tile::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(165deg, rgba(0,0,0,.34), rgba(10,11,10,.84));
  transition: background .28s;
}
.tile > * { position: relative; z-index: 1; }
.tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.tile:hover { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
.tile:hover::after { background: linear-gradient(165deg, rgba(0,0,0,.46), rgba(10,11,10,.90)); }
.tile h3 { color: var(--white); margin-bottom: .3rem; font-size: 1.35rem; }
.tile span { font-size: .82rem; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); font-weight: 600; }

/* ---------- pricing ---------- */
/* The rules that used to live here are superseded by the PRICE PANELS
   block further down. They were left in place through the redesign and
   the leftover padding on .price-card was still winning, which is why
   the photograph sat in a white gutter instead of running to the card
   edge. Dead CSS is not harmless. */

/* ---------- prose ---------- */
.prose h2 { margin-top: 2.6rem; color: var(--brand-dark); }
.prose h2:first-child { margin-top: 0; }
.prose h2::after {
  content: ""; display: block; width: 54px; height: 3px;
  background: var(--accent); border-radius: 2px; margin-top: .7rem;
}
.prose p { color: var(--ink); }
.prose-2col { columns: 2; column-gap: 3rem; }
@media (max-width: 800px) { .prose-2col { columns: 1; } }

/* ---------- testimonials ---------- */
.quotes { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 1.5rem; }
.quote {
  background: var(--white); border-radius: var(--radius); padding: 2rem;
  box-shadow: var(--shadow-sm); border-top: 3px solid var(--accent); display: flex; flex-direction: column;
}
.quote .stars { color: var(--star); letter-spacing: .13em; margin-bottom: .9rem; font-size: 1.02rem; }
.quote blockquote { margin: 0 0 1.2rem; font-size: 1rem; line-height: 1.68; color: var(--ink); flex: 1; }
.quote cite { font-style: normal; font-weight: 600; font-size: .92rem; color: var(--brand); }

/* ---------- booking ---------- */
.booking-block {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  padding: clamp(1.6rem, 4vw, 2.8rem); box-shadow: var(--shadow-md); text-align: center;
}
#booking-embed { min-height: 40px; }
#booking-embed:empty::after {
  content: "Online booking loads here."; display: block; padding: 2.4rem 1rem;
  border: 2px dashed var(--line); border-radius: var(--radius-sm);
  color: var(--ink-soft); font-size: .9rem;
}
.booking-fallback { margin-top: 1.4rem; font-size: .93rem; color: var(--ink-soft); }
.booking-fallback a { font-weight: 600; }

/* ---------- areas ---------- */
.area-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: .7rem; list-style: none; margin: 0; padding: 0; }
.area-grid a {
  display: block; padding: .85rem 1.1rem; background: var(--white);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  text-decoration: none; color: var(--ink); font-size: .93rem; transition: all .18s;
}
.area-grid a:hover { border-color: var(--brand); color: var(--brand); background: var(--accent-soft); transform: translateX(3px); }
.area-grid .plain { display: block; padding: .85rem 1.1rem; font-size: .93rem; color: var(--ink-soft); }

/* ---------- contact cards ---------- */
.contact-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: 1.4rem; }
.contact-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 2rem; text-align: center; box-shadow: var(--shadow-sm); transition: all .25s;
}
.contact-card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px); }
.contact-card .ico {
  width: 52px; height: 52px; margin: 0 auto 1.1rem; border-radius: 50%;
  background: var(--accent-soft); display: grid; place-items: center; font-size: 1.35rem;
}
.contact-card h3 { font-size: 1.2rem; margin-bottom: .35rem; }
.contact-card p { font-size: .9rem; color: var(--ink-soft); margin-bottom: .7rem; }
.contact-card a { font-weight: 600; font-size: 1.02rem; word-break: break-word; }

.hours-table { width: 100%; border-collapse: collapse; }
.hours-table th, .hours-table td { padding: .8rem .3rem; border-bottom: 1px solid var(--line); font-size: .96rem; }
.hours-table th { text-align: left; font-weight: 500; font-family: var(--sans); white-space: nowrap; }
.hours-table td { text-align: right; font-weight: 600; color: var(--brand); white-space: nowrap; }
.hours-table tr:last-child th, .hours-table tr:last-child td { border-bottom: 0; }

/* ---------- CTA band ---------- */
.cta-band { background: var(--brand); color: var(--white); text-align: center; padding: clamp(3rem, 7vw, 5rem) 0; }
.cta-band h2 { color: var(--white); }
.cta-band p { color: rgba(255,255,255,.88); max-width: 55ch; margin-inline: auto; font-size: 1.06rem; }
.cta-actions { display: flex; flex-wrap: wrap; gap: .9rem; justify-content: center; margin-top: 2rem; }

/* ---------- footer ---------- */
.site-footer { background: var(--ink); color: rgba(255,255,255,.72); padding: clamp(3rem, 6vw, 4.5rem) 0 0; font-size: .93rem; }
/* Five columns now: brand, Quick Links, Price List, Areas We Serve, Visit Us.
   It was four, so adding the areas column pushed Visit Us onto a second row
   underneath the brand and left a hole across the middle. The brand column
   keeps the extra width; the four link columns share what is left. */
/* Five children: brand + Quick Links + Price List + Areas We Serve + Visit Us.
   Five never divides evenly, so below the wide breakpoint the brand column is
   given a full row of its own and the four link groups share the row beneath.
   That keeps every row full instead of leaving one orphan block. */
.footer-grid { display: grid; grid-template-columns: 1.6fr repeat(4, 1fr); gap: 2.2rem; }
@media (max-width: 1100px) {
  .footer-grid { grid-template-columns: repeat(4, 1fr); gap: 2.4rem 2rem; }
  .footer-grid > :first-child { grid-column: 1 / -1; max-width: 46ch; }
}
@media (max-width: 780px) {
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 2rem 2.5rem; }
  .footer-grid > :first-child { grid-column: 1 / -1; }
}
@media (max-width: 640px)  { .footer-grid { grid-template-columns: 1fr; } }
/* h2 since the a11y pass: h4 straight after the page's h2s skipped a level.
   The size is set here, so the tag change is invisible on screen. */
.site-footer h2 {
  font-family: var(--sans); font-size: .78rem; font-weight: 600; letter-spacing: .17em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 1.1rem;
}
.site-footer a { color: rgba(255,255,255,.8); text-decoration: none; }
.site-footer a:hover { color: var(--accent); }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: .55rem; }
.site-footer .logo-text { color: var(--white); }
.site-footer .logo-text small { color: rgba(255,255,255,.55); }
.footer-social { display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 1.2rem; }
.footer-social a {
  width: 38px; height: 38px; border-radius: 50%; background: rgba(255,255,255,.09);
  display: grid; place-items: center; color: rgba(255,255,255,.88);
  transition: background .2s ease, color .2s ease, transform .2s ease;
}
/* The glyph inherits the link color, so one rule recolors icon and text alike. */
.footer-social svg { width: 18px; height: 18px; fill: currentColor; display: block; }
.footer-social .soc-txt { font-size: .62rem; font-weight: 800; letter-spacing: .03em; }
/* Each button carries its own brand color inline (--brand), set in footer.php.
   X and TikTok are black brands, invisible on a dark footer, so those two get a
   white chip with dark ink instead — that is what --brand-ink is for. */
.footer-social a:hover,
.footer-social a:focus-visible {
  background: var(--brand, var(--accent));
  color: var(--brand-ink, #fff);
  transform: translateY(-2px);
}
.footer-social a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .footer-social a { transition: none; }
  .footer-social a:hover, .footer-social a:focus-visible { transform: none; }
}
.footer-bottom {
  margin-top: 3rem; padding: 1.5rem 0; border-top: 1px solid rgba(255,255,255,.12);
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
  font-size: .84rem; color: rgba(255,255,255,.5);
}
.footer-bottom a { color: rgba(255,255,255,.6); }

/* ---------- misc ---------- */
.skip {
  position: absolute; left: -9999px; top: 0; background: var(--brand); color: #fff;
  padding: .8rem 1.3rem; z-index: 999; border-radius: 0 0 var(--radius-sm) 0;
}
.skip:focus-visible { left: 0; }
/* :focus fires on mouse clicks too, which is why this was popping up in the
   corner during normal use. :focus-visible fires only for keyboard
   navigation, so it stays out of the way but still works for anyone
   tabbing through the page. */
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

@media print {
  .site-header, .topbar, .cta-band, .site-footer, .hero-actions { display: none; }
  body { background: #fff; font-size: 12pt; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ===========================================================
   HERO SPLIT + LIGHT SERVICE CARDS
   These styles cover the state BEFORE their photography is in.
   When the image archive lands, add class "has-img" to a .tile
   and drop an <img> inside it — the dark photo-overlay styles
   above take over automatically.
   =========================================================== */
.hero-split { display: grid; grid-template-columns: 1.15fr .85fr; gap: 0; align-items: stretch;
  /* One filter for the pair, so no seam shows where they meet. Three stacked
     drop-shadows: a soft green bloom thrown up-left and a crimson one thrown
     down-right, matching the diagonal the frame already runs, plus a neutral
     shadow underneath so the block still has real weight rather than only
     glow. drop-shadow follows the rounded silhouette, unlike box-shadow. */
  /* Was a green glow up-left and a crimson one down-right. filter creates a
     filtered subtree, so that green spilled across the photograph around and
     behind the copy panel — which is the green hue on desktop. The phone rule
     below already used a single neutral shadow, which is exactly why the phone
     looked right and the desktop did not. Neutral here too: same weight, same
     silhouette, no color cast on the picture. */
  filter:
    drop-shadow(-14px -10px 26px rgba(0,0,0,.32))
    drop-shadow(14px 10px 26px rgba(0,0,0,.26))
    drop-shadow(0 22px 40px rgba(0,0,0,.42)); }
@media (max-width: 940px) { .hero-split { grid-template-columns: 1fr; } }

.hero-card {
  background: rgba(255,255,255,.97); color: var(--ink); border-radius: var(--radius);
  padding: 2.2rem; box-shadow: var(--shadow-lg);
}
.hero-card .rating-big { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .3rem; }
.hero-card .rating-big b { font-family: var(--serif); font-size: 3rem; line-height: 1; color: var(--brand); }
.hero-card .rating-big .stars { color: var(--star); font-size: 1.15rem; letter-spacing: .1em; }
.hero-card .rating-sub { font-size: .88rem; color: var(--ink-soft); margin-bottom: 1.5rem; }
.hero-card hr { border: 0; border-top: 1px solid var(--line); margin: 1.4rem 0; }
.hero-card h3 { font-size: 1.05rem; font-family: var(--sans); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-deep); margin-bottom: 1rem; font-size: .76rem; }
.hero-card dl { margin: 0; display: grid; grid-template-columns: 1fr auto; gap: .55rem 1rem; font-size: .95rem; }
.hero-card dt { color: var(--ink); }
.hero-card dd { margin: 0; font-weight: 700; color: var(--brand); white-space: nowrap; }
.hero-card .fine { font-size: .78rem; color: var(--ink-soft); margin-top: 1.2rem; }

/* light service cards (no photography yet) */
.tiles.cards { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .tiles.cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .tiles.cards { grid-template-columns: 1fr; } }
.card-tile {
  position: relative; display: flex; flex-direction: column; min-height: 0;
  background: var(--white); border: 1px solid var(--line); border-top: 3px solid var(--accent);
  border-radius: var(--radius); padding: 1.9rem 1.7rem; text-decoration: none; color: var(--ink);
  box-shadow: var(--shadow-sm); transition: transform .25s, box-shadow .25s, border-top-color .25s;
}
.card-tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-top-color: var(--brand); }
.card-tile .loc { font-size: .7rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--accent-deep); margin-bottom: .55rem; }
.card-tile h3 { font-size: 1.4rem; margin-bottom: .5rem; color: var(--ink); }
.card-tile p { font-size: .92rem; color: var(--ink-soft); margin-bottom: 1.1rem; flex: 1; }
.card-tile .go { font-size: .82rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--brand); }
.card-tile:hover .go { text-decoration: underline; text-underline-offset: 4px; }

/* pillars on the dark band */
.pillars { display: grid; grid-template-columns: repeat(auto-fit,minmax(260px,1fr)); gap: 1.4rem; }
.pillar { background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.11); border-radius: var(--radius); padding: 2rem; }
.pillar h3 { color: var(--white); font-size: 1.3rem; }
.pillar p { color: rgba(255,255,255,.86); font-size: .95rem; margin: 0; }

/* ===========================================================
   PHOTOGRAPHY
   =========================================================== */

/* interior page hero with a background photograph */
.hero.has-bg{background:var(--green-deep)}
.hero-bg{position:absolute;inset:0;overflow:hidden}
.hero-bg img{width:100%;height:100%;object-fit:cover}
.hero.has-bg::before{z-index:1;background:
  linear-gradient(100deg,rgba(10,11,10,.96) 0%,rgba(10,11,10,.90) 46%,rgba(10,11,10,.74) 100%),
  linear-gradient(to top,rgba(10,11,10,.55),transparent 45%)}
.hero.has-bg .hero-bg img{filter:saturate(.94)}
.hero.has-bg > .wrap{position:relative;z-index:2}

/* service cards with photography */
.card-tile.has-photo{padding:0;border-top-width:0;overflow:hidden}
.card-tile.has-photo .ct-img{display:block;overflow:hidden;background:#f2f2ea}
.card-tile.has-photo .ct-img img{width:100%;aspect-ratio:3/2;object-fit:cover;display:block;
  transition:transform .45s ease}
.card-tile.has-photo:hover .ct-img img{transform:scale(1.055)}
.card-tile.has-photo .ct-body{display:flex;flex-direction:column;flex:1;padding:1.5rem 1.6rem 1.7rem;
  border-top:3px solid var(--accent);transition:border-top-color .25s}
.card-tile.has-photo:hover .ct-body{border-top-color:var(--brand)}
.card-tile.has-photo h3{margin-bottom:.4rem}

/* images inside prose */
.prose-fig{margin:2rem 0;padding:0}
.prose-fig img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:var(--radius);
  box-shadow:var(--shadow-sm)}
.prose-fig.wide img{aspect-ratio:21/9}

/* ---------- booking iframe ---------- */
/* The block sits inside .narrow (820px) but the widget needs far more room,
   so it breaks out of the column. Width is set per-site in config.php
   ('booking_width'), falling back to 1400px. */
.booking-block{
  width:min(var(--bk-w,1400px), calc(100vw - 2.5rem));
  margin-left:50%;transform:translateX(-50%);
  max-width:none;
}
.booking-frame{position:relative;width:100%;min-height:var(--bk-h,470px);
  border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden;
  background:var(--white);margin-top:1.6rem}
.booking-frame iframe{width:100%;height:var(--bk-h,470px);border:0;display:block;
  transition:height .3s ease}
@media(max-width:760px){
  .booking-block{width:100%;margin-left:0;transform:none}
  .booking-frame{min-height:var(--bk-hm,560px)}
  .booking-frame iframe{height:var(--bk-hm,560px)}
}


/* ===========================================================
   HOMEPAGE v2 — full-bleed hero, featured services, gallery,
   owner block, back-to-top
   =========================================================== */

/* ---------- hero: background image + configurable overlay ---------- */
.hero.has-bg{background:var(--green-deep)}
.hero.has-bg .hero-bg{position:absolute;inset:0;overflow:hidden;z-index:0}
.hero.has-bg .hero-bg img{width:100%;height:100%;object-fit:cover;
  object-position:var(--focus,center)}
/* the overlay strength comes from config.php > hero_overlay */
/* Two jobs: keep the salon photo visible on the right where the price card
   sits, and put a solid, readable ground under the copy on the left. A flat
   wash over the whole image does neither — it just greys the photograph. */
.hero.has-bg::before{content:"";position:absolute;inset:0;z-index:1;background:
  /* the reading scrim — heavy left, gone by two-thirds across */
  linear-gradient(95deg,
    rgba(10,11,10,calc(var(--ov,.62) + .12)) 0%,
    rgba(10,11,10,calc(var(--ov,.62) + .06)) 36%,
    rgba(10,11,10,calc(var(--ov,.62) - .26)) 68%,
    rgba(10,11,10,calc(var(--ov,.62) - .40)) 100%),
  /* Was two green layers "so the dark reads as deep leaf rather than grey".
     It read as green over the photograph and fought the white text. A neutral
     deepening in the same place does the same structural job without tinting
     the picture. */
  radial-gradient(ellipse 70% 80% at 12% 40%, rgba(0,0,0,.34), transparent 70%),
  /* anchor the top and bottom edges so the nav and trust bar sit on something */
  linear-gradient(to bottom, rgba(10,11,10,.55), transparent 22%),
  linear-gradient(to top, rgba(10,11,10,.60), transparent 38%)}
@media (max-width:940px){
  /* stacked layout — the copy sits over the middle of the photo, so even it out */
  .hero.has-bg::before{background:
    linear-gradient(180deg, rgba(10,11,10,.86) 0%, rgba(10,11,10,.78) 55%, rgba(10,11,10,.88) 100%),
    radial-gradient(ellipse 90% 60% at 50% 30%, rgba(0,0,0,.32), transparent 70%)}
}
.hero.has-bg > .wrap{position:relative;z-index:2}
.hero-copy{max-width:640px}
.hero h1{text-wrap:balance;text-shadow:0 2px 18px rgba(10,18,6,.55)}
.hero .hero-lede{color:rgba(255,255,255,.94);text-shadow:0 1px 10px rgba(10,18,6,.5)}
.hero .eyebrow{text-shadow:0 1px 8px rgba(10,18,6,.6)}
.hero-trust{text-shadow:0 1px 8px rgba(10,18,6,.5)}

/* ---------- trust bar ---------- */
.hero-trust{display:flex;flex-wrap:wrap;align-items:center;gap:1.4rem;
  margin-top:2.6rem;padding-top:1.7rem;border-top:1px solid rgba(255,255,255,.2);
  font-size:.88rem;color:rgba(255,255,255,.85)}
.trust-item{display:inline-flex;align-items:center;gap:.45rem}
a.trust-item{color:inherit;text-decoration:none;padding:.3rem .6rem;margin:-.3rem -.6rem;
  border-radius:100px;transition:background .2s}
a.trust-item:hover{background:rgba(255,255,255,.13);color:#fff}
.hero-trust strong{color:#fff;font-weight:600}
.hero-trust .stars{color:var(--star);letter-spacing:.08em}

/* ---------- hero price card ---------- */
.hero-card .hc-kicker{font-family:var(--sans);font-size:.72rem;font-weight:600;
  letter-spacing:.17em;text-transform:uppercase;color:var(--accent-deep);margin:0 0 1.1rem}
.hero-card .hc-btn{width:100%;margin-top:1.4rem;padding:.85rem 1rem;font-size:.78rem}
.hero-card dl{margin:0;display:grid;grid-template-columns:1fr auto;gap:.6rem 1rem;font-size:.95rem}
.hero-card dt{color:var(--ink)}
.hero-card dd{margin:0;font-weight:700;color:var(--brand);white-space:nowrap}
.hero-card .fine{font-size:.79rem;color:var(--ink-soft);margin-top:1.2rem;line-height:1.6}

/* ---------- featured service cards ---------- */
.feat-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:1.5rem}
@media(max-width:820px){.feat-grid{grid-template-columns:1fr}}
.feat-card{display:flex;flex-direction:column;background:var(--white);
  border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
  text-decoration:none;color:var(--ink);box-shadow:var(--shadow-sm);
  transition:transform .25s,box-shadow .25s}
.feat-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-md)}
.feat-card .ct-img{display:block;overflow:hidden;background:#f2f2ea}
.feat-card .ct-img img{width:100%;aspect-ratio:16/9;object-fit:cover;display:block;
  transition:transform .45s ease}
.feat-card:hover .ct-img img{transform:scale(1.05)}
.feat-card .ct-body{display:flex;flex-direction:column;flex:1;padding:1.6rem 1.7rem 1.8rem;
  border-top:3px solid var(--accent)}
.feat-top{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.feat-card h3{margin:0 0 .5rem;font-size:1.5rem}
.feat-price{font-family:var(--sans);font-size:.85rem;font-weight:700;color:var(--brand);
  background:var(--accent-soft);padding:.28rem .7rem;border-radius:100px;white-space:nowrap}
.feat-card p{font-size:.95rem;color:var(--ink-soft);flex:1;margin-bottom:1.1rem}

.feat-card .go{font-size:.8rem;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--brand)}

/* ---------- compact secondary services ---------- */
.mini-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(196px,1fr));gap:.8rem}
.mini-card{display:flex;align-items:center;justify-content:space-between;gap:.8rem;
  padding:1rem 1.2rem;background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius-sm);text-decoration:none;color:var(--ink);
  font-size:.95rem;transition:all .18s}
.mini-card:hover{border-color:var(--brand);color:var(--brand);background:var(--accent-soft)}
.mini-go{color:var(--accent-deep);font-size:1.1rem}
.mini-card:hover .mini-go{color:var(--brand)}

/* ---------- gallery ---------- */
/* Column count is the client's setting, but it is expressed as a MINIMUM
   TILE WIDTH rather than repeat(N) — repeat() will not take a calc or a
   custom property as its count in any shipping browser. --gal-min is worked
   out in PHP as the container width divided by the chosen count, so eight
   across at full width falls to six, then four, then two as the screen
   narrows, with no breakpoint per setting. */
.gallery{--gal-gap:clamp(.4rem,.55vw,.9rem);
  display:flex;flex-wrap:wrap;justify-content:center;gap:var(--gal-gap)}
.gallery .gal-item{width:calc((100% - 3 * var(--gal-gap)) / 4)}  /* per-gallery override in gallery_block() */
.gal-item[hidden]{display:none}

/* pager */
.gal-pager{display:flex;justify-content:center;align-items:center;gap:.4rem;
  flex-wrap:wrap;margin-top:1.6rem}
.gal-pg{min-width:2.3rem;height:2.3rem;padding:0 .55rem;border-radius:999px;
  border:1px solid var(--line,#dcdfd2);background:#fff;color:var(--ink,#23281c);
  font:inherit;font-size:.92rem;font-weight:600;cursor:pointer;
  display:grid;place-items:center;transition:background .18s,border-color .18s,color .18s}
.gal-pg:hover{border-color:var(--accent,#71aa36);color:var(--accent,#71aa36)}
.gal-pg.is-on{background:var(--accent,#71aa36);border-color:var(--accent,#71aa36);color:#fff}
.gal-nav{font-size:1.3rem;line-height:1}
.gal-pg[disabled]{opacity:.35;cursor:default}
.gal-pg[disabled]:hover{border-color:var(--line,#dcdfd2);color:var(--ink,#23281c)}
.gal-item{padding:0;border:0;background:#f2f2ea;cursor:zoom-in;border-radius:var(--radius-sm);
  overflow:hidden;display:block;box-shadow:var(--shadow-sm);transition:transform .25s,box-shadow .25s}
.gal-item img{width:100%;aspect-ratio:1;object-fit:cover;display:block;transition:transform .5s ease}
.gal-item:hover{transform:translateY(-3px);box-shadow:var(--shadow-md)}
.gal-item:hover img{transform:scale(1.07)}

/* ---------- lightbox ---------- */
.lightbox{position:fixed;inset:0;z-index:200;background:rgba(16,20,12,.94);
  display:grid;place-items:center;padding:clamp(1rem,5vw,3rem)}
.lightbox[hidden]{display:none}
.lightbox figure{margin:0;max-width:min(1100px,92vw);text-align:center}
.lightbox img{max-width:100%;max-height:78vh;border-radius:var(--radius);display:block;margin-inline:auto}
.lightbox figcaption{color:rgba(255,255,255,.8);font-size:.9rem;margin-top:1rem}
.lightbox button{position:absolute;background:rgba(255,255,255,.12);color:#fff;border:0;
  cursor:pointer;border-radius:50%;width:52px;height:52px;font-size:1.9rem;line-height:1;
  display:grid;place-items:center;transition:background .18s}
.lightbox button:hover{background:rgba(255,255,255,.26)}
.lb-close{top:1.4rem;right:1.4rem;font-size:1.7rem}
.lb-prev{left:1.4rem;top:50%;transform:translateY(-50%)}
.lb-next{right:1.4rem;top:50%;transform:translateY(-50%)}
@media(max-width:600px){
  .lb-prev{left:.5rem}.lb-next{right:.5rem}
  .lightbox button{width:44px;height:44px;font-size:1.5rem}
}

/* ---------- owner block ---------- */
.owner-grid{display:grid;grid-template-columns:.8fr 1.2fr;gap:clamp(2rem,5vw,4rem);align-items:center}
@media(max-width:820px){.owner-grid{grid-template-columns:1fr}}
.owner-photo img{width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:var(--radius);
  box-shadow:var(--shadow-md)}
.owner-placeholder{width:100%;aspect-ratio:4/5;border-radius:var(--radius);
  background:linear-gradient(150deg,var(--green-deep),var(--accent-deep));
  display:grid;place-items:center;box-shadow:var(--shadow-md)}
.owner-placeholder span{font-family:var(--serif);font-size:clamp(5rem,12vw,9rem);
  color:rgba(255,255,255,.9);line-height:1}
.owner-role{font-family:var(--sans);font-size:.78rem;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--accent-deep);margin:-.4rem 0 1.4rem}
.owner-copy h2{margin-bottom:.2rem}

/* ---------- back to top ---------- */
.to-top{position:fixed;right:clamp(1rem,3vw,2rem);bottom:clamp(1rem,3vw,2rem);z-index:80;
  width:48px;height:48px;border-radius:50%;border:0;cursor:pointer;
  background:var(--brand);color:#fff;box-shadow:var(--shadow-lg);
  display:grid;place-items:center;font-size:1.25rem;line-height:1;
  opacity:0;visibility:hidden;transform:translateY(12px);
  transition:opacity .25s,transform .25s,visibility .25s,background .2s}
.to-top.show{opacity:1;visibility:visible;transform:translateY(0)}
.to-top:hover{background:var(--brand-dark)}
@media print{.to-top{display:none}}

/* ---------- signed-in editor bar (front end) ----------
   Deliberately OUTSIDE the brand palette. It used to be #1e2024, which is
   near enough to the site's own dark top bar that the two read as one strip
   and you cannot tell where the site ends and the tooling begins. Indigo is
   in neither the green nor the crimson family, so it always reads as chrome
   sitting on top of the site rather than part of it. */
.editbar{background:linear-gradient(180deg,#4A4585,#3B3670);
  color:#fff;font:500 .82rem/1 var(--sans);
  display:flex;align-items:center;gap:1.1rem;flex-wrap:wrap;
  padding:.6rem clamp(1rem,4vw,2.5rem);position:relative;z-index:100;
  border-bottom:3px solid var(--accent);
  box-shadow:0 2px 10px rgba(0,0,0,.3)}
.editbar a{color:#fff;text-decoration:none;padding:.35rem .75rem;border-radius:5px;
  background:rgba(255,255,255,.18);transition:background .18s,color .18s}
.editbar a:hover{background:var(--accent);color:#1C2A0F}
.editbar .eb-who{margin-right:auto;color:rgba(255,255,255,.8);font-weight:400}
.editbar .eb-who strong{color:#fff;font-weight:600}
.editbar .eb-out{background:transparent;color:rgba(255,255,255,.7)}
.editbar .eb-out:hover{background:rgba(255,255,255,.2);color:#fff}
.eb-dot{width:9px;height:9px;border-radius:50%;background:var(--accent);flex:none;
  box-shadow:0 0 0 3px rgba(132,196,65,.3)}
@media print{.editbar{display:none}}

/* ---------- spacing + text utilities ----------
   Used instead of inline style= so a design change is a one-line edit here,
   never a hunt through 30 generated pages. */
.mt-1{margin-top:1.5rem}
.mt-2{margin-top:2.2rem}
.mt-3{margin-top:2.5rem}
.mb-2{margin-bottom:2rem}
.my-3{margin:3rem 0 1rem}
.note{color:var(--ink-soft);font-size:.95rem}
.big{font-size:1.15rem}
.lede-sm{color:var(--ink-soft);max-width:52ch;margin-inline:auto}
.narrow-table{max-width:420px;margin-inline:auto}

/* ---------- sticky booking bar ----------
   Slides up once the reader is committed to a long page. Hides itself while
   the booking form is on screen. Sits above the back-to-top button. */
.bookbar{position:fixed;left:0;right:0;bottom:0;z-index:60;
  background:var(--accent-deep,#2C4318);color:#fff;
  box-shadow:0 -4px 18px rgba(0,0,0,.22);
  padding:.7rem 1rem calc(.7rem + env(safe-area-inset-bottom,0px));
  transform:translateY(110%);transition:transform .28s ease;
  will-change:transform}
.bookbar.show{transform:translateY(0)}
.bookbar-in{max-width:1100px;margin:auto;display:flex;align-items:center;
  justify-content:space-between;gap:1.2rem;flex-wrap:wrap}
.bookbar-copy{margin:0;font-size:.95rem;line-height:1.35}
.bookbar-copy strong{display:block;font-size:1.02rem}
.bookbar-copy span{color:rgba(255,255,255,.8);font-size:.85rem}
.bookbar-acts{display:flex;gap:.6rem;align-items:center;flex:none}
.bookbar .btn{padding:.62rem 1.1rem;font-size:.92rem}
.bookbar .btn-ghost{border-color:rgba(255,255,255,.55);color:#fff;background:transparent}
.bookbar .btn-ghost:hover{background:rgba(255,255,255,.14)}
/* keep the back-to-top button clear of the bar when it is up */
.bookbar.show ~ .to-top,body.bookbar-up .to-top{bottom:5.6rem}
@media(max-width:640px){
  .bookbar-in{flex-direction:column;align-items:stretch;gap:.55rem;text-align:center}
  .bookbar-copy span{display:none}
  .bookbar-acts{justify-content:stretch}
  .bookbar-acts .btn{flex:1}
}
@media(prefers-reduced-motion:reduce){.bookbar{transition:none}}
@media print{.bookbar{display:none}}

/* ===========================================================
   HOMEPAGE WARM-UP — color in the long light stretches.
   Scoped to the sections above the CTA band; the crimson band,
   footer and sticky bar are deliberately untouched.
   =========================================================== */

/* a hairline of brand under every section heading, so a section starts
   with something other than black text on white */
.section-head h2{position:relative;padding-bottom:.85rem}
.section-head h2::after{content:"";position:absolute;left:50%;bottom:0;
  transform:translateX(-50%);width:64px;height:3px;border-radius:2px;
  background:linear-gradient(90deg,var(--accent),var(--brand))}
.section-brand .section-head h2::after{background:var(--accent)}

/* the tinted band needs its cards to lift off it */
/* the cards carry their own padding-box/border-box backgrounds — do not
   set a flat one here or it wipes the gradient frame out */

/* service cards: color on the edge and on hover, not just a grey box */
.feat-card{border-top:3px solid transparent;transition:.2s}
.feat-card:hover{border-top-color:var(--accent);
  box-shadow:0 14px 34px rgba(44,67,24,.16);transform:translateY(-3px)}
.feat-price{background:var(--accent-soft);color:var(--accent-deep)}

.mini-card{transition:.18s}
.mini-card:hover{background:var(--accent-soft);border-color:var(--accent)}

/* the gallery sits between two pale bands — give it a soft wash of its own
   so three sections in a row do not read as one white block */
#gallery{background:
  linear-gradient(180deg, var(--white) 0%, #FBF7F2 55%, var(--white) 100%)}

/* pull the eyebrow up in weight — it is the only color above most headings */
.eyebrow{color:var(--accent-deep);letter-spacing:.16em;font-weight:700}
.section-brand .eyebrow,.hero .eyebrow{color:var(--accent)}

/* ===========================================================
   HOMEPAGE, PASS 2 — anchor the hero, seat the price card,
   and give the panels some character.
   =========================================================== */

/* ---- 1. the hero closes with a green edge and casts onto the page ---- */
/* the green edge did its job when the hero was flat color; now the panel
   carries the brand, so the shadow alone separates the hero from the page */
.hero{box-shadow:0 14px 30px -8px rgba(28,42,15,.42);
  position:relative;z-index:3}
/* the section below must sit under that shadow, not over it */
.hero + .section{position:relative;z-index:1}

/* ---- 2. the price card: seated, framed, not floating ---- */
/* The frame is a gradient painted in the border box, with the card's own
   background sitting in the padding box on top. A 45deg ramp puts crimson
   in two diagonally opposite corners and green through the middle of the
   run, so the two reds face each other across the card. */
:root{--edge-card:11px;--edge-panel:8px}
.hero-card{
  position:relative;
  border:var(--edge-card) solid transparent;
  border-left-width:0;                    /* the dark panel closes this side */
  border-radius:0 20px 20px 0;
  padding:1.9rem 1.9rem 1.7rem;
  display:flex;flex-direction:column;justify-content:center;
  background:
    linear-gradient(rgba(255,255,255,.985),rgba(255,255,255,.985)) padding-box,
    linear-gradient(45deg,
      var(--brand) 0%,
      var(--brand) 8%,
      var(--accent-deep) 30%,
      var(--accent) 50%,
      var(--accent-deep) 70%,
      var(--brand) 92%,
      var(--brand) 100%) border-box;
  box-shadow:none}
/* a soft ground shadow on the floor beneath it */

.hero-card h3{color:var(--accent-deep)}
.hero-card dd{color:var(--brand)}
.hero-card dl{row-gap:.7rem}
.hero-card dt{position:relative;padding-left:1.05rem}
.hero-card dt::before{content:"";position:absolute;left:0;top:.55em;width:5px;height:5px;
  border-radius:50%;background:var(--accent)}

/* ---- 3. service panels with some life in them ---- */
/* A thick multi-color frame competes with the photograph, so these lead
   with the image instead: a floating price badge, a brand strip along the
   bottom echoing the small tabs, and real lift on hover. */
.feat-card{position:relative;border:1px solid rgba(92,143,43,.20);border-radius:18px;
  background:var(--white);overflow:hidden;
  box-shadow:0 2px 4px rgba(28,42,15,.06),0 14px 30px -16px rgba(28,42,15,.35);
  transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s,border-color .28s}
.feat-card:hover{transform:translateY(-7px);border-color:rgba(92,143,43,.45);
  box-shadow:0 8px 14px rgba(28,42,15,.10),0 34px 60px -22px rgba(28,42,15,.5)}

/* the photo gets room to breathe and a soft foot so it does not stop dead */
.feat-card .ct-img{position:relative}
.feat-card .ct-img::after{content:"";position:absolute;inset:auto 0 0 0;height:46%;
  background:linear-gradient(to top,rgba(10,11,10,.30),transparent);pointer-events:none}
.feat-card .ct-img img{aspect-ratio:16/10}
.feat-card:hover .ct-img img{transform:scale(1.07)}

/* price badge sits ON the photo — the one thing you want read first */
.feat-card .feat-price{position:absolute;top:.9rem;right:.9rem;z-index:2;
  background:var(--brand);color:#fff;border:0;
  padding:.4rem .85rem;font-size:.82rem;letter-spacing:.02em;
  box-shadow:0 4px 14px rgba(120,15,45,.45);
  transition:transform .28s}
.feat-card:hover .feat-price{transform:scale(1.06)}

.feat-card .ct-body{border-top:0;padding:1.5rem 1.6rem 1.7rem;
  background:var(--white)}
.feat-card h3{color:var(--green-deep);margin-bottom:.45rem}
.feat-top{display:block}

/* the brand strip along the foot — the small tabs, scaled up */
.feat-card::after{content:"";position:absolute;left:0;right:0;bottom:0;height:5px;
  background:linear-gradient(90deg,var(--accent) 0%,var(--accent-deep) 45%,var(--brand) 100%);
  transform:scaleX(1);transform-origin:left;transition:height .28s}
.feat-card:hover::after{height:9px}

.feat-card .go{display:inline-flex;align-items:center;gap:.4rem;transition:gap .18s}
.feat-card:hover .go{gap:.75rem}

/* ---- the small "also in the salon" tiles were nearly invisible ---- */
.mini-card{border:4px solid transparent;border-radius:10px;
  background:
    linear-gradient(#fff,#fff) padding-box,
    linear-gradient(45deg,var(--brand) 0%,var(--accent-deep) 32%,var(--accent) 50%,
      var(--accent-deep) 68%,var(--brand) 100%) border-box;
  font-weight:600;color:var(--green-deep);
  box-shadow:0 1px 2px rgba(28,42,15,.05)}
.mini-card:hover{color:var(--brand);transform:translateX(2px);
  box-shadow:0 4px 12px rgba(28,42,15,.16)}
.mini-name{font-weight:600}

/* ---- section rhythm: let each band close with a hairline ---- */
.section-alt{border-bottom:1px solid rgba(92,143,43,.16)}

/* ===========================================================
   HERO: overlay off, panel behind the words
   =========================================================== */

/* "Darken the whole photo" set to 0 removes the wash entirely, so the
   photograph runs clean and the panel below does the readability work. */
.hero.has-bg.no-ov::before{display:none}
.hero.has-bg.no-ov .hero-bg img{filter:none}

/* The panel. Only the homepage hero has .hero-copy, so interior pages are
   untouched. Opacity comes from --box (Business Info), 0 removes it. */
.hero-copy{position:relative;max-width:none;
  background:rgba(0,0,0,var(--box,.5));   /* dark is the default */
  padding:2.4rem 2.6rem;
  border-radius:18px 0 0 18px;
  display:flex;flex-direction:column;justify-content:center}

/* The pricing frame stops dead at the seam, which draws a hard vertical
   line right where the two halves are meant to read as one. These carry the
   top and bottom bands on across the dark panel and fade them out, so the
   frame dissolves into the dark instead of ending. Gone by roughly a
   quarter of the way across the whole unit. */
.hero-copy::before,.hero-copy::after{content:"";position:absolute;
  left:0;right:-2px;                    /* overlap the seam so no hairline shows */
  height:var(--edge-card,11px);pointer-events:none;z-index:2}
/* the top band leaves the card green, so it fades out green */
.hero-copy::before{top:0;border-radius:18px 0 0 0;
  /* ends on rgb(113,170,54) — sampled off the card's own top border at the
     seam. The card's frame is a 45deg ramp, so its top-left corner is not
     the bright --accent but a darker point partway to --accent-deep;
     finishing on --accent left a visible step. */
  background:linear-gradient(90deg,
    transparent 0%,
    transparent 34%,
    rgba(113,170,54,.55) 64%,
    rgb(113,170,54) 100%)}
/* the bottom of the card is crimson at that corner, so this one fades out
   crimson — matching green there was the hard stop */
.hero-copy::after{bottom:0;border-radius:0 0 0 18px;
  background:linear-gradient(90deg,
    transparent 0%,
    transparent 34%,
    rgba(194,39,73,.55) 64%,
    var(--brand) 100%)}
.hero-copy.nobox::before,.hero-copy.nobox::after{display:none}
.hero-copy > *{position:relative;z-index:1}
/* with a panel doing the work the text shadows are no longer needed */
.hero-copy h1,.hero-copy .hero-lede,.hero-copy .eyebrow,.hero-copy .hero-trust{text-shadow:none}

@media (max-width:940px){
  .hero-split{filter:drop-shadow(0 16px 30px rgba(0,0,0,.5))}
  .hero-copy{border-radius:16px 16px 0 0;padding:1.7rem 1.5rem}
  .hero-card{border-radius:0 0 16px 16px;
    border-left-width:var(--edge-card);border-top-width:0}
}

/* ---- the rating, sitting under the price card's button ---- */
.hc-rating{display:flex;align-items:center;justify-content:center;gap:.55rem;
  margin-top:1.3rem;padding-top:1.2rem;border-top:1px solid var(--line);
  text-decoration:none;color:var(--ink-soft);font-size:.9rem;
  transition:color .18s}
.hc-rating:hover{color:var(--brand)}
.hc-rating .stars{color:var(--star);letter-spacing:.08em;font-size:.95rem}
.hc-rating b{color:var(--ink);font-weight:700}

/* ===========================================================
   OWNER BLOCK — this sits between the gallery and the dark
   band, and as a bare photo-plus-paragraph it read as a lull.
   It now carries a tinted band, a framed portrait with the
   rating pinned to it, and her rule as a real pull-quote.
   =========================================================== */
.section-owner{background:var(--band);
  border-top:1px solid rgba(92,143,43,.16);
  border-bottom:1px solid rgba(92,143,43,.16)}
.owner-grid{align-items:center}

/* the portrait gets the same frame language as the hero card */
.owner-photo{position:relative}
.owner-photo img,.owner-placeholder{
  border:6px solid transparent;border-radius:18px;
  background:
    linear-gradient(#fff,#fff) padding-box,
    linear-gradient(45deg,var(--brand) 0%,var(--accent-deep) 32%,var(--accent) 50%,
      var(--accent-deep) 68%,var(--brand) 100%) border-box;
  box-shadow:0 20px 44px -18px rgba(28,42,15,.5)}

/* the rating, pinned across the foot of the portrait */
.owner-badge{position:absolute;left:1.2rem;right:1.2rem;bottom:-1.1rem;
  display:flex;align-items:center;justify-content:center;gap:.5rem;
  background:var(--white);border:1px solid rgba(92,143,43,.25);
  border-radius:100px;padding:.55rem .9rem;
  font-size:.84rem;color:var(--ink-soft);
  box-shadow:0 8px 20px -8px rgba(28,42,15,.4)}
.owner-badge .stars{color:var(--star);letter-spacing:.06em}
.owner-badge b{color:var(--ink)}

.owner-copy h2{font-size:clamp(2.2rem,4.5vw,3rem);margin-bottom:.15rem}
.owner-role{color:var(--accent-deep)}

/* her rule, given the weight it deserves rather than buried in a paragraph */
.owner-quote{margin:1.5rem 0;padding:0 0 0 1.4rem;
  border-left:4px solid var(--accent);
  font-family:var(--serif);font-size:clamp(1.25rem,2.2vw,1.62rem);
  line-height:1.4;color:var(--green-deep);font-style:italic}

.owner-facts{list-style:none;margin:1.5rem 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:.6rem}
.owner-facts li{background:var(--white);border:1px solid rgba(92,143,43,.22);
  border-radius:100px;padding:.45rem .95rem;font-size:.85rem;color:var(--ink-soft)}
.owner-facts b{color:var(--green-deep)}

@media(max-width:820px){
  .owner-badge{position:static;margin-top:1.4rem;left:auto;right:auto}
}

/* ---------- light panel variant ----------
   Over a bright photograph a black panel stops blending and starts reading as
   a grey smudge with the picture showing through it. The light panel matches
   the price card beside it, so the pair reads as one light card sitting on
   the photo rather than two opposing blocks. */
.hero-copy-light{background:rgba(255,255,255,calc(var(--box,.5) + .38))}
.hero-copy-light .eyebrow{color:var(--accent-deep)}
.hero-copy-light h1{color:var(--green-deep)}
.hero-copy-light .hero-lede{color:var(--ink)}
.hero-copy-light .hero-trust{color:var(--ink-soft);
  border-top-color:rgba(36,36,36,.16)}
.hero-copy-light .hero-trust strong{color:var(--ink)}
.hero-copy-light .trust-item{color:var(--ink-soft)}
.hero-copy-light .btn-ghost{border-color:rgba(36,36,36,.3);color:var(--ink)}
.hero-copy-light .btn-ghost:hover{background:var(--green-deep);color:#fff;
  border-color:var(--green-deep)}
.hero-copy-light .crumbs{color:var(--ink-soft)}
.hero-copy-light .crumbs a{color:var(--accent-deep)}

/* ===========================================================
   REVIEWS -> BOOKING — this ran as one long cream stretch with
   104px of padding on each side of the join, so 208px of empty
   space sat between the last review and the booking heading.
   =========================================================== */

/* close the gap: the reviews lead into the booking form, they are not
   two unrelated sections that each need full breathing room */
.section:has(+ #book){padding-bottom:clamp(2rem,4vw,3rem)}
#book{padding-top:clamp(2.5rem,5vw,3.5rem)}

/* and give the booking block a ground of its own, so the white form card
   reads as a card instead of vanishing into a white page */
/* The booking block is already a white card. Putting it on deep leaf turns
   that card into the focus of the section instead of a white shape lost on a
   white page — but the text inside the card must stay dark, or it is white
   on white. Only the ground changes, not the card. */
#book{background:var(--green-deep);position:relative}
#book .booking-block{
  box-shadow:0 30px 70px -20px rgba(0,0,0,.55),
             0 0 0 1px rgba(132,196,65,.35);
  border:0}
/* a hairline of brand across the top of the card, like the price card */
#book .booking-block{position:relative;overflow:hidden}
#book .booking-block::before{content:"";position:absolute;left:0;right:0;top:0;height:5px;
  background:linear-gradient(90deg,var(--accent) 0%,var(--accent-deep) 45%,var(--brand) 100%)}
/* The bar no longer parks above the footer — it retires itself as soon as the
   crimson CTA band comes into view, so there is nothing left to park. */

/* ===========================================================
   MOBILE PASS
   The desktop layout was being squeezed rather than redesigned:
   the hero ran 1456px on an 844px screen, the copy panel alone
   filled the whole first screen, and the photograph — the thing
   that actually sells a salon — was never visible above the fold.
   =========================================================== */

/* the phone button: hidden on desktop, the primary control on a phone */
.header-call{display:none}

@media (max-width: 860px){
  /* --- top bar: one line, and keep the half that earns its place --- */
  .topbar{font-size:.76rem}
  .topbar .wrap{display:flex;justify-content:center;gap:.6rem;padding-top:.4rem;padding-bottom:.4rem}
  .topbar-hours{display:none}          /* the hours are in the footer and on Contact */
  .topbar-rating{white-space:nowrap}   /* the rating is the bit worth the space */

  /* --- header: bigger logo, and a tap-to-call beside the menu --- */
  .site-header .wrap{padding-top:.55rem;padding-bottom:.55rem;gap:.6rem}
  .logo img{height:74px}
  .header-cta{display:none}            /* the hero and the sticky bar both carry Book */
  .header-call{display:inline-flex;align-items:center;justify-content:center;
    width:44px;height:44px;border-radius:50%;flex:none;
    background:var(--brand);color:#fff;text-decoration:none;
    box-shadow:0 2px 8px rgba(120,15,45,.35);margin-left:auto}
  .header-call:active{transform:scale(.94)}
  .nav-toggle{margin-left:.2rem}
}

@media (max-width: 640px){
  /* --- hero: let the photograph be seen --- */
  .hero{padding-top:1.1rem;padding-bottom:1.6rem}
  /* the panel no longer runs edge to edge, so the picture frames it */
  .hero-split{margin-inline:.25rem}
  .hero-copy{padding:1.5rem 1.35rem 1.4rem;border-radius:16px 16px 0 0}
  .hero h1{font-size:clamp(1.85rem,8.5vw,2.35rem);line-height:1.12;max-width:none}
  .hero .hero-lede{font-size:.98rem;line-height:1.5;margin-bottom:1.3rem;
    max-width:34ch}
  /* full-width taps, in the order a phone user wants them */
  .hero-actions{flex-direction:column;gap:.6rem}
  .hero-actions .btn{width:100%;justify-content:center;padding:.95rem 1rem}
  /* the trust line was wrapping one item onto a lonely second row */
  .hero-trust{margin-top:1.5rem;padding-top:1.1rem;gap:.5rem 1rem;font-size:.8rem}
  .hero-trust .trust-item:last-child{display:none}

  /* the price card: tighter, and it keeps the rounded foot of the unit */
  .hero-card{padding:1.4rem 1.35rem 1.3rem;border-radius:0 0 16px 16px}
  .hero-card dl{row-gap:.55rem;font-size:.92rem}
  .hc-kicker{font-size:.72rem}
  .hero-card .fine{font-size:.74rem}
  .hc-rating{margin-top:1rem;padding-top:.9rem;font-size:.82rem}

  /* --- sections: the desktop rhythm is too generous on a phone --- */
  .section{padding:clamp(2.4rem,7vw,3.4rem) 0}
  .section-head{margin-bottom:1.8rem}
  .section-head h2{font-size:clamp(1.7rem,7vw,2.1rem)}

  /* service panels read better as a single strong column than as squeezed cards */
  .feat-card .ct-img img{aspect-ratio:16/9}
  .feat-card .ct-body{padding:1.2rem 1.2rem 1.4rem}
  .feat-card h3{font-size:1.3rem}

  /* stop the sticky bar sitting on top of the last line of every section */
  body{padding-bottom:0}
}

@media (max-width: 400px){
  .logo img{height:66px}
  .hero-copy{padding:1.3rem 1.1rem 1.2rem}
  .hero-card{padding:1.2rem 1.1rem}
}

/* ---- footer on a phone: one centred column ----
   The desktop grid stacks into four ragged left-aligned blocks with the logo
   floating on its own. Centred reads as deliberate at this width. */
@media (max-width: 640px){
  .footer-grid{text-align:center;gap:2rem}
  .footer-grid > div{display:flex;flex-direction:column;align-items:center}
  .footer-grid p{max-width:34ch}
  .site-footer .logo,.site-footer img{margin-inline:auto}
  .footer-social{justify-content:center}
  .site-footer .hours-table{margin-inline:auto;width:auto;max-width:15rem}
  .site-footer .hours-table th{text-align:left;padding-right:1.2rem}
  .site-footer .hours-table td{text-align:right}
  .footer-bottom{text-align:center;flex-direction:column;gap:.5rem}
}

/* the back-to-top button was landing on the sticky bar's buttons */
body.bookbar-up .to-top{bottom:1.2rem}
@media (max-width:640px){
  .to-top{bottom:1rem;right:1rem}
  body.bookbar-up .to-top{bottom:calc(1rem + 4.6rem)}
}

/* ===========================================================
   MOBILE MENU — a real full-screen panel.
   It was a white drop-down pinned under the header: it stopped
   partway down, the page showed through beneath it, and there
   was nothing behind it to separate menu from page.
   =========================================================== */
@media (max-width: 1100px){

  /* the scrim: everything behind the menu goes dark */
  .nav-scrim{position:fixed;inset:0;z-index:60;background:rgba(12,20,8,.6);
    opacity:0;visibility:hidden;transition:opacity .22s;
    -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
  body.nav-open .nav-scrim{opacity:1;visibility:visible}
  .nav-scrim{top:var(--admin-top,0)}
  /* the page must not scroll behind an open menu */
  body.nav-open{overflow:hidden}

  .nav{
    /* Starts below the editor bar when there is one — signed in, the drawer
       used to run up behind it and its own close button went with it.
       --admin-top is 0 for a visitor, so nothing changes for them. */
    position:fixed;inset:var(--admin-top,0) 0 0 auto;width:min(88vw,380px);
    z-index:70;
    flex-direction:column;align-items:stretch;gap:0;
    background:var(--white);
    border-bottom:0;border-left:5px solid transparent;
    border-image:linear-gradient(180deg,var(--accent),var(--accent-deep),var(--brand)) 1;
    padding:calc(1.2rem + env(safe-area-inset-top,0px)) 1.4rem
            calc(2rem + env(safe-area-inset-bottom,0px));
    max-height:none;height:calc(100dvh - var(--admin-top,0px));overflow-y:auto;
    box-shadow:-18px 0 50px rgba(0,0,0,.45);
    display:flex;                        /* always laid out, slid off-screen */
    transform:translateX(100%);
    transition:transform .26s cubic-bezier(.2,.7,.3,1);
    visibility:hidden}
  .nav.open{transform:translateX(0);visibility:visible}

  /* room for the close button, which now sits inside the panel */
  .nav::before{content:"Menu";display:block;font-family:var(--sans);
    font-size:.72rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
    color:var(--accent-deep);padding:.2rem .4rem 1rem}

  .nav > li > a{padding:1.05rem .4rem;border-bottom:1px solid var(--line);
    border-radius:0;font-size:1.05rem}
  .nav > li.current > a{color:var(--brand)}

  .submenu{position:static;opacity:1;visibility:visible;transform:none;box-shadow:none;
    border:0;border-left:3px solid var(--accent-soft);border-radius:0;
    margin:0 0 .6rem .5rem;padding:.35rem 0 .35rem .7rem;min-width:0;background:none}
  .submenu a{padding:.6rem .2rem;font-size:.95rem;display:block}
  .has-sub > a::after{float:right}

  /* the close control: fixed to the panel, always reachable */
  .nav-toggle{position:relative;z-index:80}
  .nav-toggle[aria-expanded="true"]{position:fixed;top:calc(var(--admin-top,0px) + 1.15rem);right:1.15rem}
  .nav-toggle[aria-expanded="true"] span{background:var(--ink)}

  /* the two things a phone user actually wants, at the foot of the menu */
  .nav-cta{display:flex;flex-direction:column;gap:.6rem;margin-top:1.4rem;
    padding-top:1.2rem;border-top:1px solid var(--line);list-style:none}
  .nav-cta .btn{width:100%;justify-content:center}
}
@media (min-width: 1101px){ .nav-scrim,.nav-cta{display:none} }

/* ---- mobile: the hero bands must follow the stacked corners ----
   The bands are shaped for the desktop layout, where they run left from the
   card and only the outer top-left corner is rounded. Stacked on a phone the
   panel is rounded at BOTH top corners, so a band rounded on one side leaves
   a hard square edge on the other. */
@media (max-width: 940px){
  /* Stacked, the top band is not continuing anything — the card sits below,
     not beside. So it reads better as a clean brand bar across the full
     width than as a gradient fading in from nowhere. */
  .hero-copy::before{border-radius:16px 16px 0 0;left:0;right:0;
    background:linear-gradient(90deg,var(--accent) 0%,var(--accent-deep) 45%,var(--brand) 100%);
    -webkit-mask:none;mask:none}
  /* the lower band meets the price card, so it stays square and edge to edge */
  .hero-copy::after{border-radius:0;left:0;right:0;
    background:linear-gradient(90deg,var(--brand) 0%,var(--accent-deep) 55%,var(--accent) 100%);
    -webkit-mask:none;mask:none}
}

/* ===========================================================
   OPTIONAL: TURN THE STICKY STRIP OFF ON DESKTOP ALTOGETHER

   It now retires itself the moment the crimson "Ready When You
   Are" band comes into view, at every width, so it no longer
   repeats that band at the bottom of the page.

   If you would rather it never showed on a desktop at all — the
   header keeps its own Book Now button on screen the whole way
   down there, so the strip is arguably redundant above 1040px —
   uncomment the three lines below by deleting the /* on the next
   line and the */
/*
@media (min-width: 1101px) {
  .bookbar { display: none; }
  body.bookbar-up .to-top { bottom: 1.2rem; }
}
*/

/* ===========================================================
   PRICE PANELS

   The old Duda site paired every price table with a photograph
   beside it, and that was the right instinct: a picture of gel
   curing under UV belongs next to the hard gel prices, not
   floating over four unrelated tables. This takes that layout
   and fixes what was wrong with it — the photo sat in a grey
   box with dead space around it, the medallion in the corner
   was a generic tick that told you nothing, the prices were
   unaligned, and the small print was styled as though it were
   another service.

   Here the photograph runs edge to edge and full height, the
   badge carries the cheapest price in that table, the figures
   are tabular so the column lines up, and the note is a
   footnote outside the list.
   =========================================================== */

.price-block{ margin-top:.4rem; }
.anchor-only{ display:block; height:0; scroll-margin-top:90px; }

/* ---- the group name ---- */
.price-group{
  text-align:center; color:var(--green-deep);
  font-size:clamp(1.9rem,3.6vw,2.6rem); line-height:1.15;
  margin:0 0 2.1rem; padding-bottom:.85rem; position:relative;
  scroll-margin-top:90px;
}
.price-group::after{
  content:""; position:absolute; left:50%; bottom:0; transform:translateX(-50%);
  width:84px; height:3px; border-radius:2px;
  background:linear-gradient(90deg,var(--accent),var(--accent-deep) 55%,var(--brand));
}

/* ---- one panel per table ---- */
.ptables{ display:grid; gap:1.9rem; }
.ptable{
  position:relative; display:grid; grid-template-columns:1.05fr .95fr;
  align-items:stretch; overflow:hidden;
  border:1px solid rgba(92,143,43,.20); border-radius:18px;
  background:var(--white);
  box-shadow:0 2px 4px rgba(28,42,15,.06),0 14px 30px -16px rgba(28,42,15,.35);
  transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s,border-color .28s;
}
.ptable:hover{ transform:translateY(-5px); border-color:rgba(92,143,43,.42);
  box-shadow:0 8px 14px rgba(28,42,15,.10),0 32px 56px -22px rgba(28,42,15,.48); }
/* the family strip every card on this site closes with */
.ptable::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:5px; z-index:2;
  background:linear-gradient(90deg,var(--accent) 0%,var(--accent-deep) 45%,var(--brand) 100%); }

/* photo on the right by default, left on every other one, so a page of
   these does not read as one long column of identical blocks */
.ptable-body { grid-column:1; padding:1.9rem 2rem 2.1rem; }
/* a section the client added has no photograph paired with it yet, so the
   prices take the full width rather than leaving half the panel empty */
.ptable:not(:has(.ptable-photo)){ grid-template-columns:1fr; }
.ptable-photo{ grid-column:2; }
.ptable.flip .ptable-body { grid-column:2; }
.ptable.flip .ptable-photo{ grid-column:1; grid-row:1; }

.ptable-body h3{
  margin:0 0 .9rem; padding-bottom:.7rem; position:relative;
  color:var(--green-deep); font-size:1.45rem; line-height:1.2;
}
.ptable-body h3::after{
  content:""; position:absolute; left:0; bottom:0; width:100%; height:2px;
  background:linear-gradient(90deg,var(--accent) 0%,var(--accent-deep) 60%,
    rgba(194,39,73,.25) 100%);
}

/* ---- the photograph ---- */
.ptable-photo{ position:relative; margin:0; min-height:280px; overflow:hidden; }
/* The photo used to meet the price list on a hard vertical line, which read
   as two things bolted together. A short scrim on the inner edge lets the
   card carry through instead of stopping dead. */
.ptable-photo::before{ content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(90deg,rgba(255,255,255,.55) 0%,rgba(255,255,255,0) 14%); }
.ptable.flip .ptable-photo::before{
  background:linear-gradient(270deg,rgba(255,255,255,.55) 0%,rgba(255,255,255,0) 14%); }
.ptable-photo img{ position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block; transition:transform .5s cubic-bezier(.2,.7,.3,1); }
.ptable:hover .ptable-photo img{ transform:scale(1.04); }
/* the cheapest figure in the table, which is the one thing a photograph of a
   treatment cannot tell you */
.ptable-from{
  position:absolute; top:1rem; right:1rem; z-index:2;
  display:flex; align-items:baseline; gap:.35rem;
  background:var(--brand); color:#fff; border-radius:999px;
  padding:.42rem .95rem; font-family:var(--sans); font-weight:700; font-size:1rem;
  letter-spacing:.01em; box-shadow:0 6px 18px rgba(120,15,45,.4);
}
.ptable-from span{ font-size:.68rem; font-weight:600; text-transform:uppercase;
  letter-spacing:.09em; opacity:.85; }
.ptable.flip .ptable-from{ right:auto; left:1rem; }

/* ---- the price list ---- */
.ptable-scroll{ overflow-x:auto; }
.price-table{ width:100%; border-collapse:collapse; font-size:.95rem; }
.price-table th,.price-table td{
  text-align:left; padding:.62rem .55rem; font-weight:400;
  border-bottom:1px solid rgba(92,143,43,.14);
}
.price-table th{ color:var(--ink); }
.price-table td{
  text-align:right; font-weight:700; color:var(--brand); white-space:nowrap;
  /* tabular figures, so the column of prices lines up instead of drifting */
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1;
}
.price-table tbody tr:nth-child(odd) th,
.price-table tbody tr:nth-child(odd) td{ background:rgba(92,143,43,.045); }
.price-table tbody tr:hover th,
.price-table tbody tr:hover td{ background:rgba(92,143,43,.10); }
.price-table tbody tr:last-child th,
.price-table tbody tr:last-child td{ border-bottom:0; }

.ptable-note{
  margin:.95rem 0 0; font-size:.82rem; font-style:italic; color:var(--ink-soft);
  padding-left:1rem; border-left:2px solid rgba(92,143,43,.35);
}

/* ---- the card groups (manicures) ---- */
.price-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(310px,1fr)); gap:1.6rem; }
/* The About page reuses .price-card for its Quality / Value / Service trio,
   without the photo-and-body structure the pricing grid now has — so it lost
   all its padding when this was redesigned. Anything without a .pcard-body
   gets the padding on the card itself, as it had before. */
.price-card:not(:has(.pcard-body)){ padding:1.9rem 1.9rem 2.1rem; }
.price-card{
  position:relative; display:flex; flex-direction:column;
  border:1px solid rgba(92,143,43,.20); border-radius:18px;
  background:var(--white); overflow:hidden;
  box-shadow:0 2px 4px rgba(28,42,15,.06),0 14px 30px -16px rgba(28,42,15,.35);
  transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s,border-color .28s;
}
/* These were the only price blocks with no photograph, which is why the
   section read as thin next to the ones that had one. */
.pcard-photo{ position:relative; margin:0; overflow:hidden; }
.pcard-photo img{ width:100%; aspect-ratio:16/10; object-fit:cover; display:block;
  transition:transform .5s cubic-bezier(.2,.7,.3,1); }
.price-card:hover .pcard-photo img{ transform:scale(1.05); }
/* a short foot on the photo so it does not stop dead against the white */
.pcard-photo::after{ content:""; position:absolute; inset:auto 0 0 0; height:42%;
  background:linear-gradient(to top,rgba(10,11,10,.28),transparent); pointer-events:none; }
.pcard-body{ display:flex; flex-direction:column; flex:1;
  padding:1.5rem 1.6rem 1.9rem; }
.price-card:hover{ transform:translateY(-7px); border-color:rgba(92,143,43,.45);
  box-shadow:0 8px 14px rgba(28,42,15,.10),0 34px 60px -22px rgba(28,42,15,.5); }
.price-card::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:5px;
  background:linear-gradient(90deg,var(--accent) 0%,var(--accent-deep) 45%,var(--brand) 100%);
  transition:height .28s; }
.price-card:hover::after{ height:9px; }
.price-card .price-amt{
  position:absolute; top:.9rem; right:.9rem; z-index:2;
  background:var(--brand); color:#fff; border-radius:999px;
  padding:.38rem .9rem; font-family:var(--sans); font-size:.86rem; font-weight:700;
  white-space:nowrap; box-shadow:0 6px 18px rgba(120,15,45,.45); transition:transform .28s;
}
.price-card:hover .price-amt{ transform:scale(1.06); }
.price-card h3{ display:block; margin:0 0 .55rem;
  color:var(--green-deep); font-size:1.32rem; line-height:1.25; }
.price-card p{ font-size:.95rem; color:var(--ink-soft); margin:0; }
.price-card ul{ list-style:none; margin:1.05rem 0 0; padding:0; }
/* the list is the flexible part, so every card's foot strip lines up */
.price-card p{ flex:0 0 auto; }
.price-card li{ position:relative; padding-left:1.55rem; margin-bottom:.45rem; font-size:.93rem; }
.price-card li::before{
  content:""; position:absolute; left:.2rem; top:.34em; width:.5rem; height:.82rem;
  border:solid var(--accent-deep); border-width:0 2px 2px 0;
  transform:rotate(42deg); border-radius:1px; background:none;
}

/* ---- "Jump to" ---- */
/* This was a four-column grid, so the last row was always short and one long
   name wrapped to two lines and made its row taller than the rest — it read
   as scattered rather than laid out. Pills that size to their own text and
   centre-wrap have no rows to leave ragged. */
/* the eyebrow was left-aligned over a centred row, which read as a mistake */
.jump-wrap .eyebrow{ text-align:center; }
.jump-tabs{
  display:flex; flex-wrap:wrap; justify-content:center; gap:.6rem;
  list-style:none; margin:0 auto; padding:0; max-width:1000px;
}
.jump-tabs a{
  display:inline-flex; align-items:center; gap:.5rem; white-space:nowrap;
  padding:.62rem 1.15rem; border-radius:999px;
  border:1px solid rgba(92,143,43,.32); background:var(--white);
  color:var(--green-deep); font-size:.92rem; font-weight:600; text-decoration:none;
  box-shadow:0 1px 2px rgba(28,42,15,.05);
  transition:background .18s,border-color .18s,color .18s,transform .18s,box-shadow .18s;
}
.jump-tabs a::after{
  content:"\2193"; font-size:.85em; line-height:1; opacity:.5;
  transition:transform .18s,opacity .18s;
}
.jump-tabs a:hover,.jump-tabs a:focus-visible{
  background:var(--green-deep); border-color:var(--green-deep); color:#fff;
  transform:translateY(-2px); box-shadow:0 8px 18px rgba(28,42,15,.20);
}
.jump-tabs a:hover::after,.jump-tabs a:focus-visible::after{
  transform:translateY(2px); opacity:1;
}

@media (max-width:820px){
  /* stacked, the photo becomes a header band above its prices */
  .ptable,.ptable.flip{ grid-template-columns:1fr; }
  .ptable-body,.ptable.flip .ptable-body{ grid-column:1; grid-row:2;
    padding:1.5rem 1.4rem 1.8rem; }
  .ptable-photo,.ptable.flip .ptable-photo{ grid-column:1; grid-row:1;
    min-height:0; height:180px; }
  /* stacked, the scrim would sit on the wrong edge entirely */
  .ptable-photo::before,.ptable.flip .ptable-photo::before{
    background:linear-gradient(0deg,rgba(255,255,255,.5) 0%,rgba(255,255,255,0) 22%); }
  .ptable.flip .ptable-from{ left:auto; right:1rem; }
  .pcard-body{ padding:1.3rem 1.3rem 1.6rem; }
  /* long names are allowed to wrap once the row is narrow */
  .jump-tabs a{ white-space:normal; }
}

/* ===========================================================
   PRICE PAGE RHYTHM
   Eight pale sections in a row read as a spreadsheet however
   good the individual panels are — which is what the old site
   beat us on. It broke its price list into full-bleed color
   bands and let the white cards sit on top of them. Same idea
   here, in this salon's green and crimson rather than crimson
   throughout, cycling cream → green → cream → crimson.
   =========================================================== */
.pband{ position:relative; }
.band-deep { background:var(--green-deep); }
.band-brand{ background:var(--brand); }

/* the group name is the only thing on the band itself, so it carries the
   contrast: white type, and the rule under it goes pale rather than dark */
.band-deep .price-group,
.band-brand .price-group{ color:#fff; }
.band-deep .price-group::after,
.band-brand .price-group::after{
  background:linear-gradient(90deg,rgba(255,255,255,.35),#fff 50%,rgba(255,255,255,.35));
}

/* On color the cards need a touch more lift or they look pasted on, and the
   green hairline disappears into the green band — so it goes to a soft white
   edge instead. */
.band-deep .ptable,.band-brand .ptable,
.band-deep .price-card,.band-brand .price-card{
  border-color:rgba(255,255,255,.30);
  box-shadow:0 3px 6px rgba(8,14,4,.22),0 20px 44px -18px rgba(8,14,4,.55);
}
.band-deep .ptable:hover,.band-brand .ptable:hover,
.band-deep .price-card:hover,.band-brand .price-card:hover{
  border-color:rgba(255,255,255,.55);
  box-shadow:0 8px 16px rgba(8,14,4,.26),0 38px 66px -22px rgba(8,14,4,.62);
}

/* a hairline where two cream bands meet, so the rhythm still reads there */
.pband + .pband:not(.band-deep):not(.band-brand){
  border-top:1px solid rgba(92,143,43,.16);
}

/* ===========================================================
   OTHER SERVICES
   The row at the foot of every service page. It was plain
   outlined boxes — the same treatment as a disabled button, on
   the one element whose whole job is to send you somewhere
   else. These are photo tiles using the picture each service
   already has for its own page header, so the row is
   recognisable at a glance instead of eight identical
   rectangles of text.
   =========================================================== */
.svc-tiles{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr));
  gap:1.1rem; list-style:none; margin:0; padding:0;
}
.svc-tile{
  position:relative; display:block; overflow:hidden;
  border-radius:14px; text-decoration:none;
  border:1px solid rgba(92,143,43,.20);
  box-shadow:0 2px 4px rgba(28,42,15,.06),0 12px 26px -16px rgba(28,42,15,.35);
  transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s,border-color .28s;
}
.svc-tile img{
  width:100%; aspect-ratio:5/3; object-fit:cover; display:block;
  transition:transform .5s cubic-bezier(.2,.7,.3,1);
}
/* the name sits on the photograph, so it needs its own ground rather than
   relying on whatever happens to be in the bottom of the picture */
.svc-tile::before{
  content:""; position:absolute; inset:auto 0 0 0; height:72%; pointer-events:none;
  background:linear-gradient(to top,rgba(12,20,7,.86) 0%,rgba(12,20,7,.55) 42%,
    rgba(12,20,7,0) 100%);
}
.svc-tile span{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  display:flex; align-items:center; gap:.45rem;
  padding:.85rem 1rem 1rem;
  color:#fff; font-weight:600; font-size:.98rem; line-height:1.25;
  text-shadow:0 1px 10px rgba(0,0,0,.45);
}
.svc-tile span::after{
  content:"\2192"; margin-left:auto; font-weight:700; opacity:.7;
  transition:transform .2s,opacity .2s;
}
/* the accent strip, so these belong to the same family as everything else */
.svc-tile::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:4px; z-index:3;
  background:linear-gradient(90deg,var(--accent) 0%,var(--accent-deep) 45%,var(--brand) 100%);
  transform:scaleX(0); transform-origin:left; transition:transform .3s ease;
}
.svc-tile:hover,.svc-tile:focus-visible{
  transform:translateY(-5px); border-color:rgba(92,143,43,.45);
  box-shadow:0 8px 14px rgba(28,42,15,.10),0 28px 48px -20px rgba(28,42,15,.5);
}
.svc-tile:hover img,.svc-tile:focus-visible img{ transform:scale(1.06); }
.svc-tile:hover::after,.svc-tile:focus-visible::after{ transform:scaleX(1); }
.svc-tile:hover span::after,.svc-tile:focus-visible span::after{
  transform:translateX(4px); opacity:1;
}
/* a service with no photograph paired to it still needs to be a link */
.svc-tile.no-img{ background:var(--green-deep); min-height:112px; }
.svc-tile.no-img span{ position:static; min-height:112px; align-items:center; }
@media (prefers-reduced-motion: reduce){
  .svc-tile,.svc-tile img,.svc-tile::after,.svc-tile span::after{ transition:none; }
  .svc-tile:hover{ transform:none; }
}
@media (max-width:640px){
  /* One tile per row turned an eight-item footer nav into eight screens of
     scrolling. Two up keeps the whole set in view. */
  .svc-tiles{ grid-template-columns:repeat(2,1fr); gap:.7rem; }
  .svc-tile img{ aspect-ratio:4/3; }
  .svc-tile span{ font-size:.84rem; padding:.6rem .7rem .72rem; }
  .svc-tile span::after{ display:none; }   /* no room, and the tile is obviously a link */
}

/* ===========================================================
   CLIENT-MADE SECTIONS
   Blocks the salon added themselves on the Edit Pages screen.
   Deliberately built from the same parts as everything else —
   the band colors from the price page, the card radius, the
   photo treatment — so an owner adding a section cannot end up
   with something that looks bolted on.
   =========================================================== */
.xsec .xsec-body h2{ color:var(--green-deep); margin:0 0 .9rem;
  font-size:clamp(1.7rem,3.2vw,2.3rem); line-height:1.15; }
.xsec .xsec-body p:last-child{ margin-bottom:0; }
.xsec-text .xsec-body{ margin-inline:auto; }

/* the split layouts put the photo hard against the text, full height */
.xsec-split{ display:grid; grid-template-columns:1.05fr .95fr; gap:0;
  align-items:stretch; overflow:hidden; border-radius:18px;
  border:1px solid rgba(92,143,43,.20); background:var(--white);
  box-shadow:0 2px 4px rgba(28,42,15,.06),0 14px 30px -16px rgba(28,42,15,.35); }
.xsec-split .xsec-body{ padding:2rem 2.2rem; align-self:center; }
.xsec-photo{ position:relative; margin:0; min-height:300px; overflow:hidden; }
.xsec-photo img{ position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block; }
.xsec-left .xsec-body { grid-column:2; }
.xsec-left .xsec-photo{ grid-column:1; grid-row:1; }

/* on a color band the panel keeps its own light ground, and the heading
   outside a panel reverses out */
.xsec.band-deep .xsec-split,.xsec.band-brand .xsec-split{
  border-color:rgba(255,255,255,.30);
  box-shadow:0 3px 6px rgba(8,14,4,.22),0 20px 44px -18px rgba(8,14,4,.55); }
.xsec.band-deep.xsec-text .xsec-body,
.xsec.band-brand.xsec-text .xsec-body{ color:rgba(255,255,255,.92); }
.xsec.band-deep.xsec-text .xsec-body h2,
.xsec.band-brand.xsec-text .xsec-body h2{ color:#fff; }
.xsec.band-deep.xsec-text .xsec-body a,
.xsec.band-brand.xsec-text .xsec-body a{ color:#fff; text-decoration:underline; }

@media (max-width:820px){
  .xsec-split,.xsec-left .xsec-split{ grid-template-columns:1fr; }
  .xsec-split .xsec-body,.xsec-left .xsec-body{ grid-column:1; grid-row:2;
    padding:1.5rem 1.4rem 1.8rem; }
  .xsec-photo,.xsec-left .xsec-photo{ grid-column:1; grid-row:1;
    min-height:0; height:200px; }
}

/* ===========================================================
   SERVICE PAGE BANDS

   The body of a service page is one editable block: <h2> then
   paragraphs, over and over. Rendered as a single column it read
   as a wall of text — the headings were the only thing breaking
   it up and they were doing all the work alone.

   prose_bands() splits that same block on its headings and hands
   each section its own full-width band. Nothing about the stored
   content changed; this is the layout it is poured into.

   The first attempt hung the heading in a column of its own beside
   the copy. On a section with three paragraphs that reads as a
   magazine spread; on a section with one it reads as a mistake,
   because half the band is empty and the heading is stranded out
   to the left with nothing under it. So the heading sits ON TOP of
   its copy instead — number, title, a gradient bar, then the text
   left-aligned beneath it, the whole block in one measured column.
   The bar is the same green-to-crimson hairline that runs across
   the price cards and the booking card, so the sections belong to
   the same site rather than looking bolted on.
   =========================================================== */

.sband{padding-block:clamp(3rem,6vw,5rem)}
.sband-alt{background:var(--band)}
.sband-deep{background:var(--green-deep)}

/* one measured column, centred — no dead gutter beside short copy */
.sband-inner{max-width:880px;margin-inline:auto}

/* ---------- the masthead ---------- */
.sband-head{margin:0 0 1.5rem}
/* The mark had no container, so it read as a stray glyph floating above the
   heading rather than part of it. In a badge it belongs to the section. */
.sband-head{display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(.85rem,1.6vw,1.2rem);align-items:start;margin:0 0 1.5rem}
.sband-badge{
  display:grid;place-items:center;width:52px;height:52px;border-radius:50%;
  background:var(--accent-soft);
  box-shadow:inset 0 0 0 1px rgba(132,196,65,.38)}
.sband-badge svg{display:block;width:22px;height:22px}
.sband-badge path{fill:var(--accent-deep)}
.sband-titles{min-width:0}
.sband-kicker{
  margin:.35rem 0 .3rem;font:600 .72rem/1 var(--sans);
  letter-spacing:.19em;text-transform:uppercase;color:var(--accent-deep)}
.sband-head h2{
  margin:0;font-family:var(--serif);font-weight:600;
  font-size:clamp(1.7rem,3vw,2.5rem);line-height:1.1;
  letter-spacing:-.015em;color:var(--brand-dark);
  /* a long heading wraps to a second line instead of stretching the full
     width of the band — a 50-character title set on one line reads as a
     banner, not a heading */
  max-width:26ch;
  /* long service headings break evenly instead of leaving one orphan word */
  text-wrap:balance}
.sband-head h2::after{content:none}   /* the shared .prose rule; the bar does this job */
/* Short again, per the concept — but heavier than the first attempt. With a
   kicker above the heading and a ghost word behind it there is already plenty
   holding the section together, and a full-width rule only competes with the
   band edges either side of it. */
.sband-bar{
  display:block;width:92px;height:4px;border-radius:2px;margin-top:1rem;
  background:linear-gradient(90deg,
    var(--accent) 0%,var(--accent-deep) 46%,var(--brand) 100%)}

/* ---------- the copy ---------- */
.sband-body p{margin:0 0 1.05em;line-height:1.78;color:var(--ink)}
.sband-body p:last-child{margin-bottom:0}
.sband-body>p:first-child{font-size:1.07rem;line-height:1.72}

/* an inclusion list, rescued from a run of hyphens — see prose_chips() */
.sband-chips{
  display:flex;flex-wrap:wrap;gap:.5rem;
  list-style:none;margin:1.5rem 0 0;padding:0}
.sband-chips li{
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.5rem 1rem;border-radius:999px;
  background:var(--white);border:1px solid var(--line);
  font:500 .87rem/1 var(--sans);color:var(--ink)}
.sband-chips li::before{
  content:"";width:6px;height:6px;border-radius:50%;
  background:var(--accent);flex:none}

/* ---------- the lead ---------- */
.sband-lead{padding-top:clamp(2.4rem,4.4vw,3.4rem)}
.sband-lead .sband-body{max-width:68ch;margin-inline:auto;text-align:center}
.sband-lead .sband-body>p:first-child{
  font-size:clamp(1.14rem,1.9vw,1.34rem);line-height:1.62;color:var(--ink)}
.sband-lead .sband-body>p{color:var(--ink-soft)}
/* an opening long enough to be an essay is left-aligned — centred, it is
   unreadable, and the ragged left edge is what makes it look wrong */
.sband-lead-long .sband-body{text-align:left;max-width:none}
.sband-lead .sband-photo{margin-top:clamp(1.8rem,3.6vw,2.8rem)}
.sband-lead .sband-photo img{aspect-ratio:21/9}

/* ---------- a band that owns a photograph ---------- */
/* The masthead stays full width and the copy takes half, so the picture is
   big enough to be worth having rather than a thumbnail beside a paragraph. */
.sband.has-photo .sband-inner{
  max-width:1060px;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  grid-template-areas:"head head" "body photo";
  column-gap:clamp(2rem,4vw,3.6rem);row-gap:0}
.sband.has-photo.flip .sband-inner{grid-template-areas:"head head" "photo body"}
.sband.has-photo .sband-head{grid-area:head}
.sband.has-photo .sband-body{grid-area:body}
/* The copy in a band usually runs longer than the picture beside it. Pinned,
   the photograph travels with the paragraphs instead of leaving a hole under
   itself for the second half of the section. */
.sband.has-photo .sband-photo{grid-area:photo;align-self:start;position:sticky;top:96px}
.sband-photo,.sband-photo .prose-fig{margin:0;padding:0}
.sband-photo img{
  width:100%;aspect-ratio:4/3;object-fit:cover;
  border-radius:var(--radius);
  box-shadow:0 18px 45px -18px rgba(36,36,36,.5)}

/* ---------- reversed out on the deep bands ---------- */
.sband-deep .sband-head h2{color:#fff}
.sband-deep .sband-badge{background:rgba(255,255,255,.07);
  box-shadow:inset 0 0 0 1px rgba(132,196,65,.42)}
.sband-deep .sband-badge path{fill:var(--accent)}
.sband-deep .sband-kicker{color:var(--accent)}
.sband-deep .sband-bar{
  background:linear-gradient(90deg,
    var(--accent) 0%,#A6D45F 48%,var(--brand-light) 100%)}
.sband-deep .sband-body p{color:rgba(255,255,255,.87)}
.sband-deep .sband-body a{color:var(--accent)}
.sband-deep .sband-chips li{
  background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.22);
  color:rgba(255,255,255,.92)}
.sband-deep .sband-photo img{box-shadow:0 18px 45px -18px rgba(0,0,0,.75)}

/* ---------- phones and small tablets ---------- */
@media (max-width:820px){
  .sband.has-photo .sband-inner,
  .sband.has-photo.flip .sband-inner{
    grid-template-columns:minmax(0,1fr);
    grid-template-areas:"head" "photo" "body";
    row-gap:1.35rem}
  .sband.has-photo .sband-photo{position:static}
  .sband-lead .sband-body{text-align:left}
  .sband-photo img{aspect-ratio:16/10}
  .sband-chips li{font-size:.83rem;padding:.45rem .85rem}
}


/* ---------- the promises strip ---------- */
/* Once per page, under the pricing. Everything a page repeats eleven times
   turns into wallpaper, so this is the whole decoration budget spent in one
   place rather than smeared across every band. */
.trust-band{padding-block:clamp(1.6rem,3vw,2.4rem);background:var(--white);
  border-block:1px solid var(--line)}
.trust-strip{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:0;list-style:none;margin:0;padding:0}
.trust-item{
  display:flex;align-items:flex-start;gap:.85rem;
  padding:.4rem clamp(1rem,2.2vw,1.9rem)}
.trust-item + .trust-item{border-left:1px solid var(--line)}
.trust-ico{color:var(--accent-deep);flex:none;margin-top:.1rem}
.trust-ico svg{display:block}
.trust-item h2{
  margin:0 0 .2rem;font:600 .78rem/1.2 var(--sans);
  letter-spacing:.09em;text-transform:uppercase;color:var(--brand-dark)}
.trust-item p{margin:0;font-size:.86rem;line-height:1.5;color:var(--ink-soft)}

@media (max-width:900px){
  .trust-strip{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.1rem .4rem}
  .trust-item + .trust-item{border-left:0}
  .trust-item:nth-child(even){border-left:1px solid var(--line)}
}
@media (max-width:520px){
  .trust-strip{grid-template-columns:minmax(0,1fr)}
  .trust-item:nth-child(even){border-left:0}
  .trust-item{padding-inline:0}
}

/* ---------- emphasis the client controls ---------- */
/* Bold in the editor becomes the brand highlight. Better than me guessing
   which phrase in someone else's copy deserves the color. */
.sband-body strong,.sband-body b{color:var(--accent-deep);font-weight:600}
.sband-deep .sband-body strong,.sband-deep .sband-body b{color:var(--accent)}

/* ---------- a very long section, set in two columns ---------- */
.sband-2col .sband-inner{max-width:1080px}
.sband-2col .sband-body{
  columns:2;column-gap:clamp(2rem,4vw,3.6rem);
  orphans:3;widows:3}
/* Paragraphs MUST be allowed to break across the column gap. Holding them
   whole sounds tidier and is the opposite: one 900-character paragraph then
   refuses to share, so column one ends early and leaves a dead half-page.
   Splitting mid-paragraph is what every newspaper does, and it balances. */
.sband-2col .sband-body>p{break-inside:auto}
.sband-2col .sband-body>p:first-child{font-size:1rem}
.sband-2col .sband-chips{column-span:all;break-inside:avoid}
@media (max-width:900px){
  .sband-2col .sband-body{columns:1}
}

/* ---------- botanical mark ---------- */
/* Decoration, so it behaves like decoration: behind everything, never
   clipped (the photo column is sticky and an overflow rule here would kill
   that), and gone on any screen narrow enough for it to crowd the words. */
/* isolation:isolate here was the mistake: it makes the section its own
   stacking context, so a z-index:-1 pseudo-element paints BEHIND the
   section's own background and vanishes. The ornament sits at 0 and the
   content is lifted to 1 instead. */
.sband-alt,.sband-deep{position:relative}
.sband-inner{position:relative;z-index:1}
/* One ornament per corner. The ghost word owns the top-right on every band
   now, so the sprig lives along the bottom instead of being switched off. */
.sband-alt::before,.sband-deep::before{
  content:"";position:absolute;z-index:0;
  width:150px;height:150px;pointer-events:none;
  background:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'><g fill='none' stroke='%2384C441' stroke-width='3' stroke-linecap='round'><path d='M100 190 C100 130 100 70 100 14'/><path d='M100 158 C72 156 54 140 50 116 C78 114 96 130 100 158Z' fill='%2384C441' fill-opacity='.55'/><path d='M100 132 C128 130 146 114 150 90 C122 88 104 104 100 132Z' fill='%2384C441' fill-opacity='.55'/><path d='M100 104 C74 102 58 87 54 65 C80 63 96 78 100 104Z' fill='%2384C441' fill-opacity='.55'/><path d='M100 76 C126 74 142 59 146 37 C120 35 104 50 100 76Z' fill='%2384C441' fill-opacity='.55'/><path d='M100 48 C82 46 70 34 67 18 C86 16 97 28 100 48Z' fill='%2384C441' fill-opacity='.55'/></g></svg>") no-repeat center/contain}
.sband-alt::before{bottom:1.6rem;left:2.2rem;opacity:.13;transform:rotate(-166deg)}
.sband-deep::before{bottom:1.6rem;right:2.2rem;opacity:.16;transform:rotate(172deg)}
@media (max-width:1180px){
  .sband-alt::before,.sband-deep::before{display:none}
}


/* ---------- the ghost word ---------- */
/* The heading again, set enormous and nearly invisible behind the section.
   It is what stops a band of plain paragraphs reading as a document. Only
   short headings get one — see prose_bands() — so it lands as an accent on
   some sections rather than a device on all of them. */
.sband{position:relative}
.sband .wrap{position:relative}
/* The word itself comes from --ghost, set inline per band. See
   ghost_css_str(): it is decoration, so it lives in the CSS layer rather than
   as a text node a screen reader and a contrast checker both have to be told
   to ignore. */
.sband-ghost::before{content:var(--ghost,"")}
.sband-ghost{
  position:absolute;z-index:0;top:.1em;right:0;
  pointer-events:none;user-select:none;
  font-family:var(--serif);font-weight:600;
  /* One line, always. Wrapped to two it drops into the body copy and the
     collision reads as a fault rather than a flourish. Nowrap keeps it beside
     the heading where it belongs; the 24-character limit in prose_bands() is
     what guarantees it still fits. */
  white-space:nowrap;
  /* size is set inline, per heading — see prose_bands() */
  line-height:1;
  letter-spacing:-.02em;text-transform:uppercase;text-align:right;
  color:rgba(92,143,43,.10)}
.sband-deep .sband-ghost{color:rgba(255,255,255,.055)}
@media (max-width:1180px){ .sband-ghost{display:none} }

/* ---------- the promises, as the closing edge of the hero ---------- */
/* It was a white panel dropped between two content bands, which is exactly
   what it looked like. On the hero's own ground it finishes the hero instead
   of interrupting the page. */
.trust-band{
  background:var(--green-deep);
  padding-block:clamp(1.5rem,2.8vw,2.1rem);
  /* The hero above carries a gradient wash, so its foot never matches a flat
     color exactly. A hairline turns that seam into a deliberate rule instead
     of a near-miss. */
  border-top:1px solid rgba(255,255,255,.12);
  border-bottom:0}
.trust-band .trust-item + .trust-item{border-left:1px solid rgba(255,255,255,.16)}
.trust-band .trust-ico{color:var(--accent)}
.trust-band .trust-item h2{color:#fff}
.trust-band .trust-item p{color:rgba(255,255,255,.72)}
@media (max-width:900px){
  .trust-band .trust-item + .trust-item{border-left:0}
  .trust-band .trust-item:nth-child(even){border-left:1px solid rgba(255,255,255,.16)}
}
@media (max-width:520px){
  .trust-band .trust-item:nth-child(even){border-left:0}
}

/* The lead has no heading for the ghost to hide behind, so on that one band
   it gets a line of its own above the copy instead of landing across it. */
.sband-ghost-lead{left:0;right:0;top:0;text-align:center}
.sband-lead.has-ghost .sband-inner{padding-top:2.4rem}
.sband-lead-long .sband-ghost-lead{text-align:left}

/* A price card whose photograph is not on the server keeps its shape and its
   price badge — the brand gradient stands in for the picture rather than the
   card collapsing or showing a broken image. */
.pcard-photo.no-photo{
  background:linear-gradient(135deg,var(--accent-soft) 0%,var(--band) 60%,#F6E7EC 100%);
  min-height:190px}


/* ---------- two blocks of copy, side by side (Contact) ---------- */
/* One narrow column with two headings in it left two thirds of the page
   empty and read as a document. Side by side they read as a page. */
.two-col{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1.8rem,4.5vw,4rem);align-items:start}
.two-col-item>h2:first-child{margin-top:0}
.two-col-item p{line-height:1.75}
@media (max-width:820px){
  .two-col{grid-template-columns:minmax(0,1fr);gap:2rem}
}

/* ---------- Areas Served: the service links ---------- */
/* These were outlined boxes — the same treatment as a disabled button, on
   the one element whose whole job is to be clicked. */
.area-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(238px,1fr));
  gap:.75rem;list-style:none;margin:0;padding:0}
.area-grid a{
  position:relative;display:flex;align-items:center;gap:.7rem;
  padding:.95rem 1.15rem .95rem 1.3rem;
  background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius-sm);box-shadow:var(--shadow-sm);
  text-decoration:none;color:var(--ink);
  font:500 .95rem/1.35 var(--sans);
  transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease}
.area-grid a::before{
  content:"";position:absolute;left:0;top:14%;bottom:14%;width:3px;
  border-radius:0 3px 3px 0;
  background:linear-gradient(180deg,var(--accent),var(--brand));
  transform:scaleY(.5);transition:transform .16s ease}
.area-grid a::after{
  content:"\2192";margin-left:auto;color:var(--accent-deep);
  transition:transform .16s ease}
.area-grid a:hover{
  transform:translateY(-2px);box-shadow:var(--shadow-md);
  border-color:rgba(132,196,65,.55)}
.area-grid a:hover::before{transform:scaleY(1)}
.area-grid a:hover::after{transform:translateX(3px)}
.area-grid a span{min-width:0}

/* a band that is a masthead plus its own content, with no .sband-inner */
.sband>.wrap>.area-grid{margin-top:0}


/* ---------- vertical rhythm between touching bands ---------- */
/* Two bands of the same color meeting means their padding adds up and the
   page opens a hole. Where the ground does not change there is no seam to
   dress, so the pair share one gap instead of two. */
.sband + .sband:not(.sband-alt):not(.sband-deep){padding-top:clamp(1.6rem,3vw,2.4rem)}
.sband:not(.sband-alt):not(.sband-deep):has(+ .sband:not(.sband-alt):not(.sband-deep)){
  padding-bottom:clamp(1.6rem,3vw,2.4rem)}
.sband-alt + .sband-alt{padding-top:clamp(1.6rem,3vw,2.4rem)}
.sband-alt:has(+ .sband-alt){padding-bottom:clamp(1.6rem,3vw,2.4rem)}

/* the three pillars sit tighter under their masthead than a price grid does */
/* Equal height, so the three brand feet line up. Ragged card bottoms are the
   single most common tell that a row of cards was not designed. */
.sband .tiles{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:clamp(1rem,2vw,1.5rem);align-items:stretch}
.sband .tiles>.price-card{display:flex;flex-direction:column}


/* ===========================================================
   THE MENU — the one services page
   A salon price list is a reference document. People arrive
   knowing what they want and are looking for a number. Bands,
   photographs, ghost words and colored grounds all put
   distance between them and it, so none of them are here.
   =========================================================== */

.menu-page{padding-block:clamp(2rem,4vw,3.2rem)}
/* 860px was set when the menu was one column of short rows. At a larger face
   it reads cramped, so the measure widens with it. */
.menu-page .wrap.narrow{max-width:940px}

/* Jump buttons, built on the same object as the city-page links: white card,
   1px rule, soft shadow, a brand bar that grows on the left and an arrow that
   slides on hover. Reusing that treatment rather than inventing a third button
   style means the site has one idea of what "a thing you click through to"
   looks like. Square-ish (4px) rather than pill, so it never competes with the
   hero and booking CTAs.

   They WRAP at every width. An earlier version put them in a horizontal
   scroll strip on phones, which ran three buttons off the right edge with
   nothing to say the rest were there — the six a visitor could not see may as
   well not have existed. Centred flex-wrap instead, so a part-full row centres
   rather than hanging off the left, and the labels wrap inside the button
   instead of forcing it wider than the screen. */
.menu-jump{padding-block:1.15rem;border-bottom:1px solid var(--line);
  background:var(--white);position:sticky;top:0;z-index:20;
  /* the nav links here directly, so leave room above it when it is the
     landing target rather than parking it under the header */
  scroll-margin-top:0}
.menu-jump .wrap.narrow{max-width:1180px}
.jump-list{display:flex;flex-wrap:wrap;gap:.55rem;justify-content:center;
  list-style:none;margin:0;padding:0}
.jump-list > li{display:flex;min-width:0}
.jump-list a{
  position:relative;display:flex;align-items:center;gap:.55rem;width:100%;
  padding:.72rem 1.05rem .72rem 1.25rem;
  /* Given more presence: a soft brand ground instead of white-on-white, a
     firmer edge and a real shadow. On a page that is one long price list this
     row IS the navigation, and it was reading as decoration. */
  background:linear-gradient(180deg,#FFFFFF,#F7FAF1);
  border:1px solid #DCE4CD;border-radius:5px;
  box-shadow:0 1px 0 rgba(35,40,28,.04),0 2px 6px -2px rgba(35,40,28,.10);
  font:700 .95rem/1.3 var(--sans);color:var(--brand-dark);letter-spacing:.002em;
  text-decoration:none;
  /* wraps rather than forcing the button wider than the viewport */
  white-space:normal;overflow-wrap:break-word;
  transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease,background .16s ease}
.jump-list a > span{flex:1;min-width:0}
.jump-list a::before{
  content:"";position:absolute;left:0;top:12%;bottom:12%;width:4px;
  border-radius:0 4px 4px 0;
  background:linear-gradient(180deg,var(--accent),var(--brand));
  transform:scaleY(.72);transition:transform .16s ease}
.jump-list a::after{
  content:"\2192";color:var(--accent-deep);font-weight:400;flex:0 0 auto;
  transition:transform .16s ease}
.jump-list a:hover{
  transform:translateY(-2px);
  background:linear-gradient(180deg,#FFFFFF,var(--accent-soft));
  box-shadow:0 6px 16px -6px rgba(35,40,28,.22);
  border-color:rgba(132,196,65,.75)}
.jump-list a:hover::before{transform:scaleY(1)}
.jump-list a:hover::after{transform:translateX(3px)}
.jump-list a:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* Below the point where nine content-width buttons stop making even rows,
   go to a fixed count so every row is full and nothing is orphaned. */
@media (max-width:1023px){
  .jump-list > li{flex:1 1 calc(33.333% - .55rem*2/3);max-width:calc(33.333% - .37rem)}
}
@media (max-width:720px){
  .jump-list{gap:.45rem}
  .jump-list > li{flex:1 1 calc(50% - .225rem);max-width:calc(50% - .225rem)}
  .menu-jump{padding-block:.85rem}
  .jump-list a{padding:.6rem .7rem .6rem .85rem;font-size:.86rem;gap:.35rem}
}
/* No one-per-row breakpoint. Nine stacked buttons is a screenful of nothing
   but navigation before any price is visible; two-up with the label wrapping
   is shorter and still comfortably tappable at 320px. A lone last button
   centres itself, which reads as deliberate rather than orphaned. */

.menu-sec{margin:0 0 clamp(2.4rem,4.5vw,3.6rem);scroll-margin-top:110px}
.menu-sec:last-child{margin-bottom:0}
.menu-sec>h2{
  margin:0 0 .5rem;text-align:center;
  font-family:var(--serif);font-weight:600;letter-spacing:.01em;
  font-size:clamp(1.5rem,3vw,2.05rem);color:var(--brand-dark)}
.menu-note{margin:0 auto 1.2rem;max-width:62ch;text-align:center;
  font-size:1rem;line-height:1.65;color:#4a5346}

.menu-table{width:100%;border-collapse:collapse;
  border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden}
.menu-table th,.menu-table td{
  text-align:left;padding:1.05rem 1.25rem;border-bottom:1px solid var(--line);
  vertical-align:top;font-weight:400}
.menu-table tr:last-child th,.menu-table tr:last-child td{border-bottom:0}
.menu-table tr:nth-child(even) th,.menu-table tr:nth-child(even) td{background:#FBFCF8}

/* This page is the one most visitors come for, and a fair number of them are
   reading it at arm's length on a phone. Everything here is a step up from
   where it was: name 1rem -> 1.1rem, description .9 -> 1rem, price 1 -> 1.2rem,
   and the greys are darkened so the description is not the faintest thing on
   the page. */
.mname{display:block;font-weight:600;color:var(--ink);font-size:1.1rem;line-height:1.45}
.mdesc{display:block;margin-top:.4rem;font-size:1rem;line-height:1.65;color:#4a5346}
.mincl{display:block;margin-top:.5rem;font-size:.92rem;line-height:1.65;color:var(--accent-deep)}
.mprice{width:140px;white-space:nowrap;text-align:right;
  font-weight:700;font-size:1.2rem;color:var(--brand);font-variant-numeric:tabular-nums}

/* a section that holds several lists keeps their names inline */
.mrow-sub th{
  background:var(--band) !important;
  font:700 .85rem/1.3 var(--sans) !important;letter-spacing:.09em;text-transform:uppercase;
  color:var(--accent-deep);padding-top:.8rem;padding-bottom:.8rem}

@media (max-width:600px){
  .menu-table th,.menu-table td{padding:.85rem .85rem}
  .mname{font-size:1.05rem}
  .mdesc{font-size:.97rem}
  .mprice{width:88px;font-size:1.08rem}
  .mincl{display:none}     /* the inclusion list is a lot of words on a phone */
}


/* the one line of prose a service page carries, above its menu */
.svc-intro{
  max-width:62ch;margin:0 auto clamp(1.6rem,3vw,2.4rem);
  text-align:center;font-size:1.06rem;line-height:1.72;color:var(--ink)}

.area-h2{margin:2rem 0 1rem;text-align:center;font-family:var(--serif);font-weight:600;
  font-size:clamp(1.4rem,2.6vw,1.9rem);color:var(--brand-dark)}
.area-more{margin:1.4rem 0 0;text-align:center}
.area-more a{font-weight:600;color:var(--brand);text-decoration:none}
.area-more a:hover{text-decoration:underline}

/* ---------- city pages ---------- */
/* A town list is one word per row, so the 238px minimum that suits service
   names leaves most of each box empty. Tighter minimum, same styling. */
.area-grid-tight { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }

/* Starting-price table on the town pages. Deliberately not the full menu —
   thirteen pages carrying the whole price list would be thirteen copies of
   the same content. */
.snap-table { width: 100%; border-collapse: collapse; margin: .4rem 0 1.4rem; }
.snap-table th, .snap-table td { padding: .72rem .2rem; text-align: left;
  border-bottom: 1px solid var(--line); font-size: 1rem; }
.snap-table th { font-weight: 600; color: var(--ink); }
.snap-table td { text-align: right; font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--brand); font-weight: 600; }
.snap-table tr:last-child th, .snap-table tr:last-child td { border-bottom: 0; }
.snap-note { color: var(--ink-soft); font-size: .93rem; margin: 0 0 .8rem; }

/* ---------- footer hours ---------- */
/* .hours-table is shared with the Contact page, where .8rem row padding and a
   .96rem face are right. In the footer that made the Visit Us column taller
   and louder than the four beside it, which is what made the row look wrong —
   the column count was a symptom. Matched to the footer's own list rhythm:
   same size as the links, same .55rem gap, no rules across it. */
.site-footer .hours-table { margin-top: .55rem; }
.site-footer .hours-table th,
.site-footer .hours-table td {
  padding: 0 0 .55rem;
  border-bottom: 0;
  font-size: .93rem;
  line-height: 1.5;
  vertical-align: baseline;
}
.site-footer .hours-table th { font-weight: 400; color: rgba(255,255,255,.72); padding-right: 1rem; }
/* Crimson #C22749 on the #242424 footer is 2.72:1 — a real WCAG AA failure,
   and the opening hours are exactly the kind of thing someone squints at.
   Same hue, lifted until it passes: 6.23:1. */
.site-footer .hours-table td { font-weight: 600; color: #F0839C; }
.site-footer .hours-table tr:last-child th,
.site-footer .hours-table tr:last-child td { padding-bottom: 0; }

/* ---------- services menu ---------- */
/* A link plus a button, never nested — <a> inside a <summary> or a <button> is
   a control inside a control: invalid, and announced as one thing that does
   two. So "Our Services" stays a real link to the price list, and the chevron
   beside it is the disclosure.

   Opening is CSS-first: :hover and :focus-within on the <li>, so it works with
   JavaScript off and for keyboard users tabbing through. site.js adds the
   button state, taps on touch screens, Escape, and a close delay. */
.nav .has-menu { position: relative; display: flex; align-items: center; gap: .15rem; }
.svcmenu-label { white-space: nowrap; }
.svcmenu-chev {
  display: inline-grid; place-items: center; cursor: pointer;
  width: 1.5rem; height: 1.5rem; padding: 0;
  background: none; border: 0; border-radius: 4px; color: inherit;
  transition: transform .22s ease, background .16s;
}
.svcmenu-chev svg { width: 15px; height: 15px; fill: none;
  stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.svcmenu-chev:hover { background: var(--accent-soft); }
.svcmenu-chev:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.svcmenu-panel {
  position: absolute; top: calc(100% + .7rem); left: 50%; translate: -50% 0;
  z-index: 120; width: min(41rem, calc(100vw - 2rem));
  background: var(--white); border: 1px solid var(--line);
  border-radius: 12px; padding: .8rem;
  box-shadow: 0 24px 60px -18px rgba(20,26,14,.34), 0 0 0 1px rgba(132,196,65,.16);
  opacity: 0; visibility: hidden; translate: -50% -6px;
  transition: opacity .16s ease, translate .16s ease, visibility 0s linear .16s;
}
/* the gap between the row and the panel would end the hover, so bridge it */
.nav .has-menu::after {
  content: ""; position: absolute; top: 100%; left: 0; right: 0; height: .8rem;
}
.nav .has-menu:hover .svcmenu-panel,
.nav .has-menu:focus-within .svcmenu-panel,
.nav .has-menu.is-open .svcmenu-panel {
  opacity: 1; visibility: visible; translate: -50% 0; transition-delay: 0s;
}
.nav .has-menu:hover .svcmenu-chev,
.nav .has-menu.is-open .svcmenu-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .svcmenu-panel { transition: opacity .01s, visibility 0s; translate: -50% 0; }
  .svcmenu-chev { transition: background .16s; }
}
.svcmenu-panel::before {
  content: ""; position: absolute; top: -7px; left: 50%; margin-left: -7px;
  width: 12px; height: 12px; background: var(--white); rotate: 45deg;
  border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  border-radius: 2px 0 0 0;
}
.svcmenu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .25rem; }
.svcmenu-item {
  position: relative; display: flex; align-items: baseline; gap: .6rem;
  padding: .62rem .8rem .62rem .95rem; border-radius: 7px;
  text-decoration: none; color: var(--ink); font-size: .93rem; line-height: 1.3;
  transition: background .15s, color .15s;
}
.svcmenu-item::before {
  content: ""; position: absolute; left: .3rem; top: 30%; bottom: 30%; width: 3px;
  border-radius: 3px; background: linear-gradient(180deg, var(--accent), var(--brand));
  opacity: 0; transition: opacity .15s;
}
.svcmenu-item:hover, .svcmenu-item:focus-visible { background: var(--band); }
.svcmenu-item:hover::before, .svcmenu-item.is-current::before { opacity: 1; }
.svcmenu-item.is-current { background: var(--accent-soft); font-weight: 600; }
.svcmenu-name { flex: 1; min-width: 0; }
.svcmenu-from {
  flex: 0 0 auto; font-size: .8rem; font-weight: 600;
  color: var(--accent-deep); font-variant-numeric: tabular-nums;
}
.svcmenu-all-top {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin: 0 0 .5rem; padding: .7rem .95rem;
  background: var(--band); border-radius: 8px;
  text-decoration: none; color: var(--brand-dark);
  font-size: .96rem; font-weight: 700; transition: background .15s;
}
.svcmenu-all-top:hover { background: var(--accent-soft); }
.svcmenu-allnote { font-weight: 400; font-size: .84rem; color: var(--ink-soft); }

/* On a phone the nav is already a full-height panel, and there is no hover, so
   the menu opens inline inside it under the button. */
@media (max-width: 1100px) {
  .nav .has-menu {
    display: block; padding: 0; border-bottom: 1px solid var(--line);
  }
  .nav .has-menu::after { display: none; }
  .svcmenu-label {
    display: block; padding: .95rem 3.2rem .95rem .4rem; border: 0;
  }
  .svcmenu-chev {
    position: absolute; top: .55rem; right: .3rem;
    width: 2.6rem; height: 2.6rem; border-radius: 6px;
  }
  .svcmenu-chev svg { width: 18px; height: 18px; }
  .svcmenu-panel {
    position: static; translate: 0; left: auto; width: auto; box-shadow: none;
    border: 0; border-radius: 0; background: transparent;
    padding: 0 0 .6rem .55rem; margin-left: .4rem;
    border-left: 2px solid var(--accent-soft);
    /* collapsed by height so it can animate, and so it is out of the tab order
       when shut */
    opacity: 1; visibility: hidden; height: 0; overflow: hidden;
    transition: height .2s ease, visibility 0s linear .2s;
  }
  /* hover means nothing on a touch screen: only the button opens it */
  .nav .has-menu:hover .svcmenu-panel { visibility: hidden; height: 0; }
  /* translate: 0 has to be repeated at THIS specificity. The desktop
     open-state rule sets translate: -50% 0 and lives outside any media query,
     so a plain `.svcmenu-panel { translate: 0 }` in here lost to it and the
     panel sat 143px off the left edge of the drawer with its labels cut off. */
  .nav .has-menu.is-open .svcmenu-panel,
  .nav .has-menu:focus-within .svcmenu-panel {
    visibility: visible; height: auto; padding-top: .35rem; transition-delay: 0s;
    translate: 0; left: auto; width: auto;
  }
  .nav .has-menu:hover .svcmenu-panel { translate: 0; left: auto; }
  .svcmenu-panel::before { display: none; }
  .svcmenu-grid { grid-template-columns: 1fr; gap: 0; }
  .svcmenu-item { padding: .68rem .6rem; }
  .svcmenu-all-top { margin-top: .45rem; }
}

/* Jump buttons, built on the same object as the city-page links: white card,
   1px rule, soft shadow, a brand bar that grows on the left and an arrow that
   slides on hover. Reusing that treatment rather than inventing a third button
   style means the site has one idea of what "a thing you click through to"
   looks like. Square-ish (4px) rather than pill, so it never competes with the
   hero and booking CTAs.

   They WRAP at every width. An earlier version put them in a horizontal
   scroll strip on phones, which ran three buttons off the right edge with
   nothing to say the rest were there — the six a visitor could not see may as
   well not have existed. Centred flex-wrap instead, so a part-full row centres
   rather than hanging off the left, and the labels wrap inside the button
   instead of forcing it wider than the screen. */
.menu-jump{padding-block:1.15rem;border-bottom:1px solid var(--line);
  background:var(--white);position:sticky;top:0;z-index:20;
  /* the nav links here directly, so leave room above it when it is the
     landing target rather than parking it under the header */
  scroll-margin-top:0}
.menu-jump .wrap.narrow{max-width:1180px}
.jump-list{display:flex;flex-wrap:wrap;gap:.55rem;justify-content:center;
  list-style:none;margin:0;padding:0}
.jump-list > li{display:flex;min-width:0}
.jump-list a{
  position:relative;display:flex;align-items:center;gap:.55rem;width:100%;
  padding:.72rem 1.05rem .72rem 1.25rem;
  /* Given more presence: a soft brand ground instead of white-on-white, a
     firmer edge and a real shadow. On a page that is one long price list this
     row IS the navigation, and it was reading as decoration. */
  background:linear-gradient(180deg,#FFFFFF,#F7FAF1);
  border:1px solid #DCE4CD;border-radius:5px;
  box-shadow:0 1px 0 rgba(35,40,28,.04),0 2px 6px -2px rgba(35,40,28,.10);
  font:700 .95rem/1.3 var(--sans);color:var(--brand-dark);letter-spacing:.002em;
  text-decoration:none;
  /* wraps rather than forcing the button wider than the viewport */
  white-space:normal;overflow-wrap:break-word;
  transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease,background .16s ease}
.jump-list a > span{flex:1;min-width:0}
.jump-list a::before{
  content:"";position:absolute;left:0;top:12%;bottom:12%;width:4px;
  border-radius:0 4px 4px 0;
  background:linear-gradient(180deg,var(--accent),var(--brand));
  transform:scaleY(.72);transition:transform .16s ease}
.jump-list a::after{
  content:"\2192";color:var(--accent-deep);font-weight:400;flex:0 0 auto;
  transition:transform .16s ease}
.jump-list a:hover{
  transform:translateY(-2px);
  background:linear-gradient(180deg,#FFFFFF,var(--accent-soft));
  box-shadow:0 6px 16px -6px rgba(35,40,28,.22);
  border-color:rgba(132,196,65,.75)}
.jump-list a:hover::before{transform:scaleY(1)}
.jump-list a:hover::after{transform:translateX(3px)}
.jump-list a:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* Below the point where nine content-width buttons stop making even rows,
   go to a fixed count so every row is full and nothing is orphaned. */
@media (max-width:1023px){
  .jump-list > li{flex:1 1 calc(33.333% - .55rem*2/3);max-width:calc(33.333% - .37rem)}
}
@media (max-width:720px){
  .jump-list{gap:.45rem}
  .jump-list > li{flex:1 1 calc(50% - .225rem);max-width:calc(50% - .225rem)}
  .menu-jump{padding-block:.85rem}
  .jump-list a{padding:.6rem .7rem .6rem .85rem;font-size:.86rem;gap:.35rem}
}
/* No one-per-row breakpoint. Nine stacked buttons is a screenful of nothing
   but navigation before any price is visible; two-up with the label wrapping
   is shorter and still comfortably tappable at 320px. A lone last button
   centres itself, which reads as deliberate rather than orphaned. */

.menu-sec{margin:0 0 clamp(2.4rem,4.5vw,3.6rem);scroll-margin-top:110px}
.menu-sec:last-child{margin-bottom:0}
.menu-sec>h2{
  margin:0 0 .5rem;text-align:center;
  font-family:var(--serif);font-weight:600;letter-spacing:.01em;
  font-size:clamp(1.5rem,3vw,2.05rem);color:var(--brand-dark)}
.menu-note{margin:0 auto 1.2rem;max-width:62ch;text-align:center;
  font-size:1rem;line-height:1.65;color:#4a5346}

.menu-table{width:100%;border-collapse:collapse;
  border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden}
.menu-table th,.menu-table td{
  text-align:left;padding:1.05rem 1.25rem;border-bottom:1px solid var(--line);
  vertical-align:top;font-weight:400}
.menu-table tr:last-child th,.menu-table tr:last-child td{border-bottom:0}
.menu-table tr:nth-child(even) th,.menu-table tr:nth-child(even) td{background:#FBFCF8}

/* This page is the one most visitors come for, and a fair number of them are
   reading it at arm's length on a phone. Everything here is a step up from
   where it was: name 1rem -> 1.1rem, description .9 -> 1rem, price 1 -> 1.2rem,
   and the greys are darkened so the description is not the faintest thing on
   the page. */
.mname{display:block;font-weight:600;color:var(--ink);font-size:1.1rem;line-height:1.45}
.mdesc{display:block;margin-top:.4rem;font-size:1rem;line-height:1.65;color:#4a5346}
.mincl{display:block;margin-top:.5rem;font-size:.92rem;line-height:1.65;color:var(--accent-deep)}
.mprice{width:140px;white-space:nowrap;text-align:right;
  font-weight:700;font-size:1.2rem;color:var(--brand);font-variant-numeric:tabular-nums}

/* a section that holds several lists keeps their names inline */
.mrow-sub th{
  background:var(--band) !important;
  font:700 .85rem/1.3 var(--sans) !important;letter-spacing:.09em;text-transform:uppercase;
  color:var(--accent-deep);padding-top:.8rem;padding-bottom:.8rem}

@media (max-width:600px){
  .menu-table th,.menu-table td{padding:.85rem .85rem}
  .mname{font-size:1.05rem}
  .mdesc{font-size:.97rem}
  .mprice{width:88px;font-size:1.08rem}
  .mincl{display:none}     /* the inclusion list is a lot of words on a phone */
}


/* the one line of prose a service page carries, above its menu */
.svc-intro{
  max-width:62ch;margin:0 auto clamp(1.6rem,3vw,2.4rem);
  text-align:center;font-size:1.06rem;line-height:1.72;color:var(--ink)}

.area-h2{margin:2rem 0 1rem;text-align:center;font-family:var(--serif);font-weight:600;
  font-size:clamp(1.4rem,2.6vw,1.9rem);color:var(--brand-dark)}
.area-more{margin:1.4rem 0 0;text-align:center}
.area-more a{font-weight:600;color:var(--brand);text-decoration:none}
.area-more a:hover{text-decoration:underline}

/* ---------- city pages ---------- */
/* A town list is one word per row, so the 238px minimum that suits service
   names leaves most of each box empty. Tighter minimum, same styling. */
.area-grid-tight { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }

/* Starting-price table on the town pages. Deliberately not the full menu —
   thirteen pages carrying the whole price list would be thirteen copies of
   the same content. */
.snap-table { width: 100%; border-collapse: collapse; margin: .4rem 0 1.4rem; }
.snap-table th, .snap-table td { padding: .72rem .2rem; text-align: left;
  border-bottom: 1px solid var(--line); font-size: 1rem; }
.snap-table th { font-weight: 600; color: var(--ink); }
.snap-table td { text-align: right; font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--brand); font-weight: 600; }
.snap-table tr:last-child th, .snap-table tr:last-child td { border-bottom: 0; }
.snap-note { color: var(--ink-soft); font-size: .93rem; margin: 0 0 .8rem; }

/* ---------- footer hours ---------- */
/* .hours-table is shared with the Contact page, where .8rem row padding and a
   .96rem face are right. In the footer that made the Visit Us column taller
   and louder than the four beside it, which is what made the row look wrong —
   the column count was a symptom. Matched to the footer's own list rhythm:
   same size as the links, same .55rem gap, no rules across it. */
.site-footer .hours-table { margin-top: .55rem; }
.site-footer .hours-table th,
.site-footer .hours-table td {
  padding: 0 0 .55rem;
  border-bottom: 0;
  font-size: .93rem;
  line-height: 1.5;
  vertical-align: baseline;
}
.site-footer .hours-table th { font-weight: 400; color: rgba(255,255,255,.72); padding-right: 1rem; }
/* Crimson #C22749 on the #242424 footer is 2.72:1 — a real WCAG AA failure,
   and the opening hours are exactly the kind of thing someone squints at.
   Same hue, lifted until it passes: 6.23:1. */
.site-footer .hours-table td { font-weight: 600; color: #F0839C; }
.site-footer .hours-table tr:last-child th,
.site-footer .hours-table tr:last-child td { padding-bottom: 0; }

/* ---------- services menu ---------- */
/* A <details> disclosure rather than a hover menu: it opens on a touch screen,
   it is keyboard-operable and announced properly, and it still works with
   JavaScript off. The <summary> holds a real link so "Our Services" itself
   remains clickable — the chevron is what opens the panel. */
.nav .has-menu { position: relative; }
.svcmenu { position: relative; }
/* The whole row is the control now — <summary> is a button, so nothing
   interactive may live inside it. The link to the price list is the first
   item in the panel instead. */
.svcmenu > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: .3rem;
}
.svcmenu > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 6px; }
.svcmenu > summary::-webkit-details-marker { display: none; }
.svcmenu > summary::marker { content: ""; }
.svcmenu-chev {
  display: inline-grid; place-items: center;
  width: 1.1rem; height: 1.1rem; transition: transform .22s ease;
}
.svcmenu-chev svg { width: 15px; height: 15px; fill: none;
  stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.svcmenu[open] .svcmenu-chev { transform: rotate(180deg); }

.svcmenu-panel {
  position: absolute; top: calc(100% + .85rem); left: 50%; translate: -50% 0;
  z-index: 120; width: min(41rem, calc(100vw - 2rem));
  background: var(--white); border: 1px solid var(--line);
  border-radius: 12px; padding: .8rem;
  box-shadow: 0 24px 60px -18px rgba(20,26,14,.34), 0 0 0 1px rgba(132,196,65,.16);
  animation: svcmenu-in .17s ease both;
}
@keyframes svcmenu-in { from { opacity: 0; translate: -50% -6px; } to { opacity: 1; translate: -50% 0; } }
@media (prefers-reduced-motion: reduce) {
  .svcmenu-panel { animation: none; }
  .svcmenu-toggle { transition: background .16s; }
}
/* a little arrow pointing back at the menu item */
.svcmenu-panel::before {
  content: ""; position: absolute; top: -7px; left: 50%; margin-left: -7px;
  width: 12px; height: 12px; background: var(--white); rotate: 45deg;
  border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  border-radius: 2px 0 0 0;
}
.svcmenu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .25rem; }
.svcmenu-item {
  position: relative; display: flex; align-items: baseline; gap: .6rem;
  padding: .62rem .8rem .62rem .95rem; border-radius: 7px;
  text-decoration: none; color: var(--ink); font-size: .93rem; line-height: 1.3;
  transition: background .15s, color .15s;
}
.svcmenu-item::before {
  content: ""; position: absolute; left: .3rem; top: 30%; bottom: 30%; width: 3px;
  border-radius: 3px; background: linear-gradient(180deg, var(--accent), var(--brand));
  opacity: 0; transition: opacity .15s;
}
.svcmenu-item:hover, .svcmenu-item:focus-visible { background: var(--band); }
.svcmenu-item:hover::before, .svcmenu-item.is-current::before { opacity: 1; }
.svcmenu-item.is-current { background: var(--accent-soft); font-weight: 600; }
.svcmenu-name { flex: 1; min-width: 0; }
.svcmenu-from {
  flex: 0 0 auto; font-size: .8rem; font-weight: 600;
  color: var(--accent-deep); font-variant-numeric: tabular-nums;
}
.svcmenu-all-top {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin: 0 0 .5rem; padding: .7rem .95rem;
  background: var(--band); border-radius: 8px;
  text-decoration: none; color: var(--brand-dark);
  font-size: .96rem; font-weight: 700;
  transition: background .15s;
}
.svcmenu-all-top:hover { background: var(--accent-soft); }
.svcmenu-allnote { font-weight: 400; font-size: .84rem; color: var(--ink-soft); }

/* On a phone the nav is already a full-height panel, so the menu opens inline
   inside it rather than floating over the page. */
@media (max-width: 1100px) {
  /* In the phone panel the row has to match Home / About Us / Contact exactly:
     same padding, same rule underneath, chevron pushed to the right. The
     <summary> is not an <a>, so none of `.nav > li > a` reaches it. */
  .nav .has-menu { display: block; }
  .svcmenu > summary {
    display: flex; align-items: center; justify-content: space-between;
    padding: .95rem .4rem; border-bottom: 1px solid var(--line);
  }
  .svcmenu-chev { width: 2rem; height: 2rem; }
  .svcmenu-chev svg { width: 18px; height: 18px; }
  .svcmenu-panel {
    position: static; translate: 0; left: auto; width: auto; box-shadow: none;
    border: 0; border-radius: 0; background: transparent;
    padding: .35rem 0 .6rem .55rem; margin-left: .4rem;
    border-left: 2px solid var(--accent-soft);
    animation: none;
  }
  .svcmenu-panel::before { display: none; }
  .svcmenu-grid { grid-template-columns: 1fr; gap: 0; }
  .svcmenu-item { padding: .68rem .6rem; }
  .svcmenu-all-top { margin-top: .45rem; }
}


/* The logo is nearly 4:1, so at 66px tall it is 263px wide — on a 390px phone
   that leaves the call button and the hamburger fighting over what is left.
   Step it down before it gets there rather than letting the controls shrink. */
@media (max-width: 430px) { .logo img { height: 56px; } }
@media (max-width: 360px) { .logo img { height: 48px; } }


/* ---------- buttons: never wider than their screen ---------- */
/* "See All Services & Pricing" measured 318px inside a 320px viewport, which
   pushed the whole page sideways by 17px. A button is the one thing a visitor
   is meant to hit, so it may shrink and it may wrap, but it may never be the
   reason the page scrolls. */
.btn { max-width: 100%; box-sizing: border-box; }
@media (max-width: 420px) {
  .btn {
    white-space: normal; text-wrap: balance;
    padding-inline: 1.1rem; line-height: 1.3;
  }
  .hero-actions .btn, .cta-actions .btn { width: 100%; }
}

/* ===========================================================
   ABOUT — pared back
   Twelve headings of "we are good at nails" became four
   sections that each carry a checkable fact. The layout is
   deliberately quiet: no bands, no ghost words, no badges. On
   a page whose whole argument is "we are straight with you",
   restraint is the argument.
   =========================================================== */
.ab-row { padding-block: clamp(3rem, 7vw, 6rem); background: var(--white); }
.ab-row.ab-tint { background: var(--band); }

.ab-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
}
/* alternate which side the photograph falls on */
.ab-row.ab-flip .ab-fig { order: 2; }

.ab-fig { margin: 0; }
.ab-fig img {
  width: 100%; height: auto; display: block;
  aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 14px; box-shadow: var(--shadow-md);
}
.ab-copy h2, .ab-copy h3 {
  margin: 0 0 1rem; font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.5rem, 3.2vw, 2.15rem); line-height: 1.2;
  color: var(--brand-dark); letter-spacing: -.01em;
}
/* a short brand rule instead of a decorative watermark */
.ab-copy h2::after, .ab-copy h3::after {
  content: ""; display: block; width: 3.2rem; height: 3px; margin-top: .85rem;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--accent), var(--brand));
}
.ab-copy p {
  margin: 1.1rem 0 0; font-size: 1.06rem; line-height: 1.75; color: #3f4739;
  max-width: 46ch;
}
.ab-copy p:first-of-type { margin-top: 1.2rem; }

@media (max-width: 860px) {
  .ab-grid { grid-template-columns: 1fr; gap: 1.6rem; }
  /* the photo leads on a phone, whichever side it takes on a desktop */
  .ab-row.ab-flip .ab-fig { order: 0; }
  .ab-copy p { max-width: none; }
}
@media (max-width: 420px) {
  .ab-fig img { aspect-ratio: 3 / 2; }
}


/* ---------- About: Meet the Owner ---------- */
/* The block closes the page directly under section four, which is tinted, so
   the two ran together as one long field of the same color. A half-step
   deeper reads as a separate section without turning into another loud band,
   and the text on it is unchanged, so nothing about contrast moves. */
.about-owner .section-owner { background: #E9EFDA; position: relative; }
.about-owner .section-owner::before {
  content: ""; display: block; position: absolute; inset: 0 0 auto 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(74,117,34,.28) 22%,
                              rgba(74,117,34,.28) 78%, transparent);
}

/* ---------------------------------------------------- contact note cards --
   Two columns of unbroken prose is what this was: forty lines of type in one
   measure, the left column running out halfway and leaving a hole. The
   content is a place and a procedure, so it is set as a place and a procedure
   — an address you can act on, and numbered steps — inside two cards that
   hold the band together. */
.notecards{
  display:grid; gap:1.5rem; align-items:start;
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
}
.notecard{
  position:relative; background:#fff; border:1px solid rgba(0,0,0,.07);
  border-radius:16px; padding:2rem 1.9rem 1.9rem;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 12px 30px -18px rgba(0,0,0,.28);
}
.notecard h2{margin:.15rem 0 .9rem; font-size:1.55rem; line-height:1.2}
.notecard h2::after{content:none}          /* the card is the frame; no rule needed */
.notecard p{margin:0 0 .9rem; line-height:1.65}
.notecard p:last-child{margin-bottom:0}

.nc-ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:44px; height:44px; border-radius:12px; margin-bottom:.9rem;
  background:var(--green-pale,#eef3e6); color:var(--accent-deep,#4A7522);
}
.nc-ico svg{width:24px; height:24px}

.nc-addr{
  font-weight:600; line-height:1.45;
  padding:.75rem .9rem; border-left:3px solid var(--accent-deep,#4A7522);
  background:rgba(0,0,0,.025); border-radius:0 8px 8px 0;
}

.nc-list{margin:0 0 1.1rem; padding:0; list-style:none}
.nc-list li{padding:.5rem 0; border-top:1px solid rgba(0,0,0,.06); line-height:1.6}
.nc-list li:first-child{border-top:0}

/* Counters rather than <ol> markers so the number can be a filled disc that
   lines up with the first line of text at any wrap. */
.nc-steps{margin:0 0 1.1rem; padding:0; list-style:none; counter-reset:ncs}
.nc-steps li{
  counter-increment:ncs; position:relative; padding:0 0 .95rem 2.6rem; line-height:1.6;
}
.nc-steps li::before{
  content:counter(ncs); position:absolute; left:0; top:.05rem;
  width:1.75rem; height:1.75rem; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--accent-deep,#4A7522); color:#fff;
  font-size:.85rem; font-weight:700; font-variant-numeric:tabular-nums;
}
.nc-steps li:last-child{padding-bottom:0}

.nc-foot{
  margin-top:1.1rem; padding-top:1rem; border-top:1px solid rgba(0,0,0,.07);
  font-size:.95rem; color:var(--soft,#5b5b52);
}
.nc-btn{margin-top:.3rem}

@media (max-width:520px){
  .notecard{padding:1.5rem 1.25rem}
  .notecard h2{font-size:1.35rem}
}


/* ---- About: overview + Our Standards (client copy, Sep 2026) ----
   The overview reads as a letter from the salon, so it is set as one:
   a single comfortable measure, the first paragraph a touch larger to
   lead the eye in. The standards follow as the same alternating rows the
   page already used, numbered, under one heading of their own. */
.ab-overview { padding-block: clamp(3rem, 6vw, 5rem) clamp(1.5rem, 3vw, 2.5rem); }
.ab-overview p {
  margin: 0 0 1.2rem; font-size: 1.08rem; line-height: 1.8; color: #3f4739;
}
.ab-overview p:first-child {
  font-family: var(--serif); font-size: clamp(1.3rem, 2.4vw, 1.6rem);
  line-height: 1.5; color: var(--ink);
}
.ab-overview p:last-child { margin-bottom: 0; }

.ab-standards-head {
  text-align: center; padding-block: clamp(2rem, 4vw, 3rem) clamp(.5rem, 2vw, 1rem);
}
.ab-standards-head h2 {
  margin: .3rem 0 .6rem; font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.9rem, 4vw, 2.7rem); color: var(--brand-dark); letter-spacing: -.01em;
}
.ab-standards-lede { margin: 0 auto; max-width: 44ch; color: var(--ink-soft); }

.ab-num {
  margin: 0 0 .35rem !important; font-family: var(--sans); font-weight: 700;
  font-size: .8rem !important; letter-spacing: .18em; color: var(--accent-deep) !important;
}

/* ---- Contact: Google map ----
   Full width of the band under the two note cards, rounded to match
   them. 16:9 on a desktop; taller on a phone, where a letterbox map is
   too thin to read the streets on. */
.map-wrap { margin-top: 1.5rem; }
.map-frame {
  display: block; width: 100%; aspect-ratio: 16 / 7; min-height: 320px; border: 0;
  border-radius: 16px; box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 12px 30px -18px rgba(0,0,0,.28);
  background: #eef0ea;
}
.map-link { margin: .7rem 0 0; text-align: right; font-size: .92rem; }
.map-link a { color: var(--brand); font-weight: 600; display: inline-block; padding: .6rem 0; }
@media (max-width: 640px) {
  .map-frame { aspect-ratio: 4 / 5; min-height: 0; }
  .map-link { text-align: center; }
}
