/* Hallmark · genre: atmospheric surface on an editorial voice (house-style.md §3.7)
 * macrostructure: inherited — ELEVATION pass. The draft owns section order, words,
 *                 facts and the one action. Not a claim on this site moved.
 * theme: custom (tuned) · axes: light paper / classical-serif (Caudex) / warm-blush h~24
 * nav: N12 banner + retracting bar · footer: Ft5 statement
 * enrichment: none generated — their own photographs, graded in CSS
 * contrast: pass (40–41) · mobile: pass (34, 49, 50–57) · tokens: pass (48)
 * pre-emit critique: P5 H5 E5 S5 R4 V5
 *
 * Every colour, face and radius is a token from css/tokens.css, which carries the
 * brand.json roles verbatim and marks every derived value with the ray it moved along.
 * ========================================================================= */

/* ============================================================================
   Reset / base
   ========================================================================= */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scrollbar-gutter: stable;
  overflow-x: clip;                 /* gate 34 — clip, never hidden: it preserves */
}                                   /* position:sticky and :fixed on descendants  */

body {
  margin: 0;
  overflow-x: clip;
  background: var(--surface-field);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-style: normal;               /* gate 38a — headers are roman, always */
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: 0.01em;
  margin: 0 0 0.5em;
  text-wrap: balance;
  overflow-wrap: anywhere;          /* gate 51 */
  min-width: 0;
}

h1 { font-size: clamp(2rem, 5.2vw, 3.1rem); line-height: 1.08; }
h2 { font-size: clamp(1.6rem, 3.6vw, 2.3rem); }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem); }
h4 { font-size: var(--text-base); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition: text-decoration-color var(--dur-micro) var(--ease-out),
              color var(--dur-micro) var(--ease-out);
}
a:hover { text-decoration-thickness: 2px; }

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

ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
li { margin-bottom: 0.35em; }

/* Focus is carried by their ink, not by the recorded Wix blue — #439FF0 measures
   2.82:1 on their paper and fails the 3:1 focus-indicator floor (gate 40). */
:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
  border-radius: var(--r-xs);
  transition: none;                 /* gate 15 — a focus ring never fades in */
}

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

.skip-link {
  position: fixed; left: var(--space-2xs); top: -80px;
  z-index: calc(var(--z-intro) + 1);
  background: var(--ink); color: var(--paper);
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-button);
  font-weight: 700; text-decoration: none;
  box-shadow: var(--shadow-lift);
}
.skip-link:focus { top: var(--space-2xs); }

/* ============================================================================
   The field beneath — house-style.md §3.3, light recipe.
   Their paper as the ground, three ambient orbs in their blush and the observed
   grey. Glass needs something to float over; a pane on a flat colour is a box.
   ========================================================================= */

.page-field {
  position: fixed;
  inset: 0;
  z-index: var(--z-field);
  pointer-events: none;
  overflow: hidden;
  background:
    radial-gradient(58rem 40rem at 84% -6%, var(--surface-warm) 0%, transparent 62%),
    radial-gradient(46rem 34rem at -8% 24%, var(--surface-warm-2) 0%, transparent 58%),
    var(--surface-field);
}
.page-field span {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(6px);
  will-change: transform;
}
.page-field span:nth-child(1) {
  width: 44rem; height: 44rem; top: -14rem; right: -12rem;
  background: radial-gradient(circle, var(--surface-band) 0%, transparent 68%);
  opacity: 0.72;
  animation: drift-a 22s var(--ease-in-out) infinite alternate;
}
.page-field span:nth-child(2) {
  width: 34rem; height: 34rem; top: 42%; left: -13rem;
  background: radial-gradient(circle, var(--surface-warm-2) 0%, transparent 66%);
  opacity: 0.78;
  animation: drift-b 18s var(--ease-in-out) infinite alternate;
}
.page-field span:nth-child(3) {
  width: 30rem; height: 30rem; bottom: 6%; right: -8rem;
  background: radial-gradient(circle, var(--surface-well) 0%, transparent 70%);
  opacity: 0.30;
  animation: drift-c 26s var(--ease-in-out) infinite alternate;
}
@keyframes drift-a { to { transform: translate3d(-3.5rem, 2.5rem, 0); } }
@keyframes drift-b { to { transform: translate3d(2.5rem, -3rem, 0); } }
@keyframes drift-c { to { transform: translate3d(-2rem, -2rem, 0); } }

/* Everything above the field */
.notice, .site-header, main, .site-footer { position: relative; z-index: var(--z-raised); }

/* ============================================================================
   Intro — house-style.md §3.4. Their own mark on their own graded photograph,
   holding the viewport for a beat, then settling back.

   It clears itself by CSS animation alone. If the script never runs, or dies
   mid-flight, the page still unblocks — an intro that can trap a grieving family
   behind a curtain is a broken build, not a flourish.
   ========================================================================= */

.intro { display: none; }
html.js .intro {
  display: block;
  position: fixed;
  inset: 0;
  z-index: var(--z-intro);
  animation: intro-out 1100ms var(--ease-out) 420ms forwards;
}
/* The plate carries a real <img>, not a background-image: a url() inside this
   stylesheet resolves against css/, not against the document, and the plate ships
   silently empty. */
.intro__plate {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--surface-well);
}
.intro__plate img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--grade-field);
}
.intro__plate::after {
  content: "";
  position: absolute; inset: 0;
  /* one extra veil over the field scrim: the plate holds the whole screen, so the
     photograph reads as a ground here rather than as a picture being shown */
  background: var(--scrim-field), var(--scrim-pane), rgba(251, 247, 244, 0.22);
}
.intro__mark {
  position: absolute;
  top: 50%; left: 50%;
  width: clamp(120px, 13vw, 176px);
  aspect-ratio: 1;
  height: auto;
  translate: -50% -50%;
  border-radius: 50%;
  box-shadow: var(--shadow-glass);
  animation: intro-mark 1500ms var(--ease-out) forwards;
}
@keyframes intro-out {
  to { opacity: 0; transform: scale(1.07); visibility: hidden; pointer-events: none; }
}
@keyframes intro-mark {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: none; }
}

