/* ==========================================================================
   PostScript Grants — stylesheet
   Direction: clean professional services site. Sans-serif throughout,
   centered section headers, flat surfaces, white and light-grey grounds.
   ========================================================================== */

:root {
  /* --- colour ------------------------------------------------------------ */
  --white:      #FFFFFF;
  --tint:       #F5F6F8;
  --tint-2:     #E9ECF0;
  /* Sampled from Amber's logo artwork so the page navy matches the wordmark. */
  --navy:       #12244B;
  --navy-deep:  #0B1830;
  --navy-soft:  #1C4372;
  /* Brand blue. #3299ff is only 2.9:1 on white, so it can't carry small text or
     sit behind white button labels. --accent-bright is the true brand shade and
     is used wherever contrast doesn't apply (borders, hover, glows, on navy);
     --accent is one step deeper and clears AA for text and button fills. They
     read as the same blue. */
  --accent-bright: #3299FF;
  --accent:        #0F6FD6;
  --accent-dark:   #0B5CB5;
  --accent-light:  #6DB4FF;
  --accent-tint:   #E8F2FE;
  /* Cool neutral, matched to the grey section tint. */
  --border:     #E3E6EA;
  --border-2:   #CBD1D9;
  --text:       #16232F;
  --text-soft:  #56636F;
  --on-dark:      #FFFFFF;
  --on-dark-soft: rgba(255, 255, 255, 0.76);
  --on-dark-line: rgba(255, 255, 255, 0.18);

  /* --- type -------------------------------------------------------------- */
  --sans: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --fs-h1:    clamp(2.5rem, 5.4vw, 4.25rem);
  --fs-h2:    clamp(1.95rem, 3.5vw, 2.85rem);
  --fs-h3:    1.19rem;
  --fs-body:  1.0625rem;
  --fs-lede:  clamp(1.08rem, 1.5vw, 1.25rem);
  --fs-label: 0.775rem;

  /* --- shape ------------------------------------------------------------- */
  --r-lg: 16px;
  --r-md: 12px;
  --r-sm: 8px;
  --r-pill: 999px;

  /* --- layout ------------------------------------------------------------ */
  --shell: 1180px;
  --pad: clamp(1.25rem, 5vw, 3rem);
  --section-y: clamp(4.5rem, 8vw, 7.5rem);
  --nav-h: 80px;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

body {
  margin: 0;
  background: var(--white);
  color: var(--text);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }
svg { display: block; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; }
li { list-style: none; }
a { color: inherit; }

h1, h2, h3 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.028em;
  line-height: 1.12;
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); letter-spacing: -0.035em; line-height: 1.06; }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -0.014em; line-height: 1.3; }

::selection { background: var(--accent); color: #fff; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; top: -100px; left: var(--pad); z-index: 100;
  background: var(--navy); color: #fff;
  padding: 0.7rem 1.2rem; border-radius: var(--r-pill);
  font-size: var(--fs-label); font-weight: 600; text-decoration: none;
}
.skip-link:focus { top: 1rem; }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.section { padding-block: var(--section-y); scroll-margin-top: var(--nav-h); }
.section--tint { background: var(--tint); }
.contact { scroll-margin-top: var(--nav-h); }

/* --------------------------------------------------------------------------
   Centered section header
   -------------------------------------------------------------------------- */

.head {
  max-width: 52rem;
  margin-inline: auto;
  margin-bottom: clamp(2.75rem, 5vw, 4rem);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.head h2 { max-width: 20ch; }
.head__sub {
  font-size: var(--fs-lede);
  color: var(--text-soft);
  max-width: 62ch;
  line-height: 1.6;
  /* Stops a last line from being a single orphaned word — which is what made
     "funding." drop on its own under the Services heading. */
  text-wrap: pretty;
}
.head--light h2 { color: var(--on-dark); }
.head--light .head__sub { color: var(--on-dark-soft); }

.eyebrow {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent);
}
.eyebrow--light { color: var(--accent-light); }

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

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  --btn-bd: var(--border-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.85rem 1.6rem;
  font-family: var(--sans);
  font-size: 0.93rem;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1.5px solid var(--btn-bd);
  border-radius: var(--r-pill);
  transition: background-color 0.25s ease, color 0.25s ease,
              border-color 0.25s ease, transform 0.25s ease;
}
.btn:hover { transform: translateY(-1px); }

