/* UNGROW landing page
   Built from brand-system/tokens.json v2. Role tokens only, never raw palette in components.
   Bone is the default ground. Petrol is the reversed ground. */

:root {
  /* palette, fixed */
  --petrol: #1c4b50;
  --petrol-deep: #0f3136;
  --bone: #faf6ee;
  --cream: #f1e7d6;
  --charcoal: #24211e;
  --hivis: #f5d000;
  --rust: #963a1a;

  /* role tokens, bone theme */
  --ground: var(--bone);
  --ground-alt: var(--cream);
  --ink: var(--charcoal);
  --ink-muted: #5e544a;
  --brand: var(--petrol);
  --on-brand: var(--bone);
  --accent: var(--hivis);
  --on-accent: var(--charcoal);
  --line: #5e544a;
  --outline: var(--charcoal);
  --focus: var(--petrol);

  /* spacing, 4px base */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-6: 24px; --space-8: 32px; --space-12: 48px; --space-16: 64px;

  --radius-md: 12px;
  --radius-pill: 999px;
  --stroke-rule: 2px;

  --font: "Archivo", system-ui, -apple-system, sans-serif;
}

[data-theme="petrol"] {
  /* colour is only declared on body, so children inherit the COMPUTED value and never
     see the tokens redefined here. Re-declare it on the themed element itself. */
  color: var(--ink);
  --ground: var(--petrol);
  --ground-alt: #245a60;
  --ink: var(--bone);
  --ink-muted: #c3d3d0;
  --brand: var(--bone);
  --on-brand: var(--petrol);
  --line: #8fb0ab;
  --focus: var(--hivis);
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 24px;
  -webkit-font-smoothing: antialiased;
}

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

/* ---------- type scale, from tokens ---------- */
.ug-display  { font-size: clamp(38px, 9vw, 72px); line-height: .92; font-weight: 900; letter-spacing: -.02em; margin: 0; text-wrap: balance; }
.ug-headline { font-size: clamp(26px, 5.5vw, 36px); line-height: 1; font-weight: 900; letter-spacing: -.01em; margin: 0; text-wrap: balance; }
.ug-notice   { font-size: clamp(20px, 4vw, 26px); line-height: 1; font-weight: 900; letter-spacing: .04em; font-stretch: 75%; text-transform: uppercase; margin: 0; }
.ug-title    { font-size: 20px; line-height: 26px; font-weight: 800; margin: 0; }
.ug-body     { font-size: 16px; line-height: 24px; font-weight: 400; margin: 0; }
.ug-strong   { font-weight: 700; }
.ug-label    { font-size: 11px; line-height: 14px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; margin: 0; }
.ug-small    { font-size: 13px; line-height: 18px; font-weight: 500; margin: 0; }

.ug-accent { color: var(--accent); }

/* ---------- layout ---------- */
.ug-wrap { width: 100%; max-width: 1200px; margin: 0 auto; padding-inline: var(--space-4); }
@media (min-width: 900px) { .ug-wrap { padding-inline: var(--space-12); } }

.ug-section { padding-block: var(--space-8); }
@media (min-width: 900px) { .ug-section { padding-block: var(--space-16); } }

.ug-band { background: var(--ground); color: var(--ink); }

/* ---------- nav ---------- */
.ug-nav { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); min-height: 72px; }
.ug-nav__mark { width: 132px; }
@media (min-width: 900px) { .ug-nav { min-height: 96px; } .ug-nav__mark { width: 168px; } }
/* Always a flex row. It used to be display:none below 720px, which silently hid the phone
   number on every phone: the rule meant to keep the number when the section links collapse
   was scoped to the children, so the hidden parent won regardless.
   align-items:center matters because the tel is a padded pill and the section links are bare
   text; without it they stretch to the pill's height and their text sits at the top of that
   box, which reads as the pill being dropped in at the wrong height. */
.ug-nav__links { display: flex; align-items: center; gap: var(--space-6); }
.ug-nav__links a { color: var(--ink); text-decoration: none; font-weight: 700; font-size: 15px; }
/* the wordmark link carries the browser default otherwise */
.ug-nav a { text-decoration: none; }
/* no underline anywhere on this site: hover lifts the colour instead. */
.ug-nav__links a:hover { color: var(--hivis); }

/* ---------- hero ---------- */
.ug-hero { display: grid; gap: var(--space-8); align-items: center; padding-bottom: var(--space-12); }
@media (min-width: 900px) { .ug-hero { grid-template-columns: 1fr 1fr; gap: var(--space-12); padding-bottom: var(--space-16); } }
.ug-hero__method { color: var(--ink-muted); margin-top: var(--space-4); font-size: 18px; line-height: 26px; font-weight: 500; }
@media (min-width: 900px) { .ug-hero__method { font-size: 20px; line-height: 28px; } }
.ug-hero__cta { margin-top: var(--space-6); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
.ug-hero__crew { justify-self: center; width: min(62vw, 300px); }
@media (min-width: 900px) { .ug-hero__crew { width: 100%; max-width: 360px; } }

/* ---------- button ---------- */
.ug-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 52px; padding: var(--space-3) var(--space-6);
  background: var(--accent); color: var(--on-accent);
  border: 0; border-radius: var(--radius-md);
  font-family: var(--font); font-size: 17px; font-weight: 900; letter-spacing: -.01em;
  text-decoration: none; cursor: pointer;
}
.ug-btn:hover { filter: brightness(.95); }
.ug-btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.ug-btn--brand { background: var(--brand); color: var(--on-brand); }
.ug-btn--outline { background: transparent; color: var(--ink); border: var(--stroke-rule) solid var(--line); }
.ug-btn[disabled] { opacity: .45; cursor: not-allowed; }
.ug-btn--full { width: 100%; }

/* ---------- multi step form ---------- */
.ug-price { display: grid; gap: var(--space-8); align-items: start; }
@media (min-width: 980px) { .ug-price { grid-template-columns: 1fr 1fr; gap: var(--space-12); } }
.ug-price > * { min-width: 0; }
.ug-form-card {
  max-width: 560px;
  background: var(--ground); color: var(--ink);
  border: var(--stroke-rule) solid var(--line);
  border-radius: var(--radius-md);
  padding: var(--space-6);
}
@media (min-width: 720px) { .ug-form-card { padding: var(--space-8); } }

.ug-steps { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-6); }
.ug-steps__bar { flex: 1; height: 6px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--line) 35%, transparent); overflow: hidden; }
.ug-steps__fill { height: 100%; width: 33.33%; background: var(--accent); border-radius: var(--radius-pill); transition: width .28s ease; }
.ug-steps__count { flex: none; font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-muted); white-space: nowrap; }

.ug-step[hidden] { display: none !important; }
.ug-step__q { margin-bottom: var(--space-2); }
.ug-step__hint { color: var(--ink-muted); margin-bottom: var(--space-6); }

.ug-field { display: block; margin-bottom: var(--space-4); position: relative; }
.ug-field > label { display: block; font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--space-1); }
.ug-field__opt { font-weight: 600; letter-spacing: .06em; text-transform: none; }
.ug-input {
  width: 100%; min-height: 52px; padding: var(--space-3) var(--space-4);
  background: var(--ground); color: var(--ink);
  border: var(--stroke-rule) solid var(--line); border-radius: var(--radius-md);
  font-family: var(--font); font-size: 16px; font-weight: 500; line-height: 24px;
}
.ug-input::placeholder { color: var(--ink-muted); opacity: .75; }
.ug-input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-color: var(--focus); }
.ug-input--notice:focus-visible { outline: 0; outline-offset: 0; }
.ug-input[aria-invalid="true"] { border-color: var(--rust); }

.ug-err { color: var(--rust); font-size: 13px; font-weight: 700; margin-top: var(--space-1); min-height: 18px; }
[data-theme="petrol"] .ug-err { color: var(--hivis); }

