/* Stowit marketing site — additions on top of the design system.
   tokens.css / illustration.css / surfaces.css are unmodified; everything
   page-specific (full-bleed hero, scan states, estimator) lives here. */

html, body { margin: 0; padding: 0; background: var(--paper-cool); }
body { font-family: var(--font-sans); color: var(--ink); }

/* ── Header — surface 1a, the two-port cargo run ──────────────────────
   The hero's scene is pinned to 1120px: the boat, its 148px run, and both
   piers are absolute pixel offsets that only agree at that one width. So
   below 1120px the whole surface is SCALED, never reflowed — a percentage
   translateX would resolve against the boat's own width, not the scene's,
   and the boat would moor on top of the far pier. fitHero() sets --hero-s;
   the wrapper's height follows it so the page below doesn't gap. */
/* Full-bleed: the surface is a page header now, not a card on a canvas, so
   it drops the panel's width, radius and shadow and runs to both edges. */
.page-hero { padding: 0; }
.hero { width: 100%; border-radius: 0; box-shadow: none; overflow: visible; }
/* display:block, not the surface's flex — as a flex item the inner bar would
   shrink to its content and `margin:0 auto` would centre that, instead of
   spanning and pushing the links to the right edge. */
.hero__nav { display: block; padding: 0; background: var(--sky-light); }
/* 1120 + the copy column's own 56px inset, so the wordmark sits on the same
   left edge as the headline below it. */
.hero__nav-inner {
  max-width: 1120px; margin: 0 auto; padding: 14px 56px 6px;
  display: flex; align-items: center; gap: 12px;
}
.hero__scene { height: clamp(430px, 40vw, 540px); }
/* The home hero carries two lanes and two buttons now, and at the old height
   the last line landed ON the water -- grey mono on blue, unreadable. The extra
   sky is the whole change: the swell, its motion and the ship are untouched,
   they simply sit lower. Found by rendering it; the stylesheet reads fine
   either way.
   Scoped ABOVE 900px on purpose. Below that the copy stacks above a shorter
   illustration band and the scene is height:auto -- and because this selector
   is more specific than that rule, an unscoped version overrode it and pinned
   the scene to a fixed height while the copy grew to 737px. The water then cut
   straight through the middle of the second lane. */
@media (min-width: 901px) {
  .page-hero .hero__scene { height: clamp(560px, 46vw, 620px); }
}

/* The water is fluid so it never scales, but the boat and piers sit at fixed
   offsets inside a stage that does. Scaling the water band by the same factor
   keeps the waterline under the hull instead of swallowing it. */
.hero__water {
  --water-h: calc(104px * var(--hero-s, 1));
  --crest-h: calc(36px * var(--hero-s, 1));
}

/* Sky, clouds and water are fluid; this holds everything whose position the
   design pins to 1120px. Centred by transform rather than `margin:auto`,
   because auto margins collapse to 0 once the box is wider than its parent
   and park it at the left edge. Scaled from the BOTTOM so the boat and the
   piers stay on the waterline as it shrinks. */
.hero__stage {
  position: absolute; inset: 0 auto 0 50%;
  width: 1120px; height: 100%;
  transform-origin: bottom left;
  transform: scale(var(--hero-s, 1)) translateX(-50%);
  /* Pure decoration, and it comes AFTER the copy in the DOM, so without this
     it paints over the hero's buttons and eats every click on them. */
  pointer-events: none;
}
/* Aligned to the same 1120 column as the nav and the stage, but never
   scaled — it is a sibling of the stage, not a child. */
.hero__copy { left: max(24px, calc(50% - 504px)); z-index: 2; }

/* Products / FAQ / Pricing / Contact use the same .band chrome as How it works.
   Inner copy stays a reading column so it does not stretch across 1120px. */
.home-body { margin: 28px 0 0; max-width: 62ch; }
/* The products band is a card row, not a column of prose, so it takes the
   full band width. Measured: without this the three cards come out 171px
   wide and the commands inside them have nowhere to go. */
.home-body--wide { max-width: none; }
.home-body .home-faq {
  margin: 0; padding: 0 0 0 18px;
  font-size: 14.5px; line-height: 1.58; color: var(--ink-muted-cool);
}
.home-body .home-faq li { margin-bottom: 10px; }
.home-body .home-faq b { color: var(--ink); font-weight: 600; }
.home-body > p {
  margin: 0 0 10px; font-size: 16.5px; line-height: 1.62; color: var(--ink-muted-cool);
}
.home-body > p:last-child { margin-bottom: 0; }
.home-product__title {
  margin: 0 0 8px; font: 600 16px var(--font-sans); color: var(--ink);
}
.home-product__tag {
  display: inline-block; margin-left: 8px;
  font: 600 11px var(--font-sans); text-transform: uppercase; letter-spacing: .04em;
  color: var(--verified-text); background: var(--verified-bg);
  padding: 2px 8px; border-radius: var(--r-chip);
}
.home-product__tag--soon {
  color: var(--note-text); background: var(--note-bg);
}
.home-product p {
  margin: 0 0 10px; font-size: 14px; line-height: 1.58; color: var(--ink-muted-cool);
}
.home-product p:last-child { margin-bottom: 0; }
.home-pricing-tier {
  padding: 12px 0; border-top: 1px solid var(--hairline-cool);
}
.home-pricing-tier:first-child { border-top: 0; padding-top: 0; }
.home-pricing-tier__price {
  margin: 0; font: 600 18px var(--font-sans); color: var(--ink);
}
.home-pricing-tier__note {
  font-size: 13px; color: var(--ink-faint-cool); font-style: italic;
}
/* A product entry is a pitch, not a row in a list: a benefit line, the argument,
   then one button into that product's own funnel. Compress and Dock share an
   install step, so their buttons must not both be "install stowit" -- Dock's
   reveals the two commands it actually needs, and Attic's reveals the read-only
   command that tells you what Attic would refuse to store. */
/* ── Products: three across ────────────────────────────────────────────────
   Todd, 2026-09-03, pointing at the Direct Routes canvas: he meant the
   LAYOUT, not the copy. Cards on a white surface, one row, equal height, each
   with its own way in. `align-items: stretch` plus a body that grows is what
   keeps three very unequal blocks of copy from stepping the buttons out of
   line -- Attic's is three paragraphs and Compress's is one. */
.home-products {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px; margin: 6px 0 0; align-items: stretch;
}
.home-product {
  display: flex; flex-direction: column; gap: 10px;
  padding: 22px; background: #fff;
  border: 1px solid var(--hairline-warm, var(--hairline-cool));
  border-radius: 12px;
}
/* The hero's "Stow it." button focuses this card so the eye lands on ONE of
   the three, not on the row. `outline: none` here would delete the only signal
   the button gives, so it is styled rather than removed. */
.home-product:focus-visible,
.home-product:focus {
  outline: 3px solid var(--sun);
  outline-offset: 3px;
  border-color: var(--sun);
}
/* Without this the card lands flush at y=0 and the top of its own ring is
   clipped off-screen -- measured, not guessed. */
.home-product { scroll-margin-top: 22px; }
.home-product__head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.home-product__icon { display: block; width: 20px; height: 20px; color: var(--brand-blue); }
.home-product__icon svg { display: block; width: 20px; height: 20px; }
/* The body carries the length difference so the CTA lands on one line across
   all three cards. */
.home-product__body { flex: 1 1 auto; }
.home-product__body p { margin: 0 0 10px; }
.home-product__body p:last-child { margin-bottom: 0; }
.home-product .home-product__cta { align-self: flex-start; }
/* Real measured figures, set as a scannable list so the proof reads before the
   price does. */
.home-product__proof {
  list-style: none; margin: 0 0 12px; padding: 10px 12px;
  background: var(--note-bg); border-radius: 10px;
  font: 400 13.5px/1.5 var(--font-sans); color: var(--ink);
}
.home-product__proof li::before { content: "\2713  "; color: var(--brand-blue); font-weight: 700; }
/* Two routes per card where a card has two. The row wraps rather than shrinking
   the buttons, because a CTA that has to be read at 11px is not a CTA.

   It STICKS to the bottom of its own card (Todd, 2026-09-08: "make sure the
   CTA's move with the scroll if section is expanded"). Expanding a card's
   disclosure pushes its buttons a screen and a half down; sticky keeps the
   thing you can do in front of you for as long as the card it belongs to is
   on screen, and lets go the moment the card ends -- so it never floats over
   a neighbour. The background and the negative margins are what stop the
   copy showing through it and let it span the card's own padding. */
