/* ==========================================================================
   Foundation Software Ltd — site styles
   Palette: deep forest + copper + cream (Foundation identity system)
   ========================================================================== */

:root {
  /* The Foundation Agent palette, as measured off foundationagent.co.uk.
     Paper first, forest for emphasis, bronze for accent. The names below are
     the ones 395 declarations in this file already use, so they keep their
     meaning — what changed is the ground they describe. Where a name says
     "dark" it now means "on the page", because the page is no longer dark. */

  /* Core */
  --ink:          #F7F5F0;   /* the page itself */
  --paper:        #F7F5F0;
  --wash:         #F0EDE6;   /* the alternate band */
  --surface:      #FFFFFF;   /* cards sitting on either */
  --forest:       #12291F;   /* the one colour both sites share */
  --forest-2:     #1C3A2D;
  --forest-deep:  #0E1A14;
  --green:        #FFFFFF;
  --green-mid:    #F0EDE6;
  --green-line:   #E7E2D8;
  --copper:       #8A5424;   /* bronze: the accent, dark enough to read on paper */
  --copper-mid:   #A66730;
  --gold:         #8A5424;
  --bronze-soft:  #E5B884;   /* the light bronze, for use on forest only */
  --glow:         rgba(138,84,36,0.18);
  --copper-deep:  #8A5424;
  --cream:        #F0EDE6;
  --white:        #FFFFFF;

  /* Text */
  --text:         #141A17;
  --text-muted:   #5B615C;
  --text-soft:    #686D68;
  --on-dark:      #141A17;   /* "on the page" — see the note above */
  --muted-dark:   #5B615C;
  --error:        #8E2A20;   /* on cream and white: 7.7:1 and 8.4:1 */
  --error-soft:   #FFB4A6;   /* the same job on the forest panels */
  --on-forest:    #FFFFFF;   /* the deliberate dark panels, and only those */
  --on-forest-2:  #AFC0B6;

  /* Lines */
  --rule:         #E7E2D8;
  --rule-warm:    #DED7C9;

  /* Live accent — swapped per brand panel */
  --accent:       var(--copper);

  /* Rhythm */
  --shell:        1240px;
  --gutter:       clamp(20px, 5vw, 56px);
  --section-y:    clamp(72px, 11vh, 140px);

  /* Archivo for display, Manrope for everything read, Cormorant Garamond for
     the one lyrical word in a headline. --mono drove 41 label styles and now
     routes to Manrope, which is what carries the Agent site's small caps. */
  --display: 'Archivo', 'Instrument Sans', -apple-system, sans-serif;
  --serif:   'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --sans:    'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono:    'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}


* { box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

::selection { background: var(--copper); color: var(--green); }

/* Keyboard focus, in the brand's own colours rather than the browser's blue. */
:focus-visible {
  outline: 2px solid var(--copper);
  outline-offset: 3px;
  border-radius: 2px;
}
.on-cream :focus-visible { outline-color: var(--copper-deep); }
.on-cream .pcard.feature :focus-visible { outline-color: var(--copper); }

/* ---------- Type primitives ---------- */

.display {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.02;
  margin: 0;
}
.h1 { font-size: clamp(40px, 6.8vw, 86px); }
.h2 { font-size: clamp(32px, 4.6vw, 60px); }
.h3 { font-size: clamp(23px, 2.3vw, 31px); line-height: 1.15; }

.eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 22px;
  color: var(--copper);
}
.eyebrow::before {
  content: "";
  width: 26px;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}

.lede {
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.62;
  color: var(--muted-dark);
  max-width: 56ch;
}
.on-cream .lede { color: var(--text-muted); }
.lede b { color: var(--copper); font-weight: 600; }
.on-cream .lede b { color: var(--copper-deep); }

/* ---------- Layout ---------- */

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

section { position: relative; }
.band { padding-block: var(--section-y); }

/* The alternate band. It used to be the light exception on a dark page; now it
   is the slightly deeper of two light grounds, which is the rhythm the Agent
   site keeps — paper, wash, paper, wash. */
.on-cream {
  background: var(--wash);
  color: var(--text);
}
.on-cream .eyebrow { color: var(--copper-deep); }

/* Forest is now something a section opts into rather than the default. Used for
   the few panels that should carry weight; everything inside flips back to the
   light-on-dark colours the file already had names for. */
.on-forest {
  background: var(--forest);
  color: var(--on-forest);
}
.on-forest h1, .on-forest h2, .on-forest h3, .on-forest .display { color: var(--on-forest); }
.on-forest .lede, .on-forest p { color: var(--on-forest-2); }
.on-forest .eyebrow { color: var(--bronze-soft); }

.grain::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.32'/%3E%3C/svg%3E");
}

/* ---------- Scroll progress ---------- */

.progress {
  position: fixed;
  inset: 0 auto auto 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--copper), var(--gold));
  z-index: 90;
}

/* ---------- Header ---------- */

.site-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 80;
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease), backdrop-filter 0.4s;
  border-bottom: 1px solid transparent;
}
.site-head.is-stuck {
  background: rgba(247,245,240,0.86);
  backdrop-filter: blur(18px) saturate(140%);
  border-bottom-color: rgba(138,84,36,0.18);
}
.head-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  height: 78px;
  transition: height 0.4s var(--ease);
}
.site-head.is-stuck .head-inner { height: 64px; }

.brandmark {
  display: inline-flex;
  align-items: center;
  gap: 13px;
  color: var(--copper);
  flex: none;
}
.brandmark svg { width: 30px; height: 30px; flex: none; }
.brandmark .word {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  color: var(--on-dark);
  line-height: 1;
}
.brandmark .suffix {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted-dark);
  display: block;
  margin-top: 5px;
}

.nav { display: flex; align-items: center; gap: clamp(16px, 1.9vw, 30px); }
.nav a {
  font-size: 13.5px;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--muted-dark);
  position: relative;
  padding-block: 6px;
  transition: color 0.25s;
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--copper);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform 0.4s var(--ease);
}
.nav a:hover { color: var(--on-dark); }
.nav a:hover::after { transform: scaleX(1); transform-origin: 0 50%; }
.nav a.nav-portal { color: var(--muted-dark); }
.nav a.nav-portal:hover { color: var(--on-dark); }

/* Solid forest, 14px, sentence case — the Agent site's primary button. The
   copper gradient pill it replaces was built to glow against a near-black hero;
   on paper it read as the loudest thing on the page, which a button on a page
   of writing should not be. */
.btn {
  --btn-bg: var(--forest);
  --btn-fg: var(--on-forest);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 24px;
  border-radius: 14px;
  border: 1px solid transparent;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.005em;
  text-transform: none;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  flex: none;
  white-space: nowrap;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), background 0.3s;
  will-change: transform;
}
.btn span { position: relative; z-index: 1; }
.btn:hover { box-shadow: 0 10px 30px rgba(18,41,31,0.18); }
.btn:active { transform: scale(0.98); }
.btn .arrow { transition: transform 0.35s var(--ease); }
.btn:hover .arrow { transform: translateX(4px); }

.btn.ghost {
  --btn-bg: var(--surface);
  --btn-fg: var(--text);
  border-color: var(--rule);
}
.btn.ghost:hover { border-color: var(--copper); color: var(--copper); box-shadow: none; }
.on-cream .btn.ghost { --btn-fg: var(--text); border-color: var(--rule-warm); }
.on-cream .btn.ghost:hover { border-color: var(--copper-deep); color: var(--copper-deep); }
/* On the few forest panels the pair swaps over: white fill leads, forest reads
   as the quiet one. */
.on-forest .btn { --btn-bg: var(--surface); --btn-fg: var(--forest); }
.on-forest .btn.ghost { --btn-bg: transparent; --btn-fg: var(--on-forest); border-color: rgba(255,255,255,0.3); }

.burger {
  display: none;
  width: 44px; height: 44px;
  border: 1px solid rgba(20,26,23,0.3);
  border-radius: 50%;
  background: none;
  cursor: pointer;
  position: relative;
}
.burger i {
  position: absolute;
  left: 13px; right: 13px;
  height: 1.5px;
  background: var(--on-dark);
  transition: transform 0.35s var(--ease), opacity 0.2s;
}
.burger i:nth-child(1) { top: 18px; }
.burger i:nth-child(2) { top: 24px; }
.burger.is-open i:nth-child(1) { transform: translateY(3px) rotate(45deg); }
.burger.is-open i:nth-child(2) { transform: translateY(-3px) rotate(-45deg); }

.drawer {
  position: fixed;
  inset: 0;
  z-index: 79;
  /* Paper, not ink. The links inside are ink now, and a dark drawer made the
     whole mobile menu invisible — the kind of thing that only shows up on a
     phone, which is where most of this site is read. */
  background: rgba(247,245,240,0.98);
  backdrop-filter: blur(20px);
  display: grid;
  place-content: center;
  gap: 8px;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
.drawer.is-open { opacity: 1; visibility: visible; }
.drawer a {
  font-family: var(--display);
  font-weight: 600;
  font-size: 30px;
  padding-block: 10px;
  transform: translateY(14px);
  opacity: 0;
  transition: transform 0.5s var(--ease), opacity 0.5s var(--ease);
}
.drawer.is-open a { transform: none; opacity: 1; }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-top: 120px;
  padding-bottom: 90px;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 80% 0%, rgba(138,84,36,0.13), transparent 58%),
    radial-gradient(90% 70% at 0% 100%, rgba(36,64,47,0.75), transparent 60%),
    var(--ink);
}
#constellation {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.9;
}
.hero .shell { position: relative; z-index: 2; }

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(36px, 6vw, 90px);
  align-items: end;
}

