/* ==========================================================================
   Castleberg Digital, shared stylesheet
   --------------------------------------------------------------------------
   One file for every page. Edit the tokens below to re-skin the whole site.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens, colours, type, spacing
   -------------------------------------------------------------------------- */
:root {
  /* Colour, Castleberg Digital brand (brand guidelines §3).
     Warm charcoal base, gold accent. Gold is an accent, not a flood:
     small doses on a dark canvas, one clear gold action per screen. */
  --bg:          #141311;  /* charcoal near-black page background */
  --bg-alt:      #1C1A16;  /* surface, cards, panels, section banding */
  --ink:         #F0ECE0;  /* warm light text */
  --ink-soft:    #948C78;  /* muted sub-text, captions */
  --ink-dim:     #66604F;  /* fine print, disabled */
  --accent:      #C9973F;  /* gold, links, CTAs, highlights, contours */
  --accent-hover:#DBAD5C;  /* brighter gold for link/ghost hover on dark */
  /* Button gradient runs toward a slightly deeper gold, kept light
     enough that dark button text holds WCAG AA contrast */
  --accent-grad: linear-gradient(135deg, #C9973F, #B08334);
  --accent-soft: #2A2418;  /* dark gold-tinted fill, tags, subtle panels */
  --success:     #C9973F;  /* warm gold for review stars + confirmations */
  --hairline:    #332E24;  /* dividers */
  --paper:       #221F1A;  /* raised surface, form fields, cards */

  /* Type, Playfair Display (headings/logotype) + Inter (body/UI) */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Motion, every transition/animation on the site uses these, so the
     whole site moves at one consistent tempo. All motion is disabled by the
     prefers-reduced-motion block further down. */
  --dur-fast: 140ms;       /* hovers, presses, focus feedback */
  --dur-base: 220ms;       /* accordion, small reveals */
  --dur-slow: 450ms;       /* page fade, scroll reveals */
  --ease-out: cubic-bezier(0.22, 0.65, 0.3, 1);

  /* Layout */
  --container: 68rem;      /* ~1088px max content width */
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --section-pad: clamp(3.5rem, 9vw, 6.5rem);
  --radius-pill: 999px;    /* buttons + tags */
  --radius-soft: 10px;     /* form fields, mockup frames */
}

/* --------------------------------------------------------------------------
   2. Reset + base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@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;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

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

/* Headings: Playfair Display for the big two only, body face elsewhere for restraint */
h1, h2 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0 0 0.6em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.3rem, 5.5vw, 3.6rem); }
h2 { font-size: clamp(1.6rem, 3.2vw, 2.25rem); }
h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.125rem;
  line-height: 1.35;
  margin: 0 0 0.5em;
}
h4 { font-family: var(--font-body); font-weight: 600; font-size: 1rem; margin: 0 0 0.4em; }

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

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--accent-hover); }

ul, ol { padding-left: 1.2em; margin: 0 0 1em; }

hr {
  border: 0;
  border-top: 1px solid var(--hairline);
  margin: 2rem 0;
}

/* Visible keyboard focus everywhere */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Utility: visually hidden but available to screen readers */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link (first element on every page) */
.skip-link {
  position: absolute;
  left: 1rem; top: -3rem;
  z-index: 100;
  background: var(--accent);
  color: #141311; /* dark on gold, white would fail contrast */
  padding: 0.5rem 1rem;
  border-radius: 0 0 6px 6px;
  text-decoration: none;
  transition: top var(--dur-fast) ease;
}
.skip-link:focus { top: 0; color: #141311; }

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */
.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Sections: hairline top rule + optional band background = the page rhythm.
   No boxes, no shadows. */
.section { padding-block: var(--section-pad); }
.section + .section { border-top: 1px solid var(--hairline); }
.section--band { background: var(--bg-alt); }

/* Narrow measure for long-form copy (About, FAQ, intros) */
.measure { max-width: 42rem; }

.eyebrow {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1rem;
}

.lede {
  font-size: 1.15rem;
  color: var(--ink-soft);
  max-width: 38rem;
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1;
  padding: 0.9rem 1.6rem;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--dur-fast) ease,
    border-color var(--dur-fast) ease,
    color var(--dur-fast) ease,
    box-shadow var(--dur-fast) ease,
    filter var(--dur-fast) ease,
    transform var(--dur-fast) ease;
}
/* Hover feedback: every button darkens and grows slightly; press settles
   it back down a pixel. (Gradient backgrounds can't transition, so the
   darken is a filter shift instead of a colour swap.) */
