/* ===========================================================================
   Drashti Beauty Salon, shared design system for the static public pages.

   Every public page (home, service categories, individual treatments, about,
   suburb pages) links this file. Before it existed the same ~270 lines were
   pasted into each page; at nine pages that is nine places to change a colour
   and nine chances to miss one. It is also a real download win: the stylesheet
   is fetched once and served from cache for every page after the first.

   Page-specific rules stay in a small inline <style> on the page that needs
   them, the homepage service grid, a page's one-off price-table grouping, and
   so on. Anything used by two or more pages belongs here.
   =========================================================================== */

/* Brand colours carry a contrast requirement, because they are text far more
   often than they are decoration: --coral is every price figure, every "see all
   prices" link and the fill behind the white Book Appointment label, and --muted
   is the body copy inside cards.

   The original values did not clear WCAG AA. Measured on the live site:
   coral #E4674F was 3.31:1 on white and 2.94:1 on --coral-soft, muted #8B8791
   was 3.52:1 on white, against a 4.5:1 requirement for text this size. The
   button was the worst of it: the most important control on the site was also
   its least legible element.

   The replacements below are the smallest shift that clears 4.5:1 on every
   ground these tokens were measured sitting on (white, --cream, --coral-soft,
   and the #F3F3F4 hours chip). "Smallest" is meant literally: the search was
   over hue, saturation and lightness, ranked by CIE76 distance from the
   original, so the palette keeps its character. Coral moves dE 12.8, which is
   visible side by side and unremarkable on its own.

   Ratios, worst ground first:
     --coral       4.60 on --coral-soft, 4.96 on --cream, 5.18 on white
     --coral-dark  6.38 on --coral-soft, 7.18 on white
     --muted       4.56 on --coral-soft, 4.62 on the chip, 5.13 on white

   If you change one of these, re-check it against all four grounds rather than
   white alone. --coral-soft is always the binding one, and it is the ground the
   small 12px price chips sit on. */
:root {
    --coral: #BD452F;
    --coral-dark: #9A3623;
    --coral-soft: #FBEFEC;
    --coral-mist: #F7E0DA;
    --ink: #1C1B22;
    --cream: #FAFAFA;
    --muted: #706C76;
    --line: #EEEEEF;
    --white: #FFFFFF;
    --radius: 16px;
    --shadow-sm: 0 2px 10px rgba(28, 27, 34, .05);
    --shadow-md: 0 10px 34px rgba(28, 27, 34, .10);
    --font-display: 'Poppins', sans-serif;
    --font-body: 'Roboto', sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
    font-family: var(--font-body);
    font-weight: 300;
    color: var(--ink);
    background: var(--cream);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; }
a { color: inherit; }
h1, h2, h3 { font-family: var(--font-display); letter-spacing: -0.015em; line-height: 1.15; }

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 22px; }

/* ---------- Buttons ---------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    font-family: var(--font-display); font-weight: 600; font-size: 15px;
    padding: 13px 26px; border-radius: 999px; text-decoration: none;
    transition: transform .18s ease, box-shadow .18s ease, background .18s ease;
    white-space: nowrap;
}
.btn-primary {
    background: var(--coral); color: #fff;
    box-shadow: 0 6px 18px rgba(189, 69, 47, .32);
}
.btn-primary:hover { background: var(--coral-dark); transform: translateY(-2px); box-shadow: 0 10px 24px rgba(189, 69, 47, .38); }
.btn-ghost {
    background: transparent; color: var(--ink);
    border: 1.5px solid var(--line); background: var(--white);
}
.btn-ghost:hover { border-color: var(--coral); color: var(--coral); transform: translateY(-2px); }
.btn-lg { padding: 16px 34px; font-size: 16px; }

/* ---------- Header ---------- */
header {
    position: sticky; top: 0; z-index: 50;
    background: rgba(250, 250, 250, .85);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
}
.nav { display: flex; align-items: center; justify-content: space-between; height: 72px; gap: 16px; }
.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; }
/* flex:0 0 auto: the header is a three-way flex row, so a tight viewport takes
   its millimetres out of whatever will give them. Without this the logo itself
   shrank (40px down to 37px) before the nav ever collapsed. */
.brand img { width: 40px; height: 40px; border-radius: 12px; flex: 0 0 auto; }
/* nowrap: the header is a three-way flex row, so when the nav gets tight the
   brand is what the browser squeezes, and "Drashti Beauty Salon" would break
   onto two lines inside a 72px bar. Better to hold the name on one line and let
   the nav collapse to its hamburger instead. */
.brand span { font-family: var(--font-display); font-weight: 700; font-size: 17px; white-space: nowrap; }
.nav-links { display: flex; gap: 22px; }
.nav-links a {
    text-decoration: none; font-weight: 400; font-size: 14.5px; color: var(--ink);
    opacity: .82; transition: color .15s, opacity .15s;
}
.nav-links a:hover { color: var(--coral); opacity: 1; }
.nav-links .mobile-only { display: none; }
/* Staff sign-in. It belongs in the header (staff were having to type the
   address, because the only link was in the footer) but it is not a customer
   destination, so it sits after a hairline, in the muted grey, and never takes
   the coral hover the service links get. Quiet, but findable without scrolling
   to the bottom of the page. */
