/* ==========================================================================
   Southside Digital: site.css
   One shared stylesheet for every page. Hand-coded, no build step.
   Look: "Clear Water: Follow the Link" (canvas shell.md). Mobile-first,
   intrinsic layouts (flex-wrap / auto-fit grids), works 320-1440px.

   Contents
     1. Tokens
     2. Base and reset
     3. Typography
     4. Layout (container, sections, stack, cluster, split, grid)
     5. Utilities and placeholders (.ph)
     6. Header, nav, skip link
     7. Notices and capacity line
     8. Buttons and links
     9. Heading block and hero (incl. typing headline and the slate stage)
    10. Google listing mock-up (.gbp) and browser panels
    11. Cards: work, service columns, steps, dead ends, price, quote sheet
    12. Lists: promises, checklist, spec sheet, callout, facts, toc, contact
    13. FAQ
    14. Forms
    15. CTA band, booking panel, misc page parts
    16. Footer
    17. Motion, print
   ========================================================================== */

/* 1. Tokens ---------------------------------------------------------------- */
:root {
  /* Colour: six tokens. #42A9C8 (teal) is decoration only: it fails as text. */
  --slate: #303642;   /* body text, headings, input borders, footer, slate band */
  --action: #397085;  /* links, primary buttons, eyebrows, focus ring, icons (5.48:1) */
  --teal: #42A9C8;    /* decoration: eyebrow slash, ring, dashed path, stars */
  --tint: #F5FBFC;    /* alternate sections, notice bar, placeholder fills */
  --paper: #FFFFFF;   /* page, cards, inputs, text on slate/action */
  --line: #D5E0E5;    /* hairlines (decorative only) */
  /* Functional, not part of the palette: form error text and borders (7.0:1 on paper, 6.7:1 on tint). */
  --danger: #A8281E;
  --line-on-dark: rgba(255, 255, 255, 0.2);
  --shadow: 0 1px 2px rgba(48, 54, 66, 0.06), 0 8px 24px rgba(48, 54, 66, 0.10);

  /* Type */
  --font: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fs-h1: clamp(1.875rem, 1.1rem + 3.2vw, 3.5rem);       /* 30 -> 56 */
  --fs-h2: clamp(1.625rem, 1.2rem + 1.7vw, 2.5rem);       /* 26 -> 40 */
  --fs-h3: clamp(1.1875rem, 1.05rem + 0.6vw, 1.5rem);     /* 19 -> 24 */
  --fs-h4: clamp(1.125rem, 1.05rem + 0.3vw, 1.25rem);     /* 18 -> 20 */
  --fs-lead: clamp(1rem, 0.9rem + 0.45vw, 1.25rem);       /* 16 -> 20 */
  --fs-body: clamp(1rem, 0.95rem + 0.15vw, 1.0625rem);    /* 16 -> 17 */
  --fs-faq: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);    /* 17 -> 19 */
  --fs-price: clamp(2.25rem, 1.9rem + 1.2vw, 3rem);       /* 36 -> 48 */
  --fs-price-sm: 1.75rem;                                 /* quote rows, plan cards */
  --fs-ui: 0.9375rem;                                     /* 15: nav, small links */
  --fs-small: 0.875rem;                                   /* 14: captions, notices */
  --fs-eyebrow: 0.8125rem;                                /* 13: eyebrows, labels */
  --fs-tag: 0.75rem;                                      /* 12: review tags, mock labels only */

  /* Space (4/8 scale) and rhythm */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;
  --gutter: clamp(1rem, 0.5rem + 2vw, 2rem);               /* 16 at 390, 32 at 1440 */
  --section-pad: clamp(3.5rem, 2.5rem + 4vw, 6rem);        /* 56 -> 96 */
  --hero-pad-top: clamp(2rem, 1rem + 4vw, 5rem);
  --hero-pad-bottom: clamp(3rem, 2rem + 4vw, 6rem);
  --block-gap: clamp(2rem, 1.5rem + 1.5vw, 3rem);          /* heading block -> content */
  --split-gap: clamp(2rem, 1rem + 3vw, 4rem);
  --card-pad: clamp(1.25rem, 1rem + 1vw, 2rem);
  --container: 1200px;

  /* Shape */
  --radius: 10px;      /* cards, buttons, inputs, boxes */
  --radius-sm: 4px;    /* placeholders and tags */
  --radius-tile: 6px;  /* listing mock tiles only */

  /* Sticky header height, used for anchor scroll offset */
  --header-h: 120px;

  color-scheme: light;
}

@media (max-width: 23em) {
  :root { --header-h: 165px; }   /* below ~368px the nav wraps: three header rows */
}
@media (min-width: 56em) {
  :root { --header-h: 72px; }
}

/* 2. Base and reset -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  margin: 0;
  min-width: 0;
  background: var(--paper);
  color: var(--slate);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }

/* Lists with a class are layout lists (no bullets). Plain lists in .prose keep bullets. */
ul[class], ol[class],
.site-nav ul, .toc ol, .breadcrumb ol { list-style: none; margin: 0; padding: 0; }

img, picture, video { display: block; max-width: 100%; height: auto; }
svg { flex-shrink: 0; }

input, button, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

a { color: var(--action); text-underline-offset: 3px; }
a:hover { color: var(--slate); }

:focus-visible {
  outline: 3px solid var(--action);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--paper);
}

[hidden] { display: none !important; }

strong, b { font-weight: 700; }

/* 3. Typography ------------------------------------------------------------ */
h1, .h1 {
  font-size: var(--fs-h1);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.025em;
  max-width: 18ch;
  text-wrap: balance;
}
.h1--wide { max-width: 24ch; }

h2, .h2 {
  font-size: var(--fs-h2);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.02em;
  max-width: 24ch;
  text-wrap: balance;
}

h3, .h3 {
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h4, .h4 {
  font-size: var(--fs-h4);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

/* An H2 that sits in a card at H3 size (quote sheet, "At a glance") */
.h2--card { font-size: var(--fs-h3); line-height: 1.3; letter-spacing: -0.01em; max-width: none; }

p { text-wrap: pretty; }

.lead { font-size: var(--fs-lead); line-height: 1.55; max-width: 60ch; }

/* Eyebrow: plain <p>, never a heading. The teal slash is drawn by CSS and hidden from screen readers. */
.eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--action);
  text-wrap: balance;
}
.eyebrow::before {
  content: "/ ";
  content: "/ " / "";
  color: var(--teal);
}

.small { font-size: var(--fs-small); line-height: 1.5; }
.ui-text { font-size: var(--fs-ui); line-height: 1.5; }

