/* Marketing site: topbar/wordmark, pages, CTAs. */
/* ===== Marketing site =====
   Public pages (/staff, /pricing, /security, /how-it-works, /pull-the-plug,
   /about, /vs/:competitor) rendered through layouts/marketing.html.slim.
   Reuses the theme tokens. Layout assumes body.marketing — the
   marketing layout sets that class so the marketing rules don't leak into
   the company. */

body.marketing {
  background: var(--bg);
  color: var(--text);
  overflow-x: clip;
}

/* Topbar */

.marketing-topbar {
  /* In the flow, not pinned: the page is read top to bottom and the one ask is
     on the cover and under the footer. Relative only so it paints over the
     cover, which is pulled up under it. */
  position: relative;
  z-index: 1;
  background: var(--bg);
  border-bottom: 1px solid var(--hairline);
}

.marketing-topbar__inner {
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 1.5rem;
  height: 3.5rem;
  display: flex;
  align-items: center;
  gap: 2rem;
}

/* The wordmark is bigger than the nav links, so centering each box on its own
   leaves its baseline ~2px low. Group them and align that group on the baseline;
   the outer flex still centers the group in the bar. */
.marketing-topbar__brandnav {
  display: flex;
  align-items: baseline;
  gap: 2rem;
  flex: 1;
}

.marketing-topbar__nav {
  display: flex;
  gap: 1.5rem;
}

.marketing-topbar__nav a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.92rem;
  transition: color 120ms;
}

.marketing-topbar__nav a:hover {
  color: var(--text);
}

/* The bar is 3.5rem tall and its links one line of text in the middle of it.
   Padding with the same negative margin makes most of the bar the target
   without moving the baseline the group aligns on. */
.marketing-topbar__nav a,
.marketing-topbar .marketing-logo {
  padding-block: 0.75rem;
  margin-block: -0.75rem;
}

/* A ghost, not a second accent: the page has one filled button and it is the
   cover's ask. This one is navigation for someone who already signed up. */

.marketing-topbar__cta {
  appearance: none;
  font: inherit;
  cursor: pointer;
  /* Signed in it is a link, signed out a form's button: as an inline box the
     link is sized by its font and the button by its line-height, which left
     the two states 6px apart in height. One flex box sizes both the same. */
  display: inline-flex;
  align-items: center;
  line-height: 1.2;
  background: transparent;
  border: 1px solid var(--hairline-strong);
  color: var(--text);
  padding: 0.5rem 1rem;
  border-radius: calc(var(--radius) / 2);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9rem;
  transition: background 120ms, border-color 120ms;
}

.marketing-topbar__cta:hover {
  background: var(--fill-raised);
  border-color: var(--text-muted);
}

@media (max-width: 48em) {
  .marketing-topbar__nav { display: none; }
}

/* On a phone the cover carries headline, panel and ask in one fold, so the
   copy's own air is what gives. */
@media (max-width: 40rem) {
  /* No padding-top here: `.marketing-hero--cover`'s own shorthand is further
     down the sheet and resets it — the override that used to sit here never
     applied. The top band's air is the clamp in that shorthand. */
  .marketing-hero--cover .marketing-hero__h1 { margin-bottom: 1rem; }
  .marketing-hero--cover .marketing-hero__sub { margin-bottom: 1.25rem; }

  /* Promise, then the ask, then the terms. On a phone the price sentence above
     the button made three paragraphs to read before anything to press; under
     it, it is what it has always been — the small print that answers "what
     does it cost" once the button has been seen. */
  .marketing-hero--cover .marketing-hero__ask { flex-direction: column-reverse; }

  .marketing-hero__ask form,
  .marketing-hero__ask .marketing-cta {
    display: block;
    width: 100%;
    text-align: center;
  }
  .marketing-hero--cover .marketing-hero__ask p {
    margin: var(--space-3) 0 0;
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.88);
    text-shadow: 0 1px 20px rgba(8, 15, 30, 0.5);
  }

  /* The panel is taller than the phone's fold has room for under the
     headline, so the ask goes first: price and button on the first screen,
     the demo's top edge showing under them as the reason to scroll. */
  .marketing-hero--cover .demo-stage { order: 1; }
}


/* Hang-tag: the flat amber stock the contractor cards carried their weekly
   price on (f00f640 cut the roster, not the idiom). No hole, no pointed end,
   no tilt. */