.home-product__actions {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 4px;
  position: sticky; bottom: 0;
  background: #fff;
  margin-left: -22px; margin-right: -22px; margin-bottom: -22px;
  padding: 10px 22px 22px;
}
.home-product__actions .home-product__cta { margin-top: 0; }
/* Attic has three paragraphs where Compress has one, and in an equal-height
   row that difference is a 400px void under the other two cards. Every word
   stays -- the tail of it just opens on demand, so the three bodies are
   comparable and the row reads as the canvas draws it. */
.home-product__more { margin-top: 10px; }
.home-product__more > summary {
  cursor: pointer; list-style: none;
  font: 600 13px var(--font-sans); color: var(--brand-blue);
}
.home-product__more > summary::-webkit-details-marker { display: none; }
.home-product__more > summary::after { content: " \203A"; }
.home-product__more[open] > summary::after { content: " \2039"; }
.home-product__more > p { margin: 10px 0 0; }
.home-product__cta[aria-pressed="true"] { filter: brightness(.94); }
/* A price with no next step is a page a reader leaves. Each pricing tier
   carries the same route its product card does. */
.home-pricing-tier__cta { margin-top: 10px; }
/* One pane under the row, not three inside the columns: a vault-init command
   does not fit a third of the band, and the canvas draws it wide too. */
.home-routepane {
  margin-top: 20px; padding: 20px 22px;
  background: #fff;
  border: 1px solid var(--hairline-warm, var(--hairline-cool));
  border-left: 3px solid var(--sun);
  border-radius: 12px;
}
.home-routepane__title {
  margin: 0 0 14px; font: 700 15px var(--font-sans); color: var(--ink);
}
@media (max-width: 900px) {
  .home-products { grid-template-columns: 1fr; gap: 16px; }
}
.home-product__lede {
  margin: 0 0 8px; font: 600 15.5px var(--font-sans); color: var(--ink);
}
.home-product__tag--price {
  color: var(--brand-blue); background: var(--brand-blue-wash, var(--note-bg));
  text-transform: none; letter-spacing: 0;
}
.home-product__cta {
  margin: 4px 0 0; padding: 8px 16px;
  font: 600 13.5px var(--font-sans); color: var(--ink);
  background: var(--sun); border: 0; border-radius: var(--r-chip);
  cursor: pointer;
}
.home-product__cta:hover { filter: brightness(1.04); }
/* The second route on a card is real but subordinate: two sun pills side by
   side read as two primaries and the reader has to pick. Outline, brand ink,
   no fill -- and declared here rather than above, because the base rule sets
   both background and color and the cascade goes to whoever is last. */
.home-product__cta--quiet {
  background: transparent; color: var(--brand-blue);
  box-shadow: inset 0 0 0 1.5px currentColor;
}
.home-product__cta--quiet:hover { background: var(--note-bg); filter: none; }
.home-product__cta--quiet[aria-pressed="true"] { background: var(--note-bg); filter: none; }
.home-product__reveal {
  margin-top: 14px; padding: 12px 16px;
  /* The band is already warm paper, so a warm panel on it has no edge. One
     rule down the left ties the steps to the button that revealed them. */
  border-left: 3px solid var(--sun);
}
.home-product__step {
  margin: 0 0 6px; font: 600 13px var(--font-sans); color: var(--ink);
}
.home-product__cmd {
  display: block; width: 100%; margin: 0 0 12px; padding: 10px 12px;
  font: 13px/1.45 var(--font-mono); color: var(--ink); text-align: left;
  background: var(--paper, #fff); border: 1px solid var(--hairline-cool);
  border-radius: 8px; cursor: pointer;
}
.home-product__cmd:hover { border-color: var(--brand-blue); }
.home-product__cmd:hover .convert__cmd-cue { box-shadow: 0 0 0 4px var(--sun-glow-soft); }
/* The pre/overflow moves onto the command itself now that the button also
   holds a cue chip. One line that scrolls, never a wrap: at 390px a wrap split
   "<your-drive>" across two lines, which reads as a typo in a command someone
   is about to paste. */
.home-product__cmd .convert__cmd-text {
  white-space: pre; overflow-x: auto;
}
.home-product__note {
  margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-faint-cool);
}
.home-product__waitlist { font-size: 12.5px; }

/* ── Numbered step panes, one per product ──────────────────────────────────
   Todd, 2026-09-03: each product needs a button into its own funnel, shaped
   like the Direct Routes canvas. Three panes with the same grammar -- a
   numbered rail, one command per step, copy the lot -- so a visitor who has
   already decided ("I have a drive") never has to go through the number
   first. The rail is the yellow the CTA is, so the pane reads as belonging
   to the button that opened it. */
.home-steps { margin: 0 0 12px; padding: 0; list-style: none; }
.home-step {
  position: relative; padding-left: 30px; margin: 0 0 14px;
}
.home-step:last-child { margin-bottom: 0; }
.home-step__n {
  position: absolute; left: 0; top: 1px;
  width: 21px; height: 21px; border-radius: 50%;
  display: grid; place-items: center;
  font: 700 11.5px var(--font-sans); color: var(--ink);
  background: var(--sun);
}
.home-step__t {
  margin: 0 0 6px; font: 600 13px var(--font-sans); color: var(--ink);
}
/* A step whose answer is a link, not a command -- Linux has no one-line
   installer, and printing one would be the rule this project has broken
   five times. */
