@charset "UTF-8";
/* ============================================================================
   Restored Reflections — one stylesheet, mobile-first.

   ⚠ THE PALETTE IS GENEVIEVE'S OWN, SPECIFIED BY HER 2026-09-08.
   She sent three brand colors: #72966E (green), #053E4A (deep teal), #CAA7BC (mauve).
   They are used EXACTLY where contrast allows and only lightness-shifted where it does
   not — hue and saturation are never altered, so every value on this page is hers.

     --navy  #053E4A  her deep teal, exact   10.56:1 on --bg
     --blush #CAA7BC  her mauve, exact        1.94:1  DECORATIVE ONLY
     --green #72966E  her green, exact        3.01:1  DECORATIVE / large only
     --teal  #587555  her green darkened ONLY enough to carry small text (4.63:1)
     --ink / --muted / --navy-panel  derived from her deep teal

   ⚠ Her green at its true value CANNOT be text: 3.01:1 fails the 4.5:1 body minimum.
   That is why --green and --teal are two tokens. Never put --green on type.

   THE PREVIOUS PALETTE WAS SAMPLED FROM HER OLD LOGO.
   Her mark is a navy phoenix rising over a blush lotus whose stem is a tattoo
   needle, on a cream ground. Every value below was pulled off that file with
   Pillow and then contrast-checked. The numbers in the comments are computed,
   not estimated.

   ⚠ --blush is DECORATIVE ONLY. Against the cream page it measures 2.01:1,
   which fails AA for text (needs 4.5:1) and fails even the 3:1 floor for
   meaningful UI. It may tint a panel or draw a rule that carries no meaning.
   It may never be text, a border that communicates state, or an icon a person
   has to read. That is the same trap a brand orange usually sets, and it is
   easier to fall into on a beauty-adjacent site than almost anywhere else.

   ⚠ --bg is the logo's OWN ground color. That is deliberate: her logo is a
   raster with cream baked in, and matching the page to it means the mark sits
   on the page with no halo and no keying-out of a background that would have
   damaged the fine navy linework.

   This site serves two people who arrive in completely different states of
   mind: a woman choosing a beauty service, and a woman finishing breast
   reconstruction. The design answer is calm, warm and unhurried — never
   clinical (which frightens the first) and never frothy (which insults the
   second). Generous line-height, long measure, no motion that travels.
   ========================================================================= */