.ug-actions { display: flex; gap: var(--space-3); align-items: center; margin-top: var(--space-6); }
.ug-back { background: none; border: 0; padding: var(--space-3); color: var(--ink-muted); font-family: var(--font); font-weight: 700; font-size: 15px; cursor: pointer; }
.ug-back:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-md); }

/* honeypot, hidden by class, never an inline style */
.ug-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- address autocomplete dropdown ---------- */
.ug-ac {
  position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 4px);
  background: var(--ground); color: var(--ink);
  border: var(--stroke-rule) solid var(--line); border-radius: var(--radius-md);
  box-shadow: 0 10px 30px -12px rgba(0,0,0,.35);
  max-height: 268px; overflow-y: auto; list-style: none; margin: 0; padding: var(--space-1);
}
.ug-ac[hidden] { display: none; }
.ug-ac li { padding: var(--space-3) var(--space-4); border-radius: 8px; cursor: pointer; font-size: 15px; line-height: 20px; }
.ug-ac li[aria-selected="true"], .ug-ac li:hover { background: color-mix(in srgb, var(--brand) 12%, transparent); }
.ug-ac li .ug-ac__main { font-weight: 700; }
.ug-ac li .ug-ac__sub { color: var(--ink-muted); font-size: 13px; }

/* ---------- crew lineup ---------- */
.ug-lineup { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-3); align-items: end; }
.ug-lineup figure { margin: 0; text-align: center; }
.ug-lineup img { width: 100%; max-width: 168px; margin-inline: auto; }
.ug-lineup figcaption { margin-top: var(--space-3); font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-muted); }
.ug-lineup__rule { height: var(--stroke-rule); background: var(--line); margin-top: var(--space-4); }

/* ---------- steps / how it works ---------- */
.ug-grid { display: grid; gap: var(--space-6); }
.ug-grid > *, .ug-hero > *, .ug-guarantee > * { min-width: 0; }
@media (min-width: 760px) { .ug-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ug-card { background: var(--ground-alt); border-radius: var(--radius-md); padding: var(--space-6); }
.ug-card__n { font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-muted); margin: 0 0 var(--space-3); }
.ug-card p:last-child { margin-bottom: 0; }

/* ---------- guarantee ---------- */
.ug-guarantee { display: grid; gap: var(--space-6); align-items: center; }
@media (min-width: 860px) { .ug-guarantee { grid-template-columns: 1fr 1fr; gap: var(--space-12); } }
.ug-proof { background: var(--cream); border: var(--stroke-rule) solid var(--line); padding: var(--space-4); }
.ug-proof__plate { aspect-ratio: 4 / 3; background: #d8cfc0; display: grid; place-items: center; position: relative; }
.ug-proof__plate span { font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: #6b6156; }
.ug-proof__stamp {
  position: absolute; right: 10px; bottom: 10px;
  border: 4px solid var(--rust); color: var(--rust); border-radius: 6px;
  padding: 4px 12px; font-size: 16px; font-weight: 900; letter-spacing: .1em; transform: rotate(-6deg);
}
.ug-proof__meta { display: flex; gap: var(--space-6); margin-top: var(--space-4); }
.ug-proof__meta div { flex: 1; }

/* ---------- footer ---------- */
.ug-footer { border-top: var(--stroke-rule) solid var(--line); padding-block: var(--space-8); }
.ug-footer__row { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; justify-content: space-between; }
.ug-footer__mark { width: 120px; }

.ug-tagline { font-weight: 800; }

/* ---------- success ---------- */
.ug-done[hidden] { display: none; }
.ug-done { text-align: center; padding-block: var(--space-4); }
.ug-done img { width: 120px; margin: 0 auto var(--space-6); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ============================================================
   EVICTION SYSTEM
   The notice, the stamp, the hazard stripe, the height chart.
   Brought forward from brand-system/components.
   ============================================================ */

/* ---------- hazard stripe, from the drum label ---------- */
.ug-hazard {
  height: 14px;
  background: repeating-linear-gradient(-45deg,
    var(--hivis) 0 14px, var(--charcoal) 14px 28px);
}

/* ---------- the notice ---------- */
.ug-notice-doc {
  background: var(--bone);
  border: var(--stroke-rule) solid var(--charcoal);
  max-width: 560px;
  overflow: hidden;
}
.ug-notice-doc__band {
  background: var(--charcoal);
  padding: var(--space-4) var(--space-6);
}
.ug-notice-doc__band h2 {
  color: var(--bone);
  font-size: clamp(19px, 4.4vw, 25px);
  font-weight: 900;
  letter-spacing: .06em;
  line-height: 1;
  margin: 0;
}
.ug-notice-doc__crew {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4); align-items: end;
  padding: var(--space-6) var(--space-6) 0;
}
.ug-notice-doc__crew img { width: 100%; max-width: 66px; height: auto; margin-inline: auto; }
.ug-notice-doc__body { padding: var(--space-6); }

/* a filled notice row: label above, value on a hairline rule */
.ug-row { padding-bottom: var(--space-2); border-bottom: 1px solid color-mix(in srgb, var(--charcoal) 30%, transparent); margin-bottom: var(--space-4); }
.ug-row__k { display: block; font-size: 10px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--space-1); }
.ug-row__v { font-size: 15px; font-weight: 800; color: var(--ink); margin: 0; overflow-wrap: anywhere; }
.ug-row__v--pending { color: var(--ink-muted); font-weight: 700; }

/* inputs inside the notice read as something being filled in */
.ug-input--notice {
  border: 0; border-bottom: var(--stroke-rule) solid var(--charcoal);
  border-radius: 0; padding-inline: 0; background: transparent;
  font-weight: 800; font-size: 16px;
}
/* One underline, thickened in place. An outer box-shadow draws a SECOND line below the
   border and an outline draws a rectangle around the field; inset keeps it to one mark
   and avoids any layout shift. */
.ug-input--notice:focus-visible,
.ug-input--notice:focus {
  outline: 0;
  border-bottom-color: var(--focus);
  box-shadow: inset 0 -3px 0 0 var(--focus);
}

/* ---------- served stamp ---------- */
.ug-stamp {
  display: inline-block; transform: rotate(-8deg);
  border: 4px solid var(--rust); border-radius: 7px;
  color: var(--rust); padding: 6px 18px;
  font-size: 25px; font-weight: 900; letter-spacing: .12em; line-height: 1;
}
[data-theme="petrol"] .ug-stamp { border-color: var(--hivis); color: var(--hivis); }

/* ---------- hivis action band, the notice footer ---------- */
.ug-hivis-band {
  background: var(--accent); color: var(--on-accent);
  padding: var(--space-6);
  display: flex; gap: var(--space-4); align-items: center; justify-content: space-between;
}
.ug-hivis-band p { margin: 0; }
.ug-hivis-band__big { font-size: 22px; font-weight: 900; line-height: 1; }
.ug-hivis-band__sub { font-size: 11px; font-weight: 700; line-height: 15px; margin-top: 4px; }

/* the wordmark footer inside the notice */
.ug-notice-doc__foot { background: var(--petrol-deep); padding: var(--space-6); display: grid; place-items: center; }
.ug-notice-doc__foot img { width: 128px; }

/* ---------- height chart lineup ---------- */
.ug-chart { position: relative; padding: var(--space-8) var(--space-4) 0; background: var(--cream); border: var(--stroke-rule) solid var(--charcoal); }
.ug-chart__ticks { position: absolute; inset: var(--space-4) var(--space-4) 64px; pointer-events: none; }
.ug-chart__ticks span { position: absolute; left: 0; right: 0; border-top: 1px solid color-mix(in srgb, var(--charcoal) 18%, transparent); }
.ug-chart__row { position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-3); align-items: end; }
.ug-chart__row figure { margin: 0; text-align: center; }
.ug-chart__row img { width: 100%; max-width: 136px; margin-inline: auto; }
.ug-chart__plate {
  margin-top: var(--space-3); background: var(--charcoal); color: var(--bone);
  font-size: 10px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  padding: 6px 4px;
}
.ug-chart__base { height: var(--stroke-rule); background: var(--charcoal); margin-top: var(--space-4); }
.ug-chart__cap { text-align: center; padding: var(--space-4) 0 var(--space-6); }

