/* home-signup.css — the hero email box, the review cards, and the few pieces
 * of the signup modal that the house stylesheet does not already own.
 *
 * ── 🚨 READ THIS BEFORE ADDING A RULE ─────────────────────────────────
 *
 * Alex, 2026-08-24, looking at the first build on dev: *"Styling is all off.
 * How have you done the styling? It doesn't match everything else on the
 * platform."*
 *
 * The cause was not taste. `marketing-site.css` already ships a complete signup
 * dialog — `.signup-overlay`, `.signup-modal`, `.signup-close`, `.signup-title`,
 * `.signup-sub`, `.signup-form`, `.signup-field`, `.signup-submit`,
 * `.signup-trust` — lifted byte-for-byte from `sales-goldmine.html`, with a
 * comment above it explaining how carefully it was matched. **home.html renders
 * that exact markup for its own log-in dialog.** The first cut of this file
 * built a SECOND modal system beside it: its own overlay, its own scrim, its own
 * field, its own button, its own shadow. Two designs, one page, one file apart.
 *
 * ⚠️ SO THIS FILE NO LONGER STYLES: the overlay, the scrim, the modal box, the
 * close button, the title, the sub, the form, the text input or the submit
 * button. Those are the house's. What is left below is the genuinely new
 * furniture — the step crumb, the included list, the price panel, the review
 * card, the trust row — and every one is written in the house tokens.
 *
 * ⚠️ TWO PALETTES EXIST AND THEY ARE NOT THE SAME. `:root` carries the cool set
 * the home page uses (`--ink:#15172b`, `--ink2`, `--ink3` — no hyphen).
 * `.signup-overlay` re-declares a warm set ON ITSELF (`--ink:#2a2030`,
 * `--ink-2`, `--ink-3` — hyphenated). A rule that works on the page and a rule
 * that works in the modal are therefore NOT interchangeable, and a token that
 * silently falls back is how the first build ended up half a shade out
 * everywhere. Anything used in both places is mapped explicitly at the bottom.
 */

/* ═══ On the page ═══════════════════════════════════════════════════════
   Root tokens only: --paper --ink --ink2 --ink3 --line --cta --accent --good.
   Nothing hyphenated, because none of it exists out here. */

/* ── Hero ─────────────────────────────────────────────────────────────
   Present on load. No microcopy under the field — Alex, 2026-08-24: "we don't
   need to put underneath it 'card required, 14 days free, nothing charged
   today'. Just remove all that text." The trust row below is two short
   reassurances, which is what the approved artefact carried, not that text. */
.hs-hero{width:100%; max-width:470px; margin:0 auto;}
.hs-row{display:flex; gap:9px; align-items:stretch; flex-wrap:wrap;}

/* ⚠️ HOLDS THE CTA BACK WHILE WE FIND OUT IF THIS PERSON IS ALREADY SIGNED IN.
   Only applied when a token is actually present, and removed under a 2.5s cap
   in home-signup.js — a signed-out visitor never meets this rule and never
   waits. It reserves the row's height so the page does not jump when the form
   arrives, and it hides `#start-free` (the no-JS anchor) too, which is the
   thing that would otherwise flash "Start your 14-day trial" at somebody who
   is one round-trip away from being sent to their dashboard.
   `visibility` rather than `display` is what keeps the space reserved. */
.acts.hs-checking{min-height:96px;}
.acts.hs-checking > *{visibility:hidden;}

/* Proportioned to `.signup-field input`, the platform's own text field:
   1.5px border, 10px radius, 12px/14px padding, 14.5px type. The one
   deliberate difference is the font size on small screens — see below. */