.hero h1 .line { display: block; overflow: hidden; }
.hero h1 .line > span {
  display: block;
  transform: translateY(105%);
  animation: rise 1s var(--ease) forwards;
}
.hero h1 .line:nth-child(2) > span { animation-delay: 0.09s; }
.hero h1 .line:nth-child(3) > span { animation-delay: 0.18s; }
@keyframes rise { to { transform: none; } }

/* The one lyrical word, in Cormorant Garamond italic — the move the Agent site
   makes with "Own the postcode." A serif among the Archivo is what stops a
   headline reading as a slab, and it does the job the copper gradient used to:
   drawing the eye to the word the sentence turns on.

   Optically larger than the sans around it, because a serif at the same em
   reads smaller; and the descender needs a little room or the italic f clips. */
.hero h1 em,
.display em {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: 1.12em;
  line-height: 0.9;
  letter-spacing: -0.005em;
  color: var(--copper);
  padding-right: 0.06em;
  background: none;
  -webkit-text-fill-color: currentColor;
}
@keyframes molten {
  from { background-position: 0% 50%; }
  to { background-position: 100% 50%; }
}

.hero-aside {
  border-left: 1px solid rgba(20,26,23,0.2);
  padding-left: clamp(20px, 3vw, 34px);
  opacity: 0;
  animation: fade 1s var(--ease) 0.45s forwards;
}
@keyframes fade { to { opacity: 1; } }

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 34px;
}
/* The £-CTA should be the brightest object in the hero before anyone hovers it. */
.hero-cta .btn:not(.ghost) {
  box-shadow: 0 8px 30px rgba(138,84,36,0.25);
}
.hero-cta .btn:not(.ghost)::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,0.38) 50%, transparent 70%);
  transform: translateX(-120%);
  animation: sheen 1.1s var(--ease) 1.4s 1;
}
@keyframes sheen { to { transform: translateX(120%); } }

.hero-note {
  margin: 18px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.hero-note b { color: var(--copper); font-weight: 500; }

.hero-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin-top: 26px;
  padding-top: 26px;
  border-top: 1px solid rgba(20,26,23,0.18);
}
.hero-meta div { min-width: 88px; }
.hero-meta .n {
  font-family: var(--display);
  font-weight: 600;
  background: linear-gradient(100deg, var(--copper), var(--gold));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-size: 34px;
  line-height: 1;
}
.hero-meta .k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
  margin-top: 9px;
  display: block;
}

.scroll-hint {
  position: absolute;
  left: var(--gutter);
  bottom: 26px;
  z-index: 2;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted-dark);
  display: flex;
  align-items: center;
  gap: 12px;
}
.scroll-hint .rail {
  width: 54px; height: 1px;
  background: rgba(20,26,23,0.3);
  position: relative;
  overflow: hidden;
}
.scroll-hint .rail::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--copper);
  transform: translateX(-100%);
  animation: sweep 2.4s var(--ease) infinite;
}
@keyframes sweep {
  0% { transform: translateX(-100%); }
  60%, 100% { transform: translateX(100%); }
}

/* ---------- Marquee ---------- */

.marquee {
  border-block: 1px solid rgba(138,84,36,0.16);
  background: var(--wash);
  overflow: hidden;
  padding-block: 20px;
  display: flex;
  gap: 0;
  white-space: nowrap;
}
.marquee ul {
  display: flex;
  align-items: center;
  gap: 46px;
  margin: 0;
  padding: 0 23px;
  list-style: none;
  animation: slide 38s linear infinite;
}
.marquee li {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
  display: flex;
  align-items: center;
  gap: 46px;
}
.marquee li::after {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--copper);
  opacity: 0.6;
}
@keyframes slide { to { transform: translateX(-100%); } }
.marquee:hover ul { animation-play-state: paused; }

/* ---------- Section headers ---------- */

.sec-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.78fr);
  gap: clamp(24px, 5vw, 70px);
  align-items: end;
  margin-bottom: clamp(40px, 6vw, 68px);
}

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

.svc-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
}
.svc {
  position: relative;
  padding: clamp(26px, 3vw, 40px);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  background: transparent;
  overflow: hidden;
  transition: background 0.45s var(--ease);
}
.svc::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background: var(--copper-deep);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.5s var(--ease);
}
.svc:hover { background-color: var(--white); }
.svc:hover::before { transform: scaleX(1); }
.svc .num {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  color: var(--copper-deep);
}
.svc .ico {
  width: 34px; height: 34px;
  margin: 20px 0 22px;
  color: var(--green);
  transition: transform 0.5s var(--ease), color 0.3s;
}
.svc:hover .ico { transform: translateY(-3px); color: var(--copper-deep); }
.svc h3 {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}
.svc p { margin: 0; font-size: 15px; line-height: 1.62; color: var(--text-muted); }
.svc ul {
  margin: 18px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
.svc ul li {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-soft);
  border: 1px solid var(--rule-warm);
  border-radius: 999px;
  padding: 5px 10px;
}

/* A service card given the full width of the ruled grid — used for booking,
   which needs more room than a third of a row to say anything useful. */
.svc.wide { grid-column: 1 / -1; }
.svc.wide > p { max-width: 62ch; }
.svc-more {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 48px);
}
.svc-more h4 {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--copper-deep);
  margin: 0 0 8px;
}
.svc-more p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--text-muted); }
@media (max-width: 820px) { .svc-more { grid-template-columns: minmax(0, 1fr); gap: 20px; } }

/* ---------- Brands ---------- */

.brands { background: var(--green); overflow: hidden; }
.brands::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 60% at 15% 0%, rgba(138,84,36,0.12), transparent 65%);
  pointer-events: none;
}
.brands .shell { position: relative; z-index: 1; }

.brand-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 34px;
}
.brand-tab {
  border: 1px solid rgba(20,26,23,0.25);
  background: transparent;
  border-radius: 999px;
  padding: 11px 20px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  letter-spacing: 0.03em;
  color: var(--muted-dark);
  transition: color 0.3s, border-color 0.3s, background 0.3s;
}
.brand-tab .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
  transition: opacity 0.3s, transform 0.3s;
}
.brand-tab:hover { color: var(--on-dark); border-color: rgba(138,84,36,0.5); }
.brand-tab[aria-selected="true"] {
  color: var(--ink);
  background: var(--accent);
  border-color: var(--accent);
}
.brand-tab[aria-selected="true"] .dot { opacity: 1; transform: scale(1.25); }

.brand-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(30px, 5vw, 66px);
  align-items: center;
  border: 1px solid rgba(20,26,23,0.16);
  border-radius: 4px;
  background: rgba(20,26,23,0.45);
  padding: clamp(26px, 3.4vw, 52px);
}
.brand-panel[hidden] { display: none; }
.brand-panel.is-entering .brand-copy > *,
.brand-panel.is-entering .device { animation: panelIn 0.6s var(--ease) both; }
.brand-panel.is-entering .brand-copy > *:nth-child(2) { animation-delay: 0.05s; }
.brand-panel.is-entering .brand-copy > *:nth-child(3) { animation-delay: 0.1s; }
.brand-panel.is-entering .brand-copy > *:nth-child(4) { animation-delay: 0.15s; }
.brand-panel.is-entering .brand-copy > *:nth-child(5) { animation-delay: 0.2s; }
@keyframes panelIn {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

.brand-role {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
}
.brand-role .pip {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 currentColor;
  animation: pulse 2.6s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(138,84,36,0.5); }
  70% { box-shadow: 0 0 0 9px rgba(138,84,36,0); }
  100% { box-shadow: 0 0 0 0 rgba(138,84,36,0); }
}

