/* Holt & Co · homepage
 * Rebuilt 2026-09-19 on the stone/graphite tokens (brand/kit/assets/holt-and-co.tokens.css).
 * Layout lifted from two Framer templates Melanje chose the same evening, Creston and Oakridge
 * (reference/site-inspiration-2026-09-19/source/), and rebuilt static so the page scrolls
 * natively. No smooth-scroll, no scroll-linked animation, one script for the form.
 *
 * Token values are copied, not invented. If a value is not in the tokens file it is a layout
 * measure taken from the templates (container 1180, section rhythm 80 to 160, list rows).
 */

/* ---- Fonts: Switzer for everything, Gambetta for the display line ------------------------ */
@font-face { font-family: "Switzer";  font-weight: 400; font-display: swap; src: url("fonts/Switzer-Regular.woff2") format("woff2"); }
@font-face { font-family: "Switzer";  font-weight: 500; font-display: swap; src: url("fonts/Switzer-Medium.woff2")  format("woff2"); }
@font-face { font-family: "Gambetta"; font-weight: 400; font-display: swap; src: url("fonts/gambetta-400.woff2")     format("woff2"); }
@font-face { font-family: "Gambetta"; font-weight: 500; font-display: swap; src: url("fonts/gambetta-500.woff2")     format("woff2"); }

/* ---- Tokens (mirror of the kit; the kit file is canonical) ------------------------------- */
:root {
  --paper:    #DAD5CF;
  --card:     #E6E2DC;
  --ink:      #302E2F;
  --muted:    #454240;
  --line:     #C4BEB6;
  --charcoal: #454244;
  --crimson:  #7F1B14;
  --muted-soft: #5E5953; /* the inactive language only; 4.75:1 on paper. --muted was too close to ink to read as inactive */
  --white:    #FFFFFF;  /* the Enquire block only: heading, contact links, focus ring. Paper read as grey on graphite, Melanje 2026-09-21 */

  --display: "Gambetta", Georgia, "Times New Roman", serif;
  --sans:    "Switzer", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  --size-min:  14px;
  --size-body: 17px;
  --size-ui:   15px;
  --size-caps-ui: 12px;        /* buttons and main nav, uppercase since 2026-09-21. 13px/0.12em needed 1366px for the header row; 12px/0.10em fits at 1280 */
  --caps-ui-tracking: 0.10em;
  --caps-tracking: 0.20em;

  --step-display: clamp(34px, 4.6vw, 56px);
  --step-lead:    19px;
  --step-body:    17px;
  --step-small:   15px;
  --step-label:   14px;
  --leading-display: 1.08;
  --leading-body:    1.62;

  --space-1: 6px;  --space-2: 12px; --space-3: 18px;
  --space-4: 26px; --space-5: 40px; --space-6: 64px;
  --gutter:  clamp(24px, 5vw, 64px);
  --measure: 44ch;
  --max:     1180px;

  --radius: 0;      /* was 6px; all corners square since 2026-09-19 late, Melanje */
  --hairline: 1px;
  --transition: .28s ease;

  /* layout measures from the templates, not brand tokens */
  --section: clamp(64px, 10vw, 176px);
}

/* ---- Base ------------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: auto; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--step-body);
  line-height: var(--leading-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
/* Hover is a hairline (audit 2026-09-20). The old a:hover shifted ink to charcoal, a change nobody
   could see; links that are not buttons now show a hairline under the text instead. Review 2026-09-21. */
a { text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 4px; transition: text-decoration-color var(--transition), color var(--transition), opacity var(--transition); }
a:hover { text-decoration-color: currentColor; }
.btn, .head-nav a, .head-lang a, .head-mark, .foot-mark, .enq-contact a { text-decoration: none; }
.head-mark:hover, .foot-mark:hover { opacity: .7; }
p { margin: 0 0 var(--space-3); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }
h1, h2, h3, h4 { margin: 0; font-weight: 400; }
ul, ol { margin: 0; padding: 0; list-style: none; }
:focus-visible { outline: 2px solid var(--charcoal); outline-offset: 3px; }

.wrap { width: min(100% - 2 * var(--gutter), var(--max)); margin-inline: auto; }
.wrap-wide { width: min(100% - 2 * var(--gutter), 1600px); margin-inline: auto; }

/* Type roles */
.display { font-family: var(--display); font-size: var(--step-display); line-height: var(--leading-display); letter-spacing: -0.015em; font-weight: 400; }
.display-lg { font-family: var(--display); font-size: clamp(40px, 5.2vw, 76px); line-height: 1.0; letter-spacing: -0.02em; font-weight: 400; }
.display-sm { font-family: var(--display); font-size: clamp(21px, 1.7vw, 24px); line-height: 1.35; letter-spacing: -0.005em; font-weight: 400; } /* the hero statement and the FAQ questions share it; consistency pass 2026-09-21 */
.lead { font-size: var(--step-lead); line-height: 1.55; color: var(--ink); }
.small { font-size: var(--step-small); color: var(--muted); }
.caps { font-size: var(--step-label); letter-spacing: var(--caps-tracking); text-transform: uppercase; font-weight: 500; color: var(--muted); }
.muted { color: var(--muted); }

/* Buttons: one bordered style, after Frama, and one filled for the primary ask */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; padding: 0 var(--space-4);
  border: var(--hairline) solid var(--ink); border-radius: 0;
  background: transparent; color: var(--ink);
  font: inherit; font-size: var(--size-caps-ui); line-height: 1; font-weight: 500; letter-spacing: var(--caps-ui-tracking); text-transform: uppercase; /* caps, Melanje 2026-09-21 */
  cursor: pointer; transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.btn:hover { background: var(--ink); color: var(--paper); }