.btn:hover { transform: scale(1.04); }
.btn:active { transform: scale(1.02) translateY(1px); }
.btn--primary {
  background: var(--accent-grad);
  color: #141311; /* dark text on gold, AA contrast; white fails */
  font-weight: 600;
}
.btn--primary:hover {
  color: #141311;
  filter: brightness(0.88);
  box-shadow: 0 4px 18px rgba(201, 151, 63, 0.3);
}
.btn--primary:active {
  filter: brightness(0.82);
  box-shadow: 0 2px 8px rgba(201, 151, 63, 0.25);
}
.btn--ghost {
  background: transparent;
  color: var(--accent-hover);
  border-color: var(--accent);
}
.btn--ghost:hover {
  background: var(--accent-soft);
  color: var(--ink);
  border-color: var(--accent-hover);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

/* --------------------------------------------------------------------------
   5. Header + nav (shared component, same markup on every page)
   -------------------------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--hairline);
  background: var(--bg);
}
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 4.25rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.2rem;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.brand svg { width: 1.7rem; height: 1.7rem; flex: none; }
/* The full horizontal logo lockup (SVG). 3rem tall ≈ 163px wide, above
   the brand guideline's 140px wordmark minimum. Explicit flex sizing:
   the global img { max-width: 100% } otherwise collapses an auto-width
   SVG to 0 inside the flex header. */
.brand img {
  height: 3rem;
  width: calc(3rem * 3.4); /* 680:200 aspect */
  max-width: none;
  flex: none;
  display: block;
}

.site-nav ul {
  list-style: none;
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.8vw, 1.4rem);
  margin: 0;
  padding: 0;
}
.site-nav a {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  padding: 0.35rem 0.1rem;
  border-bottom: 2px solid transparent;
  transition: color var(--dur-fast) ease;
}
.site-nav a:hover { color: var(--accent); }
/* Desktop only: an understated underline that draws in on hover/focus.
   (Mobile menu links keep the plain colour shift.) */