/* Content held out until it settles. Pure CSS, so JS-off is simply the page.
   Only the home page runs the curtain; the interior pages settle straight away,
   because a 1.5s plate on every click is a toll, not an entrance. */
html.js .site-header,
html.js .hero__card,
html.js .hero__aside {
  animation: settle 760ms var(--ease-out) 120ms both;
}
html.js .hero__card  { animation-delay: 180ms; }
html.js .hero__aside { animation-delay: 260ms; }

html.js body[data-intro] .site-header { animation-delay: 520ms; }
html.js body[data-intro] .hero__card  { animation-delay: 640ms; }
html.js body[data-intro] .hero__aside { animation-delay: 760ms; }
@keyframes settle {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

/* Scroll reveal — driven by IntersectionObserver, and only ever applied by it,
   so a page with no observer support is simply visible. */
html.js.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--dur-reveal) var(--ease-out),
              transform var(--dur-reveal) var(--ease-out);
}
html.js.reveal-ready .reveal.in { opacity: 1; transform: none; }

/* ============================================================================
   Glass primitives — house-style.md §3.2.
   The opaque fill ships FIRST. The blur is an upgrade inside @supports, so a
   browser without backdrop-filter gets a solid warm card, never transparent text.
   ========================================================================= */

.glass-lt {
  background: var(--pane-solid);
  border: var(--border-hair) solid var(--hairline);
  box-shadow: var(--shadow-soft), var(--shadow-inset);
}
.glass-pane {
  background: var(--pane-solid);
  border: var(--border-hair) solid var(--glass-border);
  box-shadow: var(--shadow-glass), var(--shadow-inset);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass-lt {
    background: var(--glass-lt);
    border-color: var(--glass-border);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
  .glass-pane {
    background: var(--glass-pane);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}

/* ============================================================================
   Layout primitives
   ========================================================================= */

.container {
  width: min(100% - var(--space-xl), var(--container));
  margin-inline: auto;
}
@media (max-width: 480px) {
  .container { width: min(100% - var(--space-md), var(--container)); }
}

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

/* Section rhythm — grounds alternate and every band carries its own edge, so no
   two sections read as the same beat separated by equal air (gate 9). */
.section--warm {
  background:
    linear-gradient(180deg, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0) 30%),
    var(--surface-warm);
  border-block: var(--border-hair) solid var(--hairline);
}
.section--rule { border-top: var(--border-hair) solid var(--hairline); }

.prose { max-width: var(--prose); }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--n-600);
  margin: 0 0 var(--space-xs);
}

/* gate 54 — the eyebrow always stacks directly above its heading in one column.
   Never tag-left / heading-right. */
.section-head {
  display: block;
  margin-bottom: var(--space-lg);
  max-width: 74ch;
}
.section-head .lede {
  max-width: 58ch;
  font-size: var(--text-lg);
  color: var(--n-700);
}

.grid { display: grid; gap: var(--gap); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }

/* Technical marginalia — house-style.md §3.5. Set in the body face with tabular
   figures rather than a third family, so the 2+1 rule holds at two (gate 37). */
.mark {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--n-600);
}
.mark--rule {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}
.mark--rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--hairline-rule), transparent);
}

/* ============================================================================
   Cards — tint, hairline and elevation. No blur: a page of simultaneous
   backdrop-filters is a phone paint bill (house-style.md §3.5).
   ========================================================================= */

.card {
  position: relative;
  background: var(--pane-solid);
  border: var(--border-hair) solid var(--hairline);
  border-radius: var(--r-md);
  padding: var(--space-md);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  border-radius: var(--r-md) var(--r-md) 0 0;
  background: var(--glass-hi);
  pointer-events: none;
}

.rule { border: 0; border-top: var(--border-hair) solid var(--hairline); margin: 0; }

/* ============================================================================
   Buttons — their 20px radius. Eight states, all present (gate 26).
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-height: var(--tap);
  padding: var(--space-xs) var(--space-md);
  border: var(--border-strong) solid var(--ink);
  border-radius: var(--radius-button);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 700;
  line-height: 1.15;
  text-decoration: none;
  cursor: pointer;
  text-align: center;
  max-width: 100%;
  white-space: nowrap;              /* gate 49 — a CTA never reads on two lines */
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease-out),
              background-color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.btn:hover  { background: var(--n-700); border-color: var(--n-700);
              transform: translateY(-2px); box-shadow: var(--shadow-soft); }
.btn:active { transform: translateY(0); box-shadow: var(--shadow-xs); }
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 0.55; cursor: not-allowed; transform: none; box-shadow: none;
}

/* The one ambient flourish on the primary action — a slow sweep, on hover only.
   No infinite loop: an ornament that never stops pulls the eye off the phone number. */
.btn--lg::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(100deg,
    transparent 38%, var(--glass-border-lt) 50%, transparent 62%);
  background-size: 250% 100%;
  background-position: 180% 0;
  opacity: 0;
  pointer-events: none;
}
.btn--lg { position: relative; overflow: hidden; }
.btn--lg:hover::after {
  opacity: 0.5;
  transition: background-position 900ms var(--ease-out), opacity var(--dur) linear;
  background-position: -80% 0;
}

.btn--secondary {
  background: var(--pane-solid);
  color: var(--ink);
  border-color: var(--ink);
}
.btn--secondary:hover { background: var(--surface-band); border-color: var(--ink); }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--hairline-rule);
  box-shadow: none;
}
.btn--ghost:hover { background: var(--surface-warm); border-color: var(--ink); }

.btn--on-dark {
  background: var(--paper); color: var(--ink); border-color: var(--paper);
}
.btn--on-dark:hover { background: var(--surface-band); border-color: var(--surface-band); }

.btn--lg { min-height: 56px; padding: var(--space-sm) var(--space-lg); font-size: var(--text-lg); }
.btn--block { width: 100%; }