.btn-fill { background: var(--ink); color: var(--paper); }
.btn-fill:hover { background: transparent; border-color: var(--ink); color: var(--ink); } /* inverts; ink to charcoal was invisible. Melanje 2026-09-21 */
.btn:active { transition-duration: .08s; opacity: .85; } /* press feedback, touch included */
.btn-quiet { border-color: var(--line); }
.acts { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: center; }
.acts .small { margin: 0; }

.rule { border: 0; border-top: var(--hairline) solid var(--line); margin: 0; }

/* ---- 00 Header · Oakridge's two-sided bar: mark left, verbs centre, contact right --------- */
.site-head { position: sticky; top: 0; z-index: 10; border-bottom: var(--hairline) solid var(--line); background: var(--paper); }
.head-row {
  display: grid; grid-template-columns: max-content 1fr max-content; align-items: center; /* max-content: the mark and the contact never squeeze */
  gap: var(--space-4); min-height: 72px;
}
.head-mark img { height: 26px; width: auto; max-width: none; }
.head-nav { display: flex; justify-content: center; gap: clamp(16px, 2.4vw, 36px); }
.head-nav a { font-size: var(--size-caps-ui); font-weight: 500; letter-spacing: var(--caps-ui-tracking); text-transform: uppercase; white-space: nowrap; padding: var(--space-1) 0; border-bottom: var(--hairline) solid transparent; line-height: 1; min-height: 44px; display: inline-flex; align-items: center; transition: border-color var(--transition), color var(--transition); } /* 44px hit area, audit 2026-09-20 finding 5 */
.head-nav a:hover { border-bottom-color: var(--ink); color: var(--ink); }
.head-contact { display: flex; align-items: center; gap: var(--space-3); }
.head-lang { display: flex; align-items: center; gap: 2px; font-size: var(--size-caps-ui); font-weight: 500; letter-spacing: var(--caps-ui-tracking); } /* same size as the nav since the nav went caps, 2026-09-21 */
/* The underline is text-decoration, not a border, so it hugs the word. On the border it was
   drawn at the foot of the 44px tap target and floated about 15px under the text (2026-09-22).
   Same idiom as every other non-button link on the site: transparent to current, transitioned. */
.head-lang a { padding: var(--space-1) 6px; color: var(--muted-soft); line-height: 1; text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: var(--hairline); text-underline-offset: 5px; transition: text-decoration-color var(--transition), color var(--transition); }
.head-lang a[aria-current="page"] { color: var(--ink); text-decoration-color: var(--ink); }
.head-lang a:hover { color: var(--ink); text-decoration-color: var(--ink); } /* so hovering the inactive language reads */
.head-lang a, .head-menu summary { min-height: 44px; display: inline-flex; align-items: center; }
.foot-col a { min-height: 44px; display: inline-flex; align-items: center; }
.enq .enq-consent input[type="checkbox"] { width: 22px; height: 22px; margin: 1px 0 0; flex: none; } /* 22px, audit finding 5; the 18px rule below is superseded */
.service-copy p:not(.caps), .faq-list details p { max-width: var(--measure); } /* kit --measure 44ch, audit finding 4 */
.head-lang a + a::before { content: ""; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.head-menu { display: none; }

/* ---- 01 Hero · Creston: the wordmark as the first thing on the page --------------------- */
.hero { padding-top: clamp(64px, 12vw, 200px); } /* raised twice 2026-09-20 at Melanje's request: air between the header and the statement (was 56px) */
.hero-top { display: grid; grid-template-columns: 68.88% minmax(0, 1fr); gap: 0; align-items: end; margin-bottom: var(--space-4); }
/* 68.88%: the left edge of the C in CO., measured from the SVG (x 551 in a viewBox from -34, 849.3 wide) */
.hero-top .statement { margin: 0; max-width: none; font-family: var(--display); font-size: clamp(21px, 1.7vw, 24px); line-height: 1.35; font-weight: 400; letter-spacing: -0.005em; } /* = .display-sm */
.hero-top .statement { grid-column: 1; max-width: 44ch; justify-self: start; } /* eyebrow removed 2026-09-20; the statement keeps the right column, narrowed the same day */
.hero-mark { width: 100%; }
.hero-mark img { width: 100%; height: auto; }
.hero-meta p { margin: 0; max-width: none; }
.hero-meta {
  display: flex; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) 0; border-top: var(--hairline) solid var(--line); border-bottom: var(--hairline) solid var(--line);
  margin-top: var(--space-4);
}
.hero-bleed { margin: var(--space-5) 0 var(--space-6); }
.hero-photo { margin: 0; position: relative; overflow: hidden; height: clamp(360px, 82vh, 900px); }
.hero-photo picture { display: block; position: absolute; inset: -15% 0; } /* 130% tall: the slack the parallax drifts through (motion.js, 2026-09-21) */
.hero { padding-bottom: 0; }
.hero-photo img { width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.hero-photo figcaption { margin-top: var(--space-2); }

/* ---- Services · one section per verb, image and copy alternating (Oakridge's two columns) - */
.service { padding: var(--space-6) 0 0; }
.service + .service { margin-top: 0; } /* was --space-6 on top of the padding: 26px above the content, 128px below. Balanced 2026-09-20 */
.service .service-grid { border-top: var(--hairline) solid var(--line); padding-top: var(--space-6); }
.service-head { display: flex; justify-content: flex-start; gap: var(--space-3); margin-bottom: var(--space-5); }
.service-copy > * { margin-bottom: 0; }
.service-copy > .service-head { margin-bottom: var(--space-5); }
.service-head .caps { margin: 0; }
.service-head .index { color: var(--muted); }
.service-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(32px, 5vw, 96px); align-items: center; }
.service-photo { width: 100%; aspect-ratio: 4 / 5; position: relative; overflow: hidden; }
.service-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transform-origin: 50% 50%; will-change: transform; } /* zooms in as it crosses the viewport, motion.js 2026-09-24 (was a parallax drift) */
/* All five section images are 4:5 since 2026-09-20 (was 4:5 / 1:1 alternating). */
.service.img-right .service-photo { order: 2; }
.service-copy h2 { margin-bottom: var(--space-4); color: var(--ink); max-width: 17ch; } /* 17ch, 2026-09-29: "Custom furniture" on one line (Melanje, iPad notes); was 12ch */
.service-copy .lead { margin-bottom: var(--space-3); max-width: 40ch; }
.service-copy p:not(.lead):not(.caps) { max-width: 46ch; }
.service-copy p:not(.lead):not(.caps) { color: var(--muted); }
.service-copy .acts { margin-top: var(--space-5); }

