/* ==========================================================================
   Shri Sai Interior — components
   ========================================================================== */

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  --btn-bg: var(--charcoal);
  --btn-fg: var(--ivory);
  --btn-bd: var(--charcoal);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-block-size: 3rem;
  padding: 0.9rem 1.75rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bd);
  border-radius: var(--radius-xs);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
              background-color var(--dur) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

/* Brass wipes up from the floor of the button. */
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--brass);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform var(--dur) var(--ease-out);
}
.btn:hover::after, .btn:focus-visible::after { transform: scaleY(1); }
.btn:hover, .btn:focus-visible { border-color: var(--brass); color: var(--charcoal); }
.btn:active { transform: translateY(1px); }

/* For the one commitment button on a page — the enquiry submit. Weight should
   match what it is asking for. */
.btn--lg {
  min-block-size: 3.5rem;
  padding: 1.1rem 2.5rem;
  font-size: var(--step-0);
  justify-self: start;
}
.btn--lg svg { inline-size: 1em; block-size: 1em; }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--charcoal);
  --btn-bd: var(--rule-strong);
}
.btn--ghost:hover, .btn--ghost:focus-visible { color: var(--charcoal); }

.btn--on-dark {
  --btn-bg: var(--ivory);
  --btn-fg: var(--charcoal);
  --btn-bd: var(--ivory);
}
.btn--ghost-on-dark {
  --btn-bg: transparent;
  --btn-fg: var(--ivory);
  --btn-bd: var(--rule-inverse);
}
.btn--ghost-on-dark:hover, .btn--ghost-on-dark:focus-visible { color: var(--charcoal); }

.btn--block { inline-size: 100%; }

/* Text link with an underline that draws in from the left. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  padding-block-end: 0.35em;
  position: relative;
}
.link-arrow::before {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 1px;
  background: var(--rule-strong);
}
.link-arrow::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 1px;
  background: var(--brass);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
.link-arrow:hover::after, .link-arrow:focus-visible::after { transform: scaleX(1); }
.link-arrow svg { inline-size: 1em; block-size: 1em; transition: transform var(--dur) var(--ease-out); }
.link-arrow:hover svg { transform: translateX(0.25em); }
/*
 * .footer is listed alongside .on-dark because it is a charcoal surface that
 * does NOT carry the .on-dark class — the same gap that hid the CTA band's lede.
 * Without this, the footer's "Request a Consultation" link inherited the light
 * surface colour and rendered charcoal-on-charcoal: contrast 1.00, an entirely
 * invisible link that was still in the DOM, still focusable, and still counted
 * as a call to action.
 *
 * The rest of the footer is patched the same per-element way (.footer
 * .gstin-line, .footer .phone-link); this link was simply missed.
 */
.on-dark .link-arrow, .footer .link-arrow { color: var(--text-inverse); }
.on-dark .link-arrow::before, .footer .link-arrow::before { background: var(--rule-inverse); }
.on-dark .link-arrow::after, .footer .link-arrow::after { background: var(--brass-light); }

/* --------------------------------------------------------------------------
   Announcement strip
   -------------------------------------------------------------------------- */

.strip {
  background: var(--charcoal);
  color: var(--text-inverse-muted);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  border-block-end: 1px solid var(--rule-inverse);
}
.strip__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  min-block-size: 42px;
}
.strip__group { display: flex; align-items: center; gap: var(--space-m); }
.strip__item { display: inline-flex; align-items: center; gap: 0.5em; white-space: nowrap; }
.strip__item svg { inline-size: 0.95em; block-size: 0.95em; color: var(--brass-light); flex: none; }
.strip a:hover { color: var(--ivory); }

/* --------------------------------------------------------------------------
   Header / navigation
   -------------------------------------------------------------------------- */

.header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header);
  background: transparent;
  border-block-end: 1px solid transparent;
  transition: background-color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
              backdrop-filter var(--dur) var(--ease-out);
}

/*
 * "Transparent over the hero" needs the hero to actually sit UNDER the header.
 * A sticky element still occupies flow space, so without this the transparent
 * header reveals the ivory page background instead of the dark hero — and every
 * light-on-dark element in it (the wordmark, the logo, the nav) turns invisible.
 * Cancelling its own height pulls the hero up beneath it; the hero adds matching
 * top padding so nothing lands under the bar.
 */
.header--over-hero { margin-block-end: calc(-1 * var(--header-h)); }

/* Over a dark hero the header starts transparent; after scroll it earns a surface. */
.header--pinned {
  background: rgba(34, 32, 29, 0.86);
  backdrop-filter: blur(14px) saturate(1.1);
  border-block-end-color: var(--rule-inverse);
}
.header--solid {
  background: var(--charcoal);
  border-block-end-color: var(--rule-inverse);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  min-block-size: var(--header-h);
}

.brand { display: inline-flex; align-items: center; gap: 0.85rem; flex: none; }
.brand__symbol { inline-size: 38px; block-size: 38px; flex: none; color: var(--ivory); }
.brand__text { display: grid; gap: 0.15rem; }
.brand__name {
  font-family: var(--font-display);
  font-size: 1.19rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--ivory);
  white-space: nowrap;
}
.brand__tagline {
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--stone-light);
  line-height: 1;
  white-space: nowrap;
}

.nav { display: none; }
.nav__list { display: flex; align-items: center; gap: clamp(1rem, 1.8vw, 2.1rem); }
.nav__link {
  position: relative;
  display: block;
  padding-block: 0.4rem;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--stone-light);
  transition: color var(--dur-fast) var(--ease-out);
  white-space: nowrap;
}
.nav__link::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 1px;
  background: var(--brass-light);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur) var(--ease-out);
}
.nav__link:hover, .nav__link:focus-visible { color: var(--ivory); }
.nav__link:hover::after, .nav__link:focus-visible::after { transform: scaleX(1); transform-origin: left; }
.nav__link[aria-current='page'] { color: var(--ivory); }
.nav__link[aria-current='page']::after { transform: scaleX(1); }

.header__actions { display: flex; align-items: center; gap: var(--space-s); }
.header__cta { display: none; }

/* Mobile menu button */
.burger {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  inline-size: 44px;
  block-size: 44px;
  padding: 10px;
  flex: none;
}
.burger__bar {
  display: block;
  block-size: 1.5px;
  inline-size: 100%;
  background: var(--ivory);
  transition: transform var(--dur) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.burger[aria-expanded='true'] .burger__bar:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.burger[aria-expanded='true'] .burger__bar:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] .burger__bar:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* Mobile drawer */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: var(--z-mobilenav);
  background: var(--charcoal);
  padding: var(--space-l) var(--gutter) var(--space-2xl);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-1.25rem);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out), visibility var(--dur);
}
.mobile-nav[data-open='true'] { opacity: 1; visibility: visible; transform: none; }
.mobile-nav__head { display: flex; align-items: center; justify-content: space-between; margin-block-end: var(--space-xl); }
.mobile-nav__list { display: grid; gap: 0; }
.mobile-nav__item { border-block-end: 1px solid var(--rule-inverse); }
.mobile-nav__item:first-child { border-block-start: 1px solid var(--rule-inverse); }
.mobile-nav__link {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  padding-block: var(--space-s);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  color: var(--ivory);
}
.mobile-nav__link[aria-current='page'] { color: var(--brass-light); }
.mobile-nav__num {
  font-size: var(--step--2);
  font-family: var(--font-body);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--stone);
}
.mobile-nav__foot { margin-block-start: auto; padding-block-start: var(--space-xl); display: grid; gap: var(--space-s); }

body[data-scroll-locked='true'] { overflow: hidden; }