.hang-tag {
  display: inline-block;
  padding: 0.3rem 0.7rem;
  background: #f5cb52;
  color: #4a3500;
  text-shadow: none;
  border-radius: 0.3rem;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* Main */

.marketing-main {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* Hero block */

.marketing-hero {
  padding: 6rem 0 4rem;
  text-align: left;
  max-width: 48rem;
}

.marketing-hero__h1 {
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  margin-bottom: 1.25rem;
  color: var(--text);
  /* Share the words between the lines: a headline that ends on one word alone
     is the widow the brand brief rules out. */
  text-wrap: balance;
}

.marketing-hero__sub {
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.marketing-hero__strap {
  font-size: 0.95rem;
  color: var(--text-muted);
  font-style: italic;
}

/* Section block */

.marketing-section {
  /* 6rem, not 4: the floors carry pictures and panels now, and at 4 they read
     as one long block with rules through it. */
  padding: 6rem 0;
  border-top: 1px solid var(--hairline);
}

/* A heading set as a heading: tight leading, not the body's 1.6, which at
   36px opened 22px of air inside a two-line h2. */
.marketing-section h2 {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 1rem;
  color: var(--text);
  text-wrap: balance;
}

.marketing-section h3 {
  font-size: 1.15rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
  color: var(--text);
}

.marketing-section p {
  color: var(--text-muted);
  margin-bottom: 1rem;
  max-width: 56rem;
}

.marketing-section ul,
.marketing-section ol {
  color: var(--text-muted);
  padding-left: 1.5rem;
  margin-bottom: 1rem;
  max-width: 56rem;
}

.marketing-section li {
  margin-bottom: 0.5rem;
}

.marketing-section li strong {
  color: var(--text);
}

.marketing-section__caption {
  font-size: 0.875rem;
  color: var(--text-muted);
  font-style: italic;
}

.marketing-section--quiet {
  border-top: none;
  padding-top: 1rem;
}

/* No divider line, and a tighter gap, directly under the landing hero */
.marketing-hero--landing + .marketing-section {
  border-top: none;
  padding-top: 2rem;
}

/* The landing's closing ask, under the footer: one button, centred on a whole
   screen, and nothing around it but air. A glow smudged the page and a tinted
   strip made a second footer.

   2026-09-20: the glow was tried a second time by someone who had not read the
   line above, and smudged the page exactly as promised. What the screen took
   in the end was streaks — a field of them crossing behind the button, drawn
   further down. Air is still what a single button needs; a whole empty screen
   of it read as the page having run out.

   It rides up the last half-screen slower than the page does and settles into
   the centre, instead of turning over on a hinge: the hinge was the last leaf
   of a book falling flat, which needed a leaf — with the band a full screen and
   the button centred in it, the same rotation was a button doing a flip. Riding
   slow is also what gets it on screen before the halfway mark while leaving it
   level with the eye at the bottom; the two cannot both come from the layout,
   since a button centred on the last screen is half a screen from the end of
   the page by definition. The band's height is in the page from the start, and
   the scroll position alone says how far the button has come. */

.marketing-closer {
  /* The footer's own rule closes the links; this one closes the footer, so the
     empty screen under it reads as the page's last floor rather than as the
     page having run out. */
  border-top: 1px solid var(--hairline);
  /* svh, not vh, for the same reason the cover uses it — the URL bar must not
     sit over the button, and a dynamic unit would resize the band under the
     animation. */
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  /* Dead centre, so the button is level with the eye once the page has bottomed
     out. Nothing here buys it an earlier entrance — half a screen has to pass
     under it either way; that is the animation's job, below. */
  align-content: center;
  /* The band, not the button, is what the rise is timed against: the button is
     a button tall, and on its own timeline the whole move would be over in the
     inch it takes to clear the bottom edge. */
  view-timeline-name: --closer;
}

/* A screen of plain white under the footer read as the page having run out
   rather than as its last floor. What fills it is the work itself: the six
   marks from "What an agent can do", the same drawings, adrift. A glow was
   tried here first and thrown out — a coloured wash under a button is a
   gradient with nothing to say, and on a near-white field it reads as dirt on
   the screen. These say what the page spent three thousand pixels saying, at
   the weight of a watermark.

   `clip`, not `hidden`: hidden would make the band a scroll container and the
   view timeline the button rides on would have nothing left to measure. */
.marketing-closer {
  position: relative;
  isolation: isolate;
  overflow: clip;
}

/* The pipes board: the whole band, behind everything, with the button standing
   on it. The controller makes the canvas and draws into it; the band stays
   white, because the canvas has an alpha channel and the page shows through
   wherever no pipe is. */
.marketing-closer__pipes {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* Off until the screen has been left alone, and slower arriving than leaving:
   a screensaver fades up, and a visitor who has come back wants their page
   now. The 600ms is written out rather than taken from --dur, which is a real
   token in 01_base (220ms) — the fallback in var(--dur, 600ms) never fired,
   so the fade ran at a third of what the JS timer beside it was waiting for. */
.marketing-closer__pipes {
  opacity: 0;
  transition: opacity 600ms ease;
}

.marketing-closer__pipes.is-on {
  opacity: 1;
  transition-duration: 1600ms;
}

/* A full board clears the way a screensaver does: the picture goes, all of it,
   and the next one starts on an empty grid. Fading the pipes themselves means
   fading them towards the colour of the page, which is a renderer that has to
   know what is behind it. */
.marketing-closer__pipes.is-on.is-wiping {
  opacity: 0;
  transition-duration: 1200ms;
}

.marketing-closer__pipes canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.marketing-closer__inner {
  padding-inline: 1.5rem;
  text-align: center;
}

/* Scroll-driven: no observer, no timer, and off the compositor — transform and
   opacity only. Held behind @supports because without a view timeline the
   animation never runs, and its `from` keyframe would leave the button faint
   and low for good. Reduced motion gets it in place, which is the end of the
   animation, not the start of it. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .marketing-closer__inner {
      animation: closer-rise both;
      animation-timeline: --closer;
      /* The band is exactly a screen tall, so entry progress reads off as the
         band's own height and the button, centred, would clear the bottom edge
         at 50%. Starting six rem high it clears it at 40% instead, and the
         range ends a breath before the page bottoms out. */
      animation-range: entry 40% entry 95%;
      /* The house curve, so the button settles into its place rather than
         tracking the scroll one to one the whole way. */
      animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
    }
  }
}

@keyframes closer-rise {
  from {
    transform: translateY(-6rem);
    opacity: 0;
  }

  to {
    transform: none;
    opacity: 1;
  }
}

/* Bigger than the cover's: the cover's button sits on a photograph with a price
   line beside it, this one is alone on an empty page. */

.marketing-closer .marketing-cta {
  margin-top: 0;
  padding: 1.125rem 2.5rem;
  font-size: 1.125rem;
  border-radius: var(--radius);
}

/* The landing ask, under the roster wheel. Centred column: one line of pain,
   the price anchor, the button, then the small print that answers the only
   question standing between reading and signing in (when am I charged). */
/* Negative top eats the ring stage's bottom slack (clearance kept there for the
   near tile's drop shadow), so the ask sits under the wheel instead of a hole. */
/* Feature hero — alternating text / visual */

.marketing-feature {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 38rem;
  gap: 3rem;
  /* Top, not centre: beside a tall panel the copy floated in the middle of its
     column with air above and below it. */
  align-items: start;
  padding: 6rem 0;
  border-top: 1px solid var(--hairline);
}

/* The floor the three claims answer: it gives up half its bottom air to them,
   so the two read as one spread without running into each other. */
.marketing-feature--demo {
  padding-bottom: 3rem;
}

.marketing-feature--reversed {
  grid-template-columns: 38rem minmax(0, 1fr);
}

.marketing-feature--reversed .marketing-feature__media {
  order: -1;
}

/* Two claims of equal weight on one floor: each column is its own little
   feature — the words, then the picture under them. */

.marketing-feature-pair {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2.5rem;
  /* No rule and a short gap over it: the three claims answer the floor above
     them, so the two read as one spread rather than two filed sections. */
  padding: 1.5rem 0 6rem;
}

/* The three headings wrap to different depths, so the pictures hang off the
   bottom of the row instead of the bottom of their own text: a column of art
   that steps up and down reads as three floors, not one. */
.marketing-feature-pair__item {
  display: flex;
  flex-direction: column;
}

.marketing-feature-pair__item .marketing-feature__text {
  margin-bottom: 1.5rem;
}

.marketing-feature-pair__item .marketing-feature__img {
  margin-top: auto;
}

/* No 30rem cap here: the column IS the measure, and a paragraph that stops
   short of a picture it sits on reads as a column that missed. */
.marketing-feature-pair__item .marketing-feature__text p {
  max-width: none;
}

/* A third of the wrap is a third of a floor, so these take the split title's
   size rather than the full-width floor's: three 32px claims across one row
   read as three pages. Tighter tracking and a shorter drop to the line under
   it, so name and clause read as one object. */
.marketing-feature-pair__item .marketing-feature__text h2 {
  font-size: clamp(1.25rem, 1.8vw, 1.5rem);
  letter-spacing: -0.025em;
  margin-bottom: 0.375rem;
}

/* A step down from the floors' body: at a third of the width the clause is a
   caption to the claim, not a paragraph of its own. */
.marketing-feature-pair__item .marketing-feature__text p {
  font-size: 0.9375rem;
  line-height: 1.6;
}



.marketing-feature__text h2 {
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin-bottom: 0.5rem;
  color: var(--text);
}

.marketing-feature__text p {
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1.55;
  max-width: 30rem;
}

.marketing-feature__img {
  display: block;
  width: 100%;
  /* The tag declares its box for the first paint; the column decides the rendered size. */
  height: auto;
  /* Fills its column and carries the browser window's frame: since one of the
     three floors shows the product itself, the other two have to present their
     art at the same size and in the same frame, or the middle floor reads as a
     different page. 16:10 is that window's ratio too. */
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius);
  box-shadow: 0 1rem 2.5rem rgba(15, 23, 42, 0.16), 0 0 0 1px rgba(15, 23, 42, 0.06);
}