.tiers.tiers-compact { margin-top: var(--space-5); grid-template-columns: 1fr; border-top: var(--hairline) solid var(--line); border-bottom: 0; }
.tiers.tiers-compact .tier { border-right: 0; border-bottom: var(--hairline) solid var(--line); padding: var(--space-3) 0; grid-template-rows: none; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); column-gap: var(--space-4); row-gap: var(--space-1); align-items: start; }
.tiers.tiers-compact .tier + .tier { padding-left: 0; }
.tiers.tiers-compact .tier h3 { font-size: clamp(22px, 2vw, 26px); grid-column: 1; }
.tiers.tiers-compact .tier .price { grid-column: 1; font-size: var(--step-body); }
.tiers.tiers-compact .tier .note { grid-column: 2; grid-row: 1 / 3; margin: 0; max-width: none; }
.tiers-compact + .small { margin-top: var(--space-3); }

/* ---- Questions · native details, no script --------------------------------------------- */
.faq { padding: var(--section) 0; }
.faq-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: clamp(32px, 5vw, 96px); align-items: start; }
.faq-grid > div:first-child { position: sticky; top: calc(72px + var(--space-5)); } /* 72px = the sticky header; audit 2026-09-20 finding 2 */
.faq-grid .caps { margin: 0 0 var(--space-2); }
.faq-list { border-top: var(--hairline) solid var(--line); }
.faq-list details { border-bottom: var(--hairline) solid var(--line); }
.faq-list summary { list-style: none; cursor: pointer; padding: var(--space-3) 0; font-family: var(--display); font-size: clamp(21px, 1.7vw, 24px); line-height: 1.35; letter-spacing: -0.005em; /* = .display-sm */ display: flex; justify-content: space-between; gap: var(--space-3); align-items: baseline; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary > span { text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 6px; transition: text-decoration-color var(--transition); } /* the span keeps the hairline off the marker */
.faq-list summary::after { content: "+"; font-family: var(--sans); font-size: var(--step-lead); color: var(--muted); flex: none; transition: color var(--transition); }
.faq-list summary:hover > span { text-decoration-color: currentColor; }
.faq-list summary:hover::after { color: var(--ink); }
.faq-list details[open] summary::after { content: "\2013"; }
.faq-list details p { margin: 0 0 var(--space-4); max-width: var(--measure); color: var(--muted); } /* was 56ch; kit measure, audit 2026-09-20 */
.faq-list details[open] summary { color: var(--ink); }

/* ---- Tiers · three columns inside the Keep section, hairline between --------------------- */
.tiers { display: grid; grid-template-columns: repeat(3, 1fr); border-top: var(--hairline) solid var(--line); border-bottom: var(--hairline) solid var(--line); }
.tier { padding: var(--space-5) var(--space-4) var(--space-5) 0; border-right: var(--hairline) solid var(--line); display: grid; grid-template-rows: auto auto auto 1fr auto; gap: var(--space-2); }
.tier + .tier { padding-left: var(--space-4); }
.tier:last-child { border-right: 0; padding-right: 0; }
.tier h3 { font-family: var(--display); font-size: clamp(24px, 2.4vw, 32px); line-height: 1.15; letter-spacing: -0.01em; font-weight: 400; }
.tier .price { font-size: var(--step-lead); font-weight: 500; }
.tier .price .small { font-weight: 400; margin-left: var(--space-1); }
.tier ul { display: grid; gap: var(--space-1); padding-top: var(--space-2); }
.tier li { padding-left: 1.2em; position: relative; }
.tier li::before { content: ""; position: absolute; left: 0; top: 0.75em; width: 0.5em; height: var(--hairline); background: var(--ink); }
.tier .note { color: var(--muted); font-size: var(--step-small); }
.tier .btn { justify-self: start; }

/* ---- 10 Enquire ------------------------------------------------------------------------ */
.enquire { padding: var(--section) 0; background: var(--ink); color: var(--paper); }
.enquire .caps, .enquire .small, .enquire .enq-opt, .enquire .enq-hint { color: var(--line); }
.enq-intro .caps { margin: 0 0 var(--space-2); } /* same gap as the FAQ eyebrow */
.enquire p { color: var(--paper); }
.enquire .enq-intro h2 { color: var(--white); }
.enquire .enq-contact a { color: var(--white); border-bottom: var(--hairline) solid transparent; width: max-content; transition: border-color var(--transition); } /* --line under white read green on graphite */
.enquire .enq-contact a:hover { border-bottom-color: var(--white); color: var(--white); }
.enquire .btn-fill { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.enquire .btn-fill:hover { background: transparent; border-color: var(--white); color: var(--white); } /* inverts, as on the page */
.enquire .enq-consent { color: var(--line); }
.enquire .enq-consent a { color: var(--paper); }
.enquire .enq-notice { background: var(--charcoal); border-left-color: var(--crimson); color: var(--paper); }
.enquire :focus-visible { outline-color: var(--white); }
.enq-grid-outer { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: clamp(32px, 5vw, 96px); align-items: start; }
.enq-intro .sticky { position: static; } /* the intro is the taller column; it cannot stick. The form does, below */
.enq-grid-outer .enq { position: sticky; top: calc(72px + 4rem); } /* 4rem under the sticky header (was 2rem). Removed, restored and raised the same day, Melanje 2026-09-21 */
.enq-intro h2 { margin-bottom: var(--space-4); } /* same as the service headings */
.enq-contact { display: grid; gap: var(--space-1); margin-top: var(--space-4); }
.enq-portrait { width: min(220px, 100%); margin: var(--space-4) 0 0; }
.enq-portrait img { display: block; width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.enq-contact a { font-weight: 400; } /* same weight as the footer's contact links */

.enq fieldset { border: 0; padding: 0; margin: 0 0 var(--space-4); }
.enq legend { font-size: var(--step-label); letter-spacing: var(--caps-tracking); text-transform: uppercase; font-weight: 500; color: var(--muted); margin-bottom: var(--space-2); }
.enq-choices { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.enq-choice { position: relative; }
.enq-choice input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.enq-choice span { display: inline-flex; align-items: center; min-height: 40px; padding: 0 var(--space-3); border: var(--hairline) solid var(--line); border-radius: 0; font-size: var(--size-ui); font-weight: 500; letter-spacing: 0.01em; transition: background var(--transition), border-color var(--transition), color var(--transition); }
.enq-choice input:checked + span { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.enq-choice input:focus-visible + span { outline: 2px solid var(--charcoal); outline-offset: 3px; }

.enq-fields { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3) var(--space-4); align-items: start; } /* start: a taller field (the WhatsApp row) must not stretch its neighbour */
.enq-field { display: grid; gap: var(--space-1); max-width: none; margin: 0; }
.enq-field-wide { grid-column: 1 / -1; }
.enq-field label { font-size: var(--step-small); font-weight: 500; color: var(--paper); }
.enq-opt { color: var(--muted); font-weight: 400; }
.enq-hint { font-size: var(--step-small); color: var(--muted); }
.enq input[type="text"], .enq input[type="email"], .enq input[type="tel"], .enq textarea {
  width: 100%; font: inherit; font-size: var(--step-body); color: var(--ink);
  background: var(--paper); border: var(--hairline) solid var(--paper); border-radius: 0;
  padding: 12px 14px; transition: border-color var(--transition);
}
.enq select { width: 100%; font: inherit; font-size: var(--step-body); color: var(--ink); background: var(--paper); border: var(--hairline) solid var(--paper); border-radius: 0; padding: 12px 14px; transition: border-color var(--transition); cursor: pointer; appearance: none; -webkit-appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%), linear-gradient(135deg, var(--ink) 50%, transparent 50%); background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%; background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; }
.enq select:invalid { color: var(--muted); }
.enq input:hover, .enq textarea:hover, .enq select:hover { border-color: var(--line); }
.enq input:focus, .enq textarea:focus, .enq select:focus { outline: none; border-color: var(--white); box-shadow: 0 0 0 2px var(--white); } /* was --line, invisible on graphite */
.enq ::placeholder { color: var(--muted); opacity: .7; }
.enq-consent label, .enq-consent input { cursor: pointer; }
.enq textarea { resize: vertical; min-height: 120px; }
.enq-phone { display: grid; gap: var(--space-1); margin: 0; }
.enq-phone-row { display: grid; grid-template-columns: minmax(0, 118px) minmax(0, 1fr); gap: var(--space-2); } /* dialling code + number, added 2026-09-21 */
.enq-phone-row select { padding-right: 34px; }
.enq-consent { display: grid; grid-template-columns: auto 1fr; gap: var(--space-2); align-items: start; margin: var(--space-4) 0; max-width: none; font-size: var(--step-small); color: var(--muted); }
.enq-consent input { margin-top: 5px; width: 18px; height: 18px; accent-color: var(--paper); }
.enq-consent a { text-decoration: underline; text-underline-offset: 3px; }
.enq-under { margin-top: var(--space-2); }
.enq-notice { margin-top: var(--space-3); padding: var(--space-3); background: var(--card); border-left: 3px solid var(--crimson); color: var(--ink); max-width: none; }

/* ---- 11 Footer · Oakridge and Creston: the wordmark at page width, then the rest -------- */
.site-foot { padding: var(--space-6) 0 var(--space-5); }
.foot-col .foot-mark { display: inline-block; width: max-content; min-height: 0; padding: 0; margin-bottom: var(--space-4); } /* header-sized, above Family-run. Was page-width; Melanje 2026-09-21. Specific enough to beat the footer link rule */
.foot-mark img { height: 26px; width: auto; display: block; }
/* Footer runs the header's width (.wrap-wide), Melanje 2026-09-21. The 4.8% / 4.7% insets that hung the
   columns off the letters of the old page-width wordmark went with it. */
.foot-grid { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-6); }
.foot-grid > .foot-col { grid-column: 1; }
.foot-group { grid-column: 2; display: flex; justify-content: flex-end; gap: clamp(40px, 5vw, 80px); }
.foot-col h3 { font-size: var(--step-label); letter-spacing: var(--caps-tracking); text-transform: uppercase; font-weight: 500; color: var(--muted); margin-bottom: var(--space-2); }
.foot-col a, .foot-col span { display: block; padding: 3px 0; min-height: 44px; } /* links and plain rows share one row height, so Where matches What we do and Contact */
.foot-col p { max-width: 38ch; color: var(--muted); } /* body copy is muted page-wide; the links stay ink */
.foot-bottom { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin: var(--space-6) 0 0; padding-top: var(--space-3); border-top: var(--hairline) solid var(--line); }
.foot-bottom p { margin: 0; max-width: none; }

/* ---- Responsive -------------------------------------------------------------------------- */
@media (max-width: 1100px) {
  .foot-grid { grid-template-columns: 1fr; gap: var(--space-5); }
  .foot-grid > .foot-col, .foot-group { grid-column: auto; }
  .foot-group { justify-content: flex-start; flex-wrap: wrap; }
}

/* Header only: five uppercase nav items, the mark and the caps button fit from 1280px (measured
   2026-09-21 at 12px/0.10em). Below 1240 the nav folds into the Menu; the page layout keeps 820. */
@media (max-width: 1240px) {
  .head-nav { display: none; }
  .head-menu { display: block; }
  .head-menu summary { list-style: none; cursor: pointer; font-size: var(--size-caps-ui); font-weight: 500; letter-spacing: var(--caps-ui-tracking); text-transform: uppercase; padding: var(--space-1) 0; }
  .head-menu summary::-webkit-details-marker { display: none; }
  .head-menu[open] { position: relative; }
  .head-menu nav { position: absolute; right: 0; top: calc(100% + var(--space-2)); background: var(--card); border: var(--hairline) solid var(--line); border-radius: 0; padding: var(--space-3) var(--space-4); display: grid; gap: var(--space-2); min-width: 220px; z-index: 5; }
  .head-menu nav a { font-size: var(--size-caps-ui); font-weight: 500; letter-spacing: var(--caps-ui-tracking); text-transform: uppercase; }
}

@media (max-width: 820px) {
  .head-row { min-height: 64px; }
  .head-lang { display: none; }

  .hero-top, .service-grid, .faq-grid, .enq-grid-outer { grid-template-columns: 1fr; }
  .service-photo { aspect-ratio: 4 / 3 !important; order: 0 !important; }
  .service-head { margin-bottom: var(--space-3); }
  .faq-grid > div:first-child { position: static; }
  .tiers.tiers-compact .tier { grid-template-columns: 1fr; }
  .tiers.tiers-compact .tier .note { grid-column: 1; grid-row: auto; }
  .hero-meta { flex-direction: column; gap: var(--space-1); }
  .hero-photo { height: clamp(280px, 52vh, 480px); }
  .tiers { grid-template-columns: 1fr; }
  .tier { border-right: 0; border-bottom: var(--hairline) solid var(--line); padding: var(--space-4) 0; }
  .tier + .tier { padding-left: 0; }
  .tier:last-child { border-bottom: 0; }
  .enq-grid-outer .enq { position: static; }
  .hero-bleed { margin-bottom: 0; } /* rhythm doubled once on the phone, audit finding 11 */
  .enq-fields { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: 1fr; gap: var(--space-4); }
  .foot-group { flex-direction: column; gap: var(--space-4); }
}

/* ---- Motion (GSAP, motion.js, 2026-09-21; same register as the Carnivore Capital build) ----- */
.motion .rv { visibility: hidden; } /* html.motion is set by the head gate; motion.js reveals, or clears the class if GSAP fails */
.split-line { will-change: transform; }
.motion h2.rv, .motion .statement.rv { display: flow-root; } /* a block formatting context: the masks' negative margins stay inside the heading instead of collapsing into its own margin */
.split-mask-line-mask { padding-bottom: .22em; margin-bottom: -.22em; } /* a negative margin meeting a zero margin collapses to itself, so each line still occupies exactly its line box */
.split-mask-line-mask:first-child { padding-top: .1em; margin-top: -.1em; } /* accents on the first line (Möbel) */ /* the mask is the line box; at line-height 1.0 Gambetta's descenders (the g in staging) and accents fell outside it and were clipped. Room, with the margins cancelling it. 2026-09-21 */

@media (max-width: 360px) {
  .head-row { gap: 8px; }
  .head-mark img { height: 20px; } /* the mark no longer squeezes (max-content), so it steps down on the narrowest phones */
  .site-head .btn { padding: 0 var(--space-3); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
  .rv { visibility: visible; }
  .hero-photo img, .service-photo img { transform: none !important; }
}

/* ---- Launch pass, 2026-09-22 ------------------------------------------------------------- */

/* Skip link. There was none; the sticky header put five nav items, a language pair and a button
   in front of the content for every keyboard and screen-reader visitor. Hidden until focused,
   then it sits over the header (z-index above .site-head's 10). */
.skip-link {
  position: absolute; left: var(--space-2); top: -100px; z-index: 20;
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--space-4);
  background: var(--ink); color: var(--paper); text-decoration: none;
  font-size: var(--size-caps-ui); font-weight: 500; letter-spacing: var(--caps-ui-tracking);
  text-transform: uppercase; transition: top var(--transition);
}
.skip-link:focus-visible { top: var(--space-2); outline: 2px solid var(--paper); outline-offset: 2px; }
main:focus { outline: none; } /* main is tabindex="-1" purely as the skip target */

/* Anchor offset. Every CTA on the page is an in-page jump and the header is sticky, so the
   heading it lands on was sliding under the bar. 72px header + air; 64px below 820. */
:target, #main, .service, .faq, .enquire { scroll-margin-top: calc(72px + var(--space-3)); }
@media (max-width: 820px) {
  :target, #main, .service, .faq, .enquire { scroll-margin-top: calc(64px + var(--space-3)); }
}

/* Full-width buttons on the phone (Melanje, 2026-09-22): easier to see and easier to hit.
   560px, not 820, so the tablet keeps its inline row. The header button is excluded: it sits in
   a three-column bar beside the mark and the Menu and must stay its own width. */
@media (max-width: 560px) {
  .acts { flex-direction: column; align-items: stretch; gap: var(--space-2); }
  .acts .btn, .enq .btn, .enq button[type="submit"] { width: 100%; justify-content: center; }
  .site-head .acts { flex-direction: row; }
  .site-head .btn { width: auto; }
}

/* Tap targets, measured at 320px on 2026-09-22 and found short. WCAG 2.2 AA (2.5.8) asks 24px;
   these are the primary phone navigation and the highest-intent contact links, so they go to 44.
   Found short: the six links inside the Menu panel (19px), the Enquire contact links (29px),
   the footer legal links (19px) and the consent checkbox (22px). */
.head-menu nav a { min-height: 44px; display: flex; align-items: center; }
.enq-contact a { min-height: 44px; display: inline-flex; align-items: center; }
.foot-bottom a { min-height: 44px; display: inline-flex; align-items: center; }
.enq .enq-consent input[type="checkbox"] { width: 24px; height: 24px; }
/* The wordmark link's hit area, not its size: the image stays 26px (20px under 360px), the
   anchor grows to a 44px row around it. The Privacy link inside the consent sentence stays as
   it is: 2.5.8 exempts a link inline in a block of text. */
.head-mark, .foot-mark { display: inline-flex; align-items: center; min-height: 44px; }

/* ---- Legal pages (privacy, cookies), 2026-09-22 ------------------------------------------
   One column, generous measure, the same type scale as the homepage. No motion, no reveal
   classes: these are pages people read under pressure, often on a phone, sometimes because
   something has gone wrong. They load complete. */
.legal { padding: var(--space-6) 0 var(--section); }
.legal-head { margin-bottom: var(--space-6); padding-bottom: var(--space-4); border-bottom: var(--hairline) solid var(--line); }
.legal-head .caps { margin-bottom: var(--space-3); }
.legal-head h1 { font-family: var(--display); font-size: var(--step-display); line-height: var(--leading-display); letter-spacing: -0.015em; }
.legal-head .lead { margin-top: var(--space-3); font-size: var(--step-lead); color: var(--muted); max-width: 62ch; }
.legal-body { max-width: 68ch; }
.legal-body h2 { font-family: var(--display); font-size: clamp(24px, 2.4vw, 30px); line-height: 1.2; letter-spacing: -0.01em; margin: var(--space-6) 0 var(--space-3); }
.legal-body h3 { font-size: var(--step-body); font-weight: 500; margin: var(--space-4) 0 var(--space-2); }
.legal-body p { color: var(--muted); max-width: none; }
.legal-body ul { list-style: none; margin: 0 0 var(--space-3); padding: 0; }
.legal-body li { position: relative; padding-left: var(--space-4); margin-bottom: var(--space-2); color: var(--muted); }
.legal-body li::before { content: ""; position: absolute; left: 0; top: .72em; width: 10px; height: var(--hairline); background: var(--line); }
.legal-body a { text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
.legal-body a:hover { text-decoration-color: currentColor; }
.legal-table { width: 100%; border-collapse: collapse; margin: var(--space-3) 0 var(--space-4); font-size: var(--step-small); }
.legal-table th, .legal-table td { text-align: left; vertical-align: top; padding: var(--space-2) var(--space-3) var(--space-2) 0; border-bottom: var(--hairline) solid var(--line); color: var(--muted); }
.legal-table th { font-weight: 500; color: var(--ink); }
.legal-meta { margin-top: var(--space-6); padding-top: var(--space-4); border-top: var(--hairline) solid var(--line); font-size: var(--step-small); color: var(--muted); }
@media (max-width: 560px) {
  .legal-table, .legal-table tbody, .legal-table tr, .legal-table td, .legal-table th { display: block; width: 100%; }
  .legal-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .legal-table tr { padding: var(--space-3) 0; border-bottom: var(--hairline) solid var(--line); }
  .legal-table td, .legal-table th { border: 0; padding: 0 0 var(--space-1); }
  .legal-table td::before { content: attr(data-label) ": "; font-weight: 500; color: var(--ink); }
}

/* ---- Consent banner, 2026-09-22 ----------------------------------------------------------
   A bar at the foot, not a full-screen block: the page stays readable while you decide, which
   is both kinder and what the regulators actually want (no nagging overlay, no dark pattern).
   Accept and Reject are the same size and weight, side by side. */
.consent {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--ink); color: var(--paper);
  border-top: var(--hairline) solid var(--charcoal);
}
.consent-inner {
  width: min(100% - 2 * var(--gutter), 1600px); margin-inline: auto;
  padding: var(--space-4) 0;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-5);
}
.consent-copy { max-width: 72ch; }
.consent-title { margin: 0 0 var(--space-1); font-size: var(--step-body); font-weight: 500; color: var(--white); }
.consent-body  { margin: 0; font-size: var(--step-small); line-height: 1.55; color: var(--paper); opacity: .85; max-width: none; }
.consent-body a { color: var(--white); text-decoration: underline; text-decoration-color: currentColor; text-underline-offset: 3px; }
.consent-acts { display: flex; gap: var(--space-2); flex: none; }
/* On the ink ground the page's ink-bordered buttons would vanish, so both invert.
   Accept and Reject are deliberately IDENTICAL: same border, same ground, same weight, same
   hover. The EDPB and CNIL both treat a visually louder Accept as a dark pattern that
   invalidates the consent, so the filled treatment is dropped here even though the rest of the
   site uses it for a primary action. The only difference between the two is the word. */
.consent .btn, .consent .btn-fill {
  border-color: var(--paper); color: var(--paper); background: transparent;
}
.consent .btn:hover, .consent .btn-fill:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.consent .btn:focus-visible { outline: 2px solid var(--white); outline-offset: 3px; }

@media (max-width: 820px) {
  .consent-inner { flex-direction: column; align-items: stretch; gap: var(--space-3); padding: var(--space-3) 0 var(--space-4); }
  .consent-acts { flex-direction: column; }
  .consent .btn { width: 100%; justify-content: center; }
}
/* The footer's legal row. "Cookie choices" is a button, not a link, because it opens a dialog
   rather than going anywhere; it is styled to sit in the row without looking like a control. */
.foot-legal { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.foot-legal span { color: var(--line); }
.foot-linkish {
  appearance: none; background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
  min-height: 44px; display: inline-flex; align-items: center;
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px;
  transition: text-decoration-color var(--transition);
}
.foot-linkish:hover { text-decoration-color: currentColor; }
.foot-linkish:focus-visible { outline: 2px solid var(--charcoal); outline-offset: 3px; }

/* The honeypot. Hidden from sight, from screen readers (aria-hidden on the wrapper) and from
   the tab order (tabindex="-1"), but still a real field a bot will fill. Not display:none,
   because some bots skip those; off-canvas and zero-opacity is the safer trick. */
.enq-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; opacity: 0; }

/* The form's status line. One live region, three tones. It already carried role="status", so a
   screen reader announces it without moving focus; focus moves anyway because the message is
   the answer to the thing the visitor just did. */
.enq-notice {
  margin: var(--space-3) 0 0; padding: var(--space-3) var(--space-4);
  font-size: var(--step-small); line-height: 1.55; max-width: none;
  border-left: 2px solid var(--paper); background: rgba(255,255,255,.06); color: var(--paper);
}
.enq-notice:focus-visible { outline: 2px solid var(--white); outline-offset: 3px; }
.enq-notice[data-tone="ok"]   { border-left-color: var(--white); color: var(--white); }
.enq-notice[data-tone="bad"]  { border-left-color: var(--white); }
.enq-notice[data-tone="busy"] { opacity: .8; }

/* ---- Fixed enquire bar, tablet and below, 2026-09-22 -------------------------------------
   Melanje's call. The Enquire button leaves the header at 1024px and becomes a fixed bar, so
   the CTA is reachable from any scroll position and the header has room for the mark and Menu.
   It also fixes a measured WCAG 1.4.4 failure: at 1.5x zoom the three header items no longer
   fit a phone and "Menu" was clipped off the edge. */
.cta-bar { display: none; }

@media (max-width: 1024px) {
  .site-head .btn { display: none; }          /* out of the header */

  .cta-bar {
    display: block;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    background: var(--paper);
    border-top: var(--hairline) solid var(--line);
    /* The iPhone home indicator sits in the bottom inset; without this the button is under it. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
    transform: translateY(0);
    transition: transform var(--transition), opacity var(--transition);
  }
  .cta-bar-inner {
    width: min(100% - 2 * var(--gutter), 1600px); margin-inline: auto;
    padding: var(--space-2) 0;
  }
  .cta-bar .btn { width: 100%; justify-content: center; }

  /* The footer must not end underneath the bar. */
  body { padding-bottom: calc(44px + 2 * var(--space-2) + env(safe-area-inset-bottom, 0px)); }

  /* Out of the way when it would be noise or an obstruction:
     - while the consent banner is open, because that decision comes first and both are fixed
       to the bottom edge;
     - once the enquiry form itself is on screen, because a button that scrolls you to where
       you already are is just a bar over the fields. */
  .consent-open .cta-bar,
  .at-enquire .cta-bar { transform: translateY(100%); opacity: 0; pointer-events: none; }
}

/* Reduced motion: appear and disappear without sliding. */
@media (prefers-reduced-motion: reduce) {
  .cta-bar { transition: none !important; }
}

/* ---- WhatsApp button, every page, 2026-10-03 ----------------------------------------------
   Melanje: a quick way to message her directly, in the Enquire button's colours rather than
   WhatsApp green. Injected by cta.js. The one round thing on a square site, on purpose: it is
   the WhatsApp shape people look for. The paper hairline keeps it visible over the graphite
   Enquire section, where a graphite circle would otherwise disappear. */
.wa-float {
  position: fixed; right: 20px; z-index: 35;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  width: 56px; height: 56px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ink); color: var(--paper);
  border: var(--hairline) solid var(--paper);
  box-shadow: 0 2px 12px rgba(48, 46, 47, .22);
  transition: bottom var(--transition), opacity var(--transition), transform var(--transition);
}
.wa-float svg { width: 26px; height: 26px; display: block; }
.wa-float:hover { transform: translateY(-2px); }
.wa-float:active { transform: none; opacity: .85; }
.wa-float:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; box-shadow: 0 0 0 6px var(--paper); } /* the paper halo keeps the ring readable over the graphite section */

