/* ============================================
   Wet Paint Bayside — stylesheet
   ============================================ */

:root {
  --navy: #1E1C45;
  --navy-dark: #14132F;
  --red: #D13B2E;
  --red-dark: #B12F23;
  --cream: #FBF8F3;
  --cream-2: #F1E9DB;
  --sand: #CBC0A8;
  --ink: #2A2934;
  --white: #FFFFFF;

  --font-head: 'Fraunces', Georgia, serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

  --wrap: 1180px;
  --radius: 12px;
  --shadow: 0 10px 30px rgba(20, 19, 47, 0.12);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--cream);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

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

.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 24px;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--navy);
  color: #fff;
  padding: 10px 16px;
  z-index: 999;
}
.skip-link:focus { left: 16px; top: 16px; }

h1, h2, h3, h4 {
  font-family: var(--font-head);
  color: var(--navy);
  margin: 0;
  line-height: 1.1;
  font-weight: 600;
}

p { margin: 0; }

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

.eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 10px;
}
.eyebrow-light { color: #F3B9AE; text-shadow: 0 1px 10px rgba(15,14,36,0.7); }

.section-title {
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  margin-bottom: 12px;
}
.section-title-light { color: #fff; margin-bottom: 40px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 26px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.95rem;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn:hover { transform: translateY(-1px); }

.btn-primary {
  background: var(--red);
  color: #fff;
}
.btn-primary:hover { background: var(--red-dark); }

.btn-outline {
  background: transparent;
  color: #fff;
  border-color: rgba(255,255,255,0.55);
}
.btn-outline:hover { background: rgba(255,255,255,0.12); }

.btn-full { width: 100%; justify-content: center; margin-top: 6px; }

.text-link {
  color: var(--red);
  font-weight: 600;
  border-bottom: 1px solid var(--red);
  padding-bottom: 2px;
  white-space: nowrap;
}

/* ---------- Entrance animations ---------- */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Plays once on page load — used for above-the-fold hero/header elements */
.load-anim {
  opacity: 0;
  animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* Plays once when an element scrolls into view — toggled via IntersectionObserver */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.in-view {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .load-anim { animation: none; opacity: 1; }
  .reveal { transition: none; opacity: 1; transform: none; }
  /* No pinning and no reveal — the hero renders as a plain finished section. */
  .hero-stage { height: auto; }
  .hero { position: static; height: auto; min-height: 640px; }
  .hero-content { opacity: 1; }
  .hero-content > * { transform: none; }
  .hero-overlay { opacity: 1; }
  .hero-cue { display: none; }
  .hero-stage.is-idle .hero-content { visibility: visible; }
}

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: transparent;
}
.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  gap: 16px;
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
}
.logo-mark-img { height: 93px; width: auto; flex: none; display: block; }
.logo-text {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 2.18rem;
  color: #fff;
  line-height: 1.1;
}
.logo-text-sub {
  display: block;
  font-family: var(--font-body);
  font-size: 1.14rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.75);
}
.footer-brand .logo-text,
.logo-text-footer { color: var(--navy); }
.footer-brand .logo-text-sub { color: rgba(30,28,69,0.6); }

/* --- Header wordmark "paint" transition ---------------------------------
   The sticky header is transparent, so the wordmark repaints itself as it
   passes over light vs dark sections. A gradient is clipped to the glyphs
   and slid across them, so the new colour wipes on left-to-right behind a
   thin red "wet edge" — like it's being brushed on. Scoped to the header so
   the footer lockup is untouched. JS toggles .on-light (see main.js).       */
.site-header .logo-text,
.site-header .logo-text-sub {
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  background-repeat: no-repeat;
  /* 220% rather than 200% so the visible window is narrower than half the
     gradient. At 200% the window lands exactly on the halves, which parks the
     red edge on the last glyph once the wipe settles; the extra 20% gives the
     band room to travel clear off both ends. */
  background-size: 220% 100%;
  background-position: 100% 0;
  transition: background-position 0.85s cubic-bezier(0.66, 0, 0.34, 1);
}
/* The window spans 100/220 = 45.45% of the gradient, so it covers 0–45.45% at
   rest on light and 54.55–100% at rest on dark. Keeping the red band inside
   48.6–49.4% leaves it outside both, and only on screen mid-wipe. */