/* ============================================================================
   Badges
   ========================================================================= */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  min-height: 34px;
  padding: var(--space-3xs) var(--space-xs);
  border-radius: var(--r-pill);
  border: var(--border-hair) solid var(--hairline-strong);
  background: var(--pane-solid);
  color: var(--ink);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: var(--shadow-xs);
}
.badge--live {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}
.badge--soon { background: var(--surface-band); border-color: var(--hairline-strong); }
.badge__dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; flex: none;
}

/* a badge inside a flex column inherits align-items:stretch and spans the whole
   card, which turns a pill into a bar */
.sale-card__body > .badge,
.sale-detail .badge { align-self: flex-start; }

button.badge { cursor: pointer; min-height: 44px; padding-inline: var(--space-sm); }
button.badge:hover { border-color: var(--ink); transform: translateY(-1px); }
button.badge:active { transform: translateY(0); }
button.badge:disabled { opacity: 0.55; cursor: not-allowed; }

/* ============================================================================
   N12 · Banner + retracting bar
   The notice IS the banner — it is their own announcement, not chrome we invented.
   The bar below it rides flush at rest and retracts into a floating glass strip
   once the page moves.
   ========================================================================= */

.notice {
  background: var(--ink);
  color: var(--paper);
  font-size: var(--text-sm);
  padding: var(--space-2xs) 0;
}
.notice p { margin: 0; }
.notice a { color: var(--paper); text-underline-offset: 3px; }

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: var(--surface-band);
  border-bottom: var(--border-hair) solid var(--hairline-strong);
  transition: background-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.site-header::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: var(--shadow-inset);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

/* Retracted state — the bar lifts off the page and becomes glass */
body.is-scrolled .site-header {
  background: var(--pane-solid);
  border-bottom-color: transparent;
  box-shadow: var(--shadow-soft);
}
body.is-scrolled .site-header::after { opacity: 1; }

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  body.is-scrolled .site-header {
    background: var(--glass-nav);
    -webkit-backdrop-filter: blur(16px) saturate(150%);
    backdrop-filter: blur(16px) saturate(150%);
  }
}

.site-header__bar {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) 0;
  flex-wrap: wrap;
}
/* The bar compacts once, in a single frame, at the scroll threshold — the padding
   is NOT transitioned (gate 14: never animate a layout property). What animates is
   the material: background, blur and shadow, all composited. */
body.is-scrolled .site-header__bar { padding: var(--space-2xs) 0; }

.brand-lockup {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  text-decoration: none;
  margin-right: auto;
  min-width: 0;
}
.brand-lockup img {
  width: 52px; height: 52px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
  border: var(--border-hair) solid var(--glass-border);
  box-shadow: var(--shadow-xs);
  transition: transform var(--dur) var(--ease-out);
}
.brand-lockup:hover img { transform: translateY(-2px); }
/* the mark settles on scroll by scale, not by width/height — composited, and it
   does not re-lay the bar out on the way */
body.is-scrolled .brand-lockup img { transform: scale(0.82); }
body.is-scrolled .brand-lockup:hover img { transform: scale(0.82) translateY(-2px); }
.brand-lockup__name {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.2;                 /* gate 55 — all-caps display never below 1.0 */
}
.brand-lockup__sub {
  font-size: var(--text-xs);
  color: var(--n-600);
  letter-spacing: 0.04em;
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-md);
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-nav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;              /* gate 49 */
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 10px;
  height: 2px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
.site-nav a:hover::after,
.site-nav a[aria-current="page"]::after { transform: scaleX(1); }

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  flex-wrap: wrap;
}
.header-phone {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--space-2xs);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.header-phone:hover { text-decoration: underline; text-decoration-thickness: 2px; }

/* The phone menu. Below 980px the five links do not belong in the bar — four rows
   of nav would eat a fifth of the viewport on the phone this audience is holding. */
.nav-toggle {
  display: none;
  align-items: center;
  gap: var(--space-2xs);
  min-height: var(--tap);
  padding: var(--space-2xs) var(--space-sm);
  border: var(--border-strong) solid var(--ink);
  border-radius: var(--radius-button);
  background: var(--pane-solid);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}
.nav-toggle:hover  { background: var(--surface-band); transform: translateY(-2px); }
.nav-toggle:active { transform: translateY(0); }
.nav-toggle:disabled { opacity: 0.55; cursor: not-allowed; }
.nav-toggle__bars {
  display: block; position: relative;
  width: 18px; height: 2px; background: currentColor; flex: none;
}
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: ""; position: absolute; left: 0;
  width: 18px; height: 2px; background: currentColor;
}
.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after  { top: 6px; }

.nav-sheet[hidden] { display: none; }
.nav-sheet {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  justify-content: flex-end;
}
.nav-sheet__backdrop {
  position: absolute; inset: 0;
  border: 0; padding: 0; margin: 0;
  background: rgba(0, 0, 0, 0.44);
  cursor: pointer;
}
.nav-sheet__panel {
  position: relative;
  width: min(88vw, 380px);
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-md);
  background: var(--pane-solid);
  border-left: var(--border-hair) solid var(--hairline);
  box-shadow: var(--shadow-modal);
  animation: sheet-in var(--dur-long) var(--ease-out);
}
@keyframes sheet-in { from { transform: translateX(16px); opacity: 0; } }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav-sheet__panel {
    background: var(--glass-nav);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}
.nav-sheet__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-sm); margin-bottom: var(--space-md);
}
.nav-sheet__close {
  flex: none;
  width: var(--tap); height: var(--tap);
  border-radius: 50%;
  border: var(--border-hair) solid var(--hairline-strong);
  background: var(--pane-solid);
  color: var(--ink);
  font-size: 1.25rem; line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}