/* Long-form text (privacy, terms) */
.prose { max-width: 68ch; }
.prose > * + * { margin-top: 1em; }
.prose h2 { font-size: var(--fs-h3); line-height: 1.3; letter-spacing: -0.01em; margin-top: 2em; max-width: none; }
.prose h3 { font-size: var(--fs-h4); margin-top: 1.5em; }
.prose ul, .prose ol { margin-bottom: 0; padding-left: 1.25em; }
.prose li + li { margin-top: 0.4em; }
.prose a { font-weight: 600; overflow-wrap: anywhere; }

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

/* Sections: paper by default. Never put two tints next to each other;
   the CTA band is always tint, so the section above it is paper. */
.section { padding-block: var(--section-pad); background: var(--paper); }
.section--tint { background: var(--tint); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.section--hero { padding-top: var(--hero-pad-top); padding-bottom: var(--hero-pad-bottom); }
.section--slate { background: var(--slate); color: var(--paper); } /* the signature band: once per page at most */
.section--flush-top { padding-top: 0; }

/* Vertical stack with gap. Default 16px. */
.stack { display: flex; flex-direction: column; gap: var(--s4); }
.stack--xs { gap: var(--s2); }
.stack--sm { gap: var(--s3); }
.stack--md { gap: 20px; }
.stack--lg { gap: var(--s5); }
.stack--xl { gap: var(--s6); }
.stack--section { gap: var(--block-gap); }               /* heading block -> content */
.stack--loose { gap: clamp(3rem, 2rem + 3vw, 4.5rem); }  /* between big sub-blocks */
.stack--start { align-items: flex-start; }

/* Horizontal wrapping row (button rows, link rows, tag rows) */
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) var(--s4); }
.cluster--tight { gap: var(--s1) var(--s4); }
.cluster--wide { gap: var(--s3) var(--s5); }
.cluster--tags { gap: 6px; }

/* Two-column row: side by side on desktop, stacked below ~1000px.
   Children default to flex: 1 1 460px; use .col-* to change the basis. */
.split { display: flex; flex-wrap: wrap; align-items: center; gap: var(--split-gap); }
.split > * { flex: 1 1 460px; min-width: 0; }
.split--top { align-items: flex-start; }
.split--wide-gap { gap: clamp(2.5rem, 1rem + 4vw, 5rem); }
.split--cta { align-items: flex-start; gap: var(--s6) clamp(2rem, 1rem + 4vw, 5rem); }
.col-300 { flex-basis: 300px !important; }
.col-320 { flex-basis: 320px !important; }
.col-360 { flex-basis: 360px !important; }
.col-420 { flex-basis: 420px !important; }
.col-480 { flex-basis: 480px !important; }
.col-520 { flex-basis: 520px !important; }
.col-560 { flex-basis: 560px !important; }
.col-grow-2 { flex-grow: 2 !important; }
.col-grow-3 { flex-grow: 3 !important; }
.col-fixed { flex-grow: 0 !important; }                  /* e.g. headshot column: 0 1 400px */

/* Auto-fit grid: 3 columns at 1440, 1 at 390. min(100%, …) stops overflow at 320px. */
.grid {
  --min: 280px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr));
  gap: var(--s5);
}
.grid--150 { --min: 150px; gap: var(--s4) 20px; }
.grid--220 { --min: 220px; }
.grid--240 { --min: 240px; }
.grid--260 { --min: 260px; }
.grid--300 { --min: 300px; }
.grid--320 { --min: 320px; }
.grid--400 { --min: 400px; }
.grid--wide-gap { gap: var(--s5) 40px; }

/* Any wide content (tables) goes in here: no horizontal page scroll. */
.scroll-x { overflow-x: auto; }

/* 5. Utilities and placeholders ------------------------------------------- */
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}
.measure { max-width: 68ch; }
.measure-lead { max-width: 60ch; }
.tabular { font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }
.break-anywhere { overflow-wrap: anywhere; }
.rule-top { padding-top: var(--block-gap); border-top: 1px solid var(--line); }

/* Spam trap for a native form (hidden from people and screen readers; bots fill it) */
.hp-field { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* PLACEHOLDERS. Every unconfirmed value carries class "ph" so Ashton can find
   them all (search the HTML for class="ph). They must look unfinished.
   .ph            inline FILL value inside a sentence: [business name]
   .ph--tag       small review tag after a line: [CONFIRM: …], Written OK pending
   .ph--box       image placeholder (role="img" + aria-label), square unless an aspect class is set
   .ph--note      a longer instruction for Ashton, e.g. "No OK yet? Use: …"      */
.ph {
  background: var(--tint);
  color: var(--slate);
  border: 1px dashed var(--action);
  border-radius: var(--radius-sm);
  padding: 0 4px;
}
.ph--tag {
  display: inline-block;
  font-size: var(--fs-tag);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: var(--action);
  background: var(--paper);
  padding: 1px 6px;
  vertical-align: middle;
}
.ph--note {
  display: block;
  font-size: var(--fs-tag);
  font-weight: 600;
  line-height: 1.45;
  color: var(--action);
  background: var(--paper);
  padding: 6px 10px;
  max-width: 60ch;
}
.ph--box {
  width: 100%;
  aspect-ratio: 1 / 1;   /* square by default: the "[Photo of Ashton]" boxes; .ph--shot / .ph--wide override */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s5);
  border-width: 2px;
  border-radius: var(--radius);
  text-align: center;
  font-size: var(--fs-ui);
  font-weight: 600;
  line-height: 1.4;
}
.ph--square { aspect-ratio: 1 / 1; }
.ph--shot { aspect-ratio: 1200 / 723; }   /* matches the laptop mockups */
.ph--wide { aspect-ratio: 1440 / 900; }
.ph--sm { padding: var(--s3); font-size: var(--fs-tag); }
.ph--on-paper { background: var(--paper); }

/* 6. Header, nav, skip link ----------------------------------------------- */
.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 100;
  padding: 12px 16px;
  background: var(--action);
  color: var(--paper);
  border-radius: var(--radius);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; color: var(--paper); }

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
/* Two rows on a phone (logo + nav, then phone + button); one row on desktop. */
.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px var(--s5);
  padding-block: 10px;
}
.site-header__brand {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s1) var(--s4);
  min-width: 0;
}
.site-logo { display: inline-flex; align-items: center; min-height: 44px; }
.site-logo img { height: 36px; width: auto; }

.site-nav ul { display: flex; flex-wrap: wrap; gap: 0 2px; }
.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 10px;
  color: var(--slate);
  font-size: var(--fs-ui);
  font-weight: 600;
  text-decoration: none;
}
.site-nav a:hover { color: var(--action); text-decoration: underline; text-decoration-color: var(--teal); text-decoration-thickness: 2px; text-underline-offset: 6px; }
/* Current page: aria-current="page" (or "true" for a child page, e.g. a case study under Work) */
.site-nav a[aria-current] {
  color: var(--action);
  text-decoration: underline;
  text-decoration-color: var(--teal);
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}