/* The consent decision comes first, as with the enquire bar. */
.consent-open .wa-float { opacity: 0; pointer-events: none; }

/* Tablet and below the enquire bar owns the bottom edge, so the button sits just above it. At the
   form it leaves with the bar: on a phone it sat on the message field (seen on staging,
   2026-10-03), and the Enquire section carries its own WhatsApp link. */
@media (max-width: 1024px) {
  .wa-float { right: 16px; bottom: calc(44px + 2 * var(--space-2) + 12px + env(safe-area-inset-bottom, 0px)); }
  .at-enquire .wa-float { opacity: 0; pointer-events: none; }
}

@media (prefers-reduced-motion: reduce) {
  .wa-float { transition: none !important; }
  .wa-float:hover { transform: none; }
}

@media print { .wa-float { display: none; } }

/* Desktop: room under the footer so the button never sits on "Cookie choices" at the very bottom
   (56px button + 20px offset + air). Tablet and below already pad the body for the enquire bar. */
@media (min-width: 1025px) { .site-foot { padding-bottom: 104px; } }

/* Very narrow CSS widths, 2026-09-22. Reached by a small phone at 200% browser zoom rather than
   by any real device: 360px at 2x is a 180px viewport. WCAG 1.4.4 asks for 200% without loss of
   content, and at that size the wordmark plus Menu plus a 24px gutter each side no longer fit.
   The mark steps down again and the gutter tightens. Nothing below 300px is a phone, so this
   costs the real layouts nothing. */