.nav-sheet__close:hover  { background: var(--surface-band); transform: translateY(-2px); }
.nav-sheet__close:active { transform: translateY(0); }
.nav-sheet__close:disabled { opacity: 0.55; cursor: not-allowed; }
.nav-sheet ul { list-style: none; margin: 0 0 var(--space-md); padding: 0; }
.nav-sheet li { margin: 0; border-top: var(--border-hair) solid var(--hairline); }
.nav-sheet li:first-child { border-top: 0; }
.nav-sheet a.nav-sheet__link {
  display: flex; align-items: center;
  min-height: 56px;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.nav-sheet a.nav-sheet__link[aria-current="page"] { text-decoration: underline;
  text-decoration-thickness: 2px; text-underline-offset: 4px; }
.nav-sheet__actions { display: grid; gap: var(--space-2xs); }

@media (max-width: 980px) {
  .site-nav { display: none; }
  .nav-toggle { display: inline-flex; }
  .header-actions .btn { display: none; }
}
@media (min-width: 981px) {
  .nav-sheet { display: none; }

  /* Two tiers, declared rather than wrapped. The five destinations plus the brand,
     the phone and the CTA cannot hold one 1240px row at any weight that stays
     readable for this audience, so the bar is a masthead over a nav strip — which
     is what a wrapped flex row was accidentally drawing anyway. */
  .site-header__bar {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    grid-template-areas: "brand actions" "nav nav";
    align-items: center;
    row-gap: var(--space-2xs);
    flex-wrap: nowrap;
  }
  .brand-lockup   { grid-area: brand; margin-right: 0; }
  .header-actions { grid-area: actions; justify-content: flex-end; }
  .site-nav {
    grid-area: nav;
    border-top: var(--border-hair) solid var(--hairline-strong);
    padding-top: var(--space-3xs);
  }
  body.is-scrolled .site-nav { border-top-color: var(--hairline); }
}
@media (max-width: 520px) {
  .brand-lockup__sub { display: none; }
  .header-phone { display: none; }   /* the phone lives in the sheet at this width,
                                        where it is a 56px row rather than 8px of bar */
}

/* ============================================================================
   Hero — anchored on one of their own photographs, graded and scrimmed, with the
   headline and the aside standing on it as two sibling panes. Never a pane inside
   a pane (house-style.md §3.6).
   ========================================================================= */

.hero {
  position: relative;
  padding-block: clamp(40px, 6vw, 72px) var(--section-y);
}
/* gate 44a — the close is heavier than the open, so the hero pulls into the next
   section's rhythm instead of floating off the top of the page */
.hero--anchored { padding-block: clamp(40px, 5vw, 64px) calc(var(--section-y) * 1.35); }

.hero__field {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--surface-well);
}
.hero__field img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--grade-field);
}
.hero__field::after {
  content: "";
  position: absolute; inset: 0;
  background: var(--scrim-field);
}
.hero__grid {
  position: relative;
  display: grid;
  gap: clamp(24px, 4vw, 48px);
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);   /* gate 50 */
  align-items: start;
}
@media (max-width: 900px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr); }
}

.hero__card {
  border-radius: var(--r-lg);
  padding: clamp(20px, 3.4vw, 40px);
}
/* single-column heroes — the pane holds the measure so the lede does not run
   the full 1240px and stop being a paragraph */
.hero__card--wide { max-width: 74ch; }
.hero h1 { margin-bottom: var(--space-sm); }
.hero__lede {
  font-size: clamp(1.0625rem, 2vw, 1.3125rem);
  max-width: 46ch;
  color: var(--n-700);
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;              /* gate 36 */
  gap: var(--space-xs);
  margin-top: var(--space-md);
}
.hero__reassure {
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: var(--border-hair) solid var(--hairline);
  font-size: var(--text-sm);
  color: var(--n-600);
  max-width: 52ch;
}

.hero__aside {
  border-radius: var(--r-lg);
  padding: clamp(20px, 2.6vw, 28px);
}
.hero__aside h2 { font-size: var(--text-xl); }

/* ============================================================================
   Sale cards + sale detail
   ========================================================================= */

.sale-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--pane-solid);
  border: var(--border-hair) solid var(--hairline);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.sale-card:hover {
  transform: translateY(-4px);
  border-color: var(--hairline-strong);
  box-shadow: var(--shadow-lift);
}
.sale-card__media {
  aspect-ratio: 4 / 3;
  background: var(--surface-well);
  overflow: hidden;
}
.sale-card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--grade-tile);
  transition: transform 600ms var(--ease-out);
}
.sale-card:hover .sale-card__media img { transform: scale(1.04); }
.sale-card__media--none {
  display: grid;
  place-items: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--text-sm);
  color: var(--n-600);
  background:
    repeating-linear-gradient(135deg,
      transparent 0 10px, var(--surface-warm-2) 10px 11px),
    var(--surface-warm);
}
.sale-card__body {
  padding: var(--space-md);
  display: flex; flex-direction: column;
  gap: var(--space-xs);
  flex: 1;
}
.sale-card__body h3 { margin: 0; }

/* A finished sale is evidence, not an offer. It carries no link, so it must not behave like
   one: no lift, no shadow, no zoom under the cursor — the affordances on the live cards are
   what tell somebody there is a page behind them. The photograph sits back a shade so that the
   sales that ARE on read first when both sections are on the page together. */
.sale-card--past { box-shadow: none; }
.sale-card--past:hover {
  transform: none;
  box-shadow: none;
  border-color: var(--hairline);
}
.sale-card--past .sale-card__media img { opacity: .88; }
.sale-card--past:hover .sale-card__media img { transform: none; }

.meta-list { margin: 0; }
.meta-list div {
  display: flex;
  gap: var(--space-xs);
  padding: var(--space-2xs) 0;
  border-top: var(--border-hair) solid var(--hairline);
  font-size: var(--text-sm);
}
.meta-list div:first-child { border-top: 0; }
.meta-list dt {
  flex: none;
  width: 8.5em;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: var(--text-xs);
  color: var(--n-600);
  padding-top: 2px;
}
.meta-list dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }

@media (max-width: 460px) {
  .meta-list div { display: block; }
  .meta-list dt { width: auto; margin-bottom: 2px; }
}

