/* ============================================
   HEMUS Web Solutions — design tokens
   ============================================ */
:root {
  --bg-base: #000000;
  --surface-1: #202022;
  --surface-2: #2B2B2E;
  --accent-1: #D9A61E;
  --accent-2: #FFDD66;
  --accent-gradient: linear-gradient(100deg, var(--accent-1), var(--accent-2));
  --text-primary: #FFFFFF;
  --text-muted: #9C9C9C;
  --border-soft: rgba(255, 255, 255, 0.1);
  --border-softer: rgba(255, 255, 255, 0.06);

  --font-display: "Fraunces", serif;
  --font-body: "Inter", sans-serif;
  /* Condensed uppercase face used by the header tiers and the hero headline. */
  --font-header: "Bebas Neue", "Inter", sans-serif;

  /* Both header tiers share one height so they read as a matched pair. */
  --bar-height: 56px;

  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 2rem;
  --space-lg: 4rem;
  --space-xl: 7rem;

  --radius-sm: 10px;
  --radius-md: 16px;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

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

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
}

body {
  margin: 0;
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  overflow-x: hidden;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.1;
  margin: 0;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(2rem, 3.2vw, 2.85rem); font-weight: 450; }
h2 { font-size: clamp(2rem, 3.2vw, 2.85rem); font-weight: 450; }
h3 { font-size: clamp(1.25rem, 1.8vw, 1.5rem); font-weight: 500; }

p { margin: 0; color: var(--text-muted); max-width: 62ch; }

a { color: inherit; text-decoration: none; }

ul, ol { margin: 0; padding: 0; list-style: none; }

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

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--accent-1);
  color: var(--bg-base);
  padding: 0.75rem 1.25rem;
  z-index: 999;
  border-radius: 0 0 8px 0;
  font-weight: 600;
}
.skip-link:focus {
  left: 0;
}

:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 3px;
  border-radius: 4px;
}

.section-inner {
  max-width: 1160px;
  margin: 0 auto;
  padding: var(--space-xl) 1.75rem;
}
.section-inner-narrow { max-width: 720px; }
.section-inner-full { max-width: 1160px; padding-bottom: var(--space-md); }

/* ============================================
   Preloader
   ============================================ */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-base);
  transition: opacity 0.4s ease, visibility 0.4s ease;
}
.preloader-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
}
.preloader-mark .brand-mark { height: 2rem; display: block; margin: 0 auto 0.75rem; }
.preloader-mark {
  font-family: var(--font-display);
  font-size: 1.4rem;
  letter-spacing: 0.02em;
  color: var(--text-primary);
}
.preloader-text {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.preloader-bar {
  width: 160px;
  height: 2px;
  border-radius: 2px;
  background: var(--border-soft);
  overflow: hidden;
}
.preloader-bar-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--accent-gradient);
  transition: width 0.85s var(--ease-out);
}
.preloader.is-done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* ============================================
   Custom cursor
   ============================================ */
.cursor {
  position: fixed;
  top: 0; left: 0;
  width: 0; height: 0;
  pointer-events: none;
  z-index: 9999;
  /* NO blend mode. `mix-blend-mode: difference` lived here and solved the
     black-vs-white-band problem, but it created a worse one over TEXT: the
     arrow inverts per pixel, so straddling a black letter on a white page made
     half the arrow black and half white. It read as the letter slicing through
     the cursor — reported as "the cursor goes under the letter".

     A two-tone pointer solves all three grounds at once and depends on no
     backdrop: dark outline + light fill, which is exactly why every OS pointer
     is built this way. Don't reintroduce a blend mode here. */
}
.cursor-dot {
  position: absolute;
  top: 0; left: 0;
  width: 22px; height: 22px;
  margin: 0;
  /* Layer 1 — the OUTLINE. Same arrow path but stroked, so the silhouette is
     ~1.5px fatter all round than the fill sitting on top of it. */
  background-color: #0A0A0A;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 2L2 17L6.5 13.5L10 21L12.3 20L8.7 12.6L14 12.6Z' stroke='%23000' stroke-width='3.4' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 2L2 17L6.5 13.5L10 21L12.3 20L8.7 12.6L14 12.6Z' stroke='%23000' stroke-width='3.4' stroke-linejoin='round'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  /* Grounds the white fill on a white page, invisible on black where it isn't
     needed. Applies to the composited two-tone shape, not each layer. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
  transform-origin: 8% 8%;
  transition: transform 0.2s ease;
}
.cursor-dot::after {
  /* Layer 2 — the FILL, drawn over the outline using the unstroked path. */
  content: "";
  position: absolute;
  inset: 0;
  background-color: #FFFFFF;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 2L2 17L6.5 13.5L10 21L12.3 20L8.7 12.6L14 12.6Z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 2L2 17L6.5 13.5L10 21L12.3 20L8.7 12.6L14 12.6Z'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  transition: background-color 0.2s ease;
}
.cursor-ring { display: none; }
/* Nothing inverts any more, so the brand gold is safe to use again — it reads
   as gold on every ground instead of turning blue-violet on the white bands. */
.cursor.is-hovering .cursor-dot { transform: scale(1.35); }
.cursor.is-hovering .cursor-dot::after { background-color: var(--accent-1); }
.cursor.is-hidden { opacity: 0; }

/* Show custom cursor only on fine-pointer devices with JS enabled */
.has-custom-cursor,
.has-custom-cursor a,
.has-custom-cursor button {
  cursor: none;
}

/* ============================================
   Announcement bar (sits above the nav, scrolls away — not sticky)
   ============================================ */