.nav-staff {
    color: var(--muted) !important;
    border-left: 1px solid var(--line);
    padding-left: 22px;
    opacity: 1;
}
.nav-staff:hover { color: var(--ink) !important; }
/* Inside the open hamburger the row is vertical, so a left border would draw a
   stray tick beside the link instead of separating anything. */
.nav-links.open .nav-staff { border-left: none; padding-left: 0; }
.nav-cta { display: flex; gap: 10px; align-items: center; }
.nav-cta .btn { padding: 10px 20px; font-size: 14px; }
.menu-btn { display: none; background: none; border: none; cursor: pointer; padding: 8px; }
.menu-btn svg { width: 26px; height: 26px; stroke: var(--ink); }

/* ---------- Breadcrumbs ----------
   Google asks that the BreadcrumbList in structured data reflect a trail the
   visitor can actually see. Every page carried the JSON-LD and none of them
   showed the trail, so this makes the markup honest and gives deep pages a
   one-tap route back up. */
.crumbs {
    font-size: 13px; color: var(--muted); padding: 16px 0 0;
    display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
}
.crumbs a { text-decoration: none; color: var(--muted); transition: color .15s; }
.crumbs a:hover { color: var(--coral); }
.crumbs span[aria-current] { color: var(--ink); font-weight: 400; }
.crumbs li { list-style: none; display: inline-flex; gap: 6px; align-items: center; }
.crumbs li::after { content: "/"; color: var(--line); }
.crumbs li:last-child::after { content: ""; }
.crumbs ol { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* ---------- Hero ---------- */
.hero { position: relative; overflow: hidden; padding: 72px 0 84px; }
.hero-bg {
    position: absolute; inset: 0; pointer-events: none;
    background:
        radial-gradient(560px 420px at 88% 8%, var(--coral-mist) 0%, transparent 68%),
        radial-gradient(420px 380px at -6% 92%, #F3ECE9 0%, transparent 65%);
}
.hero-grid { position: relative; display: grid; grid-template-columns: 1.05fr .95fr; gap: 56px; align-items: center; }
.eyebrow {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--font-display); font-weight: 600; font-size: 12.5px;
    letter-spacing: .14em; text-transform: uppercase; color: var(--coral);
    margin-bottom: 18px;
}
.eyebrow::before { content: ""; width: 26px; height: 2px; background: var(--coral); border-radius: 2px; }
.hero h1 { font-size: clamp(34px, 5vw, 54px); font-weight: 700; margin-bottom: 20px; }
.hero h1 em { font-style: normal; color: var(--coral); }
.hero p.lead { font-size: 17.5px; color: #4A4752; max-width: 32em; margin-bottom: 30px; font-weight: 300; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 30px; }
.hero-trust { display: flex; gap: 20px; flex-wrap: wrap; }
.hero-trust span { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--muted); font-weight: 400; }
.hero-trust svg { width: 15px; height: 15px; fill: var(--coral); flex: none; }

/* Hero visual composition */
.hero-art { position: relative; min-height: 420px; }
.hero-blob {
    position: absolute; inset: 6% 4% 6% 10%;
    background: linear-gradient(150deg, var(--coral-soft) 0%, var(--coral-mist) 55%, #F2CFC6 100%);
    border-radius: 46% 54% 58% 42% / 48% 44% 56% 52%;
    box-shadow: var(--shadow-md);
}
.hero-blob svg { position: absolute; inset: 0; width: 100%; height: 100%; opacity: .5; }
.chip {
    position: absolute; background: rgba(255, 255, 255, .92);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, .8); border-radius: 14px;
    box-shadow: var(--shadow-md); padding: 12px 18px;
    font-size: 13.5px; font-weight: 400;
    animation: floaty 5.5s ease-in-out infinite;
}
.chip b { font-family: var(--font-display); font-weight: 600; display: block; font-size: 14.5px; }
.chip .price { color: var(--coral); font-weight: 600; }
.chip-1 { top: 9%; left: 0; animation-delay: 0s; }
.chip-2 { top: 42%; right: 0; animation-delay: 1.4s; }
.chip-3 { bottom: 8%; left: 12%; animation-delay: 2.8s; }
@keyframes floaty { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
@media (prefers-reduced-motion: reduce) { .chip { animation: none; } }

/* ---------- Sections ---------- */
section { padding: 78px 0; }
.sec-head { max-width: 620px; margin-bottom: 44px; }
.sec-head h2 { font-size: clamp(26px, 3.4vw, 36px); font-weight: 700; margin-bottom: 12px; }
.sec-head p { color: var(--muted); font-size: 16px; }
.sec-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.sec-head.center .eyebrow { justify-content: center; }

.card {
    background: var(--white); border: 1px solid var(--line);
    border-radius: var(--radius); padding: 30px; box-shadow: var(--shadow-sm);
}

/* ---------- Price tables ---------- */
.price-card { max-width: 680px; margin: 0 auto; }
.price-table { width: 100%; border-collapse: collapse; font-size: 15.5px; }
.price-table td { padding: 13px 0; border-bottom: 1px dashed var(--line); }
.price-table tr:last-child td { border-bottom: none; }
.price-table td:last-child { text-align: right; font-weight: 500; white-space: nowrap; }
.price-table .dur { color: var(--muted); font-size: 13.5px; font-weight: 300; display: block; }
.price-note { font-size: 13.5px; color: var(--muted); margin-top: 14px; font-style: italic; text-align: center; }
.svc-cta { text-align: center; margin-top: 42px; }

/* A long menu needs grouping. The selector is td.group-row, not .group-row:
   the heading cell is the only td in its row, so ".price-table td:last-child"
   above (0,2,1) otherwise out-specifies it and right-aligns the headings.
   Matching that specificity and coming later in the sheet wins it back. */
.price-table td.group-row {
    font-family: var(--font-display); font-weight: 600; font-size: 12.5px;
    letter-spacing: .1em; text-transform: uppercase; color: var(--coral);
    text-align: left; padding-top: 22px; border-bottom: none;
}
.price-table tr:first-child td.group-row { padding-top: 0; }

/* ---------- Full price list (/prices) ----------
   Three columns rather than the service pages' two, because the whole point of
   this page is being able to compare duration alongside price. Same specificity
   trick as .group-row: the note spans the row so it is also td:last-child, which
   would otherwise right-align it. */
.price-list-card { max-width: 760px; }
.price-list td.dur-col {
    text-align: right; white-space: nowrap; padding-right: 20px;
    color: var(--muted); font-size: 13.5px; font-weight: 300;
}
.price-table td.group-note {
    padding: 2px 0 14px; border-bottom: none;
    font-size: 13.5px; font-weight: 300; color: var(--muted); text-align: left;
    /* white-space matters as much as text-align here, and for the same reason:
       the note spans the row, so it is also td:last-child and inherits that
       rule's `nowrap`. A sentence that cannot wrap stretched the table to 723px
       inside a 331px card on a phone. Both group cells opt back out. */
    white-space: normal;
}
.price-table td.group-row { white-space: normal; }
/* A bookable treatment name. Every price row on every page now deep-links into
   /book-online?service=<slug>, so the name has to read as tappable without
   turning the menu into a wall of blue. Underline in the brand tint, colour
   only on hover. */
.price-table td a,
.price-list td a,
.svc-card li a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--coral-mist); }
.price-table td a:hover,
.price-list td a:hover,
.svc-card li a:hover { color: var(--coral); border-bottom-color: var(--coral); }
/* Group headings inside a price table are page links, not booking links. */
.price-table td.group-row a { color: var(--coral); border-bottom: none; }
.price-list td.group-row a { color: var(--coral); border-bottom: none; }
@media (max-width: 560px) {
    .price-list td.dur-col { padding-right: 10px; font-size: 12.5px; }
}