/* Karen's own words about a sale. Set apart by a hairline and a warm ground,
   not by a coloured slab (gate 5). */
.sale-note {
  position: relative;
  margin: 0;
  padding: var(--space-sm) var(--space-sm) var(--space-sm) var(--space-md);
  border-radius: var(--r-sm);
  background: var(--surface-warm);
  border: var(--border-hair) solid var(--hairline);
  font-size: var(--text-sm);
  color: var(--n-700);
}
.sale-note::before {
  content: "";
  position: absolute;
  left: var(--space-2xs); top: var(--space-sm); bottom: var(--space-sm);
  width: 2px; border-radius: 2px;
  background: var(--hairline-rule);
}

.sale-detail {
  display: grid;
  gap: clamp(24px, 3.5vw, 48px);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);   /* gate 50 */
  align-items: start;
  padding-block: var(--section-y);
  border-top: var(--border-hair) solid var(--hairline);
}
@media (max-width: 900px) {
  .sale-detail { grid-template-columns: minmax(0, 1fr); }
}

/* The booking panel that stands in for the detail blocks between sales. A sale detail is two
   columns because it has photographs beside its text; this one has no second column, so it
   keeps the single measure rather than leaving half the row empty. */
.sale-detail--book { grid-template-columns: minmax(0, 62ch); }
.sale-detail--book .btn + .btn { margin-left: var(--space-2xs); }

.thumb-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: var(--space-2xs);
  margin-top: var(--space-xs);
}
.thumb-row img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: cover;
  border-radius: var(--r-xs);
  border: var(--border-hair) solid var(--hairline);
  filter: var(--grade-tile);
  box-shadow: var(--shadow-xs);
  transition: transform 600ms var(--ease-out);
}
.thumb-row img:hover { transform: scale(1.05); }

.figure {
  position: relative;
  margin: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  border: var(--border-hair) solid var(--hairline);
  background: var(--surface-well);
  box-shadow: var(--shadow-soft);
}
.figure img { width: 100%; filter: var(--grade-tile); }
.figure--portrait { max-width: 420px; }
.tile-grid .figure img { aspect-ratio: 3 / 4; object-fit: cover; }
.tile-grid .figure {
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.tile-grid .figure:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
.figure figcaption {
  padding: var(--space-2xs) var(--space-xs);
  font-size: var(--text-sm);
  color: var(--n-600);
  background: var(--pane-solid);
  border-top: var(--border-hair) solid var(--hairline);
}

/* ============================================================================
   Steps, rates, testimonials, FAQ
   ========================================================================= */

.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.steps > li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: var(--space-sm);
  padding: var(--space-md) 0;
  border-top: var(--border-hair) solid var(--hairline);
  margin: 0;
}
.steps > li:first-child { border-top: 0; padding-top: 0; }
.steps > li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
  line-height: 2.2;
  color: var(--n-600);
}
.steps h3 { margin-bottom: var(--space-3xs); }
.steps p { margin: 0; color: var(--n-700); }

.rate-card {
  background: var(--pane-solid-2);
  border-color: var(--hairline-strong);
  box-shadow: var(--shadow-soft);
}
.rate-list { margin: 0; }
.rate-list div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-sm);
  padding: var(--space-xs) 0;
  border-top: var(--border-hair) solid var(--hairline-strong);
}
.rate-list div:first-child { border-top: 0; padding-top: 0; }
.rate-list dt { font-size: var(--text-sm); color: var(--n-700); max-width: 30ch; }
.rate-list dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.quote-grid { columns: 2; column-gap: var(--gap); }
@media (max-width: 860px) { .quote-grid { columns: 1; } }

.quote {
  break-inside: avoid;
  margin: 0 0 var(--gap);
  padding: var(--space-md);
  background: var(--pane-solid);
  border: var(--border-hair) solid var(--hairline);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.quote:hover { transform: translateY(-3px); box-shadow: var(--shadow-soft); }
.quote blockquote { margin: 0 0 var(--space-xs); }
.quote p { font-size: var(--text-base); }
.quote figcaption {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--n-600);
  padding-top: var(--space-2xs);
  border-top: var(--border-hair) solid var(--hairline);
}

/* ============================================================================
   UI pass · icon-led components that replace stacked prose
   Shared inline-SVG icons (drawn in an in-page <svg> sprite) inherit currentColor.
   ========================================================================= */

/* stroke/fill must live on the referencing <svg> — a <use> instance does not
   inherit the sprite root's presentation attributes across the use boundary */
.ui-icon {
  width: 20px; height: 20px; flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ui-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- testimonial cards: a glanceable card; the full note expands in place --- */
.quote-card {
  break-inside: avoid;
  margin: 0 0 var(--gap);
  padding: var(--space-md);
  background: var(--pane-solid);
  border: var(--border-hair) solid var(--hairline);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.quote-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-soft); }
.quote-card__mark {
  display: block;
  font-family: var(--font-display);
  font-size: 2.6rem; line-height: 0.5;
  color: var(--hairline-rule);
  margin-bottom: var(--space-xs);
}
.quote-card blockquote, .quote-card__body { margin: 0; }
.quote-card blockquote p, .quote-card__body p { font-size: var(--text-base); margin: 0 0 var(--space-xs); }
.quote-card blockquote p:last-child, .quote-card__body p:last-child { margin-bottom: 0; }
.quote-card figcaption {
  margin-top: var(--space-sm);
  padding-top: var(--space-2xs);
  border-top: var(--border-hair) solid var(--hairline);
  font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--n-600);
}