.announce-bar {
  background: #000000;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.announce-bar-inner {
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 1.75rem;
  height: var(--bar-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
/* Right-to-left marquee. The track holds the message TWICE, back to back, and
   slides exactly -50% — so the second copy lands where the first began and the
   loop is seamless. The duplicate is aria-hidden with tabindex="-1" on its link
   so screen readers and keyboard users only ever meet the real one. */
.announce-bar-ticker {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  align-self: stretch;
  display: flex;
  align-items: center;
}
.announce-bar-track {
  display: flex;
  align-items: center;
  width: max-content;
  animation: announceScroll 26s linear infinite;
}
.announce-bar-ticker:hover .announce-bar-track { animation-play-state: paused; }
@keyframes announceScroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.announce-bar-msg strong { font-weight: 700; color: var(--accent-1); }
.announce-bar-sep { padding-right: 4rem; color: rgba(255,255,255,0.35); }
.announce-bar-msg {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  white-space: nowrap;
  padding-right: 4rem;
  margin: 0;
  max-width: none;
  font-family: var(--font-header);
  font-size: 1rem;
  letter-spacing: 0.5px;
  color: #E9E6DD;
}
.announce-bar-link {
  color: var(--accent-1);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
  transition: color 0.2s ease;
}
.announce-bar-link:hover { color: var(--accent-2); }

/* Full-height cells divided by hairlines; hover inverts each into a gold chip. */
.announce-bar-social {
  display: flex;
  align-self: stretch;
  flex-shrink: 0;
  border-left: 1px solid rgba(255, 255, 255, 0.18);
  border-right: 1px solid rgba(255, 255, 255, 0.18);
}
.announce-bar-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  color: #E9E6DD;
  transition: color 0.2s ease, background 0.2s ease;
}
.announce-bar-icon svg { width: 18px; height: 18px; fill: currentColor; }
.announce-bar-icon + .announce-bar-icon { border-left: 1px solid rgba(255, 255, 255, 0.18); }
.announce-bar-icon:hover { color: #000000; background: var(--accent-1); }

/* ============================================
   Nav
   ============================================ */
.nav-wrap {
  position: sticky;
  top: 0;
  z-index: 500;
  background: #2A2A2D;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.nav {
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 1.75rem;
  height: var(--bar-height);
  display: flex;
  align-items: center;
  gap: 2.5rem;
}
.nav-logo {
  font-family: var(--font-header);
  font-size: 1.4rem;
  font-weight: 400;
  letter-spacing: 1px;
  line-height: 1;
  color: #F2F0EA;
}
/* The real logo: gold monogram beside the wordmark. The mark is inline SVG so
   it takes currentColor and costs no extra request; the wordmark stays live
   text in Fraunces, which the site already loads — using the logo file's own
   Bodoni + Jost would have added two more families for two words. */
.brand-mark {
  width: auto;
  height: 1.65rem;
  flex-shrink: 0;
  color: var(--accent-1);
  fill: currentColor;
}
.nav-logo-stacked {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  line-height: 1;
}
.nav-logo-text {
  display: flex;
  flex-direction: column;
  line-height: 1;
}
.footer-logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.footer-logo .brand-mark { height: 1.35rem; }
.nav-logo-word {
  font-family: var(--font-display);
  font-size: 1.22rem;
  font-weight: 500;
  letter-spacing: 3px;
  line-height: 1;
  color: #F2F0EA;
}
.nav-logo-text .nav-logo-word {
  padding-bottom: 0.28rem;
  border-bottom: 1px solid var(--accent-1);
}
.nav-logo-sub {
  margin-top: 0.26rem;
  font-family: var(--font-body);
  font-size: 0.5rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent-1);
}

/* Header lockup entrance: HEMUS drops in letter by letter, then the sub-line
   shoots up under it. Added by initLogoEntrance(), which only runs on the
   .nav-logo-stacked header logo — the footer shares .nav-logo-word and is
   deliberately left alone. */
.nav-logo-word .nl {
  display: inline-block;
  animation: logoLetterDrop 0.55s var(--ease-out) both;
}
@keyframes logoLetterDrop {
  from { opacity: 0; transform: translateY(-0.75em); }
  to   { opacity: 1; transform: none; }
}
/* `display: block` matters — the sub-line is a <span>, and transform does
   nothing on an inline box. */
.nav-logo-sub.is-anim {
  display: block;
  animation: logoSubRise 0.55s var(--ease-out) 0.55s both;
}
@keyframes logoSubRise {
  from { opacity: 0; transform: translateY(0.8em); }
  to   { opacity: 1; transform: none; }
}
.nav-menu {
  display: flex;
  align-items: center;
  gap: 2.125rem;
  margin-left: auto;
}
.nav-menu a {
  font-family: var(--font-header);
  font-size: 1rem;
  letter-spacing: 0.6px;
  color: #E9E6DD;
  transition: color 0.2s ease;
}
.nav-menu a:hover { color: var(--accent-1); }
.nav-menu a[aria-current="page"] { color: var(--accent-1); }
.nav-cta {
  font-family: var(--font-header);
  font-size: 1rem;
  letter-spacing: 0.6px;
  color: #000000;
  background: var(--accent-1);
  padding: 0.55rem 1.375rem;
  border-radius: 2px;
  transition: opacity 0.2s ease;
}
.nav-cta:hover { background: var(--accent-2); opacity: 1; }
.nav-cta:active { background: #C08F14; }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 32px; height: 32px;
  background: none;
  border: none;
  margin-left: auto;
}
.nav-toggle span {
  display: block;
  height: 1.5px;
  background: var(--text-primary);
  border-radius: 2px;
}

/* ============================================
   Hero
   ============================================ */
.hero {
  position: relative;
  height: 100vh;
  min-height: 640px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 1.75rem;
  border-bottom: 1px solid var(--border-softer);
  overflow: hidden;
}
/* The photographic layer. Holds the still as its background (fallback +
   what the GSAP drift animates when no video runs) with the clip layered
   over it. The gradient/vignette wash lives in .hero-atmosphere ABOVE this,
   so it tints the video and the still identically. */
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background: url("assets/img/hero-still.jpg") center / cover no-repeat;
  filter: brightness(0.8) saturate(1.05);
  transform-origin: 50% 50%;
  will-change: transform;
}
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* No filter here: .hero-media (this element's parent) already carries the
     brightness/saturate wash, and CSS filters compound down the tree — setting
     it in both places rendered the clip at a fraction of the intended brightness. */
  opacity: 0;
  transition: opacity 1.2s ease;
}
/* Only fades up once the clip is actually playing, so a stalled load never
   leaves a black hole where the still used to be. */
.hero-video.is-playing { opacity: 1; }

.hero-atmosphere {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.4) 0%,
    rgba(0, 0, 0, 0.12) 40%,
    rgba(0, 0, 0, 0.5) 100%
  );
}
.hero-inner {
  position: relative;
  z-index: 2;
  max-width: 1120px;
  margin: 0 auto;
  text-align: center;
}
.hero-brand {
  margin-bottom: var(--space-md);
}
.hero-brand-word {
  display: inline-flex;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(3.25rem, 9vw, 7.5rem);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.hero-brand-letter {
  display: inline-block;
  will-change: transform, opacity;
}
.hero-brand-sub {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent-1);
}
.hero-headline {
  font-family: var(--font-header);
  font-weight: 400;
  text-transform: uppercase;
  /* Sized so each authored line fits on ONE visual line at every desktop
     width — at 7vw/6.2rem both lines wrapped, rendering the headline as four. */
  font-size: clamp(2.2rem, 5.2vw, 5rem);
  line-height: 0.98;
  letter-spacing: 0.5px;
  color: #F2F0EA;
  margin: 0;
}
/* Two authored lines. Each is its own transform target, and each clips its own
   overflow so a line sliding in is masked rather than floating over the layout. */
.hero-headline-line {
  display: block;
  overflow: hidden;
  white-space: nowrap;
}
.hero-headline-line > span {
  display: block;
  will-change: transform, opacity;
}
.hero-divider {
  width: 90px;
  height: 3px;
  margin: 28px auto;
  background: var(--accent-1);
  transform-origin: center;
}
.hero-sub {
  margin: 0 auto;
  font-size: clamp(1rem, 1.6vw, 1.3rem);
  font-weight: 300;
  letter-spacing: 0.3px;
  line-height: 1.65;
  color: #D8D5CC;
  max-width: 46ch;
  /* The subline is thin and light-grey over lit windows. Low-cost insurance now
     that the background runs brighter; the headline is heavy enough not to
     need it. */
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.65);
}
.hero-ctas {
  margin-top: 2.5rem;
  display: flex;
  justify-content: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.hero-scroll-cue {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: 2.25rem;
  transform: translateX(-50%);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(242, 240, 234, 0.5);
  border-radius: 50%;
  color: #F2F0EA;
  animation: heroScrollBounce 2.2s ease-in-out infinite;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.hero-scroll-cue:hover { color: var(--text-primary); border-color: var(--border-soft); }
@keyframes heroScrollBounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(6px); }
}

/* ONE button identity across the site. This used to be three: a 100px gradient
   pill (.btn-primary), a 2px flat-gold rectangle (.nav-cta) and a square black
   block (.cta-gold-btn) — all three visible inside one scroll of rates.html.
   2px flat gold was chosen because it already matched the nav CTA and the form
   fields, and a squared edge reads more editorial than a pill.
   The gradient went with it: at button size `--accent-gradient` just reads as
   an uneven gold, and "gold is an accent, never a large fill" is the palette
   rule this site is built on. */
.btn {
  display: inline-flex;
  align-items: center;
  padding: 0.95rem 2rem;
  border-radius: 2px;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.btn-primary {
  background: var(--accent-1);
  color: #0A0A0A;
}
.btn-primary:hover { background: var(--accent-2); }
.btn-primary:active { background: #C08F14; }
.btn-ghost {
  border: 1px solid var(--border-soft);
  color: var(--text-primary);
}
.btn-ghost:hover { border-color: var(--accent-1); color: var(--accent-1); }
.btn-ghost:active { border-color: var(--accent-2); color: var(--accent-2); }
.btn-outline {
  border: 1px solid var(--border-soft);
  color: var(--text-primary);
  width: 100%;
  justify-content: center;
  margin-top: 1.75rem;
}
.btn-outline:hover { border-color: var(--accent-1); color: var(--accent-1); }
.btn-outline:active { border-color: var(--accent-2); }

.hero-mark-number {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 5rem;
  line-height: 1;
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ============================================
   Services
   ============================================ */

/* Single-column disclosure list. Hovering (or focusing, or tapping) a row opens
   it: the row's own header stays put and the panel expands underneath, so the
   thing under the cursor never moves out from under it. Rows below slide down. */
.services-accordion {
  border-top: 1px solid var(--border-softer);
  max-width: 900px;
}
.service-row {
  border-bottom: 1px solid var(--border-softer);
}
.service-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  background: none;
  border: none;
  text-align: left;
  padding: 1.5rem 0.25rem;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  color: var(--text-muted);
  transition: color 0.25s ease, padding-left 0.35s var(--ease-out);
}
.service-item-num {
  font-size: 0.8rem;
  font-style: italic;
  color: var(--text-muted);
  transition: color 0.25s ease;
}
.service-item-name { flex: 1; }
.service-item-chevron {
  display: flex;
  color: var(--text-muted);
  transition: transform 0.35s var(--ease-out), color 0.25s ease;
}

.service-row.is-active .service-item {
  color: var(--text-primary);
  padding-left: 1rem;
}
.service-row.is-active .service-item-num,
.service-row.is-active .service-item-chevron { color: var(--accent-1); }
.service-row.is-active .service-item-chevron { transform: rotate(180deg); }

/* The gold spine that used to mark the active tab, now on the open row. */
.service-row { position: relative; }
.service-row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.5rem;
  width: 4px;
  height: 1.6rem;
  border-radius: 4px;
  background: var(--accent-gradient);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.service-row.is-active::before { opacity: 1; }

/* Height is animated from a measured pixel value set by the script, so the
   panel can expand smoothly without a hardcoded max-height guess. */
.accordion-panel {
  height: 0;
  overflow: hidden;
  transition: height 0.4s var(--ease-out);
}
.service-panel-inner {
  padding: 0 0.25rem 1.75rem 1rem;
}
.service-panel p {
  font-size: 1.02rem;
  line-height: 1.7;
  max-width: 62ch;
}

/* No JS (or no measurement yet): every panel is simply open and readable. */
.accordion:not(.is-enhanced) .accordion-panel { height: auto; }

@media (prefers-reduced-motion: reduce) {
  .accordion-panel { transition: none; }
}


/* ============================================
   Pricing
   ============================================ */
/* No background here: `main > section` provides the ground and `.page-light`
   overrides it. Setting `transparent` made the band see-through, which shows
   the pinned header straight through it. */
.pricing-head { max-width: 50ch; margin-bottom: var(--space-lg); }
.pricing-head p { margin-top: 0.75rem; font-size: 1.05rem; }

.pricing-block + .pricing-block { margin-top: var(--space-lg); }
.pricing-block-head {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.75rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border-softer);
}
.pricing-block-eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-1);
  margin: 0;
}
/* Was clamp(1.4rem, 2vw, 1.75rem) -- 28px, which rendered SMALLER than the
   41.6px .price-figure sitting directly beneath it. The heading that frames
   the entire offer must not be quieter than the numbers it introduces. */