/* ==========================================================================
   CINEMATIC HERO (v2)
   ==========================================================================
   The reference template gets its impact from full-bleed photography we do not
   have. So the impact here comes from three things it does not do:
   type at display scale, a material backdrop rather than a room shot, and a
   composition that overlaps rather than sits in columns.

   The backdrop is a generated MATERIAL macro (stone/plaster/oak), never a room
   — it is texture and atmosphere, not a claim about completed work.
   ========================================================================== */

.hero-v2 {
  position: relative;
  isolation: isolate;
  background: var(--charcoal);
  color: var(--ivory);
  overflow: clip;
  /* The header floats over this, so the top padding only needs to clear it plus
     breathing room — not a full display-scale gap, which pushed the CTAs under
     the fold on a 1440x900 laptop. */
  padding-block: calc(var(--header-h) + clamp(1.5rem, 3vw, 3.25rem)) clamp(2rem, 1rem + 3vw, 3.5rem);
  min-block-size: clamp(34rem, 88svh, 56rem);
  display: flex;
  align-items: center;
}

.hero-v2__media {
  position: absolute;
  inset: 0;
  z-index: -3;
}
.hero-v2__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Dark and desaturated — it is a backdrop for type, not the subject — but not
     crushed. At 0.42 the plaster was invisible, which defeats the point of
     having it. */
  filter: saturate(0.6) contrast(1.05) brightness(0.72);
}

/*
 * Scrim. Heavy where the headline sits (left), light where it does not (right),
 * so the material actually reads while the type still clears 4.5:1.
 */
.hero-v2::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(115% 105% at 6% 45%, rgba(18, 17, 15, 0.95) 0%, rgba(18, 17, 15, 0.82) 38%, rgba(18, 17, 15, 0.42) 72%, rgba(18, 17, 15, 0.2) 100%),
    linear-gradient(to top, rgba(18, 17, 15, 0.85) 0%, transparent 42%);
}

/* The architectural grid, kept from v1 — it reads as drawing, not decoration. */
.hero-v2::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(to right, rgba(246, 241, 233, 0.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(246, 241, 233, 0.055) 1px, transparent 1px);
  background-size: clamp(56px, 7vw, 104px) clamp(56px, 7vw, 104px);
  mask-image: radial-gradient(130% 95% at 12% 0%, #000 12%, transparent 70%);
  pointer-events: none;
}

.hero-v2__inner { position: relative; inline-size: 100%; }

/* Editorial split: type carries the meaning, the material stack carries the
   atmosphere. Single column until 64rem — below that the stack would squeeze
   the headline into a column too narrow to read. */
.hero-v2__layout {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
@media (min-width: 64rem) {
  /* The slider takes the larger share — it is the client's actual work, and it
     is the thing the page is here to show. */
  .hero-v2__layout {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    gap: clamp(2rem, 5vw, 4.5rem);
  }
}

/* --------------------------------------------------------------------------
   Hero slider

   Genuine client project photography. Contained, not full-bleed: the masters
   top out at 1600px and the boardroom is 747px, so edge-to-edge would upscale
   it into mush. A crisp contained frame beats a soft full-bleed one.
   -------------------------------------------------------------------------- */

.hero-slider {
  position: relative;
  display: grid;
  gap: var(--space-s);
}

.hero-slider__frame {
  position: relative;
  overflow: clip;
  background: var(--charcoal);
  box-shadow:
    0 0 0 1px var(--rule-inverse),
    0 2rem 4rem -1rem rgba(0, 0, 0, 0.6);
  /* 4/3 suits every master: the two portraits crop to it without losing the
     run of the kitchen, and the landscapes barely crop at all. */
  aspect-ratio: 4 / 3;
}

/* Brass reveal across the top edge — the hairline language used site-wide. */
.hero-slider__frame::after {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 2px;
  background: linear-gradient(to right, transparent, var(--brass), transparent);
  z-index: 3;
  pointer-events: none;
}

/* Slides stack in one grid cell rather than a translated track: no transform
   maths, no width bookkeeping, and the frame is sized by the aspect-ratio
   above rather than by whichever slide happens to be tallest. */
.hero-slider__slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 700ms var(--ease-out, ease),
    visibility 0s linear 700ms,
    scale 900ms var(--ease-out, ease);
  scale: 1.04;
}
.hero-slider__slide[data-current] {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
  /* Slow settle out of the crossfade — the only motion here, and it carries the
     "this slide is now the one" meaning rather than decorating. */
  scale: 1;
}

.hero-slider__slide img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* The photography IS the subject here, so it gets nothing like the material
   backdrop's heavy filtering — only enough foot gradient to seat the caption. */
.hero-slider__slide::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(18, 17, 15, 0.82) 0%, rgba(18, 17, 15, 0.25) 32%, transparent 62%);
  pointer-events: none;
}

.hero-slider__caption {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 2;
  padding: var(--space-m);
}
.hero-slider__caption a {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  color: var(--ivory);
  text-decoration: none;
}
.hero-slider__caption a:hover .hero-slider__caption-title,
.hero-slider__caption a:focus-visible .hero-slider__caption-title {
  color: var(--brass-light);
}
.hero-slider__caption-title {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  transition: color 200ms ease;
}
.hero-slider__caption svg {
  inline-size: 1em;
  block-size: 1em;
  color: var(--brass-light);
}

/* ---- Controls ---------------------------------------------------------- */

.hero-slider__controls {
  display: flex;
  align-items: center;
  gap: var(--space-m);
}

.hero-slider__count {
  font-family: var(--font-display);
  font-size: var(--step--1);
  color: var(--stone-light);
  font-variant-numeric: tabular-nums;   /* stops the index jittering on change */
  margin: 0;
  /* Hidden on phones: full-size dots + arrows + this count come to ~368px
     against 342px of usable width. The dots already say where you are, and
     shrinking the dots under 44px to keep a decoration is the wrong trade. */
  display: none;
}
@media (min-width: 30rem) {
  .hero-slider__count { display: block; }
}
.hero-slider__count-sep { margin-inline: 0.35em; color: var(--brass); }

.hero-slider__dots {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-inline-end: auto;
}
.hero-slider__dot {
  /* 44x44 hit area around a 2px visual rule — the target has to be tappable
     even though the mark is a hairline. Both axes matter: at 36px wide this
     met the minimum vertically and missed it horizontally. */
  position: relative;
  inline-size: 44px;
  block-size: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.hero-slider__dot::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-start: 50%;
  block-size: 2px;
  background: var(--rule-inverse);
  transition: background-color 250ms ease;
}
.hero-slider__dot[aria-selected='true']::before { background: var(--brass); }
.hero-slider__dot:hover::before { background: var(--stone-light); }

.hero-slider__arrows { display: flex; gap: 0.5rem; }
.hero-slider__arrow {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border: 1px solid var(--rule-inverse);
  background: none;
  color: var(--ivory);
  cursor: pointer;
  transition: border-color 200ms ease, color 200ms ease;
}
.hero-slider__arrow:hover {
  border-color: var(--brass);
  color: var(--brass-light);
}
.hero-slider__arrow svg { inline-size: 1.1rem; block-size: 1.1rem; }
/* One arrow glyph, mirrored — no second icon to keep in sync. */
.hero-slider__arrow[data-slider-prev] svg { rotate: 180deg; }

@media (prefers-reduced-motion: reduce) {
  .hero-slider__slide { transition-duration: 1ms; scale: 1; }
}

.hero-v2__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.85em;
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--brass-light);
  margin-block-end: var(--space-m);
}
.hero-v2__eyebrow::before {
  content: '';
  inline-size: clamp(1.75rem, 4vw, 4rem);
  block-size: 1px;
  background: var(--brass);
}

.hero-v2__title {
  margin-block-end: var(--space-m);
  max-inline-size: 14ch;
}