.btn--primary { --btn-bg: var(--accent); --btn-fg: #fff; --btn-bd: var(--accent); }
.btn--primary:hover { --btn-bg: var(--accent-dark); --btn-bd: var(--accent-dark); }

.btn--ghost { --btn-fg: var(--navy); --btn-bd: var(--border-2); }
.btn--ghost:hover { --btn-bg: var(--navy); --btn-fg: #fff; --btn-bd: var(--navy); }

.btn--onDark { --btn-fg: #fff; --btn-bd: rgba(255, 255, 255, 0.45); }
.btn--onDark:hover { --btn-bg: rgba(255, 255, 255, 0.14); --btn-bd: #fff; }

.btn--sm { padding: 0.6rem 1.15rem; font-size: 0.86rem; }
.btn--lg { padding: 1.05rem 2rem; font-size: 0.97rem; }
.btn--block { width: 100%; }

/* --------------------------------------------------------------------------
   Logo
   -------------------------------------------------------------------------- */

/* Amber's wordmark is flat navy artwork with transparency. On dark grounds we
   knock it out to white with a filter rather than shipping a second file —
   brightness(0) flattens it to black, invert(1) lifts it to white, and the
   alpha channel (so, the letterforms) survives both. */
.logo { display: inline-flex; align-items: center; text-decoration: none; }
.logo img { height: 26px; width: auto; }

.nav .logo img {
  filter: brightness(0) invert(1);
  transition: filter 0.35s ease;
}
.nav.is-stuck .logo img { filter: none; }

.logo--tagline img { height: 54px; filter: brightness(0) invert(1); }

/* --------------------------------------------------------------------------
   Nav
   -------------------------------------------------------------------------- */

/* Solid brand navy at rest — a defined header bar rather than the photo showing
   through — then white and frosted once the page scrolls. */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  background: var(--navy);
  transition: background-color 0.35s ease, box-shadow 0.35s ease;
}
.nav__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  position: relative;
  min-height: var(--nav-h);
  color: #fff;
  transition: color 0.35s ease;
}
.nav.is-stuck {
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--border), 0 8px 28px -20px rgba(16, 41, 74, 0.5);
}
.nav.is-stuck .nav__bar { color: var(--text); }

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.2vw, 2.1rem);
}
.nav__links > a:not(.btn) {
  font-size: 0.93rem;
  font-weight: 500;
  text-decoration: none;
  color: inherit;
  opacity: 0.88;
  transition: opacity 0.2s ease, color 0.2s ease;
}
.nav__links > a:not(.btn):hover { opacity: 1; color: var(--accent); }
.nav.is-stuck .nav__links > a:not(.btn) { opacity: 1; color: var(--text-soft); }
.nav.is-stuck .nav__links > a:not(.btn):hover { color: var(--accent); }

.nav__toggle {
  display: none;
  background: none; cursor: pointer; color: inherit;
  border: 1.5px solid currentColor; border-radius: var(--r-sm);
  padding: 0.55rem 0.62rem;
  opacity: 0.7;
}
.nav__bars { display: block; width: 18px; }
.nav__bars i {
  display: block; height: 2px; border-radius: 2px; background: currentColor;
  transition: transform 0.3s ease;
}
.nav__bars i + i { margin-top: 5px; }
.nav__toggle[aria-expanded="true"] .nav__bars i:first-child { transform: translateY(3.5px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__bars i + i { transform: translateY(-3.5px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   Hero — full-bleed background, centered content
   -------------------------------------------------------------------------- */

/* Content sits low in the frame rather than dead centre. The faces in the photo
   are in the upper-middle, which is exactly where a vertically-centred headline
   would land — dropping the text into the lower third keeps them clear of each
   other and puts the type over the darkest part of the scrim. */
.hero {
  position: relative;
  isolation: isolate;
  /* Full viewport. svh is the small-viewport unit — on mobile it measures the
     screen with the browser chrome showing, so the hero never gets taller than
     what's actually visible. vh above it as the fallback for older browsers. */
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  align-items: end;
  justify-items: center;
  padding-block: calc(var(--nav-h) + 3rem) clamp(3rem, 6vw, 5rem);
  text-align: center;
  overflow: hidden;
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--navy-deep);
  overflow: hidden;
  --photo: url("assets/hero.webp");
}

/* The photograph. Desaturated, because the original is warm — tan, wood, skin
   tones — and warm colour fights the navy badly. Pulling the saturation down
   lets the navy overlay set the colour of the whole frame.
   hero-people.svg stays underneath as the fallback if --photo ever 404s. */
.hero__bg::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--photo, none), url("assets/hero-people.svg");
  background-size: cover, cover;
  background-position: center 44%, center;
  background-repeat: no-repeat;
  filter: saturate(0.55) contrast(1.04);
}

/* The hero navy, kept as an overlay on top of the photo. Same colour ramp the
   hero used before the photo existed, now translucent: lightest across the
   upper-middle so the faces read, heaviest at the bottom where the type sits. */
.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(185deg,
    rgba(22, 58, 99, 0.74) 0%,
    rgba(18, 38, 78, 0.58) 24%,
    rgba(16, 32, 66, 0.58) 46%,
    rgba(10, 26, 50, 0.84) 74%,
    rgba(8, 20, 38, 0.95) 100%);
}