/* ---------- section head ---------- */
.ug-head { display: flex; align-items: baseline; gap: var(--space-4); margin-bottom: var(--space-8); flex-wrap: wrap; }
.ug-head__k { font-size: 10px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-muted); margin: 0; }
.ug-row--flat { border: 0; margin-bottom: 0; }
.ug-chart__ticks .t0 { top: 0 } .ug-chart__ticks .t1 { top: 25% }
.ug-chart__ticks .t2 { top: 50% } .ug-chart__ticks .t3 { top: 75% }
.ug-footer__row--pad { padding-block: var(--space-12); }
.ug-footer__meta { color: var(--ink-muted); }
/* The fine print closes the footer: its own centred line under the row, at both widths. */
.ug-footer__fine { margin-top: var(--space-6); text-align: center; color: var(--ink-muted); }
.ug-footer__fine a { color: inherit; text-decoration: none; font-weight: 700; }
.ug-footer__fine a:hover { color: var(--hivis); }
.ug-done { text-align: left; }
.ug-aside { margin-top: var(--space-8); padding: var(--space-6); background: var(--ground-alt); border-left: 4px solid var(--brand); }

/* ---------- proof, real job photography ---------- */
.ug-proof-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (min-width: 860px) { .ug-proof-grid { grid-template-columns: 2fr 1fr 1fr; grid-template-rows: auto auto; } 
  .ug-proof-grid > :first-child { grid-row: span 2; } }
.ug-shot { margin: 0; border: var(--stroke-rule) solid var(--charcoal); background: var(--charcoal); position: relative; }
.ug-shot img { width: 100%; height: 100%; object-fit: cover; display: block; aspect-ratio: 4/3; }
.ug-proof-grid > :first-child img { aspect-ratio: 3/4; }
@media (max-width: 859px) { .ug-proof-grid > :first-child img { aspect-ratio: 4/3; } }
.ug-shot figcaption {
  position: absolute; left: 0; bottom: 0; right: 0;
  background: color-mix(in srgb, var(--charcoal) 88%, transparent); color: var(--bone);
  font-size: 10px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  padding: 8px 10px;
}
.ug-proof-note { margin-top: var(--space-6); padding: var(--space-6); background: var(--ground-alt); border-left: 4px solid var(--brand); }

/* ---------- documented cases, timestamped ---------- */
/* no hard black box. The photographs are the evidence, the card is only a frame. */
.ug-case { border: 0; border-radius: 18px; overflow: hidden; background: var(--bone);
  margin-bottom: var(--space-6);
  box-shadow: 0 1px 2px rgba(29,26,23,.07), 0 14px 30px -14px rgba(29,26,23,.20); }
.ug-case__pair { display: grid; grid-template-columns: 1fr; }
@media (min-width: 720px) { .ug-case__pair { grid-template-columns: repeat(2, minmax(0,1fr)); } }
.ug-case__pair figure { margin: 0; position: relative; border-bottom: 3px solid var(--bone); }
.ug-case__pair figure:last-child { border-bottom: 0; }
@media (min-width: 720px) {
  .ug-case__pair figure { border-bottom: 0; border-right: 3px solid var(--bone); }
  .ug-case__pair figure:last-child { border-right: 0; }
}
.ug-case__pair img { width: 100%; display: block; aspect-ratio: 16/9; object-fit: cover; }
.ug-case__stamp {
  position: absolute; top: 0; left: 0;
  background: var(--charcoal); color: var(--bone);
  font-size: 10px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  padding: 7px 11px;
}
.ug-case__stamp--after { background: var(--rust); }
.ug-case__foot { border-top: 1px solid rgba(29,26,23,.14); padding: var(--space-4) var(--space-6); display: flex; gap: var(--space-4); justify-content: space-between; flex-wrap: wrap; align-items: baseline; }
.ug-case__what { font-size: 15px; font-weight: 800; margin: 0; }
.ug-case__src { font-size: 11px; font-weight: 600; color: var(--ink-muted); margin: 0; letter-spacing: .04em; }
.ug-case__foot--solo { justify-content: flex-start; }

/* ---------- talking crew ---------- */
.ug-moss { width: 100%; height: auto; display: block; border-radius: var(--radius-md); }
.ug-hero__crew { position: relative; }
.ug-moss__say {
  position: absolute; left: 50%; bottom: -14px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; padding: var(--space-2) var(--space-4);
  background: var(--accent); color: var(--on-accent);
  border: 0; border-radius: var(--radius-pill);
  font-family: var(--font); font-size: 14px; font-weight: 900; letter-spacing: -.01em;
  cursor: pointer; white-space: nowrap;
}
.ug-moss__say:hover { filter: brightness(.95); }
.ug-moss__say:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.ug-moss__ico { font-size: 11px; line-height: 1; }
.ug-moss__say[data-playing="true"] .ug-moss__ico { font-size: 13px; }
@media (prefers-reduced-motion: reduce) { .ug-moss { content: none; } }

/* ---------- sales page ---------- */
.ug-lede { font-size: clamp(19px,2.6vw,24px); line-height: 1.4; font-weight: 500; margin: 0; max-width: 30ch; }
.ug-max { max-width: 62ch; }

/* problem: photo left, argument right */
.ug-split { display: grid; gap: var(--space-8); align-items: center; }
@media (min-width: 900px) { .ug-split { grid-template-columns: 1fr 1fr; gap: var(--space-12); align-items: center; } }
.ug-split--flip > :first-child { order: 2; }
@media (max-width: 899px) { .ug-split--flip > :first-child { order: 0; } }
.ug-split > * { min-width: 0; }
.ug-photo { margin: 0; border: var(--stroke-rule) solid var(--charcoal); }
.ug-photo img { width: 100%; display: block; aspect-ratio: 5/4; object-fit: cover; }

/* the three mechanism beats */
.ug-beats { display: grid; gap: var(--space-6); counter-reset: b; }
@media (min-width: 820px) {
  /* Subgrid, so the number, the heading and the body each sit on a SHARED row across all three
     columns. Without it a heading that wraps to two lines in one column pushes only that column's
     body down, and the row stops reading as a row. The per-element margins below become the
     parent's row-gap for the same reason: a margin cannot align across siblings, a gap can. */
  .ug-beats { grid-template-columns: repeat(3, minmax(0,1fr)); column-gap: var(--space-8); row-gap: var(--space-3); }
  .ug-beat { display: grid; grid-template-rows: subgrid; grid-row: span 3; }
  .ug-beat::before { margin-bottom: 0; }
  .ug-beat h3 { margin: 0; }
}
.ug-beat { counter-increment: b; }
.ug-beat::before {
  content: counter(b, decimal-leading-zero);
  display: block; font-size: 11px; font-weight: 800; letter-spacing: .2em;
  color: var(--brand); margin-bottom: var(--space-3);
}
.ug-beat h3 { font-size: 21px; font-weight: 900; letter-spacing: -.015em; margin: 0 0 var(--space-3); line-height: 1.15; }
.ug-beat p { margin: 0; color: var(--ink-muted); }

/* the objection block, deliberately plain */
.ug-obj { border-top: 4px solid var(--charcoal); padding-top: var(--space-8); }
.ug-obj__q { font-size: clamp(22px,3.2vw,30px); font-weight: 900; letter-spacing: -.02em; margin: 0 0 var(--space-6); max-width: 22ch; line-height: 1.1; }