@media (min-width: 56.0625rem) {
  .site-nav a:not(.nav-cta) { position: relative; }
  .site-nav a:not(.nav-cta)::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -2px;
    height: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur-base) var(--ease-out);
  }
  .site-nav a:not(.nav-cta):hover::after,
  .site-nav a:not(.nav-cta):focus-visible::after { transform: scaleX(1); }
  /* The current page keeps its static border, no animated double line */
  .site-nav a[aria-current="page"]::after { content: none; }
}
.site-nav a[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
/* The nav's own CTA gets button treatment */
.site-nav a.nav-cta {
  display: inline-block; /* transforms don't apply to inline elements */
  background: var(--accent-grad);
  color: #141311; /* dark on gold */
  border-radius: var(--radius-pill);
  padding: 0.55rem 1.1rem;
  border-bottom: 0;
  transition: filter var(--dur-fast) ease, transform var(--dur-fast) ease;
}
.site-nav a.nav-cta:hover { color: #141311; filter: brightness(0.88); transform: scale(1.04); }

/* Hamburger, hidden on desktop */
.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 0.55rem 0.7rem;
  cursor: pointer;
  color: var(--ink);
}
.nav-toggle svg { width: 1.25rem; height: 1.25rem; display: block; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-open { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }

@media (max-width: 56rem) {
  .nav-toggle { display: block; }
  .site-nav {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    z-index: 50;
    background: var(--bg);
    border-bottom: 1px solid var(--hairline);
    padding: 0.5rem var(--gutter) 1.25rem;
  }
  .site-header { position: relative; }
  .site-nav.is-open { display: block; }
  .site-nav ul { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav li { border-bottom: 1px solid var(--hairline); }
  .site-nav li:last-child { border-bottom: 0; padding-top: 0.9rem; }
  .site-nav a { display: block; padding: 0.8rem 0.25rem; font-size: 1rem; }
  .site-nav a[aria-current="page"] { border-bottom-color: transparent; }
  .site-nav a.nav-cta { text-align: center; }
}

/* --------------------------------------------------------------------------
   6. Footer (shared component, same markup on every page)
   -------------------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--hairline);
  background: var(--bg-alt);
  padding-block: 2.75rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 3rem;
  justify-content: space-between;
  align-items: flex-start;
}
.site-footer strong {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
  display: block;
  margin-bottom: 0.3rem;
}
.site-footer .footer-blurb { max-width: 26rem; }
/* Brand tagline under the footer name */
.footer-tag {
  color: var(--accent);
  font-size: 0.9rem;
  margin-bottom: 0.4rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer a { color: var(--ink-soft); }
.site-footer a:hover { color: var(--accent); }
.footer-legal { flex-basis: 100%; margin-top: 0.5rem; font-size: 0.8rem; }
/* Phones: footer links get comfortable tap heights (44px-ish targets);
   desktop keeps its tight editorial spacing */
@media (max-width: 40rem) {
  .site-footer ul a { display: inline-block; padding: 0.7rem 0; }
  .footer-legal a { display: inline-block; padding: 0.7rem 0.2rem; }
}

/* --------------------------------------------------------------------------
   7. Hero, type on the left, real work on the right
   --------------------------------------------------------------------------
   The homepage signature: a browser frame beside the headline showing the
   real Milners build, a contained scroll area you can browse without
   moving the page. Proof instead of decoration. */
.hero {
  padding-block: clamp(3rem, 7vw, 5.5rem) var(--section-pad);
  /* Signature contour motif behind the hero (brand §5). The left-to-right
     gradient darkens the area behind the headline so contour lines never
     sit directly under text. */
  background-image:
    linear-gradient(90deg, var(--bg) 35%, rgba(20, 19, 17, 0.7) 60%, rgba(20, 19, 17, 0.15) 100%),
    url("assets/contour.svg");
  background-size: cover, cover;
  background-position: center, right top;
  background-repeat: no-repeat, no-repeat;
}
.hero .lede { margin-bottom: 1.75rem; }
/* Hero guarantee pillars: two short supporting columns beneath the sub-line,
   stacked on mobile. Existing tokens only, no new assets. */
.hero-pillars {
  list-style: none;
  margin: 0 0 1.75rem;
  padding: 1.5rem 0 0;
  border-top: 1px solid var(--hairline);
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem 2rem;
}
@media (min-width: 34rem) { .hero-pillars { grid-template-columns: 1fr 1fr; } }
.hero-pillars h2 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.3;
  margin: 0 0 0.35rem;
  color: var(--ink);
}
.hero-pillars p { color: var(--ink-soft); font-size: 0.92rem; margin: 0; }
/* SEO build spec: the hero H1 is the keyword line, visually styled as the
   eyebrow; the display slogan is a <p class="hero-headline"> that keeps
   the old H1's look. Semantics for search, unchanged design for people. */
h1.eyebrow { font-family: var(--font-body); line-height: 1.5; }
.hero-headline {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.3rem, 5.5vw, 3.6rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0 0 0.6em;
  text-wrap: balance;
}
.hero .container {
  display: grid;
  gap: 3rem;
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 60rem) {
  /* Give the proof frame more weight (~48%) without cramping the headline. */
  .hero .container { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 4rem; }
  /* On desktop the frame stands taller so it fills about half the first
     screen, real presence for the strongest asset on the page. */
  .hero .walk-viewport--tall { aspect-ratio: auto; height: clamp(30rem, 66vh, 42rem); }
}
/* Taller viewport for the hero frame so the pan shows more of the page */
.walk-viewport--tall { aspect-ratio: 4 / 5; }

/* --------------------------------------------------------------------------
   7b. Statement, an oversized editorial beat that breaks section rhythm
   -------------------------------------------------------------------------- */
.statement { padding-block: clamp(4.5rem, 12vw, 8.5rem); }
.statement blockquote {
  margin: 0 0 0 auto;
  max-width: 26ch;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.7rem, 4.2vw, 2.9rem);
  line-height: 1.22;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.statement blockquote em { font-style: italic; color: var(--accent-hover); }
.statement .statement-source {
  display: block;
  margin-top: 1.25rem;
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   7c. Split, asymmetric two-column prose layout (About)
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  gap: 2rem 4.5rem;
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 54rem) {
  .split { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .split--flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .split > h2 { position: sticky; top: 2rem; }
}

/* --------------------------------------------------------------------------
   9. Homepage sections
   -------------------------------------------------------------------------- */
/* Build → launch → look after: a genuine sequence, so numbers are earned */
.steps {
  list-style: none;
  counter-reset: step;
  margin: 2rem 0 0;
  padding: 0;
  display: grid;
  gap: 0;
}
.steps li {
  counter-increment: step;
  padding: 1.5rem 0;
  border-top: 1px solid var(--hairline);
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: 1rem;
  align-items: baseline;
}
.steps li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--accent);
}
.steps h3 { margin-bottom: 0.25rem; }
.steps p { color: var(--ink-soft); margin: 0; }

/* "Everything covered", the hero-adjacent numbered breakdown of what's in
   every build. Hairline rules per row only (no vertical dividers, no boxes);
   the confidence comes from the type and the numbering, not borders. */
.covered-grid {
  display: grid;
  grid-template-columns: 1fr;
  column-gap: clamp(2rem, 5vw, 4rem);
  margin-top: 2.5rem;
}
@media (min-width: 44rem) { .covered-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 64rem) { .covered-grid { grid-template-columns: 1fr 1fr 1fr; } }
.covered-item {
  padding: 1.6rem 0 1.75rem;
  border-top: 1px solid var(--hairline);
}
.covered-item .covered-num {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--accent);
  margin-right: 0.75rem;
}
.covered-item h3 { margin-bottom: 0.4rem; }
.covered-item p {
  color: var(--ink-soft);
  font-size: 0.95rem;
  margin: 0;
}

/* Tag pills, trades, towns */
.tag-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1.25rem 0 0;
  padding: 0;
}
.tag-list li {
  background: var(--accent-soft);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 500;
  padding: 0.35rem 0.9rem;
  border-radius: var(--radius-pill);
}
/* Town pills that link to a local landing page keep the pill look, with a
   quiet accent underline to show they're clickable */