.hs-in{
  flex:1 1 210px; min-width:0;
  padding:12px 14px; font-family:inherit; font-size:14.5px;
  color:var(--ink, #15172b); background:var(--paper, #fff);
  border:1.5px solid var(--line, #e8e4d8); border-radius:10px;
  transition:border-color .15s, box-shadow .15s;
}
.hs-in::placeholder{color:var(--ink3, #8a8fa6);}
.hs-in:focus{
  outline:none; border-color:var(--accent, #6a4cf1);
  box-shadow:0 0 0 4px rgba(106,76,241,.12);
}
/* ⚠️ 16px ON PHONES IS NOT A STYLE CHOICE. iOS zooms the whole page in when a
   focused input is under 16px, and the zoom does not undo itself — the visitor
   is left on a magnified page at the first step of the funnel. */
@media (max-width:540px){ .hs-in{font-size:16px;} }

.hs-go{flex:0 0 auto; white-space:nowrap; border:none; cursor:pointer; font-family:inherit;}
.hs-err{margin:9px 0 0; font-size:13px; color:#b4232a; text-align:left;}

/* ── Trust line ───────────────────────────────────────────────────────
   Centred under the hero field, and again above the review card in the modal. */
.hs-trust{
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:6px 16px; margin:14px 0 0; padding:0;
  font-size:11.5px; color:var(--ink3, #8a8fa6);
}
.hs-trust span{display:inline-flex; align-items:center; gap:5px;}
.hs-trust span::before{
  content:""; width:5px; height:5px; border-radius:50%;
  background:var(--good, #4f7c54); flex-shrink:0;
}

/* ── Review cards ─────────────────────────────────────────────────────
   Three under the hero, one on the card panel.

   ⚠️ REAL PEOPLE, REAL SENTENCES. The words and the names are theirs and are
   not editable copy. Monogram avatars rather than photographs on purpose: the
   live home page currently credits a quote to "Dr. Robert Lang" beside a
   photograph of a woman, and initials cannot go wrong in that way. */
.revs{
  list-style:none; display:grid; grid-template-columns:1fr; gap:10px;
  margin:26px auto 0; padding:0; max-width:470px; text-align:left;
}
@media (min-width:760px){
  .revs{grid-template-columns:repeat(3,1fr); max-width:880px;}
}
.rev{
  background:var(--paper, #fff); border:1px solid var(--line, #e8e4d8);
  border-radius:12px; padding:14px 15px;
}
.rev .stars{margin:0; color:#d9a441; font-size:11px; letter-spacing:2px; line-height:1;}
.rev .q{margin:7px 0 9px; font-size:13px; line-height:1.55; color:var(--ink2, #4d5168);}
.rev .who-r{margin:0; display:flex; align-items:center; gap:8px;}
.rev .av{
  width:26px; height:26px; border-radius:50%; flex-shrink:0;
  background:linear-gradient(135deg, var(--accent, #6a4cf1), var(--cta, #ec1075));
  color:#fff; font-size:10px; font-weight:700;
  display:flex; align-items:center; justify-content:center;
  font-family:"JetBrains Mono", ui-monospace, monospace;
}
.rev .nm{
  display:block; font-size:12.5px; font-weight:650; line-height:1.25;
  color:var(--ink, #15172b);
}
.rev .nm em{
  display:block; font-style:normal; font-size:10.5px; font-weight:400;
  color:var(--ink3, #8a8fa6);
}

/* ═══ Inside the modal ══════════════════════════════════════════════════
   Everything below is scoped to `.hs-signup`, which sits ON `.signup-overlay`
   — so the hyphenated warm tokens are in scope and inherited, not guessed. */

/* 🚨 THE PANEL MUST BE ABLE TO SCROLL, AND THE HOUSE MODAL CANNOT.
   `.signup-overlay` is a centring flex box with 20px padding and `.signup-modal`
   has no height bound — fine for the log-in dialog it was built for, which is
   two fields tall. This flow's card panel is ~1290px: nine included lines, the
   price panel, the card field, the button, the trust row and a review. Measured
   on a 390x844 phone it overflowed BOTH ways at once — the crumb and the close
   button clipped off the top, "start with just the free community" off the
   bottom, and no way to scroll to either, because a centred flex child that
   overflows its container cannot be reached.
   Scoped to `.hs-signup` so the log-in dialog keeps its own behaviour. */
.hs-signup .signup-modal{
  max-height:calc(100vh - 40px);
  overflow-y:auto;
  overscroll-behavior:contain;
}

/* The step crumb. `.signup-close` is 32px at top/right 16px, so the crumb
   stops short of it rather than running underneath. */
.hs-signup .hs-crumb{
  display:flex; gap:5px; margin:0 0 16px; padding-right:44px;
}
.hs-signup .hs-crumb i{
  height:3px; flex:1; border-radius:2px; display:block;
  background:var(--line-strong); transition:background .2s ease;
}
.hs-signup .hs-crumb i.on{background:var(--cta);}

.hs-signup .hs-load{margin:26px 0; text-align:center; color:var(--ink-3);}
.hs-signup .hs-block{display:block; width:100%;}

/* ═══ The Speak It moment ═══════════════════════════════════════════════
   Ported value-for-value from the approved artefact. Alex, 2026-08-24:
   "Make sure that you are doing 100% pixel-for-pixel, pixel-perfect creation
   of what you sent me in the artefact."

   🚨 THE MIC IS A PICTURE. Nothing here may ever be wired to getUserMedia —
   a signup page must not throw a permission prompt over a card field. The real
   dictation control is js/voice-input.js, behind the login. */
.hs-signup .hs-demo{
  border:1.5px solid var(--line); border-radius:10px;
  background:var(--cream-2); padding:11px 13px; margin:0 0 13px;
  transition:border-color .25s, background .25s, box-shadow .25s;
}
.hs-signup .hs-demo.live{
  border-color:var(--cta); background:#fff; box-shadow:0 0 0 4px rgba(236,16,117,.10);
}
.hs-signup .hs-say{min-height:2.9em; font-size:13.5px; color:var(--ink); margin:0;}
/* ⚠️ EVERY PIXEL HERE IS A PIXEL OFF THE BOTTOM OF THE PANEL. Measured on the
   built thing at 390x844, the submit button's bottom edge sits at 791px against
   an 804px fold — 13px of margin, which is not enough to be safe on a phone
   with a taller browser chrome. Two lines of the demo sentence is the real
   worst case, so the box is sized for exactly that and no more. */
@media (max-width:540px){ .hs-signup .hs-say{min-height:2.6em; font-size:13px;} }
.hs-signup .hs-say.hs-empty{color:var(--ink-4);}
/* ⚠️ THE CURSOR IS A PSEUDO-ELEMENT, NOT A SPAN, AND THAT IS DELIBERATE. The
   typing writes `textContent`, which wipes every child node — a cursor span
   would vanish on the first keystroke. An earlier cut had both and rendered
   two of them. */
.hs-signup .hs-say:not(.hs-done)::after{
  content:""; display:inline-block; width:1.5px; height:1em; vertical-align:-.14em;
  background:var(--cta); margin-left:1px;
}
.hs-signup .hs-demo.live .hs-say::after{animation:hs-blink 1s steps(1) infinite;}
@keyframes hs-blink{0%,50%{opacity:1}51%,100%{opacity:0}}

.hs-signup .hs-microw{display:flex; align-items:center; gap:8px; margin-top:9px;}
.hs-signup .hs-mic{
  display:inline-flex; align-items:center; gap:6px;
  border:1.5px solid var(--line-strong); border-radius:999px; background:#fff;
  color:var(--ink-2); font-size:11.5px; font-weight:600; padding:5px 11px 5px 9px;
  transition:border-color .2s, color .2s;
}
.hs-signup .hs-demo.live .hs-mic{border-color:var(--cta); color:var(--cta);}
.hs-signup .hs-dot{
  width:8px; height:8px; border-radius:50%; background:var(--ink-4);
  flex:0 0 auto; transition:background .2s;
}
.hs-signup .hs-demo.live .hs-dot{background:var(--cta); animation:hs-pulse 1.15s ease-in-out infinite;}
@keyframes hs-pulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.45);opacity:.55}}

.hs-signup .hs-wave{display:flex; align-items:flex-end; gap:2px; height:13px; opacity:0; transition:opacity .25s;}
.hs-signup .hs-demo.live .hs-wave{opacity:1;}
.hs-signup .hs-wave i{width:2px; border-radius:1px; background:var(--cta); height:3px;}
.hs-signup .hs-demo.live .hs-wave i{animation:hs-wv .7s ease-in-out infinite;}
.hs-signup .hs-wave i:nth-child(2){animation-delay:.09s}
.hs-signup .hs-wave i:nth-child(3){animation-delay:.18s}
.hs-signup .hs-wave i:nth-child(4){animation-delay:.27s}
.hs-signup .hs-wave i:nth-child(5){animation-delay:.36s}
.hs-signup .hs-wave i:nth-child(6){animation-delay:.45s}
.hs-signup .hs-wave i:nth-child(7){animation-delay:.15s}
@keyframes hs-wv{0%,100%{height:3px}50%{height:13px}}

.hs-signup .hs-built{
  font-family:"JetBrains Mono", ui-monospace, monospace;
  font-size:10.5px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-3); margin:0 0 9px; display:flex; align-items:center; gap:7px;
  opacity:0; transition:opacity .3s;
}
.hs-signup .hs-built.on{opacity:1;}
.hs-signup .hs-built b{color:var(--accent); font-weight:600;}

/* ── The three tabs ───────────────────────────────────────────────────
   Alex: "three tabs that they can click between… they feel they've got the
   full toolkit there."

   🚨 `.hs-panes` IS SIZED TO THE TALLEST TAB AND THAT IS load-bearing. If a
   tab switch could change the panel height, tapping one would slide the card
   field out from under a thumb — the exact fault the tabs exist to fix. The
   tallest tab is Marketing at four rows: 4 x 18.9px + 3 x 7px gap = 97px, with
   the rest of the box making 112. Adding a fifth line to any tab means moving
   this number, not letting it reflow. */
.hs-signup .hs-tabs{
  display:flex; gap:4px; margin:0 0 11px; padding:3px;
  background:var(--cream-2); border-radius:9px;
  opacity:0; transition:opacity .3s;
}
.hs-signup .hs-tabs.in{opacity:1;}
.hs-signup .hs-tab{
  flex:1; border:0; cursor:pointer; font-family:inherit;
  font-size:11.5px; font-weight:600; letter-spacing:.01em;
  padding:6px 4px; border-radius:6px; background:transparent; color:var(--ink-3);
  transition:background .16s, color .16s;
}
.hs-signup .hs-tab:hover{color:var(--ink-2);}
.hs-signup .hs-tab.on{background:#fff; color:var(--ink); box-shadow:0 1px 3px rgba(42,32,48,.13);}
/* 100px is Marketing at four rows (4 x 18.9 + 3 x 7 = 97) plus a hair. It is a
   fixed number rather than `auto` on purpose — see the note above — so adding a
   fifth line to any tab means changing THIS, not letting the panel reflow. */
.hs-signup .hs-panes{min-height:100px;}
.hs-signup .hs-inc[hidden]{display:none;}

/* The build tick. Items arrive one at a time, once. */
.hs-signup .hs-inc li{opacity:0; transform:translateY(4px); transition:opacity .3s, transform .3s;}
.hs-signup .hs-inc li.in{opacity:1; transform:none;}
.hs-signup .hs-inc li.in::before{animation:hs-pop .34s cubic-bezier(.34,1.56,.64,1);}
@keyframes hs-pop{0%{transform:scale(.2);opacity:0}60%{transform:scale(1.2)}100%{transform:scale(1);opacity:1}}

/* ⚠️ REDUCED MOTION GETS THE FINISHED PANEL, not a frozen half-built one.
   The JS settles the state too; this is the belt to that pair of braces, and
   it matters because the items default to opacity:0. */
@media (prefers-reduced-motion:reduce){
  .hs-signup .hs-inc li{opacity:1; transform:none;}
  .hs-signup .hs-tabs{opacity:1;}
  .hs-signup .hs-built{opacity:1;}
  .hs-signup .hs-say::after{display:none;}
}

/* What they get. The sentence above it promises a list, so there is one — the
   first build shipped "everything below is included" above nothing at all. */
.hs-signup .hs-inc{list-style:none; margin:0 0 4px; padding:0; display:grid; gap:7px;}
/* ⚠️ ONE LINE EACH IS A HARD CONSTRAINT. Alex, 2026-08-24: "Is there any way to
   split this so that everything lands more punchy, just on one line each, even
   if I split some of them out as two?" A wrapped bullet stops being scannable
   and starts being a paragraph, directly above a card field. `align-items:
   center` because nothing here should be tall enough to need otherwise — if a
   line ever wraps it will look wrong, which is the point. */
.hs-signup .hs-inc li{
  font-size:13.5px; line-height:1.4; color:var(--ink-2);
  display:flex; gap:8px; align-items:center;
}
.hs-signup .hs-inc li::before{content:"\2713"; color:var(--good); font-weight:700; flex-shrink:0;}
.hs-signup .hs-inc em{
  font-style:normal; font-size:9.5px; letter-spacing:.08em; text-transform:uppercase;
  font-family:"JetBrains Mono", ui-monospace, monospace;
  padding:2px 6px; border-radius:5px; margin-left:6px; white-space:nowrap;
  background:#fbf0df; color:#a8641b;
}

/* ── The price. The whole reason this panel was rebuilt. ───────────────
   Alex: "You also haven't told them how much they're going to be charged after
   14 days. This is very, very poor." Amount and date above the card field, in
   the accent the platform uses for anything to do with the plan. */
.hs-signup .hs-price{
  background:var(--accent-soft); border:1.5px solid rgba(106,76,241,.32);
  border-radius:12px; padding:15px 16px; margin-top:14px;
}
.hs-signup .hs-prow{
  display:flex; justify-content:space-between; gap:12px;
  font-size:13.5px; padding:3px 0;
}
.hs-signup .hs-prow b{font-variant-numeric:tabular-nums;}
.hs-signup .hs-total{
  border-top:1px solid rgba(106,76,241,.26);
  margin-top:7px; padding-top:9px; font-weight:650;
}
.hs-signup .hs-pnote{margin:9px 0 0; font-size:11.5px; line-height:1.5; color:var(--ink-2);}

/* ⚠️ THE PRICE PANEL SITS OUTSIDE THE FORM, SO NOTHING SEPARATED THEM. Alex,
   2026-08-24: "The spacing about where the card detail is is a bit cramped up
   there." `.signup-form`'s 14px gap only spaces its own children; the panel
   above it is a sibling with no bottom margin, so "Card details" was flush
   against the bottom of the price box and read as part of it. 18px matches the
   gap the list leaves above the panel, so the panel is evenly framed. */
.hs-signup .signup-form{margin-top:18px;}

/* The Stripe Element, given the box `.signup-field input` would have had, so
   the card row is not visibly a different control from the name field one step
   earlier. `.is-focus` is set from the Element's own focus/blur events —
   Stripe renders in a cross-origin iframe, so :focus-within never fires here. */
.hs-signup .hs-card{
  border:1.5px solid var(--line); border-radius:10px;
  padding:13px 14px; background:var(--cream-2);
  transition:border-color .15s, background .15s, box-shadow .15s;
}
.hs-signup .hs-card.is-focus{
  border-color:var(--accent); background:#fff;
  box-shadow:0 0 0 4px rgba(106,76,241,.12);
}

.hs-signup .hs-err{margin:0; font-size:13px; color:#b4232a; text-align:left;}
.hs-signup .hs-trust{margin-top:12px; color:var(--ink-3);}
.hs-signup .hs-trust span::before{background:var(--good);}
.hs-signup .hs-rev{margin-top:14px;}

.hs-signup .hs-tiny{margin:12px 0 0; font-size:12px; color:var(--ink-3); text-align:center;}
/* The way out sits at the very bottom and is deliberately quiet — a visible
   skip beside a buy button cannibalises the trial. */
.hs-signup .hs-link{
  background:none; border:none; padding:0; cursor:pointer;
  font-family:inherit; font-size:inherit;
  color:var(--ink-3); text-decoration:underline;
  text-decoration-color:var(--line-strong);
}
.hs-signup .hs-link:hover{color:var(--ink);}

/* ⚠️ THE PALETTE MAP. `.rev` is written above in the ROOT tokens because it is
   used on the page. Inside the overlay the warm set is in scope instead, and
   `--ink2` / `--ink3` do not exist there at all — left alone, the modal's
   review card would quietly render in the page's cooler greys beside warm text.
   These four lines are the whole fix, and they are why the map is documented
   rather than discovered again later. */
.hs-signup .rev{background:var(--surface); border-color:var(--line);}
.hs-signup .rev .q{color:var(--ink-2);}
.hs-signup .rev .nm{color:var(--ink);}
.hs-signup .rev .nm em{color:var(--ink-3);}

body.hs-open{overflow:hidden;}

/* ── The billing address block ─────────────────────────────────────────
   Alex, 2026-08-25: *"Put the postal code back in but make sure that it
   geo-detects… first line of address and postcode just maximises the chance of
   approval."* Why it is worth the friction, in Stripe's own words:
   docs/projects/billing/STRIPE-AUTH-RESEARCH.md.

   🚨 THE MODULE IS RENDERED WITH PREFIX `signup` ON PURPOSE. That makes its
   container `.signup-field`, which marketing-site.css ALREADY styles — the same
   flex column, gap, border, radius and focus ring as the name field a step
   earlier. So the address rows inherit the house form for free, and only the
   two controls the house sheet has never had need rules here:

     · `<label>` — the house label is `.signup-field span`, and the module emits
       a real <label for> because a payment field needs a clickable label and a
       screen-reader association that a <span> cannot give.
     · `<select>` — no select has existed in this dialog before.

   Both are copied from `.signup-field span` / `.signup-field input` rather than
   re-invented, so they cannot drift from the field above them. */
.hs-signup .signup-addr { display: flex; flex-direction: column; gap: 14px; margin-bottom: 14px; }
.hs-signup .signup-addr label {
  font-size: 12px; color: var(--ink-2); font-weight: 600;
}
/* A long country name truncates with an ELLIPSIS, not mid-word. Same rule as
   the subnav labels: a cut you cannot see reads as the real text. */
.hs-signup .signup-addr select {
  text-overflow: ellipsis;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 14.5px;
  color: var(--ink);
  background-color: var(--cream-2);
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
  outline: none;
  width: 100%;
  appearance: none; -webkit-appearance: none;
  /* Data URI: the CSP blocks external images, and a select with no caret reads
     as a disabled text box. Stroke colour is --ink-3. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b7e92' stroke-width='2.4'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
  padding-right: 36px;
}
.hs-signup .signup-addr select:focus {
  border-color: var(--accent);
  background-color: #fff;
  box-shadow: 0 0 0 4px rgba(106, 76, 241, 0.12);
}
.hs-signup .signup-addr [hidden] { display: none; }

/* Country + postcode share a row: see billing-address-fields.js. Stacked, the
   block cost 244px and pushed the mobile submit button ~200px below the fold. */
.hs-signup .signup-addr .signup-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* 🚨 `min-width:0` OR THE COLUMNS ARE NOT EQUAL. A grid item defaults to
   `min-width:auto`, so the text input refuses to shrink below its
   min-content width (~20 characters) and eats the row — which squeezed
   the country select to 84px and rendered "United Kingdom" as "Unite".
   The same flexbox/grid default that made the subnav label overflow. */
.hs-signup .signup-addr .signup-row > * { min-width: 0; }
@media (max-width: 359px) { .hs-signup .signup-addr .signup-row { grid-template-columns: 1fr; } }

/* ── The trial panel on a desktop ──────────────────────────────────────
   Alex, 2026-08-25: *"this page needs to be designed for desktop. The modal
   works fine for phone but there's no reason to have this scrolling downwards
   when you've got a whole desktop to play with."*

   Everything that ARGUES goes left (say what you coach, what Maya builds,
   what is included); everything that TRANSACTS goes right (price, address,
   card, submit). Below the breakpoint the grid collapses and the panel is
   exactly the single column it always was, in the original order — which is
   why the wrappers carry no styling of their own outside this block.

   ⚠️ .hs-signup IS ON THE OVERLAY, not the modal — signup-modal.js appends the
   caller's className to `signup-overlay`. Widening `.signup-modal` therefore
   has to be a descendant selector, and it has to be scoped to this class so the
   platform's other signup flows keep their 460px. */
.hs-cols { display: grid; }
@media (min-width: 900px) {
  /* ⚠️ :has(.hs-cols) — ONLY THE TWO-COLUMN PANEL, NOT EVERY STEP.
     home-signup.js opens ONE modal with className 'hs-signup' and reuses it for
     the email step, the name step and the card panel. Widening `.hs-signup
     .signup-modal` therefore stretched a one-field "What should we call you?"
     form to 880px. Alex, 2026-08-25: *"Why has this suddenly gone so wide?"*
     The wide layout belongs to the panel that actually has two columns, so the
     selector now asks for exactly that. */
  .hs-signup .signup-modal:has(.hs-cols) { max-width: 880px; }
  .hs-signup .hs-cols {
    grid-template-columns: 1fr 1fr;
    gap: 32px;
    align-items: start;
  }
  .hs-signup .hs-c-buy {
    border-left: 1px solid var(--line, #ebe1c9);
    padding-left: 32px;
  }
  /* the hero copy above the columns should not stretch to 880px */
  .hs-signup .signup-title,
  .hs-signup .signup-sub { max-width: 640px; }
}