/* the close */
.ug-close { display: grid; gap: var(--space-8); align-items: start; }
@media (min-width: 980px) { .ug-close { grid-template-columns: 1fr 1fr; gap: var(--space-12); } }
.ug-close > * { min-width: 0; }
.ug-next { list-style: none; margin: var(--space-6) 0 0; padding: 0; }
.ug-next li { display: grid; grid-template-columns: 26px 1fr; gap: var(--space-4); padding: var(--space-3) 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 30%, transparent); }
.ug-next li:last-child { border-bottom: 0; }
.ug-next b { font-family: var(--font); font-size: 11px; font-weight: 800; letter-spacing: .16em; color: var(--ink-muted); padding-top: 3px; }
.ug-next span { font-size: 16px; font-weight: 600; }


/* ============================================================
   ILLUSTRATED BRAND LAYER
   The crew are not decoration inside a grid. They live in the page:
   at scale, breaking edges, talking. Sections are colour fields, not cards.
   ============================================================ */

/* full-bleed colour scenes */
/* clip, not hidden: overflow:hidden makes the scene a scroll container, which
   silently kills position:sticky anywhere inside it. clip crops identically
   without creating one. */
.ug-scene { position: relative; overflow: clip; }
/* dark scenes must REMAP the role tokens, not just set a background, or muted text
   keeps resolving to the light theme's dark brown on a dark ground. */
.ug-scene--petrol, .ug-scene--deep {
  color: var(--ink);
  --ink: var(--bone);
  --ink-muted: #c3d3d0;
  --brand: var(--bone);
  --on-brand: var(--petrol);
  --line: #8fb0ab;
  --focus: var(--hivis);
  --ground-alt: #245a60;
}
.ug-scene--petrol { background: var(--petrol); }
.ug-scene--deep   { background: var(--petrol-deep); }
.ug-scene--bone   { background: var(--bone); color: var(--charcoal); }
.ug-scene--cream  { background: var(--cream); color: var(--charcoal); }
.ug-scene--hivis  { background: var(--hivis); color: var(--charcoal); }
.ug-scene__in { position: relative; z-index: 2; }

/* a character placed in the scene, allowed to break the edge */
.ug-char { position: absolute; z-index: 1; pointer-events: none; user-select: none; }
.ug-char img { width: 100%; height: auto; display: block; }

/* speech, the running device */

/* big statement type, the brand's real voice */
.ug-shout {
  font-size: clamp(40px, 8.5vw, 104px); line-height: .92; font-weight: 900;
  letter-spacing: -.035em; margin: 0; text-wrap: balance;
}
.ug-mid { font-size: clamp(28px, 4.6vw, 52px); line-height: 1; font-weight: 900; letter-spacing: -.025em; margin: 0; text-wrap: balance; }

/* the notice as a prop, not a card */
.ug-prop { transform: none; }


/* the stamp as a real prop */
.ug-stamp-prop {
  display: inline-block; transform: rotate(-9deg);
  border: 5px solid var(--rust); color: var(--rust);
  border-radius: 8px; padding: 8px 22px;
  font-size: clamp(22px,3.4vw,34px); font-weight: 900; letter-spacing: .14em; line-height: 1;
}
[data-theme="petrol"] .ug-stamp-prop, .ug-scene--petrol .ug-stamp-prop, .ug-scene--deep .ug-stamp-prop { border-color: var(--hivis); color: var(--hivis); }

/* served stamp sitting on the day-of photo */
.ug-case__pair figure { overflow: hidden; }
.ug-served {
  position: absolute; right: 12px; bottom: 12px; transform: rotate(-8deg);
  border: 4px solid var(--rust); color: var(--rust);
  background: color-mix(in srgb, var(--bone) 86%, transparent);
  border-radius: 7px; padding: 5px 14px;
  font-size: 17px; font-weight: 900; letter-spacing: .12em; line-height: 1; pointer-events: none;
}

/* hero, composed not gridded */
.ug-hero { align-items: center; }
.ug-hero__crew { position: relative; padding-bottom: 0; }
.ug-moss { border-radius: 0; }
.ug-moss__say { display: none; }
.ug-sound {
  position: absolute; top: 8px; right: 8px; width: 34px; height: 34px;
  border-radius: 999px; border: 0; cursor: pointer;
  background: color-mix(in srgb, var(--charcoal) 50%, transparent); color: var(--bone);
  font-size: 14px; display: grid; place-items: center;
}
.ug-sound:hover { background: var(--charcoal); }
.ug-sound:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.ug-hero__say { margin-top: var(--space-6); }

/* ============================================================
   SCENES — full bleed colour, giant type, crew at scale
   ============================================================ */
/* clip, not hidden: overflow:hidden makes the scene a scroll container, which
   silently kills position:sticky anywhere inside it. clip crops identically
   without creating one. */
.ug-scene { position: relative; overflow: clip; padding-block: clamp(56px, 9vw, 120px); }
.ug-scene__in { position: relative; z-index: 3; }

/* a crew member used as a huge background shape */
/* full strength, true colour. The copy sits above it on .ug-scene__in's z-index. */
.ug-ghost { position: absolute; z-index: 1; opacity: 1; pointer-events: none; }
.ug-ghost img { width: 100%; display: block; }

/* a crew member standing in the scene, breaking the edge */
.ug-actor { position: absolute; z-index: 2; pointer-events: none; }
.ug-actor img { width: 100%; display: block; }



/* the shout */
.ug-shout { font-size: clamp(40px, 5.8vw, 82px); line-height: .94; font-weight: 900;
  letter-spacing: -.04em; margin: 0; text-wrap: balance; }
.ug-mid { font-size: clamp(28px, 4.2vw, 54px); line-height: 1.02; font-weight: 900;
  letter-spacing: -.028em; margin: 0; text-wrap: balance; }

/* rounded photo blocks, like the reference */
.ug-pic { margin: 0; border-radius: 22px; overflow: hidden; background: var(--charcoal); }
.ug-pic img { width: 100%; display: block; aspect-ratio: 4/3; object-fit: cover; }
.ug-pic--tall img { aspect-ratio: 3/4; }
/* no photo is ever taller than the screen it is being read on */
.ug-pic img { height: auto; max-height: 68svh; }

/* stamp prop */
.ug-stamp-prop { display:inline-block; transform: rotate(-9deg);
  border: 6px solid var(--rust); color: var(--rust); border-radius: 10px;
  padding: 10px 26px; font-size: clamp(24px,4vw,44px); font-weight: 900;
  letter-spacing: .14em; line-height: 1; }
.ug-scene--petrol .ug-stamp-prop, .ug-scene--deep .ug-stamp-prop { border-color: var(--hivis); color: var(--hivis); }

/* served on the day-of frame */
.ug-case__pair figure { overflow: hidden; }
.ug-served { position:absolute; right:12px; bottom:12px; transform: rotate(-8deg);
  border:4px solid var(--rust); color:var(--rust);
  background: color-mix(in srgb, var(--bone) 86%, transparent);
  border-radius:7px; padding:5px 14px; font-size:17px; font-weight:900;
  letter-spacing:.12em; line-height:1; pointer-events:none; }

/* notice as a prop */
.ug-prop { transform: none; }

/* hero */
.ug-hero__crew { position: relative; padding-bottom: 0; }
/* he floats: no radius, no ground, no box. The alpha WebM carries transparency and the
   MP4 fallback is rendered on the hero's own colour. */
.ug-moss { border-radius: 0; background: transparent; }
.ug-moss__say { display: none; }
.ug-sound { position:absolute; top:10px; right:10px; width:36px; height:36px;
  border-radius:999px; border:0; cursor:pointer; z-index:4;
  background: color-mix(in srgb, var(--charcoal) 52%, transparent); color: var(--bone);
  font-size:15px; display:grid; place-items:center; }