/* the expandable variant: a <details> whose summary is the clamped note */
.quote-card__more > summary { list-style: none; cursor: pointer; display: block; }
.quote-card__more > summary::-webkit-details-marker { display: none; }
.quote-card__more:not([open]) .quote-card__body {
  display: -webkit-box; -webkit-line-clamp: 5; line-clamp: 5;
  -webkit-box-orient: vertical; overflow: hidden;
}
.quote-card__cue {
  display: inline-flex; align-items: center; gap: var(--space-3xs);
  margin-top: var(--space-sm);
  font-family: var(--font-body); font-weight: 700; font-size: var(--text-sm);
  color: var(--ink);
}
.quote-card__cue::before {
  content: ""; width: 15px; height: 15px; flex: none;
  background:
    linear-gradient(var(--ink), var(--ink)) center/10px 1.5px no-repeat,
    linear-gradient(var(--ink), var(--ink)) center/1.5px 10px no-repeat;
}
.quote-card__cue::after {
  content: "Read the whole note"; text-decoration: underline; text-underline-offset: 3px;
}
.quote-card__more[open] .quote-card__cue::before { background-size: 10px 1.5px, 0 0; }
.quote-card__more[open] .quote-card__cue::after { content: "Show less"; }
.quote-card__more[open] > summary .quote-card__cue { color: var(--n-600); }

/* ---- service tiles: the four service cards, now led by an icon ------------- */
.svc-tile { display: flex; flex-direction: column; gap: var(--space-2xs); }
.svc-tile__ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  border-radius: var(--r-sm);
  background: var(--surface-warm);
  border: var(--border-hair) solid var(--hairline);
  color: var(--hairline-rule);
  margin-bottom: var(--space-2xs);
}
.svc-tile__ico .ui-icon { width: 26px; height: 26px; }

/* ---- name chips: the crew, pulled out of the paragraph -------------------- */
.who-tags { display: flex; flex-wrap: wrap; gap: var(--space-2xs); margin-top: var(--space-md); }
.who-tag {
  display: inline-flex; align-items: center; gap: var(--space-3xs);
  padding: var(--space-3xs) var(--space-sm);
  border-radius: var(--r-pill);
  background: var(--surface-band);
  border: var(--border-hair) solid var(--hairline-strong);
  font-weight: 700; font-size: var(--text-sm);
}

/* ---- meta chips: the same glance-first language as the live-sale popup ----- */
.chips {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--space-2xs);
  margin: var(--space-sm) 0;
}
.chips--rows { grid-template-columns: 1fr; }   /* longer values read better stacked */
.chip {
  display: flex; align-items: flex-start; gap: var(--space-2xs);
  padding: var(--space-2xs) var(--space-xs);
  background: var(--surface-warm);
  border: var(--border-hair) solid var(--hairline);
  border-radius: var(--r-sm);
}
.chip .ui-icon { color: var(--hairline-rule); margin-top: 1px; }
.chip__label {
  display: block; font-size: var(--text-xs); font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--n-600);
}
.chip__value { display: block; font-size: var(--text-sm); color: var(--ink); }
.chip__value a { overflow-wrap: anywhere; }

.pull-quote {
  font-family: var(--font-display);
  font-style: normal;
  font-size: clamp(1.4rem, 3vw, 2rem);
  line-height: 1.3;
  max-width: 26ch;
  margin: 0;
  align-self: start;          /* or the rule runs on past the last line */
  padding-left: var(--space-md);
  border-left: 2px solid var(--hairline-rule);
}

.faq { border-top: var(--border-hair) solid var(--hairline); }
.faq details { border-bottom: var(--border-hair) solid var(--hairline); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: var(--space-sm) var(--space-xl) var(--space-sm) 0;
  position: relative;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  min-height: 44px;
  transition: color var(--dur-micro) var(--ease-out);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  position: absolute;
  right: var(--space-2xs); top: 50%;
  width: 14px; height: 14px;
  margin-top: -7px;
  background:
    linear-gradient(var(--ink), var(--ink)) center/14px 2px no-repeat,
    linear-gradient(var(--ink), var(--ink)) center/2px 14px no-repeat;
  transition: transform var(--dur) var(--ease-out);
}
.faq details[open] summary::after { transform: rotate(90deg); background-size: 14px 2px, 0 0; }
.faq summary:hover { color: var(--n-700); }
.faq details > div {
  padding: 0 0 var(--space-md);
  max-width: var(--prose);
  color: var(--n-700);
}

/* ============================================================================
   Forms — gate 39. One base height across input and button, a reserved helper
   slot so an appearing error never pushes the page down, a focus ring built
   from outline and never from border-width.
   ========================================================================= */

.form-grid { display: grid; gap: var(--space-sm); }
@media (min-width: 640px) {
  .form-grid--split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .form-grid--split .field--full { grid-column: 1 / -1; }
}

.field label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-bottom: var(--space-3xs);
}
.field .hint {
  display: block;
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--n-600);
  letter-spacing: 0;
  margin-top: 2px;
}
.field input,
.field textarea,
.field select {
  width: 100%;
  min-height: var(--tap);
  padding: var(--space-xs) var(--space-sm);
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--ink);
  background: var(--paper);
  border: var(--border-hair) solid var(--hairline-strong);
  border-radius: var(--r-sm);
  outline: 2px solid transparent;   /* reserved, so activating focus shifts nothing */
  outline-offset: 1px;
  box-shadow: var(--shadow-xs);
  transition: background-color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out),
              box-shadow var(--dur-micro) var(--ease-out);
}
.field input:hover,
.field textarea:hover { border-color: var(--hairline-rule); }
.field textarea { min-height: 130px; resize: vertical; }
.field input:focus-visible,
.field textarea:focus-visible,
.field select:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
  border-color: var(--ink);         /* colour only — border-width never moves */
  background: var(--paper);
}
.field input:disabled,
.field textarea:disabled {
  opacity: 0.55; cursor: not-allowed; background: var(--surface-warm);
}