.site-header__actions {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s2) var(--s4);
}
.header-phone {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;
  padding: 0 4px;
  color: var(--slate);
  font-size: var(--fs-ui);
  font-weight: 700;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.header-phone:hover { color: var(--action); text-decoration: underline; }

/* Icons: inline SVG, stroke follows the text colour set here.
   <svg class="icon" width="20" height="20" viewBox="0 0 24 24" aria-hidden="true">…</svg> */
.icon {
  display: block;
  flex: none;
  color: var(--action);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon--inline { display: inline-block; vertical-align: -1px; margin-left: 4px; color: inherit; stroke-width: 2.25; }
.icon--muted { color: var(--slate); }
.icon--teal { color: var(--teal); }
/* Two-colour check: teal ring (decoration) + action tick */
.icon-check { display: block; flex: none; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.icon-check circle { stroke: var(--teal); stroke-width: 1.5; }
.icon-check path { stroke: var(--action); stroke-width: 2.25; }
.icon-check--lg circle { stroke-width: 1; }
.icon-check--lg path { stroke-width: 1.75; }

/* 7. Notices and capacity line -------------------------------------------- */
/* Full-width bar, the first thing inside <main> (Services, Work, case study, About, Check). */
.notice-bar { background: var(--tint); border-bottom: 1px solid var(--line); }
.notice-bar__inner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding-block: 10px;
  font-size: var(--fs-small);
  line-height: 1.5;
}
.notice-bar a { font-weight: 600; }

/* Inline notice (hero slot on Home and /contact-us, CTA band, above the form, Thanks). */
.notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 60ch;
  padding: 12px 16px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: var(--fs-small);
  line-height: 1.5;
}

/* "Sorry, your message didn't send" (/contact-us/#form-error). Hidden until contact.php
   sends the visitor back: :target shows it without JS, site.js adds .is-shown for ?error=1. */
.form-error { display: none; border-color: var(--danger); border-left-width: 4px; }
.form-error:target, .form-error.is-shown { display: flex; }
.form-error .icon { color: var(--danger); }

/* "Next available build start: [date] …" */
.capacity { display: flex; align-items: flex-start; gap: 10px; font-size: var(--fs-small); line-height: 1.5; }

/* 8. Buttons and links ----------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: 12px 24px;
  border: 2px solid transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.btn--primary { background: var(--action); color: var(--paper); border-color: var(--action); }
.btn--primary:hover { background: var(--slate); border-color: var(--slate); color: var(--paper); }
.btn--secondary { background: var(--paper); color: var(--slate); border-color: var(--slate); }
.btn--secondary:hover { background: var(--tint); color: var(--slate); }
/* Primary on the slate band */
.btn--on-dark { background: var(--paper); color: var(--slate); border-color: var(--paper); }
.btn--on-dark:hover { background: var(--tint); border-color: var(--tint); color: var(--slate); }
/* While the form is sending (site.js): a second click does nothing */
.btn[aria-disabled="true"] { opacity: 0.75; cursor: progress; }
/* Header size */
.btn--sm { min-height: 44px; padding: 10px 18px; font-size: var(--fs-ui); white-space: nowrap; }

/* Text links */
.link { color: var(--action); font-weight: 600; text-underline-offset: 3px; }
.link--block { display: inline-flex; align-items: center; min-height: 44px; }  /* standalone links: 44px target */
.link--strong { font-weight: 700; }

/* Title link inside cards: slate text, teal underline */
.title-link {
  color: var(--slate);
  text-decoration: underline;
  text-decoration-color: var(--teal);
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
  padding-block: 13px;                 /* lifts the target towards 44px without moving layout much */
}
.title-link:hover { color: var(--action); }

/* Row of text links under every main button: Call or text · Send a message · See recent work */
.link-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s1) var(--s4);
  font-size: var(--fs-ui);
  line-height: 1.5;
}
.link-row a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* On dark backgrounds (slate band, footer) links are white and underlined. */
.on-dark a:not(.btn), .section--slate a:not(.btn) { color: var(--paper); }
.on-dark a:not(.btn):hover, .section--slate a:not(.btn):hover { color: var(--paper); text-decoration-thickness: 2px; }
.on-dark :focus-visible, .section--slate :focus-visible { outline-color: var(--paper); box-shadow: 0 0 0 2px var(--slate); }

/* 9. Heading block and hero ----------------------------------------------- */
.heading-block { display: flex; flex-direction: column; gap: var(--s3); max-width: 760px; }
.section--slate .eyebrow, .section--slate h2, .section--slate h3 { color: var(--paper); }
/* On slate only, one H2 phrase may be logo teal (4.47:1 passes at H2 size). */
.section--slate .hl { color: var(--teal); }

.hero__text { flex: 1 1 480px; min-width: 0; display: flex; flex-direction: column; gap: var(--s5); }
.hero__intro { display: flex; flex-direction: column; gap: 14px; }
.hero__actions { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s3); }
.hero__proof {
  max-width: 60ch;
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: var(--fs-ui);
  line-height: 1.7;
}
.hero__stage { flex: 1 1 420px; min-width: 0; display: flex; justify-content: center; }

/* Typing headline (copy deck 2.2). Markup in _partials/components.html.
   The ending sits in a one-cell grid with all six endings as invisible sizers,
   so the H1 reserves the height of the tallest ending at every width: no jump. */
.typed { max-width: 24ch; }
.typed__fixed { display: block; }
.typed__line { display: grid; color: var(--action); }
.typed__line > * { grid-area: 1 / 1; }
.typed__sizer { visibility: hidden; }
.typed__sizer::before { content: attr(data-typed-ending); }
.typed__sizer::after { content: ""; display: inline-block; width: 0.13em; }   /* room for the caret */
.typed__text {
  text-decoration-line: underline;
  text-decoration-style: dashed;
  text-decoration-color: var(--teal);
  text-decoration-thickness: 0.07em;
  text-underline-offset: 0.16em;
  text-decoration-skip-ink: none;
}
.typed__caret {
  display: inline-block;
  width: 0.07em;
  height: 0.95em;
  margin-left: 0.06em;
  vertical-align: -0.1em;
  background: var(--teal);
}
/* No JS = no typing, so no caret (site.js sets data-typed-ready when it starts). */
.typed:not([data-typed-ready]) .typed__caret { display: none; }
.typed-toggle {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 12px;
  background: var(--paper);
  color: var(--action);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
}
.typed-toggle:hover { border-color: var(--action); }
.typed-toggle .icon { width: 16px; height: 16px; }
.typed-toggle[data-state="paused"] .icon-pause,
.typed-toggle:not([data-state="paused"]) .icon-play { display: none; }

/* The slate "stage" in the Home hero: listing card, Website circled, dashed path
   forks to a dead end and to a real client site. */