.home-step__t a { color: var(--brand-blue); }
.home-steps__foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  margin-top: 12px;
}
.home-steps__all {
  padding: 7px 14px; font: 600 12.5px var(--font-sans); color: var(--ink);
  background: transparent; border: 1px solid var(--hairline-cool);
  border-radius: var(--r-chip); cursor: pointer;
}
.home-steps__all:hover { border-color: var(--brand-blue); }
.home-steps__alt {
  font: 400 12.5px var(--font-sans); color: var(--ink-faint-cool);
  background: transparent; border: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.home-steps__alt:hover { color: var(--brand-blue); }
/* Which machine the commands are written for. The page already detects it;
   this only lets a visitor say otherwise -- someone reading on a Mac about
   the PC in the next room. */
.home-os { display: flex; gap: 6px; margin: 0 0 12px; }
.home-os__btn {
  padding: 4px 11px; font: 600 12px var(--font-sans);
  color: var(--ink-faint-cool); background: transparent;
  border: 1px solid var(--hairline-cool); border-radius: var(--r-chip);
  cursor: pointer;
}
.home-os__btn[aria-pressed="true"] {
  color: var(--ink); background: var(--paper, #fff);
  border-color: var(--brand-blue);
}
.home-pricing-tier__unit {
  font: 400 13px var(--font-sans); color: var(--ink-faint-cool);
}
.home-accordions__cta { margin-top: 8px; }
.home-accordions__cta-note {
  margin: 12px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink-faint-cool);
}
.home-contact__email {
  font: 600 16px var(--font-sans); color: var(--brand-blue); text-decoration: none;
}
.home-contact__email:hover { text-decoration: underline; }

/* ── Narrow: stack instead of overlay ────────────────────────────────────
   Under ~900px there is no room for text over the water, so the copy
   becomes ordinary flow above a shorter illustration band. */
@media (max-width: 900px) {
  .hero__nav-inner { padding: 12px 20px 4px; }
  .hero__links { gap: 10px; }
  .hero__scene { height: auto; padding-top: 8px; }
  .hero__copy {
    position: static; width: auto; max-width: 34rem;
    padding: 0 20px 26px; left: auto; top: auto;
  }
  .hero__deck { max-width: none; }
  .hero__actions { flex-wrap: wrap; }
  /* Everything in the stage is anchored to its bottom and scales about that
     edge, so the slack is empty sky ABOVE the boat. Sizing the band by the
     scale factor crops that sky; the hull still lands on the waterline,
     because the water band scales by the same factor. */
  .hero__stage {
    position: relative; inset: auto; left: auto;
    height: calc(300px * var(--hero-s, 1)); margin-left: 50%;
  }
  .hero__clouds { display: none; }
}
/* Paper-warm behind the nav: the lockup's cabin and hull are white and
   carry only --shadow-hull, so on a near-white ground the cabin vanishes
   and the windows read as three loose dots. */
/* Sky, not paper. There is no nav BAR any more -- the sky starts at the top
   of the page and runs unbroken down to the water, and the sun sits in it. */
.hero__nav { background: var(--sky-light); position: relative; z-index: 6; overflow: visible; }
.hero__links {
  margin-left: auto; display: flex; align-items: center; gap: 12px;
  position: relative; z-index: 5;
}
.hero__menu { position: relative; }
.hero__menu-btn {
  list-style: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  margin: 0; padding: 0;
  border: 0; background: none;
}
.hero__menu-btn::-webkit-details-marker,
.hero__menu-btn::marker { display: none; content: ""; }

/* The sun that used to sit in the hero stage, at the same 68px, moved here and
   made clickable. Moved rather than copied -- two suns in one sky is worse
   than none. */
.hero__sunmark {
  position: relative;
  display: grid; place-items: center;
  width: 68px; height: 68px;
}
.hero__sunmark-rays { position: absolute; width: 68px; height: 68px; opacity: .85; }
.hero__sunmark-disc {
  position: relative;
  width: 45px; height: 45px;
  border-radius: 999px;
  background: var(--sun);
}
/* At rest there is no ring at all: it is just the sun in the sky, asking for
   nothing. The ring is the entire interaction -- it eases out from under the
   disc and glows, and stays while the menu is down. */
.hero__sunmark-ring {
  position: absolute; inset: -11px;
  border-radius: 999px;
  border: 5px solid rgba(255, 201, 74, .34);
  box-shadow: 0 0 20px rgba(255, 201, 74, .45), inset 0 0 12px rgba(255, 201, 74, .30);
  opacity: 0; transform: scale(.84);
  transition: opacity .28s ease, transform .42s cubic-bezier(.34, 1.4, .5, 1);
  pointer-events: none;
}
.hero__menu-btn:hover .hero__sunmark-ring,
.hero__menu-btn:focus-visible .hero__sunmark-ring,
.hero__menu[open] .hero__sunmark-ring { opacity: 1; transform: scale(1); }
.hero__menu[open] .hero__sunmark-ring { border-color: rgba(255, 201, 74, .52); }
.hero__menu-btn:focus-visible { outline: none; }

/* A disc reads as decoration, and behind it are Products, FAQ, Pricing and
   Contact -- the only route to any of them. Nobody hovers a picture of the sky.
   One line of grey type buys the affordance back and costs the sun nothing. */
.hero__menu-word {
  font: 700 10px var(--font-sans);
  letter-spacing: 1.4px;
  color: var(--ink-faint-cool);
}

/* Restored verbatim: replacing the mark's rules swallowed these, and the menu
   opened as a bare row of blue links. Nothing in the stylesheet said so -- the
   render did. */
.hero__menu-list {
  position: absolute; top: calc(100% + 6px); right: 0;
  min-width: 176px; padding: 8px;
  background: var(--hull);
  border: 1px solid var(--hairline-warm);
  border-radius: 14px;
  box-shadow: 0 10px 28px rgba(11, 18, 32, .12);
  display: flex; flex-direction: column; gap: 2px;
  z-index: 30;
}
.hero__menu-list a {
  padding: 9px 12px; border-radius: 9px;
  color: var(--ink-muted-cool); text-decoration: none; font-size: 13.5px;
}
.hero__menu-list a:hover { background: rgba(76, 151, 238, .08); color: var(--ink); }

.hero__cta {
  cursor: pointer; border: 0; font: 600 13.5px var(--font-sans);
  color: var(--ink); background: var(--sun);
  padding: 8px 16px; border-radius: var(--r-chip);
}
.hero__btn { cursor: pointer; border: 0; font: 600 14.5px var(--font-sans); }
/* The secondary button carries the whole tap path, which is long. Drop it a
   step in mono so the pair still fits the 430px copy column at full width. */
.hero__btn--secondary { font-family: var(--font-mono); font-weight: 400; font-size: 13px; padding: 11px 14px; }
/* The benefit, in its own voice between the headline and the explanation.
   Sized between the two so the eye lands headline -> promise -> detail. As a
   bold lead-in inside the deck it wrapped mid-sentence and read as grey wall. */
.hero__promise {
  margin: 14px 0 0; max-width: 400px;
  font: 650 19px/1.38 var(--font-sans); letter-spacing: -.2px; color: var(--ink);
  text-wrap: balance;
}
/* pretty, not balance: the deck is a paragraph, and the only thing wrong with
   it was a one-word last line under the promise. */
.hero__deck { margin-top: 10px; text-wrap: pretty; }
.hero__deck b { color: var(--ink); font-weight: 650; }
.hero__assure {
  margin: 18px 0 0; font-size: 12.5px; line-height: 1.5;
  color: var(--ink-faint-cool); max-width: 34ch;
}
.hero__assure b { color: var(--ink-muted-cool); font-weight: 600; }

/* ── The glance, now a section under the hero ─────────────────────────── */
.lead { background: var(--paper-cool); border-bottom: 1px solid var(--hairline-cool); }
.lead__nav {
  max-width: 1120px; margin: 0 auto;
  display: flex; align-items: center; gap: 12px; padding: 22px 24px 0;
}
.lead__mark { font-weight: 700; font-size: 17px; letter-spacing: -.4px; color: var(--ink); }
.lead__links { margin-left: auto; display: flex; align-items: center; gap: 24px; font-size: 13.5px; }
.lead__links a { color: var(--ink-muted-cool); text-decoration: none; }
.lead__links a:hover { color: var(--ink); }
.lead__cta {
  cursor: pointer; border: 0; font: 600 13.5px var(--font-sans);
  color: var(--ink); background: var(--sun);
  padding: 8px 16px; border-radius: var(--r-chip);
}

.lead__grid {
  max-width: 1120px; margin: 0 auto;
  padding: 52px 24px 60px;
  display: grid; grid-template-columns: 1fr 380px; gap: 64px; align-items: center;
}
/* Single-column now that the hero carries the headline; must come after
   .lead__grid or its `1fr 380px` template wins and the card sticks left. */
.lead__grid--glance { grid-template-columns: 380px; justify-content: center; padding: 44px 24px 60px; }

.lead__copy h1 { margin: 0 0 18px; color: var(--ink); }
.lead__deck { margin: 0; color: var(--ink-muted-cool); max-width: 46ch; }
.lead__actions { display: flex; gap: 10px; margin-top: 28px; flex-wrap: wrap; }

.hero__btn { cursor: pointer; user-select: none; border: 0; font: inherit; }
.hero__btn--primary { font-weight: 700; }
.hero__btn:focus-visible { outline: 2px solid var(--sun); outline-offset: 3px; }
.lead__btn--ghost {
  background: none; border: 1px solid var(--hairline-cool);
  color: var(--ink-muted-cool); font-family: var(--font-mono); font-size: 13.5px;
}
.lead__btn--ghost:hover { color: var(--ink); border-color: var(--ink-faint-cool); }

.lead__assure {
  margin: 22px 0 0; max-width: 44ch;
  font: 400 13px/1.55 var(--font-sans); color: var(--ink-faint-cool);
}
.lead__assure b { color: var(--ink-muted-cool); font-weight: 600; }

.lead__product { display: flex; flex-direction: column; gap: 14px; }
.lead__caption {
  margin: 0; font: 400 12px/1.5 var(--font-sans); color: var(--ink-faint-cool);
  text-align: center; max-width: 380px;
}
.lead__caption b { color: var(--ink-muted-cool); font-weight: 600; }
.lead__caption code { font: 400 11.5px var(--font-mono); color: var(--ink-muted-cool); }

@media (max-width: 940px) {
  .lead__grid { grid-template-columns: 1fr; gap: 44px; padding-top: 40px; }
  .lead__product { align-items: center; }
}

/* ── Scan stage, presented as a modal ─────────────────────────────────
   The proof pops up in front of the hero instead of living down the page:
   the visitor clicked a promise and the answer should land where they are
   looking. Native <dialog> — Esc closes, ::backdrop dims the page. */
.stagemodal {
  border: 0; padding: 0; margin: auto;
  width: min(1000px, calc(100vw - 28px));
  max-height: calc(100vh - 48px);
  overflow: auto; overscroll-behavior: contain;
  background: var(--paper-cool); color: var(--ink);
  border-radius: var(--r-panel, 16px);
  box-shadow: 0 28px 90px rgba(9, 26, 38, .35);
}
.stagemodal:not([open]) { display: none; }
.stagemodal::backdrop { background: rgba(9, 26, 38, .48); }
.stagemodal__close {
  position: sticky; top: 12px; float: right; margin: 12px 14px 0 0;
  z-index: 3; cursor: pointer;
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--hairline-cool); background: var(--hull);
  font: 400 20px/1 var(--font-sans); color: var(--ink-muted-cool);
}
.stagemodal__close:hover { color: var(--ink); }
.stage { max-width: 1000px; margin: 0 auto; padding: 34px 24px 56px; }

.status {
  display: flex; align-items: center; gap: 10px;
  font: 400 13.5px var(--font-sans); color: var(--ink-muted-cool);
  margin-bottom: 18px; min-height: 20px;
}
.status__dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--verified-dot); animation: statuspulse 1s infinite;
}
@keyframes statuspulse { 0%,100% { opacity: .25 } 50% { opacity: 1 } }