.brand-copy h3 {
  font-family: var(--display);
  font-size: clamp(28px, 3.4vw, 42px);
  font-weight: 700;
  margin: 0 0 14px;
  letter-spacing: -0.015em;
}
.brand-copy p { color: var(--muted-dark); margin: 0 0 22px; max-width: 46ch; }
.brand-copy .feats {
  list-style: none;
  margin: 0 0 26px;
  padding: 0;
  display: grid;
  gap: 11px;
}
.brand-copy .feats li {
  font-size: 14.5px;
  color: var(--on-dark);
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.brand-copy .feats li::before {
  content: "";
  flex: none;
  width: 14px; height: 1px;
  background: var(--accent);
  margin-top: 12px;
}
.brand-links { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.brand-links .btn {
  --btn-bg: var(--accent);
  --btn-bg: linear-gradient(135deg,
    color-mix(in srgb, var(--accent) 72%, #08150F),
    var(--accent) 55%,
    color-mix(in srgb, var(--accent) 72%, #FFFFFF));
}
.link-quiet {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-dark);
  border-bottom: 1px solid rgba(20,26,23,0.3);
  padding-bottom: 3px;
  transition: color 0.3s, border-color 0.3s;
}
.link-quiet:hover { color: var(--accent); border-color: var(--accent); }

/* Device mock */
.device {
  position: relative;
  border-radius: 14px;
  border: 1px solid rgba(20,26,23,0.22);
  background-color: var(--ink);
  background-image: linear-gradient(160deg, rgba(36,64,47,0.9), rgba(20,26,23,0.95));
  box-shadow: 0 30px 70px rgba(0,0,0,0.45);
  overflow: hidden;
  transform-style: preserve-3d;
  transition: transform 0.5s var(--ease);
}
.device.is-live, .btn.is-live { transition: none; }
.device .bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 12px 15px;
  border-bottom: 1px solid rgba(20,26,23,0.16);
  background: rgba(20,26,23,0.6);
}
.device .bar i {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: rgba(20,26,23,0.3);
}
.device .bar i:first-child { background: var(--accent); }
.device .bar .url {
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--muted-dark);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.device .screen { padding: 20px; display: grid; gap: 14px; }
.mock-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.mock-card {
  border: 1px solid rgba(20,26,23,0.16);
  border-radius: 8px;
  padding: 12px;
  background: rgba(255,255,255,0.03);
}
.mock-card .lab {
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.mock-card .val {
  font-family: var(--display);
  font-weight: 600;
  font-size: 20px;
  margin-top: 7px;
  color: var(--on-dark);
}
.mock-chart {
  height: 108px;
  border: 1px solid rgba(20,26,23,0.16);
  border-radius: 8px;
  padding: 12px;
  display: flex;
  align-items: flex-end;
  gap: 6px;
  background: rgba(255,255,255,0.03);
}
.mock-chart span {
  flex: 1;
  border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--accent), rgba(138,84,36,0.18));
  transform-origin: 50% 100%;
  animation: grow 0.9s var(--ease) both;
}
@keyframes grow { from { transform: scaleY(0.05); opacity: 0; } to { transform: none; opacity: 1; } }
.mock-list { display: grid; gap: 9px; }
.mock-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid rgba(20,26,23,0.14);
  border-radius: 8px;
  font-size: 12px;
  color: var(--muted-dark);
  background: rgba(255,255,255,0.02);
}
.mock-line b {
  color: var(--on-dark);
  font-weight: 500;
}
.mock-line .tag {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 3px 8px;
}

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

.steps { display: grid; gap: 0; border-top: 1px solid var(--rule); }
.step {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(16px, 3vw, 40px);
  padding-block: clamp(24px, 3vw, 38px);
  border-bottom: 1px solid var(--rule);
  align-items: start;
  position: relative;
  transition: padding-left 0.45s var(--ease);
}
.step::after {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--copper-deep);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 0.5s var(--ease);
}
.step:hover { padding-left: 18px; }
.step:hover::after { transform: scaleY(1); }
.step .no {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--copper-deep);
  padding-top: 8px;
}
.step h3 { font-family: var(--display); font-weight: 600; font-size: clamp(22px, 2.4vw, 30px); margin: 0; letter-spacing: -0.01em; }
.step p { margin: 0; color: var(--text-muted); font-size: 15.5px; }

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

.proof { background: var(--ink); }
.proof-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px;
  background: rgba(20,26,23,0.16);
  border: 1px solid rgba(20,26,23,0.16);
}
.proof-cell {
  background: var(--ink);
  padding: clamp(24px, 3vw, 38px);
}
.proof-cell .n {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(40px, 5vw, 62px);
  line-height: 1;
  background: linear-gradient(100deg, var(--copper-mid), var(--copper) 55%, var(--gold));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.proof-cell .k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
  margin-top: 14px;
}
.proof-cell p { font-size: 14px; color: var(--muted-dark); margin: 12px 0 0; }

/* ---------- Where we work ---------- */

.local { background: var(--green); overflow: hidden; }
.local::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 55% at 85% 100%, rgba(138,84,36,0.1), transparent 65%);
  pointer-events: none;
}
.local .shell { position: relative; z-index: 1; }
.local-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(16px, 2.2vw, 26px);
}
.where {
  border: 1px solid rgba(20,26,23,0.18);
  border-radius: 6px;
  padding: clamp(24px, 3vw, 40px);
  background: rgba(20,26,23,0.45);
  transition: border-color 0.35s var(--ease), translate 0.35s var(--ease);
}
.where:hover { border-color: rgba(138,84,36,0.45); translate: 0 -2px; }
.where h3 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(21px, 2.1vw, 27px);
  letter-spacing: -0.02em;
  margin: 0 0 10px;
}
.where > p { color: var(--muted-dark); font-size: 15px; line-height: 1.6; margin: 0 0 20px; }
.places {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.places li {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark);
  border: 1px solid rgba(20,26,23,0.3);
  border-radius: 999px;
  padding: 6px 11px;
}
.places li.hub {
  background: var(--copper);
  border-color: var(--copper);
  color: var(--green);
  font-weight: 500;
}

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

.contact { background: var(--ink); }
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(34px, 6vw, 80px);
}
.field { display: grid; gap: 8px; margin-bottom: 18px; }
.field label, .field legend {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
/* A radio group is a fieldset, and a fieldset's legend does not take part in
   the grid its parent sets up — so it needs the gap the grid would have given
   it. Used by the domain question on /free-website. */
.field legend { padding: 0; margin-bottom: 10px; }
.field input, .field select, .field textarea {
  font: inherit;
  font-size: 15px;
  color: var(--on-dark);
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(20,26,23,0.22);
  border-radius: 6px;
  padding: 13px 15px;
  transition: border-color 0.3s, background 0.3s;
  width: 100%;
}
.field textarea { min-height: 132px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--copper);
  background: rgba(255,255,255,0.06);
}
.field select option { background: var(--green); color: var(--on-dark); }
.form-note {
  font-size: 12.5px;
  color: var(--muted-dark);
  margin-top: 14px;
}
/* The two things a form note can be saying. --error is the same red the
   warning emails use. The forest variant exists because a light-background
   red on a dark panel is the mistake this replaced. */
.form-note.is-error { color: var(--error); }
.form-note.is-ok { color: var(--gold); }
.pcard.feature .form-note.is-error,
.on-forest .form-note.is-error { color: var(--error-soft); }
.pcard.feature .form-note.is-ok,
.on-forest .form-note.is-ok { color: var(--on-forest); }
.contact-aside dl { margin: 0; display: grid; gap: 22px; }
.contact-aside dt {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
  margin-bottom: 7px;
}
.contact-aside dd { margin: 0; font-size: 17px; }
.contact-aside dd a { border-bottom: 1px solid rgba(138,84,36,0.4); padding-bottom: 2px; }
.contact-aside dd a:hover { color: var(--copper); }


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

.pick-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
  margin: 0 0 4px;
}
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin: 12px 0 26px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(20,26,23,0.3);
  background: transparent;
  color: var(--muted-dark);
  border-radius: 999px;
  padding: 11px 18px;
  font-size: 13.5px;
  cursor: pointer;
  transition: color 0.25s, border-color 0.25s, background 0.25s, transform 0.25s var(--ease);
}
.chip::before {
  content: "+";
  font-family: var(--mono);
  font-size: 12px;
  color: var(--copper);
  transition: transform 0.3s var(--ease);
}
.chip:hover { color: var(--on-dark); border-color: rgba(138,84,36,0.55); translate: 0 -1px; }
.chip[aria-pressed="true"] {
  background: var(--copper);
  border-color: var(--copper);
  color: var(--green);
}
.chip[aria-pressed="true"]::before { content: "\2713"; color: var(--green); transform: scale(1.1); }
.field label .opt {
  opacity: 0.55;
  text-transform: none;
  letter-spacing: 0.06em;
}
.contact .field textarea { min-height: 96px; }


.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}
.contact-aside .card {
  border: 1px solid rgba(20,26,23,0.18);
  border-radius: 6px;
  padding: clamp(22px, 2.4vw, 32px);
  background: rgba(255,255,255,0.03);
}
.next {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  counter-reset: n;
  display: grid;
  gap: 16px;
}
.next li {
  counter-increment: n;
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 14px;
  align-items: baseline;
  font-size: 15px;
  color: var(--muted-dark);
}
.next li::before {
  content: "0" counter(n);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--copper);
}
.next li b { color: var(--on-dark); font-weight: 500; display: block; }

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