.hero__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.35rem;
  color: #fff;
}
/* Four words, so it holds one line at every size — no wrap control needed.
   Sized up, since a short headline can carry more weight without crowding. */
.hero h1 {
  max-width: 20ch;
  font-size: clamp(3rem, 7.5vw, 5.75rem);
}
/* Wide enough for two lines rather than three — the sentence is ~160 characters,
   so it needs roughly 80 per line. `balance` then evens the two out, instead of
   `pretty`, which only guards against a lone word on the last line. */
.hero__lede {
  font-size: var(--fs-lede);
  line-height: 1.6;
  color: var(--on-dark-soft);
  max-width: 84ch;
  text-wrap: balance;
}
.hero__meta {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--on-dark-line);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-soft);
  line-height: 2;
}
.hero__meta b { color: var(--accent-light); font-weight: 700; padding-inline: 0.35rem; }

/* --------------------------------------------------------------------------
   Stats
   -------------------------------------------------------------------------- */

.stats { padding-block: clamp(3rem, 6vw, 4.5rem); border-bottom: 1px solid var(--border); }
.stats__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(2rem, 4vw, 3rem);
  text-align: center;
}
.stat { display: flex; flex-direction: column; gap: 0.4rem; align-items: center; }
.stat__num {
  font-size: clamp(2.7rem, 5vw, 3.9rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.045em;
  color: var(--navy);
  font-variant-numeric: tabular-nums lining-nums;
}
.stat__num i { font-style: normal; color: var(--accent); }
.stat__label {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-soft);
  line-height: 1.6;
  max-width: 22ch;
}

/* --------------------------------------------------------------------------
   Services
   -------------------------------------------------------------------------- */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: clamp(1rem, 1.8vw, 1.5rem);
}
.card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 3vw, 2.25rem);
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
  border-color: var(--accent-bright);
  transform: translateY(-4px);
  box-shadow: 0 18px 40px -28px rgba(16, 41, 74, 0.55);
}
/* Solid blue tile, white icon. The pale tint version disappeared against the
   grey section — this carries the brand blue instead of hinting at it. The
   gradient runs bright-to-deep so the white stroke keeps 3:1 across the whole
   tile, which the flat #3299FF alone would not. */