.pricing-block-head h2 { font-size: clamp(1.9rem, 3vw, 2.6rem); }

.pricing-bundle {
  margin-top: var(--space-lg);
  padding: 1.5rem 1.75rem;
  border: 1px dashed var(--border-soft);
  border-radius: var(--radius-md);
  font-size: 1rem;
  max-width: none;
  text-align: center;
}
.pricing-bundle strong { color: var(--text-primary); font-weight: 600; }
.pricing-bundle a {
  color: var(--accent-1);
  text-decoration: none;
  font-weight: 500;
  transition: color 0.25s ease;
  white-space: nowrap;
}
.pricing-bundle a:hover { color: var(--accent-2); }

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  align-items: stretch;
}
.price-card {
  padding: 2.25rem 2rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-soft);
  display: flex;
  flex-direction: column;
}
.price-card-featured {
  background: linear-gradient(165deg, var(--surface-2), #242422);
  border: 1px solid transparent;
  background-clip: padding-box;
  position: relative;
  box-shadow: 0 20px 45px -20px rgba(217, 166, 30, 0.3);
}
.price-card-featured::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-md);
  padding: 1px;
  background: var(--accent-gradient);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
.price-badge {
  display: inline-block;
  align-self: flex-start;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--bg-base);
  background: var(--accent-gradient);
  padding: 0.3rem 0.8rem;
  border-radius: 100px;
  margin-bottom: 1rem;
}
.price-tagline {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-top: 0.35rem;
}
.price-amount { margin-top: 1.5rem; display: flex; align-items: baseline; gap: 0.3rem; }
.price-figure {
  font-family: var(--font-display);
  font-size: 2.6rem;
  color: var(--text-primary);
}
.price-period { color: var(--text-muted); font-size: 0.95rem; }
.price-features {
  margin-top: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  flex-grow: 1;
}
.price-features li {
  font-size: 0.92rem;
  color: var(--text-muted);
  padding-left: 1.2rem;
  position: relative;
  line-height: 1.5;
}
.price-features li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.5em;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent-1);
}

/* ============================================
   Page header with a video background (about.html)
   Same three-layer stack and same darkening recipe as the homepage hero:
   media (still + clip) -> gradient wash -> content.
   ============================================ */
.page-hero {
  position: relative;
  /* Taller than it was (58vh): a short wide band crops a 16:9 source hard, and
     subjects were losing their tops. See the crop note in CLAUDE.md. */
  min-height: 68vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  border-bottom: 1px solid var(--border-softer);
}
.page-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}
/* Per-page still + grade. About is night footage and takes the shared recipe;
   the services clip is a bright daytime aerial, so identical NUMBERS would give
   a blue-sky header that breaks the palette — matching the LOOK means grading
   it down and desaturating it toward the black/white/gold system. */
.page-hero--about .page-hero-media {
  background-image: url("assets/img/about-vancouver-still.jpg");
  filter: brightness(0.8) saturate(1.05);
}
.page-hero--services .page-hero-media {
  background-image: url("assets/img/services-city-still.jpg");
  background-position: center 34%;
  filter: brightness(0.55) saturate(0.2);
}
/* Night photo with warm lamps — takes the same recipe as the About clip.
   The harsher daytime grade just deadens the amber that makes it fit. */
.page-hero--testimonial .page-hero-media {
  background-image: url("assets/img/testimonial-header.jpg");
  /* Crop biased high: a centre crop cut the top off the steam clock. */
  background-position: center 20%;
  filter: brightness(0.8) saturate(1.05);
}
/* Bronze sculpture, already near-neutral — needs less desaturation than the
   daytime aerials to keep the form readable. */
.page-hero--rates .page-hero-media {
  background-image: url("assets/img/rates-train-still.jpg");
  background-position: center 57%;
  filter: brightness(0.7) saturate(0.3);
}
.page-hero--faq .page-hero-media {
  background-image: url("assets/img/faq-header.jpg");
  background-position: center 36%;
  filter: brightness(0.8) saturate(1.05);
}
.page-hero--quote .page-hero-media {
  background-image: url("assets/img/quote-header-still.jpg");
  /* The flag is bright red and white — the worst possible ground for white
     type, and the only saturated red on the site. Graded down hard. */
  filter: brightness(0.62) saturate(0.3);
}
.page-hero-media .hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.page-hero-media .hero-video.is-playing { opacity: 1; }
.page-hero-atmosphere {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.4) 0%,
    rgba(0, 0, 0, 0.12) 40%,
    rgba(0, 0, 0, 0.5) 100%
  );
}
/* The image gets ~2.5s on its own before the type arrives, so the view reads
   first. `both` fill keeps the content hidden through the delay. Any change to
   --header-delay shifts the whole sequence together. */
:root { --header-delay: 2.5s; }
@keyframes headerDropIn {
  from { opacity: 0; transform: translateY(-70px); }
  to   { opacity: 1; transform: none; }
}
@keyframes headerRiseIn {
  from { opacity: 0; transform: translateY(34px); }
  to   { opacity: 1; transform: none; }
}
@keyframes headerRuleIn {
  from { opacity: 0; transform: scaleX(0); }
  to   { opacity: 1; transform: none; }
}
.page-hero-title {
  animation: headerDropIn 0.95s var(--ease-out) var(--header-delay) both;
}
.page-hero-divider {
  transform-origin: center;
  animation: headerRuleIn 0.6s var(--ease-out) calc(var(--header-delay) + 0.55s) both;
}
.page-hero-tagline {
  animation: headerRiseIn 0.8s var(--ease-out) calc(var(--header-delay) + 0.8s) both;
}

.page-hero-inner {
  position: relative;
  z-index: 2;
  text-align: center;
  /* .section-inner's 7rem is sized for content sections; inside a header band
     it left the title floating in dead space. */
  padding-top: var(--space-md);
  padding-bottom: var(--space-md);
}
/* The brand mark, set like the homepage headline so the two pages rhyme. */
.page-hero-title {
  font-family: var(--font-header);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(2.6rem, 6.4vw, 6rem);
  line-height: 0.98;
  letter-spacing: 1px;
  color: #F2F0EA;
  margin: 0;
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.55);
}
.page-hero-divider {
  width: 90px;
  height: 3px;
  margin: 24px auto;
  background: var(--accent-1);
}
.page-hero-tagline {
  margin: 0 auto;
  max-width: 46ch;
  font-size: clamp(1rem, 1.5vw, 1.2rem);
  font-weight: 300;
  letter-spacing: 0.3px;
  color: #D8D5CC;
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.75);
}

/* ============================================
   Light page (about.html)
   The one other place the palette inverts, after index.html's .welcome.
   Colors are hardcoded dark literals on purpose: the tokens are all built
   for white-on-black, so they can't be reused here.
   ============================================ */