.site-foot {
  background: var(--ink);
  border-top: 1px solid rgba(20,26,23,0.16);
  padding-block: 40px 34px;
}
.foot-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 40px;
  align-items: center;
  justify-content: space-between;
}
.foot-inner small, .foot-inner a {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.foot-links { display: flex; flex-wrap: wrap; gap: 22px; }
.foot-links a:hover { color: var(--copper); }

/* Companies Act 2006 s.82 wants the registered name, number, place of
   registration and registered office on the site. Its own full-width row, in
   sentence case: a postal address set in 10.5px uppercase at 0.14em tracking
   is technically disclosed and practically unreadable. Two classes so it beats
   `.foot-inner small` on specificity. */
.foot-inner small.foot-legal {
  flex-basis: 100%;
  text-transform: none;
  letter-spacing: 0.02em;
  font-size: 11px;
  line-height: 1.65;
  opacity: 0.68;
}


/* ---------- Worth calculator ---------- */

.calc-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
.calc-controls .row { margin-bottom: 30px; }
.calc-controls .lab {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 12px;
}
.calc-controls .lab .klab {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.calc-controls .lab output {
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  color: var(--copper-deep);
}
input[type="range"].slider {
  width: 100%;
  appearance: none;
  -webkit-appearance: none;
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--copper-deep) var(--fill, 40%), var(--rule-warm) var(--fill, 40%));
}
input[type="range"].slider:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 5px rgba(138,84,36,0.35), 0 3px 14px rgba(138,84,36,0.45);
}
input[type="range"].slider:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 5px rgba(138,84,36,0.35);
}
input[type="range"].slider::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--copper-mid), var(--gold));
  border: 3px solid var(--white);
  box-shadow: 0 3px 14px rgba(138,84,36,0.45);
  cursor: grab;
}
input[type="range"].slider::-moz-range-thumb {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--copper-mid), var(--gold));
  border: 3px solid var(--white);
  cursor: grab;
}
.calc-out {
  background: var(--forest);
  color: var(--on-forest);
  border-radius: 12px;
  padding: clamp(28px, 3.5vw, 44px);
  position: relative;
  overflow: hidden;
  box-shadow: 0 30px 70px rgba(18,41,31,0.35);
}
.calc-out::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(90% 90% at 85% 10%, rgba(138,84,36,0.22), transparent 60%);
  pointer-events: none;
}
.calc-out > * { position: relative; }
.calc-out .k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.calc-out .big {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(44px, 5.5vw, 72px);
  line-height: 1;
  margin: 10px 0 6px;
  letter-spacing: -0.03em;
  background: linear-gradient(100deg, var(--copper), var(--gold));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.calc-out .sub { color: var(--muted-dark); font-size: 15px; margin: 0 0 20px; }
.calc-out .payback {
  border-top: 1px solid rgba(20,26,23,0.25);
  padding-top: 18px;
  margin: 18px 0 22px;
  font-size: 16px;
}
.calc-out .payback b { color: var(--gold); font-weight: 600; }

/* ---------- Quotes ---------- */

.quotes { background: var(--green); }
.quote-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}
.qcard {
  border: 1px solid rgba(20,26,23,0.18);
  border-radius: 10px;
  background: rgba(20,26,23,0.45);
  padding: clamp(22px, 2.5vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 18px;
  transition: translate 0.35s var(--ease), border-color 0.35s;
}
.qcard:hover { translate: 0 -4px; border-color: rgba(138,84,36,0.45); }
.qcard .stars { color: var(--gold); letter-spacing: 3px; font-size: 14px; }
.qcard blockquote, .qcard p { margin: 0; font-size: 15.5px; line-height: 1.6; flex: 1; }
.qcard h3 { margin: 0; letter-spacing: -0.02em; }
.qcard .stars { font-size: 9px; letter-spacing: 4px; }
.qcard .who {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-dark);
}

/* ---------- FAQ ---------- */

.faq details { border-bottom: 1px solid rgba(20,26,23,0.16); }
.faq summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 4px;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(16px, 1.6vw, 19px);
  transition: color 0.25s;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  font-family: var(--mono);
  font-size: 20px;
  color: var(--copper);
  transition: transform 0.3s var(--ease);
  flex: none;
}
.faq details[open] summary { color: var(--copper); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p {
  margin: 0;
  padding: 0 4px 20px;
  color: var(--muted-dark);
  max-width: 70ch;
}

/* ---------- Sticky CTA ---------- */

.sticky-cta {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 70;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* Follows .btn onto forest and sentence case. It was the last copper pill on
     the site, and a fixed one at that — the one element a reader cannot scroll
     away from should not also be the loudest. */
  background: var(--forest);
  color: var(--on-forest);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.005em;
  text-transform: none;
  padding: 13px 22px;
  border-radius: 14px;
  box-shadow: 0 12px 34px rgba(18,41,31,0.22), 0 2px 8px rgba(18,41,31,0.12);
  transform: translateY(120px);
  visibility: hidden;
  transition: transform 0.45s var(--ease), visibility 0.45s;
}
.sticky-cta.show { transform: none; visibility: visible; }
@media (max-width: 640px) {
  /* Full width and a size a thumb can find: on a phone this is the button. */
  .sticky-cta { left: 14px; right: 14px; bottom: 14px; justify-content: center; padding: 15px 18px;
                font-size: 15px; max-width: none; }
  .sticky-cta .long { display: none; }
  body.has-sticky-cta { padding-bottom: 76px; }
  body.has-sticky-cta .cookie-banner { bottom: 82px; }
  .cookie-banner { padding: 12px 14px; gap: 10px 14px; border-radius: 12px; }
  .cookie-banner p { font-size: 13.5px; flex-basis: 100%; }
  .cookie-banner .btn { padding: 10px 18px; }
}


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

#pricing { border-top: 1px solid var(--rule-warm); }

.price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: 14px;
}
.pcard {
  position: relative;
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--white);
  padding: clamp(24px, 2.8vw, 36px);
  display: flex;
  flex-direction: column;
  gap: 16px;
  transition: translate 0.35s var(--ease), box-shadow 0.35s var(--ease), border-color 0.35s;
}
.pcard:hover {
  translate: 0 -4px;
  border-color: var(--rule-warm);
  box-shadow: 0 24px 60px rgba(18,41,31,0.10);
}
.pcard.feature {
  background: var(--forest);
  color: var(--on-forest);
  border-color: transparent;
  box-shadow: 0 26px 64px rgba(18,41,31,0.28);
}
.pcard.feature::before {
  content: "Most popular";
  position: absolute;
  top: -11px;
  left: clamp(24px, 2.8vw, 36px);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  background: var(--copper);
  color: var(--green);
  padding: 4px 12px;
  border-radius: 999px;
}
.pcard h3 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.02em;
  margin: 0;
}
.pcard .from {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* The dark treatment without the "Most popular" badge, for a card that is the
   important half of a pair rather than a product tier. */
.pcard.feature.no-badge::before { content: none; }
.pcard.feature .from { color: var(--muted-dark); }
.pcard .amount {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(34px, 3.6vw, 46px);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--copper-deep);
}
.pcard.feature .amount {
  background: linear-gradient(100deg, var(--copper), var(--gold));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.pcard .amount small {
  display: block;
  font-family: var(--sans);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: normal;
  color: var(--text-muted);
  margin-top: 8px;
}
.pcard.feature .amount small { color: var(--muted-dark); }
.pcard ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  flex: 1;
}
/* Block, not flex. As a flex container every child element became its own
   column, so a <li> with a bold lead and then text rendered as two ragged
   columns rather than a sentence. It went unnoticed while every bullet on the
   site was a single phrase; it breaks the moment one has emphasis in it. The
   dash is positioned rather than being a flex sibling, which leaves the
   geometry identical — 13px rule, 11px gap, 11px down. */
.pcard ul li {
  position: relative;
  padding-left: 24px;
  font-size: 14.5px;
  color: var(--text-muted);
}
.pcard.feature ul li { color: var(--on-dark); }
/* --muted-dark is a grey chosen for cream backgrounds; on the forest card it
   lands at 2.4:1, which is unreadable. The dark panels get their own muted
   tone, as every other piece of text on them already does. */
.pcard.feature .form-note { color: rgba(255, 255, 255, 0.78); }
/* --gold, --copper and --copper-deep all resolve to #8A5424, which is a cream
   background's accent: 2.5:1 on forest. Bold on a dark panel is weight and
   white, exactly like the list items above it. */
.pcard.feature .form-note b { color: var(--on-forest); }
.pcard ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 11px;
  width: 13px;
  height: 1px;
  background: var(--copper-deep);
}
.pcard.feature ul li::before { background: var(--copper); }
.price-note {
  margin: 22px 0 0;
  font-size: 14.5px;
  color: var(--text-muted);
  text-align: center;
}
.price-note b { color: var(--copper-deep); font-weight: 600; }

/* The second way to buy the same thing, inside a price card. */
.alt-buy {
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--rule-warm);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}
.alt-buy b { color: var(--copper-deep); font-weight: 600; }
.alt-buy a { color: var(--copper-deep); border-bottom: 1px solid currentColor; white-space: nowrap; }
.pcard.feature .alt-buy { border-top-color: rgba(255,255,255,.18); color: var(--muted-dark); }
.pcard.feature .alt-buy b,
.pcard.feature .alt-buy a { color: var(--copper); }

/* ---------- Mid-page CTA rows ---------- */

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 16px 22px;
  margin-top: clamp(28px, 3.5vw, 44px);
  padding-top: clamp(24px, 3vw, 34px);
  border-top: 1px solid var(--rule);
  text-align: center;
}
.band:not(.on-cream) .cta-row { border-top-color: rgba(20,26,23,0.18); }
.cta-row p {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(17px, 1.9vw, 22px);
  letter-spacing: -0.02em;
}
.cta-row .sub {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 14.5px;
  color: var(--text-muted);
}
.band:not(.on-cream) .cta-row .sub { color: var(--muted-dark); }

/* ---------- Founder block ---------- */

.founder {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid rgba(20,26,23,0.2);
}
.founder .avatar {
  width: 54px;
  height: 54px;
  flex: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 21px;
  color: var(--green);
  background: linear-gradient(135deg, var(--copper-mid), var(--gold));
}
.founder p { margin: 0; font-size: 14.5px; color: var(--muted-dark); }
.founder p b { color: var(--on-dark); font-weight: 600; display: block; margin-bottom: 3px; }

/* Proof strip sitting right above the submit button */
.mini-proof {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin: 4px 0 20px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.mini-proof span { display: inline-flex; align-items: center; gap: 8px; }
.mini-proof span::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--copper);
}

/* ---------- Portal demo (in How we work) ---------- */

.portal-demo { margin-top: clamp(30px, 4vw, 48px); }
.portal-demo .device { max-width: 560px; margin-inline: auto; }
.demo-bar {
  height: 8px;
  border-radius: 999px;
  background: rgba(255,255,255,0.22);
  border: 1px solid rgba(20,26,23,0.3);
  overflow: hidden;
  margin-bottom: 4px;
}
.demo-bar i {
  display: block;
  height: 100%;
  width: 64%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--copper-mid), var(--copper) 60%, var(--gold));
}