.tag-list li a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--accent);
}
.tag-list li a:hover { color: var(--accent-hover); }

.two-col {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: 1fr;
}
@media (min-width: 48rem) {
  .two-col { grid-template-columns: 1fr 1fr; gap: 4rem; }
}

/* --------------------------------------------------------------------------
   9b. Homepage pricing teaser, three clickable price cards
   -------------------------------------------------------------------------- */
.price-teaser {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin-top: 2.5rem;
}
@media (min-width: 48rem) { .price-teaser { grid-template-columns: 1fr 1fr 1fr; } }
.price-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-soft);
  padding: 1.75rem 1.6rem;
  color: var(--ink);
  text-decoration: none;
  transition:
    border-color var(--dur-fast) ease,
    transform var(--dur-fast) ease,
    box-shadow var(--dur-fast) ease;
}
.price-card:hover,
.price-card:focus-visible {
  border-color: var(--accent);
  transform: translateY(-3px);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
}
.price-card h3 { font-family: var(--font-display); font-weight: 600; font-size: 1.25rem; margin: 0; }
.price-card .price-figure {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2rem;
  line-height: 1.1;
}
.price-card .price-from {
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-right: 0.15rem;
}
.price-card p { color: var(--ink-soft); font-size: 0.92rem; margin: 0.35rem 0 0; flex: 1; }
.price-card .price-cue {
  margin-top: 1.1rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent);
  transition: color var(--dur-fast) ease;
}
.price-card:hover .price-cue { color: var(--accent-hover); }
.price-card--featured { border-color: var(--accent); }
.price-card .price-flag {
  align-self: flex-start;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--accent-grad);
  color: #141311;
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.6rem;
}

/* --------------------------------------------------------------------------
   10. Pricing, columns divided by hairlines, not boxed cards
   -------------------------------------------------------------------------- */
.tiers {
  display: grid;
  grid-template-columns: 1fr;
  margin-top: 2.5rem;
  border-top: 1px solid var(--hairline);
}
@media (min-width: 52rem) {
  .tiers { grid-template-columns: 1fr 1fr 1fr; }
  .tier + .tier { border-left: 1px solid var(--hairline); border-top: 0; }
}
.tier {
  padding: 2rem clamp(1rem, 2.5vw, 2rem);
  display: flex;
  flex-direction: column;
  position: relative;
}
/* Hover/focus: a 2px accent rule draws in along the tier's top edge to show
   it's interactive. All three tiers are identical at rest, no tier gets
   motion-based prominence by default. */
.tier::before {
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out);
}
.tier:hover::before,
.tier:focus-within::before { transform: scaleX(1); }
.tier + .tier { border-top: 1px solid var(--hairline); }
.tier--featured { background: var(--bg-alt); }
/* Inside a band section, bg-alt would vanish, lift the featured tier onto
   the paper surface instead so it still reads as highlighted */
