/* EV Car Buyers.
   The design system rebuilt onto the owner's mockup, per
   docs/brand/MOCKUP-BUILD-SPEC.md. Dark first, Orbitron for the brand tier and
   Inter for everything that is read, one violet to blue gradient.

   The old light theme, the Space Grotesk and Instrument Sans pairing and the
   indigo and violet token families are retired. Every colour below was sampled
   off static/brand/owner/image-1785209007568.webp.

   Order is load bearing. Several section rules win on source order alone.

   1  tokens            2  reset and page       3  type
   4  base elements     5  layout and surfaces  6  utilities
   7  components        8  chrome               9  page sections
   10 motion            11 reduced motion
*/

/* ==========================================================================
   1. Tokens
   ========================================================================== */

:root{
  /* ---- surfaces, sampled ------------------------------------------------ */
  --dark-header:   #000000;   /* the header bar, pure black                  */
  --dark-page:     #0A0A0F;   /* the base dark, page and footer              */
  --dark-hero:     #04060C;   /* under the hero photograph                   */
  --dark-strip:    #101213;   /* the four across feature strip               */
  --dark-panel:    #07070F;   /* the get your offer panel                    */
  --dark-card:     #06070C;   /* the how it works card                       */
  --light-surface: #F7F6F9;   /* how it works, why choose, FAQ. one colour   */
  --light-card:    #FFFFFF;   /* inputs and cards on a light field           */

  /* ---- the gradient ----------------------------------------------------- */
  /* Fills only. White on it is 6.08:1 at the violet end, 7.90:1 at the blue. */
  --grad-from: #8122F3;
  --grad-to:   #0B2CF2;
  --grad-fill: linear-gradient(90deg, #8122F3 0%, #0B2CF2 100%);

  /* Gradient as text needs lifted stops. The true stops measure 2.50:1 at the
     blue end on the near black page, which fails even the 3:1 large text bar. */
  --grad-display:  linear-gradient(90deg, #8B5CF6 0%, #3D5CFF 100%); /* 4.66 and 3.93 on #0A0A0F */
  --grad-text:     linear-gradient(90deg, #A97DFF 0%, #4A6BFF 100%); /* 6.64 and 4.55 on #0A0A0F */
  --grad-on-light: linear-gradient(90deg, #6A2BE8 0%, #2B3BE0 100%); /* 6.24 and 6.95 on #F7F6F9 */

  /* Flat fallbacks. Declared before the clip so a browser without
     background-clip:text shows readable text rather than nothing at all. */
  --grad-display-flat:  #8B5CF6;
  --grad-text-flat:     #A97DFF;
  --grad-on-light-flat: #6A2BE8;

  /* ---- text ------------------------------------------------------------- */
  --on-dark:     #FFFFFF;   /* 19.75 on the page   */
  --on-dark-2:   #C7CAD3;   /* 12.06               */
  --on-dark-3:   #9AA0AE;   /*  7.30               */
  --on-light:    #0A0A0F;   /* 18.35 on #F7F6F9    */
  --on-light-2:  #55555F;   /*  6.84               */
  --on-light-3:  #6E6E78;   /*  5.04 on white, placeholders */
  --ink-indigo:  #2A1A8C;   /* the step numerals   */
  --icon-indigo: #4C1FC4;   /* every icon in a light section */
  --star:        #8B26EC;   /* the five hero stars, decorative */
  --lilac-100:   #E4E2FA;   /* the step number discs */

  /* ---- lines ------------------------------------------------------------ */
  --line-dark:    rgba(255,255,255,.12);
  --line-dark-2:  rgba(255,255,255,.28);
  --line-light:   #E7E6EB;
  --line-light-2: #D8D7DE;
  --line-dotted:   repeating-linear-gradient(90deg, #C9C7D2 0 5px, transparent 5px 11px);
  /* the same dots turned 90 degrees, for the stacked steps on a phone */
  --line-dotted-v: repeating-linear-gradient(180deg, #C9C7D2 0 5px, transparent 5px 11px);

  /* ---- state. the form card is the only place any of this shows ---------- */
  --alert:    #C2264B;   /* 5.72 on white */
  --alert-bg: #FDF1F4;
  --alert-dk: #93123A;

  /* ---- radii ------------------------------------------------------------ */
  --r-xs:    6px;
  --r-sm:   10px;
  --r-md:   12px;
  --r-lg:   20px;
  --r-xl:   28px;
  --r-2xl:  32px;
  --r-pill: 999px;

  /* ---- shadows. the mockup is flat, there are only these ---------------- */
  --sh-1:       0 1px 2px rgba(6,6,14,.08);
  --sh-2:       0 10px 28px rgba(6,6,14,.10);
  --sh-card:    0 24px 64px rgba(6,6,20,.28);
  --sh-card-hi: 0 30px 76px rgba(6,6,20,.38);
  --sh-grad:    0 10px 26px rgba(94,36,240,.34);
  --sh-grad-hi: 0 14px 34px rgba(94,36,240,.46);
  --sh-input:   0 2px 10px rgba(0,0,0,.28);

  /* ---- spacing. four pixel base, nothing off the scale ------------------ */
  --s-1:   4px;  --s-2:   8px;  --s-3:  12px;  --s-4:  16px;  --s-5:  20px;
  --s-6:  24px;  --s-7:  32px;  --s-8:  40px;  --s-9:  48px;  --s-10: 56px;
  --s-11: 64px;  --s-12: 80px;  --s-13: 96px;  --s-14: 120px;

  /* The section floor and ceiling, named rather than reached for off the scale.
     The mockup is a dense editorial page: normalised to a common width it fits
     the header, the whole hero, the whole feature strip and the whole how it
     works section inside one 1440 by 900 screen. At 96px a section this page
     needed nearly four screens to reach the footer and read as a generously
     spaced generic site instead. These are the mockup's ratios, not its literal
     pixels, whose body copy works out at about 12px and is not shippable. */
  --s-sec:    68px;
  --s-sec-lg: 88px;

  /* ---- layout ----------------------------------------------------------- */
  --container: 1280px;
  --gutter: clamp(20px, 4vw, 40px);
  --head-h: 76px;
  --overlap: 104px;   /* the one protrusion distance */

  /* ---- z index. the whole scale, nothing outside it --------------------- */
  --z-under: 0;
  --z-base:  1;
  --z-raise: 2;
  --z-card:  3;
  --z-head: 50;
  --z-skip:100;

  /* ---- motion ----------------------------------------------------------- */
  --ease: cubic-bezier(.22,.61,.36,1);
  --dur-1: 180ms;   /* hover and state changes */
  --dur-2: 200ms;   /* cards, accordions       */
  --dur-3: 400ms;   /* the gradient sweep      */
  --dur-4: 520ms;   /* entrances               */
  --stagger: 70ms;
  --rise: 18px;

  /* ---- type, families --------------------------------------------------- */
  /* D1. The brand board labels Orbitron the heading font. The mockup renders
     every heading in a geometric grotesque that is not Orbitron and only sets
     the logo in it. Orbitron is the brand tier here: eyebrows, step numerals,
     the plate, the footer headings. Flip --font-display to swap that. */
  --font-display: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-body:    'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-brand:   'Orbitron', 'Inter', system-ui, sans-serif;

  /* ---- type, sizes. every clamp is a solved slope, 375 to 1280 ---------- */
  --t-h1:      clamp(2.25rem,   1.7838rem + 1.989vw,  3.375rem);  /* 36 -> 54 */
  --t-h2:      clamp(1.75rem,   1.6465rem + 0.442vw,  2rem);      /* 28 -> 32 */
  --t-h2-sm:   clamp(1.625rem,  1.4696rem + 0.663vw,  2rem);      /* 26 -> 32 */
  --t-h3:      clamp(1.5rem,    1.3446rem + 0.663vw,  1.875rem);  /* 24 -> 30 */
  --t-h4:      clamp(1.125rem,  1.0732rem + 0.221vw,  1.25rem);   /* 18 -> 20 */
  --t-lead:    clamp(1rem,      0.9223rem + 0.3315vw, 1.1875rem); /* 16 -> 19 */
  --t-sub:     clamp(0.9375rem, 0.9116rem + 0.1105vw, 1rem);      /* 15 -> 16 */
  --t-item:    clamp(1rem,      0.9741rem + 0.1105vw, 1.0625rem); /* 16 -> 17 */
  --t-meta:    clamp(0.875rem,  0.8491rem + 0.1105vw, 0.9375rem); /* 14 -> 15 */
  --t-eyebrow: clamp(0.6875rem, 0.6616rem + 0.1105vw, 0.75rem);   /* 11 -> 12 */
  --t-num:     clamp(1.125rem,  1.0732rem + 0.221vw,  1.25rem);   /* 18 -> 20 */
  --t-figure:  clamp(2.5rem,    1.9723rem + 2.2541vw, 4rem);      /* 40 -> 64 */
  --t-body:    0.9375rem;   /* 15, item body and section paragraphs */
  --t-btn:     1rem;
  --t-btn-sm:  0.9375rem;
  --t-nav:     0.9375rem;
  --t-legal:   0.8125rem;

  /* ---- surface locals. every one is reset by a light surface ------------ */
  --txt:          var(--on-dark);
  --txt-2:        var(--on-dark-2);
  --txt-3:        var(--on-dark-3);
  --line-c:       var(--line-dark);
  --icon-c:       var(--grad-from);
  --eyebrow-grad: var(--grad-text);
  --eyebrow-flat: var(--grad-text-flat);
  --link-grad:    var(--grad-text);
  --link-flat:    var(--grad-text-flat);
  --focus-c:      #A78BFA;   /* 7.26 on the dark page */
}

/* Every light region resets the same locals, so a component dropped onto a
   light surface inherits the right text, line, icon and focus colours without
   a single surface specific rule of its own. */
.on-light,
.sec--wash, .sec--light,
.card, .aside-card, .infopanel, .lead-form,
.how, .faq-sec, .offer__panel--light,
.cta, .s-why, .s-moments, .s-sell__panel{
  --txt:          var(--on-light);
  --txt-2:        var(--on-light-2);
  --txt-3:        var(--on-light-3);
  --line-c:       var(--line-light);
  --icon-c:       var(--icon-indigo);
  --eyebrow-grad: var(--grad-on-light);
  --eyebrow-flat: var(--grad-on-light-flat);
  --link-grad:    var(--grad-on-light);
  --link-flat:    var(--grad-on-light-flat);
  --focus-c:      #5B2BE0;   /* 6.80 on #F7F6F9 */
}

@media (max-width: 900px){
  :root{ --overlap: 56px; --head-h: 64px }
}


/* ==========================================================================
   2. Reset and page
   ========================================================================== */

*,*::before,*::after{ box-sizing: border-box }

html{
  -webkit-text-size-adjust: 100%;
  color-scheme: dark;          /* the scrollbar and the form UI follow the page */
  scrollbar-gutter: stable;    /* so a scrollbar cannot shift a full bleed row */
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--head-h) + 16px);
}

/* The light cards hold real form controls, so they hand the UA back a light
   scheme. Without this a native select popup opens dark on a white field. */
.on-light, .sec--wash, .sec--light,
.card, .aside-card, .infopanel, .lead-form,
.how, .faq-sec, .offer__panel--light,
.cta, .s-why, .s-moments, .s-sell__panel{
  color-scheme: light;
}

body{
  margin: 0;
  background: var(--dark-page);
  color: var(--txt-2);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  font-optical-sizing: auto;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;            /* clip, not hidden. hidden breaks position:sticky */
}

h1,h2,h3,h4,p,figure,ul,ol,dl,dd{ margin: 0 }
ul,ol{ padding: 0; list-style: none }
fieldset{ border: 0; margin: 0; padding: 0; min-width: 0 }
legend{ padding: 0 }
img,svg,video{ display: block; max-width: 100% }
img{ height: auto }
button,input,select,textarea{ font: inherit; color: inherit }
main:focus{ outline: none }

/* The header is sticky, so anything scrolled to has to be held clear of it.
   html.scroll-padding-top above is the one place that happens. It covers hash
   navigation, :target, keyboard focus jumps and the scrollIntoView calls
   form.js makes when step two arrives and when Back is pressed, so form.js
   needs no change and neither does the markup.

   It is the one place on purpose. Scroll padding on the container and scroll
   margin on the element stack, and this file declared roughly a header's worth
   of each: measured on a phone, a jump to #get-your-offer landed the form 160px
   down the screen, 95px below a 65px header, with a band of empty hero above
   it, and step two of the form landed 91px below the header the same way. One
   allowance, in one place. Do not put a scroll-margin-top back on any of these
   three unless the container's padding is removed at the same time. */
:target,
#get-your-offer,
.lead-form{ scroll-margin-top: 0 }

/* form.js toggles the hidden attribute on the two fieldsets, and a display
   rule anywhere else in the cascade beats the attribute's UA default, so the
   whole two step flow dies without this. Never remove it. */
[hidden]{ display: none !important }


/* ==========================================================================
   3. Type
   ========================================================================== */

h1,h2,h3,h4,
.t-display,.t-h2,.t-h3,.t-h4{
  font-family: var(--font-display);
  color: var(--txt);
  text-wrap: balance;
}
p{ text-wrap: pretty; color: var(--txt-2) }
li{ color: var(--txt-2) }
strong,b{ font-weight: 700; color: var(--txt) }

h1,.t-display{ font-size: var(--t-h1); font-weight: 800; line-height: 1.02; letter-spacing: -.03em }
h2,.t-h2     { font-size: var(--t-h2); font-weight: 800; line-height: 1.12; letter-spacing: -.022em }
h3,.t-h3     { font-size: var(--t-h3); font-weight: 700; line-height: 1.15; letter-spacing: -.02em }
h4,.t-h4     { font-size: var(--t-h4); font-weight: 700; line-height: 1.3;  letter-spacing: -.012em }

/* Optical alignment. Large glyphs carry left side bearing, so a heading set
   flush to its container reads as indented next to the copy under it. */
h1,.t-display{ margin-left: -.02em }
h2,.t-h2     { margin-left: -.015em }

.lead,.lede{ font-size: var(--t-lead); font-weight: 400; line-height: 1.55; color: var(--txt-2); max-width: 40ch }
.lede--wide{ max-width: 52ch }
.sub,.section-sub{ font-size: var(--t-sub); line-height: 1.6; color: var(--txt-2); max-width: 56ch }
.small{ font-size: var(--t-meta); line-height: 1.55; color: var(--txt-3) }
.tiny{ font-size: var(--t-legal); line-height: 1.5; font-weight: 500; color: var(--txt-3) }
.legal{ font-size: var(--t-legal); line-height: 1.6; color: var(--txt-3) }

.figure{
  font-family: var(--font-display); font-weight: 800;
  font-size: var(--t-figure); line-height: 1; letter-spacing: -.03em; color: var(--txt);
}

/* Numbers must not jitter between states and a zero must never read as an O. */
.figure,.stat__value,.flow__num,.reason__index,.step__disc,.plate input{
  font-variant-numeric: lining-nums tabular-nums slashed-zero;
  font-feature-settings: "zero" 1, "kern" 1;
}

/* vertical rhythm inside a text block */
h1 + p, h1 + .lede, h1 + .lead{ margin-top: var(--s-5) }
h2 + p, h2 + .lede, h2 + .lead{ margin-top: var(--s-4) }
h3 + p{ margin-top: var(--s-3) }
p + p{ margin-top: var(--s-4) }


/* ==========================================================================
   4. Base elements. links, focus, the skip link
   ========================================================================== */

a{ color: var(--link-flat); text-decoration-thickness: 1px; text-underline-offset: .18em }
a:hover{ color: var(--txt) }

:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline: 3px solid var(--focus-c);
  outline-offset: 2px;
}

.skip{
  position: fixed; top: var(--s-3); left: var(--s-3); z-index: var(--z-skip);
  padding: var(--s-3) var(--s-5);
  background: var(--dark-page); color: #fff; text-decoration: none;
  font-weight: 600; border: 1px solid var(--line-dark-2);
  border-radius: var(--r-sm); box-shadow: var(--sh-card);
  transform: translateY(calc(-100% - var(--s-6)));
  transition: transform var(--dur-1) var(--ease);
}
.skip:focus-visible{ transform: none }


/* ==========================================================================
   5. Layout and surfaces
   ========================================================================== */

.wrap{
  width: 100%;
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--tight{ --container: 940px }
.wrap--prose{ --container: 720px }

.sec{ padding-block: var(--s-sec) }
.sec--lg{ padding-block: var(--s-sec-lg) }
.sec--wash, .sec--light{ background: var(--light-surface); color: var(--txt) }
.sec--tint{ background: var(--dark-strip) }
/* No mobile override here, and none on .how, .faq-sec, .people or .site-foot
   either. Every section reads --s-sec and --s-sec-lg, and section 9.10 steps
   those two tokens down twice. One rhythm, one place to change it. */

.grid12{
  display: grid; grid-template-columns: repeat(12, minmax(0,1fr));
  column-gap: var(--s-6); row-gap: var(--s-8);
}
@media (max-width: 900px){
  .grid12{ grid-template-columns: repeat(6, minmax(0,1fr)); row-gap: var(--s-7) }
  .grid12 > *{ grid-column: 1 / -1 }
}

/* the named line grid, for a row that has to run off one edge */
.sec-grid{
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [content-start] min(var(--container), 100% - (var(--gutter) * 2))
    [content-end] minmax(var(--gutter), 1fr)
    [full-end];
  row-gap: var(--s-8);
}
.sec-grid > *     { grid-column: content }
.sec-grid > .full { grid-column: full }
.sec-grid > .right{ grid-column: content-start / full-end }
.sec-grid > .left { grid-column: full-start / content-end }

/* the protruding card. one distance, used by the hero form and the page head
   aside. Whatever sits underneath opts in with .sec--receives. */
.protrude{ position: relative; z-index: var(--z-card); margin-bottom: calc(var(--overlap) * -1) }
.sec--receives, .band--receives{
  position: relative; z-index: var(--z-under);
  padding-top: calc(var(--s-sec) + var(--overlap));
}


/* ==========================================================================
   6. Utilities
   ========================================================================== */

.visually-hidden{
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.stack > * + *{ margin-top: var(--stack, var(--s-4)) }
.center{ text-align: center }
.center .lede, .center .lead{ margin-inline: auto }
.nowrap{ white-space: nowrap }

/* ---- gradient text ------------------------------------------------------ */
/* The flat colour is unconditional and the clip is added only where it is
   supported, so text can never end up transparent on nothing. */

.grad,.hl{ color: var(--grad-display-flat) }
.grad--text{ color: var(--link-flat) }

@supports ((-webkit-background-clip: text) or (background-clip: text)){
  .grad,.hl{
    background-image: var(--grad-display);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
  .grad--text{
    background-image: var(--link-grad);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}

/* ---- the eyebrow, measured off the mockup ------------------------------- */
/* Cap height 7px, AUSTRALIA'S TRUSTED EV BUYERS spans 316px across 29
   characters. That is roughly 0.25em of extra advance, locked at 0.22em so the
   trailing space cannot push the block.

   The body face, not Orbitron. Enlarged, the mockup's eyebrows are plainly the
   same grotesque as its headings, tracked out: pointed A, curved S, straight
   legged R, none of which Orbitron draws. The brief says the image wins over
   the summary. Orbitron stays where it is genuinely logo adjacent, on the step
   numerals, the rego plate and the footer headings. */

.eyebrow{
  display: block; margin: 0 0 var(--s-4);
  font-family: var(--font-body);
  font-size: var(--t-eyebrow); font-weight: 700; line-height: 1.2;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--eyebrow-flat);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)){
  .eyebrow{
    background-image: var(--eyebrow-grad);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}
/* letter-spacing adds a trailing space after the last glyph */
.center .eyebrow, .eyebrow--center{ text-align: center; margin-right: -.22em }

/* ---- rules -------------------------------------------------------------- */

.rule{ height: 1px; border: 0; margin: 0; background: var(--line-c) }
.rule--on-band{ background: var(--line-dark) }
.rule-v,.rule--v{ width: 1px; height: auto; align-self: stretch; border: 0; margin: 0; background: var(--line-c) }

/* ---- surface texture ---------------------------------------------------- */
/* One noise recipe, blended as overlay so it is safe on a dark field and on a
   light one. The templates carry both modifiers. */

.grain{ position: relative; isolation: isolate }
.grain::after{
  content: ""; position: absolute; inset: 0; z-index: 1;
  pointer-events: none; border-radius: inherit; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='3' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}
.grain--dark::after { opacity: .40 }
.grain--light::after{ opacity: .22 }

/* the lit dark field. the hero's light, without the photograph */
.mesh,.mesh--dark{
  position: relative; isolation: isolate;
  background-color: var(--dark-hero);
  background-image:
    radial-gradient(58% 52% at  8%   0%, rgba(129,34,243,.30) 0%, rgba(129,34,243,0) 62%),
    radial-gradient(52% 48% at 92%   6%, rgba(11,44,242,.30)  0%, rgba(11,44,242,0)  64%),
    radial-gradient(70% 60% at 78% 100%, rgba(94,36,240,.22)  0%, rgba(94,36,240,0)  66%);
}

/* The light streak field, the same texture the home page's offer panel carries.
   It is a background rather than an img because it is decoration with nothing
   to describe, and the mask fades it out under the words so nothing has to be
   set on top of a bright streak. */
.streaks{ position: relative; isolation: isolate }
.streaks::before{
  content: ""; position: absolute; inset: 0; z-index: var(--z-under);
  pointer-events: none;
  background-image: url("../img/brand/streaks-wide.jpg");
  background-position: 100% 62%; background-size: cover; background-repeat: no-repeat;
  opacity: .55;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0,0,0,.4) 38%, #000 78%);
          mask-image: linear-gradient(90deg, transparent 0%, rgba(0,0,0,.4) 38%, #000 78%);
}
.streaks--curve::before{
  background-image: url("../img/brand/streaks-curve.jpg");
  background-position: 100% 50%; opacity: .5;
}

/* measured texture, used once */
.blueprint{ position: relative; isolation: isolate }
.blueprint::before{
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(129,34,243,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(129,34,243,.07) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000 30%, transparent 100%);
          mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000 30%, transparent 100%);
}

/* a hairline that catches the light on one corner */
.edge{ position: relative; isolation: isolate }
.edge::after{
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  border: 1px solid rgba(255,255,255,.7); border-radius: inherit;
  -webkit-mask: radial-gradient(17% 29% at 0 0, #000 0%, transparent 90%);
          mask: radial-gradient(17% 29% at 0 0, #000 0%, transparent 90%);
}

/* a gradient hairline border. two per page, no more */
.gborder{ position: relative }
.gborder::before{
  content: ""; position: absolute; inset: 0; z-index: 1;
  pointer-events: none; user-select: none;
  border-radius: inherit; padding: 1px;
  background: var(--grad-fill);
  -webkit-mask: linear-gradient(#000,#000) content-box, linear-gradient(#000,#000);
          mask: linear-gradient(#000,#000) content-box, linear-gradient(#000,#000);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}

/* ---- photography -------------------------------------------------------- */

.photo{ position: relative; isolation: isolate; overflow: hidden; margin: 0; border-radius: var(--r-lg) }
.photo img{ display: block; width: 100%; height: 100%; object-fit: cover }

/* The brand photography is already violet and blue. The treatment only calms
   daylight stock so it sits against the dark page, it does not recolour. */
.duo img,.duo-img{ filter: saturate(.9) brightness(.92) contrast(1.04) }
.duo::after{
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(155deg, rgba(129,34,243,.16) 0%, rgba(129,34,243,0) 46%, rgba(4,6,12,.34) 100%);
}

/* The people photography is bright daylight stock. On a light section it can
   sit as it is. On the dark page it cannot: at full brightness a half width
   photograph reads as a lit window cut into the band, and the eye goes to it
   instead of to the words beside it. This is the same treatment, further down,
   with the violet the rest of the page is lit by carried across it. */
.duo--deep img,.duo--deep.duo-img{ filter: saturate(.66) brightness(.62) contrast(1.10) }
.duo--deep::after{
  background: linear-gradient(155deg, rgba(129,34,243,.30) 0%, rgba(129,34,243,.05) 44%, rgba(4,6,12,.66) 100%);
}
.photo__scrim{
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(to top, rgba(4,6,12,.86) 0%, rgba(4,6,12,.42) 38%, rgba(4,6,12,0) 72%);
}
.photo__caption{
  position: absolute; left: var(--s-6); right: var(--s-6); bottom: var(--s-6); z-index: 4;
  color: #fff; font-size: var(--t-meta); max-width: 30ch;
}


/* ==========================================================================
   7. Components
   ========================================================================== */

/* ---- 7.1 buttons -------------------------------------------------------- */
/* A bare .btn is the gradient primary, because that is what the templates ask
   for everywhere. .btn--grad is the explicit name the mockup spec uses. */

.btn,
.lead-form .go,
.lead-form .back{
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-3);
  min-height: 52px; padding-inline: 26px;
  font-family: var(--font-body); font-size: var(--t-btn); font-weight: 600;
  line-height: 1; letter-spacing: -.005em; text-align: center; text-decoration: none;
  border: 1px solid transparent; border-radius: var(--r-sm);
  cursor: pointer; appearance: none;
  transition:
    color               var(--dur-1) var(--ease),
    background-color    var(--dur-1) var(--ease),
    border-color        var(--dur-1) var(--ease),
    box-shadow          var(--dur-1) var(--ease),
    transform           var(--dur-1) var(--ease),
    background-position var(--dur-3) var(--ease);
}

.btn, .btn--grad, .btn--primary, .lead-form .go{
  color: #fff;
  background-color: var(--grad-from);
  background-image: var(--grad-fill);
  background-size: 200% 100%;
  background-position: 0 0;
  /* No resting glow. Neither the mockup nor the brand board's header preview
     puts a halo behind a gradient pill: both sit crisp on black, and on the
     near black page a violet shadow reads as the pill bleeding into the field.
     The lift stays on hover, where it is a response rather than chrome. */
  box-shadow: none;
}
.btn:hover, .btn--grad:hover, .btn--primary:hover, .lead-form .go:hover{
  color: #fff; background-position: 100% 0;
  box-shadow: var(--sh-grad); transform: translateY(-1px);
}
.btn:active, .btn--grad:active, .btn--primary:active, .lead-form .go:active{ transform: translateY(0) }
.btn[disabled], .lead-form .go[disabled]{
  background-image: none; background-color: #2A2A33; color: #9AA0AE;
  box-shadow: none; transform: none; cursor: not-allowed;
}

/* outlined, on dark. the hero's second button */
.btn--ghost{
  background-image: none; background-color: transparent;
  color: var(--on-dark); border-color: var(--line-dark-2); box-shadow: none;
}
.btn--ghost:hover{
  background-image: none; background-color: rgba(255,255,255,.05);
  border-color: rgba(255,255,255,.5); color: var(--on-dark);
  box-shadow: none; transform: none;
}

/* outlined, on light. Learn More, and the form's Back */
.btn--outline, .btn--quiet, .lead-form .back{
  background-image: none; background-color: transparent;
  color: var(--on-light); border-color: var(--line-light-2);
  box-shadow: none; min-height: 48px;
}
.btn--outline:hover, .btn--quiet:hover, .lead-form .back:hover{
  background-image: none; background-color: transparent;
  border-color: var(--icon-indigo); color: var(--icon-indigo);
  box-shadow: none; transform: none;
}
/* the same button, when it has to sit on a dark surface */
.on-dark .btn--quiet, .pagehead .btn--quiet, .band .btn--quiet, .hero .btn--quiet{
  color: var(--on-dark); border-color: var(--line-dark-2);
}
.on-dark .btn--quiet:hover, .pagehead .btn--quiet:hover,
.band .btn--quiet:hover, .hero .btn--quiet:hover{
  color: var(--on-dark); border-color: rgba(255,255,255,.5); background-color: rgba(255,255,255,.05);
}

.btn--pill{ border-radius: var(--r-pill) }
.btn--lg{ min-height: 56px; padding-inline: 32px; font-size: 1.0625rem }
.btn--sm{ min-height: 44px; padding-inline: 22px; font-size: var(--t-btn-sm) }
.btn--block, .lead-form .go, .lead-form .back{ display: flex; width: 100% }

/* a text link that carries an arrow */
.btn-link, .link-arrow, .vcard__link, .faq-sec__all{
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-meta); font-weight: 600; text-decoration: none;
  color: var(--link-flat);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)){
  .btn-link, .link-arrow, .vcard__link, .faq-sec__all{
    background-image: var(--link-grad);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
  /* an svg inside a clipped box paints from currentColor, which is now
     transparent, so the arrow is handed its own colour back */
  .btn-link svg, .link-arrow svg, .vcard__link svg, .faq-sec__all svg{ color: var(--link-flat) }
}
.btn-link svg, .link-arrow svg, .vcard__link svg, .faq-sec__all svg{
  flex: none; transition: transform var(--dur-1) var(--ease);
}
.btn-link:hover svg, .link-arrow:hover svg, .faq-sec__all:hover svg,
.vcard:hover .vcard__link svg{ transform: translateX(4px) }

/* ---- 7.2 section headers ------------------------------------------------ */

.shead{ max-width: 46ch; margin-bottom: var(--s-9) }
.shead--center{ margin-inline: auto; text-align: center }
.shead p{ margin-top: var(--s-4) }

.shead-split{ display: grid; gap: var(--s-4); margin-bottom: var(--s-9) }
.shead-split h2{ max-width: 20ch }
.shead-split .lede{ max-width: 44ch }
@media (min-width: 901px){
  .shead-split{
    grid-template-columns: minmax(0,1.15fr) minmax(0,1fr);
    column-gap: var(--s-9); align-items: end;
  }
  .shead-split .lede{ padding-bottom: .35em }
}

/* ---- 7.3 the generic surface -------------------------------------------- */

.card{
  background: var(--light-card); color: var(--txt);
  border-radius: var(--r-lg); box-shadow: var(--sh-card);
}

/* ---- 7.4 the lead form card --------------------------------------------- */
/* Restyled only. Every hook form.js reads survives untouched: .lead-form,
   [data-step], .next, .back, #make, #model, #model-map, .chips,
   input[name="condition"] and the .err pattern. */

.lead-form{
  position: relative; isolation: isolate;
  padding: var(--s-7); border-radius: var(--r-xl);
  background: var(--light-card); color: var(--txt); box-shadow: var(--sh-card);
}

.lead-form .step{ display: block }
.lead-form .step > * + *{ margin-top: var(--s-5) }

.lead-form .stepmark{
  margin: 0; font-family: var(--font-brand);
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--grad-on-light-flat);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)){
  .lead-form .stepmark{
    background-image: var(--grad-on-light);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}
.lead-form .step h2{
  margin-top: var(--s-3); font-size: var(--t-h3);
  line-height: 1.15; letter-spacing: -.02em; color: var(--on-light);
}
.lead-form .sub{ margin-top: var(--s-2); font-size: var(--t-meta); color: var(--on-light-2); max-width: none }
.lead-form .sub + *{ margin-top: var(--s-6) }
.lead-form .pair{ display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4) }
.lead-form .cardfoot{
  margin-top: var(--s-4); font-size: var(--t-meta);
  color: var(--on-light-2); text-align: center; max-width: none;
}
.lead-form .back{ margin-top: var(--s-3) }

.errbox{
  margin-bottom: var(--s-5); padding: var(--s-4) var(--s-5); max-width: none;
  background: var(--alert-bg); color: var(--alert-dk);
  border: 1px solid rgba(194,38,75,.28); border-radius: var(--r-md);
  font-size: var(--t-meta); font-weight: 600;
}

/* ---- 7.5 fields --------------------------------------------------------- */

.field{ display: block; min-width: 0 }

.lead-form label,
.lead-form .fieldlabel{
  display: block; margin-bottom: var(--s-2);
  font-size: var(--t-meta); font-weight: 600; color: var(--on-light);
}
.lead-form .opt{ font-weight: 400; color: var(--on-light-2) }

.lead-form input,
.lead-form select{
  display: block; width: 100%; min-height: 52px; padding: 0 var(--s-4);
  font-size: var(--t-item); line-height: 1.2; color: var(--on-light);
  background: var(--light-card);
  border: 1px solid var(--line-light-2); border-radius: var(--r-md);
  appearance: none;
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.lead-form input::placeholder{ color: var(--on-light-3) }
.lead-form input:hover,
.lead-form select:hover{ border-color: #B6B4C0 }
.lead-form input:focus,
.lead-form select:focus{ border-color: var(--icon-indigo); box-shadow: 0 0 0 3px rgba(76,31,196,.14) }

.lead-form select{
  padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%236E6E78' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-4) center;
  background-size: 12px 8px;
}
.lead-form select:invalid{ color: var(--on-light-3) }

.lead-form .err{
  margin-top: var(--s-2); max-width: none;
  font-size: var(--t-meta); font-weight: 600; color: var(--alert);
}
.lead-form .field:has(.err) input,
.lead-form .field:has(.err) select{ border-color: var(--alert); background-color: var(--alert-bg) }

/* the rego field, set as a plate. the one flourish in the form */
.lead-form .plate input{
  height: 60px; text-align: center; text-transform: uppercase;
  font-family: var(--font-brand); font-weight: 700;
  font-size: 1.25rem; letter-spacing: .12em;
  border-width: 2px; border-color: var(--on-light); border-radius: var(--r-sm);
  background: #FBFBFD;
}
.lead-form .plate input::placeholder{ letter-spacing: .12em; color: var(--on-light-3) }
.lead-form .plate input:focus{ border-color: var(--icon-indigo) }

/* ---- 7.6 chips, the condition selector ---------------------------------- */
/* The radios stay in the DOM at 1px and opacity 0, because form.js reads
   :checked on them. */

.chips{ display: grid; grid-template-columns: repeat(auto-fit, minmax(96px,1fr)); gap: var(--s-2) }
.chip{ display: block; margin: 0 }
.chip input{
  position: absolute; width: 1px; height: 1px; opacity: 0;
  margin: 0; padding: 0; pointer-events: none;
}
.chip span{
  display: flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 var(--s-3);
  font-size: var(--t-meta); font-weight: 600; text-align: center;
  color: var(--on-light-2); background: var(--light-card);
  border: 1px solid var(--line-light-2); border-radius: var(--r-sm);
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease);
}
.chip:hover span{ border-color: var(--icon-indigo); color: var(--on-light) }
.chip input:checked + span{ color: #fff; border-color: transparent; background-image: var(--grad-fill) }
.chip input:focus-visible + span{ outline: 3px solid var(--focus-c); outline-offset: 2px }

/* form.js validates the group itself, because reportValidity on a 1px radio
   shows a seller nothing at all. */
.field.is-invalid .chip span,
.field:has(.err) .chip span{ border-color: var(--alert); background-color: var(--alert-bg) }
.field.is-invalid .chip input:checked + span,
.field:has(.err) .chip input:checked + span{ background-image: var(--grad-fill); border-color: transparent }

/* ---- 7.7 small parts ---------------------------------------------------- */

.pill{
  display: inline-flex; align-items: center; gap: var(--s-3); max-width: none;
  padding: var(--s-2) var(--s-4) var(--s-2) var(--s-3);
  font-size: var(--t-legal); font-weight: 600; color: var(--txt);
  background: rgba(255,255,255,.06);
  border: 1px solid var(--line-c); border-radius: var(--r-pill);
}
.pill__dot{
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background-image: var(--grad-fill); box-shadow: 0 0 0 4px rgba(129,34,243,.18);
}

.badges{ display: flex; flex-wrap: wrap; gap: var(--s-2); margin: 0; padding: 0 }
.badge{
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  font-size: var(--t-legal); font-weight: 600; line-height: 1.2; color: var(--txt);
  background: rgba(255,255,255,.06);
  border: 1px solid var(--line-c); border-radius: var(--r-pill);
}
.badge__tick{ color: var(--icon-c); flex: none }
.on-light .badge, .sec--wash .badge{ background: var(--light-card) }

.ticks{ display: grid; gap: var(--s-4) }
.tick{ display: grid; grid-template-columns: 26px 1fr; gap: var(--s-3); align-items: start }
.tick__mark{
  width: 26px; height: 26px; padding: 4px; border-radius: 50%; flex: none;
  color: #fff; background-image: var(--grad-fill);
}
.tick span{ font-size: var(--t-sub); color: var(--txt-2) }
.tick strong{ color: var(--txt) }

/* the star row. decorative, because the sentence beside it states the rating */
.stars__line{
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3);
  margin-top: var(--s-7); max-width: none;
  font-size: var(--t-meta); font-weight: 500; color: var(--on-dark-2);
}
.stars{ display: inline-flex; align-items: center; gap: 4px; color: var(--star); flex: none }

/* the reassurance row. bullets, never a hyphen and never a pipe */
.assure{
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2);
  margin-top: var(--s-6); max-width: none;
  font-size: var(--t-meta); color: var(--on-dark-3);
}
.assure svg{ color: var(--grad-from); flex: none; margin-right: var(--s-1) }
.assure__dot{ opacity: .6 }

/* ---- 7.8 stats ---------------------------------------------------------- */

.stats{ display: grid; grid-template-columns: repeat(3,1fr); gap: var(--s-6); margin: 0 }
.stat,.stats__note{
  display: grid; grid-template-rows: auto auto; align-content: start; row-gap: var(--s-3);
  padding-left: var(--s-6); border-left: 1px solid var(--line-c);
}
.stat:first-child,.stats__note:first-child{ padding-left: 0; border-left: 0 }
.stat__value{
  grid-row: 1; margin: 0; color: var(--txt);
  font-family: var(--font-display); font-weight: 800;
  font-size: var(--t-figure); line-height: 1; letter-spacing: -.03em;
}
.stat__label{ grid-row: 2; font-size: var(--t-meta); line-height: 1.45; color: var(--txt-2); max-width: 22ch }
.stats__note h3{
  grid-row: 1; margin: 0; font-size: var(--t-h4); color: var(--txt);
  padding-top: var(--s-2); border-top: 2px solid var(--grad-from); justify-self: start;
}
.stats__note p{ grid-row: 2; font-size: var(--t-meta); line-height: 1.45; max-width: 26ch }
@media (max-width: 900px){
  .stats{ grid-template-columns: 1fr; gap: var(--s-5) }
  .stat,.stats__note{ padding-left: 0; border-left: 0; padding-top: var(--s-5); border-top: 1px solid var(--line-c) }
  .stat:first-child,.stats__note:first-child{ padding-top: 0; border-top: 0 }
}

/* ---- 7.9 the four step flow, the path line, the contrast pair ----------- */

.flow{ display: grid; grid-template-columns: repeat(4,1fr); gap: var(--s-6) }
.flow__step{ position: relative; padding-top: var(--s-6) }
.flow__step::before{ content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--line-c) }
.flow__step:first-child::before{ background-image: var(--grad-fill) }
.flow__step p.flow__num{
  margin: 0 0 var(--s-4); font-family: var(--font-brand); font-weight: 700;
  font-size: 1.25rem; line-height: 1; color: var(--txt); max-width: none;
}
.flow__step h3{ font-size: var(--t-h4) }
.flow__step p{ margin-top: var(--s-2); font-size: var(--t-body); color: var(--txt-2); max-width: none }
@media (max-width: 900px){ .flow{ grid-template-columns: 1fr 1fr } }
@media (max-width: 520px){ .flow{ grid-template-columns: 1fr } }

.pathline{ display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--s-6); margin: 0; padding: 0 }
.pathline li{
  position: relative; padding-top: var(--s-6);
  font-size: var(--t-h4); font-weight: 600; line-height: 1.25; color: var(--txt);
}
.pathline li::before{ content: ""; position: absolute; top: 5px; left: 0; right: 0; height: 2px; background: var(--line-c) }
.pathline li::after{
  content: ""; position: absolute; top: 0; left: 0;
  width: 12px; height: 12px; border-radius: 50%;
  background-image: var(--grad-fill); box-shadow: 0 0 0 4px rgba(129,34,243,.16);
}
.pathline li:last-child::before{
  -webkit-mask-image: linear-gradient(to right, #000 0, transparent 100%);
          mask-image: linear-gradient(to right, #000 0, transparent 100%);
}
.pathline small{
  display: block; margin-top: var(--s-2);
  font-size: var(--t-meta); font-weight: 400; color: var(--txt-3);
}
@media (max-width: 780px){ .pathline{ grid-auto-flow: row; grid-auto-columns: auto; gap: var(--s-5) } }

.contrast{ display: grid }
.contrast__row{
  display: grid; grid-template-columns: 1fr; gap: var(--s-5);
  padding-block: var(--s-7); border-top: 1px solid var(--line-c);
}
.contrast__row:first-child{ border-top: 0; padding-top: 0 }
.contrast__k{
  margin: 0; font-family: var(--font-brand);
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--txt-3);
}
.contrast__them,.contrast__us{ display: grid; gap: var(--s-2); align-content: start }
.contrast__them p,.contrast__us p{ margin: 0; max-width: 44ch }
.contrast__them p{ color: var(--txt-3) }
.contrast__us{ border-left: 2px solid var(--grad-from); padding-left: var(--s-5) }
.contrast__us p{ color: var(--txt); font-weight: 500 }
.contrast__n{
  margin: 0; font-family: var(--font-brand); font-weight: 700;
  font-size: var(--t-h4); line-height: 1; color: var(--txt);
}
@media (min-width: 781px){
  .contrast__row{ grid-template-columns: minmax(0,6ch) minmax(0,1fr) minmax(0,1fr); column-gap: var(--s-7); align-items: start }
}
@media (max-width: 780px){ .contrast__n{ display: none } }

.deflist{ display: grid; margin: 0 }
.deflist__row{ display: grid; grid-template-columns: 1fr; gap: var(--s-2); padding-block: var(--s-6); border-top: 1px solid var(--line-c) }
.deflist__row:first-child{ border-top: 0; padding-top: 0 }
.deflist dt{ font-size: var(--t-item); font-weight: 700; color: var(--txt) }
.deflist dd{ margin: 0; font-size: var(--t-sub); color: var(--txt-2); max-width: 58ch }
@media (min-width: 781px){
  .deflist__row{ grid-template-columns: minmax(0,280px) minmax(0,1fr); column-gap: var(--s-8); align-items: start }
}

/* ---- 7.10 the reason row, the moments strip ---------------------------- */

.reason{
  display: grid; grid-template-columns: minmax(0,1fr); align-items: start;
  column-gap: var(--s-7); row-gap: var(--s-4); padding-block: var(--s-8);
}
.reason__index{
  margin: 0; font-family: var(--font-brand); font-weight: 700;
  font-size: clamp(3rem, 2.2rem + 3.4vw, 5.5rem);
  line-height: .86; letter-spacing: -.02em; max-width: none;
  color: var(--grad-display-flat);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)){
  .reason__index{
    background-image: var(--grad-display);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}
.reason__body h3{ line-height: 1.12 }
.reason__body p{ margin-top: var(--s-4); max-width: 54ch }
.reason__fact{
  align-self: start; justify-self: start; max-width: none;
  padding-top: var(--s-3); border-top: 2px solid var(--grad-from);
  font-family: var(--font-brand);
  font-size: var(--t-eyebrow); font-weight: 600; line-height: 1.45;
  letter-spacing: .12em; text-transform: uppercase; color: var(--txt-3);
}
.reason__photo{ margin: 0; aspect-ratio: 5 / 4; border-radius: var(--r-lg); box-shadow: var(--sh-card) }
.reason__photo img{ object-position: 52% 58% }
@media (min-width: 901px){
  .reason{ grid-template-columns: minmax(0,148px) minmax(0,1fr) minmax(0,258px); padding-block: var(--s-12) }
  .reason__index{ grid-column: 1; grid-row: 1 }
  .reason__body { grid-column: 2; grid-row: 1 }
  .reason__fact { grid-column: 3; grid-row: 1; margin-top: var(--s-2) }
  .reason--media{ grid-template-columns: minmax(0,148px) minmax(0,1fr) minmax(0,46%) }
  .reason--media .reason__photo{ grid-column: 3; grid-row: 1; aspect-ratio: 4 / 3 }
  .reason:last-child{ padding-bottom: 0 }
}
@media (max-width: 900px){ .reason__photo{ aspect-ratio: 16 / 10 } }

.moments{ display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--s-6) }
.moment{ display: grid; gap: var(--s-4); align-content: start }
.moment__photo{ aspect-ratio: 4 / 3; border-radius: var(--r-lg) }
.moment__caption{ font-size: var(--t-body); line-height: 1.5; color: var(--txt-2); max-width: 36ch }
.moment__caption strong{ display: block; margin-bottom: var(--s-1); font-size: var(--t-item); color: var(--txt) }
@media (max-width: 780px){ .moments{ grid-template-columns: 1fr; gap: var(--s-8) } }

/* ---- 7.11 panels and prose --------------------------------------------- */

.infopanel{
  position: relative; padding: var(--s-7);
  background: var(--light-card); color: var(--txt);
  border-radius: var(--r-xl); box-shadow: var(--sh-card);
}
.infopanel h2{ font-size: var(--t-h3) }
.infopanel__list{ display: grid; gap: var(--s-5); margin-top: var(--s-6) }
.infopanel__row{ display: grid; gap: var(--s-1) }
.infopanel__k{
  margin: 0; font-family: var(--font-brand);
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--on-light-2);
}
.infopanel__v{
  margin: 0; max-width: none; overflow-wrap: anywhere;
  font-size: var(--t-h4); font-weight: 700; color: var(--on-light);
}
a.infopanel__v{ color: var(--grad-on-light-flat); text-decoration: none }
a.infopanel__v:hover{ text-decoration: underline }
.infopanel__note{ margin-top: var(--s-2); max-width: none; font-size: var(--t-meta); color: var(--on-light-2) }
.infopanel .ticks{ margin-top: var(--s-6) }
.infopanel .btn{ margin-top: var(--s-6); width: 100% }
@media (max-width: 560px){ .infopanel{ padding: var(--s-5); border-radius: var(--r-lg) } }

.aside-card{
  padding: var(--s-6);
  background: var(--light-card); color: var(--txt);
  border-radius: var(--r-xl); box-shadow: var(--sh-card);
}
.aside-card h2{ font-size: var(--t-h4) }
.aside-card ul{ display: grid; gap: var(--s-3); margin-top: var(--s-4) }
.aside-card li{ position: relative; padding-left: var(--s-5); font-size: var(--t-meta); color: var(--on-light-2) }
.aside-card li::before{
  content: ""; position: absolute; left: 0; top: .55em;
  width: 8px; height: 8px; border-radius: 50%; background-image: var(--grad-fill);
}
.aside-card a{ color: var(--grad-on-light-flat) }

.prose{ max-width: 68ch }
.prose > * + *{ margin-top: var(--s-5) }
.prose h2{ margin-top: var(--s-9) }
.prose h3{ margin-top: var(--s-8) }
.prose h2 + p, .prose h3 + p{ margin-top: var(--s-4) }

.kicker{
  margin: 0; font-family: var(--font-brand);
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--icon-c);
}


/* ==========================================================================
   8. Chrome. header, navigation, footer
   ========================================================================== */

/* White, per the owner's header mockup. It sits above a near black hero, so it
   needs its own hairline and, once stuck, a shadow. Without one, a white bar
   over dark content reads as a hole punched in the page rather than a header. */
.site-head{
  position: sticky; top: 0; z-index: var(--z-head);
  background: var(--light-card);
  border-bottom: 1px solid var(--line-light);
  transition: box-shadow var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.site-head.is-stuck{
  border-bottom-color: var(--line-light-2);
  box-shadow: 0 10px 28px -18px rgba(10,10,15,.45), 0 2px 6px -3px rgba(10,10,15,.14);
}
@supports ((backdrop-filter: blur(14px)) or (-webkit-backdrop-filter: blur(14px))){
  .site-head.is-stuck{
    background: rgba(255,255,255,.86);
    -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  }
}

.site-head__inner{
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: var(--s-6); min-height: var(--head-h);
}
.brand{ grid-column: 1; display: flex; align-items: center; text-decoration: none }
.brand img{ width: 212px; height: 40px; object-fit: contain }

/* 38, not 47, and 600, not 500. Normalised to a common width the built nav ran
   about 16 percent wider than the mockup's and read noticeably lighter. Bolder
   and tighter is what makes that header read confident rather than default. */
.nav{ grid-column: 2; display: flex; justify-content: center; align-items: center; gap: 38px }
.nav a{
  position: relative; padding-block: 10px;
  font-size: var(--t-nav); font-weight: 600; line-height: 1;
  color: var(--on-light-2); text-decoration: none;
  transition: color var(--dur-1) var(--ease);
}
.nav a::after{
  content: ""; position: absolute; left: 50%; bottom: 0;
  width: 28px; height: 2px; margin-left: -14px; border-radius: 2px;
  background-image: var(--grad-fill);
  transform: scaleX(0); transform-origin: 50% 50%;
  transition: transform var(--dur-1) var(--ease);
}
.nav a:hover{ color: var(--on-light) }
.nav a:hover::after{ transform: scaleX(1) }
.nav a[aria-current="page"]{ color: var(--on-light) }
.nav a[aria-current="page"]::after{ transform: scaleX(1) }
/* The mockup draws a short violet underline under Sell Your EV. No nav item is
   current on the home page, so the indicator the owner drew was never once
   visible on the page he is judging. base.html adds this class on the home page
   only, so it can never sit beside a real aria-current on another page. */
.nav a.is-lead{ color: var(--on-light) }
.nav a.is-lead::after{ transform: scaleX(1) }

.site-head__end{ grid-column: 3; display: flex; align-items: center; gap: var(--s-4); justify-self: end }
.site-head__end .btn{ padding-inline: 26px }

/* .btn is a flex container with a gap, for the buttons that carry a glyph. A
   bare word wrapped for the mobile label became a flex ITEM and inherited that
   gap, which showed as "Get  Your  Offer" with visible holes in it. The label
   is now a single flex item and the word inside it is ordinary inline text. */
.btn__label{ display: inline }
.btn__word{ display: inline }

.phone{ font-size: var(--t-nav); font-weight: 600; color: var(--on-light); text-decoration: none; white-space: nowrap }
.phone:hover{ color: var(--on-light-2) }

/* the phone menu. a details element, so it needs no script at all */
.mnav{ grid-column: 3; display: none; justify-self: end }
.mnav summary{
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; cursor: pointer; list-style: none;
  border-radius: var(--r-sm);
}
.mnav summary::-webkit-details-marker{ display: none }
.mnav__bars,.mnav__bars::before,.mnav__bars::after{
  content: ""; display: block; width: 22px; height: 2px; border-radius: 2px;
  background: var(--on-light);
  transition: transform var(--dur-1) var(--ease), background-color var(--dur-1) var(--ease), top var(--dur-1) var(--ease);
}
.mnav__bars{ position: relative }
.mnav__bars::before{ position: absolute; top: -7px }
.mnav__bars::after { position: absolute; top:  7px }
.mnav[open] .mnav__bars{ background: transparent }
.mnav[open] .mnav__bars::before{ top: 0; transform: rotate(45deg) }
.mnav[open] .mnav__bars::after { top: 0; transform: rotate(-45deg) }

.mnav__panel{
  position: absolute; top: 100%; left: 0; right: 0;
  display: grid; gap: 0;
  padding: var(--s-4) var(--gutter) var(--s-6);
  background: var(--light-card);
  border-top: 1px solid var(--line-light);
  box-shadow: var(--sh-card);
  max-height: calc(100vh - var(--head-h)); overflow-y: auto;
}
@supports (height: 100dvh){
  .mnav__panel{ max-height: calc(100dvh - var(--head-h)) }
}
.mnav__panel a:not(.btn){
  padding: 18px 4px; font-size: 1.0625rem; font-weight: 500;
  color: var(--on-light); text-decoration: none;
  border-bottom: 1px solid var(--line-light);
}
.mnav__panel a:not(.btn):hover{ color: var(--on-light-2) }
.mnav__panel .phone{ font-size: 1.0625rem; text-align: center; border-bottom: 0 }
.mnav__panel .btn{ margin-top: var(--s-4) }

/* Four columns below the desktop breakpoint, because the pill and the burger
   both ask for column 3 and would otherwise paint on top of each other. The
   nav's 1fr track stays as the spacer between the logo and the two controls. */
@media (max-width: 1023px){
  .nav{ display: none }
  .mnav{ display: block; grid-column: 4 }
  .site-head__inner{ grid-template-columns: auto 1fr auto auto; gap: var(--s-3) }
  .brand img{ width: 176px; height: 33px }
}
@media (max-width: 430px){
  .brand img{ width: 140px; height: 26px }
}

/* ---- footer ------------------------------------------------------------- */

.site-foot{
  position: relative; z-index: var(--z-under);
  background: var(--dark-page); color: var(--on-dark-2);
  border-top: 1px solid var(--line-dark);
  padding-block: var(--s-sec) var(--s-8);
}
.foot__top{
  display: grid; grid-template-columns: minmax(0,1.5fr) repeat(3, minmax(0,1fr));
  column-gap: var(--s-9); row-gap: var(--s-9);
}
.foot__brand{ display: grid; gap: var(--s-4); justify-items: start; align-content: start; max-width: 34ch }
.foot__brand img{ width: 188px; height: 35px; object-fit: contain }
.foot__line{ font-size: var(--t-meta); color: var(--on-dark-2); max-width: 30ch }
.phone--foot{ color: #fff }
.phone--foot:hover{ color: var(--on-dark-2) }
.foot__col{ display: grid; gap: var(--s-3); align-content: start }
.foot__h{
  margin: 0 0 var(--s-1); font-family: var(--font-brand);
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--on-dark);
}
.foot__col a,.foot__mail{ font-size: var(--t-meta); color: var(--on-dark-2); text-decoration: none }
.foot__col a:hover,.foot__mail:hover{ color: #fff; text-decoration: underline }
.foot__col p{ font-size: var(--t-meta); color: var(--on-dark-3); max-width: 32ch }
.foot__col p + p{ margin-top: 0 }
.foot__rule{ margin-block: var(--s-11) var(--s-6) }
.foot__entity{ font-size: var(--t-legal); line-height: 1.6; color: var(--on-dark-3); max-width: 96ch }
@media (max-width: 900px){
  .foot__top{ grid-template-columns: 1fr 1fr; row-gap: var(--s-8) }
  .foot__brand{ grid-column: 1 / -1 }
}
/* No single column rule below this either. The footer holds two columns down to
   320 and sets its mobile order with the order property rather than by moving
   anything in the DOM, which would change the desktop order too. Section 9.10. */


/* ==========================================================================
   9. Page sections
   ========================================================================== */

/* ---- 9.1 hero ----------------------------------------------------------- */
/* The photograph is an element rather than a background, so it can carry alt,
   width, height and fetchpriority and stay the LCP element. */

.hero{
  position: relative; isolation: isolate; overflow: hidden;
  background: var(--dark-hero);
  padding-block: var(--s-10) var(--s-9);
}
.hero--tall{ min-height: 470px; display: flex; align-items: center }

/* The inner page proportions. The home page's hero is 640 tall and carries
   nothing but words, so it can afford the height. These carry a card or a tick
   list underneath, and the padding does the work instead. */
.hero--mid{ min-height: 430px; display: flex; align-items: center }

/* The card carrying hero is taller than the words beside it, so it gets its own
   floor rather than inheriting the plain one. */
.hero--card{ padding-block: var(--s-9) var(--s-11) }

/* display:block is load bearing. The element is a <picture>, which is inline by
   default, and at 780 and below it drops back to position:relative and has to
   hold an aspect-ratio box of its own. */
/* 68 percent, against a hero no taller than it has to be. The source is
   1916 by 821, a 2.33 frame. At 58 percent of 1440 inside a 640 tall hero the
   box was 1.30, so cover threw away 44 percent of the source width: the car
   came up about 1.8 times too big, its nose ran off the right edge, and the
   violet ribbons that sweep in above the roof were cropped out entirely,
   leaving the top right quadrant dead black. At 68 percent inside a hero that
   settles near 500 the box is close to 2.0, cover crops on the width only, and
   every ribbon above the roofline survives because the full height is used. */
.hero__media{
  display: block;
  position: absolute; inset: 0 0 0 auto; z-index: 0;
  width: min(68%, 1120px); margin: 0; border-radius: 0; overflow: hidden;
}
.hero__media img{ width: 100%; height: 100%; object-fit: cover; object-position: 46% 50% }
/* The stops move left with the wider media box. The words end just inside the
   picture's left edge now, so only the first sixth of it has to be protected;
   held at the old stops the scrim reached two thirds of the way across and
   took the light off the car the mockup has fully lit. */
.hero__media::after{
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(90deg,
    #04060C 0%, #04060C 9%, rgba(4,6,12,.80) 20%,
    rgba(4,6,12,.34) 36%, rgba(4,6,12,0) 58%);
}

.hero__inner{
  position: relative; z-index: var(--z-base); width: 100%;
  display: grid; grid-template-columns: repeat(12, minmax(0,1fr));
  column-gap: var(--s-6); row-gap: var(--s-8); align-items: center;
}
.hero__words{ grid-column: 1 / 8; grid-row: 1; min-width: 0; max-width: 620px }
.hero__words h1{ max-width: 600px }
/* One tight block of three lines, the way the mockup sets it, rather than two
   paragraphs with a visible gap between them. 36ch is the measure that breaks
   the second sentence after simple, the way the mockup does, instead of after
   fast. Still two elements, because they are two sentences. */
.hero__lead{ margin-top: var(--s-5); max-width: 36ch; font-size: var(--t-lead); line-height: 1.5; color: var(--on-dark) }
.hero__lead + .hero__lead{ margin-top: 0 }
.hero__act{ display: flex; flex-wrap: wrap; gap: 19px; margin-top: var(--s-7) }

/* the form carrying hero. The home page, and the thank you and contact pages,
   which put a card rather than the form in the same column */
.hero__form { grid-column: 8 / 13; grid-row: 1 / span 2; align-self: end; min-width: 0 }
.hero__proof{ grid-column: 1 / 8;  grid-row: 2; min-width: 0 }
.hero__proof .ticks{ gap: var(--s-3) }

/* the same right hand column, for a card that is not the form */
.hero__aside{ grid-column: 8 / 13; grid-row: 1; align-self: center; min-width: 0 }

/* On the inner pages the proof list belongs to the words rather than to a row
   of its own. A second grid row has to stretch to the card beside it, which
   opens a hole between the lead and the ticks that nothing fills. */
.hero__words .hero__proof{ margin-top: var(--s-9) }

/* the hero that also carries the photograph. The media is already absolute and
   already bleeds right, so this modifier only has to hold the words off it. */
.hero--photo .hero__words{ max-width: 620px }
.hero--photo .hero__proof{ padding-bottom: var(--s-6) }

/* The hero that carries both the photograph and a card on top of it.
   The home page's 58 percent picture puts the car exactly where the card goes,
   so here the picture runs the full width instead and the crop is pushed right,
   which lands the nose in the gap between the words and the card and leaves the
   tail showing past its far edge. The scrim reaches its floor earlier for the
   same reason: the words need the same protection they always had, the card
   needs none, and everything between the two is the picture's to keep.
   Gated to the desktop breakpoint deliberately. At 1023 and below the card
   drops underneath the words and the plain hero rules are the right ones. */
@media (min-width: 1024px){
  /* One row, not two. Scoped to the breakpoint on purpose: below it the card
     drops under the words, and a hard grid-row here would beat the stacking
     rule on specificity alone and put the form above the headline on a phone. */
  .hero--card .hero__form{ grid-row: 1; align-self: center }

  /* The car runs the full width and the form card floats ON it, rather than
     sitting beside it. With the card in the hero there is only a 141px gap
     between the words and the card, and a scrim opaque to 47 percent left the
     car invisible in that slot. Pulled back to clear by 58 percent, the car
     reads across the middle, the card casts its shadow onto the bodywork, and
     the owner's light streaks survive at the right edge. */
  .hero--aside .hero__media{ width: 100% }
  .hero--aside .hero__media img{ object-position: 71% 50% }
  .hero--aside .hero__media::after{
    background: linear-gradient(90deg,
      #04060C 0%, #04060C 15%, rgba(4,6,12,.84) 29%,
      rgba(4,6,12,.38) 43%, rgba(4,6,12,0) 58%);
  }
}

@media (max-width: 1023px){
  .hero__media{ width: 46% }
  .hero__words,.hero__proof,.hero__form,.hero__aside{ grid-column: 1 / -1; grid-row: auto }
}

/* The tablet window, where the card has gone full width but the picture has
   not yet dropped into the flow. A 46 percent picture beside a full width card
   shows as a strip down the far edge, so it goes behind the whole stack instead
   and the scrim turns to run top to bottom, dark under the card and open at the
   top where the picture is the only thing there. */
@media (min-width: 781px) and (max-width: 1023px){
  .hero--aside .hero__media{ width: 100% }
  .hero--aside .hero__media img{ object-position: 58% 38% }
  .hero--aside .hero__media::after{
    background: linear-gradient(180deg,
      rgba(4,6,12,.44) 0%, rgba(4,6,12,.72) 34%,
      rgba(4,6,12,.94) 70%, #04060C 100%);
  }
}
@media (max-width: 780px){
  .hero--mid{ min-height: 0; display: block }
}
@media (max-width: 780px){
  .hero{ padding-block: var(--s-9) 0 }
  .hero--tall{ min-height: 0; display: block }
  .hero__inner{ grid-template-columns: 1fr; row-gap: var(--s-7) }
  /* The picture drops out of position:absolute and into the flow, and bleeds to
     both edges. Every hero shares this much. What sits in the box is not shared:
     the home page overrides the ratio, the crop and the margin in 9.10.2 to make
     the band the form card sits on, and the inner pages take .hero--wide below.

     The width is stated rather than left at auto. With auto, aspect-ratio and
     max-height together, the browser clamps the height and then derives the
     width back off the ratio, which lands the photograph at 236px inside a 375px
     screen with dead space beside it. Stating the width keeps the bleed.

     The 940 by 1670 default is the portrait crop and no page reaches it now.
     It stays as the fallback for any hero that carries a photograph without
     saying which shape it wants. */
  .hero__media{
    position: relative; inset: auto;
    width: calc(100% + var(--gutter) * 2);
    margin-inline: calc(var(--gutter) * -1); margin-top: var(--s-9);
    aspect-ratio: 940 / 1670; max-height: 420px;
  }
  .hero__media img{ object-position: 50% 82% }
  .hero__media::after{ display: none }
  .hero__act{ display: grid; gap: var(--s-3) }
  .hero__act .btn{ width: 100% }

  /* The inner pages keep their own landscape photograph on a phone instead of
     handing every one of them the home page's portrait crop, which would open
     five pages in a row on the same picture. There is no portrait version of
     these frames, so the box comes back to a band and the crop back to the
     middle, where the car is in all of them. */
  .hero--wide .hero__media{ aspect-ratio: 16 / 10; max-height: 320px }
  .hero--wide .hero__media img{ object-position: 54% 52% }
}

/* ---- 9.2 the feature strip --------------------------------------------- */

.strip{ background: var(--dark-strip); padding-block: 20px }
.strip__grid{ display: grid; grid-template-columns: repeat(4, minmax(0,1fr)) }
.strip__item{ display: flex; align-items: center; gap: 26px; padding-inline: var(--s-6); min-width: 0 }
.strip__item:first-child{ padding-left: 0 }
.strip__item:last-child{ padding-right: 0 }
.strip__item + .strip__item{ border-left: 1px solid var(--line-dark) }
/* 35, not 30, and the gradient rather than a flat violet. The brief asks for an
   outlined gradient icon and the mockup's glyphs carry the violet to blue
   sweep. At 30 against a 17px bold label they read at about 2x cap height
   where the mockup's read at about 2.9x, so they looked weedy beside the words
   they anchor. The stroke paint server is defined once in base.html; the flat
   colour is declared first so a browser that cannot resolve the reference, or
   a print stylesheet that drops it, still gets a violet glyph. */
.strip__icon{
  flex: none; width: 35px; height: 35px; color: var(--grad-from);
  stroke: var(--grad-from);
  stroke: url(#grad-stroke);
  filter: drop-shadow(0 0 10px rgba(129,34,243,.40));
}
.strip__text{ min-width: 0 }
.strip__label{ margin: 0; font-size: var(--t-item); font-weight: 700; line-height: 1.3; letter-spacing: -.01em; color: var(--on-dark) }
.strip__sub{ margin-top: var(--s-1); max-width: none; font-size: var(--t-body); line-height: 1.55; color: var(--on-dark-2) }

/* 2 x 2 from the tablet breakpoint, not from 640. Four columns inside a 943px
   container leaves 132px for the copy, and Thousands of sellers across our
   group. then sets as five words on five lines. The cross divider is kept. */
@media (max-width: 1023px){
  .strip{ padding-block: var(--s-6) }
  .strip__grid{ grid-template-columns: 1fr 1fr; row-gap: var(--s-6) }
  .strip__item{ padding-inline: var(--s-6); gap: var(--s-5) }
  .strip__item:nth-child(odd){ padding-left: 0; border-left: 0 }
  .strip__item:nth-child(even){ padding-right: 0; border-left: 1px solid var(--line-dark) }
  .strip__item:nth-child(n+3){ border-top: 1px solid var(--line-dark); padding-top: var(--s-6) }
}
@media (max-width: 640px){
  .strip__item{ padding-inline: var(--s-4); gap: var(--s-4) }
}
/* No single column rule below this. The strip holds 2 by 2 all the way to 320,
   because four features stacked one per row is 363px of page that says nothing
   four features in a block of two rows does not, and it is the single loudest
   reason a page reads as an endless list. See section 9.10. */

/* ---- 9.3 how it works --------------------------------------------------- */

.how{ background: var(--light-surface); color: var(--txt); padding-block: var(--s-sec) }
/* stretch, not centre. Centred, the dark card floated with 84px of empty light
   above it and 86px below, and it orphaned the hairline beside it, which ran
   the full column while the card occupied only the middle of it. In the mockup
   the card's top edge sits level with the eyebrow and its floor level with the
   step bodies, so the two halves read as one block. */
.how__grid{
  display: grid; grid-template-columns: minmax(0,1.35fr) 1px minmax(0,1fr);
  column-gap: 28px; align-items: stretch;
}
.how__words{ min-width: 0 }
.how__act{ display: flex; justify-content: center; margin-top: var(--s-6) }

.steps{ display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); column-gap: var(--s-6); margin-top: var(--s-7) }
.steps .step{ position: relative; min-width: 0 }
.step__head{ display: flex; align-items: center; gap: var(--s-5) }
/* A matched pair. In the mockup the disc and the glyph are close to the same
   size, roughly 41 against 34. At 56 against 34 the disc was 65 percent larger
   and dominated the pairing, so the icon, which is the part that actually says
   what the step is, read as small and secondary. */
.step__disc{
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--r-pill);
  background: var(--lilac-100); color: var(--ink-indigo);
  font-family: var(--font-brand); font-weight: 700;
  font-size: var(--t-h4); line-height: 1; letter-spacing: .02em;
}
.step__icon{ flex: none; width: 36px; height: 36px; color: var(--icon-indigo) }
.step__title{ margin-top: 18px; text-align: center; font-size: var(--t-item); font-weight: 700; line-height: 1.3; color: var(--on-light) }
.step__body{ margin-top: var(--s-2); max-width: none; text-align: center; font-size: var(--t-body); line-height: 1.55; color: var(--on-light-2) }
.steps .step:not(:last-child)::after{
  content: ""; position: absolute; top: 22px; left: 112px; right: calc(var(--s-6) * -1);
  height: 1px; background-image: var(--line-dotted);
}

/* Four across, for the process page, which owns four steps rather than three.
   It runs the full container instead of the home page's 1.35fr column, so each
   step still gets around 300px and the connector still clears the icon. */
.steps--4{ grid-template-columns: repeat(4, minmax(0,1fr)) }
@media (max-width: 900px){
  .steps--4{ grid-template-columns: 1fr 1fr; row-gap: var(--s-8) }
  .steps--4 .step:not(:last-child)::after{ display: none }
}
@media (max-width: 640px){ .steps--4{ grid-template-columns: 1fr } }

/* the dark card, the mockup's only non hero photo slot */
.vcard{
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 554 / 212; border-radius: var(--r-lg);
  background: var(--dark-card); box-shadow: var(--sh-card);
  color: var(--on-dark); text-decoration: none;
  transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
  /* This is a dark island inside a light section, so it has to hand the surface
     locals back. Without it the card inherited .how's light surface link colour
     and painted #6A2BE8 onto #06070C: 2.99 to 1, the only AA failure on the
     site, and on the card's one link. .vcard__body already hard codes #fff for
     the same reason, the link was simply never given the same escape hatch. */
  --link-grad: var(--grad-text);
  --link-flat: var(--grad-text-flat);
  --focus-c: #A78BFA;
}
/* At the desktop breakpoint the card is a grid item that fills its column, so
   its height comes from the row, not from a ratio. Below 900 the grid is a
   single column and the ratio is what gives the card a shape at all. */
@media (min-width: 901px){
  .vcard{ aspect-ratio: auto; align-self: stretch; min-height: 212px }
}
.vcard:hover{ transform: translateY(-2px); box-shadow: var(--sh-card-hi) }
.vcard__img{
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 70% 48%;
  filter: brightness(1.14) contrast(1.05);
}
/* Solid to a third, then off entirely by the far edge. The card is taller than
   it is wide now that it fills its column, so the old stops left the whole
   photograph under a scrim and the car read as a smudge. */
.vcard::before{
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, #06070C 0%, #06070C 30%, rgba(6,7,12,.62) 52%, rgba(6,7,12,0) 88%);
}
.vcard__body{
  position: absolute; inset: 0 auto 0 34px; z-index: 2; max-width: 46%;
  display: flex; flex-direction: column; justify-content: center;
}
.vcard__body h3{ color: #fff }
.vcard__body p{ margin-top: var(--s-3); max-width: none; font-size: var(--t-body); line-height: 1.5; color: var(--on-dark-2) }
.vcard__link{ margin-top: var(--s-4) }
/* 62 percent, not the centre. On the mockup the glyph sits over the car at
   x=1253 of a card running 902 to 1456, and at the centre it lands on the last
   word of the paragraph. */
.vcard__play{
  position: absolute; left: 62%; top: 50%; z-index: 3;
  transform: translate(-50%,-50%);
  filter: drop-shadow(0 6px 24px rgba(0,0,0,.45));
  transition: transform var(--dur-2) var(--ease);
}
.vcard:hover .vcard__play{ transform: translate(-50%,-50%) scale(1.06) }

@media (max-width: 900px){
  .how__grid{ grid-template-columns: minmax(0,1fr); row-gap: var(--s-8) }
  .how__grid .rule-v{ display: none }
  .vcard{ aspect-ratio: 16 / 10 }
  /* the body widens here, so the glyph has to move with it or it lands on the
     last word of the paragraph */
  .vcard__body{ max-width: 62% }
  .vcard__play{ left: 76% }
}
@media (max-width: 640px){
  .steps{ grid-template-columns: 1fr; row-gap: var(--s-7) }
  .steps .step:not(:last-child)::after{ display: none }
  .step__head{ gap: var(--s-4) }
  .step__title,.step__body{ text-align: left }
  .step__title{ margin-top: var(--s-4) }
  .vcard{ aspect-ratio: 4 / 3 }
  .vcard__body{ max-width: 64%; inset: 0 auto 0 var(--s-5) }
  /* pinned to the right edge rather than to a percentage. Below 640 there is no
     percentage that clears the text on every phone width. */
  .vcard__play{ left: auto; right: var(--s-5); transform: translateY(-50%) }
  .vcard:hover .vcard__play{ transform: translateY(-50%) scale(1.06) }
}

/* ---- 9.4 get your offer, and why choose --------------------------------- */
/* A 50 / 50 that bleeds to both edges without 100vw, so a Windows scrollbar
   cannot shift it. Each half aligns its own half container box to the split. */

/* Each panel is exactly half the page, so 100% inside a panel is half the
   viewport and (100% - container/2) is the same inset .wrap gets, floored at
   the gutter. Written that way rather than off 100vw on purpose: 100vw counts
   the scrollbar and would push this band a few pixels wider than the column on
   any browser that still draws one. Before this the band used the bare gutter
   and ran 40 to 1400 where every other section on the page runs 80 to 1360, so
   it bulged 40px past the page's own column on both edges. */
.offer{
  display: grid; grid-template-columns: 1fr 1fr;
  --offer-edge: max(var(--gutter), calc(100% - var(--container) / 2));
}
.offer__panel{ display: flex; position: relative; isolation: isolate; min-width: 0 }
.offer__in{ position: relative; z-index: var(--z-base); width: 100%; max-width: calc(var(--container) / 2); min-width: 0 }
.offer__panel--dark{
  background: var(--dark-panel); color: var(--on-dark);
  justify-content: flex-end;
  padding: var(--s-10) var(--s-7) var(--s-10) var(--offer-edge);
}
/* The streaks sweep across the whole panel in the mockup, as fine violet
   hairlines that pass behind the heading. Anchored bottom right they left the
   top left two thirds, exactly where the eyebrow, heading and sub line sit,
   dead flat black. The tint layer on top holds the artwork violet: the crop
   carries a pale, almost white hot core that reads as a photographic artifact
   next to the mockup's uniformly violet field. */
.offer__panel--dark::before{
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(100deg, rgba(58,16,168,.42) 0%, rgba(20,10,90,.10) 46%, rgba(96,30,244,.30) 100%),
    url("../img/brand/streaks-wide.jpg");
  background-position: 34% bottom, 34% bottom;
  background-size: cover, cover;
  background-repeat: no-repeat;
  opacity: .62;
}
.offer__panel--light{
  background: var(--light-surface); color: var(--txt);
  justify-content: flex-start;
  padding: var(--s-10) var(--offer-edge) var(--s-10) var(--s-11);
}
/* Scoped to the dark half deliberately. The light half's heading is the
   eyebrow itself, and a bare .offer h2 is more specific than .eyebrow, so it
   would silently blow that label up to 32px. */
.offer__panel--dark h2{ font-size: var(--t-h2-sm); letter-spacing: -.02em }
.offer__sub{ margin-top: var(--s-3); max-width: 62ch; font-size: var(--t-sub); color: var(--on-dark-2) }

@media (max-width: 900px){
  .offer{ grid-template-columns: 1fr }
  .offer__panel--dark,.offer__panel--light{ padding: var(--s-10) var(--gutter) }
  .offer__in{ max-width: none }
}

/* the second run at the form. The band already asks the question, so it needs
   something to press, and the seller who has read the three steps and the four
   reasons is warmer than the one who landed. It is a link up to the hero card,
   never a second form: form.js binds one .lead-form and reads #model-map by id,
   so a copy here would swallow submissions and break the hero form's make to
   model dependency at the same time. The short row that used to sit here, and
   the .quickform rules that dressed it, went with the page it pointed at. */
.offer__act{ margin-top: var(--s-5) }

/* the two by two, with the cross divider the mockup draws */
.why__grid{ display: grid; grid-template-columns: 1fr 1fr; margin-top: var(--s-6) }
.why__cell{ display: flex; gap: 16px; min-width: 0 }
.why__cell:nth-child(odd) { padding-right: var(--s-7) }
.why__cell:nth-child(even){ padding-left: var(--s-7); border-left: 1px solid var(--line-light) }
.why__cell:nth-child(-n+2){ padding-bottom: var(--s-5) }
.why__cell:nth-child(n+3) { padding-top: var(--s-5); border-top: 1px solid var(--line-light) }
.why__icon{ flex: none; width: 36px; height: 36px; color: var(--icon-indigo) }
.why__text{ min-width: 0 }
.why__title{ margin: 0; font-size: var(--t-item); font-weight: 700; line-height: 1.3; color: var(--on-light) }
.why__body{ margin-top: var(--s-1); max-width: none; font-size: var(--t-body); line-height: 1.55; color: var(--on-light-2) }

@media (max-width: 900px){
  .why__grid{ grid-template-columns: 1fr }
  .why__cell:nth-child(odd),.why__cell:nth-child(even){ padding-inline: 0; border-left: 0 }
  .why__cell:nth-child(-n+2){ padding-bottom: 0 }
  .why__cell:nth-child(n+3){ padding-top: 0; border-top: 0 }
  .why__cell + .why__cell{ margin-top: var(--s-6); padding-top: var(--s-6); border-top: 1px solid var(--line-light) }
}

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

.faq-sec{ background: var(--light-surface); color: var(--txt); padding-block: var(--s-sec) var(--s-sec-lg) }
/* 250px in the head column, not 180. At 180 with a 36px heading Frequently
   asked questions. broke to three lines where the mockup breaks it to two. */
.faq-sec__grid{
  display: grid; grid-template-columns: minmax(250px,1fr) minmax(0,4fr);
  column-gap: var(--s-8); align-items: start;
}
.faq-sec__head,.faq-sec__body{ min-width: 0 }
.faq-sec__bar{ display: flex; justify-content: flex-end; margin-bottom: var(--s-4) }
.faq-list{ display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); column-gap: var(--s-5); align-items: start }

.faq{
  background: var(--light-card);
  border: 1px solid var(--line-light); border-radius: var(--r-sm);
  transition: border-color var(--dur-2) var(--ease);
}
.faq:hover{ border-color: rgba(76,31,196,.4) }
/* The min-height fits two lines of the question, not one. The three questions
   are the mockup's own, and at a shippable body size two of them wrap where the
   first does not, so the cards' tops aligned and their bottoms did not. The
   mockup never does that: its three cards are identical rows on a common
   baseline. A grid align-items:stretch would have done it too, until somebody
   opened one card and the other two grew to match it. */
.faq summary{
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: 16px 18px; min-height: 76px; cursor: pointer; list-style: none;
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4;
  letter-spacing: -.005em; color: var(--on-light);
}
.faq summary::-webkit-details-marker{ display: none }
.faq__sign{ flex: none; width: 18px; height: 18px; color: var(--icon-indigo); transition: transform var(--dur-2) var(--ease) }
.faq[open] .faq__sign{ transform: rotate(45deg) }
.faq__a{ padding: 0 20px 18px }
.faq__a p{ max-width: none; font-size: var(--t-body); line-height: 1.55; color: var(--on-light-2) }

@media (max-width: 1023px){
  .faq-sec__grid{ grid-template-columns: 1fr; row-gap: var(--s-7) }
  .faq-sec__bar{ justify-content: flex-start; margin-bottom: var(--s-4) }
  .faq-list{ grid-template-columns: 1fr; row-gap: var(--s-3) }
  /* stacked, so nothing has to line up with anything and the two line floor is
     only wasted height */
  .faq summary{ min-height: 60px }
}

/* ---- 9.6 the people band ------------------------------------------------ */

/* Not in the mockup, which is cut off mid FAQ, and the owner asked for humans.
   It was three bright daylight frames on a centred header, and there is not a
   single centred block anywhere in the mockup. Now: two frames, left aligned
   with the words beside them, carrying the same deep treatment the rest of the
   site gives daylight stock so the photographs sit inside the brand's colour
   instead of reading as clip art cut into a premium dark page. */
.people{ background: var(--dark-page); padding-block: var(--s-sec) }
.people__grid{
  display: grid; grid-template-columns: minmax(0,.85fr) minmax(0,1fr) minmax(0,1fr);
  column-gap: var(--s-7); row-gap: var(--s-7); align-items: center;
}
.people__head{ min-width: 0; align-self: center }
/* :not(.eyebrow) is load bearing. .people__head p is one class and one element,
   so it outranks the bare .eyebrow class and was setting this band's label at
   14px where every other eyebrow on the site sets at 11. It is the only eyebrow
   anywhere that was not the same size as the others. */
.people__head p:not(.eyebrow){ margin-top: var(--s-4); max-width: 30ch; font-size: var(--t-sub); color: var(--on-dark-2) }
.people__act{ margin-top: var(--s-6) }
.people__fig{ margin: 0; min-width: 0 }
.people__frame{
  position: relative; overflow: hidden; aspect-ratio: 16 / 10;
  border-radius: var(--r-lg); background: var(--dark-strip);
}
/* The deep treatment is stated here rather than left to .duo--deep. Both
   selectors weigh the same and this one is further down the file, so a bare
   img rule here would silently win and hand back the daylight photograph the
   band exists to calm. */
/* border-radius: inherit is not decoration. The filter below promotes the image
   to its own compositing layer, and a promoted child is not always clipped by
   an ancestor's rounded overflow, which left the two bright corners of the
   showroom frame square while the dark ones looked correct. */
/* The picture element is a block that fills the frame, so the img's percentage
   height has something definite to resolve against now that a phone specific
   cut sits above it in the same element. */
.people__frame picture{ display: block; width: 100%; height: 100% }
.people__frame img{
  width: 100%; height: 100%; object-fit: cover;
  border-radius: inherit;
  filter: saturate(.62) brightness(.56) contrast(1.12);
}
.people__cap{ margin-top: 12px; max-width: none; font-size: var(--t-meta); line-height: 1.5; color: var(--on-dark-2) }
@media (max-width: 900px){
  .people__grid{ grid-template-columns: 1fr 1fr }
  .people__head{ grid-column: 1 / -1 }
}
@media (max-width: 560px){
  .people__grid{ grid-template-columns: 1fr; row-gap: var(--s-6) }
  .people__frame{ aspect-ratio: 16 / 10 }
}

/* ---- 9.7 the dark band -------------------------------------------------- */

.band{
  position: relative; isolation: isolate; z-index: var(--z-under);
  color: var(--on-dark); padding-block: var(--s-sec);
  background-color: var(--dark-panel);
  background-image:
    radial-gradient(58% 52% at 10%   0%, rgba(129,34,243,.30) 0%, rgba(129,34,243,0) 62%),
    radial-gradient(52% 48% at 94%   8%, rgba(11,44,242,.32)  0%, rgba(11,44,242,0)  64%),
    radial-gradient(64% 60% at 76% 100%, rgba(94,36,240,.22)  0%, rgba(94,36,240,0)  66%);
}
.band__inner{ position: relative; z-index: var(--z-raise) }
.band__photo{
  position: absolute; top: 0; left: 0; z-index: var(--z-under);
  width: 100%; height: clamp(280px, 34vw, 460px);
  object-fit: cover; object-position: 50% 26%;
  filter: saturate(.85) brightness(.8) contrast(1.05); opacity: .5;
  -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 34%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0, #000 34%, transparent 100%);
}
@media (max-width: 900px){ .band__photo{ height: clamp(220px, 46vw, 300px); object-position: 50% 22% } }
.band__inner .badges{ margin-top: var(--s-9) }
.band__inner .stats { margin-top: var(--s-12) }

/* ---- 9.8 the inner page head ------------------------------------------- */

.pagehead{
  position: relative; isolation: isolate; z-index: var(--z-base);
  color: var(--on-dark); padding-block: var(--s-11) var(--s-sec);
}
.pagehead__inner{ position: relative; z-index: var(--z-raise) }
.pagehead .shead{ margin-bottom: 0; max-width: 68ch }
.pagehead .lede{ max-width: 46ch }
.pagehead .badges{ margin-top: var(--s-7) }
.pagehead__act{
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4);
  margin-top: var(--s-7); max-width: none;
}
.pagehead--split{ padding-block: var(--s-11) }
.pagehead__row{
  display: grid; grid-template-columns: repeat(12, minmax(0,1fr));
  column-gap: var(--s-6); row-gap: var(--s-8); align-items: center;
}
.pagehead__words{ grid-column: 1 / 7; min-width: 0 }
.pagehead__aside{ grid-column: 8 / 13; align-self: center; min-width: 0 }
.pagehead--split .shead,
.pagehead--split .lede{ max-width: none }
@media (max-width: 900px){
  .pagehead{ padding-block: var(--s-10) var(--s-11) }
  .pagehead__row{ grid-template-columns: 1fr; row-gap: var(--s-7) }
  .pagehead__words,.pagehead__aside{ grid-column: 1 / -1 }
  .pagehead--split .shead{ max-width: none }
}

/* ---- 9.9 the composed inner page sections ------------------------------ */

.s-why{ background: var(--light-surface); color: var(--txt) }
.s-why .sec-grid{ row-gap: 0 }
.s-why .sec-grid > .rule{ margin-block: 0 }
.s-why .shead-split{ margin-bottom: var(--s-8) }

.s-equity__photo,.s-sell__photo{ margin: 0; aspect-ratio: 4 / 3; border-radius: var(--r-xl); box-shadow: var(--sh-card) }
.s-equity__photo img{ object-position: 52% 58% }
.s-sell__photo img{ object-position: 55% 62% }
.s-equity__words > * + *,
.s-sell__words > * + *{ margin-top: var(--s-5) }
.s-equity__words .shead,
.s-sell__words .shead{ margin-bottom: 0 }
.s-sell__panel{
  padding: var(--s-6); border-radius: var(--r-lg);
  background: var(--light-card); color: var(--txt); box-shadow: var(--sh-card);
}
.s-sell__panel p + p{ margin-top: var(--s-3) }
.s-sell__panel .small{ margin-top: var(--s-3) }

@media (min-width: 901px){
  .s-equity .sec-grid,.s-sell .sec-grid{
    grid-template-columns:
      [full-start] minmax(var(--gutter), calc((100% - var(--container)) / 2))
      [content-start] minmax(0, 1fr)
      [mid] minmax(0, 1fr)
      [content-end] minmax(var(--gutter), calc((100% - var(--container)) / 2)) [full-end];
    align-items: center; column-gap: var(--s-10);
  }
  .s-equity__photo{ grid-column: full-start / mid;   grid-row: 1 }
  .s-equity__words{ grid-column: mid / content-end;  grid-row: 1 }
  .s-sell__words { grid-column: content-start / mid; grid-row: 1 }
  .s-sell__photo { grid-column: mid / full-end;      grid-row: 1 }
  .s-sell__words p{ max-width: 46ch }
}
@media (max-width: 900px){
  .s-equity__photo,.s-sell__photo{ aspect-ratio: 16 / 10 }
}

.s-moments{ background: var(--light-surface); color: var(--txt) }

/* The closing card no longer crosses into the footer. The page ends on its own
   dark band, and a footer carrying 104px of dead space at the top for a card
   that may not be there is worse than a card that sits inside its section. */
.s-cta{ position: relative; isolation: isolate; z-index: var(--z-base) }
.s-cta__inner{ position: relative; z-index: var(--z-raise) }
.s-cta .protrude{ margin-bottom: 0 }
.cta{
  display: grid; gap: var(--s-7); align-items: center;
  padding: var(--s-9); border-radius: var(--r-xl);
  background: var(--light-card); color: var(--txt); box-shadow: var(--sh-card);
}
.cta h2{ font-size: var(--t-h2-sm) }
.cta__words{ min-width: 0 }
.cta__act{ display: grid; gap: var(--s-4); justify-items: start }
@media (min-width: 901px){
  .cta{ grid-template-columns: minmax(0,1.25fr) minmax(0,1fr); column-gap: var(--s-10); padding: var(--s-9) var(--s-10) }
}
@media (max-width: 900px){ .cta__act{ justify-items: stretch } }
@media (max-width: 560px){ .cta{ padding: var(--s-6) } }


/* ==========================================================================
   9.10 The mobile system
   ==========================================================================

   Four breakpoints and no new ones. 1024 and up is the desktop. 1023 and down
   is the burger and the full width card. 780 and down is where the hero
   photograph drops into the flow. 560 and down is the system. 380 and down is
   four compressions and nothing else.

   375 and 390 take an identical layout. --gutter is clamp(20px, 4vw, 40px),
   which resolves to 20 at both, so the only difference between an iPhone SE and
   an iPhone 15 is 15px of measure. Every number below is quoted at 375, the
   harder of the two, with 335px of content.

   This block sits last in section 9 on purpose. Several rules here answer a
   rule earlier in the file at the same specificity and win on source order.
   ========================================================================== */

/* ---- 9.10.1 the tokens -------------------------------------------------- */

@media (max-width: 780px){
  :root{ --s-sec: 56px; --s-sec-lg: 68px; --head-h: 64px; --overlap: 48px }
}

/* The type scale at 560 and down. The headings compress, the reading sizes do
   not. Most of it is pinning a clamp floor rather than inventing a second
   scale. Three of them are load bearing beyond their own size: --t-item drives
   the form controls, which must never go below 16px and are pinned again in
   9.10.3, and --t-body and --t-meta are almost everything on the page a seller
   actually reads.

   --t-body and --t-meta are 15, which is what the desktop sets them at, and
   they are not to be taken down again. They were 13, and 13 was the single most
   common size on the home page at 375: 33 text nodes against 16 at 15px. Every
   how it works step, every why choose reason, every feature strip line, every
   FAQ answer, both photograph captions, the form's own no obligation line and
   the whole footer, all of it set smaller on the phone than on the desktop, on
   a site whose owner puts 80 percent of his sellers on a phone. The height it
   costs is height spent on the sections that do the selling. Where a cell will
   not hold 15, cut a word rather than the type. */
@media (max-width: 560px){
  :root{
    --s-sec: 48px; --s-sec-lg: 56px; --overlap: 44px;

    --t-h1:      2.125rem;    /* 34   was 36 */
    --t-h2:      1.625rem;    /* 26   was 28 */
    --t-h3:      1.1875rem;   /* 19   was 24 */
    --t-h4:      1.0625rem;   /* 17   was 18 */
    --t-lead:    0.9375rem;   /* 15   was 16 */
    --t-item:    0.9375rem;   /* 15   was 16 */
    --t-sub:     0.875rem;    /* 14   was 15 */
    --t-body:    0.9375rem;   /* 15, the desktop size. never 13 */
    --t-meta:    0.9375rem;   /* 15, the desktop size. never 13 */
    --t-legal:   0.75rem;     /* 12   was 13 */
  }

  /* 0.18em, not 0.22em. At 11px over 29 characters 0.22em adds 64px of advance
     to a 335px column and forces AUSTRALIA'S TRUSTED EV BUYERS onto two lines.
     At 0.18em it holds one. */
  .eyebrow{ letter-spacing: .18em; margin-bottom: var(--s-3) }
  .center .eyebrow, .eyebrow--center{ margin-right: -.18em }

  h1,.t-display{ line-height: 1.05 }
  h2,.t-h2{ line-height: 1.14 }
  h3,.t-h3{ line-height: 1.25; letter-spacing: -.015em }

  /* headers sit 24 above their content, not 48 */
  .shead, .shead-split{ margin-bottom: var(--s-6) }
}

/* 360, not 380. The rule above everything else here is that 375 and 390 take an
   identical layout, and 375 is a phone in the owner's own market. The type only
   compresses where the measure genuinely runs out, which is 360 and below. The
   one thing that does move at 380 is the header pill, in 9.10.9, and that is a
   physical fit rather than a layout choice. */
@media (max-width: 360px){
  :root{ --t-h1: 2rem }   /* 32 */
}

/* ---- 9.10.2 the hero ---------------------------------------------------- */
/* The one thing this page has to do on a phone is put the form in front of the
   seller. Everything above the card is measured against that: 24 of padding,
   the eyebrow, the headline, the two lead lines, the review line, and then the
   card. Nothing else is allowed above it. */

/* Scoped to the home page, every rule of it. The inner pages carry a hero
   button that is their own primary call to action, a photograph that is not
   this band, and in two cases an aside card in the same column, so none of what
   follows belongs to them. body.is-home is the same hook the header CTA uses. */
@media (max-width: 780px){
  /* The photograph is at the foot of the band now, so the top two thirds would
     otherwise be flat #04060C behind white text, which is exactly the flatness
     the owner objected to in the mockup he was shown. This is the site's own
     mesh recipe, the same two lights the .mesh utility already carries, retuned
     for a tall narrow band. It costs no bytes and no requests. */
  body.is-home .hero{
    padding-block: var(--s-6) 0;
    background-image:
      radial-gradient(86% 30% at  4%  0%, rgba(129,34,243,.34) 0%, rgba(129,34,243,0) 66%),
      radial-gradient(76% 26% at 98%  9%, rgba(11,44,242,.30)  0%, rgba(11,44,242,0)  68%);
  }
  body.is-home .hero__inner{ row-gap: var(--s-4) }

  /* Hidden, not removed. Its one link, How It Works, is reachable from the
     burger, from the Learn More button in the section below and from the FAQ
     bar, and the button costs 70px directly above the form. */
  body.is-home .hero__act{ display: none }

  /* One tight block of three lines, the way the mockup sets it. The sibling
     rule has to be restated at this weight: scoped to body.is-home the rule
     above outranks the unscoped .hero__lead + .hero__lead and would otherwise
     open a 12px gap in the middle of what reads as one paragraph. */
  body.is-home .hero__lead{ margin-top: var(--s-3); max-width: none }
  body.is-home .hero__lead + .hero__lead{ margin-top: 0 }

  /* A band, not a portrait. The owner's mobile mockup stacks headline, car,
     card. Executed literally that costs 120px of card visibility to show a car
     that appears again in full 300px further down. Instead the car is a full
     bleed band immediately after the card, and the card's last 44px sit on top
     of it with the shadow falling across the road. Same elements, same order of
     importance, one deliberate overlap instead of a stack.

     The bleed, the drop into the flow and the dropped scrim are on the plain
     .hero__media rule further up, which every hero shares. Only the overlap,
     the ratio and the crop are the home page's.

     No z-index here. .hero__inner is already position:relative z-index 1 and
     this band is a sibling at 0, so the inner's whole stacking context, card
     included, paints above it. A competing z-index would only fight that one.

     The ratio governs and there is no max-height. Capped, the box stopped
     matching the crop and object-fit went back to work: at 780 a 168px cap
     against a 296px natural height took the roof off the car, which is the one
     thing this band exists to show. A 2.84 strip cannot run away with the page
     on its own. 146 at 375, 211 at 560, 296 at 780. */
  body.is-home .hero__media{
    margin-top: calc(var(--overlap) * -1);
    aspect-ratio: 750 / 264;
    max-height: none;
  }
  body.is-home .hero__media img{ object-position: 50% 46% }
}

@media (max-width: 560px){
  /* The one bespoke size on the page. This line has to hold a fixed sentence,
     4.9/5 from 500+ sellers across The Car Buyers group, in two lines directly
     above the card, and 13px sets it in three. 12.5px on #04060C measures well
     past the 4.5 bar in --on-dark-2. */
  .stars__line{
    margin-top: var(--s-4); gap: var(--s-3);
    flex-wrap: nowrap; align-items: flex-start;
    font-size: .78125rem; line-height: 1.35;
  }
  .stars{ padding-top: 1px }
  .stars svg{ width: 14px; height: 14px }
}

/* ---- 9.10.3 the form card ----------------------------------------------- */
/* The most important object on the site. Everything here is measured. */

@media (max-width: 560px){
  .lead-form{
    padding: var(--s-5);
    border-radius: var(--r-lg);
    /* Two shadows, not one. The wide one lifts the card off the road behind it,
       the tight one draws its edge. A single soft shadow on a white card over a
       near black photograph reads as a flat sticker, and that alone is most of
       the difference between this card and a generic one. */
    box-shadow: 0 20px 48px rgba(6,6,20,.34), 0 2px 8px rgba(6,6,20,.20);
  }
  .lead-form .step > * + *{ margin-top: var(--s-4) }
  .lead-form .step h2{ font-size: 1.375rem; line-height: 1.18; letter-spacing: -.02em }
  .lead-form .sub{ font-size: var(--t-sub) }
  .lead-form .sub + *{ margin-top: var(--s-5) }
  .lead-form .cardfoot{ margin-top: 14px }
  .errbox{ margin-bottom: var(--s-4); padding: var(--s-3) var(--s-4) }

  .lead-form label,
  .lead-form .fieldlabel{ margin-bottom: 6px; font-size: .875rem }
  .lead-form .err{ margin-top: 6px }

  /* 1rem, stated rather than inherited, and this is not negotiable. iOS Safari
     zooms the viewport when a control under 16px takes focus, the page never
     zooms back, and the seller finishes the form on a page they cannot see.
     --t-item is 15px at this breakpoint, so leaving these on the token would
     have shipped exactly that defect. */
  .lead-form input,
  .lead-form select{ min-height: 52px; font-size: 1rem; border-radius: var(--r-md) }
  .lead-form select{ padding-right: 44px }

  .lead-form .plate input{
    height: 56px; font-size: 1.125rem; letter-spacing: .1em;
    border-radius: var(--r-sm);
  }
  .lead-form .plate input::placeholder{ letter-spacing: .1em }

  /* Make and Model stack. At 375 a two up select gets 141.5px, of which the
     chevron takes 44, leaving 81 of text room, and form.js writes the string
     "Choose a make first" into the Model select, which is about 152px at 16px
     and gets clipped by the UA with no ellipsis. A clipped placeholder on a
     required field is worse than 87px of height. Stacked also matches the
     dependency: pick the make, the models appear directly underneath. */
  .lead-form .pair{ grid-template-columns: 1fr; gap: var(--s-3) }

  /* Year and Kilometres do not. Two short labels, two short values, and it
     saves 87px on the page's most important object. Written with both classes
     so it beats the rule above it whatever happens to the source order. */
  .lead-form .pair.pair--num{ grid-template-columns: 1fr 1fr; gap: var(--s-3) }

  /* Fixed two columns rather than auto-fit, so Needs work always gets 143px and
     can never be the one chip that wraps to two lines while its three
     neighbours stay on one. The radios stay in the DOM at 1px and opacity 0
     because form.js reads :checked on them. They are not buttons. */
  .chips{ grid-template-columns: 1fr 1fr; gap: var(--s-2) }
  .chip span{ min-height: 48px; font-size: .875rem }

  .lead-form .go{ min-height: 54px }
  .lead-form .back{ min-height: 48px; margin-top: var(--s-3) }
}

@media (max-width: 360px){
  .lead-form{ padding: 18px }
  .lead-form .step h2{ font-size: 1.3125rem }
}

/* ---- 9.10.4 the feature strip ------------------------------------------- */

@media (max-width: 560px){
  .strip{ padding-block: var(--s-5) }
  .strip__grid{ row-gap: var(--s-5) }
  /* start, not centre. At a readable size the four subs no longer wrap to the
     same number of lines, and centred, the two line cell sat 11px below the
     three line cell beside it, so four labels that are meant to read as one row
     stopped lining up. The glyph takes 2px of optical correction against the
     cap height of the label it now sits level with. */
  .strip__item{ padding-inline: var(--s-3); gap: var(--s-3); align-items: flex-start }
  .strip__item:nth-child(n+3){ padding-top: var(--s-5) }
  .strip__icon{ width: 28px; height: 28px; margin-top: 2px }
  .strip__sub{ margin-top: 2px }
}

/* ---- 9.10.5 how it works ------------------------------------------------ */

@media (max-width: 560px){
  .steps{ grid-template-columns: 1fr; row-gap: 28px; margin-top: var(--s-6) }

  /* A row, not a stack. The numeral holds a 44px column of its own, the title
     sits on the numeral's line and the body runs underneath it in the same
     column, with the glyph pinned to the right edge of the row. Stacked, the
     head, the title and the body cost 124px per step and read as three
     identical boxes. This costs 92 and reads as a list somebody set. */
  .steps .step{
    display: grid; grid-template-columns: 44px minmax(0,1fr);
    column-gap: var(--s-4); align-items: center;
  }
  .step__head{ grid-column: 1; grid-row: 1; gap: 0 }
  .step__title{ grid-column: 2; grid-row: 1; margin-top: 0 }
  .step__body { grid-column: 2; grid-row: 2; margin-top: var(--s-2) }
  .step__icon{ position: absolute; top: 4px; right: 0 }

  /* The desktop draws dotted connectors between the three steps and the old
     mobile rule simply switched them off, which is exactly what turned this
     section into three identical boxes, the failure of the mockup the owner did
     not like. They come back turned 90 degrees, threaded down through the
     numerals in the channel the grid above just opened. */
  .steps .step:not(:last-child)::after{
    display: block; content: "";
    top: 52px; bottom: -28px; left: 21px; right: auto;
    width: 1px; height: auto;
    background-image: var(--line-dotted-v);
  }

  /* Hidden. It points at /how-it-works/, and the card directly underneath it is
     a link to the same page carrying See how it works, so on a phone this was
     two buttons to one destination 40px apart. Same reasoning as the hero's
     second button, and the desktop keeps both because there the card is beside
     the steps rather than under them. */
  .how__act{ display: none }

  /* The card bleeds to both edges. A near black photographic band running edge
     to edge inside a light section is the strongest contrast available on the
     mobile page and it costs nothing in height. */
  .vcard{
    width: calc(100% + var(--gutter) * 2);
    margin-inline: calc(var(--gutter) * -1);
    border-radius: 0;
    aspect-ratio: 16 / 9;
  }
  .vcard__body{ inset: 0 auto 0 var(--gutter); max-width: 60% }
  .vcard__play{ right: var(--gutter) }
  .vcard__play svg{ width: 44px; height: 44px }

  /* The card is a full bleed band now, not a column beside the steps, so it
     needs less air above it than the desktop's two column gap. */
  .how__grid{ row-gap: 28px }
}

/* ---- 9.10.6 get your offer, and why choose ------------------------------ */

@media (max-width: 780px){
  /* 73KB of decoration sitting behind text, on the page where bytes matter
     most. Only the photograph goes. The tint layer above it in the same
     declaration stays, so the panel keeps the violet light the mockup draws. */
  .offer__panel--dark::before{
    background-image: linear-gradient(100deg,
      rgba(58,16,168,.42) 0%, rgba(20,10,90,.10) 46%, rgba(96,30,244,.30) 100%);
    background-position: 0 0; background-size: cover; opacity: .9;
  }
}

@media (max-width: 560px){
  /* No radius and no inset. The light half above and below reads as one
     continuous field with a dark rectangle punched into it, which is what the
     owner's mockup actually draws. Two cards would not. */
  /* The seam between the two halves is inside one band, so it does not pay the
     full section rhythm twice. 48 on the outside, 32 either side of the join. */
  .offer__panel--dark { padding: var(--s-sec) var(--gutter) var(--s-7) }
  .offer__panel--light{ padding: var(--s-7) var(--gutter) var(--s-sec) }
  .offer__act{ margin-top: var(--s-5) }
  .offer__act .btn{ min-height: 54px }
  .assure{ margin-top: var(--s-5) }

  /* 2 by 2 with the icon above the words, because a 157px column cannot hold a
     30px icon beside four lines of copy. The cross divider the mockup draws is
     kept, one hairline down the middle and one across. */
  .why__grid{ grid-template-columns: 1fr 1fr; margin-top: var(--s-5) }
  .why__cell{ flex-direction: column; gap: var(--s-3) }
  .why__cell + .why__cell{ margin-top: 0; padding-top: 0; border-top: 0 }
  .why__cell:nth-child(odd) { padding-right: var(--s-4) }
  .why__cell:nth-child(even){ padding-left: var(--s-4); border-left: 1px solid var(--line-light) }
  .why__cell:nth-child(-n+2){ padding-bottom: var(--s-5) }
  .why__cell:nth-child(n+3) { padding-top: var(--s-5); border-top: 1px solid var(--line-light) }
  .why__icon{ width: 30px; height: 30px }
}

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

@media (max-width: 560px){
  .faq-sec__grid{ row-gap: var(--s-6) }

  /* A divided list, not three cards. Measured before this: three 335px
     rectangles, the same 10px radius, the same 1px #E7E6EB border, the same
     white fill, stacked in an even 10px rhythm with the sign in the same place
     on each. Nothing overlapped, nothing bled, nothing was layered. It was the
     one section of this page that was exactly the failure the owner named in
     the mockup he was shown, and it sits immediately before the closing band,
     so it is close to the last thing the page says.

     It uses the move the rest of the page already uses: hairlines running full
     bleed to both gutters, the way the feature strip and the why grid work.
     Opening a question lifts its surface to white rather than only turning the
     sign, so the open state is a change of material and not a rotation. */
  .faq-list{
    row-gap: 0;
    width: calc(100% + var(--gutter) * 2);
    margin-inline: calc(var(--gutter) * -1);
    border-top: 1px solid var(--line-light);
  }
  .faq{
    background: transparent;
    border: 0; border-bottom: 1px solid var(--line-light); border-radius: 0;
    transition: background-color var(--dur-2) var(--ease);
  }
  .faq[open]{ background: var(--light-card) }
  /* :hover sticks on a phone after a tap, and the desktop's violet border was
     leaving one lit divider in the middle of a set of hairlines long after the
     finger had gone. The open surface is the feedback here. */
  .faq:hover{ border-color: var(--line-light) }
  .faq summary{ min-height: 60px; padding: 16px var(--gutter); font-size: 1rem }
  .faq__a{ padding: 0 var(--gutter) 20px }
}

/* ---- 9.10.8 the people band --------------------------------------------- */

@media (max-width: 560px){
  .people__grid{ grid-template-columns: 1fr; row-gap: var(--s-6) }
  .people__head{ grid-column: 1 / -1 }
  .people__head p{ margin-top: var(--s-3) }
  .people__act{ margin-top: var(--s-5) }
  .people__act .btn{ display: flex; width: 100%; min-height: 54px }

  /* One photograph, not two thumbnails. Measured before this: two 162px squares
     under saturate(.62) brightness(.56), in which the frame whose whole job is
     to prove an inspector turns up in the seller's driveway read as a grey
     mauve smudge with a 40px human somewhere inside it, and the 28px offset
     between them read as misalignment rather than as a composition because the
     captions wrapped to different line counts.

     This is the one band on the page where photography carries an argument
     rather than decorating, so it gets the width and it gets the light. Full
     content width, the landscape band the template serves for this breakpoint,
     and a treatment lifted far enough to keep the scene legible while the
     violet stays in it. The second frame goes: it is lazy and it has no layout
     box here, so a phone never requests it. */
  .people__fig + .people__fig{ display: none }
  .people__frame{ aspect-ratio: 4 / 3 }
  .people__frame img{ filter: saturate(.84) brightness(.78) contrast(1.07) }
  .people__cap{ margin-top: var(--s-3) }
}

/* ---- 9.10.9 the header and the burger ----------------------------------- */

@media (max-width: 1023px){
  .site-head__end{ display: flex }
  .site-head__end .btn{ min-height: 44px; padding-inline: 14px; font-size: .875rem }

  /* The pill arrives once the hero form has scrolled away. On the first screen
     the form is already 264px below the headline, so a header link pointing at
     it is noise, and hiding it there is what lets a 140px logo, a pill and a
     44px burger all fit inside 335px of content.

     Default visible, hidden only here, because an inner page has no
     #get-your-offer for the observer to watch and its pill must always show.
     Gated on html.js as well, so a browser with no IntersectionObserver, the
     one case reveal.js returns early on, keeps the pill the whole time.

     Opacity and pointer-events, never display, so the grid column keeps its
     width and the header cannot shift when the pill appears. */
  html.js body.is-home .site-head__end{
    opacity: 0; transform: translateY(-6px); pointer-events: none;
    transition: opacity var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
  }
  html.js body.is-home .site-head.is-past-form .site-head__end{
    opacity: 1; transform: none; pointer-events: auto;
  }

  .mnav__panel{ padding: var(--s-2) var(--gutter) var(--s-6) }
  .mnav__panel a:not(.btn){
    display: flex; align-items: center; min-height: 55px; padding: 0 4px;
  }
  .mnav__panel .btn{ min-height: 54px }
  .mnav__panel .phone{
    display: flex; align-items: center; justify-content: center;
    min-height: 44px; font-weight: 600;
  }
}

@media (max-width: 380px){
  /* The pill stays here. It used to be display:none, which took the only
     persistent call to action off an iPhone SE, a 12 mini and a 13 mini, and
     those are the phones that can least afford to lose it: measured at 375,
     from the foot of the form card to the next button in the page is 1263px,
     one and a half screens, and the only way back was two taps through a menu.

     What goes is one word of the label, not the button. base.html wraps it so
     this can happen in CSS with no second link and no script. Measured at 375
     with the gaps below: 129 of logo, 91 of pill and 44 of burger inside 335,
     which leaves 47 spare where the full label left none at all. */
  .site-head__end .btn__word{ display: none }
  /* the label is one flex item, so hiding a word inside it cannot leave a gap */
  .site-head__end .btn{ padding-inline: 12px }
  .site-head__inner{ gap: var(--s-2) }
  .brand img{ width: 132px; height: 25px }
}

/* The floor. Below this the three of them genuinely do not fit and the burger,
   which holds the same link twice, is the honest answer. Stated at a width
   rather than at a device, because it is arithmetic: the logo, the pill, the
   burger and three 8px gaps come to 291, and 330 of viewport leaves 290 of
   content. Every phone in the owner's market is above it. */
@media (max-width: 330px){
  .site-head__end{ display: none }
}

/* ---- 9.10.10 the footer ------------------------------------------------- */

@media (max-width: 560px){
  .site-foot{ padding-block: var(--s-sec) 28px }
  .foot__top{ grid-template-columns: 1fr 1fr; column-gap: var(--s-5); row-gap: 28px }
  .foot__brand{ grid-column: 1 / -1; max-width: none }
  .foot__brand img{ width: 168px; height: 31px }

  /* order, not a DOM move. Moving these three in base.html would change the
     desktop column order as a side effect, which is the difference between a
     footer tweak and a desktop regression. */
  .foot__col--site { order: 2 }
  .foot__col--legal{ order: 3 }
  .foot__col--buy  { order: 4; grid-column: 1 / -1 }
  .foot__col--buy p{ margin-top: var(--s-2) }

  /* 22 of line plus 11 of padding either side is a 44px target on every link,
     which is what the gap between them was buying at half the cost. */
  .foot__col{ gap: 0 }
  .foot__col a{ display: block; padding-block: 11px; line-height: 22px }
  .phone--foot, .foot__mail{ display: flex; align-items: center; min-height: 44px }
  .phone--foot{ font-size: 1.0625rem; font-weight: 600 }

  .foot__rule{ margin-block: var(--s-7) var(--s-5) }
  .foot__entity{ line-height: 1.55 }
}


/* ==========================================================================
   9.11 The inner pages at mobile
   ==========================================================================

   9.10 is the home page's mobile system. This is the same system carried onto
   the six pages behind it, on the same four breakpoints, so nothing reads as
   orphaned on a phone. No new breakpoint is introduced here.

   It sits after 9.10 for the same reason 9.10 sits last in section 9: several
   rules below answer a rule earlier in the file at equal specificity and win on
   source order alone.

   The two hero rules are keyed on .hero--wide, which already means, in 9.1,
   "an inner page hero that keeps its own landscape photograph on a phone rather
   than taking the home page's crop". The home hero does not carry it, so it
   cannot be reached from here, and the home rules in 9.10.2 stay untouched.
   ========================================================================== */

/* ---- 9.11.1 the hero that carries no card ------------------------------- */
/* The process page and the why us page.

   Measured at 375 before this: the band ran 764 tall, the top 530 of it was
   flat #04060C behind white text, and the photograph sat at the floor 48px
   below everything else, starting at y 578 against a fold at 812. The seller
   saw a black rectangle, and a picture only if they scrolled. Flat, evenly
   spaced and unlayered, which is the failure the owner named in the mockup he
   was shown, sitting on five pages of his own site.

   The photograph becomes the band. It stays absolute at 780 and down instead of
   dropping into the flow, a scrim carrying the page's own violet light sits over
   it, and the words sit on the photograph. The band falls from 764 to 481 on the
   process page and 710 to 427 on why us, so the section under it now arrives on
   the first screen.

   The templates hand these two a tall cut at this breakpoint, because the box
   is 0.78 wide by tall here and 1.78 on a desktop. The cut is the exact region
   the browser was showing when the treatment was measured, so serving it
   reframes nothing.

   Contrast is measured against the brightest pixel underneath each element
   rather than an average, with the scrim composited: 7.75 on the process page's
   h1 and 6.12 on its lead, 10.02 and 6.27 on why us. 6.12 is the worst case in
   either band and the bar for body text is 4.5. */
@media (max-width: 780px){
  .hero--wide.hero--mid{ min-height: 0; display: block; padding-block: var(--s-7) var(--s-8) }

  .hero--wide.hero--mid .hero__media{
    position: absolute; inset: 0;
    width: 100%; margin: 0;
    aspect-ratio: auto; max-height: none;
  }
  .hero--wide.hero--mid .hero__media img{
    height: 100%; object-position: 50% 46%;
    filter: brightness(1.12);
  }
  /* The plain hero drops this scrim at 780 because there the picture is a band
     with nothing on top of it. Here there is text on top of it, so it comes
     back, turned to run down the band instead of across it, and it carries the
     same violet the mesh gives every other dark surface on the site. */
  .hero--wide.hero--mid .hero__media::after{
    display: block;
    background:
      radial-gradient(78% 34% at 6% 2%, rgba(129,34,243,.34) 0%, rgba(129,34,243,0) 70%),
      linear-gradient(180deg,
        rgba(4,6,12,.90) 0%, rgba(4,6,12,.62) 40%,
        rgba(4,6,12,.80) 76%, #04060C 100%);
  }
}

/* ---- 9.11.2 the hero that carries a card -------------------------------- */
/* Contact and the thank you page. These two hold a white card in the same
   column the home page holds the form in, so they take the home page's
   construction rather than 9.11.1: the photograph is a band at the foot and the
   card's last 44px sit on top of it, with the shadow falling across the road.
   One signature overlap, used on all three pages that have a card.

   The picture cannot be the field behind the words here. At 375 the card is
   full width, so a photograph behind the whole 767px band would be cropped to a
   0.49 box out of a 2.33 source, which is the "unidentifiable dark mass" the
   home hero already ruled out once.

   The mesh is the home page's own recipe, unchanged. Without it the 400px above
   the card was the same flat black 9.11.1 exists to answer. */
@media (max-width: 780px){
  .hero--wide.hero--card{
    padding-block: var(--s-7) 0;
    background-image:
      radial-gradient(86% 30% at  4%  0%, rgba(129,34,243,.34) 0%, rgba(129,34,243,0) 66%),
      radial-gradient(76% 26% at 98%  9%, rgba(11,44,242,.30)  0%, rgba(11,44,242,0)  68%);
  }
  .hero--wide.hero--card .hero__inner{ row-gap: var(--s-5) }

  /* 16 by 7, and the templates serve a band cut to exactly that ratio at this
     breakpoint. Cover then has nothing left to crop, which is what stops the
     inline object-position those two images carry for the desktop from reaching
     across and reframing the phone. An inline style beats any rule in here. */
  .hero--wide.hero--card .hero__media{
    margin-top: calc(var(--overlap) * -1);
    aspect-ratio: 16 / 7; max-height: none;
  }
}

/* ---- 9.11.2b the hero buttons between the phone and the tablet ---------- */
/* .hero__act goes full width at 780 and down, which is right on a phone and
   wrong at 768, where it draws a 708px gradient pill. The home page never shows
   it, because 9.10.2 hides its hero button on a phone entirely, so this band is
   only ever seen on the four inner pages and the fix belongs to them.

   561 rather than 560, so it starts exactly where the phone system stops. */
@media (min-width: 561px) and (max-width: 780px){
  .hero--wide .hero__act{ display: flex; flex-wrap: wrap; gap: var(--s-4) }
  .hero--wide .hero__act .btn{ width: auto }
}

/* ---- 9.11.3 the page head ----------------------------------------------- */
/* Privacy, terms and the 404. No photograph, so the mesh is the whole surface. */

@media (max-width: 560px){
  /* 56 and 64 while every other section on the phone pays 48. One rhythm. */
  .pagehead{ padding-block: var(--s-sec) }
  .pagehead--split{ padding-block: var(--s-sec) }
  .pagehead__row{ row-gap: var(--s-6) }
  .pagehead .badges{ margin-top: var(--s-5) }

  /* The 404's two buttons are the only way off that page. Left as a flex row
     they wrapped to two lines at 215 and 250 wide, which is neither a row nor a
     stack. Every other pair of buttons on a phone is a full width stack. */
  .pagehead__act{ display: grid; gap: var(--s-3); margin-top: var(--s-6) }
  .pagehead__act .btn{ width: 100% }
}

/* ---- 9.11.4 the aside card ---------------------------------------------- */

@media (max-width: 560px){
  .aside-card{ padding: var(--s-5); border-radius: var(--r-lg) }
  .aside-card h2{ font-size: var(--t-h4) }
  .aside-card ul{ gap: var(--s-4); margin-top: var(--s-4) }
}

/* The 404's list, where every item is a destination rather than a sentence with
   a word in it underlined. Set as prose those four links were 16px tall, which
   is a third of a thumb, and they are the only navigation a lost visitor has.
   The row is the control now, at 44px minimum, on every breakpoint. */
.aside-card--links ul{ gap: 0; margin-top: var(--s-4) }
.aside-card--links li{ padding-left: 0 }
.aside-card--links li::before{ display: none }
.aside-card--links li + li{ border-top: 1px solid var(--line-light) }
.aside-card--links a{
  position: relative; display: block;
  min-height: 44px; padding: 11px 26px 11px 0;
  font-size: var(--t-item); font-weight: 600; line-height: 1.3;
  color: var(--on-light); text-decoration: none;
}
.aside-card--links a span{
  display: block; margin-top: 3px;
  font-size: var(--t-meta); font-weight: 400; line-height: 1.45;
  color: var(--on-light-2);
}
.aside-card--links a::after{
  content: ""; position: absolute; right: 6px; top: 50%;
  width: 7px; height: 7px; margin-top: -4px;
  border-right: 2px solid var(--icon-indigo);
  border-top: 2px solid var(--icon-indigo);
  transform: rotate(45deg);
  transition: right var(--dur-1) var(--ease);
}
.aside-card--links a:hover{ color: var(--grad-on-light-flat) }
.aside-card--links a:hover::after{ right: 0 }

/* ---- 9.11.5 the streak field -------------------------------------------- */
/* The same call 9.10.6 makes for the offer panel, and the same reason.
   streaks-wide.jpg is 73KB and streaks-curve.jpg is 96KB of decoration sitting
   behind text, and between them they load on five of the six inner pages: the
   two closing bands, and all three page heads. Every surface that carries this
   utility also carries .mesh or .band, both of which light it with gradients
   that cost nothing, so what goes is the photograph and not the light. */

@media (max-width: 780px){
  .streaks::before{ display: none }
}

/* ---- 9.11.6 who we buy from --------------------------------------------- */
/* Three full width photographs stacked one under another, 486px each, 1459px of
   section. Three identical rectangles in a column is the single clearest
   example on the site of the thing the owner objected to.

   A row each instead, with the frame square and the side alternating, which is
   the same "a row, not a stack" move 9.10.5 makes for the numbered steps. The
   section falls from 1459 to about 560, and the frames drop from 335 CSS px to
   120, which is what lets the templates ask for the 400w files. */

@media (max-width: 560px){
  .moments{ gap: var(--s-6) }
  .moment{
    grid-template-columns: 120px minmax(0,1fr);
    column-gap: var(--s-4); row-gap: 0; align-items: start;
  }
  .moment__photo{ grid-column: 1; grid-row: 1; aspect-ratio: 1 / 1; border-radius: var(--r-md) }
  .moment__caption{ grid-column: 2; grid-row: 1; max-width: none }

  .moment:nth-child(even){ grid-template-columns: minmax(0,1fr) 120px }
  .moment:nth-child(even) .moment__photo{ grid-column: 2 }
  .moment:nth-child(even) .moment__caption{ grid-column: 1 }
}

/* ---- 9.11.7 the side by side -------------------------------------------- */

@media (max-width: 560px){
  .contrast__row{ padding-block: var(--s-6); row-gap: var(--s-4) }
  /* :not(.contrast__k), for the reason spelled out in 9.11.9. The label above
     each cell is also a p in the same block, and one class plus one element
     outranks the bare .contrast__k class, so without this the 11px tracked
     Orbitron label sets at 14 alongside the copy it labels. */
  .contrast__them p:not(.contrast__k),
  .contrast__us   p:not(.contrast__k){ font-size: var(--t-sub); line-height: 1.55 }
  .contrast__us{ padding-left: var(--s-4) }
}

/* ---- 9.11.8 the long text pages ----------------------------------------- */
/* Privacy and terms.

   The measure is 335px, which at 16px Inter is 39 characters, and that is the
   measure the screen allows. It cannot be widened without dropping the type
   below 16, which is the wrong trade on a page somebody has to read carefully,
   so the size holds and the leading opens instead: 1.65 rather than 1.6.

   The headings come down from 26 to 19 and take a hairline. At 26 over three
   lines of body copy a legal subheading reads as shouting, and eight of them in
   a column with nothing between them read as one undifferentiated wall. The
   rule is what gives the document its structure at a size that belongs to the
   text underneath it. */

@media (max-width: 560px){
  .prose > * + *{ margin-top: var(--s-4) }
  .prose p{ font-size: 1rem; line-height: 1.65 }
  .prose h2{
    margin-top: var(--s-7); padding-top: var(--s-5);
    border-top: 1px solid var(--line-light-2);
    font-size: var(--t-h3);
  }
  .prose h3{ margin-top: var(--s-6); font-size: var(--t-h4) }
  .prose h2:first-child{ margin-top: 0; padding-top: 0; border-top: 0 }
  .prose h2 + p,.prose h3 + p{ margin-top: var(--s-3) }
}

/* ---- 9.11.9 the type hierarchy in a section ----------------------------- */
/* A section lede was setting at 15 over body copy at 16, which is the hierarchy
   upside down: the paragraph that introduces the argument read smaller than the
   argument. The 16 is the page default, which the mobile scale never reaches
   because these paragraphs carry no class.

   --t-lead is not the fix. It is pinned at 15 for the home hero, where it is
   measured against the form card, and moving it moves the one screen that
   matters most. The two sizes are stated here instead: 16 over 15 over 14 over
   13, top to bottom. */

@media (max-width: 560px){
  .lead,.lede{ font-size: 1rem; line-height: 1.5 }

  /* The child combinator is load bearing, and this is the trap. A descendant
     selector here reads .s-equity__words p, which is one class and one element
     and therefore outranks .eyebrow, .kicker, .small and .lede, every one of
     which is a bare class. Written that way it silently blew the 11px tracked
     eyebrows and the kicker up to 15px and flattened the section header on
     three pages. The paragraphs this rule is for are direct children; every
     one of those labels sits inside a .shead or a .s-sell__panel. */
  .s-equity__words > p,.s-sell__words > p{ font-size: 0.9375rem; line-height: 1.6 }
  .s-equity__words > * + *,.s-sell__words > * + *{ margin-top: var(--s-4) }
}

/* ---- 9.11.10 tap targets ------------------------------------------------ */

@media (max-width: 1023px){
  /* The lockup draws 25px tall and it is the site's home link on every page. */
  .brand{ min-height: 44px }
}

@media (max-width: 560px){
  /* 21px each, and on the thank you page the arrow link is the only route on to
     anything. .vcard__link is deliberately not in here: the whole card is the
     control, so the link inside it is a label rather than a target. */
  .btn-link,.link-arrow,.faq-sec__all{ min-height: 44px }
  .faq-sec__bar{ margin-bottom: var(--s-2) }
}

/* ---- 9.11.11 the closing card ------------------------------------------- */

@media (max-width: 560px){
  .cta{ row-gap: var(--s-5) }
  .cta__act{ gap: var(--s-3) }
  .cta__act .btn{ min-height: 54px }
  .cta .small{ font-size: var(--t-meta) }
}


/* ==========================================================================
   10. Motion
   ========================================================================== */

/* On load, the hero only. No observer, these fire on paint. */
@media (prefers-reduced-motion: no-preference){
  [data-load]{
    opacity: 0;
    transform: translate3d(0, 14px, 0);
    animation: rise-in var(--dur-4) var(--ease) both;
    animation-delay: calc(60ms + min(var(--i, 0), 6) * var(--stagger));
  }
  /* The photograph is slower, and is never gated behind html.js, so a browser
     with no IntersectionObserver still paints it. */
  .hero__media img{ animation: hero-settle 900ms var(--ease) both }
}
@keyframes rise-in{
  from{ opacity: 0; transform: translate3d(0, 14px, 0) }
  to  { opacity: 1; transform: none }
}
@keyframes hero-settle{
  from{ opacity: 0; transform: scale(1.045) }
  to  { opacity: 1; transform: none }
}

/* On scroll. reveal.js sets data-in on the group and --i on each riser. */
html.js [data-rise]{
  opacity: 0;
  transform: translate3d(0, var(--rise), 0);
  will-change: opacity, transform;
}
@media (prefers-reduced-motion: no-preference){
  html.js [data-rise]{
    transition:
      opacity   var(--dur-4) var(--ease) calc(min(var(--i,0), 8) * var(--stagger)),
      transform var(--dur-4) var(--ease) calc(min(var(--i,0), 8) * var(--stagger));
  }
}
html.js [data-in] [data-rise],
html.js [data-rise][data-in]{ opacity: 1; transform: none }
html.reveal-fallback [data-rise]{ opacity: 1; transform: none }


/* ==========================================================================
   11. Reduced motion, last, so it wins
   ========================================================================== */

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto }
  *, *::before, *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  [data-load], html.js [data-rise]{ opacity: 1 !important; transform: none !important }
  .hero__media img{ opacity: 1 !important; transform: none !important }
}