/* ---------- Why us ---------- */
.why { background: var(--white); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.why-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 34px; }
.svc-icon {
    width: 46px; height: 46px; border-radius: 13px; background: var(--coral-soft);
    display: flex; align-items: center; justify-content: center;
}
.svc-icon svg { width: 23px; height: 23px; stroke: var(--coral); fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.why-item .svc-icon { margin-bottom: 16px; }
.why-item h3 { font-size: 16.5px; font-weight: 600; margin-bottom: 8px; }
.why-item p { font-size: 14px; color: var(--muted); }

/* ---------- Long-form editorial ----------
   The service pages were pure price-and-book. These carry the explanatory
   content, how a treatment works, how to prepare, what happens on the day,
   which is what people actually search for before they are ready to book. */
.prose { max-width: 68ch; }
.prose.center { margin: 0 auto; }
.prose h3 {
    font-size: 20px; font-weight: 600; margin: 34px 0 10px;
}
.prose h3:first-child { margin-top: 0; }
.prose p { font-size: 16px; color: #4A4752; margin-bottom: 16px; }
.prose p:last-child { margin-bottom: 0; }
.prose ul, .prose ol { margin: 0 0 18px 0; padding-left: 0; list-style: none; }
.prose li {
    position: relative; padding-left: 26px; margin-bottom: 10px;
    font-size: 15.5px; color: #4A4752;
}
.prose ul li::before {
    content: ""; position: absolute; left: 6px; top: .62em;
    width: 7px; height: 7px; border-radius: 50%; background: var(--coral-mist);
    border: 1.5px solid var(--coral);
}
.prose ol { counter-reset: prose-step; }
.prose ol li { counter-increment: prose-step; }
.prose ol li::before {
    content: counter(prose-step); position: absolute; left: 0; top: .1em;
    font-family: var(--font-display); font-size: 12px; font-weight: 600; color: var(--coral);
    width: 19px; height: 19px; border-radius: 50%; background: var(--coral-soft);
    display: flex; align-items: center; justify-content: center;
}
.prose a { color: var(--coral-dark); font-weight: 400; text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.prose a:hover { color: var(--ink); }
.prose strong { font-weight: 500; color: var(--ink); }

/* Two-column editorial: text beside a supporting card. */
.editorial { display: grid; grid-template-columns: 1.15fr .85fr; gap: 52px; align-items: start; }

/* ---------- At-a-glance fact strip ----------
   Price, duration and how long it lasts, above the fold on a treatment page.
   These are the three things every "how much is X" searcher wants first. */
.glance {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1px; background: var(--line); border: 1px solid var(--line);
    border-radius: var(--radius); overflow: hidden; margin: 0 0 8px;
}
.glance div { background: var(--white); padding: 18px 20px; }
.glance dt {
    font-family: var(--font-display); font-size: 11px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px;
}
.glance dd { font-family: var(--font-display); font-size: 19px; font-weight: 600; color: var(--ink); }
.glance dd .unit { font-family: var(--font-body); font-size: 13px; font-weight: 300; color: var(--muted); display: block; }

/* A single fact sitting inside another card, so it drops the box of its own.
   Note .glance is a <dl>: dt and dd are only valid inside one, and HTML5 allows
   the <div> wrapper that groups each term with its definition. */
.glance-bare { border: none; background: transparent; border-radius: 0; margin-bottom: 2px; }
.glance-bare div { padding: 0 0 16px; }

/* ---------- Credentials list ---------- */
.creds { list-style: none; }
.creds li {
    position: relative; padding-left: 24px; margin-bottom: 11px;
    font-size: 14.5px; color: #4A4752;
}
.creds li:last-child { margin-bottom: 0; }
.creds li::before {
    content: ""; position: absolute; left: 4px; top: .6em;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--coral-mist); border: 1.5px solid var(--coral);
}
.card > h3 { font-size: 16px; font-weight: 600; margin: 18px 0 12px; }
.card > h3:first-child { margin-top: 0; }

/* ---------- Step-by-step ("what happens on the day") ---------- */
.steps { display: grid; gap: 18px; counter-reset: step; max-width: 760px; }
.step {
    display: grid; grid-template-columns: 42px 1fr; gap: 18px; align-items: start;
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 22px 24px; box-shadow: var(--shadow-sm);
}
.step::before {
    counter-increment: step; content: counter(step);
    font-family: var(--font-display); font-weight: 600; font-size: 15px; color: var(--coral);
    width: 34px; height: 34px; border-radius: 50%; background: var(--coral-soft);
    display: flex; align-items: center; justify-content: center;
}
.step h3 { font-size: 16.5px; font-weight: 600; margin-bottom: 5px; }
.step p { font-size: 14.5px; color: #4A4752; }

/* ---------- Before / after care ---------- */
.care-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; }
.care { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 28px; box-shadow: var(--shadow-sm); }
.care h3 { font-size: 17px; font-weight: 600; margin-bottom: 14px; display: flex; align-items: center; gap: 10px; }
.care h3 .svc-icon { width: 34px; height: 34px; border-radius: 10px; flex: none; }
.care h3 .svc-icon svg { width: 18px; height: 18px; }
.care ul { list-style: none; }
.care li {
    position: relative; padding-left: 24px; margin-bottom: 11px;
    font-size: 14.5px; color: #4A4752;
}
.care li:last-child { margin-bottom: 0; }
.care li::before {
    content: ""; position: absolute; left: 4px; top: .6em;
    width: 7px; height: 7px; border-radius: 50%; background: var(--coral-mist); border: 1.5px solid var(--coral);
}
.care.dont li::before { background: transparent; border-color: var(--muted); }

/* ---------- Callout ---------- */
.callout {
    border-left: 3px solid var(--coral); background: var(--coral-soft);
    border-radius: 0 var(--radius) var(--radius) 0; padding: 22px 26px; margin: 26px 0;
    max-width: 68ch;
}
.callout h3 { font-size: 16px; font-weight: 600; margin-bottom: 7px; }
.callout p { font-size: 14.5px; color: #4A4752; margin-bottom: 10px; }
.callout p:last-child { margin-bottom: 0; }

/* ---------- Comparison table ---------- */
.compare-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--white); box-shadow: var(--shadow-sm); }
.compare { width: 100%; border-collapse: collapse; font-size: 14.5px; min-width: 520px; }
.compare th, .compare td { padding: 14px 20px; text-align: left; border-bottom: 1px solid var(--line); vertical-align: top; }
.compare thead th {
    font-family: var(--font-display); font-size: 11.5px; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase; color: var(--muted); background: var(--cream);
}
.compare tbody th { font-weight: 500; color: var(--ink); font-family: var(--font-body); }
.compare tr:last-child th, .compare tr:last-child td { border-bottom: none; }
.compare td { color: #4A4752; }

/* ---------- FAQ ---------- */
.faq-list { max-width: 760px; margin: 0 auto; display: grid; gap: 14px; }
.faq-item {
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 4px 24px; box-shadow: var(--shadow-sm);
}
.faq-item summary {
    cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 14px;
    font-family: var(--font-display); font-weight: 600; font-size: 15.5px; padding: 16px 0;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
    content: "+"; font-size: 22px; color: var(--coral); font-weight: 500; flex: none;
    transition: transform .2s ease;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item p { font-size: 14.5px; color: #4A4752; padding-bottom: 18px; }
.faq-item p + p { padding-bottom: 18px; margin-top: -8px; }
.faq-item a { color: var(--coral-dark); font-weight: 400; }

/* ---------- Reviews ----------
   Stars always belong to a quoted, named person, never floating on their own,
   so the page can never imply a rating it has not substantiated. Each card
   shows the number of stars that reviewer actually gave, which is why a four
   star review renders four. Deliberately no Review or AggregateRating schema:
   Google does not grant review rich results to a business publishing reviews
   about itself, and self-serving review markup risks a manual action. The real
   stars come from the Google Business Profile. */
.review-strip { text-align: center; }
.stars { display: flex; gap: 4px; justify-content: center; margin-bottom: 16px; }
.stars svg { width: 26px; height: 26px; fill: #F2B01E; }
.review-strip h2 { font-size: clamp(22px, 3vw, 30px); font-weight: 700; margin-bottom: 10px; }
.review-strip p { color: var(--muted); margin-bottom: 24px; }
.quote-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
    gap: 20px; margin-bottom: 30px; text-align: left;
}
.quote {
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 26px 24px; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 14px;
}
.quote .stars { justify-content: flex-start; margin: 0; }
.quote .stars svg { width: 17px; height: 17px; }
.quote blockquote { font-size: 15.5px; line-height: 1.7; color: var(--ink); }
.quote figcaption { font-family: var(--font-display); font-weight: 600; font-size: 14px; color: var(--muted); margin-top: auto; }
.quote figcaption span { color: var(--coral); }

/* ---------- Work photos ----------
   Photographs of actual work, which is the one thing a beauty salon page can
   show that a competitor cannot copy in an afternoon.

   Every shot is cropped to a single aspect ratio by object-fit rather than
   trusted to arrive that way, because they won't: one comes off a camera at
   3:2, the next off a phone at 4:3, and a row of mismatched heights reads as
   amateur before anyone has looked at the brows. The ratio is set in CSS as
   well as on the tag so the space is reserved before the file lands and the
   page doesn't jump under a thumb that is already reaching for Book.

   A before/after pair only earns the label when both frames are the same
   person, same distance, same light, on the same day. Two shots that merely
   sit next to each other are the oldest trick in cosmetic advertising and
   customers read it instantly. .shot-pair keeps the two locked to one row so
   a mismatched pair looks as wrong in the editor as it would on the page. */
.work-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; }
.work-grid.shot-pair { grid-template-columns: repeat(2, 1fr); }
.work-grid.shot-one { max-width: 620px; margin: 0 auto; }
.shot {
    margin: 0; position: relative; overflow: hidden;
    background: var(--white); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.shot img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
/* Hold the bottom edge when cropping a 4:3 phone shot into the 3:2 card. The
   subject of a brow photo sits low in the frame and the clutter sits high, so
   a centred crop takes a bite out of the brows and keeps the shelf in the
   background. Cropping from the top costs nothing and saves both. */
.shot img.crop-bottom { object-position: 50% 100%; }
.shot figcaption { padding: 14px 18px 16px; font-size: 14px; line-height: 1.6; color: var(--muted); }
.shot figcaption b { font-family: var(--font-display); font-weight: 600; color: var(--ink); display: block; font-size: 14.5px; }
.shot .tag {
    position: absolute; top: 12px; left: 12px;
    font-family: var(--font-display); font-weight: 600; font-size: 11.5px;
    letter-spacing: .1em; text-transform: uppercase;
    background: rgba(28, 27, 34, .74); color: #fff;
    padding: 5px 12px; border-radius: 999px;
    backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}
/* Tracks --coral. Kept as rgba rather than the token because the badge sits on a
   photograph and needs the slight translucency; .94 rather than .92 so the white
   label still clears 4.5:1 even where the picture underneath is at its lightest. */
.shot .tag.after { background: rgba(189, 69, 47, .94); }
/* The line under a gallery that says whose face this is and that she agreed to
   it being here. Small, but it is the part that keeps the salon out of trouble. */
.work-note { font-size: 13px; color: var(--muted); text-align: center; margin-top: 20px; }

/* ---------- Related pages ---------- */
.related-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 18px; }
.related-card {
    display: block; text-decoration: none; background: var(--white);
    border: 1px solid var(--line); border-radius: var(--radius); padding: 24px;
    box-shadow: var(--shadow-sm);
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.related-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--coral-mist); }
.related-card h3 { font-size: 16.5px; font-weight: 600; margin-bottom: 7px; }
.related-card p { font-size: 14px; color: var(--muted); margin-bottom: 12px; }
.related-card .go { font-family: var(--font-display); font-size: 13.5px; font-weight: 600; color: var(--coral); }

/* ---------- Dark local CTA ---------- */
.local {
    background: linear-gradient(135deg, var(--ink) 0%, #2A2833 100%);
    color: var(--cream); border-radius: 24px; padding: 56px 48px;
    display: flex; align-items: center; justify-content: space-between; gap: 36px;
    position: relative; overflow: hidden;
}
.local::after {
    content: ""; position: absolute; right: -80px; top: -80px; width: 300px; height: 300px;
    background: radial-gradient(circle, rgba(228, 103, 79, .35) 0%, transparent 70%);
}
.local h2 { font-size: clamp(22px, 3vw, 30px); font-weight: 700; margin-bottom: 10px; }
.local p { color: #BDB9C4; max-width: 34em; font-size: 15.5px; }
.local .btn-primary { position: relative; z-index: 1; }
/* Suburb links inside the dark CTA. Was repeated as an inline style on every
   page; the panel is dark, so the body link colour is unreadable here. */
.local a:not(.btn) { color: #fff; text-decoration: underline; text-underline-offset: 2px; }
.local a:not(.btn):hover { color: var(--coral-mist); }

/* The closing CTA sits directly under another section and does not need the
   full section padding above it. */
.section-tight { padding-top: 0; }

/* ---------- Footer ---------- */
footer { background: var(--ink); color: #BDB9C4; padding: 56px 0 28px; font-size: 14px; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 40px; margin-bottom: 40px; }
footer .brand span { color: var(--cream); }
footer p { max-width: 30em; margin-top: 14px; }
/* h3, not h4. Every page ran ...h2, h2, h4, h4, h4 into the footer, which skips a
   level: a screen-reader user tabbing the heading list hears the outline break at
   exactly the point the page hands over to navigation. Nothing else on these pages
   uses h4, so the footer columns become h3 and the outline is continuous.
   line-height is restated because the global "h1, h2, h3" rule sets 1.15 and these
   headings previously inherited the body's 1.65; keeping it holds the footer
   spacing exactly where it was. */
footer h3 { font-family: var(--font-display); color: var(--cream); font-size: 14px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; line-height: 1.65; margin-bottom: 16px; }
footer ul { list-style: none; }
footer ul li { margin-bottom: 10px; }
footer a { color: #BDB9C4; text-decoration: none; transition: color .15s; }
/* --coral-mist, not --coral. The footer is the one dark surface a brand-coloured
   link lands on, and --coral is now dark enough for white grounds, which makes it
   too dark for this one (3.36:1 here). Mist is the same hue family and reads at
   13.5:1. .local a:hover already resolves the same problem the same way. */
footer a:hover { color: var(--coral-mist); }
.foot-bottom {
    border-top: 1px solid #33313D; padding-top: 22px;
    display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 13px; color: #8B8791;
}

/* ---------- Hours, contact and map ----------
   Lived in landing.html's homepage-only <style> until /contact was added and a
   second page needed the same hours card, address rows and map facade. Same
   move the review cards made earlier: once two pages want it, it belongs here. */
.loc-grid { display: grid; grid-template-columns: 1fr 1.15fr; gap: 22px; align-items: stretch; }
.hours-table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.hours-table td { padding: 9px 0; border-bottom: 1px dashed var(--line); }
.hours-table tr:last-child td { border-bottom: none; }
.hours-table td:last-child { text-align: right; font-weight: 500; }
.hours-table .closed { color: var(--muted); }
.card h3 { font-size: 19px; font-weight: 600; margin-bottom: 16px; display: flex; align-items: center; gap: 10px; }
.card h3 svg { width: 20px; height: 20px; stroke: var(--coral); fill: none; stroke-width: 1.8; }
.contact-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; font-size: 15px; }
.contact-row svg { width: 18px; height: 18px; stroke: var(--coral); fill: none; stroke-width: 1.8; flex: none; margin-top: 3px; }
.contact-row a { color: var(--ink); text-decoration: none; font-weight: 400; }
.contact-row a:hover { color: var(--coral); }
.loc-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.map-shell { position: relative; min-height: 320px; height: 100%; }
.map-frame { border: 0; width: 100%; height: 100%; min-height: 320px; border-radius: var(--radius); filter: grayscale(.15); }
.map-facade {
    width: 100%; height: 100%; min-height: 320px; cursor: pointer;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: radial-gradient(340px 200px at 70% 20%, var(--coral-soft) 0%, transparent 70%),
                linear-gradient(160deg, #FFFFFF 0%, #F4F1F0 100%);
    box-shadow: var(--shadow-sm); font-family: var(--font-body); color: var(--ink);
    transition: box-shadow .2s ease, transform .2s ease;
}
.map-facade:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.map-facade svg { width: 44px; height: 44px; stroke: var(--coral); fill: none; stroke-width: 1.6; }
.map-facade b { font-family: var(--font-display); font-weight: 600; font-size: 16px; }
.map-facade span {
    font-size: 13.5px; color: var(--coral); font-weight: 500;
    border: 1.5px solid var(--coral-mist); border-radius: 999px;
    padding: 6px 16px; margin-top: 4px; background: var(--white);
}

/* ---------- Responsive ----------
   The nav collapses at a WIDER breakpoint than the rest of the layout, hence
   its own query. The sitewide nav carries seven links, and measured against the
   1120px wrap that row needs a little over 1000px of viewport before the brand
   and the Book button start squeezing it. Everything else on the page is still
   happy down to 900px, so folding the two queries together would send the whole
   layout to its mobile form 120px early.

   The header holds ONE button for the same reason. A second one ("All Waxing",
   "Staff Login") left the row with 6px of slack at full width, i.e. already
   shrinking the brand; each of them also duplicated a link now sitting in the
   nav itself. Before adding another, measure.

   Measured again when the home page gained its "Staff login" text link, which
   is what moved this query from 1020px to 1100px. At 1021px the eight-link row
   had 63px of slack and the link wants 84px, so it shrank the brand: the logo
   came down to 37px and the name started clipping. At 1101px the same row
   leaves 16px between the last link and the Book button with nothing squeezed.
   A text link is far cheaper than a button (84px against roughly 130px), which
   is why this one fits where "Staff Login" as a button did not. The 80px of
   viewport handed to the hamburger buys a header that holds together. */
@media (max-width: 1100px) {
    .nav-links { display: none; }
    .menu-btn { display: block; }
    .nav-links.open {
        display: flex; flex-direction: column; gap: 4px;
        position: absolute; top: 72px; left: 0; right: 0;
        background: var(--white); border-bottom: 1px solid var(--line);
        padding: 12px 22px 18px; box-shadow: var(--shadow-md);
        max-height: calc(100vh - 72px); overflow-y: auto;
    }
    .nav-links.open a { padding: 10px 0; font-size: 16px; }
    .nav-links.open .mobile-only { display: block; }
}
@media (max-width: 900px) {
    .hero-grid { grid-template-columns: 1fr; gap: 40px; }
    .hero { padding: 48px 0 64px; }
    .hero-art { min-height: 340px; }
    .why-grid { grid-template-columns: 1fr; gap: 26px; }
    .editorial { grid-template-columns: 1fr; gap: 34px; }
    /* A grid item will not shrink below its own content unless it is told it
       may, and this column holds the 520px comparison table. Without this the
       single column stays 520px wide on a phone, which widens the whole page
       past the screen and takes the fixed bottom action bar out with it. Zero
       here lets .compare-wrap scroll the table sideways, which is what it was
       built to do. Kept out of the desktop rule so the wider two-column layout
       still shows the table in full. */
    .editorial > * { min-width: 0; }
    .care-grid { grid-template-columns: 1fr; }
    .local { flex-direction: column; align-items: flex-start; padding: 40px 30px; }
    .foot-grid { grid-template-columns: 1fr 1fr; }
    .loc-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
    .foot-grid { grid-template-columns: 1fr; gap: 30px; }
    .hero h1 { font-size: 32px; }
    .btn-lg { width: 100%; }
    .hero-actions { flex-direction: column; }
    section { padding: 56px 0; }
    .step { grid-template-columns: 30px 1fr; gap: 14px; padding: 20px; }
    .step::before { width: 26px; height: 26px; font-size: 13px; }
    /* Two brow shots side by side on a 375px screen give each one about 160px,
       which is below what it takes to see the shape the photo exists to show.
       Stacked and full width they still read as a pair, because the Before and
       After tags are on the images rather than under them. */
    .work-grid.shot-pair { grid-template-columns: 1fr; }
}

/* ---------- Sticky mobile action bar + accessibility ---------- */
.action-bar { display: none; }
.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--coral); color: #fff; padding: 12px 20px; border-radius: 0 0 10px 0;
    font-family: var(--font-display); font-weight: 600;
}
.skip-link:focus { left: 0; }
:focus-visible { outline: 3px solid var(--coral); outline-offset: 3px; border-radius: 4px; }

/* Visible to screen readers only, used for table captions that would be
   redundant next to an adjacent heading but that a screen reader still needs
   in order to announce what the table contains. */
.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;
}

@media (max-width: 780px) {
    .action-bar {
        display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
        padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
        background: rgba(250, 250, 250, .94);
        backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
        border-top: 1px solid var(--line);
    }
    .action-bar .btn { width: 100%; min-height: 52px; font-size: 15.5px; }
    body { padding-bottom: 84px; }

    /* Book + Call live in the bottom bar on phones, so the header CTA is
       redundant and was wrapping the brand name onto three lines. */
    .nav-cta .btn-primary { display: none; }
    .brand span { font-size: 15.5px; white-space: nowrap; }
    .brand img { width: 34px; height: 34px; }
}

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

/* ---------------------------------------------------------------------------
   Price list by text

   The one place on the site that captures anything from a visitor who isn't
   booking today. Deliberately below the reviews: by then they have read the
   prices and the testimonials, so the ask lands on someone who is interested
   but hesitating, not on someone who just arrived.
   --------------------------------------------------------------------------- */
.lead-strip { padding-top: 10px; }

.lead-card {
    display: grid;
    grid-template-columns: 1fr;
    gap: 26px;
    background: var(--coral-soft);
    border: 1px solid var(--coral-mist);
    border-radius: calc(var(--radius) + 4px);
    padding: 34px 26px;
}
@media (min-width: 860px) {
    .lead-card { grid-template-columns: 1.1fr 1fr; align-items: center; gap: 44px; padding: 40px; }
}

.lead-copy h2 { font-size: clamp(22px, 3vw, 30px); font-weight: 700; margin: 10px 0; }
.lead-copy p { color: var(--muted); font-size: 15.5px; }

.lead-form { display: flex; flex-wrap: wrap; gap: 10px; }
.lead-form input[type="tel"] {
    flex: 1 1 190px;
    min-width: 0;
    font: inherit;
    font-size: 16px;              /* 16px or iOS zooms the page on focus */
    padding: 14px 16px;
    border: 1px solid var(--coral-mist);
    border-radius: 12px;
    background: var(--white);
    color: var(--ink);
}
.lead-form input[type="tel"]::placeholder { color: #B9B4BE; }
.lead-form input[type="tel"]:focus-visible {
    outline: 2px solid var(--coral);
    outline-offset: 1px;
    border-color: transparent;
}
.lead-form button { flex: 0 0 auto; }
.lead-form button[disabled] { opacity: .65; cursor: default; transform: none; box-shadow: none; }

/* Both messages occupy the same row, so the card doesn't jump when one appears. */
.lead-status { flex: 1 0 100%; font-size: 14px; margin: 0; min-height: 1.2em; }
.lead-ok { color: #2E7D6B; }
.lead-err { color: var(--coral-dark); }

.lead-fine { flex: 1 0 100%; font-size: 12.5px; color: var(--muted); margin: 0; }
.lead-fine a { color: var(--coral-dark); text-decoration: underline; }

/* ---------- Tap targets ----------------------------------------------------
   WCAG 2.2 SC 2.5.8 Target Size (Minimum) is 24x24 CSS px at level AA. The
   often-quoted 44px is SC 2.5.5, which is AAA and would mean a materially
   taller footer and price table; 24 is the bar that actually applies.

   Measured at a 375px viewport before this block, the links below came in at
   15-21px: the footer navigation, every row of the price tables, the "see all
   prices" links out of the service cards and FAQ answers, and the breadcrumbs.
   Those are not incidental links, they are how someone moves from a service
   page to the price list on a phone.

   VERTICAL PADDING ON AN INLINE ELEMENT is the tool here, deliberately. Padding
   on an inline box does not grow the line box, so none of this moves the layout
   by a pixel, but it does enlarge the hit rectangle the browser tests against.
   Adjacent stacked links end up touching rather than overlapping, which SC 2.5.8
   allows.

   Anything genuinely inline in a sentence is exempt under the "inline" exception
   and is left alone. */

.svc-more a,
.faq-a a,
.foot-bottom a { padding: 5px 0; }

footer ul li a,
.svc-card ul li a,
.compare td a,
.compare th a { padding: 4px 0; }

.price-table td a,
.price-list td a,
.prose ul li a { padding: 4px 0; }

.crumbs a { padding: 2px 0; }

/* The logo lockup is a real 34px tall link but only because the mark inside it
   is 40px; give it the same floor as everything else so it cannot regress. */
.brand { min-height: 24px; }

/* The deck between the hero headline and the lead paragraph.
   Several H1s are deliberately written as a line rather than a keyword, "The one
   that actually shifts things" on /hydra-facial being the clearest case. That is
   the right call for the reader and the wrong one for a crawler, which reads the
   H1 as the page's strongest on-page signal. The deck resolves it: the headline
   keeps its voice, and the treatment and suburb land in the heading directly
   under it. */
.hero-sub {
    font-family: var(--font-display);
    font-size: clamp(17px, 2.2vw, 20px);
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: -.01em;
    color: var(--ink);
    max-width: 26em;
    /* Pulls up against the h1's 20px bottom margin so the deck reads as part of
       the headline block rather than as a floating third element. */
    margin: -6px 0 18px;
}

/* ---------- Bottom sheet (Components/Shared/BottomSheet.razor) ----------
   Same treatment as the appointment sheet, so an edit form and an appointment
   read as the same kind of thing. Capped at 85vh and scrolled internally, or a
   long form on a short phone would push its own Save button off-screen. */
.bs-sheet-scrim {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .45);
    z-index: 1400;
}
.bs-sheet {
    /* Set explicitly rather than inherited from MudBlazor's .mud-paper. The panel
       sits over a 45% scrim, so a transparent background is not a cosmetic slip,
       it makes the form unreadable. Too important to depend on another library's
       internal class staying as it is. */
    background: var(--white, #FFFFFF);
    color: var(--ink, #1C1B22);
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1500;
    border-radius: 20px 20px 0 0;
    max-height: 85vh;
    overflow-y: auto;
    /* Clear the iPhone home bar; without it the last control sits under it. */
    padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)) !important;
}
.bs-sheet:focus { outline: none; }
.bs-sheet:focus-visible { outline: 3px solid var(--coral); outline-offset: -3px; }

/* Wide screens do not need a full-bleed sheet; centre it and cap the measure. */
@media (min-width: 720px) {
    .bs-sheet {
        left: 50%;
        right: auto;
        transform: translateX(-50%);
        width: min(560px, 92vw);
        border-radius: 20px 20px 0 0;
    }
}

/* A recurring break on the day timeline (0030). Striped rather than solid, and
   deliberately not the booking colour: it is time that is spoken for, not money
   coming in, and the two should never be miscounted at a glance. */
.bs-timeline-block--break {
    background: repeating-linear-gradient(
        45deg,
        var(--bs-break-stripe, rgba(120, 120, 120, .28)) 0 4px,
        transparent 4px 8px);
    border: 1px dashed var(--bs-break-edge, rgba(120, 120, 120, .5));
    box-sizing: border-box;
}