.stage {
  width: 100%;
  max-width: 520px;
  padding: clamp(1rem, 0.5rem + 2vw, 2rem);
  background: var(--slate);
  border-radius: var(--radius);
  color: var(--paper);
}
.stage__mock { display: flex; flex-direction: column; color: var(--slate); }
/* stem: same 4-column grid as the action row, so it drops from the Website button */
.stage__stem { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; padding: 0 17px; }
.stage__stem span { grid-column: 3; justify-self: center; width: 0; height: 20px; border-left: 2.5px dashed var(--teal); }
/* fork: its two legs land on the centres of the 2fr / 3fr outcome columns */
.stage__fork {
  height: 20px;
  margin: 0 calc(30% - 4.85px) 0 calc(20% - 3.65px);
  border: 2.5px dashed var(--teal);
  border-bottom: 0;
  border-radius: 10px 10px 0 0;
}
.stage__outcomes {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  column-gap: var(--s3);
  row-gap: 6px;
}
.stage__arrow { display: block; justify-self: center; fill: none; stroke: var(--teal); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.stage__site {
  display: flex;
  align-items: center;
  min-width: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.stage__label {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: 1.3;
  color: var(--paper);
}
.stage__label .icon { color: var(--teal); stroke-width: 3; }
.stage__legend { display: flex; flex-direction: column; gap: var(--s1); align-self: start; padding-top: 6px; min-width: 0; }
.stage__caption { font-size: var(--fs-small); line-height: 1.5; color: var(--paper); }

/* 10. Google listing mock-up (.gbp) --------------------------------------- */
/* A flat illustration, not a control: wrap the mock in role="img" with a full
   aria-label; the visible figcaption carries the deck copy. */
.gbp-figure { display: flex; flex-direction: column; gap: var(--s4); width: 100%; max-width: 340px; }
.gbp-figure figcaption { font-size: var(--fs-small); line-height: 1.5; }
.section--slate .gbp-figure figcaption { color: var(--paper); }
.gbp-mock { display: flex; flex-direction: column; color: var(--slate); }

.gbp {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);          /* the only shadow on the site */
  color: var(--slate);
}
.gbp__photos { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 4px; }
.gbp__photos span { display: block; height: 72px; background: var(--tint); border: 1px solid var(--line); border-radius: var(--radius-tile); }
.gbp--lg .gbp__photos span { height: 84px; }
.gbp__info { display: flex; flex-direction: column; gap: var(--s1); }
.gbp__name { font-size: 1.25rem; font-weight: 800; line-height: 1.2; letter-spacing: -0.01em; }
.gbp__meta { display: flex; align-items: center; gap: 6px; font-size: var(--fs-eyebrow); line-height: 1.4; }
.gbp__stars { display: block; fill: var(--teal); }
.gbp__actions {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.gbp__action {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: clamp(0.625rem, 0.45rem + 0.9vw, 0.75rem);   /* "Directions" fits a 320px phone */
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
}
.gbp__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 999px;
}
.gbp__action--website { position: relative; justify-self: center; padding: 0 10px; font-weight: 700; }
.gbp__action--website .gbp__icon { border-color: var(--action); }
/* hand-drawn ring around "Website" */
.gbp__ring {
  position: absolute;
  left: -8px;
  top: -10px;
  width: calc(100% + 16px);
  height: calc(100% + 22px);
  overflow: visible;
  pointer-events: none;
  fill: none;
  stroke: var(--teal);
  stroke-width: 3;
  stroke-linecap: round;
}
.gbp__ring path { vector-effect: non-scaling-stroke; }
/* single dashed path from the Website button down to the panel (dead-end and fixed states) */
.gbp__path { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; padding: 0 17px; }
.gbp__path svg { grid-column: 3; justify-self: center; display: block; fill: none; stroke: var(--teal); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }

/* Browser panel: where the Website link leads */
.browser {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  color: var(--slate);
}
.browser__bar { display: flex; align-items: center; padding: 10px 12px; background: var(--tint); border-bottom: 1px solid var(--line); }
.browser__url {
  flex: 1 1 auto;
  min-width: 0;
  padding: 6px 12px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: var(--fs-tag);
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.browser__body { display: flex; flex-direction: column; gap: 10px; padding: 20px 16px 24px; }
.browser__body--404 { flex: 1 1 auto; align-items: center; justify-content: center; gap: var(--s2); padding: 28px 16px 32px; text-align: center; }
.browser__body--404 .icon { color: var(--slate); stroke-width: 1.75; }
.browser__title { font-size: 1.125rem; font-weight: 800; line-height: 1.2; }
.browser__meta { font-size: var(--fs-eyebrow); line-height: 1.4; }
.browser__skeleton { display: block; width: 80%; height: 8px; background: var(--line); border-radius: 4px; }
.browser__skeleton--short { width: 60%; }
.mock-btn { display: flex; align-items: center; justify-content: center; min-height: 40px; border-radius: var(--radius); font-size: var(--fs-small); font-weight: 700; }
.mock-btn--primary { background: var(--action); color: var(--paper); }
.mock-btn--outline { border: 2px solid var(--slate); }
/* compact panel used in the hero stage */
.browser--sm .browser__bar { padding: 8px; }
.browser--sm .browser__url { padding: 4px 10px; }
.browser--sm .browser__body--404 { gap: 6px; padding: 14px 10px 16px; }
.browser--sm .browser__title { font-size: var(--fs-ui); }
.browser--sm .browser__meta { font-size: var(--fs-tag); }

/* Slate band layout (houses the listing card) */
.band__text { flex: 1 1 420px; min-width: 0; display: flex; flex-direction: column; gap: 20px; }
.band__figure { flex: 0 1 340px; min-width: 0; display: flex; justify-content: center; }

/* 11. Cards ---------------------------------------------------------------- */
.card {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  min-width: 0;
  padding: var(--card-pad);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

/* Work / proof card: flat, hairline under the image, no shadow. */
.work-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.work-card__img { width: 100%; border-bottom: 1px solid var(--line); }
.work-card__media { display: flex; flex-direction: column; aspect-ratio: 1200 / 723; padding: var(--s3); border-bottom: 1px solid var(--line); }
.work-card__media .ph--box { flex: 1 1 auto; }
.work-card__body { flex: 1 1 auto; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s2); padding: 20px 20px 24px; }
.work-card__meta { font-size: var(--fs-ui); line-height: 1.5; }
.work-card--note { justify-content: center; align-items: flex-start; gap: var(--s4); padding: var(--card-pad); }

/* Featured work row (Budget Built on /portfolio/) */
.work-feature__media { display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--s4); }
.work-feature__media > * { min-width: 0; }

/* Photo with an overlaid credit (Budget Built job photo: "Photo: Budget Built") */
.figure-credit { position: relative; display: flex; margin: 0; }
.figure-credit img { flex: 1 1 auto; width: 100%; min-height: 200px; object-fit: cover; border: 1px solid var(--line); border-radius: var(--radius); }
.figure-credit figcaption {
  position: absolute;
  left: 10px; right: 10px; bottom: 10px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  font-size: var(--fs-small);
  line-height: 1.4;
}
.figure-credit__label { background: var(--paper); color: var(--slate); padding: 2px 8px; border-radius: var(--radius-sm); font-weight: 600; }

/* Framed screenshot with caption (mini proof, before/after) */
.frame { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.frame--img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.figure { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.figure figcaption { font-size: var(--fs-small); line-height: 1.5; }
.figure--sm { gap: 10px; }
.figure--sm figcaption { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s1); line-height: 1.4; }

/* Before / after labels */
.ba-label { display: inline-flex; align-items: center; padding: 3px 8px; background: var(--paper); color: var(--slate); border: 1px solid var(--slate); border-radius: var(--radius-sm); font-size: var(--fs-eyebrow); font-weight: 700; line-height: 1.3; }
.ba-label--after { background: var(--action); color: var(--paper); border-color: var(--action); }

/* Client list rows (About): thumbnail + name + tag line */
.client-list { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.client-list li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) 20px; padding: var(--s4) 0; border-bottom: 1px solid var(--line); }
.client-list__thumb { flex: 0 0 168px; width: 168px; }
.client-list__text { flex: 1 1 160px; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s1); }