/* The wide column is 44rem, so the pair stops fitting well before the phone:
   both collapse to one column at the width where the copy would be squeezed. */
/* The demo is the evidence for the list above it, not the next filed section:
   no rule between them, and half the air. Ninety-six pixels each side of a
   hairline read as two subjects; this reads as one, the claim and the proof. */
.marketing-section:has(+ .marketing-feature--demo) {
  padding-bottom: 2.5rem;
}

.marketing-section + .marketing-feature--demo {
  border-top: none;
  padding-top: 4rem;
}

/* Three abreast only while each column can still hold its line in two rows:
   between this and the floors' own breakpoint the columns were narrow enough to
   push every body onto a third line, which is where a claim stops reading as a
   claim. */
@media (max-width: 75rem) {
  .marketing-feature-pair {
    grid-template-columns: 1fr;
    gap: 3rem;
  }
}

@media (max-width: 64rem) {
  .marketing-feature,
  .marketing-feature--reversed {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  .marketing-feature { padding: 3.5rem 0; }

  .marketing-feature--reversed .marketing-feature__media {
    order: 0;
  }

  .marketing-feature-pair {
    grid-template-columns: 1fr;
    gap: 3rem;
    padding: 3.5rem 0;
  }
}

/* Primary CTA button.

   Signed in it is an <a>; signed out it is a <button> inside a button_to form.
   The browser paints that second one with its own chrome — a 2px OUTSET
   border, light on the top-left and dark on the bottom-right, plus the system
   font — so the same control looked like two different things depending on who
   was looking at it. That dark edge down the right and bottom of the closing
   band's button was the outset border, and it was invisible to anyone testing
   while signed in.

   Neutralised on the class, not at the call site: the cover's copy had these
   four lines of its own, which is exactly why it was the only one that ever
   looked right. */
.marketing-cta {
  appearance: none;
  border: none;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  display: inline-block;
  background: var(--accent);
  color: var(--bg);
  padding: 0.75rem 1.5rem;
  border-radius: calc(var(--radius) / 2);
  text-decoration: none;
  margin-top: 1rem;
  transition: background 120ms;
}

.marketing-cta:hover {
  background: var(--accent-hover);
}

/* Worked examples grid */

.pricing-examples {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.25rem;
  margin: 1.5rem 0;
}

.pricing-example {
  background: var(--bg-card);
  border-radius: var(--radius);
  padding: 1.5rem;
}

.pricing-example p {
  margin-bottom: 0.75rem;
  font-size: 0.95rem;
}

.pricing-example p:last-child {
  margin-bottom: 0;
}

/* Footer */

/* The section above already pads 4-5rem below its last line; 3rem more is the
   boundary, not another empty screen. */
.marketing-footer {
  margin-top: 3rem;
  border-top: 1px solid var(--hairline);
  padding: 4rem 0;
}

/* Brand on the left, the whole nav as one block flush right: three tracks of
   their own width, so the columns read as a unit instead of landing on an
   arbitrary quarter of the page. */
.marketing-footer__inner {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.5rem;
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) auto;
  gap: 2.5rem;
}

/* One track per column, sized to its content: a column added to the nav
   doesn't have to be counted here too. */
.marketing-footer__nav {
  display: grid;
  grid-auto-flow: column;
  gap: 3rem;
}

/* 52em is where the brand and the tracks stop fitting side by side. The
   nav then flows in two balanced text columns, so a short group and a tall one
   pair up instead of leaving a column-high hole beside the last one. */