.section--band .tier--featured { background: var(--paper); }
.tier .tier-flag {
  align-self: flex-start;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--accent-grad);
  color: #141311;
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.9rem;
}
.tier h3 { font-family: var(--font-display); font-weight: 600; font-size: 1.4rem; }
.tier .tier-price {
  font-family: var(--font-display);
  font-size: 2.1rem;
  font-weight: 600;
  margin: 0.25rem 0 0.1rem;
}
.tier .tier-from {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-right: 0.15rem;
}
.tier .tier-monthly { color: var(--ink-soft); font-size: 0.9rem; margin-bottom: 1.25rem; }
.tier ul {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
  flex: 1;
}
.tier li {
  padding: 0.5rem 0 0.5rem 1.5rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.92rem;
  position: relative;
}
.tier li::before {
  content: "";
  position: absolute;
  left: 0; top: 1.05rem;
  width: 0.55rem; height: 0.32rem;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

/* --------------------------------------------------------------------------
   11. Portfolio, offset title-only index + project detail pages
   --------------------------------------------------------------------------
   The listing is deliberately asymmetric: each entry sits at a different
   width/offset on a 12-column grid, linking through to a dedicated project
   page. Each entry pairs its title with a small browser-framed capture of
   the site's front page (or a labelled empty frame while in development). */
.work-index {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  row-gap: clamp(3.5rem, 9vw, 6.5rem);
  margin-top: clamp(1rem, 3vw, 2.5rem);
}
.work-entry {
  display: grid;
  gap: 1.5rem 2.5rem;
  grid-template-columns: 1fr;
  align-items: center;
  text-decoration: none;
}
@media (min-width: 44rem) {
  .work-entry { grid-template-columns: minmax(0, 1fr) minmax(11rem, 15rem); }
}
.work-entry__text { display: block; max-width: 34ch; }
/* The thumbnail reuses .walk-frame/.walk-chrome (all-span markup, since it
   lives inside the <a>) */
.work-entry__thumb { display: block; }
.work-entry__thumb .walk-chrome { display: flex; }
.work-entry__shot {
  display: block;
  aspect-ratio: 16 / 10;
  overflow: hidden;
}
.work-entry__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  transition: transform var(--dur-slow) var(--ease-out);
}
.work-entry:hover .work-entry__shot img,
.work-entry:focus-visible .work-entry__shot img { transform: scale(1.04); }
/* No capture yet (in development / open slot): a quiet labelled frame */
.work-entry__shot--empty {
  display: grid;
  place-items: center;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* The offsets: large opener, a right-shifted second, an indented third */
.work-entry--1 { grid-column: 1 / span 9; }
.work-entry--2 { grid-column: 6 / span 7; }
.work-entry--3 { grid-column: 2 / span 8; }
@media (max-width: 44rem) {
  .work-entry--1, .work-entry--2, .work-entry--3 { grid-column: 1 / -1; }
}
.work-entry__meta {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.7rem;
}
.work-entry__title {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.01em;
  color: var(--ink);
  /* underline draws in on hover/focus via background-size */
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 2px;
  transition: background-size var(--dur-base) var(--ease-out), color var(--dur-base) ease;
  padding-bottom: 0.08em;
}
.work-entry--1 .work-entry__title { font-size: clamp(2.4rem, 6vw, 4.4rem); }
.work-entry--2 .work-entry__title { font-size: clamp(2rem, 4.6vw, 3.2rem); }
.work-entry--3 .work-entry__title { font-size: clamp(1.8rem, 4vw, 2.8rem); }
.work-entry__cue {
  display: block;
  margin-top: 1rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--accent);
  transition: color var(--dur-fast) ease;
}
.work-entry:hover .work-entry__title,
.work-entry:focus-visible .work-entry__title { background-size: 100% 2px; }
.work-entry:hover .work-entry__cue { color: var(--accent-hover); }

/* ---- Case-study stat cards (template, see work-milners.html) ----
   Three cards: icon + headline number + short label. Only ever populated
   with real, measured numbers (change log item 8 / trust rule item 7). */
.stat-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-soft);
  overflow: hidden;
  margin-top: 2rem;
}
@media (min-width: 40rem) { .stat-cards { grid-template-columns: 1fr 1fr 1fr; } }
.stat-card {
  background: var(--paper);
  padding: 1.25rem 1.4rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
}
.stat-card svg { width: 1.4rem; height: 1.4rem; flex: none; color: var(--accent); }
.stat-card .stat-number {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.35rem;
  line-height: 1.1;
}
.stat-card .stat-label {
  display: block;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* ---- Project detail pages ---- */
.project-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 1.5rem 2.5rem;
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--hairline);
}
.project-facts h3 {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.2rem;
}
.project-facts p { margin: 0; }

/* Walkthrough frames: real full-page screenshots inside a minimal browser
   chrome. The featured frame pans through the page as you scroll
   (script.js); the rest are directly scrollable. */
.walk-frame {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-soft);
  overflow: hidden;
  background: var(--bg-alt);
}
.walk-chrome {
  display: flex;
  gap: 0.4rem;
  padding: 0.65rem 0.9rem;
  background: var(--bg-alt);
  border-bottom: 1px solid var(--hairline);
}
.walk-chrome span {
  width: 0.6rem; height: 0.6rem;
  border-radius: 50%;
  background: var(--hairline);
}
.walk-viewport {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
}
.walk-viewport img {
  width: 100%;
  height: auto;
  display: block;
}
/* Manually scrollable frames (services/booking/etc), keyboard-focusable.
   Each piece is a contained scroll area: scrolling inside it never moves
   the wider page (overscroll-behavior stops the chaining), and the in-frame
   scrollbar is always visible so it's obvious the capture scrolls. */