/* Service columns: ruled, not boxed. Solid slate rule = what I do. */
.service-cols { gap: 40px var(--s6); }
.service-col { display: flex; flex-direction: column; gap: var(--s3); min-width: 0; padding-top: var(--s5); border-top: 2px solid var(--slate); }
.service-col .icon { width: 28px; height: 28px; }
.service-col__note { font-size: 0.75em; font-weight: 600; letter-spacing: 0; }   /* "(included)" after an H3 */
.service-col__price { padding-top: var(--s3); border-top: 1px solid var(--line); font-size: var(--fs-ui); font-weight: 700; line-height: 1.5; font-variant-numeric: tabular-nums; }

/* Steps: dashed teal rule = the path. Same four steps on Home, /contact-us, /portfolio. */
.steps { gap: var(--s6) var(--s5); }
.step { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; min-width: 0; padding-top: 20px; border-top: 2px dashed var(--teal); }
.step__num { font-size: 2rem; font-weight: 800; line-height: 1; color: var(--action); font-variant-numeric: tabular-nums; }

/* "Three dead ends I fix" cards with their small drawings */
.deadend { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; padding: var(--card-pad); background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); }
.deadend__art { display: flex; align-items: center; justify-content: center; padding: 20px; background: var(--tint); border: 1px solid var(--line); border-radius: var(--radius); }
.deadend__art svg { display: block; max-width: 100%; height: auto; }
/* Drawing palette (classes on SVG shapes, so the tokens stay the only colour source) */
.art { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.art-ink { stroke: var(--slate); }
.art-action { stroke: var(--action); }
.art-teal { stroke: var(--teal); }
.art-line { stroke: var(--line); }
.art-fill-paper { fill: var(--paper); }
.art-fill-tint { fill: var(--tint); }

/* Price card: no button inside; the section puts buttons + capacity under the cards. */
.price-card { gap: var(--s4); }
.price-card__figure { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) 10px; padding-bottom: var(--s4); border-bottom: 1px solid var(--line); }
.price { font-size: var(--fs-price); font-weight: 800; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.price--sm { font-size: var(--fs-price-sm); }
.price-note { font-size: var(--fs-ui); font-weight: 600; line-height: 1.4; }
.check-line { display: flex; align-items: flex-start; gap: 10px; font-weight: 600; }

/* Quote sheet: hairline rows, dotted leader, tabular figures. */
.quote { gap: var(--s4); }
.quote__rows { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.quote-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) 10px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.quote-row--compact { padding: var(--s3) 0; }
.quote-row__item { font-weight: 700; }
.leader { flex: 1 1 24px; min-width: 24px; border-bottom: 2px dotted var(--line); }
.quote-row__price { font-size: var(--fs-price-sm); font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.quote-row__unit { font-size: var(--fs-ui); font-weight: 600; }
.quote-row__note { flex: 1 0 100%; font-size: var(--fs-small); line-height: 1.5; }

/* 12. Lists ---------------------------------------------------------------- */
/* Promise list: check icon + bold lead-in */
.promises { gap: var(--s5) 40px; }
.promise { display: flex; align-items: flex-start; gap: var(--s3); }
.promise .icon-check { margin-top: 2px; }

/* Ruled check list ("What's included") */
.checklist { gap: 0 40px; border-bottom: 1px solid var(--line); }
.checklist li { display: flex; align-items: flex-start; gap: var(--s3); padding: var(--s4) 0; border-top: 1px solid var(--line); }
.checklist .icon-check { margin-top: 2px; }
/* Plain check list (no rules) */
.checks { gap: 14px var(--s6); }
.checks li { display: flex; align-items: flex-start; gap: var(--s3); }

/* Spec sheet: label column + content, hairline rows */
.spec { display: flex; flex-direction: column; padding: 0 var(--card-pad); background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); }
.spec__row { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s6); padding: var(--s5) 0; border-bottom: 1px solid var(--line); }
.spec__row:last-child { border-bottom: 0; }
.spec__label { flex: 0 0 190px; font-size: var(--fs-faq); font-weight: 700; line-height: 1.4; }
.spec__body { flex: 1 1 480px; min-width: 0; max-width: 68ch; }

/* Callout box ("Not included") */
.callout { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s3) 40px; padding: var(--card-pad); background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); }
.callout__title { flex: 0 0 200px; display: flex; align-items: center; gap: 10px; }
.callout__body { flex: 1 1 420px; min-width: 0; max-width: 72ch; }

/* Facts list ("At a glance") as a <dl> with dotted leaders */
.facts { display: flex; flex-direction: column; border-top: 1px solid var(--line); font-size: var(--fs-ui); line-height: 1.5; }
.facts__row { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) 10px; padding: var(--s3) 0; border-bottom: 1px solid var(--line); }
.facts dt { flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 10px; font-weight: 700; }
.facts dd { margin: 0 0 0 auto; min-width: 0; text-align: right; }