@media (max-width: 52em) {
  .marketing-footer__inner {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  .marketing-footer__nav {
    display: block;
    columns: 2;
    column-gap: 2rem;
  }

  .marketing-footer__col {
    break-inside: avoid;
  }

  .marketing-footer__col + .marketing-footer__col {
    margin-top: 1.5rem;
  }
}

.marketing-footer__col,
.marketing-footer__brand {
  display: flex;
  flex-direction: column;
}

/* Sits on the headings' cap line, not above them: the wordmark is bigger, so
   its own line-box is what has to move. */
.marketing-footer__brand {
  align-items: flex-start;
  gap: 0.75rem;
  padding-top: 0.15rem;
}

.marketing-footer__tagline {
  max-width: 18rem;
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* Drops to the foot of the brand column, so it lands level with the last link
   instead of hanging under the tagline. */
.marketing-footer__signoff {
  margin-top: auto;
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* The heading names the column and steps back; the links are what gets read
   and clicked, so they carry the text color. */
.marketing-footer__heading {
  font-size: 0.75rem;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  font-weight: 600;
  margin-bottom: 0.75rem;
}

/* Each link is a full row: on a phone the footer is the site's only
   navigation, so there the rows grow to a thumb's height. */
.marketing-footer__col a {
  display: flex;
  align-items: center;
  min-height: 2rem;
  color: var(--text);
  text-decoration: none;
  font-size: 0.9rem;
  transition: color var(--dur-fast);
}

.marketing-footer__col a:hover {
  color: var(--accent);
}

.marketing-footer__col a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

@media (hover: none) {
  .marketing-footer__col a { min-height: 2.5rem; }
}


/* Marketing hero variants and FAQ */

.marketing-hero--landing {
  text-align: center;
  max-width: 56rem;
  margin: 0 auto;
  padding-bottom: 2.5rem;
}

/* Landing cover: full-bleed art, viewport tall, the copy sits on top of it.
   Breaks out of .marketing-main's 72rem column; body clips the vw overhang so
   a desktop scrollbar can't push the page sideways. The art is the LCP asset,
   so it's served as webp: cwebp -q 82 -resize 2400 0 hero-<name>.png. */

.marketing-hero--cover {
  position: relative;
  max-width: none;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  /* The cover owns the fold: headline, the demo panel and the ask all ride on
     the art. svh, not vh: on mobile the dynamic viewport is what's actually
     visible, and 100vh puts the CTA under the URL bar. */
  min-height: 100vh;
  min-height: 100svh;
  /* The topbar is 3.5rem plus its 1px rule; clear both or that rule shows as a
     hairline of page background above the art. */
  margin-top: calc(-3.5rem - 1px);
  display: flex;
  flex-direction: column;
  align-items: center;
  /* The whole cover — headline, panel, ask, cue — is centred in what the
     topbar leaves, so the air above it and below it is the same. `safe`, not
     plain `center`: on a short window the content outgrows the fold, and a
     centred overflow would push the headline up under the topbar where it
     cannot be scrolled back to. There the fold falls back to top-aligned. */
  justify-content: safe center;
  /* Equal floors above and below the centred group, plus the topbar's own
     height on top — so a window too short to centre still leaves the headline
     clear of the bar instead of butting it. */
  padding: calc(3.5rem + 1px + 1rem) 1.5rem 1rem;
  background: var(--cover-art) center / cover no-repeat;
}

/* The art is pale and deliberately empty top and bottom, so the copy runs in
   the page's own dark ink — no scrim, and the picture keeps its colour. A soft
   light halo covers the crops where a character drifts under the text. */

.marketing-hero--cover::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 42% at 50% 0%, rgba(8, 15, 30, 0.62), rgba(8, 15, 30, 0) 78%),
    radial-gradient(120% 30% at 50% 100%, rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0) 78%);
}

/* The portrait fold, and it has to sit HERE: the two rules above set their
   backgrounds with the shorthand, so anything an earlier media block said
   about the crop or the wash was thrown away. */
@media (max-width: 40rem) {
  /* Portrait shows a quarter of this landscape scene, and the middle quarter
     is a face in soft focus — the copy sat on a blur. A quarter to the left is
     wall, sky and a palm; the characters keep their heads just above the
     panel. */
  .marketing-hero--cover { background-position: 25% 100%; }

  /* Slate ink on a mid-tone blur is unreadable at any crop, so the light wash
     the cover's floor already has is pulled up under the whole copy block. */
  .marketing-hero--cover::before {
    background:
      linear-gradient(to bottom,
        rgba(8, 15, 30, 0.86) 0%,
        rgba(8, 15, 30, 0.8) 28%,
        rgba(8, 15, 30, 0.58) 40%,
        rgba(8, 15, 30, 0) 54%),
      radial-gradient(150% 40% at 50% 100%, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 80%);
  }
}

.marketing-hero--cover > * {
  position: relative;
  color: var(--text);
  text-shadow: 0 1px 16px rgba(255, 255, 255, 0.75);
}

/* The headline sits in the shaded top band, so it flips to white ink. */

.marketing-hero--cover .marketing-hero__h1,
.marketing-hero--cover .marketing-hero__sub {
  color: #fff;
  text-shadow: 0 1px 20px rgba(8, 15, 30, 0.5);
}

/* The ask follows the demo panel rather than being pinned to the cover's
   floor — the panel is what it's answering. */
.marketing-hero--cover .marketing-hero__ask {
  margin-top: 0;
  padding-top: 0;
}

/* Scroll cue on the cover's floor. A chevron drawn from two borders, bobbing
   once every couple of seconds: enough motion to read as "there is more",
   little enough to ignore. The hit area is a real 44px target around it. */

/* On the cover's floor, out of the flow: in flow it read as a fifth line of
   the centred group instead of an edge marker, and it was what the group was
   being centred around. Absolute is safe here — when the content outgrows the
   fold the cue sits at the cover's own bottom, which is where it would have
   been in flow anyway. The glyph is small; the 44px hit area around it is
   not. In the corner rather than centred: under the button, on the axis the
   eye is already on, it competed with the one thing to press. */

.marketing-hero--cover .marketing-hero__scroll {
  position: absolute;
  left: 0.5rem;
  bottom: 0.25rem;
  margin-top: 0;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--text);
  opacity: 0.4;
  transition: opacity 0.15s ease;
}

.marketing-hero--cover .marketing-hero__scroll-arrow {
  width: 0.55rem;
  height: 0.55rem;
}

.marketing-hero--cover .marketing-hero__scroll:hover,
.marketing-hero--cover .marketing-hero__scroll:focus-visible {
  opacity: 1;
}