/* ---------- Reveal ---------- */

#enquiry { scroll-margin-top: 100px; }

.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.85s var(--ease), transform 0.85s var(--ease);
  transition-delay: var(--d, 0s);
}
.reveal.is-in { opacity: 1; transform: none; }

/* ---------- Cursor ---------- */

.cursor {
  position: fixed;
  top: 0; left: 0;
  width: 26px; height: 26px;
  border: 1px solid rgba(138,84,36,0.7);
  border-radius: 50%;
  pointer-events: none;
  z-index: 100;
  transform: translate3d(-100px, -100px, 0);
  transition: width 0.3s var(--ease), height 0.3s var(--ease), background 0.3s, border-color 0.3s;
  mix-blend-mode: difference;
}
.cursor.is-big { width: 54px; height: 54px; background: rgba(138,84,36,0.16); }
@media (hover: none), (pointer: coarse) { .cursor { display: none; } }

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

@media (max-width: 1120px) {
  .svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 1020px) {
  .hero-grid, .sec-head, .brand-panel, .contact-grid, .local-grid, .calc-grid { grid-template-columns: minmax(0, 1fr); }
  .quote-grid { grid-template-columns: minmax(0, 1fr); }
  .hero-aside { border-left: 0; padding-left: 0; border-top: 1px solid rgba(20,26,23,0.2); padding-top: 26px; }
  .step { grid-template-columns: 60px minmax(0, 1fr); }
  .step p { grid-column: 2; }
}
@media (max-width: 1184px) {
  .nav, .head-inner > .btn { display: none; }
  .burger { display: block; }
}
@media (max-width: 820px) {
  .svc-grid { grid-template-columns: minmax(0, 1fr); }
  .field-row { grid-template-columns: minmax(0, 1fr); gap: 0; }
  body { font-size: 16px; }
  .mock-row { grid-template-columns: 1fr 1fr; }
  .mock-row .mock-card:last-child { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .hero h1 .line > span { transform: none; }
  .hero-aside { opacity: 1; }
}

/* ==========================================================================
   /websites/ — the dedicated websites page.
   Ground rules: .svc-grid, .steps and .pcard are cream-band furniture, .faq is
   dark-band furniture. Everything below is built for the ground it sits on.
   ========================================================================== */

/* Two cream bands in a row need a rule between them, same as #worth/#pricing. */
.hairline { border-top: 1px solid var(--rule); }

.page-hero {
  padding-block: clamp(104px, 15vh, 176px) clamp(60px, 9vh, 100px);
  border-bottom: 1px solid var(--green-line);
  background:
    radial-gradient(72% 92% at 84% 0%, rgba(138,84,36,0.11), transparent 62%),
    radial-gradient(58% 78% at 0% 104%, rgba(240,237,230,0.8), transparent 66%);
}
.page-hero .h1 { margin: 0 0 clamp(20px, 2.6vw, 30px); }
.page-hero .hero-cta { margin-top: clamp(26px, 3.4vw, 38px); }

.crumb {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted-dark);
  margin: 0 0 clamp(18px, 2.4vw, 26px);
}
.crumb a { color: var(--copper); }
.crumb a:hover { color: var(--gold); }
.crumb span { margin: 0 8px; opacity: 0.5; }

.lede.wide { max-width: 70ch; }

.quickfacts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin-top: clamp(40px, 5.5vw, 64px);
  background: var(--green-line);
  border: 1px solid var(--green-line);
}
.quickfacts > div {
  background: var(--ink);
  padding: clamp(18px, 2.2vw, 26px);
}
.quickfacts .n {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(26px, 3vw, 36px);
  line-height: 1;
  background: linear-gradient(100deg, var(--copper-mid), var(--copper) 55%, var(--gold));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.quickfacts .k {
  display: block;
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
@media (max-width: 820px) { .quickfacts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.two-up {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(16px, 2.4vw, 28px);
  align-items: start;
}
@media (max-width: 900px) { .two-up { grid-template-columns: minmax(0, 1fr); } }

/* Dark-band panels — used on #hosting. */
.panel-list {
  border: 1px solid var(--green-line);
  border-radius: 12px;
  padding: clamp(24px, 3vw, 36px);
  background: rgba(255,255,255,0.02);
}
.panel-list h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(19px, 2vw, 23px);
  margin: 0 0 18px;
  letter-spacing: -0.01em;
}
.ticks { margin: 0; padding: 0; list-style: none; display: grid; gap: 14px; }
.ticks li {
  position: relative;
  padding-left: 28px;
  font-size: 15px;
  line-height: 1.58;
  color: var(--muted-dark);
}
.ticks li b { color: var(--on-dark); font-weight: 600; }
.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 13px;
  height: 8px;
  border-left: 2px solid var(--copper);
  border-bottom: 2px solid var(--copper);
  transform: rotate(-45deg);
}
/* The "what you won't get" column — same rhythm, a struck-through mark. */
.ticks.cross li::before {
  width: 12px;
  height: 12px;
  top: 6px;
  border: 0;
  transform: none;
  background:
    linear-gradient(to bottom right, transparent 44%, var(--muted-dark) 44%, var(--muted-dark) 56%, transparent 56%),
    linear-gradient(to bottom left,  transparent 44%, var(--muted-dark) 44%, var(--muted-dark) 56%, transparent 56%);
}
.foot-note {
  margin: 22px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--green-line);
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-soft);
}

/* ==========================================================================
   /hosting/ — the sign-up page.
   Dark-band furniture: the price block sits in .page-hero, so it is styled for
   the ink background rather than the cream one. The number itself is written in
   by JS from HQ's config, which is why there is a dash in the markup and no
   price anywhere in this file.
   ========================================================================== */

/* Said out loud rather than left to the default: this stylesheet already sets
   display on enough things that an inherited `display` has beaten [hidden]
   twice before (see .brand-panel and .cap-go). These must stay hidden. */
[data-hosting-priceblock][hidden],
[data-hosting-trialonly][hidden],
[data-hosting-notrial][hidden],
#hosting-form[hidden],
#hosting-closed[hidden] { display: none; }

.host-price {
  margin-top: clamp(28px, 4vw, 40px);
  padding: clamp(20px, 2.6vw, 28px) clamp(22px, 3vw, 32px);
  border: 1px solid var(--green-line);
  border-radius: 14px;
  background: rgba(240,237,230,0.5);
  max-width: 62ch;
}
.host-price-main {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
}
.host-amount {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(44px, 6vw, 68px);
  line-height: 1;
  letter-spacing: -0.03em;
  background: linear-gradient(100deg, var(--copper), var(--gold));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  /* Reserve the width of a two-digit price so the line does not jump when the
     dash is replaced by the real number a moment later. */
  min-width: 2.6ch;
}
.host-per {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(17px, 1.7vw, 21px);
  color: var(--on-dark);
}
.host-price-note {
  margin: 10px 0 0;
  font-size: 15px;
  color: var(--muted-dark);
}
.host-price-note a { color: var(--copper); }

/* Used on the confirmation page, where a tight list of plain statements reads
   better than the numbered .next sequence. */
.card ul.plain {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}
.card ul.plain li {
  padding-left: 16px;
  position: relative;
  font-size: 15px;
  color: var(--text-muted);
}
.card ul.plain li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--copper-mid);
}
.card ul.plain b { color: var(--text); }

@media (max-width: 640px) {
  /* At 375px the price and "a month" want to stay on one line rather than
     stacking, so the number comes down a little. */
  .host-amount { font-size: 40px; }
  .host-price { padding: 18px 18px; }
}

/* ==========================================================================
   /terms/ — generated from Markdown by render-terms.py in the foundation-hq
   repo. Long-form reading on the cream band: one measured column, generous
   leading, numbered headings that stay findable when somebody is looking for
   clause 6 rather than reading the lot.
   ========================================================================== */

.terms-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  margin: clamp(20px, 2.6vw, 28px) 0 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.terms-meta b { color: var(--on-dark); font-weight: 500; }

.terms-draft {
  margin: clamp(22px, 3vw, 30px) 0 0;
  padding: 16px 20px;
  max-width: 66ch;
  border: 1px solid var(--copper-mid);
  border-radius: 12px;
  background: rgba(184, 115, 51, 0.12);
  font-size: 15px;
  color: var(--on-dark);
}
.terms-draft a { color: var(--gold); }

.terms-body {
  max-width: 68ch;
  font-size: 16px;
  line-height: 1.75;
  color: var(--text-muted);
}
.terms-body h2 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(21px, 2.1vw, 26px);
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--text);
  margin: clamp(38px, 4.5vw, 52px) 0 12px;
  /* Scroll-margin so a link to #clause-6 does not park the heading under the
     fixed header. */
  scroll-margin-top: 96px;
}
.terms-body h2:first-child { margin-top: 0; }
.terms-body h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 18px;
  color: var(--text);
  margin: 28px 0 8px;
}
.terms-body p { margin: 0 0 16px; }
.terms-body ul,
.terms-body ol { margin: 0 0 16px; padding-left: 22px; }
.terms-body li { margin-bottom: 8px; }
.terms-body b { color: var(--text); }
.terms-body a { color: var(--copper-deep); text-underline-offset: 3px; }