/* On-this-page index, set like a written quote (Services hero) */
.toc { gap: var(--s3); max-width: 500px; }
.toc ol { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.toc li { border-bottom: 1px solid var(--line); }
.toc li > a { display: flex; align-items: baseline; gap: 10px; min-height: 44px; padding: 14px 0; color: var(--slate); text-decoration: none; }
.toc__num { flex: 0 0 20px; font-size: var(--fs-ui); font-weight: 800; color: var(--action); font-variant-numeric: tabular-nums; }
.toc__text { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.toc__label { font-weight: 700; text-decoration: underline; text-decoration-color: var(--teal); text-decoration-thickness: 2px; text-underline-offset: 5px; }
.toc li > a:hover .toc__label { color: var(--action); }
.toc__price { font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.toc__note { flex: 1 0 100%; font-size: var(--fs-small); line-height: 1.5; }

/* Contact rows ("Other ways to talk"): label column + selectable links */
.contact-list { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.contact-list li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) 20px; padding: var(--s4) 0; border-bottom: 1px solid var(--line); }
.contact-list__label { flex: 0 0 120px; display: flex; align-items: center; gap: 10px; font-size: var(--fs-ui); font-weight: 700; line-height: 1.4; }
.contact-list__links { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) 20px; min-width: 0; }
.contact-list__big { display: inline-flex; align-items: center; min-height: 44px; font-size: 1.375rem; font-weight: 800; line-height: 1.2; letter-spacing: -0.01em; text-underline-offset: 4px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.contact-list__email { display: inline-flex; align-items: center; min-height: 44px; min-width: 0; font-size: 1.0625rem; font-weight: 700; text-underline-offset: 4px; overflow-wrap: anywhere; }

/* Breadcrumb (case studies) */
.breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) 10px; font-size: var(--fs-small); line-height: 1.5; }
.breadcrumb a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-weight: 600; }
.breadcrumb a .icon { color: currentColor; stroke-width: 2.25; }
.breadcrumb__sep { color: var(--teal); font-weight: 700; }
.breadcrumb [aria-current] { font-weight: 600; }

/* Service-area strip (About): suburbs separated by teal slashes */
.area-strip__inner { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 28px; padding-block: 20px; }
.slash-list { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 0; font-size: var(--fs-ui); font-weight: 600; line-height: 1.6; min-width: 0; }
.slash-list li + li::before { content: "/"; content: "/" / ""; color: var(--teal); font-weight: 400; padding: 0 10px; }

/* 13. FAQ ------------------------------------------------------------------ */
/* Plain HTML <details>; no FAQPage markup. */
.faq { border-top: 1px solid var(--line); max-width: 820px; }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  min-height: 44px;
  padding: 18px 0;
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-faq);
  font-weight: 700;
  line-height: 1.4;
  color: var(--slate);
}
.faq__item > summary::-webkit-details-marker { display: none; }
.faq__item > summary::marker { content: ""; }
.faq__item > summary:hover { color: var(--action); }
.faq__chev { width: 22px; height: 22px; stroke-width: 2.25; transition: transform 0.2s ease; }
.faq__item[open] > summary .faq__chev { transform: rotate(180deg); }
.faq__answer { display: flex; flex-direction: column; gap: var(--s3); padding: 0 0 20px; max-width: 68ch; }
.faq-split__intro { flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: var(--s4); }
.faq-split__list { flex: 2 1 560px; min-width: 0; }

/* 14. Forms ---------------------------------------------------------------- */
.form { display: flex; flex-direction: column; gap: 20px; max-width: 640px; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field__label, .fieldset legend { font-size: var(--fs-ui); font-weight: 700; line-height: 1.4; }
.field__opt { font-weight: 400; }                     /* "(required)", "(optional)" */
.field__help { font-size: var(--fs-small); line-height: 1.5; }
.input {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  font-size: 1rem;
  color: var(--slate);
  background: var(--paper);
  border: 1px solid var(--slate);                    /* 1px slate passes the 3:1 non-text rule */
  border-radius: var(--radius);
}
textarea.input { min-height: 132px; resize: vertical; }
select.input { appearance: auto; }
.input::placeholder { color: #5E6673; opacity: 1; }   /* 5.8:1 on paper */
.input[aria-invalid="true"] { border-color: var(--danger); box-shadow: inset 0 0 0 1px var(--danger); }

.fieldset { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: var(--s2); min-width: 0; }
.fieldset legend { padding: 0; margin-bottom: 6px; }
.choice {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--slate);
  border-radius: var(--radius);
  line-height: 1.4;
  cursor: pointer;
}
.choice input { flex: 0 0 20px; width: 20px; height: 20px; margin: 0; accent-color: var(--action); }
.choice:has(input:checked) { border-color: var(--action); background: var(--tint); box-shadow: inset 0 0 0 1px var(--action); }
.fieldset[aria-invalid="true"] .choice, .choice:has(input[aria-invalid="true"]) { border-color: var(--danger); }

/* Error message inserted by site.js next to the field */
.field__error { display: flex; align-items: flex-start; gap: 6px; font-size: var(--fs-small); font-weight: 600; line-height: 1.5; color: var(--danger); }
.field__error .icon { width: 18px; height: 18px; margin-top: 1px; color: var(--danger); }

.form__submit { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; padding-top: var(--s1); }
.form__status:empty { display: none; }

/* 15. CTA band, booking panel, misc --------------------------------------- */
/* CTA band: ends every page except /contact-us/ and /check/. Always tint. */
.cta-band { background: var(--tint); border-top: 1px solid var(--line); padding-block: var(--section-pad); }
.cta-band__text { flex: 1 1 420px; min-width: 0; display: flex; flex-direction: column; gap: var(--s4); }
.cta-band__actions { flex: 1 1 320px; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s4); }

/* Headshot */
.headshot { width: 100%; max-width: 400px; border-radius: var(--radius); }

/* Booking panel (a drawing of the Cal.com page, linked not embedded) */
.booking { padding: 0; gap: 0; overflow: hidden; }
.booking__head { display: flex; flex-direction: column; gap: 14px; padding: clamp(1.25rem, 1rem + 1vw, 1.75rem); border-bottom: 1px solid var(--line); }
.booking__who { display: flex; align-items: center; gap: var(--s3); font-size: var(--fs-small); font-weight: 600; line-height: 1.4; }
.avatar { flex: 0 0 40px; display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; background: var(--tint); border: 1px solid var(--line); border-radius: 999px; font-size: var(--fs-small); font-weight: 800; }
.booking__facts { display: flex; flex-wrap: wrap; gap: var(--s2) 20px; font-size: var(--fs-small); font-weight: 600; line-height: 1.4; }
.booking__facts li { display: flex; align-items: center; gap: var(--s2); }
.booking__action { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s3); padding: clamp(1.25rem, 1rem + 1vw, 1.75rem); background: var(--tint); border-top: 1px solid var(--line); }
.cal { display: flex; flex-direction: column; gap: var(--s4); padding: clamp(1rem, 0.75rem + 1vw, 1.75rem); }
.cal__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); font-weight: 800; }
.cal__nav { display: flex; gap: 6px; }
.cal__nav span { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 1px solid var(--line); border-radius: var(--radius-tile); }
.cal__dow, .cal__days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; text-align: center; }
.cal__dow { font-size: var(--fs-tag); font-weight: 600; line-height: 1.4; }
.cal__days { font-size: var(--fs-small); line-height: 1; font-variant-numeric: tabular-nums; }
.cal__days span { display: flex; align-items: center; justify-content: center; height: 42px; border-radius: var(--radius-tile); }
.cal__days .is-open { color: var(--action); border: 2px solid var(--action); font-weight: 800; }
.cal__days .is-selected { background: var(--action); color: var(--paper); border: 2px solid var(--action); font-weight: 800; }
.cal__days .is-blocked { background: var(--tint); text-decoration: line-through; }
.cal__legend { display: flex; flex-wrap: wrap; gap: var(--s2) 20px; font-size: var(--fs-tag); font-weight: 600; line-height: 1.4; }
.cal__legend span { display: flex; align-items: center; gap: var(--s2); }
.cal__swatch { display: block; width: 14px; height: 14px; border: 2px solid var(--action); border-radius: var(--radius-sm); }
.cal__swatch--blocked { background: var(--tint); border: 1px solid var(--line); }
.cal__day-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s1) var(--s3); padding-top: var(--s4); border-top: 1px solid var(--line); }
.cal__slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: var(--s2); }
.cal__slots span { display: flex; align-items: center; justify-content: center; min-height: 38px; border: 1px solid var(--action); border-radius: var(--radius-tile); color: var(--action); font-size: var(--fs-small); font-weight: 700; font-variant-numeric: tabular-nums; }