.hero-v2__lede {
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-inverse-muted);
  max-inline-size: 54ch;   /* wider = fewer lines = the CTAs stay above the fold */
  margin-block-end: var(--space-m);
}

.hero-v2__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s) var(--space-m);
}

/* Capability strip along the foot of the hero. Statements of what we do —
   deliberately NOT the reference's fabricated counters (project totals, award
   counts, years in business), none of which the client has evidenced. */
.hero-v2__strip {
  margin-block-start: clamp(1.5rem, 3.5vw, 2.75rem);
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--rule-inverse);
  display: grid;
  gap: var(--space-m);
}
@media (min-width: 48rem) {
  .hero-v2__strip { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-l); }
}
.hero-v2__stat { display: grid; gap: 0.3rem; }
.hero-v2__stat dt {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--ivory);
  letter-spacing: var(--tracking-tight);
}
.hero-v2__stat dd {
  margin: 0;
  font-size: var(--step--2);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--stone-light);
}

/*
 * The scroll cue that used to live here was removed: it collided with the
 * capability strip.
 *
 * The cause is worth recording, because it is not obvious. The cue was
 * positioned with inset-inline-end (i.e. "the right") but also carried
 * writing-mode: vertical-rl. Logical properties resolve against the element's
 * OWN writing mode, and in vertical-rl the axes swap — the inline axis runs
 * vertically and the block axis runs right-to-left. So inset-inline-end became
 * the bottom and inset-block-end became the LEFT, and the cue landed bottom-left
 * on top of the text.
 *
 * Lesson for anything added here later: never mix logical insets with a rotated
 * writing-mode. Use physical properties, or do not rotate.
 *
 * Its job is now done by .to-top-float below, which appears once the hero has
 * been scrolled past and does something useful rather than stating the obvious.
 */

/* --------------------------------------------------------------------------
   Hero (v1) — retained for inner pages that use the framed treatment.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  background: var(--charcoal);
  color: var(--ivory);
  /* Top padding absorbs the header that now floats over this section. */
  padding-block: calc(var(--header-h) + clamp(2rem, 0.5rem + 7vw, 5rem)) clamp(3rem, 1rem + 6vw, 5.5rem);
  overflow: hidden;
}
/* A faint architectural grid, drawn not photographed. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(246, 241, 233, 0.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(246, 241, 233, 0.05) 1px, transparent 1px);
  background-size: clamp(48px, 7vw, 96px) clamp(48px, 7vw, 96px);
  mask-image: radial-gradient(120% 90% at 15% 0%, #000 15%, transparent 72%);
  pointer-events: none;
}
.hero__inner { position: relative; display: grid; gap: var(--space-xl); align-items: center; }

.hero__tagline {
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-style: italic;
  color: var(--brass-light);
  font-variation-settings: 'SOFT' 40, 'WONK' 1;
}
.hero__title { font-size: var(--step-6); max-width: 15ch; }
.hero__title em {
  font-style: italic;
  color: var(--brass-light);
  font-variation-settings: 'SOFT' 50, 'WONK' 1;
}
.hero__lede { max-width: 52ch; color: var(--text-inverse-muted); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-s); }
.hero__call {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ivory);
  min-block-size: 3rem;
}
.hero__call svg { inline-size: 1.05em; block-size: 1.05em; color: var(--brass-light); }
.hero__call:hover { color: var(--brass-light); }

.hero__services {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55em 1em;
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--rule-inverse);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stone-light);
}
.hero__services li { display: inline-flex; align-items: center; gap: 1em; }
.hero__services li:not(:last-child)::after {
  content: '';
  inline-size: 3px;
  block-size: 3px;
  background: var(--brass);
  border-radius: 50%;
}

/* Framed hero image — deliberately bounded, with a brass rule offset behind. */
.hero__figure { position: relative; }
.hero__figure::before {
  content: '';
  position: absolute;
  inset-block-start: -14px;
  inset-inline-end: -14px;
  inline-size: 55%;
  block-size: 55%;
  border-block-start: 1px solid var(--brass);
  border-inline-end: 1px solid var(--brass);
  pointer-events: none;
}
.hero__figure img {
  inline-size: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  filter: saturate(0.94) contrast(1.03);
}
.hero__figcaption {
  margin-block-start: var(--space-s);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* Sits on the dark hero — stone was 2.91 here and failed AA. */
  color: var(--stone-light);
}

/* --------------------------------------------------------------------------
   Page hero (inner pages)
   -------------------------------------------------------------------------- */

.page-hero {
  background: var(--charcoal);
  color: var(--ivory);
  padding-block: calc(var(--header-h) + clamp(2rem, 4vw, 4rem)) clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
  position: relative;
  isolation: isolate;
  overflow: clip;
}

/* Material backdrop, when the page supplies one. */
.page-hero__media { position: absolute; inset: 0; z-index: -3; }
.page-hero__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  filter: saturate(0.55) contrast(1.05) brightness(0.6);
}
.page-hero--material::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(110% 130% at 4% 50%, rgba(18, 17, 15, 0.95) 0%, rgba(18, 17, 15, 0.82) 40%, rgba(18, 17, 15, 0.5) 75%, rgba(18, 17, 15, 0.3) 100%);
}

/* The drawn grid, kept for pages with no material behind them. */
.page-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(to right, rgba(246, 241, 233, 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(246, 241, 233, 0.045) 1px, transparent 1px);
  background-size: clamp(56px, 6vw, 88px) clamp(56px, 6vw, 88px);
  mask-image: radial-gradient(100% 100% at 90% 0%, #000 10%, transparent 70%);
  pointer-events: none;
}
.page-hero--material::after { opacity: 0.5; }

.page-hero__inner { position: relative; display: grid; gap: var(--space-m); }
.page-hero__title { max-width: 18ch; }
.page-hero__lede {
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-inverse-muted);
  max-width: 56ch;
}
.page-hero--compact .page-hero__title { font-size: var(--step-5); }

.breadcrumb { font-size: var(--step--2); letter-spacing: 0.08em; color: var(--stone-light); }
.breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6em; list-style: none; margin: 0; padding: 0; }
.breadcrumb li { display: inline-flex; align-items: center; gap: 0.6em; }
/* Breadcrumbs live on the dark page hero, so the separator takes the dark-side
   token like the rest of the trail. It was --stone (2.91 here, and worse once
   stone was darkened for body copy). */
.breadcrumb li:not(:last-child)::after { content: '/'; color: var(--stone-light); opacity: 0.7; }
.breadcrumb a:hover { color: var(--brass-light); }
.breadcrumb [aria-current='page'] { color: var(--ivory); }

/* --------------------------------------------------------------------------
   Service presentation — deliberately not ten identical cards.
   -------------------------------------------------------------------------- */

/* Large featured service, image + editorial copy, alternating sides. */
.service-feature {
  display: grid;
  gap: var(--space-l);
  align-items: center;
}
.service-feature + .service-feature { margin-block-start: var(--space-2xl); }
.service-feature__media { position: relative; overflow: hidden; }
/* The ratio comes from the .ratio-* class on this element, driven by each
   service's own image_ratio — do not pin an aspect-ratio on the img here or
   portrait sources get cropped to landscape. */
.service-feature__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.service-feature:hover .service-feature__media img { transform: scale(1.035); }
.service-feature__body { display: grid; gap: var(--space-s); }
.service-feature__list {
  display: grid;
  gap: 0.4rem;
  font-size: var(--step--1);
  color: var(--text-muted);
}
/* The colour is set on the <ul>, which `.on-dark p, .on-dark .lede` does not
   cover — so on a dark section this list kept the light-surface --text-muted and
   rendered at 1.56. */