.terms-foot {
  max-width: 68ch;
  margin: clamp(44px, 5.5vw, 64px) 0 0;
  padding-top: clamp(22px, 3vw, 30px);
  border-top: 1px solid var(--rule);
  font-size: 14px;
  color: var(--text-soft);
}
.terms-foot a { color: var(--copper-deep); }

@media (max-width: 640px) {
  .terms-body { font-size: 16px; }
  .terms-meta { font-size: 11px; gap: 6px 18px; }
}

/* ==========================================================================
   /templates/ - the shop window. Previews are live scaled iframes of the real
   demo pages, so nothing here can drift out of date the way a screenshot does.
   ========================================================================== */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
  gap: clamp(16px, 2.4vw, 26px);
  margin-top: clamp(34px, 5vw, 56px);
}
.gallery.two { grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); }
@media (max-width: 700px) {
  .gallery, .gallery.two { grid-template-columns: minmax(0, 1fr); }
}

.shot {
  display: grid;
  grid-template-rows: auto 1fr;
  border: 1px solid var(--rule);
  border-radius: 14px;
  overflow: hidden;
  background: var(--white);
  transition: translate 0.4s var(--ease), box-shadow 0.4s var(--ease), border-color 0.3s;
}
.shot:hover {
  translate: 0 -4px;
  border-color: var(--copper-deep);
  box-shadow: 0 22px 50px rgba(20,26,23,0.16);
}
.shot .frame {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: #fff;
  border-bottom: 1px solid var(--rule);
}
.shot .frame iframe {
  position: absolute;
  inset: 0;
  width: 1400px;
  height: 875px;
  border: 0;
  pointer-events: none;
  transform: scale(0.3);
  transform-origin: 0 0;
}
/* Scale set from JS (see /templates/): the preview renders at a 1400px desktop
   width and is scaled down to whatever width the card ends up. Not done in CSS
   because scale() needs a unitless number and calc(100cqw / 1400) is a length. */
.shot .frame iframe { transform: scale(var(--s, 0.3)); }
.shot .meta {
  display: grid;
  gap: 7px;
  align-content: start;
  padding: clamp(17px, 2vw, 23px);
}
.shot .ttl {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.01em;
  color: var(--text);
}
.shot .go {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--copper-deep);
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-5px);
  transition: opacity 0.3s, transform 0.3s var(--ease);
}
.shot:hover .go, .shot:focus-visible .go { opacity: 1; transform: none; }
.shot .kind {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.shot .desc { font-size: 14.5px; line-height: 1.55; color: var(--text-muted); }

/* On the dark band the cards have to carry their own ground. */
.shot.dark { background: rgba(255,255,255,0.03); border-color: var(--green-line); }
.shot.dark:hover { border-color: var(--copper); box-shadow: 0 22px 50px rgba(0, 0, 0, 0.4); }
.shot.dark .frame { border-bottom-color: var(--green-line); }
.shot.dark .ttl { color: var(--on-dark); }
.shot.dark .desc { color: var(--muted-dark); }
.shot.dark .kind, .shot.dark .go { color: var(--copper); }

.rows .rowline {
  padding: 17px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 88ch;
}
.rows .rowline:first-child { border-top: 1px solid var(--rule); }
.rows .rowline b { color: var(--text); font-weight: 600; }
/* Real screenshots sit in the same frame as the live previews, but as images. */
.shot .shot-img img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 0; display: block; }
.shotnote {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin: clamp(26px, 4vw, 40px) 0 -14px;
}
/* A lone last card in a two-up gallery spans the row rather than leaving a hole.
   Wider crop so a full-bleed card does not become a 700px-tall slab. */
.gallery.two .shot:last-child:nth-child(odd) { grid-column: 1 / -1; }
@media (min-width: 701px) {
  .gallery.two .shot:last-child:nth-child(odd) .frame { aspect-ratio: 24 / 9; }
  .gallery.two .shot:last-child:nth-child(odd) .desc { max-width: 78ch; }
}
.dark .shotnote, .grain .shotnote { color: var(--muted-dark); }

/* ---------- Apps: phone screenshots on the dark band ----------
   Same two-column shell as .brand-panel (and the same 1020px collapse), so the
   platforms and the apps read as one run of work rather than two components. */

.apps .shotnote { margin-bottom: clamp(20px, 3vw, 30px); }

.app-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(30px, 5vw, 66px);
  align-items: center;
  border: 1px solid rgba(20,26,23,0.16);
  border-radius: 4px;
  background: rgba(20,26,23,0.45);
  padding: clamp(26px, 3.4vw, 52px);
}
.app-row + .app-row { margin-top: clamp(18px, 2.4vw, 28px); }
.app-row.alt .brand-copy { order: 2; }
.app-row .brand-copy .feats { margin-bottom: 0; }

.phones {
  display: flex;
  gap: clamp(12px, 2vw, 26px);
  justify-content: center;
  /* the second phone is nudged down by transform, which takes no space —
     this gives that nudge somewhere to land */
  padding-bottom: clamp(14px, 2.4vw, 30px);
}
.phone {
  margin: 0;
  flex: 1 1 0;
  max-width: 236px;
  padding: 7px;
  border-radius: 30px;
  border: 1px solid rgba(20,26,23,0.30);
  background: linear-gradient(155deg, rgba(36,64,47,0.95), rgba(20,26,23,0.98));
  box-shadow: 0 30px 66px rgba(0,0,0,0.5);
  overflow: hidden;
}
.phone img { display: block; width: 100%; height: auto; border-radius: 23px; }
.phones .phone:nth-child(2) { transform: translateY(clamp(14px, 2.4vw, 30px)); }

.app-more {
  margin: clamp(26px, 4vw, 40px) 0 0;
  font-size: 15px;
  line-height: 1.7;
  color: var(--muted-dark);
  max-width: 74ch;
}
.app-more b { color: var(--on-dark); font-weight: 600; }

@media (max-width: 1020px) {
  .app-row { grid-template-columns: minmax(0, 1fr); }
  .app-row.alt .brand-copy { order: 0; }
}

/* ==========================================================================
   Live-work stage — a laptop and two phones, cross-fading through real builds.
   Sits directly under the hero because it is the fastest answer on the page to
   "what do you actually make?": you see it rather than read it.

   Honesty rules baked into the markup, not just the copy: the laptop always
   carries the DESKTOP screenshot of that build and the phones always carry
   either that product's own app screens or the SAME site shot at iPhone width
   (reshoot-mobile.py) — never a desktop still squeezed into a phone, and never
   an app paired with a site it does not belong to. Private client systems show
   "private client system" in the browser bar instead of a URL, because there
   isn't one to open.
   ========================================================================== */

.stage { overflow: hidden; }
.stage::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(56% 46% at 50% 54%, rgba(138,84,36,0.12), transparent 68%);
}
.stage .shell { position: relative; z-index: 1; }

.rig {
  position: relative;
  padding-bottom: clamp(18px, 3.4vw, 46px);
  transform: perspective(1500px);
  transition: transform 0.6s var(--ease);
}
.rig.is-live { transition: none; }

/* ---------- Laptop ---------- */