/* Big confirmation tick (Thanks page) */
.icon-check--xl { width: 56px; height: 56px; }

/* 16. Footer --------------------------------------------------------------- */
.site-footer { background: var(--slate); color: var(--paper); }
.site-footer__inner {
  display: flex;
  flex-direction: column;
  gap: 40px;
  padding-top: clamp(3rem, 2.5rem + 2vw, 4.5rem);
  padding-bottom: var(--s6);
}
.site-footer__cols { gap: var(--s6) 40px; }
.site-footer__col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.site-footer__brand { gap: var(--s4); }
.site-footer__brand .site-logo { align-self: flex-start; }
.site-footer__brand img { height: 44px; width: auto; }
.site-footer__about { font-size: var(--fs-ui); line-height: 1.6; max-width: 34ch; }
.site-footer__title { font-size: 1rem; font-weight: 700; line-height: 1.3; color: var(--paper); max-width: none; letter-spacing: 0; }
.site-footer__list { display: flex; flex-direction: column; font-size: var(--fs-ui); line-height: 1.5; }
.site-footer__list a { display: inline-flex; align-items: center; min-height: 44px; overflow-wrap: anywhere; }
.site-footer__list .site-footer__plain { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) 6px; min-height: 44px; }
.site-footer__legal {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding-top: var(--s5);
  border-top: 1px solid var(--line-on-dark);
  font-size: var(--fs-small);
  line-height: 1.6;
}

/* 17. Motion, print -------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .typed__caret { display: none; }   /* endings swap whole, no typing */
}

@media print {
  .site-header { position: static; }
  .skip-link, .typed-toggle, .typed__caret { display: none !important; }
  .section--slate, .stage, .site-footer { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* About (/about-us/) -------------------------------------------------------- */
/* Headshot figure in a hero column (placeholder now, <img class="headshot"> later) */
.figure--headshot { width: 100%; max-width: 400px; gap: var(--s3); }
/* Plainer second line inside an image placeholder (shooting notes, alt text) */
.ph__hint { font-size: var(--fs-small); font-weight: 400; line-height: 1.5; max-width: 30ch; }
/* Gated promise (shell 5.9): dashed ring, no tick, shown only with its GATE tag */
.icon-check--gate circle { stroke-dasharray: 3 3.5; }
/* Facts list with a fixed label column and left-aligned values ("Who you'll work with") */
.facts--cols .facts__row { gap: 2px var(--s4); }
.facts--cols dt { flex: 0 0 112px; font-size: var(--fs-small); line-height: 1.6; }
.facts--cols dd { flex: 1 1 150px; margin: 0; text-align: left; line-height: 1.6; }
/* Side card beside a long column: capped width; sticks under the header on wide, tall screens */
.side-card { max-width: 420px; align-self: flex-start; }
@media (min-width: 62em) and (min-height: 44em) {   /* card is about 540px tall: never stick it on a short screen */
  .side-card { position: sticky; top: calc(var(--header-h) + var(--s5)); }
}
/* Inline link in a row: lifts the tap target towards 44px without moving the layout */
.link--pad { padding-block: 13px; }
/* Row under a list: small print on one side, a link on the other */
.cluster--between { justify-content: space-between; }
.rule-top--sm { padding-top: var(--s5); }

/* Check (/check/) ----------------------------------------------------------- */
/* Lead beside the listing card on the slate band (52ch) */
.lead--narrow { max-width: 52ch; }
/* Shorter section padding for a short block (Check "Who I am", closing ways-forward row) */
.section--compact { padding-block: clamp(3rem, 2rem + 3vw, 4.5rem); }
/* Numbered, ruled list ("What the check looked at") */
.num-list { border-top: 1px solid var(--line); }
.num-list li { display: flex; align-items: baseline; gap: 20px; padding: 20px 0; border-bottom: 1px solid var(--line); }
.num-list__num { flex: 0 0 1.75rem; font-size: 1.75rem; font-weight: 800; line-height: 1; color: var(--action); font-variant-numeric: tabular-nums; }
.num-list__text { min-width: 0; font-size: var(--fs-lead); line-height: 1.5; }
/* Two cards side by side at unequal weight, equal height (quote sheet + launch rate) */
.card-row { display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--s5); }
.card-row > * { flex: 1 1 340px; }
.card-row > .card-row__wide { flex: 1.4 1 420px; }
/* Quote rows with no heading above: no top rule, first row flush; larger price figures */
.quote__rows--flush { border-top: 0; }
.quote__rows--flush .quote-row:first-child { padding-top: 0; }
.quote-row__price--lg { font-size: clamp(1.75rem, 1.4rem + 1vw, 2.5rem); letter-spacing: -0.02em; }
/* Two equal-weight primary buttons side by side, stacked on phones (C19) */
.btn-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: var(--s3) var(--s4); max-width: 760px; }
/* Icons inside a primary button follow the white button text */
.btn--primary .icon { color: currentColor; }
/* Grid with a 40px row gap and the split column gap */
.grid--split-gap { gap: 40px var(--split-gap); }
/* Small square headshot (or its placeholder) beside a short text block */
.headshot--sm { flex: 0 0 auto; width: 200px; max-width: 100%; }

/* ==========================================================================
   Case study: /portfolio/white-risk-solutions/ (canvas CaseStudy)
   ========================================================================== */