.on-dark .service-feature__list { color: var(--text-inverse-muted); }
.service-feature__list li { display: flex; gap: 0.7em; align-items: baseline; }
.service-feature__list li::before {
  content: '';
  inline-size: 0.5em;
  block-size: 1px;
  background: var(--brass);
  flex: none;
  translate: 0 -0.3em;
}

/* Compact supporting service rows — a list, not a grid of boxes. */
.service-rows { border-block-start: 1px solid var(--rule); }
.service-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-m);
  padding-block: var(--space-m);
  border-block-end: 1px solid var(--rule);
  position: relative;
  transition: padding-inline var(--dur) var(--ease-out);
}
.service-row::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--bg-raised);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  z-index: -1;
}
.service-row:hover { padding-inline: var(--space-s); }
.service-row:hover::before { opacity: 1; }
.service-row__num { font-size: var(--step--2); font-weight: 700; letter-spacing: 0.1em; color: var(--text-faint); font-variant-numeric: tabular-nums; }
/* These are spans inside an <a>, so they need to be told to stack. */
.service-row__title { display: block; font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; }
.service-row__desc { display: block; font-size: var(--step--1); color: var(--text-muted); margin-block-start: 0.15rem; }
.service-row__go {
  inline-size: 2.5rem;
  block-size: 2.5rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  color: var(--text-muted);
  flex: none;
  transition: background-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.service-row:hover .service-row__go {
  background: var(--brass);
  border-color: var(--brass);
  color: var(--charcoal);
  transform: rotate(-45deg);
}
.service-row__go svg { inline-size: 1rem; block-size: 1rem; }

/* Icon tile used where a service has no photograph of its own. */
.service-icon {
  inline-size: 2.75rem;
  block-size: 2.75rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--rule);
  color: var(--brass-deep);
  flex: none;
}
.service-icon svg { inline-size: 1.35rem; block-size: 1.35rem; }

/* --------------------------------------------------------------------------
   Project cards
   -------------------------------------------------------------------------- */

.project-card { position: relative; display: grid; gap: var(--space-s); }
.project-card__media {
  position: relative;
  overflow: hidden;
  background: var(--beige);
}
.project-card__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out), filter var(--dur-slow) var(--ease-out);
}
.project-card:hover .project-card__media img { transform: scale(1.04); filter: saturate(1.04); }
.project-card__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(34, 32, 29, 0.55), transparent 55%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}
.project-card:hover .project-card__media::after { opacity: 1; }

/* The numeral sits with the label rather than over the photograph: blended over
   an arbitrary image it was both illegible and dependent on what was behind it. */
.project-card__meta-row {
  display: flex;
  align-items: center;
  gap: 0.7em;
  margin-block-end: 0.3rem;
}
.project-card__num {
  font-family: var(--font-display);
  font-size: var(--step--2);
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  flex: none;
}
.project-card__num::after {
  content: '';
  display: inline-block;
  inline-size: 1.1rem;
  block-size: 1px;
  background: var(--rule-strong);
  vertical-align: middle;
  margin-inline-start: 0.7em;
}
.project-card__cat {
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  /* Brass text on ivory — --brass measured 2.76 here and failed AA. */
  color: var(--brass-deep);
}
.project-card__title { font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; }
.project-card__title a::after { content: ''; position: absolute; inset: 0; } /* whole card clickable */
.project-card__meta { font-size: var(--step--1); color: var(--text-muted); }

/*
 * In a grid, cards must share one ratio or the rows go ragged and the titles
 * stop aligning. Each project keeps its true ratio on its own detail page,
 * where the whole frame matters; here the crop is centred.
 */
.project-grid .project-card__media,
.gallery-grid .gallery-item { aspect-ratio: 4 / 3; }

/* A full-width image band, ratio set by a .ratio-* class on the same element. */
.media-band { position: relative; overflow: hidden; background: var(--beige); }
.media-band img { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* Aspect ratios reserved up front so nothing shifts as images decode. */
.ratio-4x3 { aspect-ratio: 4 / 3; }
.ratio-3x4 { aspect-ratio: 3 / 4; }
.ratio-3x2 { aspect-ratio: 3 / 2; }
.ratio-1x1 { aspect-ratio: 1 / 1; }
.ratio-16x9 { aspect-ratio: 16 / 9; }
.ratio-9x16 { aspect-ratio: 9 / 16; }

/* --------------------------------------------------------------------------
   Filters
   -------------------------------------------------------------------------- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin-block-end: var(--space-l);
}
.filter {
  padding: 0.55rem 1.1rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  min-block-size: 2.5rem;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.filter:hover { color: var(--text); border-color: var(--rule-strong); }
.filter[aria-pressed='true'] {
  background: var(--charcoal);
  border-color: var(--charcoal);
  color: var(--ivory);
}

/* --------------------------------------------------------------------------
   Gallery + lightbox
   -------------------------------------------------------------------------- */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: var(--space-s);
}
.gallery-item {
  position: relative;
  overflow: hidden;
  background: var(--beige);
  padding: 0;
  border: 0;
  cursor: zoom-in;
  inline-size: 100%;
}
.gallery-item img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.gallery-item:hover img { transform: scale(1.05); }
.gallery-item__label {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  padding: var(--space-m) var(--space-s) var(--space-s);
  background: linear-gradient(to top, rgba(34, 32, 29, 0.78), transparent);
  color: var(--ivory);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  text-align: start;
  opacity: 0;
  transform: translateY(0.5rem);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.gallery-item:hover .gallery-item__label,
.gallery-item:focus-visible .gallery-item__label { opacity: 1; transform: none; }
.gallery-item[hidden] { display: none; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: rgba(20, 19, 17, 0.96);
  backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease-out), visibility var(--dur);
}
.lightbox[data-open='true'] { opacity: 1; visibility: visible; }
.lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  padding: var(--space-s) var(--gutter);
  color: var(--stone-light);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
}
.lightbox__stage {
  display: grid;
  place-items: center;
  padding: var(--space-s) var(--gutter);
  min-block-size: 0;
}
.lightbox__img {
  max-inline-size: 100%;
  max-block-size: 100%;
  object-fit: contain;
  transform: scale(0.97);
  opacity: 0;
  transition: transform var(--dur) var(--ease-out), opacity var(--dur) var(--ease-out);
}
.lightbox[data-open='true'] .lightbox__img { transform: none; opacity: 1; }
.lightbox__foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-m);
  padding: var(--space-s) var(--gutter) var(--space-l);
  color: var(--ivory);
}
.lightbox__caption { text-align: center; font-size: var(--step--1); color: var(--stone-light); max-inline-size: 60ch; }
.lightbox__btn {
  inline-size: 3rem;
  block-size: 3rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--rule-inverse);
  border-radius: 50%;
  color: var(--ivory);
  flex: none;
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.lightbox__btn:hover { background: var(--brass); border-color: var(--brass); color: var(--charcoal); }
.lightbox__btn svg { inline-size: 1.1rem; block-size: 1.1rem; }

/* --------------------------------------------------------------------------
   Process timeline
   -------------------------------------------------------------------------- */