.ug-sound:hover { background: var(--charcoal); }
.ug-sound:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* generic stack */
.ug-stack > * + * { margin-top: var(--space-6); }

/* ============================================================
   HERO — fills the viewport, form on the right, tape on the fold
   ============================================================ */
.ug-scene--hero {
  min-height: 100svh;
  display: flex; flex-direction: column;
  padding-block: 0;
}
.ug-scene--hero > .ug-scene__in { flex: 1; display: flex; flex-direction: column; }
.ug-scene--hero .ug-hero {
  flex: 1; align-items: center;
  padding-block: var(--space-8) var(--space-12);
}
@media (min-width: 900px) {
  .ug-scene--hero .ug-hero { grid-template-columns: 1fr minmax(0, 520px); gap: var(--space-12); }
}

/* the tape sits ON the fold, not after it */
.ug-hazard--fold { position: relative; z-index: 4; flex: none; }

/* The hero ghost is the real drawing, at full fidelity. It used to be flattened
   with brightness(0) invert(1) to stop its outline reading as seams, which also
   killed every line in it and left the flat colour blob. Opacity does that job
   without destroying the illustration. */
.ug-scene--hero .ug-ghost img { filter: none; }

/* form in the hero: tighter so it fits a viewport */
.ug-hero__form .ug-notice-doc { max-width: none; margin-inline: auto; }
.ug-hero__form .ug-notice-doc__crew { padding-top: var(--space-4); }
.ug-hero__form .ug-notice-doc__crew img { max-width: 44px; }
.ug-hero__form .ug-notice-doc__body { padding: var(--space-4) var(--space-6) var(--space-6); }
.ug-hero__form .ug-hivis-band { padding: var(--space-3) var(--space-6); }
.ug-hero__form .ug-hivis-band__big { font-size: 17px; }
.ug-hero__form .ug-notice-doc__foot { padding: var(--space-3); }
.ug-hero__form .ug-notice-doc__foot img { width: 104px; }
.ug-hero__form .ug-steps { margin-bottom: var(--space-4); }

/* hero type comes down a touch now the form shares the space */
.ug-scene--hero .ug-shout { font-size: clamp(38px, 6.4vw, 78px); }
.ug-scene--hero .ug-lede { font-size: clamp(17px, 1.9vw, 21px); max-width: 34ch; }

/* the close section no longer holds a form */
.ug-close__empty { display: none; }
@media (min-width: 980px) { .ug-close { grid-template-columns: 1fr; } }


/* The notice is a bone document. It must carry its own tokens so it is readable in any
   scene it is dropped into, otherwise a dark scene's remapped --ink turns its text bone
   on bone and the field values vanish. */
.ug-notice-doc {
  color: var(--charcoal);
  --ink: var(--charcoal);
  --ink-muted: #5e544a;
  --ground: var(--bone);
  --ground-alt: var(--cream);
  --brand: var(--petrol);
  --line: #5e544a;
  --focus: var(--petrol);
}
/* hero no longer holds a form */
.ug-scene--hero .ug-hero { grid-template-columns: 1fr; }
@media (min-width: 900px) { .ug-scene--hero .ug-hero { grid-template-columns: 1fr; } }
.ug-scene--hero .ug-shout { font-size: clamp(44px, 8.4vw, 104px); max-width: 14ch; }
.ug-scene--hero .ug-lede { max-width: 40ch; }
@media (min-width: 980px) { .ug-close { grid-template-columns: 1fr 1fr; } }
.ug-close__empty { display: block; }

/* ---------- hero composition ---------- */
/* Two columns again: the argument, and the character it is about. */
.ug-scene--hero .ug-hero { grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .ug-scene--hero .ug-shout { font-size: clamp(44px, 6.2vw, 86px); max-width: 12ch; }
}
/* the ghost now only exists to give the flat ground some depth.
   Whole silhouette, low and quiet, never a cropped fragment. */
/* BIG, and secondary. The character is backdrop branding at the scale of the
   scene, not a sticker in the corner. It is the real drawing: the version this
   replaces was moss.svg run through brightness(0) invert(1) to kill a seam,
   which also killed every line in it and left a flat colour blob. Held at an
   opacity where the line work still reads but the headline still wins. */
/* Sized off BOTH axes, never a pixel cap. A crew member is square, so a width
   in vw alone overflows a short window and a max-width in px stops growing on
   a big one. min() of a width share and a height share takes whichever runs
   out first, which is what makes them sit on every screen. */
.ug-scene--hero .ug-ghost--hero {
  right: -6%; bottom: -14%; width: min(46vw, 82svh); max-width: none;
}


/* ---------- the line-up ---------- */
/* A police line-up drawn straight onto the scene: no panel behind it, bone
   hairlines for the height chart, a solid bone floor, and a charcoal name
   plate under each suspect. The scale is in millimetres because that is the
   size these things really are. */
/* The scale is absolutely positioned and OUT of the flow. As padding-left it
   pushed all four columns right, so the grid was never symmetric inside the
   rules and no amount of nudging the plates was going to fix it. */
.ug-wall {
  position: relative; margin-top: var(--space-12);
  padding: var(--space-6) 0 0;
  --floor: 4px; --rule-gap: 36px;
  /* The scale is authored as a rule COUNT, not a height. Everything else (how tall
     the wall has to be, how many rules get painted, where the top number lands) is
     derived from it, so desktop reaching 50mm and mobile stopping at 40mm is one
     number changed in one place instead of four rules kept in sync by hand. */
  --rules: 5;
  display: flex; flex-direction: column; justify-content: flex-end;
  /* + room above the top rule for the number that sits on top of it */
  min-height: calc(var(--rules) * var(--rule-gap) + var(--floor) + 18px);
}
/* the height rules, stopping at the floor */
.ug-wall::before {
  /* Anchored to the floor and given an exact height, so the wall can be taller than
     the scale without the gradient inventing an extra unlabelled rule at the top. */
  content: ''; position: absolute; left: 0; right: 0; bottom: var(--floor);
  height: calc(var(--rules) * var(--rule-gap));
  /* The repeating unit must be EXACTLY --rule-gap. Written as `transparent 0 gap, line gap
     gap+1px` the period became gap+1px, so the rules crept 1px per rule away from the labels,
     which are placed at N * gap: by the fourth the number was 4px off its line and read as
     floating in empty wall. The 1px line now sits INSIDE the gap instead of being added to it. */
  background: repeating-linear-gradient(to top,
    transparent 0 calc(var(--rule-gap) - 1px), rgba(247, 244, 236, .22) calc(var(--rule-gap) - 1px) var(--rule-gap));
}
.ug-wall::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--floor); background: var(--bone);
}
/* Every rule gets a number and every number sits just ABOVE its rule, at both
   widths. Spacing them evenly between the top and the floor only lines them up by
   accident: the rules are drawn every --rule-gap up from the floor, so the labels
   are placed off the same number. `bottom: N * gap` puts a span's bottom edge on
   rule N, which is already "above the line"; the -3px is breathing room so the
   digits don't touch it. */
.ug-wall__scale {
  position: absolute; left: 0; top: 0; bottom: var(--floor); width: 0;
  font-size: 10px; font-weight: 900; letter-spacing: .12em; color: rgba(247, 244, 236, .48);
}
.ug-wall__scale span {
  position: absolute; left: 0; line-height: 1;
  translate: 0 -3px;
}
.ug-wall__scale span:nth-child(1) { bottom: calc(5 * var(--rule-gap)); }
.ug-wall__scale span:nth-child(2) { bottom: calc(4 * var(--rule-gap)); }
.ug-wall__scale span:nth-child(3) { bottom: calc(3 * var(--rule-gap)); }
.ug-wall__scale span:nth-child(4) { bottom: calc(2 * var(--rule-gap)); }
.ug-wall__scale span:nth-child(5) { bottom: calc(1 * var(--rule-gap)); }
.ug-wall__row, .ug-placards {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4);
}
@media (min-width: 860px) {
  .ug-wall__row, .ug-placards { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-6); }
  /* Four placards, three shared rows: plate, tag, body. */
  .ug-placards { row-gap: var(--space-4); }
  .ug-placard { display: grid; grid-template-rows: subgrid; grid-row: span 3; row-gap: var(--space-4); }
  .ug-placard__tag { margin-top: 0; }
  .ug-placard p { margin-top: 0; }
}
.ug-wall__row { position: relative; z-index: 1; align-items: end; padding-bottom: var(--floor); }
/* sized by HEIGHT so all four stand on one line: each drawing has its own ratio,
   and sizing by width lands every baseline somewhere different */