.field .error {
  display: block;
  visibility: hidden;
  min-height: 1lh;                  /* the slot is reserved even when empty */
  margin-top: var(--space-3xs);
  font-size: var(--text-sm);
  font-weight: 700;
}
.field[data-invalid="true"] .error { visibility: visible; }
.field[data-invalid="true"] input,
.field[data-invalid="true"] textarea {
  border-color: var(--ink);
  background: var(--surface-warm);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.form-success {
  border: var(--border-strong) solid var(--ink);
  border-radius: var(--r-md);
  padding: var(--space-md);
  background: var(--pane-solid-2);
  box-shadow: var(--shadow-soft);
}

/* ============================================================================
   Ft5 · Statement close
   The dark band the page has always ended on, re-laid so the sentence they wrote
   carries the close and the links sit under it as a colophon rather than four
   columns of index (gate 43). Every word and every link is the draft's.
   ========================================================================= */

.site-footer {
  position: relative;
  background: var(--surface-dark);
  color: var(--paper);
  padding-block: var(--section-y) var(--space-lg);
  margin-top: var(--space-xl);
  overflow: hidden;
}
.site-footer::before {
  content: "";
  position: absolute;
  top: -18rem; right: -14rem;
  width: 40rem; height: 40rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(232, 217, 207, 0.14) 0%, transparent 68%);
  pointer-events: none;
}
.site-footer > .container { position: relative; }
.site-footer a { color: var(--paper); }
.site-footer h2, .site-footer h3 { color: var(--paper); }

.footer-statement {
  display: grid;
  gap: var(--space-md);
  align-items: center;
  grid-template-columns: 96px minmax(0, 1fr);
  padding-bottom: var(--space-xl);
  margin-bottom: var(--space-xl);
  border-bottom: var(--border-hair) solid var(--hairline-on-dark);
}
.footer-statement p {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.4vw, 2.25rem);
  line-height: 1.22;
  max-width: 22ch;
  margin: 0;
}
@media (max-width: 640px) {
  .footer-statement { grid-template-columns: minmax(0, 1fr); }
}

.footer-lockup img {
  width: 96px; height: 96px;
  border-radius: 50%;
  border: var(--border-hair) solid var(--hairline-on-dark);
}

.footer-grid {
  display: grid;
  gap: var(--space-lg) var(--space-md);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}
.footer-grid h3 {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #C9C2BC;
  margin-bottom: var(--space-xs);
}
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: var(--space-2xs); }
.site-footer li a { white-space: nowrap; }   /* gate 49 */

.footer-note {
  margin-top: var(--space-xl);
  padding-top: var(--space-md);
  border-top: var(--border-hair) solid var(--hairline-on-dark);
  font-size: var(--text-sm);
  color: #C9C2BC;
}

/* ============================================================================
   Live sale dialog + carousel
   The most legibility-critical surface on the site: it is the one thing that
   opens itself, on a phone, over whatever is underneath.
   ========================================================================= */

.live-trigger { display: none; }
.live-trigger[data-ready="true"] { display: inline-flex; }

.live-dialog[hidden] { display: none; }

.live-dialog {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
@media (min-width: 700px) {
  .live-dialog { align-items: center; padding: var(--space-lg) var(--space-sm); }
}

.live-dialog__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.58);
  border: 0; padding: 0; margin: 0;
  cursor: pointer;
  animation: fade-in var(--dur-long) var(--ease-out);
}
@keyframes fade-in { from { opacity: 0; } }

.live-dialog__panel {
  position: relative;
  background: var(--pane-solid);
  color: var(--ink);
  width: 100%;
  max-width: 720px;
  max-height: 92vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  border: var(--border-hair) solid var(--glass-border);
  box-shadow: var(--shadow-modal), var(--shadow-inset);
  animation: panel-in var(--dur-long) var(--ease-out);
}
@keyframes panel-in { from { opacity: 0; transform: translateY(20px) scale(0.98); } }
@media (min-width: 700px) {
  .live-dialog__panel { border-radius: var(--r-lg); max-height: 88vh; }
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .live-dialog__panel {
    background: rgba(252, 250, 248, 0.94);   /* --pane-solid @ .94 — this pane holds
                                                addresses and door hours over an
                                                unknown page; it does not go thinner */
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}

.live-dialog__grip {
  display: block;
  width: 44px; height: 5px;
  border-radius: var(--r-pill);
  background: var(--hairline-strong);
  margin: var(--space-2xs) auto 0;
}
@media (min-width: 700px) { .live-dialog__grip { display: none; } }

/* sticky header so the close and the count stay reachable over a tall scroll sheet */
.live-dialog__header {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background: var(--pane-solid);
  border-bottom: var(--border-hair) solid var(--hairline);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .live-dialog__header {
    background: rgba(252, 250, 248, 0.92);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}
.live-dialog__headtext { flex: 1 1 auto; min-width: 0; }
.live-dialog__eyebrow {
  margin: 0;
  font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--n-600);
}
.live-dialog__heading { margin: 2px 0 0; font-size: var(--text-xl); }
.live-dialog__count { flex: none; align-self: center; }

/* one sale, one card; stacked and divided by a hairline */
.live-sale-card + .live-sale-card { border-top: var(--border-strong) solid var(--hairline); }
.live-card__head {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2xs);
  padding: var(--space-sm) var(--space-sm) 0;
}
.live-card__title { margin: 0; font-size: var(--text-xl); }

.live-dialog__close {
  flex: none;
  width: var(--tap); height: var(--tap);
  border-radius: 50%;
  border: var(--border-hair) solid var(--hairline-strong);
  background: var(--pane-solid);
  color: var(--ink);
  font-size: 1.25rem; line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}
.live-dialog__close:hover  { background: var(--surface-band); transform: translateY(-2px); }
.live-dialog__close:active { transform: translateY(0); }
.live-dialog__close:disabled { opacity: 0.55; cursor: not-allowed; }

.live-card__body { padding: var(--space-sm); display: grid; gap: var(--space-sm); }
.live-dialog__section h3 {
  font-size: var(--text-xs);
  font-family: var(--font-body);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--n-600);
  margin-bottom: var(--space-2xs);
}