.process { display: grid; gap: 0; counter-reset: step; }
.process-step {
  display: grid;
  gap: var(--space-xs);
  padding-block: var(--space-l);
  border-block-start: 1px solid var(--rule-inverse);
  position: relative;
}
.process-step:last-child { border-block-end: 1px solid var(--rule-inverse); }
.process-step__num {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 400;
  color: var(--brass-light);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.process-step__title { font-family: var(--font-display); font-size: var(--step-2); font-weight: 600; }
.process-step__body { color: var(--text-inverse-muted); max-inline-size: 52ch; }

/* --------------------------------------------------------------------------
   Video panel
   -------------------------------------------------------------------------- */

.video-panel { position: relative; overflow: hidden; background: var(--charcoal-soft); }
.video-panel video, .video-panel img { inline-size: 100%; block-size: 100%; object-fit: cover; }
.video-panel__poster { position: absolute; inset: 0; }
.video-panel__play {
  position: absolute;
  inset-block-end: var(--space-s);
  inset-inline-start: var(--space-s);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding: 0.75rem 1.25rem;
  background: rgba(34, 32, 29, 0.7);
  backdrop-filter: blur(8px);
  border: 1px solid var(--rule-inverse);
  color: var(--ivory);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  min-block-size: 2.75rem;
  transition: background-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.video-panel__play:hover { background: var(--brass); border-color: var(--brass); color: var(--charcoal); }
.video-panel__play svg { inline-size: 0.9em; block-size: 0.9em; }
.video-panel__caption {
  margin-block-start: var(--space-xs);
  font-size: var(--step--2);
  color: var(--text-muted);
  letter-spacing: 0.04em;
}

/* Muted looping craft clips — small by design, these are 480px-wide sources. */
.craft-clip { position: relative; overflow: hidden; background: var(--charcoal-soft); }
.craft-clip video { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* --------------------------------------------------------------------------
   FAQ accordion
   -------------------------------------------------------------------------- */

.faq { border-block-start: 1px solid var(--rule); }
.faq-item { border-block-end: 1px solid var(--rule); }
.faq-item__trigger {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-m);
  inline-size: 100%;
  padding-block: var(--space-m);
  text-align: start;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--text);
  min-block-size: 3.5rem;
}
.faq-item__trigger:hover { color: var(--walnut); }
.faq-item__icon {
  inline-size: 1.5rem;
  block-size: 1.5rem;
  flex: none;
  position: relative;
  margin-block-start: 0.35em;
}
.faq-item__icon::before, .faq-item__icon::after {
  content: '';
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 1.5px;
  background: var(--brass);
  transition: transform var(--dur) var(--ease-out);
}
.faq-item__icon::after { transform: rotate(90deg); }
.faq-item__trigger[aria-expanded='true'] .faq-item__icon::after { transform: rotate(0deg); }
.faq-item__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur) var(--ease-inout);
}
.faq-item__panel[data-open='true'] { grid-template-rows: 1fr; }
.faq-item__panel > div { overflow: hidden; }
.faq-item__body { padding-block-end: var(--space-m); color: var(--text-muted); max-inline-size: var(--measure); }

/* --------------------------------------------------------------------------
   Stat / commitment tiles
   -------------------------------------------------------------------------- */

/*
 * The hairline grid is drawn by the TILES, not by the container.
 *
 * It used to be the container's background showing through 1px gaps. That looks
 * right only when the tile count is an exact multiple of the column count —
 * otherwise the leftover cells have no tile covering them and the background
 * shows as a solid grey block. It was visible as three grey cells beside the
 * fifth Commitment tile, and it also hit the nine Why-Work-With-Us tiles at
 * tablet width (where the grid is 2 columns, so the ninth tile orphans).
 *
 * A 1px box-shadow on each tile bridges the 1px gap with its neighbour, forming
 * one continuous line, and the outermost shadows form the outer border. Empty
 * cells draw nothing, so the grid no longer cares how many tiles it holds.
 */
.tile-grid { display: grid; gap: 1px; }
.tile {
  box-shadow: 0 0 0 1px var(--rule);
  background: var(--bg);
  padding: var(--space-l);
  display: grid;
  gap: var(--space-2xs);
  align-content: start;
  transition: background-color var(--dur) var(--ease-out);
}
.on-dark .tile { background: var(--charcoal); box-shadow: 0 0 0 1px var(--rule-inverse); }
.tile:hover { background: var(--bg-raised); }
.on-dark .tile:hover { background: var(--charcoal-soft); }
/* Icons carry a 3.0 non-text floor, and --brass was 2.76 on the ivory tile.
   Tiles run on both surfaces, so the dark branch keeps the lighter brass. */
.tile__icon { color: var(--brass-deep); inline-size: 1.5rem; block-size: 1.5rem; margin-block-end: var(--space-2xs); }
.on-dark .tile__icon { color: var(--brass-light); }
.tile__title { font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; }
.tile__body { font-size: var(--step--1); color: var(--text-muted); }
.on-dark .tile__body { color: var(--text-inverse-muted); }

/* Spaces-we-serve pill list */
.pill-list { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--rule);
  font-size: var(--step--1);
  color: var(--text-muted);
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.pill::before { content: ''; inline-size: 4px; block-size: 4px; background: var(--brass); flex: none; }
.pill:hover { border-color: var(--brass); color: var(--text); }
.on-dark .pill { border-color: var(--rule-inverse); color: var(--text-inverse-muted); }
.on-dark .pill:hover { border-color: var(--brass-light); color: var(--ivory); }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Contact form panel and rail
   -------------------------------------------------------------------------- */

/* The form was sitting naked on the page background, which read as unfinished
   next to the bordered aside. Lifting it onto its own surface makes it an
   object you fill in rather than text that happens to have inputs. */
.form-panel {
  position: relative;
  background: var(--bg-raised);
  box-shadow:
    0 0 0 1px var(--rule),
    0 1.5rem 3.5rem -1.5rem rgba(34, 32, 29, 0.16);
  padding: clamp(1.25rem, 4vw, 2.75rem);
  display: grid;
  gap: clamp(1.75rem, 3.5vw, 2.5rem);
}

/*
 * Inside the panel the controls sit a shade DARKER than the surface they are
 * on, so they read as wells to fill rather than as more panel.
 *
 * Both .input and .form-panel default to --bg-raised, so on the panel the
 * fields were the exact same colour as their container and existed only by
 * virtue of a 1px border. Scoped to .form-panel: elsewhere a raised input on
 * the page background is still the right call.
 *
 * background-COLOR, not the `background` shorthand: .select draws its dropdown
 * chevron as a background-image, and the shorthand resets it to none — doing
 * this the lazy way silently deleted every chevron on the page.
 */
.form-panel .input,
.form-panel .select,
.form-panel .textarea {
  background-color: var(--ivory);
}
.form-panel .input:focus,
.form-panel .select:focus,
.form-panel .textarea:focus {
  background-color: var(--ivory-warm);   /* lifts on focus — the well fills with light */
}

/* Brass reveal along the top edge — the same hairline flourish as the hero
   slider frame, so the two read as one family. */
.form-panel::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 2px;
  background: linear-gradient(to right, var(--brass), var(--brass-pale), transparent);
}

/* Real fieldsets, so the grouping is announced and not merely seen. The UA
   border/padding is reset — the visual grouping is the legend and the rule. */
.form-section {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;   /* fieldset defaults to min-content; without this it
                           refuses to shrink and blows out the grid on mobile */
}

.form-section__legend {
  display: flex;
  align-items: center;
  gap: 0.85em;
  inline-size: 100%;
  padding: 0;
  margin-block-end: var(--space-m);
  border-block-end: 1px solid var(--rule);
  padding-block-end: 0.6rem;
}

.form-section__num {
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--brass-deep);
  font-variant-numeric: tabular-nums;
}

.form-section__title {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--text);
  letter-spacing: var(--tracking-tight);
}

.form-actions {
  display: grid;
  gap: var(--space-s);
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--rule);
}
.form-actions__note {
  font-size: var(--step--2);
  color: var(--text-faint);
  max-inline-size: 62ch;
}

/* ---- The dark rail ------------------------------------------------------ */

.contact-rail {
  background: var(--charcoal);
  color: var(--text-inverse);
  padding: clamp(1.25rem, 3vw, 2rem);
  align-self: start;
}

/* Hairline between blocks rather than four separate boxes. */
.contact-rail__block + .contact-rail__block {
  margin-block-start: var(--space-l);
  padding-block-start: var(--space-l);
  border-block-start: 1px solid var(--rule-inverse);
}