/* --crew-h drives the height AND the float above the line, so they cannot
   drift. The brand system is explicit: nothing touches the line, everybody
   floats a clear gap above it of about 6% of their height. */
.ug-wall { --crew-h: clamp(68px, 8vw, 168px); }
.ug-wall__row img { height: var(--crew-h); width: auto; max-width: 100%;
  display: block; margin: 0 auto calc(var(--crew-h) * .08);
  object-fit: contain; object-position: bottom; }

.ug-placards { margin-top: var(--space-8); text-align: center; }
.ug-lineup__foot { margin: var(--space-16) auto 0; max-width: 54ch; text-align: center;
  font-size: 17px; line-height: 1.55; color: var(--ink-muted); }
/* the name plate, hung under the floor line */
.ug-plate {
  display: inline-block; background: var(--charcoal); color: var(--bone);
  border-radius: 4px; padding: 5px 14px;
  font-size: 11px; font-weight: 900; letter-spacing: .16em; text-transform: uppercase;
}
.ug-placard__tag { display: block; margin-top: var(--space-4); font-size: 10px; font-weight: 900;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted); }
.ug-placard p { margin: var(--space-4) auto 0; max-width: 24ch; font-size: 14px;
  line-height: 1.5; color: var(--ink-muted); text-wrap: pretty; }

/* ---------- the call to action, repeated ---------- */
/* The page had one form, at position two, and then asked for nothing again for
   six screens. Every sales page earns the ask twice more: after the proof, and
   after the risk is taken off the table.
   It is a band, so it gets a band's proportions: room to breathe, a headline
   that lands in two lines, and one button big enough to be the only thing to
   do. An 58px crew member parked beside the button read as clip art. */
.ug-cta-band { background: var(--hivis); color: var(--charcoal); --ink: var(--charcoal); --ink-muted: #5c5039; }
.ug-cta-band .ug-wrap {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  /* --space-10 does not exist. The locked scale is 1,2,3,4,6,8,12,16, so the whole shorthand
     was invalid and BOTH gaps fell back to `normal` — which is 0 on a wrapped flex row. On a
     phone that put the sub-line hard against the button with nothing between them. */
  gap: var(--space-6) var(--space-12); padding-block: clamp(36px, 5vw, 64px);
}
.ug-cta-band h2 {
  margin: 0; font-size: clamp(28px, 3.6vw, 46px); line-height: 1.02;
  font-weight: 900; letter-spacing: -.025em; max-width: 22ch; text-wrap: balance;
}
.ug-cta-band__say { min-width: 0; }
.ug-cta-band__sub { margin: var(--space-4) 0 0; font-size: 15px; font-weight: 600; color: var(--ink-muted); }
.ug-cta-band .ug-btn { background: var(--charcoal); color: var(--bone); }
.ug-btn--lg { padding: 18px 38px; font-size: 18px; }

/* ---------- questions ---------- */
.ug-qa { display: grid; gap: var(--space-6); margin-top: var(--space-12); }
@media (min-width: 860px) {
  /* Same rule: the question and the answer each get a shared row, so a two-line question on the
     left cannot drop the answer on the right out of line with it. */
  .ug-qa { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-12); row-gap: var(--space-8); }
  .ug-qa > * { display: grid; grid-template-rows: subgrid; grid-row: span 2; row-gap: var(--space-3); }
  .ug-qa__a { margin-top: 0; }
}
.ug-qa__q { margin: 0; font-size: 18px; font-weight: 900; letter-spacing: -.01em; }
.ug-qa__a { margin: var(--space-3) 0 0; font-size: 15px; line-height: 1.5; color: var(--ink-muted); }


/* ---------- statement scenes are one screen ---------- */
/* Luke's rule: big and bold, not much in the section, and it fits on the screen.
   A statement that runs past the fold stops being a statement, and one that only
   half fills it reads as janky. Content heavy scenes (the form, the proof cases)
   are deliberately NOT in here and grow naturally. */
.ug-scene--screen {
  min-height: 100svh;
  display: grid;
  align-content: center;
}
.ug-scene--screen > .ug-wrap { width: 100%; }
/* four lines of shout is a paragraph, not a statement */
.ug-scene--screen .ug-shout { max-width: 20ch; }


/* ---------- backdrop characters vs the copy ---------- */
/* At full colour a character behind a paragraph makes it unreadable, and on a
   phone the copy fills the width so there is nowhere clear to stand. So on
   narrow screens the scene opens a band at the bottom and the character lives
   in it, below the copy rather than under it. */
/* Desktop placements. These were inline style attributes, which beat every
   media query below them and left the lichen sitting on top of a paragraph on
   every phone. Per this repo's own rule: layout never goes in a style attr. */
/* stands in the band the scene opens for it, high enough that its face clears
   the bottom of the screen rather than just the top of its head */
.ug-ghost--how { left: -4%; top: 54%; width: min(36vw, 52svh); max-width: none; }
/* Lying on his side, leaning in off the right edge, three times the size. The
   drawing is square so rotating it does not change the box, and `rotate` is its
   own property so it composes with the animation's `translate` instead of
   fighting it. */
/* Pinned in PIXELS, not per cent. A percentage offset against a capped width
   means the wider the screen the less of him shows, which is how he ended up
   as a grey edge with no eyes at 1885 while looking right at 1440. 1320 wide
   hanging 740 off the edge shows the same 580px of him at every width, and the
   eyes sit at 488 across, inside that. */
/* Upright, in the bottom right corner, and he comes up out of it diagonally.
   Sized so the face clears the bottom edge: his eyes sit at y=104 of a 200 box,
   so a little over half of him has to be above the corner. */
.ug-ghost--guarantee {
  right: -7%; bottom: -15%; top: auto;
  width: min(44vw, 76svh); max-width: none;
}
.ug-actor--blast { right: 4%; bottom: -7%; width: min(33vw, 66svh); max-width: none; }