.walk-viewport--scroll {
  overflow-y: auto;
  overscroll-behavior-y: contain;
  scrollbar-width: thin;                        /* Firefox */
  scrollbar-color: var(--accent) var(--paper);  /* Firefox */
}
/* Chromium/Safari: styling the scrollbar swaps the auto-hiding overlay
   scrollbar for a classic always-visible one, that visibility is the point */
.walk-viewport--scroll::-webkit-scrollbar { width: 10px; }
.walk-viewport--scroll::-webkit-scrollbar-track { background: var(--paper); }
.walk-viewport--scroll::-webkit-scrollbar-thumb {
  background: var(--accent);
  border-radius: 999px;
  border: 2px solid var(--paper);
}
.walk-viewport--scroll:focus-visible { outline-offset: -2px; }
.walk-featured { max-width: 56rem; margin-top: 2.5rem; }
.walk-caption {
  margin-top: 0.75rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.walk-grid {
  display: grid;
  gap: 3rem 2.5rem;
  grid-template-columns: 1fr;
  margin-top: 3rem;
}
@media (min-width: 52rem) {
  .walk-grid { grid-template-columns: 1fr 1fr; }
}
.walk-grid h3 { margin: 1rem 0 0.25rem; }
.walk-grid p { color: var(--ink-soft); font-size: 0.95rem; }

.badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--ink);
  margin-bottom: 0.75rem;
}

/* --------------------------------------------------------------------------
   11b. About, the person behind the studio
   -------------------------------------------------------------------------- */
.bio {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 40rem) {
  .bio { grid-template-columns: 11rem 1fr; }
}
/* Portrait slot, holds the real photo; the monogram is the pre-launch
   stand-in (see the PLACEHOLDER comment in about.html) */
.bio-portrait {
  aspect-ratio: 4 / 5;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-soft);
  background: var(--accent-soft);
  overflow: hidden;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 3.5rem;
  color: var(--accent-hover);
}
.bio-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --------------------------------------------------------------------------
   12. FAQ accordion, native <details> so it works without JS
   -------------------------------------------------------------------------- */
.faq-list { margin-top: 1.5rem; border-top: 1px solid var(--hairline); }
.faq-list details { border-bottom: 1px solid var(--hairline); }
.faq-list summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 1.15rem 0.25rem;
  font-weight: 600;
  font-size: 1.02rem;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after {
  content: "";
  flex: none;
  width: 0.6rem; height: 0.6rem;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform var(--dur-base) var(--ease-out);
  margin-right: 0.3rem;
}
.faq-list details[open] summary::after { transform: rotate(225deg); }
/* While the JS collapse animation runs, [open] is still true, .is-closing
   lets the chevron start rotating back immediately on click */
.faq-list details.is-closing summary::after { transform: rotate(45deg); }
.faq-list .faq-answer {
  padding: 0 2.5rem 1.25rem 0.25rem;
  color: var(--ink-soft);
  max-width: 42rem;
  overflow: hidden; /* required by the height animation in script.js */
}

/* --------------------------------------------------------------------------
   13. Forms (Contact + Get a Quote)
   -------------------------------------------------------------------------- */
.form { max-width: 36rem; margin-top: 2rem; }
.form-field { margin-bottom: 1.4rem; }
.form-field label {
  display: block;
  font-weight: 600;
  font-size: 0.92rem;
  margin-bottom: 0.35rem;
}
.form-field .hint {
  font-weight: 400;
  color: var(--ink-soft);
  font-size: 0.85rem;
}
.form-field input[type="text"],
.form-field input[type="email"],
.form-field input[type="tel"],
.form-field select,
.form-field textarea {
  width: 100%;
  font: inherit;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-soft);
  padding: 0.75rem 0.9rem;
}
.form-field textarea { min-height: 9rem; resize: vertical; }
.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
.form-field select { appearance: auto; } /* keep native arrow, reliable + accessible */

/* Radio pairs (e.g. "do you have a website?") */
.radio-row { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.radio-row label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 500;
  margin-bottom: 0;
  cursor: pointer;
}
.radio-row input { accent-color: var(--accent); width: 1.05rem; height: 1.05rem; }

/* --------------------------------------------------------------------------
   14. Reviews component (homepage), two labelled widget slots
   -------------------------------------------------------------------------- */
.review-slots {
  display: grid;
  gap: 3rem;
  margin-top: 2.5rem;
  grid-template-columns: 1fr;
}
@media (min-width: 52rem) {
  .review-slots { grid-template-columns: 1fr 1fr; gap: 4rem; }
}
.review-slot h3 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--hairline);
}
.review-slot h3 svg { width: 1.15rem; height: 1.15rem; flex: none; }
.review-slot .slot-note { font-size: 0.85rem; color: var(--ink-soft); margin-top: 1rem; }