.mac {
  position: relative;
  width: 76%;
  margin: 0 auto;
  animation: rigFloat 11s ease-in-out infinite;
}
.mac-lid {
  padding: 15px 11px;
  border-radius: 16px 16px 5px 5px;
  border: 1px solid rgba(20,26,23,0.26);
  background: linear-gradient(158deg, #2d3d34, #101d16 64%);
  box-shadow: 0 44px 96px rgba(0,0,0,0.55), inset 0 1px 0 rgba(255,255,255,0.09);
}
.mac-cam {
  display: block;
  width: 5px; height: 5px;
  margin: -8px auto 7px;
  border-radius: 50%;
  background: rgba(20,26,23,0.38);
}
.mac-view {
  position: relative;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid rgba(0,0,0,0.55);
  background: var(--forest-deep);
}
/* A screen with no sheen on it reads as a printed rectangle, not glass. */
.mac-view::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(112deg, rgba(255,255,255,0.11) 0%, rgba(255,255,255,0) 24%,
                                      rgba(255,255,255,0) 76%, rgba(255,255,255,0.05) 100%);
}
.mac-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 13px;
  background: rgba(20,26,23,0.92);
  border-bottom: 1px solid rgba(20,26,23,0.14);
}
.mac-bar i { width: 7px; height: 7px; border-radius: 50%; background: rgba(20,26,23,0.26); }
.mac-bar i:first-child { background: var(--copper); }
.mac-bar .url {
  margin-left: 10px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.07em;
  color: var(--muted-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mac-shot { position: relative; aspect-ratio: 16 / 10; background: var(--forest-deep); }

/* Two stacked layers per screen: the incoming shot is decoded underneath and
   then cross-faded, so a slide change never flashes an empty frame. */
.mac-shot .lyr, .hand-shot .lyr {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0;
  opacity: 0;
  transition: opacity 0.62s var(--ease);
}
.mac-shot .lyr.is-front, .hand-shot .lyr.is-front { opacity: 1; }

.mac-foot {
  position: relative;
  width: 116%;
  height: 13px;
  margin-left: -8%;
  border-radius: 0 0 9px 9px;
  background: linear-gradient(180deg, #33443b, #16241c 68%, #0a120e);
  box-shadow: 0 26px 44px rgba(0,0,0,0.5);
  clip-path: polygon(0 0, 100% 0, 98.6% 100%, 1.4% 100%);
}
.mac-foot::after {
  content: "";
  position: absolute;
  left: 50%; top: 0;
  width: 13%; height: 5px;
  transform: translateX(-50%);
  border-radius: 0 0 6px 6px;
  background: rgba(0,0,0,0.45);
}

/* ---------- Phones ----------
   .rig-hands is deliberately unpositioned: on desktop the two figures inside it
   are absolute and resolve against .rig, so the wrapper collapses to nothing and
   only earns its keep at the mobile breakpoint, where it becomes the flex row. */

.hand {
  position: absolute;
  width: 16.5%;
  margin: 0;
  animation: rigFloat 11s ease-in-out infinite;
}
.hand-l { left: -1%;  bottom: 0;    animation-delay: -3.6s; }
.hand-r { right: -1%; bottom: 74px; animation-delay: -7.2s; }
.hand-body {
  position: relative;
  padding: 6px;
  border-radius: 27px;
  border: 1px solid rgba(20,26,23,0.34);
  background: linear-gradient(150deg, #35473d, #0b130f 66%);
  box-shadow: 0 36px 74px rgba(0,0,0,0.58), inset 0 1px 0 rgba(255,255,255,0.10);
}
.hand-l .hand-body { transform: rotate(-4.5deg); }
.hand-r .hand-body { transform: rotate(4.5deg); }
.hand-shot {
  position: relative;
  aspect-ratio: 520 / 1127;
  border-radius: 21px;
  overflow: hidden;
  background: var(--forest-deep);
}
.island {
  position: absolute;
  z-index: 2;
  left: 50%; top: 13px;
  width: 30%; height: 7px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: #05100b;
}

@keyframes rigFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

/* ---------- Caption + tabs ---------- */

.stage-cap {
  max-width: 70ch;
  margin: clamp(24px, 3.2vw, 38px) auto 0;
  text-align: center;
}
.cap-k {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--accent);
}
.cap-t {
  margin: 0 0 10px;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(21px, 2.2vw, 29px);
  letter-spacing: -0.02em;
  color: var(--on-dark);
}
.cap-t .cap-go {
  margin-left: 12px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--accent);
  border-bottom: 1px solid rgba(138,84,36,0.35);
  white-space: nowrap;
  transition: border-color 0.3s;
}
.cap-t .cap-go:hover { border-bottom-color: var(--accent); }
.cap-t .cap-go[hidden] { display: none; }
.cap-d { margin: 0; font-size: 15.5px; line-height: 1.62; color: var(--muted-dark); }
.cap-dev {
  margin: 12px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.cap-dev b { color: var(--muted-dark); font-weight: 500; }

.stage-tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin-top: clamp(24px, 3vw, 34px);
}
/* The play button is a control, not a tab, so it sits outside the tablist —
   a tablist with a non-tab child is a lie to anything reading the roles. */
.stage-tablist {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 9px;
}
.stage-tab {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(20,26,23,0.25);
  background: transparent;
  border-radius: 999px;
  padding: 10px 18px 11px;
  cursor: pointer;
  font-size: 12.5px;
  letter-spacing: 0.03em;
  color: var(--muted-dark);
  transition: color 0.3s, border-color 0.3s, background 0.3s;
}
.stage-tab:hover { color: var(--on-dark); border-color: rgba(138,84,36,0.55); }
.stage-tab[aria-selected="true"] {
  color: var(--ink);
  background: var(--copper);
  border-color: var(--copper);
}
/* The rail doubles as the auto-advance clock — it is the only thing telling you
   the stage is about to move on, so it pauses with everything else. */
.stage-tab .rail {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: rgba(20,26,23,0.22);
  opacity: 0;
}
.stage-tab[aria-selected="true"] .rail { opacity: 1; }
.stage-tab .rail span {
  display: block;
  height: 100%;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.stage-tab[aria-selected="true"] .rail span { animation: stageFill 5.2s linear forwards; }
.stage.is-paused .stage-tab .rail span { animation-play-state: paused; }
@keyframes stageFill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.stage-play {
  width: 38px; height: 38px;
  display: inline-grid;
  place-items: center;
  border: 1px solid rgba(20,26,23,0.25);
  background: transparent;
  border-radius: 999px;
  cursor: pointer;
  color: var(--muted-dark);
  transition: color 0.3s, border-color 0.3s;
}
.stage-play:hover { color: var(--on-dark); border-color: rgba(138,84,36,0.55); }
.stage-play svg { width: 13px; height: 13px; fill: currentColor; }
.stage-play .ico-play { display: none; }
.stage-play.is-off .ico-play { display: block; }
.stage-play.is-off .ico-pause { display: none; }

.stage-note {
  margin: clamp(22px, 3vw, 30px) 0 0;
  text-align: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-dark);
}

@media (max-width: 1060px) {
  .mac { width: 86%; }
  .hand { width: 17.5%; }
  .hand-l { left: -2.5%; }
  .hand-r { right: -2.5%; bottom: 50px; }
}
@media (max-width: 820px) {
  .rig { padding-bottom: 0; }
  .mac { width: 100%; animation: none; }
  .rig-hands {
    display: flex;
    justify-content: center;
    gap: 16px;
    margin-top: 22px;
  }
  .hand { position: static; width: auto; flex: 1 1 0; max-width: 164px; animation: none; }
  .hand-l .hand-body, .hand-r .hand-body { transform: none; }
}
@media (max-width: 640px) {
  /* Six chips wrap to four rows on a phone, which is most of a screenful of
     nothing. One scrolling row instead, bled to the left edge so it reads as
     scrollable rather than truncated. */
  .stage-tabs { flex-wrap: nowrap; }
  .stage-tablist {
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    margin-left: calc(var(--gutter) * -1);
    padding-left: var(--gutter);
    padding-bottom: 4px;
  }
  .stage-tablist::-webkit-scrollbar { display: none; }
  .stage-tab { flex: 0 0 auto; scroll-snap-align: start; }
  .stage-play { flex: 0 0 auto; }
}

@media (prefers-reduced-motion: reduce) {
  /* The rail is a clock for something that is no longer moving on its own. */
  .stage-tab .rail { display: none; }
}

/* ---------- Stage hover: the device you point at comes forward ------------
   Restrained on purpose — a lift, a deepened shadow, one pass of light across
   the screen, and the other two settle back so the one you want reads first.

   The lift uses the INDIVIDUAL transform properties (translate/scale/rotate)
   rather than `transform`, because `transform` is already spoken for: rigFloat
   animates it, and the rig's pointer tilt writes to it inline. Individual
   properties compose with both instead of fighting them for the same slot.
   Hover-only media query so a tap on a phone can't leave a device stuck lifted.
   ------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .mac, .hand {
    transition: translate 0.5s var(--ease), scale 0.5s var(--ease),
                opacity 0.4s, filter 0.4s;
  }
  .hand-body { transition: rotate 0.5s var(--ease), border-color 0.4s, box-shadow 0.5s var(--ease); }
  .mac-lid { transition: border-color 0.4s, box-shadow 0.5s var(--ease); }
  .mac-shot, .hand-shot { transition: filter 0.4s; }

  .mac:hover  { translate: 0 -10px; scale: 1.022; z-index: 3; }
  .hand:hover { translate: 0 -12px; scale: 1.04;  z-index: 4; }

  /* a hovered phone stands up a little, as if picked off the desk */
  .hand-l:hover .hand-body { rotate: -1.5deg; }
  .hand-r:hover .hand-body { rotate: 1.5deg; }

  .mac:hover .mac-lid {
    border-color: rgba(138,84,36,0.5);
    box-shadow: 0 62px 120px rgba(0,0,0,0.62),
                0 0 0 1px rgba(138,84,36,0.12),
                inset 0 1px 0 rgba(255,255,255,0.14);
  }
  .hand:hover .hand-body {
    border-color: rgba(138,84,36,0.5);
    box-shadow: 0 48px 94px rgba(0,0,0,0.64),
                inset 0 1px 0 rgba(255,255,255,0.14);
  }
  .mac:hover .mac-shot, .hand:hover .hand-shot { filter: brightness(1.05); }

  /* One pass of light across the glass. Clipped by the screen's own overflow. */
  .mac-view::before, .hand-shot::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    background: linear-gradient(100deg,
      transparent 38%, rgba(255,255,255,0.17) 50%, transparent 62%);
    translate: -130% 0;
    opacity: 0;
  }
  .mac:hover .mac-view::before,
  .hand:hover .hand-shot::before { animation: glint 0.95s var(--ease) forwards; }
  @keyframes glint {
    0%   { translate: -130% 0; opacity: 0; }
    16%  { opacity: 1; }
    84%  { opacity: 1; }
    100% { translate:  130% 0; opacity: 0; }
  }

  /* Whatever you are NOT pointing at gets out of the way. */
  .rig:has(.mac:hover)    .hand,
  .rig:has(.hand:hover)   .mac,
  .rig:has(.hand-l:hover) .hand-r,
  .rig:has(.hand-r:hover) .hand-l {
    scale: 0.985;
    opacity: 0.6;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* A light sweep is pure motion — there is nothing to keep once it is stilled. */
  .mac-view::before, .hand-shot::before { display: none; }
}

/* ==========================================================================
   Sitewide interaction — the same language the device stage speaks, applied to
   every card on every page. Three moves, no more: a card LIGHTS under the
   pointer, an image surface catches ONE pass of light, and anything that floats
   LIFTS. Nothing bounces, nothing spins, nothing announces itself.

   All of it hangs off classes the generated pages already use, so the 46 sector
   pages and 27 demo sites get it from this file alone — there is no build step
   that could re-emit their HTML (see project memory: the generators lived in a
   scratchpad that is long gone).
   ========================================================================== */

@media (hover: hover) and (pointer: fine) {

  /* ---- 1. The pointer light ----
     --mx/--my are written by one delegated listener in site.js. The default
     sits the light off the card, so a card that never gets hovered, or one
     rendered with JS disabled, is simply unlit rather than wrongly lit. */
  .svc::after, .pcard::after, .shot::after, .svc-more::after,
  .proof-cell::after, .qcard::after, .where::after,
  .app-row::after, .brand-panel::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.45s var(--ease);
    background: radial-gradient(circle 360px at var(--mx, 50%) var(--my, -40%),
                                var(--spot), transparent 68%);
  }
  /* Warm ink on the cream grounds, warm light on the dark ones. */
  .svc::after, .pcard::after, .shot::after, .svc-more::after { --spot: rgba(150,89,31,0.16); }
  .proof-cell::after, .qcard::after, .where::after,
  .app-row::after, .brand-panel::after,
  .pcard.feature::after, .shot.dark::after { --spot: rgba(138,84,36,0.19); }

  .is-lit::after { opacity: 1; }

  /* The light paints in the positioned layer, so the card's own content has to
     be lifted above it or the copper washes over the type. */
  .svc > *, .pcard > *, .shot > *, .svc-more > *,
  .proof-cell > *, .qcard > *, .where > *,
  .app-row > *, .brand-panel > * { position: relative; z-index: 1; }

  /* ---- 2. One pass of light across anything with a screen in it ----
     Same gesture as the stage's laptop and phones, so a demo card on a sector
     page and the hero device rig read as the same object. */
  .shot .frame::after, .phone::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(100deg,
      transparent 38%, rgba(255,255,255,0.15) 50%, transparent 62%);
    translate: -130% 0;
    opacity: 0;
  }
  .shot:hover .frame::after,
  .phone:hover::after { animation: glint 0.95s var(--ease) forwards; }

  /* ---- 3. The app phones get the stage's treatment, because they are the
     same object photographed twice and should not behave differently. ---- */
  .phone {
    position: relative;
    transition: translate 0.5s var(--ease), scale 0.5s var(--ease),
                opacity 0.4s, border-color 0.4s, box-shadow 0.5s var(--ease);
  }
  .phone:hover {
    translate: 0 -10px;
    scale: 1.03;
    z-index: 2;
    border-color: rgba(138,84,36,0.5);
    box-shadow: 0 48px 92px rgba(0,0,0,0.62), inset 0 1px 0 rgba(255,255,255,0.14);
  }
  .phones:has(.phone:hover) .phone:not(:hover) { scale: 0.985; opacity: 0.62; }

  /* ---- 4. Cells in a ruled grid must NOT lift — the 1px seams are the design,
     and a lifting cell tears them open. They get the light and a warmed figure
     instead. ---- */
  .proof-cell .n, .proof-cell .k { transition: opacity 0.4s, color 0.4s; }
  .proof-cell:hover .k { color: var(--copper); }

  /* ---- 5. The small stuff. A shop window is judged on the details nobody
     was asked to notice. ---- */
  .places li {
    transition: border-color 0.3s, color 0.3s, translate 0.3s var(--ease);
  }
  .places li:hover { border-color: var(--copper); color: var(--copper); translate: 0 -2px; }
  .places li.hub:hover { color: var(--green); border-color: var(--gold); background: var(--gold); }

  .rows .rowline { transition: padding-left 0.4s var(--ease), color 0.3s, border-color 0.3s; }
  .rows .rowline:hover { padding-left: 14px; color: var(--text); border-color: var(--rule-warm); }

  .faq summary { transition: color 0.3s, padding-left 0.35s var(--ease); }
  .faq summary:hover { color: var(--copper); padding-left: 6px; }

  .feats li, .ticks li { transition: color 0.3s; }
  .feats li:hover, .ticks li:hover { color: var(--on-dark); }

  /* The brand-panel mocks are drawn in CSS rather than screenshotted, so they
     can respond to the pointer in a way a still never could. */
  .device { transition: translate 0.5s var(--ease), box-shadow 0.5s var(--ease); }
  .brand-panel:hover .device { translate: 0 -6px; box-shadow: 0 44px 92px rgba(0,0,0,0.5); }
}