.marketing-hero__scroll-arrow {
  width: 0.7rem;
  height: 0.7rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  rotate: 45deg;
  animation: hero-scroll-bob 2.4s ease-in-out infinite;
}

@keyframes hero-scroll-bob {
  0%, 100% { translate: 0 -0.15rem; }
  50%      { translate: 0 0.15rem; }
}

@media (prefers-reduced-motion: reduce) {
  .marketing-hero__scroll-arrow { animation: none; }
}

/* No cue on a phone: the demo's top edge already runs off the fold there, and
   a thumb scrolls without being told to. Here rather than in the phone block
   up the sheet, which the cue's own `display: grid` would override. */
@media (max-width: 40rem) {
  .marketing-hero--cover .marketing-hero__scroll { display: none; }
}

/* Marketing pages only — the app's own scrollers are driven from JS. */
html:has(body.marketing) {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html:has(body.marketing) { scroll-behavior: auto; }
}

/* The one ask, on the lower third of the cover. It carries its own frosted
   panel rather than dimming the whole picture — the art stays saturated and
   the copy still clears contrast wherever the crop lands. */

.marketing-hero__ask {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 3rem;
}

/* As wide as the panel above it, so the ask stays one line at desktop — the
   credit, the salary and the revenue share are one sentence. Where it must
   wrap, the lines share the words: a last word alone read as an afterthought. */
.marketing-hero__ask p {
  font-size: 1.05rem;
  max-width: 46rem;
  /* Closer to the button than to the picker above: the sentence is the
     button's terms, and at equal distances it belonged to neither. */
  margin-bottom: var(--space-4);
  text-wrap: balance;
}

/* The credit's hang-tag rides inside the sentence, so it takes the sentence's
   size — a smaller tag read as a footnote — and a shallower pad, so the line
   it sits in doesn't grow. Inline, not inline-block: an atomic box is a break
   opportunity, and the comma after it wrapped onto its own line. */
.marketing-hero__ask .hang-tag {
  display: inline;
  font-size: 1em;
  padding: 0.1em 0.5em;
}

.marketing-hero__ask form {
  display: inline-block;
}

.marketing-hero__ask .marketing-cta {
  font-size: 1.05rem;
  /* Wider than it is tall by a good margin: the presence comes from the plate
     and the lift, not from shouting in a bigger type. */
  padding: 1rem 2.25rem;
  margin-top: 0;
  text-shadow: none;
  /* Lifted off the picture. A flat rectangle on a photograph reads as a
     sticker; the glow is the accent's own hue, so the page still has one
     colour. */
  box-shadow:
    0 10px 24px -10px rgba(2, 132, 199, 0.65),
    0 2px 6px -2px rgba(15, 23, 42, 0.25);
  transition: background 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}

.marketing-hero__ask .marketing-cta:hover {
  transform: translateY(-1px);
  box-shadow:
    0 14px 30px -10px rgba(2, 132, 199, 0.72),
    0 3px 8px -2px rgba(15, 23, 42, 0.28);
}

/* Presses in rather than staying put: the one control on the cover should
   answer the finger. */
.marketing-hero__ask .marketing-cta:active {
  transform: translateY(1px);
  box-shadow: 0 6px 14px -8px rgba(2, 132, 199, 0.6);
}

/* The arrow leads: it steps out on hover, which is the whole animation. */
.marketing-cta__arrow {
  display: inline-block;
  margin-left: 0.4em;
  transition: transform 120ms ease;
}

.marketing-cta:hover .marketing-cta__arrow { transform: translateX(0.15em); }

@media (prefers-reduced-motion: reduce) {
  .marketing-hero__ask .marketing-cta,
  .marketing-cta__arrow { transition: background 120ms ease; }

  .marketing-hero__ask .marketing-cta:hover { transform: none; }

  .marketing-cta:hover .marketing-cta__arrow { transform: none; }
}

/* Over the cover the topbar rides on the art: no plate, light ink. It scrolls
   away with the page, so there is nothing to fade back in. */

body:has(.marketing-hero--cover) .marketing-topbar {
  background: transparent;
  border-bottom-color: transparent;
}

body:has(.marketing-hero--cover) .marketing-topbar__nav a {
  color: rgba(255, 255, 255, 0.82);
}

body:has(.marketing-hero--cover) .marketing-topbar__nav a:hover {
  color: #fff;
}

body:has(.marketing-hero--cover) .marketing-topbar__cta {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.55);
}

body:has(.marketing-hero--cover) .marketing-topbar__cta:hover {
  background: rgba(255, 255, 255, 0.16);
  border-color: #fff;
}

body:has(.marketing-hero--cover) .marketing-topbar .marketing-logo__brand,
body:has(.marketing-hero--cover) .marketing-topbar .marketing-logo__brand::before,
body:has(.marketing-hero--cover) .marketing-topbar .marketing-logo__brand::after {
  color: #fff;
}

/* A section built on the floors' own two columns, so a page of alternating
   floors can carry a heading-plus-list block without changing grid. */

/* Its heading sits in the copy column at the size the FAQ's does — under the
   floors, over the body, so the page has one ladder of headings. */
.marketing-section .marketing-split__title {
  font-size: clamp(1.375rem, 2.2vw, 1.75rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--text);
}

/* Air between the prose that opens a section and the split under it — the
   heading was landing on the lede's last line. */
.marketing-section .marketing-lede + .marketing-split {
  margin-top: var(--space-12);
}

/* The line under a split's heading: without it the copy column is a heading
   and a hole beside a block several rows tall. */
.marketing-section .marketing-split__note {
  max-width: 22rem;
  margin-top: var(--space-3);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--text-muted);
}

/* A brand mark set in running text, where the sentence already names it.
   em again, and the optical nudge below the baseline that any mark needs
   beside lowercase. The gap is a word space, not a hair: this mark is a
   filled tile with no side bearing of its own, and tight against the S it
   read as one glued word. */
.marketing-inline-mark {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  margin-right: 0.25em;
}

.marketing-section .marketing-trust p {
  margin-top: var(--space-2);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--text-muted);
}

.marketing-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 38rem;
  gap: 3rem;
  align-items: start;
}

/* Collapses with the floors, and the rule sits here rather than with theirs:
   at equal specificity the later declaration wins, and this class is defined
   further down the sheet. */