.contact-rail__title {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--ivory);
  margin-block-end: 0.35rem;
}
.contact-rail__body {
  font-size: var(--step--1);
  color: var(--text-inverse-muted);
  margin-block-end: var(--space-s);
}
.contact-rail__note {
  font-size: var(--step--2);
  color: var(--stone-light);
  margin-block-start: 0.6rem;
}
.contact-rail__note strong { color: var(--ivory); }

.contact-rail__phone {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  color: var(--ivory);
  text-decoration: none;
  letter-spacing: var(--tracking-tight);
  transition: color var(--dur-fast) var(--ease-out);
}
.contact-rail__phone svg { inline-size: 0.8em; block-size: 0.8em; color: var(--brass-light); }
.contact-rail__phone:hover { color: var(--brass-light); }

.contact-rail__address {
  font-style: normal;
  color: var(--text-inverse-muted);
  line-height: 1.7;
}

.contact-rail__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.45rem;
}
.contact-rail__list li {
  position: relative;
  padding-inline-start: 1.25rem;
  font-size: var(--step--1);
  color: var(--text-inverse-muted);
}
.contact-rail__list li::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.7em;
  inline-size: 0.6rem;
  block-size: 1px;
  background: var(--brass);
}

/*
 * align-content: start is load-bearing, not tidiness.
 *
 * A grid's align-content defaults to `stretch`, and .field sits in a two-column
 * .form-grid whose items stretch to the tallest in the row. A field WITH a hint
 * has three rows; one without has two. The shorter field was being stretched to
 * match, and its auto rows split the leftover 26px between them — inflating both
 * its label AND its input by 13px each, so the two inputs in a row no longer
 * shared a baseline. Pinning the rows to the top keeps every control aligned and
 * leaves the slack at the bottom where it belongs.
 */
.field { display: grid; gap: 0.4rem; align-content: start; }
.field__label {
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* The required asterisk is aria-hidden, so a screen reader never meets it — a
   sighted user is the ONLY one who gets this signal, which makes its contrast
   the whole ballgame. --brass was 2.76 on the panel. */
.field__req { color: var(--brass-deep); }
.field__hint { font-size: var(--step--2); color: var(--text-faint); }

.input, .select, .textarea {
  inline-size: 100%;
  padding: 0.85rem 1rem;
  min-block-size: 3rem;
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  color: var(--text);
  font-size: var(--step-0);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.input::placeholder, .textarea::placeholder { color: var(--text-faint); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--rule-strong); }
.input:focus, .select:focus, .textarea:focus { background: var(--ivory-warm); border-color: var(--brass); }
.textarea { min-block-size: 8rem; resize: vertical; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%236E675E' stroke-width='1.5'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 12px 8px;
  padding-inline-end: 2.5rem;
}

.field--invalid .input, .field--invalid .select, .field--invalid .textarea {
  border-color: #9E3B2F;
  background: #FDF6F4;
}
.field__error {
  display: flex;
  align-items: center;
  gap: 0.45em;
  font-size: var(--step--2);
  font-weight: 600;
  color: #9E3B2F;
}
.field__error svg { inline-size: 0.9em; block-size: 0.9em; flex: none; }

.checkbox { display: flex; align-items: flex-start; gap: 0.75rem; cursor: pointer; }
.checkbox input {
  inline-size: 1.25rem;
  block-size: 1.25rem;
  margin: 0.2rem 0 0;
  accent-color: var(--brass);
  flex: none;
}
.checkbox__text { font-size: var(--step--1); color: var(--text-muted); }

/* Honeypot — off-screen, not display:none, so bots still fill it. */
.hp-field {
  position: absolute !important;
  inset-inline-start: -9999px;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
}

.alert {
  display: flex;
  gap: var(--space-s);
  padding: var(--space-m);
  border-inline-start: 2px solid var(--brass);
  background: var(--bg-raised);
  font-size: var(--step--1);
}
.alert--success { border-inline-start-color: var(--olive); background: #F2F5EF; }
.alert--error { border-inline-start-color: #9E3B2F; background: #FDF6F4; }
.alert__icon { inline-size: 1.25rem; block-size: 1.25rem; flex: none; color: var(--brass-deep); }
.alert--success .alert__icon { color: var(--olive); }
.alert--error .alert__icon { color: #9E3B2F; }
.alert__title { font-weight: 700; margin-block-end: 0.2rem; }

/* --------------------------------------------------------------------------
   CTA band
   -------------------------------------------------------------------------- */

.cta-band { background: var(--charcoal); color: var(--ivory); position: relative; overflow: hidden; }
.cta-band::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 1px;
  background: linear-gradient(to right, transparent, var(--brass), transparent);
}
.cta-band__inner { display: grid; gap: var(--space-l); align-items: center; }
.cta-band__title { max-width: 18ch; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer { background: var(--charcoal); color: var(--text-inverse-muted); padding-block: var(--space-2xl) var(--space-m); }
.footer__grid { display: grid; gap: var(--space-xl); }
.footer__brand { display: grid; gap: var(--space-s); justify-items: start; }
/* The client lockup is a ~1038px square raster; without a cap it would push past
   a 320px viewport. */
.footer__brand img { max-inline-size: 100%; block-size: auto; }
.footer__logo { inline-size: clamp(11rem, 40vw, 15rem); }
.footer__desc { font-size: var(--step--1); max-inline-size: 40ch; }
.footer__heading {
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ivory);
  margin-block-end: var(--space-s);
}
.footer__list { display: grid; gap: 0.55rem; font-size: var(--step--1); }
.footer__list a:hover { color: var(--brass-light); }
/* Shared by the footer and the contact page's light tiles — hence neutral names
   and context-driven colours rather than footer-specific ones. */
.address-block { font-style: normal; font-size: var(--step--1); line-height: var(--leading-relaxed); }
.gstin-line {
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-block-start: var(--space-s);
}
.gstin-line strong { color: var(--text); font-weight: 600; }

/* --stone is a light-surface value; on charcoal it measured 2.91 and failed AA.
   stone-light gets 6.37 here, and the strong lifts to full ivory so the label
   still outranks the number. */
.footer .gstin-line, .on-dark .gstin-line { color: var(--stone-light); }
.footer .gstin-line strong, .on-dark .gstin-line strong { color: var(--ivory); }
/*
 * Large phone link. Used on the dark footer AND inside light tiles on the
 * contact page, so it takes its colour from context rather than hard-coding
 * ivory — which previously rendered it invisible on the light tiles.
 */
.phone-link {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  color: var(--text);
  transition: color var(--dur-fast) var(--ease-out);
}
.phone-link:hover { color: var(--walnut); }
/* Light-surface branch; .footer / .on-dark below already swap to brass-light. */
.phone-link svg { color: var(--brass-deep); }

.footer .phone-link,
.on-dark .phone-link { color: var(--ivory); }
.footer .phone-link:hover,
.on-dark .phone-link:hover { color: var(--brass-light); }
.footer .phone-link svg,
.on-dark .phone-link svg { color: var(--brass-light); }
.footer__bottom {
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--rule-inverse);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  font-size: var(--step--2);
  /* Dark footer — stone was 2.91 here and failed AA. */
  color: var(--stone-light);
}
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--space-m); }
.footer__legal a:hover { color: var(--brass-light); }

/* --------------------------------------------------------------------------
   Floating back-to-top

   Physical properties (right/bottom), NOT logical ones. The element this
   replaced used logical insets together with a rotated writing-mode, which
   silently swapped its axes and threw it to the opposite corner. Nothing here
   rotates, and nothing here is logical.
   -------------------------------------------------------------------------- */