@media (max-width: 899px) {
  /* On a phone they stand centre stage, near the full width with a gutter each
     side, and pop up out of the bottom. Both insets set with width:auto is what
     centres them AND sizes them to the padded width in one go. The scene opens
     enough floor underneath that a character this size never reaches the copy. */
  /* Two classes, so it beats .ug-scene--standing. That rule sits later in the
     file at equal specificity, so it was quietly winning with its desktop
     150px and the character was standing on the last line of the copy. */
  /* Only a scene with somebody standing in the bottom of it needs the floor.
     The line-up has nobody, and was getting 400px of empty petrol under it. */
  .ug-scene--screen:has(.ug-ghost, .ug-actor) { padding-bottom: 344px; }
  .ug-scene--screen .ug-ghost,
  .ug-scene--screen .ug-actor,
  .ug-scene--hero .ug-ghost--hero {
    left: var(--space-6); right: var(--space-6); top: auto; bottom: -5%;
    width: auto; max-width: none;
    --peek-x: 0; --peek-y: 94%;
  }
  /* The hero has to hold the copy, the character AND the tape inside one
     viewport. On a 375px iPhone with Safari's chrome showing that is about
     700px to spend, so the character is capped rather than run to the full
     width: square, so capping the width caps the height. left:0/right:0 with
     auto margins is what centres an absolutely positioned box. */
  /* ONE number. The character's size and the room reserved for it were two
     separate values I kept tuning against each other, so fixing either one
     opened a gap or pushed the tape off the fold. --char drives both now. */
  /* the same idea on a phone, where the height share is the binding one:
     a 375x700 window has far less room under the copy than a 430x932 one */
  .ug-scene--hero { --char: min(88vw, 44svh); }
  /* A tall phone has a third of a screen spare no matter where the copy sits:
     bottom aligned it pools above the headline, centred it splits either side
     of the button. The answer is not where to put the hole, it is to stop
     having one. Hero type scales with the viewport now so the copy fills its
     share, the character takes more of the height, and what is left is split
     evenly rather than banked in one place. */
  .ug-scene--hero .ug-hero {
    padding-block: var(--space-4) calc(var(--char) * .9 - 18px);
    align-items: center;
  }
  .ug-scene--hero .ug-shout { font-size: clamp(42px, 12.5vw, 76px); max-width: 11ch; }
  .ug-scene--hero .ug-lede { font-size: clamp(16px, 4.4vw, 22px); max-width: 30ch; }

  /* He comes OUT of the fold, not in from off screen like the rest. A fifth of
     him stays behind the tape at rest, so he reads as climbing out of it rather
     than standing on it. The room reserved above still comes off --char, minus
     the part that is behind the fold. */
  .ug-scene--hero .ug-ghost--hero {
    left: 0; right: 0; margin-inline: auto;
    /* a tenth behind the tape, not a fifth: the mouth sits at 75% of the
       drawing, so a fifth hidden clipped it. He is still cut by the fold, just
       not through the face. */
    bottom: calc(var(--char) * -.1);
    width: var(--char); max-width: none;
  }
  /* svh, NOT dvh. dvh retargets every time Safari's bottom bar shows or
     hides, so the hero resizes and everything in it shifts while you are
     scrolling. svh is measured with the chrome showing and never moves. The
     cost is a sliver of the next section when the bar retracts, which is far
     less odd than a hero that changes size under your thumb. */
  .ug-scene--hero { min-height: 100svh; }
}


/* ---------- the crew, on scroll ---------- */
/* Each one waits behind the edge it lives on, slides out when its scene comes
   on screen, has a look side to side, and slides back when you scroll past.
   --peek is how far off stage it waits, signed for the edge it enters from. */
/* Each one enters from the edge it is anchored to: the ones sitting on the
   bottom pop up out of it, the one hung off the top drops in. Sliding a bottom
   anchored character in sideways reads as wrong because you can see the edge it
   should have come from. `translate` rather than `transform` so it does not
   fight the pupils' own transform. */
.ug-crew-anim {
  translate: var(--peek-x, 0) var(--peek-y, 0);
  /* going away is quick, so it has ducked out before the scene leaves screen */
  transition: translate .38s cubic-bezier(.45, 0, .85, .4);
  will-change: translate;
}
/* arriving takes its time, and overshoots a little on the way in */
.ug-crew-anim.is-out {
  translate: 0 0;
  transition: translate .8s cubic-bezier(.2, .86, .3, 1.08);
}
/* the hero holds back a beat, so the headline lands before he does rather than
   the two arriving on top of each other the moment the page opens */
.ug-crew-anim.is-out.ug-ghost--hero { transition-delay: .55s; }
/* A full body length. 62% was tuned on a phone, where nine tenths of him is
   already behind the tape so he only had to duck. On a desktop he is fully out,
   so 62% left his seed capsules poking over the fold after he had gone. The
   phone keeps its shorter travel from the rule further down. */
.ug-ghost--hero    { --peek-y: 100%; }
.ug-actor--blast   { --peek-y: 94%; }
.ug-ghost--how     { --peek-y: 94%; }
/* straight up out of the bottom, like the rest of them */
.ug-ghost--guarantee { --peek-y: 62%; }

/* the look, once it has finished arriving */
@keyframes ug-look {
  0%, 18%   { transform: translateX(0); }
  32%, 46%  { transform: translateX(-5px); }
  60%, 74%  { transform: translateX(5px); }
  88%, 100% { transform: translateX(0); }
}
/* Twice, not once. The keyframe already holds still for its last 12% and its first 18%, so a
   second iteration reads as look - pause - look rather than a single sweep that is over before
   you have settled on the character. The two holds give about a second of stillness between. */
.ug-crew-anim.is-out .ug-pupil {
  animation: ug-look 3.4s ease-in-out .85s 2 both;
}
/* the one peering round the edge does not sweep, he darts: quick glances with
   held pauses between them, which is what reads as shifty rather than serene */
@keyframes ug-shifty {
  0%, 12%   { translate: 0 0; }
  16%, 30%  { translate: -6px 0; }
  34%, 38%  { translate: 0 0; }
  42%, 58%  { translate: 6px 0; }
  62%, 70%  { translate: 5px -2px; }
  74%, 88%  { translate: -5px 0; }
  94%, 100% { translate: 0 0; }
}
.ug-ghost--guarantee.is-out .ug-pupil {
  animation: ug-shifty 4.6s cubic-bezier(.85, 0, .15, 1) .7s infinite;
}

@media (prefers-reduced-motion: reduce) {
  .ug-crew-anim { translate: none; transition: none; }
  .ug-crew-anim.is-out .ug-pupil { animation: none; }
}


/* A scene with somebody standing in it gives them floor to stand on. Without it
   the copy runs to the bottom of the screen and the character can only show the
   top of its head without covering a paragraph. */
.ug-scene--standing { padding-bottom: clamp(150px, 17vh, 250px); }
/* No mobile override here. It used to set 176px, which landed after the 368px
   the screen scenes get on a phone and, at equal specificity, quietly won. The
   character then stood on the last line of the copy. */


/* ---------- the line-up on a phone ---------- */
/* No pinning, no stepping, no scroll hijack. "The usual suspects" only works if
   you can see all four at once, so the phone gets the same composition as the
   desktop, fitted: four on the wall, one baseline, and the names and what they
   do as a plain list underneath. It costs one screen instead of four, on a page
   whose job is to get somebody to a form. */
.ug-track, .ug-stick { display: contents; }

@media (max-width: 899px) {
  .ug-wall { padding-left: 30px; --rule-gap: 21px; --rules: 4; }
  /* 50 is desktop only. A phone does not have the wall height for a fifth rule without
     shrinking the gaps to the point the numbers collide, so mobile tops out at 40 and
     keeps every mark below it. */
  .ug-wall__scale { left: 0; font-size: 9px; }
  .ug-wall__scale span:nth-child(1) { display: none; }
  .ug-wall__row { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-2); }
  .ug-wall { --crew-h: clamp(58px, 17vw, 108px); }

  /* the placards become a list: the plate names them, the line says what they do */
  .ug-placards { grid-template-columns: 1fr; gap: 0; margin-top: var(--space-6); text-align: left; }
  .ug-placard {
    display: grid; grid-template-columns: auto 1fr; align-items: center;
    column-gap: var(--space-4); row-gap: var(--space-2);
    padding: var(--space-4) 0;
    border-top: 1px solid rgba(247, 244, 236, .14);
  }
  .ug-placard__tag { margin-top: 0; }
  .ug-placard p { grid-column: 1 / -1; margin: 0; max-width: none; }
  .ug-lineup__foot { margin-top: var(--space-12); }
}


/* ---------- the clerk's marks ---------- */
/* NOT .ug-stamp: that name is already the rust SERVED component, and reusing
   it clobbered that AND compounded its rotate with this one. */
/* The bubbles were the squatters talking. This is the other voice: somebody has
   been through the file and stamped it. It extends the notice, which is the
   page's central device, rather than inventing a second idiom.
   Rust stays reserved for SERVED and the moss seed capsules, per the brand
   system, so these are stamped in the scene's own ink. */