.page-light {
  background: #FFFFFF;
  color: #0A0A0A;
}
.page-light h2,
.page-light h3 { color: #0A0A0A; }
.page-light p { color: rgba(10, 10, 10, 0.72); }
.page-light-eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #946F14;
  margin: 0 0 0.9rem;
}
/* The gold eyebrow above is (0,1,0) and `.page-light p` on the line before it
   is (0,1,1) — so on EVERY white band the eyebrows silently rendered in muted
   body grey instead of gold, on about / services / rates / faq / testimonial /
   get-a-quote. The element is always a <p>, so the element selector in
   `.page-light p` was enough to win. (0,2,0) settles it. */
.page-light .page-light-eyebrow { color: #946F14; }
.page-light-intro { padding-bottom: 0; }
/* `.page-light-intro` was `.section-inner-narrow` (720px) directly above the
   1160px `.approach` block, both `margin: 0 auto` — so two left-aligned blocks
   on the same white ground started 220px apart at 1440px. Share the container
   and cap the MEASURE instead, which keeps the reading width without breaking
   the page's left edge. */
.page-light-intro.section-inner-narrow { max-width: 1160px; }
.page-light-intro h2,
.page-light-intro .page-light-lead { max-width: 46ch; }
.page-light-intro h2 { max-width: 20ch; }
.page-light-lead {
  margin-top: 1.25rem;
  font-size: 1.15rem;
  line-height: 1.7;
}
/* Gold reads as mustard on white, so the accent darkens just enough to pass
   as text while staying the same hue. */
.page-light .approach-eyebrow { color: #946F14; }
.page-light .approach { border-top: 1px solid rgba(10, 10, 10, 0.1); }
.page-light .approach-closing { color: #0A0A0A; }
.page-light .founder {
  border-top: 1px solid rgba(10, 10, 10, 0.1);
  padding-top: var(--space-lg);
  margin-top: var(--space-lg);
}
.page-light .founder-photo {
  background: linear-gradient(150deg, #E8E6E0, #D5D2CA);
  border: 1px solid rgba(10, 10, 10, 0.08);
}
.page-light .founder-photo span { color: rgba(10, 10, 10, 0.45); }
.page-light .founder-eyebrow { color: #946F14; }
.page-light .page-light .btn-ghost { border-color: rgba(10, 10, 10, 0.2); color: #0A0A0A; }

/* Services accordion inverted onto the light page. Borders and muted text are
   all white-on-black tokens by default, so each needs a dark counterpart. */
.page-light .services-accordion { border-top-color: rgba(10, 10, 10, 0.14); }
.page-light .service-row { border-bottom-color: rgba(10, 10, 10, 0.14); }
.page-light .service-item { color: rgba(10, 10, 10, 0.55); }
.page-light .service-item-num,
.page-light .service-item-chevron { color: rgba(10, 10, 10, 0.45); }
.page-light .service-row.is-active .service-item { color: #0A0A0A; }
.page-light .service-row.is-active .service-item-num,
.page-light .service-row.is-active .service-item-chevron { color: #946F14; }
.page-light .service-panel p { color: rgba(10, 10, 10, 0.72); }
.page-light .btn-ghost:hover { border-color: #0A0A0A; }

/* ============================================
   About
   ============================================ */
.about-head { max-width: 46ch; margin-bottom: var(--space-lg); }
.about-head p { margin-top: 0.75rem; font-size: 1.05rem; }
.about-values {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
.value-card {
  padding: 2rem 1.75rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-soft);
}
.value-card h3 { margin-bottom: 0.75rem; }
.value-card p { font-size: 0.95rem; line-height: 1.6; }
.about-cta { margin-top: var(--space-lg); }


/* ============================================
   How we work (about.html) — long-form.
   Deliberately calmer than the hero above it: narrower measure, taller
   line-height, wider paragraph gaps. Same black ground, fonts and heading
   conventions as every other section — only the pacing differs.
   ============================================ */
.approach { border-top: 1px solid var(--border-softer); }
.approach-eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-1);
  margin: 0 0 0.9rem;
}
.approach-head h2 { max-width: 20ch; }
.approach-body {
  margin-top: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: 1.9rem;
}
.approach-body p {
  font-size: 1.05rem;
  line-height: 1.85;
  max-width: 66ch;
}
.approach-closing { color: var(--text-primary); }
.approach-cta { margin-top: var(--space-lg); }

/* Scroll reveal. The hidden state is scoped to .js-reveal, which the script
   only adds once it knows it can reveal it again — so with JS off, or under
   reduced motion, the content just renders normally. */
[data-reveal].js-reveal {
  --reveal-shift: 28px;
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
}

/* Directional variants. `data-reveal="left"` still matches the bare
   `[data-reveal]` selector above, so nothing that only says `data-reveal`
   changes. These are (0,2,0) exactly like the base rule, so they MUST stay
   below it — equal specificity is decided by source order. `.is-revealed` is
   (0,3,0) and wins over all of them regardless. */
[data-reveal="left"].js-reveal,
[data-reveal="right"].js-reveal { --reveal-shift: clamp(28px, 5vw, 72px); }
[data-reveal="left"].js-reveal  { transform: translateX(calc(-1 * var(--reveal-shift))); }
[data-reveal="right"].js-reveal { transform: translateX(var(--reveal-shift)); }
[data-reveal="down"].js-reveal  { transform: translateY(calc(-1 * var(--reveal-shift))); }
[data-reveal="scale"].js-reveal { transform: scale(0.94); }

[data-reveal].js-reveal.is-revealed { opacity: 1; transform: none; }

/* A horizontal reveal starts OUTSIDE its own box, which is exactly how the
   150px sitewide overflow bug happened once before. Every section holding a
   left/right reveal clips on that axis.
   `clip`, NOT `hidden`: `overflow: hidden` creates a scroll container and
   would break the `position: sticky` page headers this site is built on.
   `clip` does not create one, and unlike `hidden` it allows the other axis to
   stay `visible`. */
.welcome,
.founder,
.testimonial-row,
.page-light-intro,
.faq-list,
.services-accordion { overflow-x: clip; }

/* On a flipped row the photo RENDERS on the right and the quote on the left —
   the grid swaps `order`, the DOM never does. So the entrance direction has to
   swap with it, or every second row would slide in from the wrong edge and the
   zig-zag would read as a mistake. (0,5,0) beats the (0,2,0) base rules. */
.testimonial-row.is-flipped .testimonial-photo[data-reveal].js-reveal { transform: translateX(var(--reveal-shift)); }
.testimonial-row.is-flipped .testimonial-body[data-reveal].js-reveal  { transform: translateX(calc(-1 * var(--reveal-shift))); }
.testimonial-row.is-flipped .testimonial-photo[data-reveal].js-reveal.is-revealed,
.testimonial-row.is-flipped .testimonial-body[data-reveal].js-reveal.is-revealed { transform: none; }

/* ============================================
   Page-hero title — word-by-word fall
   ============================================ */
/* initHeaderWords() adds .is-split once it has wrapped each word. The
   whole-block `headerDropIn` has to stop then, or the title animates twice. */
.page-hero-title.is-split { animation: none; opacity: 1; transform: none; }
.page-hero-title .hw {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  /* Without this the mask crops descenders (the 'g' in "Agency"). */
  padding-bottom: 0.1em;
}
.page-hero-title .hw > span {
  display: inline-block;
  animation: headerWordDrop 0.9s var(--ease-out) both;
}
@keyframes headerWordDrop {
  from { opacity: 0; transform: translateY(-115%); }
  to   { opacity: 1; transform: none; }
}

/* ============================================
   Welcome (index.html — deliberate light break from the black hero)
   ============================================ */
.welcome {
  background: #FFFFFF;
}
.welcome-grid {
  display: grid;
  grid-template-columns: 0.9fr 1.3fr;
  gap: var(--space-lg);
  align-items: start;
}
.welcome-eyebrow {
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* NOT --accent-1. `.welcome` hardcodes a white background instead of using
     `.page-light`, so it never inherited the light-ground gold and this eyebrow
     sat at 2.23 contrast on white — the worst text on the site. */
  color: #946F14;
  margin-bottom: 0.75rem;
}
.welcome-head h2 {
  font-family: var(--font-display);
  /* A deliberate one-off: this is the loudest thing after the hero. Pulled
     back from 4rem, which was 1.4x every other h2 on the site. */
  font-size: clamp(2.4rem, 4vw, 3.4rem);
  line-height: 1.03;
  margin: 0;
  color: #0A0A0A;
}
.welcome-body p {
  margin: 0 0 1.4rem;
  font-size: 1.18rem;
  line-height: 1.75;
  color: rgba(10, 10, 10, 0.7);
}
.welcome-body p:last-child { margin-bottom: 0; }

/* ============================================
   Closing CTA band — gold duotone
   The photo is desaturated and multiplied under the gold ground, which is what
   makes the duotone. `isolation: isolate` keeps that blend inside the section
   so it can't reach the page behind it.
   ============================================ */
.cta-gold {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--accent-1);
}
.cta-gold-media {
  position: absolute;
  inset: 0;
  background: url("assets/img/contact-city.jpg") center / cover no-repeat;
  /* Multiply DARKENS, so this layer must be bright going in. A night photo here
     turns the band near-black and the dark heading becomes unreadable — use a
     daylight/blue-hour source, and keep the opacity low enough that the gold
     ground stays dominant behind the text. */
  filter: grayscale(1) brightness(1.2);
  opacity: 0.55;
  mix-blend-mode: multiply;
  pointer-events: none;
}
/* Per-page band imagery. Brightness and opacity are set from each source's
   measured mean luminance: bright sources (>110/255) can take more opacity,
   darker ones need a bigger lift and less, or multiply crushes the heading. */
.cta-gold--home .cta-gold-media {
  background-image: url("assets/img/band-home.jpg");
  filter: grayscale(1) brightness(1.15);
  opacity: 0.55;
}
.cta-gold--rates .cta-gold-media {
  background-image: url("assets/img/band-rates.jpg");
  filter: grayscale(1) brightness(1.15);
  opacity: 0.55;
}
.cta-gold--about .cta-gold-media {
  background-image: url("assets/img/band-about.jpg");
  filter: grayscale(1) brightness(1.45);
  opacity: 0.45;
}
.cta-gold--services .cta-gold-media {
  background-image: url("assets/img/band-services.jpg");
  filter: grayscale(1) brightness(1.45);
  opacity: 0.45;
}
.cta-gold--testimonial .cta-gold-media {
  background-image: url("assets/img/band-testimonial.jpg");
  filter: grayscale(1) brightness(1.45);
  opacity: 0.45;
}
.cta-gold--faq .cta-gold-media {
  background-image: url("assets/img/band-faq.jpg");
  filter: grayscale(1) brightness(1.45);
  opacity: 0.45;
}
/* A clip dropped in here inherits the same treatment as the still. */
.cta-gold-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cta-gold-inner {
  position: relative;
  z-index: 1;
  text-align: center;
  padding-top: var(--space-lg);
  padding-bottom: var(--space-lg);
}
.cta-gold h2 {
  font-family: var(--font-header);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(1.9rem, 4.5vw, 3.4rem);
  line-height: 1;
  letter-spacing: 1px;
  color: #0A0A0A;
  margin: 0;
}
.cta-gold p {
  margin: 1.1rem auto 0;
  max-width: 34ch;
  font-family: var(--font-header);
  font-size: clamp(1.05rem, 2vw, 1.5rem);
  line-height: 1.25;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: rgba(10, 10, 10, 0.82);
}
.cta-gold-btn {
  display: inline-block;
  margin-top: 2.25rem;
  padding: 1rem 2.75rem;
  background: #000000;
  color: #F2F0EA;
  font-family: var(--font-header);
  font-size: 1rem;
  letter-spacing: 3px;
  text-transform: uppercase;
  border-radius: 2px;
  transition: background 0.2s ease;
}
.cta-gold-btn:hover { background: #1A1A1A; opacity: 1; }
.cta-gold-btn:active { background: #2A2A2A; }
/* --accent-2 is near-invisible against the gold band; the ring needs to be dark there. */
.cta-gold :focus-visible { outline-color: #0A0A0A; }

/* ============================================
   Stats (index.html — animated counters)
   ============================================ */
.stats {
  background: var(--surface-1);
  border-top: 1px solid var(--border-softer);
  border-bottom: 1px solid var(--border-softer);
}
.stats-inner {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
  text-align: center;
  padding-top: var(--space-xl);
  padding-bottom: var(--space-xl);
}
.stat-counter-value {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.5rem, 6vw, 4rem);
  color: var(--accent-1);
  font-variant-numeric: tabular-nums;
}
.stat-counter-label {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ============================================
   Founder / team (about.html)
   ============================================ */
.founder {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: var(--space-lg);
  align-items: center;
  padding-top: var(--space-lg);
  border-top: 1px solid var(--border-softer);
}
.founder-photo {
  aspect-ratio: 4/5;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border-soft);
}
.founder-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The bio is long-form now, so the photo tops out rather than stretching to
   match it, and the row aligns from the top instead of centring. */
.founder { align-items: start; }
.founder-photo { position: sticky; top: 6rem; }
.founder-bio p { margin-bottom: 1.15rem; }
.founder-bio p:last-child { margin-bottom: 0; }
.founder-pull {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2vw, 1.6rem);
  line-height: 1.3;
  color: var(--text-primary);
  margin: 2.25rem 0 !important;
}
/* `.founder-bio p:not(.founder-eyebrow)` is (0,2,1) and beats `.page-light p`,
   which left the whole bio in white-on-black muted grey on a WHITE band.
   These overrides match that specificity. */
.page-light .founder-bio p:not(.founder-eyebrow) { color: rgba(10, 10, 10, 0.75); }
.page-light .founder-bio p.founder-pull { color: #0A0A0A; }
.page-light .founder-bio h2 { color: #0A0A0A; }

@media (max-width: 900px) {
  .founder-photo { position: static; max-width: 380px; }
}
.founder-eyebrow {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-1);
  margin: 0 0 0.5rem;
}
.founder-bio h2 {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  margin: 0 0 1rem;
}
.founder-bio p:not(.founder-eyebrow) {
  font-size: 1.05rem;
  line-height: 1.75;
  color: var(--text-muted);
  margin: 0 0 1.25rem;
}

/* ============================================
   FAQ
   ============================================ */
.faq-head { max-width: 46ch; margin-bottom: var(--space-lg); }
.faq-head p { margin-top: 0.75rem; font-size: 1.05rem; }
/* Same disclosure mechanism as the services list: the question row never
   moves, the answer grows beneath it, and the rows below slide down. */
.faq-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border-softer);
  max-width: 900px;
}
.faq-row {
  position: relative;
  border-bottom: 1px solid var(--border-softer);
}
.faq-question {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  background: none;
  border: none;
  text-align: left;
  padding: 1.5rem 0.25rem;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--text-muted);
  transition: color 0.25s ease, padding-left 0.35s var(--ease-out);
}
.faq-question-text { flex: 1; }
.faq-chevron {
  display: flex;
  color: var(--text-muted);
  transition: transform 0.35s var(--ease-out), color 0.25s ease;
}
.faq-row.is-active .faq-question { color: var(--text-primary); padding-left: 1rem; }
.faq-row.is-active .faq-chevron { color: var(--accent-1); transform: rotate(180deg); }
.faq-row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.5rem;
  width: 4px;
  height: 1.6rem;
  border-radius: 4px;
  background: var(--accent-gradient);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.faq-row.is-active::before { opacity: 1; }
.faq-panel-inner { padding: 0 0.25rem 1.75rem 1rem; }
.faq-panel-inner p { font-size: 1rem; line-height: 1.7; max-width: 62ch; }

/* ============================================
   Process
   ============================================ */
.process-head { max-width: 46ch; margin-bottom: var(--space-lg); }
.process-head p { margin-top: 0.75rem; font-size: 1.05rem; }

.process-steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2rem;
  position: relative;
}
.process-steps::before {
  content: "";
  position: absolute;
  top: 1.1rem;
  left: 3%;
  right: 3%;
  height: 1px;
  background: var(--border-soft);
}
.process-step { position: relative; }
.process-num {
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.5rem;
  color: var(--accent-2);
  margin-bottom: 1.5rem;
  background: var(--bg-base);
  width: fit-content;
  padding-right: 0.75rem;
}
.process-step h3 { margin-bottom: 0.6rem; }
.process-step p { font-size: 0.95rem; line-height: 1.6; }

/* ============================================
   Testimonials
   ============================================ */
/* No background here — see the note on .pricing above. */
.reviews-head { max-width: 50ch; margin: 0 auto var(--space-lg); text-align: center; }
.reviews-head p { margin: 0.75rem auto 0; font-size: 1.05rem; }
/* ============================================
   Contact
   ============================================ */
.contact { position: relative; text-align: center; padding: var(--space-xl) 0; overflow: hidden; }
.contact-atmosphere {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Same darkening recipe as the hero (see .hero-media / .hero-atmosphere):
     brightness 0.8 on the photo, then a 0.4/0.12/0.5 black gradient over it.
     The photo needs its own layer because `filter` would hit the text too. */
  background: url("assets/img/contact-city.jpg") center / cover no-repeat;
  filter: brightness(0.8) saturate(1.05);
}
.contact-atmosphere::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.4) 0%,
    rgba(0, 0, 0, 0.12) 40%,
    rgba(0, 0, 0, 0.5) 100%
  );
}
.contact .section-inner { position: relative; z-index: 1; }
/* The Calgary photo is a bright blue-hour shot, not a night scene, so the same
   0.8 brightness leaves far more light behind the text than the hero does.
   The muted-grey copy needs protecting; the white serif h1 mostly doesn't. */
.contact h1 { max-width: 20ch; margin: 0 auto; text-shadow: 0 2px 18px rgba(0, 0, 0, 0.5); }
.contact p {
  margin: 1.25rem auto 0;
  font-size: 1.05rem;
  color: #D8D5CC;
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.75);
}
.contact-email {
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.75);
  display: inline-block;
  margin-top: 2rem;
  font-family: var(--font-display);
  font-size: 1.4rem;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 0.15rem;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.contact-email:hover { border-color: var(--accent-2); color: var(--accent-2); }