.card__icon {
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border-radius: 14px;
  background: linear-gradient(140deg, var(--accent-bright) 0%, var(--accent-dark) 100%);
  color: #fff;
  margin-bottom: 0.5rem;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.card__icon svg { width: 25px; height: 25px; stroke-width: 1.75; }
.card:hover .card__icon { transform: translateY(-2px) scale(1.04); }
.card h3 { max-width: 16ch; }
.card p { font-size: 0.96rem; color: var(--text-soft); line-height: 1.65; }

.tier__terms {
  font-size: 0.85rem;
  color: var(--text-soft);
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  margin-top: auto;
}

/* Bottoms lined up but the divider rules didn't: the first card's terms wrap to
   two lines while the others fit on one, so its border started a line higher.
   Subgrid hands each card the same four row tracks — heading, price, blurb,
   terms — so every rule lands on the same line across all three. The flex rules
   above stay as the fallback for browsers without subgrid. */
@supports (grid-template-rows: subgrid) {
  .tier {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 4;
    row-gap: 0.9rem;
  }
  /* Words, not digits, so this sits a little smaller than the figures — matching
   their point size would make it read as shouting. Subgrid keeps the row itself
   the same height across all three cards, so the layout stays even. */
.tier__price--quote strong {
  font-size: clamp(1.75rem, 2.7vw, 2.15rem);
  letter-spacing: -0.03em;
  color: var(--accent);
}

.tier__desc { flex: none; }
  .tier__terms { margin-top: 0; }
}

.footnote {
  margin-top: clamp(2rem, 3.5vw, 2.75rem);
  text-align: center;
  font-size: 0.93rem;
  color: var(--text-soft);
  max-width: 58ch;
  margin-inline: auto;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   About
   -------------------------------------------------------------------------- */

.about__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: center;
}
/* Square, because Amber's headshot is landscape (926×765) — a square crop keeps
   her full head height and trims only a little from the sides. A 4/5 portrait
   slot would have cut the frame in hard. */
.photo {
  width: 100%;
  aspect-ratio: 1 / 1;
  /* Floor in case aspect-ratio is unsupported, so the box can never collapse. */
  min-height: 260px;
  background-repeat: no-repeat;
  border-radius: var(--r-lg);
  background-color: var(--navy);
  background-image:
    var(--photo, none),
    radial-gradient(110% 80% at 74% 10%, rgba(50, 153, 255, 0.42), transparent 58%),
    linear-gradient(200deg, #1A4270 0%, #10294A 50%, #0A1D36 100%);
  background-size: cover, auto, auto;
  /* She sits right of centre in the frame, so the square crop is nudged right —
     a dead-centre crop clipped her shoulder. */
  background-position: 56% center;
  --photo: url("assets/amber.jpg");
}
.about__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 1.1rem; }
.about__copy h2 { max-width: 16ch; }
.about__copy p { color: var(--text-soft); max-width: 56ch; }
.about__copy .btn { margin-top: 0.75rem; }

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

/* Five steps is a prime number, so auto-fit stranded the fifth on its own row.
   Pinned to five columns wide, then straight to a stacked list — no orphan at
   any width. */
.steps {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(1.25rem, 2vw, 1.75rem);
}
.step {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding-top: 1.5rem;
  border-top: 2px solid var(--border-2);
  transition: border-color 0.3s ease;
}
.step:hover { border-top-color: var(--accent-bright); }

@media (max-width: 1040px) {
  .steps { grid-template-columns: 1fr; gap: 0; }
  .step {
    display: grid;
    grid-template-columns: 4.75rem 1fr;
    align-items: baseline;
    column-gap: 1.25rem;
    padding-block: 1.4rem;
    border-top-width: 1px;
  }
  .step h3 { grid-column: 2; }
  .step p:not(.step__num) { grid-column: 2; max-width: 56ch; }
}
/* Editorial scale. These are a real sequence, so the numerals carry weight
   rather than acting as small labels. Deep blue, not the bright shade — at
   this size #3299FF sits just under the 3:1 minimum on the grey ground. */
.step__num {
  font-size: clamp(2.4rem, 3.6vw, 3.4rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.045em;
  color: var(--accent);
  font-variant-numeric: lining-nums;
}
.step p:not(.step__num) { font-size: 0.94rem; color: var(--text-soft); line-height: 1.6; }

/* --------------------------------------------------------------------------
   Testimonials
   -------------------------------------------------------------------------- */

.quotes {
  position: relative;
  background: var(--navy);
  background-image: radial-gradient(60% 80% at 82% 10%, rgba(50, 153, 255, 0.25), transparent 60%);
  color: #fff;
  padding-block: clamp(3rem, 5vw, 4.25rem);
  overflow: hidden;
  text-align: center;
}
/* In normal flow, not absolutely positioned. Pulling it out of flow meant it
   ate into the top padding while the bottom kept its full value, so the block
   sat high in the section. In flow, the padding balances on its own. */
.quotes__mark {
  display: block;
  font-size: clamp(3.25rem, 5vw, 4.5rem);
  font-weight: 800;
  line-height: 0.72;
  color: var(--accent-light);
  opacity: 0.26;
  margin-bottom: 0.12em;
  pointer-events: none;
  user-select: none;
}
.quotes__viewport {
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.quotes__viewport::-webkit-scrollbar { display: none; }
.quotes__track { display: flex; }
/* Quotes vary a lot in length — Carla's is one line, Sandy's is four. Centring
   each slide in the track keeps them from jumping around as you page through. */
.quote {
  flex: 0 0 100%;
  max-width: 100%;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.quote blockquote {
  margin: 0 auto;
  font-size: clamp(1.4rem, 2.9vw, 2.3rem);
  font-weight: 600;
  line-height: 1.34;
  letter-spacing: -0.026em;
  max-width: 24ch;
  text-wrap: pretty;
}
.quote__by {
  margin-top: clamp(1.1rem, 2vw, 1.5rem);
  font-size: 0.95rem;
  font-weight: 700;
  color: #fff;
}
.quote__by span {
  display: block;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent-light);
  margin-top: 0.2rem;
}

.quotes__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: clamp(1.4rem, 2.4vw, 1.9rem);
}
/* A class selector beats the UA rule for [hidden], so without this the arrows
   showed — and did nothing — while there was only one testimonial. */
.quotes__nav[hidden] { display: none; }
.qbtn {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1.5px solid var(--on-dark-line);
  border-radius: 50%;
  color: #fff; font-size: 1rem; cursor: pointer;
  transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}
.qbtn:hover { background: #fff; border-color: #fff; color: var(--navy); }
.quotes__dots { display: flex; gap: 0.5rem; }
.quotes__dots button {
  width: 7px; height: 7px; padding: 0;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, 0.3);
  transition: background-color 0.25s ease, transform 0.25s ease;
}
.quotes__dots button[aria-current="true"] { background: var(--accent-light); transform: scale(1.35); }

/* --------------------------------------------------------------------------
   Pricing
   -------------------------------------------------------------------------- */

.tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: clamp(1rem, 1.8vw, 1.5rem);
}
.tier {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: clamp(1.9rem, 3vw, 2.4rem);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}
.tier:hover {
  border-color: var(--accent-bright);
  transform: translateY(-4px);
  box-shadow: 0 18px 40px -28px rgba(16, 41, 74, 0.55);
}
.tier__price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem;
  font-variant-numeric: tabular-nums lining-nums;
}
.tier__price span {
  flex: 0 0 100%;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin-bottom: 0.25rem;
}
.tier__price strong {
  font-size: clamp(2.2rem, 3.6vw, 2.8rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--navy);
}
.tier__price i { font-style: normal; font-size: 0.92rem; font-weight: 600; color: var(--text-soft); }
.tier__desc { font-size: 0.96rem; color: var(--text-soft); line-height: 1.65; flex: 1; }
.tier .btn { margin-top: 0.5rem; }