/* Hero: gap between the breadcrumb and the two-column row */
.stack--crumb { gap: clamp(1.5rem, 1rem + 1.5vw, 2.5rem); }
/* Two-column row that needs more room between its blocks once they stack */
.split--rows-loose { row-gap: clamp(3rem, 1.5rem + 4vw, 6rem); }
/* Before/after pair: wider gaps, so the stacked figures read as two separate shots */
.grid--ba { gap: 40px clamp(24px, 1rem + 2vw, 48px); align-items: start; }
.ba-label { letter-spacing: 0.08em; text-transform: uppercase; }
/* Icons inside buttons follow the label colour, e.g. "Visit the live site" with its arrow */
.btn .icon { color: inherit; margin-left: 0; }
/* Domain pill above the live-site button */
.url-pill {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 0;
  padding: 10px 14px;
  background: var(--tint);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: var(--fs-ui);
  font-weight: 600;
  line-height: 1.4;
}
.url-pill > span { min-width: 0; overflow-wrap: anywhere; }
/* Client quote ("In their words"): slate rule, teal quote mark (decoration only) */
.testimonial { display: flex; flex-direction: column; gap: 20px; max-width: 880px; padding-top: 28px; border-top: 2px solid var(--slate); }
.testimonial__mark { display: block; fill: var(--teal); }
.testimonial blockquote p { font-size: clamp(1.25rem, 1rem + 1vw, 1.875rem); font-weight: 700; line-height: 1.4; letter-spacing: -0.01em; }
.testimonial blockquote .ph { padding: 0 6px; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.testimonial figcaption { font-size: 1rem; line-height: 1.5; }

/* Work (/portfolio/) -------------------------------------------------------- */
/* Tighter joins between the hero and the first section (canvas Work: proof in the first two screens) */
.section--tight-bottom { padding-bottom: clamp(2.5rem, 1.5rem + 3vw, 4rem); }
.section--tight-top { padding-top: clamp(2.5rem, 1.5rem + 3vw, 4rem); }
/* Featured work card (Budget Built): screenshot + job photo side by side, then name, tag line and link */
.work-feature { gap: clamp(1.25rem, 1rem + 1vw, 1.75rem); }
.work-feature__shot { flex: 1.4 1 420px; }
.work-feature__photo { flex: 1 1 280px; }
.work-feature__foot { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s3) var(--s6); }
.work-feature__foot > .work-card__info { flex: 1 1 420px; min-width: 0; }
/* Work card with its link row pinned to the bottom, so the links line up across a row */
.work-card__body--foot { align-items: stretch; justify-content: space-between; gap: var(--s4); padding-bottom: var(--s3); }
.work-card__info { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s2); }
.work-card__foot { padding-top: var(--s1); border-top: 1px solid var(--line); }
/* Text link with a leading icon (globe = live site, page = case study); the icon follows the link colour */
.link--icon { gap: var(--s2); }
.link--icon > .icon { color: inherit; }

/* Contact (/contact-us/) ---------------------------------------------------- */
/* Top of page: hero + "Who you'll work with" on the left, the quote sheet (#prices) on the
   right. Side by side from about 1160px; below that the quote sheet follows the left column. */
.offer-top { gap: clamp(2.5rem, 1rem + 3vw, 4rem); }
.offer-top__main { flex: 1 1 672px; display: flex; flex-direction: column; gap: var(--block-gap); }
.offer-top__aside { flex: 1 1 376px; }
@media (min-width: 62em) and (min-height: 56em) {   /* the card is about 815px tall: only pin it when it fits under the header */
  .offer-top__aside { position: sticky; top: calc(var(--header-h) + var(--s5)); }
}
/* Two-part H1: the second phrase on its own line in the action colour */
.h1-accent { display: block; color: var(--action); }
/* Compact "Who you'll work with": hairline above, photo + text, then two mini work frames */
.meet { display: flex; flex-direction: column; gap: 20px; padding-top: clamp(1.5rem, 1rem + 1vw, 2rem); border-top: 1px solid var(--line); }
.meet__row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s4) var(--s5); }
.meet__photo { flex: 0 0 168px; max-width: 100%; display: flex; flex-direction: column; gap: var(--s2); }
.meet__photo figcaption { font-size: var(--fs-small); font-weight: 700; line-height: 1.4; }
.meet__text { flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s3); }
/* DIY check: three numbered steps, numbers in action-outlined circles */
.diy-steps { display: flex; flex-direction: column; gap: var(--s4); max-width: 60ch; }
.diy-steps li { display: flex; align-items: flex-start; gap: 14px; }
.diy-steps__num { flex: 0 0 32px; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; background: var(--paper); border: 2px solid var(--action); border-radius: 999px; color: var(--action); font-size: var(--fs-ui); font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.diy-steps__text { min-width: 0; padding-top: 3px; }
/* Icon + short bold line that wraps with its review tag ("I reply by the next business day.") */
.icon-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-weight: 700; }

/* ===== Page additions: Services (/services/) ================================
   Kept small and reusable; any page may use these. */
/* Price note forced onto its own line under the figure (Services price cards) */
.price-note--below { flex: 1 0 100%; }
/* Two-colour check on the slate band: white tick, teal ring */
.section--slate .icon-check path { stroke: var(--paper); }
/* Split modifiers: centre columns once they wrap; baseline row with a tight row gap */
.split--center { justify-content: center; }
.split--baseline { align-items: baseline; row-gap: var(--s3); }
/* Notes row under the slate band content (use with .grid .grid--260) */
.band__notes { gap: 28px 40px; padding-top: var(--s6); border-top: 1px solid var(--line-on-dark); }
/* Spec sheet on tint (plan terms and ownership) */
.spec--tint { background: var(--tint); }
/* Slim strip padding (logo add-on strip; shorter than .section--compact) */
.section--strip { padding-block: clamp(2.5rem, 2rem + 2vw, 3.5rem); }
/* Icon + text line at normal weight, text wraps beside the icon (uptime service line) */
.icon-text { display: flex; align-items: flex-start; gap: 10px; }
.icon-text > .icon { margin-top: 3px; }

/* Home (index.html) ----------------------------------------------------- */
/* Headshot column in "Meet Ashton": 0 1 400px with .col-fixed (canvas Main 2.6). */
.col-400 { flex-basis: 400px !important; }

/* Check (/check/), continued: 16px leader minimum, as in the canvas, so
   "Starter (up to 5 pages): $1,490" stays on one line at 390 */
.quote__rows--flush .leader { flex-basis: 16px; min-width: 16px; }

/* ===== 3 x 2 grids (added 12 Oct): exactly three across on wide screens,
   two on tablets, one on phones. Used for Home "Recent work" and "What I do". ===== */
.grid--3up { --min: 280px; }
@media (min-width: 62em) {
  .grid--3up { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ===== Brand tile in place of the headshot (26 Oct, until assets/img/ashton.jpg exists) ===== */
.headshot-tile { width: 100%; max-width: 400px; aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; background: var(--tint); border: 1px solid var(--line); border-radius: var(--radius); }
.headshot-tile img { width: 44%; height: auto; }