.contact-ctas { justify-content: center; }

/* ============================================
   Footer
   ============================================ */
.footer { border-top: 1px solid var(--border-softer); }

/* Two blocks pushed to opposite edges. This used to be a bare `display: flex`
   with no `justify-content`, left over from when a deleted `.footer-links`
   column carried `margin-right: auto` and did the spreading. With that column
   gone both blocks shrank to fit and clumped against the left edge, leaving
   ~490px of dead space at 1024px and far more on a wide screen — while
   `.footer-contact` went on right-aligning its text inside its own narrow box,
   so the type had a ragged edge pointing at nothing. Keep the explicit
   `space-between`: it is the only thing holding this layout together. */
.footer-inner {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 3rem;
  /* Was var(--space-md) — 32px, the tightest block on a site that gives every
     other section 112px. A cramped footer reads as an afterthought. */
  padding-top: 4.5rem;
  padding-bottom: 3rem;
  flex-wrap: wrap;
}
.footer-brand { max-width: 34ch; }
.footer-tagline {
  margin: 1.1rem 0 0;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 32ch;
}
.footer-col-title {
  margin: 0 0 0.9rem;
  font-family: var(--font-header);
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-1);
}
.footer-email {
  display: block;
  font-size: 1.02rem;
  letter-spacing: 0.01em;
  color: var(--text-primary);
  transition: color 0.2s ease;
}
.footer-email:hover { color: var(--accent-1); }