/* --------------------------------------------------------------------------
   Contact
   -------------------------------------------------------------------------- */

.contact {
  background: var(--navy);
  background-image: radial-gradient(60% 70% at 50% 0%, rgba(50, 153, 255, 0.22), transparent 62%);
  padding-block: var(--section-y);
}
.contact .head { margin-bottom: clamp(2.5rem, 4vw, 3.25rem); }

/* A class selector outranks the browser's built-in [hidden] rule, so without
   the companion rule below, JS sets hidden on success and nothing happens —
   the form stays on screen with a stuck "Sending..." button. */
.form[hidden] { display: none; }

.form {
  max-width: 40rem;
  margin-inline: auto;
  background: var(--white);
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  box-shadow: 0 30px 70px -40px rgba(4, 14, 28, 0.8);
}
.form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1.1rem; }

.field { display: flex; flex-direction: column; gap: 0.4rem; margin: 0; }
.field label {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--text);
  background: var(--tint);
  border: 1.5px solid var(--border);
  border-radius: var(--r-sm);
  padding: 0.75rem 0.95rem;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.field textarea { resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: #93A0A8; }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--border-2); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  background: var(--white);
  border-color: var(--accent-bright);
}
.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-soft) 50%),
                    linear-gradient(135deg, var(--text-soft) 50%, transparent 50%);
  background-position: right 1rem center, right calc(1rem + 5px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 2.25rem;
  cursor: pointer;
}
.field select option { background: var(--white); color: var(--text); }
.field :user-invalid { border-color: #C0563F; }

.form .btn { margin-top: 0.5rem; }
.form__status { font-size: 0.93rem; color: var(--accent); min-height: 1.4em; text-align: center; }
.form__status[data-state="error"] { color: #C0563F; }

/* Success state. Same white card as the form it replaces, so the section does
   not visibly lurch when they swap. */
.sent {
  max-width: 40rem;
  margin-inline: auto;
  background: var(--white);
  border-radius: var(--r-lg);
  padding: clamp(2.25rem, 4vw, 3rem);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  box-shadow: 0 30px 70px -40px rgba(4, 14, 28, 0.8);
}
.sent[hidden] { display: none; }
.sent__icon {
  width: 56px; height: 56px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent-tint);
  color: var(--accent);
}
.sent__icon svg { width: 28px; height: 28px; }
.sent h3 { font-size: clamp(1.15rem, 2vw, 1.4rem); max-width: 22ch; }
.sent p {
  font-size: 0.97rem;
  color: var(--text-soft);
  line-height: 1.65;
  max-width: 46ch;
  text-wrap: pretty;
}
.sent a { color: var(--accent); font-weight: 600; }

.form__privacy {
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--text-soft);
  text-align: center;
  max-width: 44ch;
  margin-inline: auto;
}

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

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