@media (prefers-reduced-motion: reduce) {
  .shot .frame::after, .phone::after { display: none; }
}

/* Honeypot for the enquiry form: off-screen rather than display:none, because
   some bots skip anything that is not rendered at all. No person reaches it —
   it is aria-hidden and out of the tab order. */
.hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px; overflow: hidden;
}

/* Marketing opt-in. Unticked by default and never required: the enquiry is
   answered either way, and a pre-ticked box is not consent under PECR. */
.optin { display: flex; gap: 10px; align-items: flex-start; margin: 4px 0 18px;
  cursor: pointer; font-size: 13.5px; line-height: 1.5; color: var(--soft); }
.optin input { margin: 2px 0 0; width: 17px; height: 17px; flex: 0 0 auto; accent-color: var(--gold); }
.optin span { flex: 1; }
/* A radio group lives in a fieldset, which is a .field — so .field label's
   10px uppercase micro-label lands on the choices and turns a sentence into
   four lines of shouting. The legend is the label here; the options are prose.
   Used by the domain question on /free-website. */
.field label.optin {
  font-family: inherit;
  font-size: 13.5px;
  letter-spacing: normal;
  text-transform: none;
  color: var(--soft);
}

/* Inside the forest panels: the bronze that reads on paper is too dark on
   forest, so the light bronze takes over, and the muted greys flip. */
.pcard.feature .amount,
.calc-out .amount {
  color: var(--bronze-soft);
  -webkit-text-fill-color: var(--bronze-soft);
  background: none;
  animation: none;
}
.pcard.feature .amount small,
.pcard.feature .from,
.pcard.feature ul li,
.calc-out .k { color: var(--on-forest-2); }
.pcard.feature h3 { color: var(--on-forest); }
.pcard.feature ul li b { color: var(--on-forest); }
/* The tick or bullet before each line, which was drawn for a cream card. */
.pcard.feature ul li::before { color: var(--bronze-soft); background: var(--bronze-soft); }


/* ==========================================================================
   Form controls on a touch device.
   ========================================================================== */

/* iOS Safari zooms the whole page in when a focused field is smaller than 16px,
   and does not zoom back out — so a six-field form is six pinches. Keyed on
   `pointer: coarse` rather than a width, because an iPad in landscape is 1024px
   wide and zooms exactly the same; a breakpoint would have missed it.

   Desktop keeps 15px: the problem is the zoom, not the size. */
@media (pointer: coarse) {
  .field input,
  .field select,
  .field textarea { font-size: 16px; }

  /* And while we are here: a 17px tick box is a cursor-sized target on a
     screen operated with a thumb. These are the boxes a form cannot be
     submitted without. */
  .optin input[type="checkbox"],
  .field input[type="checkbox"],
  .field input[type="radio"] { width: 22px; height: 22px; }
}

/* ---------------- Cookie banner (Meta pixel, consent first) ---------------- */
.cookie-banner {
  position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 90;
  max-width: 560px; margin: 0 auto; padding: 16px 18px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--rule-warm); border-radius: 14px;
  box-shadow: 0 18px 50px rgba(18,41,31,0.16);
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px;
}
.cookie-banner p { margin: 0; flex: 1 1 260px; font-size: 15px; line-height: 1.45; }
.cookie-banner a { color: var(--copper); }
.cookie-actions { display: flex; align-items: center; gap: 14px; }
.link-btn {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--copper); text-decoration: underline; text-underline-offset: 3px;
}
.link-btn:hover { color: var(--copper-mid); }

/* Optional parts of a sign-up form, folded away: most people never need them. */
.form-extras { margin: 6px 0 18px; border-top: 1px solid var(--rule); padding-top: 14px; }
.form-extras > summary { cursor: pointer; font-weight: 600; color: var(--text); list-style: none; }
.form-extras > summary::-webkit-details-marker { display: none; }
.form-extras > summary::before { content: "+"; display: inline-block; width: 1.2em; color: var(--copper); }
.form-extras[open] > summary::before { content: "\2212"; }
.form-extras > summary .opt { display: block; font-weight: 400; color: var(--text-muted); font-size: 14px; margin: 2px 0 0 1.2em; }
.form-extras[open] > summary { margin-bottom: 14px; }

/* ---------------- /mockup/: the free mock-up form, in the hero ---------------- */
.mockup-form, .mockup-done {
  max-width: 640px; margin-top: clamp(22px, 3vw, 34px);
  background: var(--surface); border: 1px solid var(--rule-warm); border-radius: 14px;
  padding: clamp(18px, 3vw, 28px);
  box-shadow: 0 18px 50px rgba(18,41,31,0.08);
}
.mockup-form .btn { width: 100%; justify-content: center; margin-top: 4px; }
.mockup-steps { max-width: 720px; margin: 0; padding-left: 1.3em; display: grid; gap: 14px;
                font-size: 17px; line-height: 1.55; color: var(--text); }
.mockup-steps b { color: var(--text); }
@media (max-width: 640px) {
  .mockup-form .field-row { grid-template-columns: minmax(0, 1fr); gap: 0; }
}