/* Legal strip. Separated by a rule rather than a gap so the footer reads as
   one block with a base, not as two stacked sections. */
.footer-bottom {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding-top: 1.5rem;
  padding-bottom: 2.25rem;
  border-top: 1px solid var(--border-softer);
}
.footer-legal {
  margin: 0;
  font-size: 0.74rem;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  max-width: none;
}
.footer-legal a { color: var(--text-primary); text-decoration: none; border-bottom: 1px solid var(--border-soft); transition: color 0.2s ease, border-color 0.2s ease; }
.footer-legal a:hover { color: var(--accent-1); border-bottom-color: var(--accent-1); }

/* ============================================
   Legal pages (privacy.html) — long-form on a white band
   ============================================ */
.legal-updated { margin-top: 1rem; font-size: 0.8rem; letter-spacing: 0.04em; color: rgba(10, 10, 10, 0.5); }
.legal-body { max-width: 68ch; }
.legal-body h3 {
  margin: 2.75rem 0 0.9rem;
  font-size: clamp(1.15rem, 1.6vw, 1.4rem);
  color: #0A0A0A;
}
.legal-body h3:first-child { margin-top: 0; }
.legal-body p { margin: 0 0 1rem; font-size: 1rem; line-height: 1.8; }
.legal-body ul { margin: 0 0 1.25rem; padding-left: 1.2rem; }
.legal-body li { margin-bottom: 0.6rem; font-size: 1rem; line-height: 1.75; color: rgba(10, 10, 10, 0.72); }
.legal-body strong { color: #0A0A0A; font-weight: 600; }
.legal-body code {
  font-size: 0.88em;
  padding: 0.1em 0.35em;
  border-radius: 2px;
  background: rgba(10, 10, 10, 0.06);
}
.legal-body a { color: #946F14; text-decoration: underline; text-underline-offset: 2px; }
.legal-contact { list-style: none; padding-left: 0; }
.legal-contact li { margin-bottom: 0.4rem; }

/* Consent note directly above the quote form's submit button. */
.form-consent {
  margin: 0 0 1.25rem;
  max-width: 52ch;
  font-size: 0.85rem;
  line-height: 1.65;
  color: rgba(10, 10, 10, 0.6);
}
.form-consent a { color: #946F14; text-decoration: underline; text-underline-offset: 2px; }

/* Shown by initQuoteForm() only while the form has no endpoint. It must look
   like a real handover, not an error — the visitor has just typed out a brief. */
.form-fallback {
  margin-top: 1.5rem;
  padding: 1.5rem 1.6rem;
  border: 1px solid rgba(10, 10, 10, 0.16);
  border-left: 3px solid #946F14;
  border-radius: 2px;
  background: rgba(154, 116, 21, 0.06);
}
.form-fallback p { margin: 0; font-size: 0.95rem; line-height: 1.7; color: rgba(10, 10, 10, 0.78); }
.form-fallback strong { color: #0A0A0A; }
.form-fallback-actions {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
  margin-top: 1.2rem !important;
}
.form-fallback-tel { font-size: 0.92rem; color: #946F14; text-decoration: underline; text-underline-offset: 3px; }

/* ============================================
   Responsive
   ============================================ */
@media (max-width: 900px) {
  .hero-inner { grid-template-columns: 1fr; }


  .pricing-grid { grid-template-columns: 1fr; }
  .about-values { grid-template-columns: 1fr; }
  .welcome-grid { grid-template-columns: 1fr; }
  .process-steps { grid-template-columns: 1fr 1fr; row-gap: 2.5rem; }
  .process-steps::before { display: none; }
  .founder { grid-template-columns: 1fr; }
  .stats-inner { grid-template-columns: 1fr; gap: var(--space-lg); }
}

@media (max-width: 700px) {
  .hero-headline-line { white-space: normal; }
  .announce-bar-social { display: none; }
  .announce-bar-inner { height: auto; padding-top: 0.7rem; padding-bottom: 0.7rem; }
  .announce-bar-ticker { overflow: visible; }
  .announce-bar-track { animation: none; width: auto; }
  .announce-bar-track .announce-bar-msg[aria-hidden="true"] { display: none; }
  /* The duplicated MESSAGES were hidden here but the separators never were, so
     four `.announce-bar-sep` bullets kept their 4rem padding (~73px each) and
     held the shrink-to-fit track open at 478px inside a 356px viewport. That
     put 150px of horizontal overflow on EVERY page of the site at phone width.
     The bullets are decorative and already aria-hidden, so they simply go. */
  .announce-bar-sep { display: none; }
  .announce-bar-track { flex-wrap: wrap; }
  .announce-bar-msg { display: block; white-space: normal; padding-right: 0; font-size: 0.9rem; line-height: 1.5; }
  .announce-bar-link { margin-left: 0.35rem; }

  .nav-menu {
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    background: var(--surface-1);
    padding: 1.25rem 1.75rem;
    gap: 1.25rem;
    border-bottom: 1px solid var(--border-softer);
    display: none;
  }
  .nav-menu.is-open { display: flex; }
  .nav-toggle { display: flex; }
  .nav-cta { display: none; }

  .process-steps { grid-template-columns: 1fr; }
  .footer-inner { flex-direction: column; align-items: flex-start; }
}

/* ============================================
   Reduced motion & touch devices
   ============================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .page-hero-title,
  .page-hero-divider,
  .page-hero-tagline {
    animation: none;
    opacity: 1;
    transform: none;
  }
  .announce-bar-track { animation: none; }
  .announce-bar-ticker { overflow-x: auto; }
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

@media (hover: none) and (pointer: coarse) {
  .cursor { display: none; }
  .has-custom-cursor, .has-custom-cursor a, .has-custom-cursor button { cursor: auto; }
}

/* ============================================
   Alternating bands
   Pages alternate black and white grounds down the scroll. A plain <section>
   is already black (--bg-base); .page-light inverts it. .band only manages the
   seam between them.
   ============================================ */
.band + .band { border-top: 1px solid var(--border-softer); }
.page-light.band + .band { border-top: none; }
.band + .page-light.band { border-top: none; }
.band-head { margin-bottom: var(--space-lg); }
.band-head h2,
.band-head h1 { max-width: 20ch; }   /* privacy.html's heading is an h1 — it is the page's only heading */
.band-close { text-align: center; }
.band-close h2 { max-width: 24ch; margin: 0 auto; }
.band-close p { margin: 1rem auto 0; font-size: 1.05rem; }

/* Pricing lives on both grounds now, so its dark-ground colours need light
   counterparts — same approach as the services accordion. */
.page-light .pricing-block-eyebrow { color: #946F14; }
.page-light .price-card { border-color: rgba(10, 10, 10, 0.14); }
.page-light .price-card h3 { color: #0A0A0A; }
.page-light .price-figure { color: #0A0A0A; }
.page-light .price-tagline,
.page-light .price-period,
.page-light .price-features li { color: rgba(10, 10, 10, 0.7); }
.page-light .price-card-featured {
  background: linear-gradient(165deg, #FAF8F3, #F1EEE6);
  box-shadow: 0 20px 45px -24px rgba(10, 10, 10, 0.25);
}
.page-light .btn-outline { border-color: rgba(10, 10, 10, 0.25); color: #0A0A0A; }
.page-light .btn-outline:hover { border-color: #946F14; }
.page-light .pricing-bundle { border-color: rgba(10, 10, 10, 0.22); }
.page-light .pricing-bundle strong { color: #0A0A0A; }
.page-light .pricing-bundle a { color: #946F14; }


/* ============================================
   Quote form (get-a-quote.html) — lives on a .page-light band
   ============================================ */
.form-head p { margin-top: 1rem; font-size: 1.05rem; }
.quote-form {
  margin-top: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}
.form-field { display: flex; flex-direction: column; }
.form-field label {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(10, 10, 10, 0.7);
  margin-bottom: 0.55rem;
}
.req { color: #B0341A; }
.form-field input,
.form-field select,
.form-field textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  color: #0A0A0A;
  background: #FFFFFF;
  border: 1px solid rgba(10, 10, 10, 0.22);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  width: 100%;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.form-field textarea { resize: vertical; min-height: 8rem; }
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: #946F14;
  box-shadow: 0 0 0 3px rgba(217, 166, 30, 0.22);
}
/* Only flag a field the visitor has actually got wrong. `:user-invalid` matches
   ONLY after they have interacted with the field or attempted to submit.

   The previous guard was `:not(:placeholder-shown):invalid`. It looked right and
   was documented as right, and it silently did the opposite: `:placeholder-shown`
   can only match a field that HAS a `placeholder` attribute, and on this form
   only `website` has one. So on every other required field `:not(:placeholder-shown)`
   was permanently true, and first name, last name, email and the project
   textarea all rendered in error red the moment the page loaded — on the site's
   highest-intent page, before the visitor had typed a single character.

   Browsers too old for `:user-invalid` drop this rule entirely and show no error
   tint at all, which is strictly better than showing the wrong one. Native
   validation still blocks the submit either way.

   DON'T go back to a `:placeholder-shown` guard unless every field it covers is
   guaranteed to carry a placeholder. */
.form-field input:user-invalid,
.form-field textarea:user-invalid,
.form-field select:user-invalid { border-color: #B0341A; }
.form-submit {
  align-self: flex-start;
  margin-top: 0.5rem;
  border: none;
  cursor: pointer;
  font-size: 1rem;
}
.form-note {
  font-size: 0.85rem;
  color: rgba(10, 10, 10, 0.55);
  margin: 0;
}

@media (max-width: 700px) {
  .form-row { grid-template-columns: 1fr; }
}

/* ============================================
   Parallax — header and gold-band imagery drift slower than the page
   Pure transform on the media layer only; never affects layout.
   ============================================ */
.page-hero-media,
.cta-gold-media {
  will-change: transform;
}

.inline-link {
  color: #946F14;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.inline-link:hover { color: #0A0A0A; }

/* FAQ head sits on the light band now. */
.page-light .faq-head h2 { max-width: 22ch; }

/* THE FAQ ACCORDION HAD NO LIGHT-GROUND COLOURS AT ALL. `faq.html`'s accordion
   sits on `<section class="page-light band faq">` — a WHITE band — but every
   colour on it was a dark-theme token, so:
     - closed questions rendered in --text-muted grey on white  (contrast 2.75)
     - and an OPENED question took --text-primary, i.e. WHITE ON WHITE (1.00) —
       click a question and the thing you just clicked disappears.
   The services accordion got its light counterparts when it was built; FAQ was
   added later and this set was simply never written. These mirror the services
   values exactly — keep the two in step. */
.page-light .faq-list { border-top-color: rgba(10, 10, 10, 0.14); }
.page-light .faq-row { border-bottom-color: rgba(10, 10, 10, 0.14); }
.page-light .faq-question { color: rgba(10, 10, 10, 0.55); }
.page-light .faq-chevron { color: rgba(10, 10, 10, 0.45); }
.page-light .faq-row.is-active .faq-question { color: #0A0A0A; }
.page-light .faq-row.is-active .faq-chevron { color: #946F14; }
.page-light .faq-row::before { background: #946F14; }
.page-light .faq-panel-inner p { color: rgba(10, 10, 10, 0.72); }

/* Gold rules draw themselves in as their band arrives. */
.rule-draw { transform-origin: left center; }
.rule-draw.js-reveal { transform: scaleX(0); transition: transform 0.9s var(--ease-out); }
.rule-draw.js-reveal.is-revealed { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .page-hero-media,
  .cta-gold-media { transform: none !important; }
  .rule-draw.js-reveal { transform: none; }
}

/* ============================================
   Sticky header reveal ("window" transition)
   The hero/page-header pins at the top and the section beneath scrolls UP OVER
   it, so the black-to-white change reads as a panel arriving rather than a hard
   seam. Everything after the header needs its own stacking level and an OPAQUE
   background, or the pinned header shows through it.
   ============================================ */
/* Kept at (0,0,2) ON PURPOSE. An earlier version used
   `main > section:not(.hero):not(.page-hero)` — (0,2,2) — which outranked
   `.welcome` and `.page-light` and silently turned every WHITE band black.
   At this weight, any single-class background rule wins normally. */
main > section {
  position: relative;
  z-index: 1;
  background-color: var(--bg-base);
}
/* (0,1,0) beats the rule above, so these need no extra weight. Setting a
   background on the header too is harmless: its media layer covers it. */
.hero,
.page-hero { position: sticky; top: 0; z-index: 0; }

/* The footer sits outside <main>, so it needs lifting too or it scrolls
   behind the pinned header. */
.footer { position: relative; z-index: 1; background-color: var(--bg-base); }

/* Pinning a full-height header on a small screen costs more than it gives —
   the reveal is barely visible and it keeps a video decoding behind content. */
@media (max-width: 700px) {
  .hero,
  .page-hero { position: relative; }
}
@media (prefers-reduced-motion: reduce) {
  .hero,
  .page-hero { position: relative; }
}

/* ============================================
   Testimonials — alternating photo / text rows
   One person per full-width band, grounds alternating white and black down the
   page, and the photo swapping sides each time so the eye zig-zags.
   ============================================ */
.testimonial-band .section-inner { padding-top: var(--space-lg); padding-bottom: var(--space-lg); }
.testimonial-row {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: var(--space-lg);
  align-items: center;
}
/* Reversing the COLUMN rather than the DOM order keeps the photo before the
   quote for screen readers and keyboard order on every row. */
.testimonial-row.is-flipped { grid-template-columns: 1.2fr 0.8fr; }
.testimonial-row.is-flipped .testimonial-photo { order: 2; }
.testimonial-row.is-flipped .testimonial-body { order: 1; }

.testimonial-photo {
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(150deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--border-soft);
}
.testimonial-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.testimonial-initials {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5vw, 4rem);
  letter-spacing: 0.08em;
  color: var(--accent-1);
  opacity: 0.85;
}
.page-light .testimonial-photo {
  background: linear-gradient(150deg, #F1EEE6, #E4E0D6);
  border-color: rgba(10, 10, 10, 0.12);
}
.page-light .testimonial-initials { color: #946F14; }

.testimonial-quote-mark {
  display: block;
  font-family: var(--font-display);
  font-size: 4.5rem;
  line-height: 0.6;
  color: var(--accent-1);
  margin-bottom: 0.75rem;
}
.page-light .testimonial-quote-mark { color: #946F14; }

.testimonial-body blockquote { margin: 0; }
.testimonial-body blockquote p {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  line-height: 1.55;
  color: var(--text-primary);
  max-width: 34ch;
}
.page-light .testimonial-body blockquote p { color: #0A0A0A; }

.testimonial-cite { display: block; margin-top: 1.75rem; font-style: normal; }
.testimonial-name {
  display: block;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-primary);
}
.testimonial-meta {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-1);
}
.page-light .testimonial-name { color: #0A0A0A; }
.page-light .testimonial-meta { color: #946F14; }

@media (max-width: 900px) {
  .testimonial-row,
  .testimonial-row.is-flipped { grid-template-columns: 1fr; gap: var(--space-md); }
  .testimonial-row.is-flipped .testimonial-photo { order: 0; }
  .testimonial-row.is-flipped .testimonial-body { order: 0; }
  .testimonial-photo { max-width: 320px; }
  .testimonial-body blockquote p { max-width: none; }
}

/* ============================================
   Why digital marketing matters (services.html)
   Dark band between the accordion and the gold CTA.
   ============================================ */
.why-band .section-inner { padding-top: var(--space-lg); padding-bottom: var(--space-lg); }
.why-head { margin-bottom: var(--space-lg); }
.why-eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-1);
  margin: 0 0 0.9rem;
}
.why-head h2 { max-width: 20ch; }
.why-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2.25rem 2rem;
}
.why-item { border-top: 1px solid var(--border-soft); padding-top: 1.35rem; }
.why-num {
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.9rem;
  color: var(--accent-1);
  margin-bottom: 0.7rem;
}
.why-item h3 {
  font-size: clamp(1.05rem, 1.4vw, 1.22rem);
  margin-bottom: 0.6rem;
  color: var(--text-primary);
}
.why-item p { font-size: 0.95rem; line-height: 1.7; max-width: none; }

.page-light .why-item { border-top-color: rgba(10, 10, 10, 0.14); }
.page-light .why-num { color: #946F14; }
.page-light .why-item h3 { color: #0A0A0A; }

@media (max-width: 1100px) { .why-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .why-grid { grid-template-columns: 1fr; gap: 1.75rem; } }

/* ============================================
   Evidence band (index.html)
   Dark ground, so --text-primary and --accent-1 apply normally. Every figure
   is paired with a printed .evidence-source; see the markup comment.
   ============================================ */
.evidence-lead {
  margin: 1.1rem 0 0;
  max-width: 52ch;
  font-size: 1.05rem;
  line-height: 1.75;
}
.evidence-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.5rem;
}
.evidence-item { border-top: 1px solid var(--border-soft); padding-top: 1.6rem; }
.evidence-figure {
  margin: 0 0 1.1rem;
  font-family: var(--font-display);
  font-size: clamp(3rem, 5.6vw, 4.4rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent-1);
}
.evidence-figure span {
  font-size: 0.42em;
  margin-left: 0.06em;
  vertical-align: 0.62em;
}
.evidence-claim {
  margin: 0 0 1rem;
  max-width: 30ch;
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--text-primary);
}
.evidence-source {
  margin: 0;
  max-width: 34ch;
  font-size: 0.73rem;
  line-height: 1.6;
  letter-spacing: 0.03em;
  color: var(--text-muted);
}
.evidence-close {
  margin: var(--space-lg) 0 0;
  max-width: 42ch;
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.9vw, 1.55rem);
  line-height: 1.45;
  color: var(--text-primary);
}
@media (max-width: 900px) {
  .evidence-grid { grid-template-columns: 1fr; gap: 2rem; }
}

/* ============================================
   Journey band (index.html) — WHITE ground via .page-light
   ============================================ */
/* `.band-head h2` caps at 20ch, which broke this two-sentence heading across
   four lines. (0,2,1) beats it. */
.journey .band-head h2 { max-width: 26ch; }
.journey-figure { margin: var(--space-lg) 0; }
.journey-svg { display: block; width: 100%; height: auto; }
.journey-notes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.25rem;
}
.journey-note { border-top: 1px solid rgba(10, 10, 10, 0.14); padding-top: 1.3rem; }
.journey-note h3 {
  margin-bottom: 0.6rem;
  font-size: clamp(1.05rem, 1.4vw, 1.2rem);
  color: #0A0A0A;
}
.journey-note p { font-size: 0.95rem; line-height: 1.7; max-width: none; }
@media (max-width: 800px) {
  .journey-notes { grid-template-columns: 1fr; gap: 1.6rem; }
  .journey-figure { margin: var(--space-md) 0; }
}

/* ============================================
   Premium typographic lift (Hemus Digital Agency rebrand)
   Slightly more open tracking on display type, calmer body rhythm, and more
   air between sections — the simplest, most reliable "premium" signal there is.
   ============================================ */
h1, h2, h3 { letter-spacing: -0.015em; }
.page-hero-title { letter-spacing: 2px; }
.hero-headline { letter-spacing: 1px; }

/* Long-form copy reads better a touch looser. */
.approach-body p,
.founder-bio p:not(.founder-eyebrow),
.page-light-lead { line-height: 1.8; }

/* THE PULL QUOTES WERE RENDERING AT BODY SIZE. `.founder-pull` is (0,1,0);
   `.founder-bio p:not(.founder-eyebrow)` is (0,2,1) and beat it on BOTH
   `font-size` (1.05rem won over clamp(1.25rem,2vw,1.6rem) -- 16.8px instead of
   25.6px) and `line-height` (the 1.8 rule just above won over 1.3). The three
   lines that carry the founder's whole argument therefore scanned as ordinary
   paragraphs, and a reader skimming the block saw one undifferentiated wall.

   This is the SAME trap already documented for `color` on this element -- that
   one was fixed with a matching-specificity override and this one was missed.
   Any future `.founder-pull` property needs (0,2,1) or higher AND must sit
   after both rules above, or it silently loses. */
.founder-bio p.founder-pull {
  font-family: var(--font-display);
  font-size: clamp(1.45rem, 2.2vw, 1.95rem);
  line-height: 1.28;
}

/* Section eyebrows share one treatment across the site. */
.page-light-eyebrow,
.approach-eyebrow,
.pricing-block-eyebrow,
.why-eyebrow,
.welcome-eyebrow { font-feature-settings: "liga" 1, "kern" 1; }

/* More breathing room between bands on the long pages. */
.band .section-inner { padding-top: calc(var(--space-lg) * 1.15); padding-bottom: calc(var(--space-lg) * 1.15); }

/* Pricing figures carry the premium read — give them presence. */
.price-figure { letter-spacing: -0.02em; }
.price-card { padding: 2.5rem 2.15rem; }
.price-features li { line-height: 1.6; }
.price-card em { font-style: italic; opacity: 0.85; }

/* Rates footnote — sets the expectation that current pricing is a phase,
   so raising it later reads as planned rather than opportunistic. */
.pricing-note {
  margin: 1.5rem auto 0;
  max-width: 62ch;
  text-align: center;
  font-size: 0.88rem;
  line-height: 1.7;
  color: var(--text-muted);
}
.page-light .pricing-note { color: rgba(10, 10, 10, 0.6); }

/* Footer contact block — email plus the location line that carries the
   local-business signal. */
.footer-contact { text-align: right; }
.footer-location {
  margin: 0.9rem 0 0;
  font-size: 0.78rem;
  line-height: 1.7;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  max-width: none;
}
@media (max-width: 700px) {
  .footer-contact { text-align: left; }
}

/* Footer phone + social row. Icons are the same filled set as the announce
   bar, at a calmer weight since the footer shouldn't compete with the header. */
.footer-phone {
  display: block;
  margin-top: 0.35rem;
  font-size: 1.02rem;
  letter-spacing: 0.02em;
  color: var(--text-primary);
  transition: color 0.2s ease;
}
.footer-phone:hover { color: var(--accent-1); }

/* Phone glyph in front of the number, in the announce bar and the footer.
   `currentColor` so it inherits every hover state already defined on those
   links instead of needing its own. */
.tel-icon,
.wa-icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  vertical-align: -0.12em;
  margin-right: 0.4em;
  flex: none;
}
.footer-phone .tel-icon { width: 0.95em; height: 0.95em; }

/* "Call on WhatsApp" under the footer number. This is the ONLY contact method
   on the site that actually places a call from a desktop — `tel:` depends on
   the OS having a handler registered, `wa.me` opens WhatsApp Desktop or Web on
   its own. That is why it earns a line of its own rather than only existing as
   one of the four social glyphs. */
.footer-whatsapp {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  transition: color 0.2s ease;
}
.footer-whatsapp:hover { color: var(--accent-1); }
.footer-whatsapp .wa-icon { width: 0.95em; height: 0.95em; }
.footer-social {
  display: flex;
  gap: 1.1rem;
  margin-top: 1.6rem;
  justify-content: flex-start;
}
.footer-social-icon {
  display: flex;
  color: var(--text-muted);
  transition: color 0.2s ease, transform 0.2s ease;
}
.footer-social-icon svg { width: 18px; height: 18px; fill: currentColor; }
.footer-social-icon:hover { color: var(--accent-1); transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) { .footer-social-icon:hover { transform: none; } }
@media (max-width: 700px) {
  .footer-inner { gap: 2.5rem; padding-top: 3.5rem; }
  .footer-brand, .footer-contact { max-width: none; }
  .footer-bottom { flex-direction: column; gap: 0.5rem; }
}