.countdown {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* --- compact visual sale card: media, chips, countdown, one click-through --- */

.live-icon { width: 20px; height: 20px; flex: none; }

/* the photographs lead now — they sit at the top of the panel, full width.
   Capped so the countdown and the click-through still sit high in the card. */
.live-media .carousel__viewport { aspect-ratio: 16 / 11; max-height: min(44vh, 440px); }

/* the essentials as glanceable chips instead of stacked When/Where prose */
.live-chips { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2xs); }
.live-chip {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  min-width: 0;
  padding: var(--space-2xs) var(--space-xs);
  background: var(--surface-warm);
  border: var(--border-hair) solid var(--hairline);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--ink);
}
.live-chip span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-chip .live-icon { color: var(--hairline-rule); }
/* the address chip is the wide one — it runs the full row under the date/time pair */
.live-chip--wide { grid-column: 1 / -1; }

/* the countdown is the loudest thing in the card, but stays in the house palette */
.live-countdown {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--r-md);
  background: var(--surface-band);
  border: var(--border-hair) solid var(--hairline-strong);
}
.live-countdown__dot {
  flex: none; width: 11px; height: 11px; border-radius: 50%;
  background: var(--hairline-rule);
  box-shadow: 0 0 0 4px rgba(192, 167, 148, 0.28);
}
.live-countdown__head {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.live-countdown__detail { font-size: var(--text-sm); color: var(--n-600); margin-top: 2px; }
/* a sale that is open right now goes ink-solid, the same signal the live badge uses */
.live-countdown--live { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.live-countdown--live .live-countdown__detail { color: #D9D2CC; }
.live-countdown--live .live-countdown__dot {
  background: var(--paper); box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.22);
  animation: live-pulse 1.8s var(--ease-in-out) infinite;
}
@keyframes live-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.22); }
  50%      { box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.06); }
}

/* the one primary action: through to this sale's own page */
.live-cta { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2xs); }
.live-cta .live-icon { width: 22px; height: 22px; }

/* directions + calendar, quiet, side by side */
.live-secondary { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2xs); }
.live-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-height: var(--tap);
  padding: var(--space-2xs) var(--space-xs);
  border-radius: var(--r-md);
  border: var(--border-hair) solid var(--hairline-strong);
  background: var(--pane-solid);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.live-iconbtn:hover  { background: var(--surface-band); transform: translateY(-2px); }
.live-iconbtn:active { transform: translateY(0); }
.live-iconbtn .live-icon { color: var(--hairline-rule); }

/* one short line of context, never a paragraph — the rest is on the sale page */
.live-desc {
  margin: 0;
  color: var(--n-600);
  font-size: var(--text-sm);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.carousel { display: grid; gap: var(--space-xs); }

.carousel__viewport {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--surface-well);
  aspect-ratio: 4 / 3;
  touch-action: pan-y;
  border: var(--border-hair) solid var(--hairline);
}
.carousel__track {
  display: flex;
  height: 100%;
  transition: transform var(--dur-long) var(--ease-out);
}
.carousel__slide { flex: 0 0 100%; height: 100%; margin: 0; position: relative; }
.carousel__slide img { width: 100%; height: 100%; object-fit: cover; filter: var(--grade-tile); }
.carousel__slide figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: var(--space-lg) var(--space-xs) var(--space-xs);
  background: var(--scrim-media);
  color: var(--paper);
  font-size: var(--text-sm);
}

.carousel__controls {
  display: flex;
  align-items: center;              /* gate 36 */
  justify-content: space-between;
  gap: var(--space-xs);
}
.carousel__nav {
  width: var(--tap); height: var(--tap);
  border-radius: 50%;
  border: var(--border-hair) solid var(--hairline-strong);
  background: var(--pane-solid);
  color: var(--ink);
  cursor: pointer;
  font-size: 1.125rem; line-height: 1;
  box-shadow: var(--shadow-xs);
  transition: background-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}
.carousel__nav:hover  { background: var(--surface-band); transform: translateY(-2px); }
.carousel__nav:active { transform: translateY(0); }
.carousel__nav:disabled { opacity: 0.55; cursor: not-allowed; }
.carousel__counter {
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
}
.carousel[data-single="true"] .carousel__controls { display: none; }

body.is-locked { overflow: hidden; }

/* ============================================================================
   Reduced motion — house-style.md §3.4. It costs the look nothing and it is the
   difference between a site that moves and a site that makes someone ill.
   ========================================================================= */

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

  .intro, html.js .intro { display: none !important; }

  html.js .site-header,
  html.js .hero__card,
  html.js .hero__aside,
  .nav-sheet__panel,
  .live-dialog__panel,
  .live-dialog__backdrop { animation: none !important; opacity: 1; transform: none; }

  html.js.reveal-ready .reveal {
    opacity: 1; transform: none;
    transition: opacity 140ms linear;
  }

  .page-field span { animation: none !important; }

  .btn, .card, .sale-card, .quote, .figure, .thumb-row img,
  .sale-card__media img, .tile-grid .figure, .carousel__track,
  .nav-toggle, .nav-sheet__close, .live-dialog__close, .carousel__nav,
  .brand-lockup img, .site-header, .site-header__bar {
    transition-duration: 140ms !important;
    transform: none !important;
  }
  .btn--lg:hover::after { opacity: 0; }
}


/* ---- the rest of a finished sale's album, under its main photograph -------------------
   One photograph says the house existed; a strip says forty things were sorted, priced and
   sold out of it. Static markup and no click, so it survives with JavaScript off. */
.sale-card__thumbs {
  display: flex;
  align-items: center;
  gap: var(--space-3xs, 6px);
  padding: var(--space-2xs) var(--space-sm) 0;
  min-width: 0;
}
.sale-card__thumbs img {
  flex: 0 0 auto;
  width: 54px;
  height: 40px;
  object-fit: cover;
  border-radius: var(--r-xs);
  border: var(--border-hair) solid var(--hairline);
  filter: var(--grade-tile);
}
.sale-card__thumbs-more {
  color: var(--n-600);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  padding-left: var(--space-3xs, 6px);
}
/* Past cards carry a photograph, a strip and a body; on a narrow screen the strip is the
   first thing that should give up its room. */
@media (max-width: 520px) {
  .sale-card__thumbs img:nth-child(n+4) { display: none; }
}