@media (max-width: 64rem) {
  .marketing-split {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }
}

/* Inline links in the marketing prose. There was no rule for them at all, so
   every one on these pages — the FAQ's answers, the legal pages, this section's
   own note — came out in browser blue with a full underline: the one colour on
   the site that belongs to no palette. --accent-hover, because accent as TEXT
   is 4.1:1 and this is body copy. */

.marketing-section a:not(.marketing-cta) {
  color: var(--accent-hover);
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--accent-hover) 35%, transparent);
  text-underline-offset: 0.15em;
  transition: color var(--dur-fast) ease, text-decoration-color var(--dur-fast) ease;
}

.marketing-section a:not(.marketing-cta):hover {
  color: var(--accent);
  text-decoration-color: currentColor;
}

/* Voices: a reel of testimonial cards before the FAQ. The form is the one a
   reader already recognises — card, stars, the business under
   it — so it is read as testimonials in a scroll-past; the discipline
   is in what it does not carry: no names, no portraits, no second colour.
   The stars are review gold, the colour a reader already reads as a rating.
   The reel drifts at a constant rate — eased, it would stop at every loop.
   It runs the full width of the window, so the edges read as the window's
   and not as a box cutting cards off. */

.marketing-voices-reel {
  width: 100vw;
  margin: var(--space-12) calc(50% - 50vw) 0;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.marketing-section .marketing-voices {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: none;
  display: flex;
  width: max-content;
  /* The loop is paced per card, so adding quotes lengthens it instead of
     speeding the reel up. --voices-start, a fraction set per render, is where
     in the loop a load lands, so a reload opens on different cards. */
  --voices-loop: calc(var(--voices-count, 14) * 8.5s);
  animation: voices-drift var(--voices-loop) linear infinite;
  animation-delay: calc(var(--voices-start, 0) * -1 * var(--voices-loop));
}

.marketing-voices-reel--narrow {
  display: none;
}

.marketing-section .marketing-voices + .marketing-voices {
  margin-top: var(--space-6);
  animation-direction: reverse;
}

/* No rule above or below: the reel is already a band of cards running the
   window's width, and a line either side of it frames a frame. */
.marketing-section--voices,
.marketing-section--voices + .marketing-section {
  border-top: none;
}

@keyframes voices-drift {
  to { transform: translateX(-50%); }
}

.marketing-section .marketing-voice {
  width: 22rem;
  flex: none;
  margin: 0 var(--space-6) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-6);
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
}

/* The mark hangs above the text as its own line rather than in front of the
   first word: hung into the margin it would need the card's padding to give
   it room, and a card with uneven padding reads as a mistake. */
.marketing-voice__quote {
  margin: 0;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  line-height: 1.55;
  color: var(--text);
  text-wrap: pretty;
}

/* Five stars cut from one strip: the fill runs --stars steps of star + gap,
   the rest shows the empty colour through the same mask. */
.marketing-voice__stars {
  --star: 1.125rem;
  --step: calc(var(--star) + var(--space-1));
  width: calc(5 * var(--step) - var(--space-1));
  height: var(--star);
  background: linear-gradient(90deg, #f5b301 calc(var(--stars) * var(--step)), var(--hairline-strong) 0);
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5l3.1 6.9 7.4.7-5.6 5 1.7 7.4L12 17.6l-6.6 3.9 1.7-7.4-5.6-5 7.4-.7z'/%3E%3C/svg%3E") 0 0 / var(--star) var(--star) space;
  mask-repeat: space no-repeat;
}

.marketing-voice__who {
  margin-top: auto;
  font-size: 0.9375rem;
  line-height: 1.35;
  color: var(--text-muted);
}

@media (max-width: 56.25em) {
  .marketing-section .marketing-voice {
    width: 17rem;
    margin-right: var(--space-4);
  }

  .marketing-voices-reel--wide {
    display: none;
  }

  .marketing-voices-reel--narrow {
    display: block;
  }
}

/* Still, the reel becomes a strip the reader swipes through themselves. */
@media (prefers-reduced-motion: reduce) {
  .marketing-voices-reel {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
  }

  .marketing-section .marketing-voices {
    animation: none;
  }

  .marketing-section .marketing-voice {
    scroll-snap-align: start;
  }

  .marketing-section .marketing-voice[inert] {
    display: none;
  }
}

/* FAQ details/summary */

.marketing-section details {
  border-top: 1px solid var(--hairline);
  max-width: 44rem;
}

/* Inside the split it already has a column; the cap would only narrow it. */
.marketing-split__main details { max-width: none; }

.marketing-section details:last-of-type {
  border-bottom: 1px solid var(--hairline);
}

.marketing-section details[open] {
  padding-bottom: 1rem;
}

/* The answer keeps a reading measure: the row is 44rem wide, and 16px prose
   across all of it runs to ninety characters a line. */
.marketing-section details p {
  max-width: 38rem;
}

/* The row's air is the summary's own padding, so the whole row is the tap
   target, not the one line of text in its middle. */
.marketing-section details summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--text);
  padding: 1rem 1.5rem 1rem 0;
  position: relative;
  list-style: none;
}

.marketing-section details summary::-webkit-details-marker {
  display: none;
}

.marketing-section details summary::after {
  content: "+";
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  font-size: 1.25rem;
  transition: transform 200ms;
}

.marketing-section details[open] summary::after {
  content: "−";
}

.marketing-section details p {
  margin-top: 0;
  margin-bottom: 0;
}

/* Legal documents — render Markdown via app/services/markdown_renderer.rb.
   The first section heading follows the preamble at the same distance every
   later one follows its section. */

/* A 40rem measure (about 80 characters at this size: a document, not a
   marketing column), the notes' 17rem column and the gap between. */
.legal-doc {
  max-width: 60rem;
  padding: 0 0 3rem;
  color: var(--text);
  line-height: 1.65;
}

.legal-doc h1,
.legal-doc h2,
.legal-doc h3 {
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text);
  margin-top: 2.5rem;
  margin-bottom: 0.75rem;
}

.legal-doc h1 { font-size: 1.75rem; }
.legal-doc h2 { font-size: 1.4rem; }
.legal-doc h3 { font-size: 1.15rem; margin-top: 1.75rem; }