.site-header .logo-text {
  background-image: linear-gradient(90deg,
    #33323C 0 48.6%,
    var(--red) 48.6% 49.4%,
    #FFFFFF 49.4% 100%);
}
.site-header .logo-text-sub {
  background-image: linear-gradient(90deg,
    rgba(51,50,60,0.72) 0 48.6%,
    var(--red) 48.6% 49.4%,
    rgba(255,255,255,0.75) 49.4% 100%);
  transition-delay: 110ms;
}
.site-header.on-light .logo-text,
.site-header.on-light .logo-text-sub {
  background-position: 0 0;
}

/* Nav links and menu button need to stay legible over the same sections */
.site-header .main-nav a,
.site-header .nav-toggle,
.site-header .nav-toggle span {
  transition: color 0.5s ease, background-color 0.5s ease;
}
.site-header.on-light .main-nav a { color: #33323C; }
.site-header.on-light .nav-toggle { background: rgba(30,28,69,0.10); }
.site-header.on-light .nav-toggle span { background: #33323C; }

@media (prefers-reduced-motion: reduce) {
  .site-header .logo-text,
  .site-header .logo-text-sub,
  .site-header .main-nav a,
  .site-header .nav-toggle,
  .site-header .nav-toggle span { transition: none; }
}

.main-nav {
  display: flex;
  gap: 28px;
}
.main-nav a {
  color: #fff;
  font-size: 0.92rem;
  font-weight: 500;
  opacity: 0.9;
}
.main-nav a:hover { opacity: 1; }

.header-actions { display: flex; align-items: center; gap: 14px; }

.phone-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--red);
  color: #fff;
  padding: 9px 16px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  border: none;
  background: rgba(255,255,255,0.15);
  border-radius: 8px;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 18px;
  height: 2px;
  background: #fff;
  margin: 0 auto;
}

/* ---------- Hero ---------- */
/* The stage is one viewport plus --hero-reveal of extra height. The hero
   sticks to the top of it, so scrolling through that extra height leaves the
   page visually still while the copy reveals; past it, the stage runs out and
   the page carries on to the ticker as normal. */
.hero-stage {
  --hero-reveal: 520px;
  position: relative;
  /* The header tuck is added back so the pinned distance equals --hero-reveal
     exactly rather than being short by the header's height. */
  height: calc(100vh + var(--header-h, 140px) + var(--hero-reveal));
  /* Margin and padding use the same value so hero content never shifts; only the
     hero's top edge moves. Over-estimating just tucks it further under the
     header, while under-estimating exposes the page background — so the
     pre-JS fallback is deliberately generous. */
  margin-top: calc(var(--header-h, 140px) * -1);
}
.hero {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: flex-end;
  padding-top: var(--header-h, 140px);
  overflow: hidden;
}
/* Mobile browsers shrink the viewport as their chrome retracts; svh is the
   stable "small viewport" height, so the hero doesn't jump mid-scroll. */
@supports (height: 100svh) {
  .hero-stage { height: calc(100svh + var(--header-h, 140px) + var(--hero-reveal)); }
  .hero { height: 100svh; }
}
.hero-bg {
  position: absolute;
  inset: 0;
  /* The photo carries the section, so the wash over it is only a whisper of
     navy to tie it to the brand palette. Legibility is bought locally instead
     — see the bottom-left scrim on .hero-overlay and the text shadows below —
     which keeps the sky, roof and greenery bright. */
  background:
    radial-gradient(ellipse at 75% 30%, rgba(209,59,46,0.08), transparent 55%),
    linear-gradient(135deg, rgba(43,41,80,0.14) 0%, rgba(20,19,47,0.18) 100%),
    url("../assets/images/hero-house.jpg") center 58% / cover no-repeat,
    linear-gradient(135deg, #2b2950 0%, #1E1C45 55%, #14132F 100%);
}
.hero-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    /* Narrow band behind the transparent header — the nav and phone pill sit
       over open sky on the right and would otherwise wash out. It lives here
       rather than on .hero-overlay because the overlay fades away on scroll
       and the header does not. */
    linear-gradient(180deg, rgba(15,14,36,0.5) 0%, rgba(15,14,36,0.16) 16%, transparent 30%),
    repeating-linear-gradient(115deg, rgba(255,255,255,0.022) 0px, rgba(255,255,255,0.022) 2px, transparent 2px, transparent 40px);
}
.hero-overlay {
  position: absolute;
  inset: 0;
  /* A tinted column down the left holds the copy at full contrast, then washes
     out entirely by ~74% so the right two-fifths of the photo — the house
     front, the palm, the lawn — stay bright and untouched. */
  background:
    linear-gradient(90deg,
      rgba(15,14,36,0.90) 0%,
      rgba(15,14,36,0.86) 24%,
      rgba(15,14,36,0.68) 38%,
      rgba(15,14,36,0.38) 50%,
      rgba(15,14,36,0.12) 62%,
      transparent 74%),
    linear-gradient(0deg, rgba(15,14,36,0.34) 0%, transparent 32%);
  /* --hero-p is the reveal progress written by main.js: 0 on load — nothing
     but the photo — through to 1 once the copy has fully arrived. It defaults
     to 1 so that without JS the hero simply renders finished. */
  opacity: var(--hero-p, 1);
}
.hero-content {
  position: relative;
  padding-top: 120px;
  padding-bottom: 72px;
  /* Pulled out of the centred .wrap track and pinned left so the copy sits
     inside the tinted column rather than drifting toward the middle on wide
     screens. */
  margin: 0;
  max-width: 680px;
  padding-left: clamp(24px, 5.5vw, 96px);
  padding-right: 24px;
  opacity: var(--hero-p, 1);
}
/* Each line starts a little lower than the one above it, so they arrive in
   sequence rather than as one slab. --stagger is set per element in the HTML. */
.hero-content > * {
  transform: translate3d(0, calc((1 - var(--hero-p, 1)) * var(--stagger, 30px)), 0);
}
/* Before the reveal starts the copy is invisible but still laid out, so take
   the links out of the tab order rather than leaving unreachable focus targets
   sitting over the photo. */
.hero-stage.is-idle .hero-content { visibility: hidden; }

/* Scroll cue — the first scroll reveals the copy instead of moving the page,
   which needs a nudge to read as intentional. Fades out as the copy arrives. */
.hero-cue {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  opacity: calc(1 - var(--hero-p, 1) * 3);
}
.hero-cue-line {
  width: 1px;
  height: 40px;
  background: linear-gradient(180deg, transparent, rgba(255,255,255,0.9));
  animation: cue-drift 2.2s ease-in-out infinite;
}
.hero-cue-text {
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.9);
  text-shadow: 0 1px 10px rgba(15,14,36,0.8);
}
@keyframes cue-drift {
  0%, 100% { transform: translateY(-6px); opacity: 0.35; }
  50%      { transform: translateY(0);    opacity: 1; }
}
.hero-title {
  font-size: clamp(2.4rem, 5.5vw, 4rem);
  color: #fff;
  margin-bottom: 20px;
  /* A soft halo rather than a heavier overlay — lifts the type off the photo
     without dimming the image behind it. */
  text-shadow: 0 2px 24px rgba(15,14,36,0.65), 0 1px 4px rgba(15,14,36,0.45);
}
.hero-title .hl {
  background: linear-gradient(transparent 62%, rgba(209,59,46,0.55) 0%);
}
.hero-sub {
  color: rgba(255,255,255,0.92);
  text-shadow: 0 1px 14px rgba(15,14,36,0.7), 0 1px 3px rgba(15,14,36,0.5);
  font-size: 1.05rem;
  max-width: 540px;
  margin-bottom: 32px;
}
.hero-ctas { display: flex; gap: 14px; flex-wrap: wrap; }