/* the live proof surface — same family as the convert card */
.proof--live { width: 100%; max-width: 640px; margin: 0 auto; }
.proof-card.proof {
  width: 100%;
  max-width: 640px;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  overflow: visible;
}
.proof-card .proof__pitch {
  margin-top: 0;
}
.proof-card .proof__squeeze-note {
  text-align: center;
  margin: 6px 0 0;
}
.proof-card__pane[hidden] { display: none !important; }
.proof-card__head { margin-top: 0; }
.proof-card__hero {
  margin: 0 0 4px;
  font-size: clamp(22px, 3vw, 28px);
  line-height: 1.2;
}
.proof-card__hero .proof__open-num { font-weight: inherit; }
.proof-card__hull {
  margin-top: 18px;
  padding: 20px 22px 18px;
  border-radius: var(--r-card);
  background: var(--hull);
  border: 1px solid var(--hairline-cool);
  box-shadow: 0 2px 12px rgba(9, 26, 38, .06);
}
.proof-card__funnel-title {
  margin: 28px 0 14px;
  font-size: clamp(22px, 3vw, 28px);
  line-height: 1.15;
  text-align: center;
  text-wrap: balance;
}
.proof-card__back {
  appearance: none; cursor: pointer; border: 0; background: none; padding: 0 0 12px;
  font: 600 14px var(--font-sans); color: var(--brand-blue);
}
.proof-card__back:hover { text-decoration: underline; }
.proof-card__why {
  margin: 18px 0 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-muted-cool);
}
.proof-card__alt-link {
  appearance: none; cursor: pointer; border: 0; background: none; padding: 0;
  margin-top: 14px;
  font: 600 14px var(--font-sans); color: var(--brand-blue);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.proof-card__step-link {
  display: inline-block;
  margin-top: 10px;
  font-weight: 600;
  color: var(--brand-blue);
}
.proof__start-block { margin-top: 18px; }
.proof__cmd-area[hidden],
.proof__cmd-collapsed[hidden] { display: none !important; }
.proof__cmd-collapsed {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}
.proof__copied-chip {
  display: inline-block;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--sun);
  font: 700 13px var(--font-sans);
  color: var(--ink);
}
.proof__show-cmd {
  appearance: none; cursor: pointer; border: 0; background: none; padding: 0;
  font: 600 13px var(--font-sans); color: var(--brand-blue);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ── Conversion ───────────────────────────────────────────────────────── */
.convert { max-width: 640px; margin: 28px auto 0; text-align: left; }
.convert__head { text-align: center; margin-bottom: 28px; overflow: visible; }
.convert__scene {
  position: relative;
  width: 100%;
  height: 132px;
  margin: 0 0 18px;
  overflow: visible;
}
.convert__boat {
  position: absolute;
  left: 50%;
  bottom: 82px;
  transform: translateX(-50%);
  z-index: 1;
  overflow: visible;
  /* Room for the bow flare and the pennant — same problem scale() caused. */
  padding: 0 12px;
}
/* Hero proportions at ~55% — same vars the courier uses, which match illustration.css. */
.convert__boat .boat {
  --bob-dur: 3.2s;
  --hull-w: 104px; --hull-h: 34px;
  --hull-r: 5px; --hull-br: 17px; --hull-brv: 22px;
  --hull-pad: 15px; --hull-fill: #FFFFFF;
  --hold-h: 20px; --hold-gap: 4px;
  --deck-h: 4px; --deck-gap: 3px; --stripe-r: 2px;
  --super-shift: -9px; --funnel-w: 12px; --funnel-h: 17px;
  --cabin-w: 42px; --cabin-h: 16px;
  filter: drop-shadow(0 3px 7px rgba(11, 18, 32, .13));
}
.convert__boat .boat__mast { width: 2px; height: 11px; left: 3px; }
.convert__boat .boat__flag { width: 11px; height: 7px; left: 2px; bottom: calc(100% + 6px); }
.convert__boat .boat__cabin::after { left: 6px; right: 6px; top: 5px; height: 5px; }
.convert__boat .folder { --folder-w: 14px; --folder-h: 16px; --folder-tab: 4px; }
.convert__water {
  /* Homepage hero proportions scaled for ~520px modal — 220px wave-w → 2–3 crests. */
  --water-h: 92px;
  --water-bleed: 24px;
  --crest-h: 32px;
  z-index: 0;
}
.convert__status {
  margin: 0 0 10px; font: 400 13.5px/1.45 var(--font-sans);
  color: var(--ink-muted-cool);
}
.convert__title {
  margin: 0; font: 800 clamp(24px, 3.2vw, 30px)/1.15 var(--font-sans);
  letter-spacing: -.7px; color: var(--ink); text-wrap: balance;
}
.convert__steps {
  margin: 0 0 22px; padding: 0; list-style: none; counter-reset: convertstep;
}
.convert__step {
  counter-increment: convertstep; position: relative;
  padding: 0 0 22px 44px; font-size: 15px; line-height: 1.55; color: var(--ink-muted-cool);
}
.convert__step:last-child { padding-bottom: 0; }
.convert__step::before {
  content: counter(convertstep); position: absolute; left: 0; top: 1px;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--sun); color: var(--ink);
  font: 700 13px/28px var(--font-sans); text-align: center;
}
.convert__step b, .convert__step kbd { color: var(--ink); font-weight: 600; }
.convert__step kbd {
  display: inline-block; padding: 1px 6px; border-radius: 4px;
  border: 1px solid var(--hairline-cool); background: var(--hull);
  font: 600 12px/1.4 var(--font-sans);
}
.convert__step a { color: var(--brand-blue); }
.convert__cmd {
  display: block; width: 100%; box-sizing: border-box; cursor: pointer;
  margin-top: 10px; text-align: left;
  background: var(--surface-sunk-cool); border: 1px solid var(--hairline-cool);
  border-radius: var(--r-button); padding: 12px 14px;
  font: 400 14px/1.35 var(--font-mono); color: var(--ink);
}
.convert__cmd:hover { border-color: var(--harbour-a-label); }
/* `display: block` above beats the UA agent's `[hidden]` rule, so a hidden
   command button still rendered -- an empty grey box under "Then dock the heavy
   folder:" whenever the payload carries no `thenHere`, which is every bare
   `stowit compress-place`. Pre-existing; found by rendering the pane, and
   checked against origin/main before being called ours. Five other rules in
   this file already carry exactly this override. */
.convert__cmd[hidden] { display: none !important; }
/* The cue is the loud half. Before this, the button's whole label was the
   command, so a 66-character path read as a code block rather than as
   something to click. */
.convert__cmd-cue {
  display: inline-block; background: var(--sun); color: var(--ink);
  border-radius: var(--r-chip); padding: 6px 14px;
  font: 700 13.5px/1 var(--font-sans); letter-spacing: .01em;
  white-space: nowrap;
}
.convert__cmd:hover .convert__cmd-cue { box-shadow: 0 0 0 4px var(--sun-glow-soft); }
.convert__cmd-text {
  display: block; margin-top: 9px;
  font: 400 13px/1.45 var(--font-mono); color: var(--ink-muted-cool);
  overflow-wrap: anywhere;
}
.convert__cmd-note {
  display: block; margin-top: 6px; font-size: 13px; color: var(--ink-faint-cool);
}
.convert__waiting {
  text-align: center; margin: 16px 0 0; font-size: 14px; font-style: italic;
  color: var(--ink-muted-cool);
}
.proof__hook {
  margin-top: 14px;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-muted-cool);
  max-width: 42em;
}
.proof__open {
  margin: 0;
  font-size: 19px;
  line-height: 1.55;
  color: var(--ink);
  max-width: 42em;
}
.proof__open-num {
  font-weight: 800;
  color: var(--ink);
}
.proof__squeeze-note {
  margin: 8px 0 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-muted-cool);
  max-width: 42em;
}
.proof__squeeze-note[hidden] { display: none; }
.proof__pitch {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(148px, 13.5em);
  gap: 12px 18px;
  align-items: stretch;
  margin-top: 14px;
  max-width: 42em;
}
.proof__bullets {
  margin: 0;
  padding-left: 1.25em;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-muted-cool);
}
.proof__bullets li { margin: 0 0 6px; }
.proof__bullets li:last-child { margin-bottom: 0; }
.proof__bullets-kicker {
  margin-top: 14px;
}
.proof__did-you-know {
  margin: 0;
  align-self: start;
  border-color: color-mix(in srgb, var(--sea) 22%, var(--hairline-cool));
  background: color-mix(in srgb, var(--paper-cool) 88%, var(--sea-pale) 12%);
}
.proof__did-you-know summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 10px;
  padding: 12px 14px 0;
  font-size: 13px;
  line-height: 1.35;
}
/* The chevron is the base rule's `::after`. A float is inert in grid, so it is
   placed explicitly: row 1, right column, beside the label rather than adrift. */