.legal-doc__intro { max-width: 40rem; }

.legal-doc__intro > :first-child { margin-top: 0; }

/* Full-strength ink: this is the text the reader came to read, and a policy
   set in the caption grey is a policy nobody reads. */
.legal-doc p,
.legal-doc ul,
.legal-doc ol {
  color: var(--text);
  margin-bottom: 1rem;
}

.legal-doc ul,
.legal-doc ol {
  padding-left: 1.5rem;
}

.legal-doc li {
  margin-bottom: 0.5rem;
}

.legal-doc strong {
  color: var(--text);
}

.legal-doc em {
  color: var(--text);
  font-style: italic;
}

.legal-doc hr {
  border: none;
  border-top: 1px solid var(--hairline);
  margin: 2.5rem 0;
}

.legal-doc table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5rem 0;
}

.legal-doc th,
.legal-doc td {
  text-align: left;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--hairline);
  color: var(--text-muted);
}

.legal-doc th {
  color: var(--text);
  font-weight: 600;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.legal-doc a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.legal-doc code {
  background: var(--bg-card);
  padding: 0.1em 0.35em;
  border-radius: 0.25rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  color: var(--text);
}

/* The sections are a grid: text down column one, the plain-words notes down
   column two. Every section is two rows, heading then body, numbered off the
   item's --i, so a note lands on its section's body row and starts level with
   the first paragraph; a row grows to the taller of text and note, so notes
   never overlap. The notes follow all the text in the DOM (see the view), so
   a selection stays in one column. */
.legal-doc__sections {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 17rem;
  column-gap: 3rem;
}

.legal-doc__heading { grid-column: 1; grid-row: calc(var(--i) * 2 + 1); }
.legal-doc__body    { grid-column: 1; grid-row: calc(var(--i) * 2 + 2); }
.legal-doc__note    { grid-column: 2; grid-row: calc(var(--i) * 2 + 2); }

/* The column's one label, in the first heading's row, sat on its floor so
   it stands just over the first note. */
.legal-doc__label {
  grid-column: 2;
  grid-row: 1;
  align-self: end;
  padding: 0 0 var(--space-2) calc(var(--space-4) + 2px);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* A section with no note beside it, such as an annex, takes the margin column
   as well: its table wants the room. Prose inside it keeps the document's
   measure, so only the table grows. */
.legal-doc__span { grid-column: 1 / -1; }

.legal-doc__body.legal-doc__span > :not(table) { max-width: 40rem; }

.legal-doc__note {
  align-self: start;
  margin-top: 0.125rem;
  padding-left: var(--space-4);
  border-left: 2px solid var(--hairline-strong);
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-muted);
}

.legal-doc__note blockquote,
.legal-doc__note p {
  margin: 0;
  color: inherit;
}

/* Narrow: one column, three rows a section, the note between heading and
   body as a tinted aside; the label goes with the column, and the first note
   carries it instead. */
@media (max-width: 56.25em) {
  .legal-doc__sections { grid-template-columns: minmax(0, 1fr); }

  .legal-doc__heading { grid-row: calc(var(--i) * 3 + 1); }
  .legal-doc__note    { grid-column: 1; grid-row: calc(var(--i) * 3 + 2); }
  .legal-doc__body    { grid-row: calc(var(--i) * 3 + 3); }

  .legal-doc__label { display: none; }

  .legal-doc__note {
    margin: 0 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-left: none;
    border-radius: var(--radius-sm);
    background: var(--bg-panel);
  }

  .legal-doc__note:first-of-type::before {
    content: "In plain words";
    display: block;
    margin-bottom: var(--space-1);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
}


/* Marketing topbar actions + animated wordmark. */
.marketing-topbar__actions { margin-left: auto; }

/* "Brrr" wordmark, real text: a bold italic that leaves a two-step speed trail
   (two crisp echoes streaking left = the word printing fast). Offsets are in em
   so the trail scales with font-size across the marketing and app topbars. */
.marketing-logo {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3em;
  font-size: 1.1rem;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  font-style: normal;
}

/* The mark lines up on the grid by the near echo, the first ink the eye
   reads as an edge: the far one at 8% hangs into the margin, the way a
   quote mark hangs, or the mark reads indented from the text under it. */
.marketing-logo__brand {
  position: relative;
  display: inline-block;
  margin-left: 0.28em;
  font-weight: 800;
  font-style: italic;
  letter-spacing: -0.035em;
  color: var(--text);
}

.marketing-logo__fg { position: relative; z-index: 5; }

/* Echoes: two copies of the word pushed left and faded, as generated content
   so they aren't real text — selecting/copying the wordmark yields "Brrr", not
   "BrrrBrrrBrrr". content is the literal word (same in the wordmark and the
   hero, its only two users); they inherit the brand's bold italic. */
.marketing-logo__brand::before,
.marketing-logo__brand::after {
  content: "Brrr";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--text);
  pointer-events: none;
}
.marketing-logo__brand::before { transform: translateX(-0.28em); /* = the brand's margin-left */ opacity: 0.22; z-index: 3; }
.marketing-logo__brand::after  { transform: translateX(-0.55em); opacity: 0.08; z-index: 2; }


/* ===== /about =====
   A manifesto page: one claim per section, the prose kept at a reading
   measure, and one band of art carrying the only reference we have. */

/* The thesis is the section's own heading rather than a label announcing it,
   so it takes a statement's size: a step above the page's other h2s, tighter
   tracking, and a measure that keeps it to two lines on a desktop. Not only
   /about's since 2026-09-16 — the landing's vision is the same move, and a
   claim set ABOVE a heading gives the section two heads and the wrong one
   wins. */
.marketing-section h2.section-claim {
  font-size: clamp(1.75rem, 4vw, 3rem);
  letter-spacing: -0.03em;
  max-width: 34rem;
  margin-bottom: 1.5rem;
}

/* The argument under the claim reads as prose, so it takes the brief's 40rem
   measure and a step up in size from the page's caption-weight body. */
.marketing-section .about-prose p {
  max-width: 40rem;
  font-size: 1.0625rem;
  line-height: 1.7;
}

/* The one band of art, with its explanation UNDER it rather than on it: a
   three-line note over a busy render is a contrast problem that no scrim
   fixes honestly, and the line alone is what the picture is for. */
.about-figure {
  margin: 0;
  padding-bottom: 4rem;
  border-top: 1px solid var(--hairline);
}

/* It breaks the wrap the way the landing cover does; the line runs in white
   ink over a scrim that darkens the middle only, so the picture keeps its
   colour at the edges. */
.about-band {
  position: relative;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  padding: clamp(5rem, 14vw, 9.5rem) 1.5rem;
  background: var(--cover-art) center / cover no-repeat;
  text-align: center;
}

.about-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(75% 65% at 50% 50%, rgba(8, 15, 30, 0.74), rgba(8, 15, 30, 0.12) 78%);
}