.to-top-float {
  /* One source of truth for the size, so the ring cannot drift from the button. */
  --btn-size: 3rem;

  position: fixed;
  right: var(--gutter);
  bottom: var(--space-m);
  z-index: var(--z-actionbar);

  display: grid;
  place-items: center;
  inline-size: var(--btn-size);
  block-size: var(--btn-size);

  background: rgba(34, 32, 29, 0.82);
  backdrop-filter: blur(10px);
  border: 1px solid var(--rule-inverse);
  border-radius: 50%;
  color: var(--ivory);

  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

/*
 * Reveal — CSS scroll-driven, no JavaScript.
 *
 * Same reasoning as the page-hero parallax: a scroll listener works, but it
 * cannot be verified in automation here (a backgrounded tab fires no scroll
 * events and ticks no transitions), and it is a moving part that can fail
 * silently. scroll() lets the browser drive it, and getAnimations() can prove
 * it is running.
 *
 * The @supports guard matters: without it, a browser lacking scroll timelines
 * would leave the button stuck at opacity 0 forever. Unsupported means the
 * button is simply always visible — still useful, never broken.
 */
@supports (animation-timeline: scroll()) {
  .to-top-float {
    opacity: 0;
    visibility: hidden;
    transform: translateY(0.75rem) scale(0.9);

    animation: to-top-reveal linear both;
    animation-timeline: scroll(root block);
    /* Appears as the first screen leaves — where the old "Scroll" cue used to sit. */
    animation-range: 80vh 100vh;
  }

  @keyframes to-top-reveal {
    from { opacity: 0; visibility: hidden; transform: translateY(0.75rem) scale(0.9); }
    to   { opacity: 1; visibility: visible; transform: none; }
  }
}

.to-top-float:hover,
.to-top-float:focus-visible {
  background: var(--brass);
  border-color: var(--brass);
  color: var(--charcoal);
}

/*
 * Scoped to .icon, NOT to `svg`.
 *
 * `.to-top-float svg` also matched the progress ring's SVG and forced it to
 * 1.05rem, so the ring rendered as a small detached circle pinned to the
 * corner instead of tracking the button's edge. The ring is a sibling SVG and
 * must size itself.
 */
.to-top-float > .icon {
  inline-size: 1.05rem;
  block-size: 1.05rem;
  transition: transform var(--dur) var(--ease-out);
  /* Sits above the ring, in the middle of the grid. */
  grid-area: 1 / 1;
  z-index: 1;
}
.to-top-float:hover > .icon { transform: translateY(-2px); }

/* A thin brass ring around the button's own edge, showing how far down the page
   you are. Decorative, so it is hidden from assistive tech; the button's label
   carries the meaning.

   The size MUST be explicit. An <svg> is a replaced element: unlike a div it
   does not stretch to fill an inset box, it falls back to intrinsic sizing.

   inset:0 with a 100% size, NOT inset:-1px with a fixed size. Setting top AND
   bottom AND a height over-constrains an absolutely positioned box, and the two
   axes then resolved differently (48 wide but 46 tall), squashing the circle.
   inset:0 + 100% is symmetric and lands the ring flush inside the button's 1px
   border — concentric, and reading as a single ring rather than two. */
.to-top-float__ring {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  /* Start the arc at 12 o'clock rather than 3 o'clock. */
  rotate: -90deg;
  pointer-events: none;
  overflow: visible;
}
.to-top-float__ring circle {
  fill: none;
  stroke: var(--brass);
  stroke-width: 1.5;
  /* r=23.25 on a 48px box -> circumference ~146. */
  stroke-dasharray: 146;
  stroke-dashoffset: 146;   /* empty until the scroll timeline drives it */
  transition: stroke var(--dur-fast) var(--ease-out);
}
.to-top-float:hover .to-top-float__ring circle { stroke: var(--charcoal); }

/* Reading progress, driven by the document's own scroll position. */
@supports (animation-timeline: scroll()) {
  .to-top-float__ring circle {
    animation: to-top-progress linear both;
    animation-timeline: scroll(root block);
    animation-range: 0% 100%;
  }

  @keyframes to-top-progress {
    from { stroke-dashoffset: 146; }
    to   { stroke-dashoffset: 0; }
  }
}

/* Clear the mobile action bar, which owns the bottom edge on phones. */
@media (max-width: 47.99rem) {
  .to-top-float { bottom: calc(3.5rem + var(--space-s) + env(safe-area-inset-bottom, 0px)); }
}

/* Reduced motion: the button still appears and the ring still fills — both are
   information, not decoration — but nothing slides or scales. */
@media (prefers-reduced-motion: reduce) {
  @supports (animation-timeline: scroll()) {
    .to-top-float { transform: none; }
    @keyframes to-top-reveal {
      from { opacity: 0; visibility: hidden; transform: none; }
      to   { opacity: 1; visibility: visible; transform: none; }
    }
  }
  .to-top-float:hover svg { transform: none; }
}

/* --------------------------------------------------------------------------
   WhatsApp floating button (desktop only — mobile uses the action bar)
   -------------------------------------------------------------------------- */

.whatsapp-float {
  --wa-green: #25D366;
  --btn-size: 3rem;

  position: fixed;
  right: var(--gutter);
  /* Stack above the to-top button with a small gap */
  bottom: calc(var(--space-m) + var(--btn-size) + var(--space-xs));
  z-index: var(--z-actionbar);

  display: inline-flex;
  align-items: center;
  gap: 0.6rem;

  block-size: var(--btn-size);
  padding-inline: 0.875rem;
  border-radius: calc(var(--btn-size) / 2);

  background: var(--wa-green);
  color: #fff;
  box-shadow: 0 2px 12px rgba(37, 211, 102, 0.35);
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  max-inline-size: var(--btn-size);

  transition: max-inline-size var(--dur) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}

/* Hidden on mobile — action bar handles it there */
@media (max-width: 47.99rem) {
  .whatsapp-float { display: none; }
}

.whatsapp-float .icon {
  flex-shrink: 0;
  inline-size: 1.2rem;
  block-size: 1.2rem;
}

.whatsapp-float__label {
  overflow: hidden;
  max-inline-size: 0;
  opacity: 0;
  transition: max-inline-size var(--dur) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}

.whatsapp-float:hover,
.whatsapp-float:focus-visible {
  max-inline-size: 14rem;
  box-shadow: 0 4px 20px rgba(37, 211, 102, 0.45);
  background: #20b858;
}

.whatsapp-float:hover .whatsapp-float__label,
.whatsapp-float:focus-visible .whatsapp-float__label {
  max-inline-size: 10rem;
  opacity: 1;
}

/* Same scroll-driven reveal as to-top-float */
@supports (animation-timeline: scroll()) {
  .whatsapp-float {
    opacity: 0;
    visibility: hidden;
    transform: translateY(0.75rem) scale(0.9);
    animation: to-top-reveal linear both;
    animation-timeline: scroll(root block);
    animation-range: 80vh 100vh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .whatsapp-float,
  .whatsapp-float__label { transition: none; }
}

/* --------------------------------------------------------------------------
   Mobile sticky action bar
   -------------------------------------------------------------------------- */

.action-bar {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: var(--z-actionbar);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  background: rgba(34, 32, 29, 0.94);
  backdrop-filter: blur(12px);
  border-block-start: 1px solid var(--rule-inverse);
  padding-block-end: env(safe-area-inset-bottom, 0);
  transform: translateY(100%);
  transition: transform var(--dur) var(--ease-out);
}
.action-bar[data-visible='true'] { transform: none; }
.action-bar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  min-block-size: 3.5rem;
  padding: 0.5rem;
  color: var(--ivory);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.action-bar__item + .action-bar__item { border-inline-start: 1px solid var(--rule-inverse); }
.action-bar__item svg { inline-size: 1.05rem; block-size: 1.05rem; color: var(--brass-light); }
.action-bar__item:active { background: var(--charcoal-tint); }
.action-bar__item--accent { background: var(--brass); color: var(--charcoal); }
.action-bar__item--accent svg { color: var(--charcoal); }

/* Keep the bar from covering the last of the page. */
@media (max-width: 47.99rem) {
  body[data-actionbar='true'] { padding-block-end: 3.5rem; }
}

/* --------------------------------------------------------------------------
   Misc
   -------------------------------------------------------------------------- */

.note {
  margin-block-start: var(--space-l);
  font-size: var(--step--2);
  /* --text-muted, not --text-faint. text-faint is scaled for plain --ivory
     (4.61 there); notes also sit on the warmer #E8DFD1 band, where it dropped to
     3.92 and failed AA. The rule down the left already marks this as an aside —
     the colour does not have to whisper as well. */
  color: var(--text-muted);
  border-inline-start: 1px solid var(--rule);
  padding-inline-start: var(--space-s);
  max-inline-size: 62ch;
}
/* stone-light, not stone: this is the on-dark branch (stone was 2.91 here). */
.on-dark .note { border-inline-start-color: var(--rule-inverse); color: var(--stone-light); }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rule);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ── About hero ─────────────────────────────────────────────────────────── */

.about-hero {
  position: relative;
  isolation: isolate;
  background: var(--charcoal);
  color: var(--ivory);
  overflow: clip;
  padding-block: calc(var(--header-h) + clamp(2rem, 4vw, 5rem)) clamp(3rem, 2rem + 5vw, 6rem);
  min-block-size: clamp(36rem, 92svh, 60rem);
  display: flex;
  align-items: flex-end;
}

.about-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.about-hero__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Richer than the material-texture hero — the cafe render has warm gold tones
     worth keeping. Slight darkening only, no desaturation. */
  filter: brightness(0.52) contrast(1.08);
}