.review {
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--hairline);
}
.review .stars {
  color: var(--success); /* gold stars, ratings read naturally in gold */
  font-size: 0.9rem;
  letter-spacing: 0.15em;
}
.review blockquote {
  margin: 0.4rem 0;
  font-size: 0.95rem;
}
.review cite {
  font-style: normal;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   15. Closing CTA band
   -------------------------------------------------------------------------- */
/* Closing CTA: charcoal surface with the contour motif as texture and one
   clear gold action, gold is an accent, never a flood (brand §3). The
   radial gradient quietens the lines behind the centred text. */
.cta-band {
  background-color: var(--bg-alt);
  background-image:
    radial-gradient(ellipse at center, rgba(28, 26, 22, 0.95) 0%, rgba(28, 26, 22, 0.6) 55%, rgba(28, 26, 22, 0.2) 100%),
    url("assets/contour.svg");
  background-size: cover, cover;
  background-position: center, center;
  border-top: 1px solid var(--hairline);
  color: var(--ink);
  text-align: center;
  padding-block: var(--section-pad);
}
.cta-band h2 { color: var(--ink); }
.cta-band p { color: var(--ink-soft); max-width: 34rem; margin-inline: auto; }
.cta-band .btn--primary { margin-top: 1.5rem; }
.cta-band a:not(.btn) { color: var(--accent); }

/* --------------------------------------------------------------------------
   16. Page-level helpers
   -------------------------------------------------------------------------- */
.page-intro { padding-block: clamp(3rem, 7vw, 5rem) clamp(2rem, 5vw, 3.5rem); }
.page-intro .lede { margin-top: 0.25rem; }
/* Contour-textured intro (build-your-website page), same text-protection
   gradient trick as the homepage hero */
.page-intro--contour {
  background-image:
    linear-gradient(90deg, var(--bg) 35%, rgba(20, 19, 17, 0.7) 60%, rgba(20, 19, 17, 0.15) 100%),
    url("assets/contour.svg");
  background-size: cover, cover;
  background-position: center, right top;
  background-repeat: no-repeat, no-repeat;
}

/* --------------------------------------------------------------------------
   16c. The package builder (build-your-website.html)
   --------------------------------------------------------------------------
   Interactive configurator: pick a package, toggle add-ons, choose a care
   plan, live estimate stays stuck to the bottom of the screen. Markup and
   pricing come from Sam's quote-form.html, restyled onto the site tokens. */
.builder { max-width: 48rem; }
.builder fieldset.builder-card {
  background: var(--bg);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-soft);
  padding: 1.4rem 1.4rem 1rem;
  margin: 0 0 1.25rem;
}
.builder legend {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 0 0.5rem;
}
.builder .opt {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  margin-bottom: 0.5rem;
  cursor: pointer;
  transition: border-color var(--dur-fast) ease, background-color var(--dur-fast) ease;
}
.builder .opt:hover { border-color: var(--accent); background: var(--accent-soft); }
.builder .opt:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.builder .opt input {
  margin-top: 3px;
  accent-color: var(--accent);
  width: 17px; height: 17px;
  flex: none;
}
.builder .opt .t { flex: 1; }
.builder .opt .t b { font-weight: 600; }
.builder .opt .t span { display: block; color: var(--ink-soft); font-size: 0.8rem; margin-top: 2px; }
.builder .opt .price { color: var(--accent); font-weight: 600; white-space: nowrap; font-size: 0.9rem; }
.builder .builder-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 1rem;
}
@media (max-width: 35rem) { .builder .builder-grid { grid-template-columns: 1fr; } }
.builder .form-field label .hint { font-weight: 400; }
/* Live estimate, sticks to the bottom while configuring */
.builder .estimate {
  position: sticky;
  bottom: 0.75rem;
  z-index: 40;
  background: var(--paper);
  border: 1px solid #8A6B34; /* soft gold, the one bordered gold moment */
  border-radius: var(--radius-soft);
  padding: 1rem 1.4rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.75rem;
  margin-top: 1.25rem;
  box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.45);
}
@media (max-width: 40rem) {
  /* sit above the fixed Call/Book bar on phones */
  .builder .estimate { bottom: calc(3.6rem + env(safe-area-inset-bottom)); }
}
.builder .estimate .nums { display: flex; gap: 1.75rem; }
.builder .estimate .lab {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.builder .estimate .val {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.75rem;
  color: var(--accent);
  line-height: 1.1;
}
.builder .estimate .val small { font-size: 0.85rem; color: var(--ink-soft); font-family: var(--font-body); font-weight: 400; }
.builder .estimate .note { font-size: 0.72rem; color: var(--ink-dim); flex-basis: 100%; margin: 0; }

/* Definition-style rows (About page, payment terms) */
.fact-rows { border-top: 1px solid var(--hairline); margin-top: 2rem; }
.fact-row {
  display: grid;
  gap: 0.35rem 2.5rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--hairline);
}
@media (min-width: 44rem) {
  .fact-row { grid-template-columns: 14rem 1fr; }
}
.fact-row h3 { margin: 0; }
.fact-row p { color: var(--ink-soft); margin: 0; }