@media (max-width: 300px) {
  :root { --gutter: 12px; }
  .head-mark img { height: 16px; }
  .head-row { gap: 6px; min-height: 56px; }
}

/* ---- Header on tablet and below, 2026-09-22 (Melanje) ------------------------------------
   Three things across the bar: the mark left, the language centred, Menu hard right. The
   language pair was hidden below 820px; it comes back now that Enquire has left for the fixed
   bottom bar and there is room for it.

   display:contents on .head-contact dissolves the wrapper so its children become grid items of
   .head-row directly, which is what lets the language sit in the middle column while Menu keeps
   the right. The wrapper is a plain div with no role, so nothing is lost by dissolving it. */
@media (max-width: 1024px) {
  .head-contact { display: contents; }
  .head-lang { display: flex; justify-self: center; }
  .head-menu { display: block; justify-self: end; }
}

/* ---- Hero nameplate, 2026-09-22 (Melanje) ------------------------------------------------
   "Family-run · Garden Route" moves out of the meta band and sits directly above the wordmark,
   so the three read as one nameplate: descriptor, name, territory. Before this the descriptor
   and the towns shared a rule-bounded band that was designed for the desktop row, where they
   sit at opposite ends. Stacked on a phone they collapsed into one lump with a 6px gap and the
   towns wrapping to three lines. */