.footer { background: var(--navy-deep); color: #fff; padding-block: clamp(3rem, 6vw, 4.5rem) 0; }
.footer__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2.5rem 3rem;
  padding-bottom: clamp(2.5rem, 5vw, 3.5rem);
}
.footer__brand { display: flex; flex-direction: column; gap: 0.75rem; max-width: 30rem; }
.footer__brand p { font-size: 0.95rem; color: var(--on-dark-soft); }
.footer__brand a[href^="mailto"] { color: var(--accent-light); text-decoration: none; font-weight: 600; }
.footer__brand a[href^="mailto"]:hover { text-decoration: underline; }
.footer__nav { display: flex; flex-wrap: wrap; gap: 0.6rem 1.75rem; align-content: flex-start; }
.footer__nav a { font-size: 0.93rem; font-weight: 500; color: var(--on-dark-soft); text-decoration: none; }
.footer__nav a:hover { color: #fff; }

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding-block: 1.5rem;
  border-top: 1px solid var(--on-dark-line);
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.55);
}

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */

/* Hiding only ever happens once JS is confirmed, so a JS failure can never
   leave the page blank. */
.js-ready .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.js-ready .reveal.is-in { opacity: 1; transform: none; }

.js-ready .load {
  opacity: 0;
  transform: translateY(20px);
  animation: settle 0.9s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}
.load--1 { animation-delay: 0.06s; }
.load--2 { animation-delay: 0.15s; }
.load--3 { animation-delay: 0.24s; }
.load--4 { animation-delay: 0.33s; }
.load--5 { animation-delay: 0.42s; }

@keyframes settle { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js-ready .reveal, .js-ready .load,
  .reveal, .load { opacity: 1; transform: none; animation: none; }
  .btn:hover, .card:hover, .tier:hover, .card:hover .card__icon { transform: none; }
  .quotes__viewport { scroll-behavior: auto; }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 960px) {
  .about__grid { grid-template-columns: 1fr; }
  .about__media { max-width: 420px; margin-inline: auto; }
}