.proof__did-you-know summary::after {
  float: none;
  grid-column: 2;
  grid-row: 1;
  align-self: center;
  font-size: 18px;
  line-height: 1;
}
.proof__did-you-know-head {
  grid-column: 1;
  grid-row: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.proof__did-you-know-teaser {
  grid-column: 1 / -1;
  grid-row: 2;
  color: var(--ink-muted-cool);
  font-weight: 400;
}
.proof__did-you-know-label {
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
}
.proof__did-you-know-accent {
  display: flex;
  align-items: flex-end;
  flex: 0 0 auto;
}
.proof__did-you-know-boat {
  position: relative;
  flex: 0 0 auto;
  width: 22px;
  height: 20px;
}
.proof__did-you-know-mast {
  position: absolute;
  left: 3px;
  bottom: 0;
  width: 2px;
  height: 16px;
  background: var(--ink-faint-warm);
  border-radius: 2px;
}
.proof__did-you-know-flag {
  position: absolute;
  left: 2px;
  bottom: 14px;
  width: 16px;
  height: 10px;
  border-radius: 2px 5px 5px 2px;
  background: var(--class-model-cache);
  transform: rotate(-3deg);
  transform-origin: left bottom;
}
.proof__did-you-know-wave {
  grid-column: 1 / -1;
  grid-row: 3;
  height: 10px;
  margin: 8px -14px 0;
  overflow: hidden;
  opacity: .72;
}
.proof__did-you-know-wave .water__crest {
  display: block;
  width: 100%;
  height: 8px;
  background: var(--sea);
  -webkit-mask-image: var(--wave);
          mask-image: var(--wave);
  -webkit-mask-size: 48px 100%;
          mask-size: 48px 100%;
  -webkit-mask-repeat: repeat-x;
          mask-repeat: repeat-x;
}
.proof__did-you-know[open] .proof__did-you-know-flag {
  animation: proofdykflag 1.1s ease-in-out 2;
}
.proof__did-you-know[open] .proof__did-you-know-wave .water__crest {
  animation: wavepan 2.8s linear infinite;
}
@keyframes proofdykflag {
  0%, 100% { transform: rotate(-4deg); }
  50% { transform: rotate(7deg); }
}
.proof__did-you-know p {
  padding: 0 12px 12px;
  font-size: 13px;
  line-height: 1.52;
}
@media (max-width: 520px) {
  .proof__pitch {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .proof__did-you-know {
    max-width: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .proof__did-you-know[open] .proof__did-you-know-flag,
  .proof__did-you-know[open] .proof__did-you-know-wave .water__crest {
    animation: none;
  }
}
.proof__terminal-how {
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.48;
  color: var(--ink-muted-cool);
}
.proof__terminal-paste {
  display: block;
  margin-top: 4px;
  color: var(--ink);
  font-weight: 500;
  font-size: 12.5px;
}
.proof__terminal-how kbd {
  font-family: var(--font-mono);
  font-size: 0.92em;
  padding: 1px 5px;
  border-radius: 4px;
  border: 1px solid var(--hairline-cool);
  background: var(--paper);
}
.proof__then {
  margin-top: 8px;
  padding-top: 0;
  border-top: 0;
}
.proof__then .section-label { display: none; }
.proof__then-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 0;
}
.proof__mini-card {
  display: flex;
  flex-direction: column;
  padding: 16px 16px 14px;
  border: 1px solid var(--hairline-cool);
  border-radius: var(--r-card);
  background: var(--paper-warm);
}
.proof__mini-ill {
  height: 72px;
  margin: 0 0 12px;
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.proof__mini-title {
  margin: 0 0 8px;
  font: 700 15px/1.25 var(--font-sans);
  color: var(--ink);
}
.proof__mini-body {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.52;
  color: var(--ink-muted-cool);
  flex: 1;
}
.proof__mini-cta {
  appearance: none;
  cursor: pointer;
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 10px 14px;
  border: 0;
  border-radius: var(--r-chip);
  background: var(--sun);
  color: var(--ink);
  font: 600 13px/1.3 var(--font-sans);
  text-align: center;
  text-decoration: none;
}
.proof__mini-cta:hover { filter: brightness(0.97); }
.proof__mini-cta--link { display: block; }
.proof__mini-reveal {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline-cool);
}
.proof__mini-reveal[hidden] { display: none; }

/* Card 1 — computer to drive on one U-shaped cord */
.proof__ill--drive {
  gap: 6px;
  align-items: flex-end;
  padding-bottom: 2px;
}
.proof__ill-pc { position: relative; width: 38px; flex-shrink: 0; }
.proof__ill-screen {
  display: block;
  width: 38px;
  height: 26px;
  background: var(--paper-cool);
  border-radius: 4px;
  box-shadow: inset 0 0 0 2px var(--hairline-cool);
}
.proof__ill-screen::after {
  content: "";
  display: block;
  margin: 6px auto 0;
  width: 16px;
  height: 9px;
  border-radius: 2px;
  background: var(--brand-blue);
  opacity: .32;
}
.proof__ill-stand {
  display: block;
  width: 16px;
  height: 4px;
  margin: 3px auto 0;
  background: var(--ink-faint-cool);
  border-radius: 0 0 3px 3px;
}
.proof__ill-cord {
  flex: 0 0 34px;
  width: 34px;
  height: 18px;
  margin: 0 0 12px;
  box-sizing: border-box;
  border-bottom: 3px solid var(--deck-2);
  border-left: 3px solid var(--deck-2);
  border-right: 3px solid var(--deck-2);
  border-radius: 0 0 14px 14px;
}
.proof__ill-drive {
  position: relative;
  width: 30px;
  height: 38px;
  flex-shrink: 0;
}
.proof__ill-drive-body {
  display: block;
  width: 30px;
  height: 34px;
  background: var(--hull);
  border-radius: 5px;
  box-shadow: inset 0 -10px 0 var(--surface-sunk-cool);
}
.proof__ill-drive-led {
  position: absolute;
  bottom: 7px;
  left: 50%;
  transform: translateX(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--verified-dot);
}

/* Card 2 — mini boat on water under a soft cloud */
.proof__ill--hosted {
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
}
.proof__ill-cloud {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  width: 48px;
  height: 16px;
  border-radius: var(--r-chip);
  background: var(--sky-light);
  box-shadow:
    -16px 5px 0 -3px var(--sky-light),
    16px 3px 0 -5px rgba(234, 244, 251, .85);
}
.proof__ill-boat {
  position: relative;
  z-index: 1;
  animation: bob 3.4s ease-in-out infinite;
}
.proof__ill-hull {
  display: block;
  width: 46px;
  height: 15px;
  background: var(--hull);
  border-radius: 4px 4px 9px 9px / 4px 4px 11px 11px;
  box-shadow:
    inset 0 -4px 0 var(--deck-1),
    inset 0 -8px 0 var(--deck-2);
}
.proof__ill-mast {
  position: absolute;
  left: 7px;
  bottom: calc(100% - 1px);
  width: 2px;
  height: 13px;
  background: var(--deck-2);
  border-radius: 1px;
}
.proof__ill-flag {
  position: absolute;
  left: 5px;
  bottom: calc(100% + 9px);
  width: 11px;
  height: 7px;
  background: var(--brand-blue);
  border-radius: 1px 2px 2px 1px;
}
.proof__ill-wave {
  width: 68px;
  height: 10px;
  margin-top: -3px;
  background: var(--brand-blue);
  opacity: .42;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
}
@media (prefers-reduced-motion: reduce) {
  .proof__ill-boat { animation: none; }
}
@media (max-width: 640px) {
  .proof__then-cards { grid-template-columns: 1fr; }
}
.proof__then-cmd {
  display: block;
  width: 100%;
  text-align: left;
  margin-top: 0;
  font-size: 14px;
  font-weight: 700;
}
.proof__then-note {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-muted-cool);
}
.proof__close {
  margin: 20px 0 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-muted-cool);
  text-align: center;
}
.proof__pricing-link {
  color: var(--brand-blue);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  margin-left: 0.35em;
}
.proof__start {
  margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--hairline-cool);
}
.proof__start--hero {
  margin-top: 20px;
  padding: 18px 20px 16px;
  border: 2px solid var(--sun);
  border-radius: var(--r-card);
  background: var(--paper-warm);
}
.proof__start--hero .section-label {
  color: var(--harbour-a-label);
  font-size: 11px;
  letter-spacing: 1.4px;
}
.proof__start-cmd { display: block; width: 100%; text-align: left; margin-top: 8px; font-weight: 700; }
.proof__start--hero .proof__start-cmd {
  margin-top: 10px;
  font-size: 15px;
  font-weight: 700;
  border-color: var(--sun);
  background: #fff;
}
.proof__start-note {
  margin: 10px 0 0; font-size: 13px; line-height: 1.48; color: var(--ink-muted-cool);
}
.proof__start-step {
  margin: 8px 0 0; font-size: 13px; line-height: 1.48; color: var(--ink-muted-cool);
}
.proof__start-step[hidden] { display: none !important; }
.convert__send { width: 100%; max-width: 320px; }
.convert__switch {
  margin: 0 0 18px; font-size: 14px; text-align: center; color: var(--ink-muted-cool);
}
.convert__switch-btn {
  appearance: none; cursor: pointer; border: 0; background: none; padding: 0;
  font: inherit; color: var(--brand-blue); text-decoration: underline;
  text-underline-offset: 2px;
}
.convert__switch-menu { display: inline; margin-left: 6px; }
.convert__switch-link {
  appearance: none; cursor: pointer; border: 0; background: none; padding: 0 4px;
  font: inherit; color: var(--brand-blue);
}
.convert__switch-link:hover { text-decoration: underline; }
.convert__more {
  margin: 0 0 10px; border: 1px solid var(--hairline-cool); border-radius: var(--r-card);
  background: var(--paper-warm); overflow: hidden;
}
.convert__more summary {
  cursor: pointer; padding: 12px 16px; font: 600 14px var(--font-sans); color: var(--ink);
  list-style: none;
}
.convert__more summary::-webkit-details-marker { display: none; }
.convert__more summary::after {
  content: "›"; float: right; color: var(--ink-faint-cool);
  transform: rotate(90deg); transition: transform .2s;
}
.convert__more[open] summary::after { transform: rotate(-90deg); }
.convert__more p {
  margin: 0; padding: 0 16px 14px; font-size: 14px; line-height: 1.58;
  color: var(--ink-muted-cool);
}
.install {
  display: inline-block; cursor: pointer;
  background: var(--surface-sunk-cool); border: 1px solid var(--hairline-cool);
  border-radius: var(--r-button); padding: 14px 20px;
  font: 400 15px/1 var(--font-mono); color: var(--ink);
}
.install:hover { border-color: var(--harbour-a-label); }
.copied { color: var(--verified-text); font-size: 12.5px; margin-left: 10px; }
.ghost {
  appearance: none; cursor: pointer; font: inherit; font-size: 14px;
  background: none; border: 1px solid var(--hairline-cool);
  color: var(--ink-muted-cool); padding: 11px 20px; border-radius: var(--r-button);
}
.ghost:hover { color: var(--ink); border-color: var(--ink-faint-cool); }