.hero-eyebrow {
  margin: 0 0 var(--space-2);
  color: var(--muted);
}

/* The towns are spans so they wrap as whole place names, never breaking mid-name, and so the
   separator can be dropped on the phone. A wrapped list punctuated by interpuncts leaves a
   dangling "·" at the end of a line, which is what made this look untidy; below 560px the
   spacing does the separating instead. */
.hero-places { display: flex; flex-wrap: wrap; column-gap: var(--space-2); row-gap: var(--space-1); }
.hero-places span { white-space: nowrap; }
/* The separator is ::after on the preceding town, not ::before on the next one, and the span
   is nowrap, so the "·" can never begin a wrapped line. It trails the last town on a line
   instead, which reads as a continuation. Caught on the phone, 2026-09-22. */
.hero-places span:not(:last-child)::after { content: "·"; color: var(--line); margin-left: var(--space-2); }

/* On the phone the list has to wrap. Dropping the separators and widening the gaps was tried
   first and read as a broken two-column table, so the separators stay and the tracking tightens
   instead, which brings it to two lines that read as one wrapped list. 14px is the floor and is
   not touched; only the letter-spacing moves. */
@media (max-width: 560px) {
  .hero-places { column-gap: var(--space-1); row-gap: 4px; letter-spacing: 0.10em; }
  .hero-places span:not(:last-child)::after { margin-left: var(--space-1); }
}