.ug-mark {
  display: inline-block; margin-top: var(--space-12);
  border: 3px solid currentColor; border-radius: 6px;
  padding: 7px 16px;
  font-size: clamp(12px, 1.3vw, 15px); font-weight: 900;
  letter-spacing: .2em; text-transform: uppercase; line-height: 1;
  color: var(--ink-muted);
  rotate: -3.5deg;
  /* a stamp is pressed unevenly, so it is never quite solid */
  opacity: .82;
}
.ug-mark--right { rotate: 2.5deg; }
.ug-mark--mid { rotate: -2deg; }
@media (max-width: 899px) { .ug-mark { margin-top: var(--space-8); letter-spacing: .16em; } }


/* ---------- the notice's closing band ---------- */
/* Petrol, not hi-vis and not black either. With the wordmark bar gone the band sits directly under
   the Next button, and yellow on yellow leaves the button with no edge to it.
   The brand system allows one hi-vis per surface anyway, and on this one the
   button is the action, so the button keeps it. */
.ug-notice-doc .ug-hivis-band {
  background: var(--petrol); color: var(--bone);
}
.ug-notice-doc .ug-hivis-band__sub { color: #a9c0bd; }


/* ---------- the ask arrives from the direction you came ---------- */
/* Scrolling down, it rises into place from below. Scrolling back up, it drops
   in from above. Same band either way, but the motion tells you which way you
   are travelling through the page, so the ask reads as somewhere you have
   arrived at rather than something that was always sitting there.
   The class is added by script, so with no JS everything is simply visible. */
.ug-reveal > * {
  opacity: 0;
  translate: 0 var(--from, 30px);
  transition: opacity .42s ease, translate .66s cubic-bezier(.2, .9, .28, 1);
}
.ug-reveal.is-in > * { opacity: 1; translate: 0 0; }
.ug-reveal.is-in > * + * { transition-delay: .09s; }

@media (prefers-reduced-motion: reduce) {
  .ug-reveal > * { opacity: 1; translate: none; transition: none; }
}


/* ---------- the verdict ---------- */
/* Four suspects, then the ruling lands across them. Rust, because a stamp is
   exactly what the brand reserves rust for. It THUMPS rather than fades: it
   arrives oversized and slams down to size with a touch of overshoot, which is
   what a stamp does. Opacity snaps in a twelfth of a second so it never looks
   like it is drifting in. */
.ug-verdict {
  /* Anchored off the crew, not off the wall box: the wall is now taller than the crew
     (it runs to 50mm) so a percentage of the wall would float the stamp above them. */
  position: absolute; left: 50%; bottom: calc(var(--floor) + var(--crew-h) * .55); z-index: 3;
  margin: 0; pointer-events: none;
  border: 6px solid var(--rust); border-radius: 10px;
  /* no fill: the faces are the brand, so they read through the stamp rather
     than being blotted out by it */
  color: var(--rust); background: none;
  padding: 8px clamp(16px, 2.4vw, 34px);
  font-size: clamp(21px, 3.6vw, 47px); font-weight: 900;
  letter-spacing: .14em; text-transform: uppercase; line-height: 1;
  translate: -50% -50%;
  rotate: -11deg;
  scale: 1.5;
  opacity: 0;
  transition: opacity .12s linear, scale .3s cubic-bezier(.2, 1.5, .4, 1);
}
/* late on purpose: the crew settle, then the ruling comes down on them */
.ug-verdict.is-in { opacity: 1; scale: 1; transition-delay: .62s; }

@media (prefers-reduced-motion: reduce) {
  .ug-verdict { transition: none; }
  .ug-verdict.is-in { transition-delay: 0s; }
}


/* ---------- hero copy: one column, one gap ---------- */
/* Every element in here used to carry its own margin, one of them inline. They
   fought, they collapsed, and the button ended up touching the paragraph above
   it. One flex column with one gap means the rhythm is a single number that
   scales with the viewport, and there is nothing left to drift. */
.ug-hero__copy {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: clamp(18px, 3.2vh, 34px);
}
.ug-hero__copy > * { margin: 0; }
.ug-hero__lede { color: var(--ink-muted); }


/* The phone in the nav. The only actionable thing up there, so it is the only thing that
   looks actionable: hivis on the dark hero ground, charcoal text, pill. Left as a real
   tel: link despite format-detection=telephone=no, which is there to stop iOS turning
   "24 months" and "3 to 18 months" into phone links. */
.ug-nav__tel {
  background: var(--hivis); color: var(--charcoal); border-radius: 999px;
  padding: 8px 16px; font-weight: 800; letter-spacing: .01em; white-space: nowrap;
  display: inline-flex; align-items: center; gap: var(--space-2);
}
.ug-nav__tel:hover { filter: brightness(1.06); }
/* The icon is the phone on a phone only. On desktop the number itself is the button. */
.ug-nav__telicon { display: none; }

@media (max-width: 719px) {
  /* A filled pill carrying ten digits is the heaviest thing in the header and fights the
     wordmark for the top of the page. On a phone the number is a tap, not a thing to read,
     so it becomes an outline glyph: same action, a fraction of the weight. */
  /* Bone, not hivis, and deliberately: the header already sits above a hivis "Get a price"
     button, and a second yellow object up here pulls the eye off the headline. In bone the
     glyph weighs the same as the wordmark it sits opposite, which is what balances the row.
     Written at .ug-nav__links .ug-nav__tel so it beats `.ug-nav__links a { color: var(--ink) }`
     rather than winning by accident. */
  .ug-nav__links .ug-nav__tel {
    background: none; color: var(--bone);
    border: 2px solid currentColor; border-radius: 999px;
    width: 44px; height: 44px; padding: 0; justify-content: center;   /* 44px is the tap target */
  }
  .ug-nav__links .ug-nav__tel:active { color: var(--hivis); }
  .ug-nav__tel:hover { filter: none; }
  .ug-nav__telicon { display: block; width: 20px; height: 20px; }
  .ug-nav__telnum { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; }   /* kept for screen readers */
}
.ug-footer__meta a { color: inherit; text-decoration: none; font-weight: 700; }
.ug-footer__meta a:hover { color: var(--hivis); }
@media (max-width: 719px) {
  /* On a phone the number matters more than the section links: calling is the action, and the
     links only jump down the same page. Matches the width at which the row stops fitting. */
  .ug-nav__links a:not(.ug-nav__tel) { display: none; }
}

/* ---------------------------------------------------------------------------
   Legal pages (/privacy). One column of readable prose on bone, nothing
   decorative: these pages exist to be read, not to sell. No underlines.
   --------------------------------------------------------------------------- */
.ug-legal { max-width: 70ch; }
.ug-legal .ug-mid { margin: var(--space-2) 0 var(--space-4); }
.ug-legal .ug-lede { max-width: 48ch; margin-bottom: var(--space-8); color: var(--ink-muted); }
.ug-legal h2 {
  font-size: clamp(16px, 1.8vw, 19px); font-weight: 900; line-height: 1.25;
  letter-spacing: .01em; text-transform: uppercase;
  margin: var(--space-8) 0 var(--space-3);
}
.ug-legal p { font-size: 15px; line-height: 1.65; margin: 0 0 var(--space-3); }
.ug-legal ul { margin: 0 0 var(--space-4); padding-left: var(--space-6); }
.ug-legal li { font-size: 15px; line-height: 1.65; margin-bottom: var(--space-2); }
.ug-legal a { color: var(--rust); font-weight: 700; text-decoration: none; }
.ug-legal a:hover { color: var(--charcoal); }

@media (max-width: 899px) {
  /* Stacked, the meta line is the last thing above the fine print, so it centres
     with it rather than sitting hard left under a centred line. */
  .ug-footer__row { justify-content: center; text-align: center; }
  .ug-footer__meta { width: 100%; }
}