/* ---------- Ticker ---------- */
.ticker {
  background: var(--navy-dark);
  overflow: hidden;
  white-space: nowrap;
  padding: 14px 0;
}
.ticker-track {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  animation: scroll-left 28s linear infinite;
}
.ticker-track span {
  color: rgba(255,255,255,0.85);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.ticker-track i {
  color: var(--red);
  font-style: normal;
  margin: 0 8px;
}
@keyframes scroll-left {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ---------- Statement ---------- */
.statement {
  /* Tighter at the top than the 100px the section shipped with. Centred, the
     block is narrower than the full-width sections either side of it, so the
     standard section padding read as a gap rather than as breathing room. */
  /* No padding below: the section ends flush with the hairline at the bottom
     of the wrap, so the beige stops there rather than carrying on past it.
     The space that used to sit here now lives on .services instead. */
  padding: 55px 0 0;
  text-align: center;
  /* Same darker beige as the quote section near the foot of the page. */
  background: var(--cream-2);
}
/* Hairline between this section and What we do, matched to the rules that
   separate the service rows. Drawn as a child of the wrap rather than a border
   on it: a border sits outside the wrap's 24px side padding and would run
   wider than those rules, where this lands on exactly the same column.
   96px above it and 96px below (carried by the services section, since this
   one now ends flush with the line) leave it sitting evenly between the two. */
.statement .wrap::after {
  content: "";
  display: block;
  margin-top: 96px;
  border-bottom: 1px solid rgba(30,28,69,0.12);
}
.statement-title {
  font-size: clamp(1.9rem, 3.4vw, 2.75rem);
  max-width: 780px;
  margin-bottom: 18px;
  /* The max-widths above are narrower than the wrap, so without this the
     blocks stay pinned to its left edge and only the text inside centres. */
  margin-inline: auto;
}
.statement-sub {
  /* Wider than the 560px it ran at when left-aligned: centred text has no
     straight edge to guide the eye back to, so a taller, narrower column is
     harder to read than the same words on fewer lines. */
  max-width: 680px;
  margin-inline: auto;
  color: #57536b;
  font-size: 1.05rem;
}

/* ---------- Services ---------- */
/* 96px on top rather than 40: the statement section above now ends flush with
   its hairline, so the clearance below that line is carried here — matching
   the 96px above it. */
.services { padding: 96px 0 100px; }

.service-row {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 28px;
  align-items: start;
  padding: 32px 0;
  border-top: 1px solid rgba(30,28,69,0.12);
}
.service-row:last-child { border-bottom: 1px solid rgba(30,28,69,0.12); }

.service-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: var(--navy);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}

.service-body h3 { font-size: 1.3rem; margin-bottom: 8px; }
.service-body p { color: #57536b; max-width: 480px; }
/* Paragraphs are margin-less globally, so a row that runs to a second line
   needs its own gap or the two would sit flush against each other. */
.service-body p + p { margin-top: 8px; }

/* ---------- Portfolio ---------- */
.portfolio { padding: 40px 0 100px; }
.portfolio-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 20px;
  margin-bottom: 36px;
  flex-wrap: wrap;
}

/* --- Slider ---------------------------------------------------------------
   One component, used by both the portfolio photos and the reviews. Built on
   native scroll-snap rather than a transform slider, so swipe, trackpad,
   keyboard and the scrollbar all behave the way the platform intends. The JS
   layers arrows, dots and mouse-drag over the top and can fail without
   breaking the ability to scroll through the slides.
   Each user sets its own --slide-w; everything else is shared.            */
.slider {
  position: relative;
  /* Width of one slide. The track's side padding is derived from the same
     figure so the first and last slides can still reach the centre. */
  --slide-w: 68%;
}
.slider-track {
  display: flex;
  gap: 18px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-inline: calc((100% - var(--slide-w)) / 2);
  /* Room for the slides to lift on hover without the shadow being clipped. */
  padding-block: 10px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.slider-track::-webkit-scrollbar { display: none; }
/* Only offer the grab cursor where there's a real mouse to grab with. */
@media (hover: hover) and (pointer: fine) {
  .slider-track { cursor: grab; }
}
/* Dragging with the mouse sets scrollLeft directly; smooth scrolling would
   fight that, so JS swaps this class in for the duration of the drag. */
.slider-track.is-dragging {
  scroll-behavior: auto;
  scroll-snap-type: none;
  cursor: grabbing;
}
/* Held for the single frame it takes to shift the track by a whole set when
   the loop wraps. Snapping and smooth scrolling would both animate a move
   that is supposed to be invisible. */
.slider-track.is-jumping {
  scroll-behavior: auto;
  scroll-snap-type: none;
}
/* Held for the length of a slide change. JS animates scrollLeft frame by frame
   to get a slower travel than the browser's own smooth scrolling allows, and
   both of these would fight it. Snap comes back at the end, on target. */
.slider-track.is-gliding {
  scroll-behavior: auto;
  scroll-snap-type: none;
}

.slider-slide {
  flex: 0 0 var(--slide-w);
  scroll-snap-align: center;
  position: relative;
  margin: 0;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* Slides either side sit back so the middle one clearly reads as current.
     Timed to the glide in main.js so the fade and the travel finish together. */
  opacity: 0.42;
  transform: scale(0.94);
  transition: opacity 0.8s ease, transform 0.8s ease;
}
.slider-slide.is-active { opacity: 1; transform: scale(1); }

/* --- Portfolio slides --- */
.pf-slide { overflow: hidden; }
.pf-slide img {
  display: block;
  width: 100%;
  height: auto;
  /* Every file is exported to 4:3, so this only guards against a slide
     collapsing before its image has loaded. */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
}
.pf-slide figcaption {
  position: absolute;
  inset: auto 0 0 0;
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: linear-gradient(0deg, rgba(20,19,47,0.82) 0%, rgba(20,19,47,0.45) 45%, transparent 100%);
}
.pf-title { color: #fff; font-weight: 600; font-size: 1.02rem; }
.pf-tag { color: rgba(255,255,255,0.75); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; }

/* --- Arrows --- */
.slider-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 48px;
  height: 48px;
  border: 0;
  border-radius: 50%;
  background: #fff;
  color: var(--navy);
  box-shadow: 0 6px 20px rgba(20,19,47,0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease, opacity 0.25s ease;
}
.slider-nav:hover { background: var(--red); color: #fff; }
.slider-nav:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }
.slider-prev { left: calc((100% - var(--slide-w)) / 2 - 66px); }
.slider-next { right: calc((100% - var(--slide-w)) / 2 - 66px); }

/* --- Dots --- */
.slider-dots {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 26px;
}
.slider-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(30,28,69,0.22);
  cursor: pointer;
  transition: background-color 0.3s ease, width 0.3s ease;
}
.slider-dot.is-active {
  width: 26px;
  border-radius: 4px;
  background: var(--red);
}
.slider-dot:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .slider-track { scroll-behavior: auto; }
  .slider-slide { transition: none; opacity: 1; transform: none; }
  .slider-dot { transition: none; }
}

/* The side gutters shrink as the screen narrows, so the slide takes more of
   the width and the arrows move in over the content. Below 760px there is no
   room left for them and swiping takes over — which is the gesture people
   reach for on a phone anyway. */
@media (max-width: 980px) {
  .slider { --slide-w: 80%; }
  .slider-prev { left: 10px; }
  .slider-next { right: 10px; }
}
@media (max-width: 760px) {
  .slider { --slide-w: 86%; }
  .slider-track { gap: 12px; }
  .slider-nav { display: none; }
  .pf-slide figcaption { padding: 16px 18px; }
}

/* ---------- Process ---------- */
.process {
  background: var(--navy);
  padding: 90px 0;
}
.process-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px;
}
.process-num {
  display: block;
  color: var(--red);
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.95rem;
  margin-bottom: 14px;
}
.process-step h3 { color: #fff; font-size: 1.15rem; margin-bottom: 10px; }
.process-step p { color: rgba(255,255,255,0.72); font-size: 0.92rem; }

/* ---------- Reviews ---------- */
.reviews { padding: 100px 0; }
.rv-slider { margin-top: 36px; }
/* Reviews are read, not glanced at, so the centre card gets less width than a
   photo — a quote set 68% of the page wide is a short, wide block that the eye
   has to track across. Scoped to min-width so the narrower screens keep the
   shared widths, which are already as wide as they can go. */
@media (min-width: 981px) {
  .rv-slider { --slide-w: 52%; }
}
.review-card {
  background: #fff;
  border: 1px solid rgba(30,28,69,0.1);
  padding: 28px;
  /* Slides stretch to the tallest in the set, so the footer is pushed to the
     bottom rather than floating under a short quote. */
  display: flex;
  flex-direction: column;
}
.stars { color: var(--red); letter-spacing: 2px; margin-bottom: 14px; font-size: 0.95rem; }
.review-card p { color: #3a3850; margin-bottom: 22px; font-size: 1rem; flex: 1; }
.review-card footer { display: flex; align-items: center; gap: 12px; font-size: 0.85rem; color: #6a6680; }
.review-card footer strong { color: var(--navy); }
.avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--cream-2);
  color: var(--navy);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.8rem;
  flex: none;
}

/* ---------- Quote / Contact ---------- */
.quote { padding: 100px 0; background: var(--cream-2); }
.quote-grid {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: 64px;
}
.quote-sub { color: #57536b; margin: 18px 0 28px; max-width: 420px; }

.contact-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.contact-list li { display: flex; align-items: center; gap: 10px; font-size: 0.95rem; }
.contact-list a:hover { color: var(--red); }

.quote-form {
  background: #fff;
  border-radius: var(--radius);
  padding: 32px;
  box-shadow: var(--shadow);
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.form-row .field { margin-bottom: 0; }
.field label { font-size: 0.82rem; font-weight: 600; color: var(--navy); }
.field input,
.field select,
.field textarea {
  font-family: var(--font-body);
  font-size: 0.95rem;
  padding: 12px 14px;
  border: 1px solid var(--sand);
  border-radius: 8px;
  background: var(--cream);
  color: var(--ink);
  resize: vertical;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 2px solid var(--red);
  outline-offset: 1px;
}
.form-helper { text-align: center; font-size: 0.78rem; color: #8a869c; margin-top: 10px; }
.form-success {
  text-align: center;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--red);
  margin-top: 14px;
}
/* Same treatment as the success line - the wording carries the difference, and a
   second colour here would fight the two the page already uses. */
.form-error {
  text-align: center;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--red);
  margin-top: 14px;
}
.form-error a { color: inherit; }

/* ---------- Footer ---------- */
.site-footer { background: var(--navy-dark); padding: 70px 0 0; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 32px;
  padding-bottom: 50px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.footer-brand .logo-mark-img { height: 40px; }
.footer-brand .logo-text { font-size: 1.15rem; }
.footer-brand .logo-text-sub { font-size: 0.62rem; }
.footer-brand .logo-text,
.footer-brand .logo-text-sub { color: #fff; }
.footer-brand .logo-text-sub { color: rgba(255,255,255,0.6); }
.footer-tag { color: rgba(255,255,255,0.65); margin-top: 14px; font-family: var(--font-head); font-style: italic; }

.footer-col { display: flex; flex-direction: column; gap: 12px; }
.footer-col h4 { color: #fff; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 6px; }
.footer-col a, .footer-col span { color: rgba(255,255,255,0.7); font-size: 0.92rem; }
.footer-col a:hover { color: var(--red); }

.footer-bottom {
  padding: 24px;
  text-align: center;
  color: rgba(255,255,255,0.45);
  font-size: 0.82rem;
}

/* ---------- Responsive ---------- */
/* Scale the logo lockup down as space tightens so it never crowds the nav/phone */
@media (max-width: 1100px) {
  .logo-mark-img { height: 74px; }
  .logo-text { font-size: 1.7rem; }
  .logo-text-sub { font-size: 0.9rem; }
}

@media (max-width: 980px) {
  .service-row { grid-template-columns: 48px 1fr; }
  .process-grid { grid-template-columns: repeat(2, 1fr); }
  .quote-grid { grid-template-columns: 1fr; gap: 40px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 760px) {
  /* A thumb-flick covers ground fast, so the reveal is shortened to match. */
  .hero-stage { --hero-reveal: 340px; }
  /* The copy runs edge to edge here, so the corner-anchored scrim no longer
     sits under all of it — swap to a bottom-up wash. */
  .hero-overlay {
    background:
      linear-gradient(0deg,
        rgba(15,14,36,0.88) 0%,
        rgba(15,14,36,0.6) 42%,
        rgba(15,14,36,0.18) 72%,
        rgba(15,14,36,0.05) 100%);
  }
  /* The mobile header is taller relative to the hero, so it needs a slightly
     deeper band than the desktop default. */
  .hero-bg::after {
    background-image:
      linear-gradient(180deg, rgba(15,14,36,0.62) 0%, rgba(15,14,36,0.2) 14%, transparent 26%),
      repeating-linear-gradient(115deg, rgba(255,255,255,0.022) 0px, rgba(255,255,255,0.022) 2px, transparent 2px, transparent 40px);
  }
  .main-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--navy);
    flex-direction: column;
    padding: 20px 24px;
    gap: 16px;
    display: none;
  }
  .main-nav.open { display: flex; }
  /* Dropdown has its own navy panel, so links stay white regardless of section */
  .site-header.on-light .main-nav.open a { color: #fff; }
  /* 44px rather than the desktop 40: that's the minimum touch target both Apple
     and Google publish, and this is the only way into the nav on a phone. */
  .nav-toggle { display: flex; width: 44px; height: 44px; }
  .phone-pill span { display: none; }
  .phone-pill { padding: 10px; }
  .logo-mark-img { height: 56px; }
  .logo-text { font-size: 1.3rem; }
  .logo-text-sub { font-size: 0.68rem; }
  .form-row { grid-template-columns: 1fr; }
  /* Exactly 16px, not the 0.95rem used elsewhere. Safari on iOS zooms the page
     in on any field it focuses below 16px and never zooms back out, leaving the
     visitor part-way through the quote form on a magnified, sideways-scrolling
     page. The size is the whole point here — don't drop it back for looks. */
  .field input,
  .field select,
  .field textarea { font-size: 1rem; }
  .footer-grid { grid-template-columns: 1fr; }
}