.about-band__line {
  position: relative;
  margin-inline: auto;
  text-wrap: balance;
}

.about-band__line {
  max-width: 32rem;
  font-size: clamp(1.5rem, 3.2vw, 2.25rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.025em;
  color: #fff;
  margin-bottom: var(--space-4);
}

/* The caption sits on the page, in the page's own ink. */
.about-band__note {
  max-width: 36rem;
  margin: var(--space-8) auto 0;
  text-align: center;
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--text-muted);
  text-wrap: pretty;
}

/* Today beside next: the contrast is what a reader is weighing, so the lists
   sit side by side. A rule over each column, because the two are genuinely
   separate things being compared. */
.about-split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-8) var(--space-16);
  max-width: 58rem;
  margin-top: var(--space-8);
}

.marketing-section .about-split h3 {
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline-strong);
  margin-bottom: var(--space-4);
}

.marketing-section .about-split ul {
  max-width: none;
  margin-bottom: 0;
  padding-left: 1.25rem;
}

.marketing-section .about-split li {
  margin-bottom: var(--space-3);
  font-size: 0.9375rem;
  line-height: 1.6;
}

@media (max-width: 48rem) {
  .about-split {
    grid-template-columns: 1fr;
    gap: var(--space-8);
    max-width: 34rem;
  }
}


/* ===== /how-it-works: the flow =====
   A real sequence, so it runs on a rail: the number sits ON the line, the
   step's own text beside it, one sentence where one will do. The rail stops
   at the last dot rather than running off into the page. */
.flow {
  max-width: 44rem;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: flow;
}

.flow__step {
  counter-increment: flow;
  position: relative;
  padding: 0 0 var(--space-8) var(--space-12);
  border-left: 1px solid var(--hairline);
}

.flow__step:last-child {
  border-left-color: transparent;
  padding-bottom: 0;
}

.flow__step::before {
  content: counter(flow);
  position: absolute;
  left: 0;
  top: 0;
  translate: -50% 0;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  background: var(--bg);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* The dot is 2rem tall, so the title sits on its centre line. */
.marketing-section .flow h3 {
  padding-top: 0.2rem;
  font-size: 1.15rem;
  line-height: 1.3;
  margin-bottom: var(--space-2);
}

.marketing-section .flow p {
  max-width: 34rem;
  margin-bottom: 0;
  font-size: 0.9375rem;
  line-height: 1.65;
}

@media (max-width: 40rem) {
  .flow__step { padding-left: var(--space-8); }

  .flow__step::before {
    width: 1.6rem;
    height: 1.6rem;
    font-size: 0.75rem;
  }
}

/* ===== /pricing: the plan =====
   The price, what it buys and the button in one object, with the only three
   things that can move a week beside it. That card is the page's whole job,
   and it used to be three paragraphs of prose. */
.plan-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: var(--space-12);
  align-items: start;
  /* The same 58rem the capability grid stops at, so the plan, the three weeks
     and the reasons share one right edge down the page. */
  max-width: 58rem;
}

.plan {
  padding: var(--space-8);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  background: var(--bg-card);
}

.plan__eyebrow {
  margin: 0 0 var(--space-3);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* One line per thing the week buys, each under its own rule: three sentences
   in a paragraph read as an argument, three ruled lines read as an invoice. */
.plan__list {
  max-width: none;
  margin: 0 0 var(--space-6);
  padding: 0;
  list-style: none;
}

.plan__list li {
  margin-bottom: 0;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--hairline);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--text);
}

.plan .marketing-cta {
  display: block;
  margin-top: 0;
  text-align: center;
}

.plan__note {
  max-width: none;
  margin: var(--space-3) 0 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Beside the card: quiet blocks under their own rules rather than a second
   card competing with the first. */
.plan-extra + .plan-extra {
  margin-top: var(--space-6);
}

.marketing-section .plan-extra h3 {
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline-strong);
  font-size: 1rem;
  margin-bottom: var(--space-2);
}

.marketing-section .plan-extra p {
  max-width: none;
  margin-bottom: 0;
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* The card and its three notes hold two columns down to 40rem: at tablet width
   a 34rem cap left them hugging the left while the invoice cards below ran the
   full width, and the page's right edge came apart. */
@media (max-width: 40rem) {
  .plan-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
    max-width: 34rem;
  }
}

/* The examples are cards now, so they take the chrome's hairline; the total is
   the ticket alone, with the air a total deserves above it. */
.pricing-examples {
  max-width: 58rem;
}

.pricing-example {
  border: 1px solid var(--hairline);
}

.pricing-example__total {
  margin-top: var(--space-4);
}

/* The one number a pricing page exists for, set as a figure rather than
   buried in a sentence. */
.price-figure {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: var(--space-2) 0 var(--space-8);
}

/* Money on this page rides the hang-tag's amber stock, the same ticket the
   landing writes "free" on and the contractor cards carried their weekly
   price on. The ink and the stock come from .hang-tag; these only set the
   size, and the padding and radius follow it in em so one ticket at 4rem
   and one inside a sentence are the same object. */
.price-figure__amount {
  font-size: clamp(2.5rem, 6vw, 4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  padding: 0.12em 0.22em;
  border-radius: 0.1em;
}

.hang-tag--inline {
  font-size: 1em;
  padding: 0.1em 0.4em;
}

.price-figure__unit {
  font-size: 1.05rem;
  color: var(--text-muted);
}