.privacy {
  margin: 34px auto 0; max-width: 640px; text-align: center;
  color: var(--ink-muted-cool); font: 400 13.5px/1.6 var(--font-sans);
  border: 1px dashed var(--hairline-cool); border-radius: var(--r-card);
  padding: 18px 22px; background: var(--paper-warm);
}
.privacy b { color: var(--verified-text); }

/* ── Estimator ────────────────────────────────────────────────────────── */
.est { max-width: 520px; margin: 0 auto; }
.est[hidden] { display: none; }
.est__note {
  background: var(--note-bg); color: var(--note-text);
  border-radius: var(--r-card); padding: 12px 16px;
  font: 400 13px/1.5 var(--font-sans); margin-bottom: 26px; text-align: center;
}
.est__q { margin-bottom: 22px; }
.est__q label { display: block; font-size: 14px; color: var(--ink-muted-cool); margin-bottom: 9px; }
.est__q label b { color: var(--ink); }
.est__q input[type=range] { width: 100%; accent-color: var(--harbour-a-label); }
.est__go {
  display: block; margin: 28px auto 0; cursor: pointer;
  background: var(--sun); color: var(--ink); font: 700 15px var(--font-sans);
  border: 0; border-radius: var(--r-button); padding: 13px 26px;
}

footer.site {
  padding: 40px 24px; text-align: center;
  color: var(--ink-faint-cool); font-size: 12.5px;
  border-top: 1px solid var(--hairline-cool);
}

@media (max-width: 900px) {
  .hero--page .hero__copy { left: 24px; width: auto; right: 24px; top: 28px; }
  .hero--page .hero__scene { height: 520px; }
  .t-hero-headline { font-size: 38px; letter-spacing: -1.2px; }
  .hero--page .hero__drive { display: none; }
}

/* ── Content bands ─────────────────────────────────────────────────────
   The page was one screen and a footer. These are the sections that give
   it a body: how it works, the promise, what it finds, where it runs. */
.band { background: var(--paper-cool); border-bottom: 1px solid var(--hairline-cool); scroll-margin-top: 16px; }
.band--warm { background: var(--paper-warm); border-bottom-color: var(--hairline-warm); }
.band__inner {
  max-width: 1120px; margin: 0 auto;
  /* Padding is a variable so a shut band can be a row instead of a room, and
     the two states can transition into each other. See --band-pt below. */
  padding: var(--band-pt, 76px) 56px var(--band-pb, 82px);
  transition: padding .62s cubic-bezier(.22, .61, .36, 1);
}
.band__label { margin: 0 0 14px; color: var(--brand-blue); }
.band__title {
  margin: 0; max-width: 22ch;
  font: 800 clamp(28px, 3.4vw, 40px)/1.14 var(--font-sans);
  letter-spacing: -.02em; color: var(--ink); text-wrap: balance;
}
.band__deck {
  margin: 20px 0 0; max-width: 62ch;
  font-size: 16.5px; line-height: 1.62; color: var(--ink-muted-cool);
}
.band--warm .band__deck { color: var(--ink-muted-warm); }
.band__deck b { color: var(--ink); font-weight: 650; }
.band__foot {
  margin: 26px 0 0; max-width: 62ch;
  font-size: 13.5px; line-height: 1.6; color: var(--ink-faint-cool);
}

/* Three steps. Numbered because the order is the safety argument — the
   copy really does happen before anything is freed. */
.steps {
  list-style: none; margin: 42px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px;
}
.step {
  background: var(--hull); border: 1px solid var(--hairline-cool);
  border-radius: var(--r-panel, 16px); padding: 26px 26px 30px;
}
.step__n {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 50%; background: var(--sun);
  font: 800 14px var(--font-sans); color: var(--ink);
}
.step__h { margin: 16px 0 8px; font: 700 17px/1.3 var(--font-sans); color: var(--ink); }
.step__p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-muted-cool); }

/* Measured figures. */
.figures {
  margin: 40px 0 0; display: grid;
  grid-template-columns: repeat(4, 1fr); gap: 24px;
}
.figure { display: flex; flex-direction: column; gap: 6px; padding-left: 16px; border-left: 3px solid var(--sun); }
.figure__n { font-variant-numeric: tabular-nums; color: var(--ink); }
.figure__l { font-size: 13px; line-height: 1.45; color: var(--ink-muted-warm); }
.figures__note { margin: 24px 0 0; font-size: 12.5px; color: var(--ink-faint-warm); }

/* What it finds. */
.finds { list-style: none; margin: 38px 0 0; padding: 0; display: grid; gap: 2px; }
.find {
  display: grid; grid-template-columns: 12px 210px 1fr; align-items: baseline; gap: 16px;
  padding: 15px 4px; border-top: 1px solid var(--hairline-cool);
}
.find:last-child { border-bottom: 1px solid var(--hairline-cool); }
.find__dot { width: 9px; height: 9px; border-radius: 50%; transform: translateY(-1px); }
.find__n { font: 650 15px var(--font-sans); color: var(--ink); }
.find__d { font-size: 14.5px; line-height: 1.55; color: var(--ink-muted-cool); }

@media (max-width: 900px) {
  .band__inner { padding: var(--band-pt, 48px) 20px var(--band-pb, 54px); }
  .steps { grid-template-columns: 1fr; gap: 16px; }
  .figures { grid-template-columns: repeat(2, 1fr); gap: 20px; }
  .find { grid-template-columns: 10px 1fr; }
  .find__d { grid-column: 2; }
}

/* ── Three ways to get the space back ──────────────────────────────────
   The middle card is the one that ships, so it carries the emphasis; the
   other two are labelled and deliberately quieter. */