/* The band holds one line now, so it no longer needs to push two items apart. */
.hero-meta { justify-content: flex-start; }
@media (max-width: 820px) {
  .hero-meta { flex-direction: row; }   /* was column, for the two stacked lines that have gone */
}

/* ---- 404, 2026-09-24. The legal page shell, a way home, and the five services as the way back in */
.notfound .legal-head { border-bottom: 0; margin-bottom: var(--space-5); }
.notfound-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-6); }
.notfound-list { border-top: var(--hairline) solid var(--line); padding-top: var(--space-4); }
.notfound-list .caps { margin-bottom: var(--space-3); }
.notfound-list ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 0; }
.notfound-list a { display: inline-flex; align-items: center; min-height: 44px; font-family: var(--display); font-size: var(--step-lead); color: var(--ink); text-decoration-color: var(--line); text-underline-offset: 0.2em; }
.notfound-list a:hover { text-decoration-color: currentColor; }
@media (max-width: 559px) { .notfound-actions .btn { width: 100%; justify-content: center; } }

/* ---- Hero nameplate on desktop, 2026-09-29 (Melanje) ---------------------------------------
   On the phone the descriptor stays above the wordmark (the 2026-09-22 nameplate, above). On
   desktop it returns to the rule-bounded band under the wordmark: "Family-run · Garden Route"
   left, the towns right. Done with grid areas rather than moving the markup, so the phone order
   and the reading order stay as they are. The two cells carry matching rules and padding with no
   gap between them, so the band reads as one line. */
@media (min-width: 1100px) { /* the five towns fit one line from 1075px, measured */
  .hero > .wrap-wide { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "top top" "mark mark" "eyebrow meta"; }
  .hero-top { grid-area: top; }
  .hero-mark { grid-area: mark; }
  .hero-eyebrow, .hero-meta {
    margin: var(--space-4) 0 0; padding: var(--space-3) 0;
    border-top: var(--hairline) solid var(--line); border-bottom: var(--hairline) solid var(--line);
  }
  .hero-eyebrow { grid-area: eyebrow; padding-right: var(--space-4); }
  .hero-meta { grid-area: meta; justify-content: flex-end; }
  .hero-places { justify-content: flex-end; }
}