:root {
  /* ── color ─────────────────────────────────────────────────────────── */
  --bg:            #F5F3EF;   /* unchanged — her logo's own ground */
  --surface:       #FFFFFF;
  --surface-alt:   #EEEBE5;
  --blush-tint:    #F3E9EE;   /* panel wash only — from her mauve */
  --navy-panel:    #032B34;   /* from her deep teal */
  --ink:           #04343F;   /* 12.08:1 on --bg — from her deep teal */
  --muted:         #075565;   /*  7.59:1 on --bg — from her deep teal, quieter than --ink */
  --navy:          #053E4A;   /* 10.56:1 — GENEVIEVE'S DEEP TEAL, exact */
  --teal:          #587555;   /*  4.63:1 — her green, darkened only enough to carry small text.
                                 ⚠ Her exact green #72966E is 3.01:1 and CANNOT be text; it is
                                 --green below and is used for rules, borders and decoration. */
  --green:         #72966E;   /*  3.01:1 — GENEVIEVE'S GREEN, exact. DECORATIVE / large only. */
  --blush:         #CAA7BC;   /*  1.94:1 — GENEVIEVE'S MAUVE, exact. DECORATIVE ONLY, never text */
  --border:        #DCD7CE;
  --on-navy:       #FFFFFF;   /* 11.70:1 on --navy */
  --blush-on-navy: #D3B5C7;   /*  8.01:1 on --navy-panel — her mauve, lightened to read */

  /* ── type ───────────────────────────────────────────────────────────── */
  --font-display: "Libre Bodoni", Georgia, "Times New Roman", serif;
  --font-text:    "Karla", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-script:  "Sacramento", "Brush Script MT", cursive;

  /* A modular scale that stays readable at 375px. Body never below 16px. */
  --t-xs:   0.8125rem;
  --t-sm:   0.9375rem;
  --t-base: 1.0625rem;
  --t-lg:   1.1875rem;
  --t-xl:   1.375rem;
  --t-2xl:  1.75rem;
  --t-3xl:  2.125rem;
  --t-4xl:  2.625rem;

  /* ── space ──────────────────────────────────────────────────────────── */
  --s-1: 0.25rem; --s-2: 0.5rem;  --s-3: 0.75rem; --s-4: 1rem;
  --s-5: 1.5rem;  --s-6: 2rem;    --s-7: 3rem;    --s-8: 4rem;  --s-9: 6rem;

  --wrap: 68rem;
  --measure: 38rem;          /* long-form text never runs wider than this */
  --radius: 10px;
  --radius-lg: 18px;
  /* Layered, not single: a tight contact shadow + a soft ambient one is what
     reads as an object sitting ABOVE the page rather than a box with a smudge. */
  --shadow: 0 1px 2px rgba(22, 40, 63, .08), 0 8px 24px rgba(22, 40, 63, .08);
  --shadow-lift: 0 2px 4px rgba(22, 40, 63, .10), 0 18px 44px rgba(22, 40, 63, .16);
  --edge-light: inset 0 1px 0 rgba(255, 255, 255, .55);
  /* Paper tooth: a tiled 160px SVG turbulence at ~4% alpha. It is a texture the
     eye reads as material, not a pattern it reads as noise. The CSP already
     allows img-src data: — verified in .htaccess before this shipped. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.045'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (min-width: 48rem) {
  :root {
    --t-2xl: 2rem; --t-3xl: 2.625rem; --t-4xl: 3.5rem;
  }
}

/* ── reset ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background-color: var(--bg);
  background-image: var(--grain);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--t-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  /* room for the phone action bar so it never covers the last line of a page */
  padding-bottom: env(safe-area-inset-bottom);
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--navy); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--teal); }
::selection { background: var(--navy); color: #FBF8F3; }
:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; border-radius: 4px; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -0.01em;
  margin: 0 0 var(--s-4);
  text-wrap: balance;
}
h1 { font-size: var(--t-4xl); }
h2 { font-size: var(--t-3xl); margin-top: var(--s-8); }
h3 { font-size: var(--t-xl); margin-top: var(--s-6); }
p, ul, ol { margin: 0 0 var(--s-4); }
p { max-width: var(--measure); text-wrap: pretty; }
ul, ol { max-width: var(--measure); padding-left: 1.25rem; }
li { margin-bottom: var(--s-2); text-wrap: pretty; }
strong { font-weight: 700; }
hr { border: 0; height: 1px; margin: var(--s-7) 0;
     background: linear-gradient(90deg, transparent, var(--border) 12%, var(--border) 88%, transparent); }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--s-4); }
@media (min-width: 48rem) { .wrap { padding-inline: var(--s-6); } }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--navy); color: var(--on-navy);
  padding: var(--s-3) var(--s-4); border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; }