.ways {
  margin: 42px 0 0; display: grid;
  grid-template-columns: repeat(3, 1fr); gap: 26px; align-items: start;
}
.way {
  background: var(--hull); border: 1px solid var(--hairline-cool);
  border-radius: var(--r-panel, 16px); padding: 24px 24px 26px;
}
.way--now { border-color: var(--sun); box-shadow: 0 0 0 2px rgba(255, 201, 74, .28); }
.way__chip {
  display: inline-block; padding: 4px 11px; border-radius: var(--r-chip);
  background: var(--sun); color: var(--ink);
  font: 700 11px/1 var(--font-sans); letter-spacing: .04em; text-transform: uppercase;
}
.way__chip--soon {
  background: var(--surface-sunk-cool); color: var(--ink-muted-cool);
  box-shadow: inset 0 0 0 1px var(--hairline-cool);
}
.way__h { margin: 16px 0 10px; font: 700 18px/1.25 var(--font-sans); color: var(--ink); }
.way__p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-muted-cool); }
.way__p b { color: var(--ink); font-weight: 650; }
.way__note {
  margin: 14px 0 0; padding-top: 13px; border-top: 1px solid var(--hairline-cool);
  font-size: 12.5px; line-height: 1.55; color: var(--ink-faint-cool);
}
@media (max-width: 900px) { .ways { grid-template-columns: 1fr; gap: 16px; } }

/* ── How to use it ─────────────────────────────────────────────────────
   Same row rhythm as "what it finds": command on the left, the outcome in
   plain English on the right. Outcomes only — no engine internals here. */
.install--howto { display: inline-block; margin: 30px 0 6px; }
.cmds { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 2px; }
.cmd {
  display: grid; grid-template-columns: 320px 1fr; align-items: baseline; gap: 18px;
  padding: 14px 4px; border-top: 1px solid var(--hairline-cool);
}
.cmd:last-child { border-bottom: 1px solid var(--hairline-cool); }
.cmd__c { font: 500 13.5px var(--font-mono); color: var(--ink); white-space: nowrap; }
.cmd__d { font-size: 14.5px; line-height: 1.55; color: var(--ink-muted-cool); }
.cmd__d b { color: var(--ink); font-weight: 650; }
.cmds-options { margin-top: 40px; }
.cmds-options__label { margin: 0; color: var(--brand-blue); }
.cmds--options { margin-top: 14px; }
.cmds--options .cmd__c { white-space: normal; }
@media (max-width: 900px) {
  .cmd { grid-template-columns: 1fr; gap: 6px; }
  .cmd__c { white-space: normal; }
}

/* ── The headline blank ────────────────────────────────────────────────
   Deliberately no number: any figure we print becomes the anchor a
   visitor measures their result against, and it is usually too low. The
   scan fills this in with theirs. */