/* Scrim: heaviest at bottom where text sits, lighter up top to show the image. */
.about-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(18, 17, 15, 0.92) 0%,
    rgba(18, 17, 15, 0.55) 45%,
    rgba(18, 17, 15, 0.18) 100%
  );
}

.about-hero__inner {
  position: relative;
  display: grid;
  gap: var(--space-m);
  max-inline-size: 42ch;
}

.about-hero__eyebrow { color: var(--accent); }

.about-hero__title {
  color: var(--ivory);
  max-inline-size: 16ch;
}
.about-hero__title em { color: var(--accent); font-style: italic; }

.about-hero__lede {
  font-size: var(--step-1);
  color: var(--stone-light);
  max-inline-size: 38ch;
  line-height: 1.6;
}

/* ==========================================================================
   Premium services page — /services redesign
   svc-feature: editorial alternating image/text blocks (no clip-path reveal
   so images appear as soon as the browser fetches them, not on scroll).
   svc-card: 3-col grid for supporting services.
   svc-stat-strip: dark stat band between sections.
   svc-turnkey: dark editorial CTA section.
   ========================================================================== */

/* ── Featured service blocks ─────────────────────────────────────────────── */

.svc-feature {
  display: grid;
  gap: var(--space-l);
}
.svc-feature + .svc-feature { margin-block-start: var(--space-2xl); }

.svc-feature__media {
  position: relative;
  overflow: hidden;
}
.svc-feature__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
  display: block;
}
.svc-feature:hover .svc-feature__media img { transform: scale(1.03); }

.svc-feature__body {
  display: grid;
  gap: var(--space-s);
  align-content: start;
}

.svc-feature__meta {
  display: flex;
  align-items: baseline;
  gap: var(--space-m);
}
.svc-feature__num {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 600;
  font-style: italic;
  line-height: 1;
  color: var(--brass-pale);
  flex: none;
}
.svc-feature__title {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 600;
  line-height: 1.2;
  max-inline-size: 22ch;
}
.svc-feature__lede {
  font-size: var(--step-0);
  color: var(--text-muted);
  line-height: 1.7;
  max-inline-size: 46ch;
}
.svc-feature__list {
  display: grid;
  gap: 0.4rem;
  font-size: var(--step--1);
  color: var(--text-muted);
  margin-block-start: var(--space-s);
}
.svc-feature__list li { display: flex; gap: 0.7em; align-items: baseline; }
.svc-feature__list li::before {
  content: '';
  inline-size: 0.5em;
  block-size: 1px;
  background: var(--brass);
  flex: none;
  translate: 0 -0.3em;
}
.svc-feature__cta { margin-block-start: var(--space-s); }

/* ── Stat strip ──────────────────────────────────────────────────────────── */

.svc-stat-strip {
  background: var(--charcoal);
  padding-block: var(--space-2xl);
}
.svc-stat-strip__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-xl) var(--space-2xl);
  margin: 0;
  padding: 0;
}
.svc-stat-strip__item { text-align: center; }
.svc-stat-strip__item dt {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 600;
  font-style: italic;
  color: var(--brass-light);
  line-height: 1;
}
.svc-stat-strip__item dd {
  display: block;
  font-size: var(--step--2);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--stone-light);
  margin: 0.4rem 0 0;
}

/* ── Supporting services grid ────────────────────────────────────────────── */

.svc-grid {
  display: grid;
  gap: var(--space-m);
  margin-block-start: var(--space-xl);
}
.svc-card {
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--ivory);
  border: 1px solid var(--rule);
  border-block-start: 2px solid var(--rule);
  position: relative;
  overflow: hidden;
  transition: border-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
  color: inherit;
}
.svc-card:hover {
  border-block-start-color: var(--brass);
  box-shadow: 0 4px 24px rgba(0,0,0,0.08);
}
.svc-card__thumb {
  aspect-ratio: 3 / 2;
  overflow: hidden;
}
.svc-card__thumb img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
  display: block;
}
.svc-card:hover .svc-card__thumb img { transform: scale(1.04); }

.svc-card__inner {
  display: grid;
  gap: 0.5rem;
  align-content: start;
  padding: var(--space-m) var(--space-m) var(--space-l);
}
.svc-card__inner--no-thumb { padding-block-start: var(--space-l); }

.svc-card__num {
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--brass);
  font-variant-numeric: tabular-nums;
}
.svc-card__title {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.25;
  margin-block-start: 0.25rem;
}
.svc-card__summary {
  font-size: var(--step--1);
  color: var(--text-muted);
  line-height: 1.6;
  margin-block-start: 0.25rem;
}
.svc-card__go {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  margin-block-start: var(--space-s);
  transition: color var(--dur) var(--ease-out);
}
.svc-card__go svg { inline-size: 0.85em; block-size: 0.85em; }
.svc-card:hover .svc-card__go { color: var(--brass); }

/* ── Turnkey dark section ────────────────────────────────────────────────── */

.svc-turnkey {
  background: var(--charcoal);
  padding-block: var(--space-3xl);
}
.svc-turnkey__inner {
  display: grid;
  gap: var(--space-m);
  max-inline-size: 54ch;
}
.svc-turnkey__eyebrow { color: var(--brass); }
.svc-turnkey__title {
  color: var(--ivory);
  max-inline-size: 18ch;
}
.svc-turnkey__title em {
  color: var(--brass-light);
  font-style: italic;
}
.svc-turnkey__body {
  display: grid;
  gap: var(--space-s);
  color: var(--stone-light);
  font-size: var(--step-0);
  line-height: 1.75;
}

/* ── Responsive breakpoints for svc-* ───────────────────────────────────── */

@media (min-width: 36rem) {
  .svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 62rem) {
  .svc-feature {
    grid-template-columns: 55fr 45fr;
    gap: var(--space-2xl);
    align-items: center;
  }
  .svc-feature--flip .svc-feature__media { order: 2; }
  .svc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