/* ── buttons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-2);
  min-height: 48px;                    /* factory floor; satisfies the 44px AA target */
  padding: var(--s-3) var(--s-5);
  border-radius: 999px;
  font-family: var(--font-text);
  font-size: var(--t-base);
  font-weight: 700;
  text-decoration: none;
  border: 2px solid transparent;
  cursor: pointer;
  text-align: center;          /* if a label ever does wrap, it wraps centered */
  transition: background-color .18s ease, color .18s ease, border-color .18s ease,
              transform .18s ease, box-shadow .18s ease;
}
.btn-primary {
  background: linear-gradient(180deg, #234a7c 0%, var(--navy) 55%, #142e50 100%);
  color: var(--on-navy);
  box-shadow: 0 1px 2px rgba(22, 40, 63, .25), 0 6px 16px rgba(24, 56, 96, .28),
              inset 0 1px 0 rgba(255, 255, 255, .18);
}
.btn-primary:hover, .btn-primary:focus-visible {
  background: linear-gradient(180deg, #2e6a68 0%, var(--teal) 55%, #1c4342 100%);
  color: var(--on-navy);
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(22, 40, 63, .25), 0 10px 24px rgba(24, 56, 96, .32),
              inset 0 1px 0 rgba(255, 255, 255, .18);
}
.btn-primary:active {
  transform: translateY(1px);
  box-shadow: 0 1px 2px rgba(22, 40, 63, .28), inset 0 2px 6px rgba(10, 22, 38, .35);
}
.btn-ghost:active { transform: translateY(1px); }
.btn-ghost { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn-ghost:hover, .btn-ghost:focus-visible {
  background: var(--navy); color: var(--on-navy);
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(24, 56, 96, .25);
}
.btn-lg { font-size: var(--t-lg); padding: var(--s-4) var(--s-6); }

.cta-note {
  font-size: var(--t-sm); color: var(--muted);
  max-width: 34rem; margin-top: var(--s-3);
}

/* ── header ────────────────────────────────────────────────────────────── */
.site-header {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .6), 0 6px 18px -8px rgba(22, 40, 63, .14);
  position: relative; z-index: 40;
}
.header-inner {
  display: flex; align-items: center; gap: var(--s-4);
  padding-block: var(--s-3);
  min-height: 68px;                 /* room for the fixed toggle at scroll-top */
  padding-right: 72px;              /* the toggle floats here; keep the brand clear of it */
}
@media (min-width: 72rem) { .header-inner { padding-right: var(--s-6); min-height: 0; } }
.brand { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; color: inherit; margin-right: auto; }
.brand-logo { width: 46px; height: 46px; border-radius: 50%; flex: none;
              box-shadow: 0 0 0 1px var(--border), 0 2px 8px rgba(22, 40, 63, .14); }
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-mark {
  font-family: var(--font-script);
  font-size: 1.6rem;
  color: var(--navy);
  line-height: 1.1;
  white-space: nowrap;      /* the wordmark is a mark, not a sentence — it never wraps */
}
.brand-sub {
  font-size: 0.6875rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
  white-space: nowrap;      /* line 2 is a title, line 3 (the place) is its own block */
}
/* The place-name group wraps as a unit, so the separator never ends a line. */
.brand-place { white-space: nowrap; display: block; }

.header-cta { display: none; }
/* ⚠ NO `display:none` on .site-nav here, deliberately. The panel is visible by
   default and main.js adds [hidden] on init. If it defaulted to hidden, a phone
   with JavaScript off would have a menu button that does nothing and no way to
   reach any page but this one. */

.nav-toggle {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 48px; height: 48px; padding: 0 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 50%;
  cursor: pointer;
}
.nav-toggle-bar { display: block; height: 2px; background: var(--navy); border-radius: 2px; }
.nav-toggle[aria-expanded="true"] { background: var(--navy); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar { background: var(--on-navy); }

/* ── MOBILE NAV — the factory's floating-hamburger standard (07 §D, Variant A) ──
   The header scrolls away normally. The hamburger ALONE goes position:fixed and
   follows the scroll, and the panel opens as a fixed panel anchored beneath it.

   ⚠ THIS IS NOT A STYLE PREFERENCE, IT IS THE FIX FOR A MEASURED DEFECT.
   The first version anchored the panel to the header with position:absolute.
   Scroll down a phone, tap the menu, and the panel opened at the top of the
   DOCUMENT — off screen — with no close control anywhere in the viewport. The
   render gate caught it on this build, and it had caught the identical defect on
   redolocal.com's own nav after a visual pass and two adversarial panels missed
   it. A menu you cannot see and cannot close is worse than no menu.

   The whole header bar must NOT stay fixed on mobile — only the hamburger. */
@media (max-width: 71.999rem) {
  .site-header { position: static; }

  .nav-toggle {
    position: fixed;
    top: 14px; right: 14px;
    z-index: 1002;
    box-shadow: 0 3px 10px rgba(22, 40, 63, .22);
  }

  .site-nav {
    position: fixed;
    top: 74px; right: 14px; left: auto;
    z-index: 1001;
    width: min(78vw, 20rem);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 12px 32px rgba(22, 40, 63, .28);
    padding: var(--s-3) var(--s-4) var(--s-4);
    max-height: calc(100vh - 96px);
    overflow-y: auto;
  }
  .site-nav[hidden] { display: none; }
  .site-nav:not([hidden]) { display: block; }
  .nav-list, .dropdown { list-style: none; margin: 0; padding: 0; max-width: none; }
  .nav-link, .dropdown a {
    display: block; padding: var(--s-3) var(--s-2);
    min-height: 48px; line-height: 1.5;
    text-decoration: none; color: var(--ink); font-weight: 600;
    border-bottom: 1px solid var(--border);
  }
  .dropdown a { font-weight: 400; padding-left: var(--s-5); color: var(--muted); }
  .dropdown a:hover { color: var(--navy); }
  /* the same active marker on the phone panel */
  .nav-link[aria-current="page"], .dropdown a[aria-current="page"] {
    background: var(--blush-tint); border-radius: var(--radius);
    box-shadow: inset 3px 0 0 var(--green); color: var(--navy);
  }
  .caret { display: none; }
  .nav-mobile-cta { display: block; margin-top: var(--s-4); }
  .nav-mobile-cta .btn { width: 100%; }
}

/* desktop nav — a single row, always */
@media (min-width: 72rem) {
  .nav-toggle { display: none; }
  .site-nav { display: block !important; }
  .header-cta { display: inline-flex; white-space: nowrap; flex: none; }
  .nav-list {
    list-style: none; margin: 0; padding: 0; max-width: none;
    display: flex; align-items: center; gap: var(--s-5);
  }
  .nav-item { position: relative; margin: 0; }
  .nav-link {
    display: inline-flex; align-items: center; gap: 6px;
    padding: var(--s-3) 0;
    font-weight: 600; font-size: var(--t-sm);
    letter-spacing: .01em;
    color: var(--ink); text-decoration: none;
    white-space: nowrap;                 /* never let a label stack into two lines */
  }
  .nav-link:hover { color: var(--navy); }
  /* ⚠ ACTIVE-TAB HIGHLIGHT — added 2026-09-08 at Genevieve's request. A tinted pill
     plus a solid underline bar in her green: color alone is never the only signal,
     so it still reads for anyone who cannot distinguish the tint. */
  .nav-link[aria-current="page"] {
    color: var(--navy);
    background: var(--blush-tint);
    border-radius: 999px;
    padding-inline: var(--s-3);
    box-shadow: inset 0 -3px 0 var(--green);
  }
  .caret {
    width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent;
    border-top: 5px solid currentColor; opacity: .7;
  }
  .dropdown {
    position: absolute; top: 100%; left: calc(-1 * var(--s-4));
    min-width: 19rem; max-width: none;
    list-style: none; margin: 0; padding: var(--s-2) 0;
    background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
    opacity: 0; visibility: hidden; transform: translateY(4px);
    transition: opacity .15s ease, transform .15s ease, visibility .15s;
  }
  .nav-item.has-children:hover > .dropdown,
  .nav-item.has-children:focus-within > .dropdown {
    opacity: 1; visibility: visible; transform: translateY(0);
  }
  .dropdown li { margin: 0; }
  .dropdown a {
    display: block; padding: var(--s-2) var(--s-4);
    font-size: var(--t-sm); color: var(--ink); text-decoration: none;
  }
  .dropdown a:hover { background: var(--blush-tint); color: var(--navy); }
  .dropdown a[aria-current="page"] {
    background: var(--blush-tint); color: var(--navy); font-weight: 700;
    box-shadow: inset 3px 0 0 var(--green);
  }
  .dropdown-all { border-top: 1px solid var(--border); margin-top: var(--s-2); padding-top: var(--s-2); }
  .dropdown-all a { font-weight: 700; color: var(--navy); white-space: nowrap; }
  .nav-mobile-cta { display: none; }
}

/* ── sections ──────────────────────────────────────────────────────────── */
.section { padding-block: var(--s-8); }
.section--tight { padding-block: var(--s-7); }
.section--tint { background: var(--surface-alt); }
.section--blush { background: var(--blush-tint); }
/* Colored bands sit INTO the page (inset top highlight + soft inset shadows);
   cards and photographs sit ON it. That opposition is the 3D grammar here. */
.section--tint, .section--blush {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .65),
              inset 0 16px 28px -24px rgba(22, 40, 63, .28),
              inset 0 -16px 28px -26px rgba(22, 40, 63, .16);
}
.section--navy {
  background-color: var(--navy-panel);
  background-image: var(--grain),
                    radial-gradient(120% 90% at 12% -10%, rgba(56, 98, 154, .55) 0%, rgba(56, 98, 154, 0) 55%),
                    linear-gradient(180deg, #1a3a63 0%, var(--navy-panel) 70%);
  color: var(--on-navy);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08),
              inset 0 18px 36px -28px rgba(0, 0, 0, .5);
}
.section--navy h2, .section--navy h3 { color: var(--on-navy); }
.section--navy a { color: var(--blush-on-navy); }
.section--navy .lede, .section--navy p { color: #E6ECF4; }

.section-head { max-width: var(--measure); margin-bottom: var(--s-6); }
/* ⚠ h2 carries margin-top for rhythm WITHIN prose. As the first thing in a
   section it stacked on top of the section's own padding, which is why the
   colored bands measured 131px of space above their heading and 84px below and
   read as sitting low in their own band. */
.section-head h2:first-child, .section-head h3:first-child { margin-top: 0; }
.section > .wrap > h2:first-child { margin-top: 0; }
.kicker {
  font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; color: var(--teal); margin-bottom: var(--s-2);
}
/* ⚠ The decorative dash before every kicker was REMOVED 2026-09-08 at Genevieve's
   request ("too many dashes"). It rendered 20 times across the site. The kicker
   keeps its color and letter-spacing, which is what made it read as a label. */
.section--navy .kicker { color: var(--blush-on-navy); }
.lede { font-size: var(--t-lg); color: var(--muted); max-width: var(--measure); }

/* ── hero ──────────────────────────────────────────────────────────────── */
.hero { padding-block: var(--s-7) var(--s-8); }
@media (max-width: 30rem) {
  /* Measured: at the full display size the headline ran five lines and pushed
     the CTA to 853px on an 844px screen — below the fold on the exact device
     most of this traffic uses. */
  .hero h1 { font-size: 2.25rem; }
  .hero { padding-block: var(--s-5) var(--s-6); }
  .hero-services a { padding: 6px var(--s-3); font-size: var(--t-xs); }
  .hero-services { gap: 6px; margin-bottom: var(--s-4); }
}
.hero-grid { display: grid; gap: var(--s-6); align-items: center; }
@media (min-width: 56rem) {
  .hero-grid { grid-template-columns: 1.05fr .95fr; gap: var(--s-8); }
}
.hero h1 { margin-bottom: var(--s-4); }
.hero .lede { margin-bottom: var(--s-5); }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* ── THE HERO SERVICE ROW ──────────────────────────────────────────────
   Every service she offers, above the fold, tappable. The hero used to name
   only the restorative work in prose, which told a woman looking for brows
   that this business was not for her. These are chips rather than a bullet
   list so they read as a menu at a glance, and each one is a real link so the
   hero doubles as navigation for the two audiences arriving with completely
   different intents. */
.hero-services {
  list-style: none; padding: 0; max-width: none;
  margin: 0 0 var(--s-5);
  display: flex; flex-wrap: wrap; gap: var(--s-2);
}
.hero-services li { margin: 0; }
.hero-services a {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: var(--s-2) var(--s-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: var(--t-sm);
  color: var(--ink);
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(22, 40, 63, .05);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease, color .18s ease;
}
.hero-services a:hover, .hero-services a:focus-visible {
  color: var(--navy);
  border-color: var(--blush);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(22, 40, 63, .12);
}
.hero-services strong { font-weight: 700; }
/* "soon" — small, muted, and unmissable, so nobody taps expecting to book */
.hero-services span {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .08em;
  color: var(--muted); font-weight: 700;
}
@media (prefers-reduced-motion: reduce) { .hero-services a:hover { transform: none; } }
.hero-figure { margin: 0; position: relative; }
/* The blush plate sits offset behind the photograph — a flat second layer is
   the cheapest honest 3D cue there is, and it puts her brand blush to work
   somewhere it never has to pass a contrast check. */
.hero-figure::before {
  content: ""; position: absolute; inset: 14px -14px -14px 14px;
  background: var(--blush-tint);
  border-radius: var(--radius-lg);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6);
  z-index: 0;
}
/* The second plate: a thin navy keyline offset the OTHER way. Three stacked
   layers (keyline, blush plate, photograph) is what reads as depth; two reads
   as a drop shadow. */
.hero-figure::after {
  content: ""; position: absolute; inset: -10px 10px 10px -10px;
  border: 1px solid rgba(24, 56, 96, .22);
  border-radius: var(--radius-lg);
  z-index: 0; pointer-events: none;
}
.hero-figure img {
  position: relative; z-index: 1;
  border-radius: var(--radius-lg);
  box-shadow: 0 3px 8px rgba(22, 40, 63, .14), 0 24px 48px rgba(22, 40, 63, .18);
  /* framed-print keyline just inside the photo edge */
  outline: 1px solid rgba(255, 255, 255, .35);
  outline-offset: -7px;
  width: 100%;
}

/* ── cards ─────────────────────────────────────────────────────────────── */
.cards { display: grid; gap: var(--s-4); list-style: none; padding: 0; max-width: none; }
@media (min-width: 40rem) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 60rem) { .cards--3 { grid-template-columns: repeat(3, 1fr); } }
.card {
  background: linear-gradient(180deg, #FFFFFF 0%, #FDFCFA 100%);
  border: 1px solid var(--border);
  border-top-color: #EAE4DB;          /* lit edge */
  border-bottom-color: #D3C9BC;       /* shaded edge — light falls from above */
  border-radius: var(--radius-lg);
  padding: var(--s-5);
  margin: 0;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow), var(--edge-light);
  transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
.card:hover { transform: translateY(-4px); border-color: #D9C7BE;
              box-shadow: var(--shadow-lift), var(--edge-light); }
.card--soon:hover { transform: none; box-shadow: none; }
.card h3 { margin-top: 0; }
.card p { margin-bottom: var(--s-4); }
.card .card-link { margin-top: auto; font-weight: 700; text-decoration: none;
                   text-wrap: balance; }
.card .card-link:hover { text-decoration: underline; }
.card--soon { border-style: dashed; background: transparent; }
.badge {
  display: inline-block; font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--teal); background: var(--surface-alt);
  border-radius: 999px; padding: 2px 10px; margin-bottom: var(--s-2);
}

/* ── gallery ───────────────────────────────────────────────────────────── */
.gallery { display: grid; gap: var(--s-4); list-style: none; padding: 0; max-width: none; }
@media (min-width: 40rem) { .gallery { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 62rem) { .gallery { grid-template-columns: repeat(3, 1fr); } }
.shot { margin: 0; background: var(--surface); border: 1px solid var(--border);
        border-radius: var(--radius-lg); overflow: hidden;
        display: flex; flex-direction: column;
        box-shadow: var(--shadow);
        transition: transform .22s ease, box-shadow .22s ease; }
.shot:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
/* ⚠ NOT margin-top:auto. Pushing the caption to the bottom of the card made the
   gap ABOVE it depend on how many lines the caption ran to — 45px under a
   one-line caption, 19px under a two-line one, so caption first-lines did not
   line up across a row. Sitting them directly under the image aligns the tops,
   which is the edge a reader's eye actually tracks. */
.shot figcaption { margin-top: 0; }
/* The clipping wrapper the hover morph needs. */
/* ⚠ A FIXED CROP, NOT NATURAL HEIGHTS. Her photographs come in three different
   shapes — a 621x1280 portrait, a 480x639, and a 1280x587 letterbox. Dropped into
   a grid at natural height, the tall one sets the row and the others left a band
   of dead white under their captions. The render gate calls that a "dead or
   sparse band" and it was the most visible defect on the homepage. One ratio,
   center-cropped, makes the row read as a set. */
/* ⚠ TWO TILE SHAPES, AND THE REASON IS THE SUBJECT, NOT THE GRID.
   Her photographs come in two families: near-3:4 portraits of a face, and wide
   ~2.1:1 crops of a brow line. The first attempt forced every tile to one 4:5
   ratio. It made the rows tidy and it CUT BOTH BROW TAILS OFF the panorama and
   ran the brows off the top and bottom of the tall one — on a portfolio, where
   the brows are the entire point. An inspector measured it: the 4:5 tile kept
   only 37% of the panorama.

   That is a worse defect than the dead white band it replaced. So the wide
   photographs get a wide tile at their own ratio and span the full row; the
   portraits share one 4:5 tile, which crops them by about six percent of height
   and touches nothing that matters. Tidy rows are not worth a sliced eyebrow. */
.shot-media { overflow: hidden; aspect-ratio: 4 / 5; position: relative; }
.shot-media::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .30), inset 0 -1px 0 rgba(22, 40, 63, .10);
}
.shot--wide { grid-column: 1 / -1; }
.shot--wide .shot-media { aspect-ratio: 2.06; }
.shot-media img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  transition: transform 1.6s ease;
}
.shot:hover .shot-media img, .shot:focus-within .shot-media img { transform: scale(1.07); }
.shot figcaption { padding: var(--s-3) var(--s-4); font-size: var(--t-sm); color: var(--muted);
                   border-top: 1px solid #F1ECE5; }

/* ⚠ DELIBERATE prefers-reduced-motion OVERRIDE, scoped to image wrappers ONLY.
   The zoom is a slow in-place scale that travels nowhere; without this carve-out
   it silently vanishes for anyone whose OS sets the preference, which is exactly
   how it once shipped looking broken. Nothing else on this site overrides the
   preference — no carousel, no parallax, no motion that crosses the viewport. */
@media (prefers-reduced-motion: reduce) {
  .shot-media img { transition: transform 1.6s ease; }
  .shot:hover .shot-media img, .shot:focus-within .shot-media img { transform: scale(1.07); }
}

/* ── prose helpers ─────────────────────────────────────────────────────── */
.prose { max-width: var(--measure); }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }

/* ⚠ THE SPLIT-ALIGNMENT FIX. When .prose sits ON the .wrap element itself,
   both classes set max-width at equal specificity, .prose wins by source order,
   and `margin-inline: auto` then CENTRES the whole article inside the page.
   Measured result: the hero H1 sat at x=209 and every section beneath it at
   x=448 — the body of the page shunted 239px right of its own headline, with no
   rule or background change to explain it, and a dead left margin running the
   full length of the article. The inspector panel caught it on two pages and on
   /terms, where it stranded the breadcrumb alone in the left column.
   So the wrap keeps owning the page gutter, and the measure applies to the
   children instead — text column constrained, left edge honest. */
.wrap.prose { max-width: var(--wrap); }
.wrap.prose > * { max-width: var(--measure); }

.callout {
  border-left: 4px solid var(--blush);
  border-image: linear-gradient(180deg, var(--blush) 0%, rgba(202, 167, 188, .25) 100%) 1;
  background: linear-gradient(180deg, #FFFFFF 0%, #FDFBF9 100%);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--s-4) var(--s-5);
  margin: var(--s-6) 0;
  max-width: var(--measure);
  box-shadow: var(--shadow);
}
.callout p:last-child { margin-bottom: 0; }
.callout--quiet { border-left-color: var(--border); border-image: none; background: var(--surface-alt); }

.plain-list { list-style: none; padding: 0; }
.plain-list li { padding-left: 1.5rem; position: relative; }
.plain-list li::before {
  content: ""; position: absolute; left: 0; top: .65em;
  width: 7px; height: 7px; border-radius: 50%; background: var(--blush);
}

/* margin-top matches the heading-to-body rhythm everywhere else on the page;
   without it the first number badge tucked under the heading's descenders. */
.steps { list-style: none; counter-reset: step; padding: 0; margin-top: var(--s-5);
         max-width: var(--measure); }
.steps > li { counter-increment: step; position: relative; padding-left: 3rem; margin-bottom: var(--s-5); }
.steps > li::before {
  content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 2rem; height: 2rem; border-radius: 50%;
  background: radial-gradient(circle at 30% 28%, #2d5a94 0%, var(--navy) 62%);
  color: var(--on-navy);
  box-shadow: 0 2px 6px rgba(24, 56, 96, .35), inset 0 1px 0 rgba(255, 255, 255, .22);
  display: grid; place-items: center;
  font-weight: 700; font-size: var(--t-sm);
}
.steps h3 { margin-top: 0; font-size: var(--t-lg); }
/* The path between the numbers: each orb hands off to the next with a fading
   hairline, so the journey reads as one line rather than a stack of items. */
.steps > li:not(:last-child)::after {
  content: ""; position: absolute; left: calc(1rem - 1px);
  top: 2.4rem; bottom: calc(-1 * var(--s-5) + .4rem);
  width: 2px; border-radius: 2px;
  background: linear-gradient(180deg, var(--border) 0%, rgba(222, 214, 204, 0) 100%);
}

/* ⚠ The separator spans the container; only the TEXT is held to the measure.
   Held to the measure itself, every hairline stopped a third of the way across
   the page — eighteen rules in a row each dying mid-air, which reads as a
   half-loaded layout rather than as whitespace. */
.faq-item { border-bottom: 1px solid var(--border); padding-block: var(--s-5); max-width: none; }
.faq-item > * { max-width: var(--measure); }
.faq-item:first-of-type { border-top: 1px solid var(--border); }
.faq-item h3 { margin: 0 0 var(--s-3); font-size: var(--t-lg); }
.faq-item p:last-child { margin-bottom: 0; }

/* A full-width color band with everything crammed into the left third looks
   like a mistake. At desktop the head and the action sit side by side so the
   band is actually occupied; on a phone it stacks as normal. */
.cta-band .btn { margin-top: var(--s-2); }
/* The button and its supporting line are ONE unit. As two siblings in the band's
   second column they became two grid rows, and a tall heading beside them spread
   the pair 174-192px apart — microcopy floating away from the thing it explains. */
.cta-actions { margin: 0; }
.cta-actions p { margin: 0; }
.cta-actions .cta-note { margin-top: var(--s-3); }
@media (min-width: 56rem) {
  .cta-band { display: grid; grid-template-columns: 1.25fr 1fr;
              column-gap: var(--s-7); row-gap: var(--s-3);
              align-items: center; align-content: center;
              grid-auto-rows: min-content; }
  /* ⚠ The heading spans every row. Without this the left column stretched row 1
     and the button's own supporting line, sitting in row 2, was pushed up to
     181px away from the button — reading as detached microcopy belonging to
     nothing. Rows now hug their content and the pair stays together. */
  .cta-band > :not(.section-head) { align-self: center; }
  .cta-band .section-head { margin-bottom: 0; }
  .cta-band > :not(.section-head) { grid-column: 2; margin: 0; }
  .cta-band .cta-note { margin-top: var(--s-3); }
}

/* ── footer ────────────────────────────────────────────────────────────── */
/* ⚠ NO margin-top. It used to be var(--s-9), which painted a 96px strip of the
   pale page background between the last colored band and the footer. Where the
   band above was itself navy, that stripe read as one dark block split in two by
   a rendering fault. Sections already carry their own padding, so the footer
   butts up cleanly without it. */
.site-footer {
  position: relative;
  background-color: var(--navy-panel);
  background-image: var(--grain),
                    radial-gradient(110% 70% at 88% -8%, rgba(56, 98, 154, .40) 0%, rgba(56, 98, 154, 0) 55%),
                    linear-gradient(180deg, #16345A 0%, var(--navy-panel) 40%);
  color: #DCE4EE; padding-top: var(--s-8);
}
/* the jewelry line: a blush thread across the footer's top edge */
.site-footer::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, rgba(202, 167, 188, 0) 0%, var(--blush) 18%,
                                     var(--blush) 82%, rgba(202, 167, 188, 0) 100%);
  opacity: .75;
}
.site-footer a { color: #FFFFFF; text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }
.footer-grid { display: grid; gap: var(--s-6); }
@media (min-width: 40rem) { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 60rem) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
.footer-brand { font-family: var(--font-script); font-size: 1.75rem; color: #FFFFFF; margin: 0 0 var(--s-2); }
.footer-head { font-size: var(--t-xs); letter-spacing: .12em; text-transform: uppercase;
               font-weight: 700; color: var(--blush-on-navy); margin: 0 0 var(--s-3); }
.footer-note { font-size: var(--t-sm); color: #C8D3E1; max-width: 22rem; }
.footer-list { list-style: none; padding: 0; margin: 0; font-size: var(--t-sm); }
.footer-list li { margin-bottom: var(--s-2); text-wrap: pretty; }
.footer-social {
  list-style: none; display: flex; gap: var(--s-3);
  padding: 0; margin: var(--s-4) 0 0; max-width: none;
}
.footer-social li { margin: 0; }
.footer-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  color: #FFFFFF; border: 1px solid rgba(255, 255, 255, .28);
  transition: background-color .18s ease, border-color .18s ease, color .18s ease, transform .18s ease;
}
.footer-social a:hover, .footer-social a:focus-visible {
  color: var(--blush-on-navy); border-color: var(--blush-on-navy);
  background: rgba(255, 255, 255, .08);
  transform: translateY(-1px); text-decoration: none;
}
@media (prefers-reduced-motion: reduce) { .footer-social a:hover { transform: none; } }

.footer-base {
  border-top: 1px solid rgba(255,255,255,.16);
  margin-top: var(--s-7); padding-block: var(--s-5) var(--s-6);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5);
  justify-content: space-between; align-items: baseline;
}
.footer-areas, .footer-legal { font-size: var(--t-sm); color: #C8D3E1; margin: 0; max-width: 40rem; }

/* ── the phone action bar ──────────────────────────────────────────────── */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; gap: var(--s-2);
  padding: var(--s-2) var(--s-3) calc(var(--s-2) + env(safe-area-inset-bottom));
  align-items: stretch;        /* both pills the same height, whatever the label */
  background: rgba(245, 243, 239, .97);
  border-top: 1px solid var(--border);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 -6px 20px rgba(22, 40, 63, .12);
  backdrop-filter: blur(6px);
}
.sticky-btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; border-radius: 999px;
  font-weight: 700; font-size: var(--t-sm); text-decoration: none;
  padding-inline: var(--s-3); text-align: center;
}
.sticky-primary {
  background: linear-gradient(180deg, #234a7c 0%, var(--navy) 55%, #142e50 100%);
  color: var(--on-navy); flex: 1.7;
  box-shadow: 0 1px 2px rgba(22, 40, 63, .25), inset 0 1px 0 rgba(255, 255, 255, .18);
}
.sticky-ghost { background: transparent; color: var(--navy); border: 2px solid var(--navy); flex: 1; }
@media (min-width: 72rem) { .sticky-cta { display: none; } }
@media (max-width: 71.999rem) { body { padding-bottom: 5.25rem; } }

/* ── utility ───────────────────────────────────────────────────────────── */
.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;
}
.breadcrumbs { font-size: var(--t-sm); color: var(--muted); padding-top: var(--s-5); }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s-2); padding: 0; margin: 0; max-width: none; }
.breadcrumbs li { margin: 0; }
/* ⚠ ::after on the PRECEDING crumb, not ::before on the following one.
   As a ::before the separator wrapped with its own crumb and landed
   flush-left at the start of line two, reading as a stray bullet under
   "Home". A separator belongs at the end of the line it breaks. */
.breadcrumbs li:not(:last-child)::after { content: " ›"; margin-left: var(--s-2); color: var(--muted); }

/* Depth without motion for reduced-motion users: the shadows stay (they are
   static), the hover lifts stop travelling. The gallery image zoom keeps its
   documented carve-out above; nothing else moves. */
@media (prefers-reduced-motion: reduce) {
  .card, .shot, .btn { transition-property: background-color, color, border-color, box-shadow; }
  .card:hover, .shot:hover, .btn-primary:hover, .btn-ghost:hover { transform: none; }
}