.blank {
  display: inline-block; min-width: 2.4em; /* digits only — the sentence carries the GB */
  border-bottom: .09em solid var(--sun);
  border-radius: 4px 4px 0 0;
  /* An empty white field on the sky, not a tinted block: the sun token over
     --sky-light mixes to a muddy tan that reads as a rendering fault. */
  background: rgba(255, 255, 255, .72);
  font-variant-numeric: tabular-nums;
  transition: background-color .5s ease, min-width .5s ease;
}
.blank.is-filled {
  min-width: 0; padding: 0 .06em;
  background: none; border-bottom-color: var(--sun);
  animation: blankin .5s ease-out both;
}
@keyframes blankin {
  from { opacity: 0; transform: translateY(.12em); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .blank, .blank.is-filled { transition: none; animation: none; }
}

/* The copy column is 430px in the design-system canvas, which was sized for
   a two-line headline with no inline slot. */
.hero__copy { width: min(560px, 44vw); }
@media (max-width: 900px) { .hero__copy { width: auto; } }

/* ── Shut bands, and the boat that comes to open them ──────────────────
   The landing is the pitch; everything under it starts closed, so the page
   reads as a short list of questions instead of a mile of scroll. Click a
   header and the boat leaves its last berth, runs down the right-hand lane,
   ties up alongside that header, and the section opens behind it. The whole
   run is ~2.4s and is driven by voyage() at the foot of index.html — these
   rules only describe the states it moves between.

   Nothing here collapses without JavaScript: .band__wrap and .band__body do
   not exist in the markup, the script builds them. A reader with JS off gets
   the old page, fully open. */

.band__head { position: relative; }

/* A real button, stretched over the header, rather than a click handler on
   the <h2>: keyboard, focus ring and screen-reader announcement all come
   free, and a <button> cannot legally contain the <p> and <h2> it covers. */
.band__toggle {
  position: absolute; inset: -22px -12px -16px -12px;
  margin: 0; padding: 0;
  background: none; border: 0; border-radius: 12px;
  font: inherit; color: transparent; cursor: pointer;
}
.band__toggle:hover { background: rgba(76, 151, 238, .05); }
.band__toggle:focus-visible { outline: 2px solid var(--brand-blue); outline-offset: 3px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The affordance. Quiet on purpose — the title is the thing being clicked,
   this only says the title is clickable. */
.band__cue {
  display: inline-flex; align-items: center; gap: 9px;
  margin: 16px 0 0; font: 600 13px var(--font-sans);
  color: var(--ink-faint-cool); letter-spacing: .01em;
}
.band--warm .band__cue { color: var(--ink-faint-warm); }
.band__cue::after {
  content: ""; width: 7px; height: 7px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform .45s cubic-bezier(.22, .61, .36, 1);
}
.band.is-open .band__cue::after { transform: translateY(1px) rotate(-135deg); }
.band__toggle:hover ~ .band__cue,
.band__head:hover .band__cue { color: var(--brand-blue); }

/* 0fr -> 1fr is the one height transition that needs no measured pixel
   value, so a section can reflow (or fill in its scan numbers) without the
   animation quietly lying about how tall it is. */
.band__wrap {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .62s cubic-bezier(.22, .61, .36, 1);
}
.band.is-open .band__wrap { grid-template-rows: 1fr; }
.band__body {
  /* `hidden` and `clip` both clip. Only `hidden` makes this a scroll
     container, and a scroll-container ancestor is exactly what stops
     `position: sticky` inside it from ever moving -- measured on the real
     page against a control, not reasoned about: with `hidden` the product
     cards' action rows tracked the scroll one-for-one, with `clip` they
     stayed put. The `hidden` below it is the fallback for a browser that
     does not know `clip`; there the buttons simply do not follow. */
  overflow: hidden;
  overflow: clip;
  /* .band__body is a grid item, and a grid item's automatic minimum size is
     its min-content width unless something waives it. `overflow: hidden`
     waived it as a side effect; `clip` does not, so switching one word blew
     every band out to 566px inside a 390px phone -- measured, and invisible
     until the sweep. Waive it deliberately instead of relying on a side
     effect of the clipping mode. */
  min-width: 0;
  opacity: 0; transform: translateY(-8px);
  transition: opacity .4s ease .1s, transform .5s cubic-bezier(.22, .61, .36, 1) .1s;
}
.band.is-open .band__body { opacity: 1; transform: none; }

/* A shut band is a row, not an empty room. */
.band.is-collapsible { --band-pt: 38px; --band-pb: 40px; }
.band.is-collapsible.is-open { --band-pt: 76px; --band-pb: 82px; }
@media (max-width: 900px) {
  .band.is-collapsible { --band-pt: 28px; --band-pb: 30px; }
  .band.is-collapsible.is-open { --band-pt: 48px; --band-pb: 54px; }
}

/* ── The courier ──────────────────────────────────────────────────────
   One boat for the whole page. It is fixed while it is under way (so it
   glides against the viewport as the page scrolls beneath it) and absolute
   once it has tied up (so it stays with the section it opened). voyage()
   swaps the two; nothing here assumes either. */
.courier {
  position: absolute; top: 0; left: 0;
  width: 116px; height: 86px;
  z-index: 40; pointer-events: none;
  opacity: 0; transition: opacity .5s ease;
  will-change: transform;
}
.courier.is-visible { opacity: 1; }

.courier__boat {
  position: absolute; left: 6px; bottom: 12px;
  --bob-dur: 3.2s;
  --hull-w: 104px; --hull-h: 34px;
  --hull-r: 5px; --hull-br: 17px; --hull-brv: 22px;
  --hull-pad: 15px; --hull-fill: #FFFFFF;
  --hold-h: 20px; --hold-gap: 4px;
  --deck-h: 4px; --deck-gap: 3px; --stripe-r: 2px;
  --super-shift: -9px; --funnel-w: 12px; --funnel-h: 17px;
  --cabin-w: 42px; --cabin-h: 16px;
  filter: drop-shadow(0 3px 7px rgba(11, 18, 32, .13));
}
/* The shared boat parts are drawn at hero scale; the fixed-pixel bits of the
   superstructure have to come down with the rest of it. */
.courier .boat__mast { width: 2px; height: 11px; left: 3px; }
.courier .boat__flag { width: 11px; height: 7px; left: 2px; bottom: calc(100% + 6px); }
.courier .boat__cabin::after { left: 6px; right: 6px; top: 5px; height: 5px; }
.courier .folder { --folder-w: 14px; --folder-h: 16px; --folder-tab: 4px; }

/* The bit of sea it sits on. Widening it is the whole wake effect. */
.courier__wake {
  position: absolute; left: 0; bottom: 5px;
  width: 116px; height: 12px;
  background: var(--sea); opacity: .22;
  border-radius: 50%;
  transform-origin: 50% 50%;
  transition: transform .5s ease, opacity .5s ease;
}
.courier.is-sailing .courier__wake { transform: scaleX(1.28) scaleY(.7); opacity: .3; }
.courier.is-sailing .courier__boat { animation: bobfast .85s ease-in-out infinite; }

/* Tying up: the hull knocks the berth once and settles, and the wash it
   pushed ahead of it spreads and fades. */
@keyframes courierdock {
  0%   { transform: translateY(0) rotate(0deg); }
  30%  { transform: translateY(6px) rotate(2.2deg); }
  62%  { transform: translateY(-3px) rotate(-1.4deg); }
  100% { transform: translateY(0) rotate(0deg); }
}
@keyframes courierwash {
  0%   { transform: scaleX(1.28) scaleY(.7); opacity: .3; }
  45%  { transform: scaleX(1.5) scaleY(1.15); opacity: .34; }
  100% { transform: scaleX(1) scaleY(1); opacity: .22; }
}
.courier.is-docking .courier__boat { animation: courierdock .36s cubic-bezier(.3, .9, .4, 1); }
.courier.is-docking .courier__wake { animation: courierwash .36s ease-out; }

/* Cargo goes ashore into the section it just opened. */
@keyframes courierunload {
  0%   { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(16px) scale(.7); }
}
.courier.is-docking .folder { animation: courierunload .5s ease-in both; }
.courier.is-docking .folder:nth-child(2) { animation-delay: .07s; }
.courier.is-docking .folder:nth-child(3) { animation-delay: .14s; }

/* Below ~760px the header has no clear water to the right of its title, so
   the boat would tie up on top of the words. The sections still open — they
   just open on their own. */
@media (max-width: 759px) { .courier { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .courier { display: none; }
  .band__wrap, .band__body, .band__inner, .band__cue::after { transition: none; }
}

.page-hero--compact .hero { min-height: 0; padding-bottom: 0; }
.page-hero--compact .hero__scene { display: none; }

.pricing-page {
  max-width: 640px;
  margin: 0 auto;
  padding: 32px 24px 64px;
}
.pricing-page__title {
  font-size: 36px;
  font-weight: 800;
  letter-spacing: -1px;
  margin: 0 0 12px;
  color: var(--ink);
}
.pricing-page__lede {
  font-size: 18px;
  line-height: 1.55;
  color: var(--ink);
  margin: 0 0 20px;
}
.pricing-page p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-muted-cool);
  margin: 0 0 16px;
}
.pricing-page code {
  font-family: var(--font-mono);
  font-size: 0.92em;
}
.pricing-page a { color: var(--brand-blue); }
.pricing-page__back {
  display: inline-block;
  margin-top: 12px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ── The hero copy: one line, then a lane per product ──────────────────────
   Nothing here touches .boat__*, .water or .brand__* — the ship, the swell and
   the logo are exactly as they were. */
/* The headline sits in the nav row, centred between the wordmark and the sun
   (Todd, 2026-09-30). 900, not 800: at this size it has to hold its own
   beside two pieces of illustration. Absolute inside the nav row, so the logo
   and the menu keep their places and the headline never pushes either.
   Below 901px there is no room between them, so it takes its own row. */
.hero__headline--solo {
  margin: 0;
  font: 900 clamp(34px, 4.6vw, 56px)/1.02 var(--font-sans);
  letter-spacing: -2.2px;
  white-space: nowrap;
}
.hero__stowit b { color: var(--brand-blue); font-weight: 900; }
.hero__nav-inner { position: relative; }
@media (min-width: 901px) {
  .hero__nav-inner .hero__headline--solo {
    position: absolute; left: 50%; top: calc(50% + 4px);
    transform: translate(-50%, -50%);
  }
}
@media (max-width: 900px) {
  .hero__nav-inner { flex-wrap: wrap; }
  .hero__nav-inner .hero__headline--solo {
    order: 3; flex-basis: 100%; padding: 14px 0 12px; white-space: normal;
  }
}

/* Two lanes, one per product, split to the two sides of the page with open
   sky between them: Squeeze it on the left, Stow it on the right. Each lane
   is 250px of text inset 100px from its edge of the 1120 column, and carries
   its own button centred under it. */
@media (min-width: 901px) {
  .page-hero .hero__copy {
    left: 50%; transform: translateX(-50%);
    width: min(1120px, calc(100% - 48px));
    top: 36px;
  }
}
.hero__lanes {
  display: grid; grid-template-columns: 350px 1fr 350px;
}
.hero__lane { display: flex; flex-direction: column; min-width: 0; }
.hero__lane--a { grid-column: 1; padding-left: 100px; }
.hero__lane--b { grid-column: 3; padding-right: 100px; }
.hero__lane-head { display: flex; align-items: center; gap: 7px; color: var(--ink); }
.hero__lane-title { margin: 0; font: 800 30px/1.05 var(--font-sans); letter-spacing: -1px; }
.hero__lane-name {
  margin: 8px 0 0;
  font: 700 11px var(--font-sans); letter-spacing: 1.3px;
  color: var(--harbour-a-label);
}
.hero__lane-copy { margin: 11px 0 0; font: 400 15px/1.58 var(--font-sans); color: var(--ink-muted-cool); }
.hero__lane-copy b { color: var(--ink); font-weight: 650; }
.hero__lane-copy .hero__lane-free { font-weight: 700; }
/* auto margin, not a fixed gap: the two buttons then sit on one line whatever
   the copy does later, instead of only because the words happened to balance. */
.hero__lane-nudge {
  margin: auto 0 0; padding-top: 10px;
  font: 400 15px/1.58 var(--font-sans); color: var(--ink-muted-cool);
}
.hero__anchor { vertical-align: -5px; margin-left: 5px; color: var(--ink-faint-warm); }
.hero__lane-cta { margin-top: 12px; display: flex; justify-content: center; }
.hero__lane-cta .hero__btn { white-space: nowrap; }
.hero__btn--attic { background: var(--harbour-a-label); color: #fff; font-weight: 700; }
/* Centred on the page, between the lanes' buttons and the boat. Anchored to
   the TOP, a fixed distance under the lanes: anchored to the water it rode up
   into the buttons wherever the scene is shorter than 620px (measured at 1280
   and 1024). The lanes do not move with the scene, so the note must not. */
.hero__note {
  margin: 0;
  font: 400 13px/1.7 var(--font-mono); color: var(--ink-faint-cool);
  text-align: center;
}
@media (min-width: 901px) {
  .hero__note {
    position: absolute; left: 0; right: 0; z-index: 2;
    top: 344px;
  }
}
/* A shorter scene puts the boat higher, so lift the block to keep clear of it. */
@media (min-width: 901px) and (max-width: 1279px) {
  .page-hero .hero__copy { top: 16px; }
  .hero__note { top: 322px; }
}

@media (max-width: 1080px) {
  .hero__lanes { grid-template-columns: 300px 1fr 300px; }
  .hero__lane--a { padding-left: 50px; }
  .hero__lane--b { padding-right: 50px; }
}
@media (max-width: 900px) {
  .hero__lanes { grid-template-columns: 1fr 1fr; gap: 0 27px; }
  .hero__lane--a, .hero__lane--b { grid-column: auto; padding: 0; }
  .hero__note { padding: 0 20px 18px; text-align: left; }
}
@media (max-width: 820px) {
  .hero__lanes { width: 100%; grid-template-columns: 1fr; }
  .hero__lane--a { padding-bottom: 22px; border-bottom: 1px solid rgba(11, 18, 32, .13); }
  .hero__lane--b { padding-top: 22px; }
  .hero__lane-nudge { margin-top: 12px; }
  .hero__lane-cta { justify-content: flex-start; }
}
.home-product__hint {
  font: 400 12px var(--font-sans); color: var(--ink-faint-cool);
}

/* The Attic's three plans in the pricing band. A plain list, one plan a row, so
   the comparison reads top to bottom on a phone as well as on a laptop. */
.home-plan-interval { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 10px; }
.home-plans { list-style: none; margin: 0 0 12px; padding: 0; }
.home-plan {
  padding: 10px 0; border-top: 1px solid var(--hairline-cool);
}
.home-plan:first-child { border-top: 0; }
.home-plan__name {
  margin: 0 0 2px; font: 600 13px var(--font-sans); letter-spacing: .02em;
  text-transform: uppercase; color: var(--ink-muted-cool);
}
.home-plan__fit { margin: 2px 0 0; font-size: 13px; color: var(--ink-faint-cool); }