@media (max-width: 760px) {
  .nav__toggle { display: block; }
  .nav__links {
    position: absolute;
    top: calc(100% - 0.5rem); left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    color: var(--text);
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: 0 24px 50px -30px rgba(16, 41, 74, 0.55);
    padding: 0.5rem 1.25rem 1.35rem;
    display: none;
  }
  .nav__links.is-open { display: flex; }
  .nav__links > a:not(.btn) {
    padding-block: 0.9rem;
    border-bottom: 1px solid var(--border);
    font-size: 1rem;
    opacity: 1;
    color: var(--text);
  }
  .nav__links .btn { margin-top: 1.1rem; }

  /* A fixed height instead of 100svh.
     svh measures the screen with Safari's chrome showing, so the hero was a
     different height on every device — and a different height again in
     DevTools, which has no chrome to subtract. The photo is set to cover, so
     changing the box's shape re-crops it: her face landed somewhere different
     each time. Pinning the height makes the crop identical everywhere.
     min-height rather than height, so the box can still grow if the text wraps
     further than expected at very narrow widths. */
  .hero { min-height: 620px; }

  /* The hero text is bottom-anchored. On a narrow screen the photo crops much
     tighter than it does on desktop, which brings a face up into where the
     headline sits. Trimming the bottom padding drops the type further down the
     frame, clear of her, and onto the darkest part of the scrim. */
  .hero { padding-bottom: 1.5rem; }

  /* Lift the photograph so her face clears the headline.
     On a phone the image is height-constrained under `cover` — it fits the box
     exactly top to bottom, which leaves no vertical slack to reposition. So
     oversize it to 125% of the box height first, then anchor the bottom: that
     crops the top quarter and carries her face up out of the type. The second
     value keeps the SVG fallback on its original cover behaviour. */
  /* The service list is wide enough that it wraps to three cramped lines on a
     phone and crowds the hero. Hidden here rather than deleted — it still runs
     on desktop, and the same four services appear in full in the Services
     section below, so nothing is lost to a mobile visitor.
     display:none also takes it out of the accessibility tree, which is correct:
     a screen reader on a phone would otherwise read a list the sighted user
     cannot see. */
  .hero__meta { display: none; }

  .hero__bg::before {
    background-size: auto 125%, cover;
    /* 75% rather than bottom. The oversize leaves 25% of the box height spare;
       anchoring hard to the bottom spent all of it going up and clipped the top
       of her head, which sits at y=140 in the 1200x800 original. Easing back to
       75% drops the frame about 30px and leaves her hair a margin, while still
       carrying her face clear of the headline. This is the number to turn if
       the crop needs adjusting again. */
    background-position: center 75%, center;
  }

  .steps { grid-template-columns: 1fr; }

  /* Three stats under auto-fit gave two across and a stranded third. Stack
     them — one per row reads cleanly and gives the big figures room. */
  .stats__grid { grid-template-columns: 1fr; gap: 2.25rem; }

  /* ---- consistent centring on mobile ----------------------------------
     On desktop the section headings centre while card and step content sits
     left, which reads fine across a wide row. Once everything collapses into
     one narrow column, that mix looks accidental — so centre it all. */

  .card,
  .tier,
  .step,
  .about__copy {
    text-align: center;
    align-items: center;
  }

  /* Icons and numerals are flex children, so centring the text is not enough. */
  .card__icon { margin-inline: auto; }
  .card h3 { max-width: none; }
  /* The price is a flex row — "Starting at" on its own line, then the figure and
     "/month" beside it. Centring the card's text does nothing to flex children:
     their horizontal position is set by justify-content. The rule here used to
     say align-items, which is the cross axis, so it never moved anything.
     Baseline alignment is left alone so "/month" keeps sitting on the figure's
     baseline instead of drifting to its vertical middle. */
  .tier__price { justify-content: center; }

  .step {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding-block: 1.75rem;
  }
  .step p:not(.step__num) { max-width: none; }

  .about__copy p { max-width: none; }
  .about__copy .btn { align-self: center; }

  .footer__inner { justify-content: center; text-align: center; }
  .footer__brand { align-items: center; }
  .footer__nav { justify-content: center; }
  .logo { justify-content: center; }
  .footer__legal { align-items: center; text-align: center; }
}

@media (max-width: 480px) {
  .form__row { grid-template-columns: 1fr; }
  .footer__legal { flex-direction: column; }
}


/* --------------------------------------------------------------------------
   Print / save-as-PDF
   -------------------------------------------------------------------------- */

@media print {
  /* Scroll reveals are opacity-0 until JS sees them. Anything never scrolled
     into view would otherwise print as a blank gap. */
  .js-ready .reveal, .js-ready .load,
  .reveal, .load { opacity: 1 !important; transform: none !important; animation: none !important; }

  /* Keep the navy panels and the hero photo — browsers drop backgrounds by default. */
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }

  /* A fixed header would stamp itself onto every page. */
  .nav { position: static; }
  .skip-link { display: none; }

  /* A full-height hero would eat an entire sheet on its own. */
  .hero { min-height: 0; padding-block: 3rem 2.5rem; }
  .hero h1 { font-size: 3rem; }

  .section, .quotes, .contact { padding-block: 2.5rem; }

  /* The carousel shows one quote at a time on screen; print them all. */
  .quotes__viewport { overflow: visible; }
  .quotes__track { display: block; }
  .quote { max-width: none; margin-bottom: 1.5rem; }
  .quotes__nav { display: none; }

  /* Don't split a card across a page break. */
  .card, .tier, .step, .quote, .stat { break-inside: avoid; }
  .about__grid { break-inside: avoid; }

  @page { margin: 12mm; }
}