/* --------------------------------------------------------------------------
   16b. Mobile action bar, phones only, injected by script.js
   --------------------------------------------------------------------------
   A thumb-reach Call / Book bar fixed to the bottom of the viewport on
   small screens. Progressive enhancement: no JS, no bar, nothing lost. */
.mobile-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  display: flex;
  gap: 1px;
  background: var(--hairline);
  border-top: 1px solid var(--hairline);
  padding-bottom: env(safe-area-inset-bottom);
}
.mobile-bar a {
  flex: 1;
  text-align: center;
  padding: 0.95rem 0.5rem;
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
}
.mobile-bar .bar-call { background: var(--bg-alt); color: var(--ink); }
.mobile-bar .bar-book { background: var(--accent-grad); color: #141311; }
@media (min-width: 40.0625rem) { .mobile-bar { display: none; } }
@media (max-width: 40rem) {
  body.has-mobile-bar { padding-bottom: calc(3.4rem + env(safe-area-inset-bottom)); }
}

/* Calendly embed frame, sits on a bg-alt panel so the third-party widget
   doesn't read as an unstyled box on the dark page. The embed URL also
   carries dark-theme colour params (see booking.html). */
.calendly-wrap {
  margin-top: 2rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-soft);
  overflow: hidden;
  background: var(--bg-alt);
}

/* --------------------------------------------------------------------------
   17. Motion
   --------------------------------------------------------------------------
   All durations/easings come from the tokens in :root. Everything here is
   neutralised for reduced-motion users by the prefers-reduced-motion block
   near the top of this file (instant state changes, not slower ones), and
   script.js additionally skips its motion behaviours entirely.
   -------------------------------------------------------------------------- */

/* Page load: one brief fade for the whole page, the only entrance motion
   that runs on every navigation */
@media (prefers-reduced-motion: no-preference) {
  body { animation: page-in var(--dur-slow) var(--ease-out); }
}
@keyframes page-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ---- Scroll reveals ----
   script.js adds .reveal-pending to elements marked data-reveal (and to the
   children of data-reveal-group), then .reveal-visible when they enter the
   viewport, once only, never re-triggered on scroll direction changes.
   Without JS (or with reduced motion) the classes are never added, so
   content is simply visible. transform+opacity only: no layout shift. */
.reveal-pending {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
.reveal-visible {
  opacity: 1;
  transform: none;
}
/* Group stagger (e.g. the build → launch → look after steps): a short
   ~100ms offset per item, reinforcing the sequence without a slow cascade */
[data-reveal-group] > .reveal-pending:nth-child(2) { transition-delay: 100ms; }
[data-reveal-group] > .reveal-pending:nth-child(3) { transition-delay: 200ms; }
[data-reveal-group] > .reveal-pending:nth-child(4) { transition-delay: 300ms; }
[data-reveal-group] > .reveal-pending:nth-child(5) { transition-delay: 400ms; }
[data-reveal-group] > .reveal-pending:nth-child(n+6) { transition-delay: 500ms; }

/* ---- Portfolio: idle pulse on "coming soon" badges ----
   Slow and shallow, reads as "alive", not as a loading spinner. Ends on
   its resting state so the reduced-motion override (1 iteration, ~0ms)
   leaves the badge looking normal. */
.badge--pulse { animation: badge-pulse 3.2s ease-in-out infinite; }
@keyframes badge-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}


/* ---- Form submit states (Contact / Get a Quote) ----
   Calm swap: form fades out, confirmation fades in. The .form-success and
   .form-error blocks live in the page HTML with [hidden]; script.js toggles
   them. Removing [hidden] restarts the fade-in animation. */
.form-fading { opacity: 0; transition: opacity var(--dur-base) ease; }
.form-success {
  max-width: 36rem;
  padding: 1.5rem 0;
  border-top: 2px solid var(--success); /* confirmation = warm gold */
  animation: page-in var(--dur-slow) var(--ease-out);
}
.form-success h2 { font-size: 1.5rem; }
.form-success p { color: var(--ink-soft); }
.form-error {
  color: #F87171;
  font-size: 0.92rem;
  margin: 0 0 1.25rem;
}
