/* Made by Wacho — US offer landing page (landing/websites/)
   ---------------------------------------------------------------------------
   Self-contained. This page shares NOTHING with the root styles.css: its
   palette, both its faces and its button shape are foreign to the site kit,
   so importing the kit would only mean overriding all of it. Nothing here is
   loaded by any other page, and nothing here loads from anywhere else.

   Two faces only: Libre Baskerville 400 for every heading and the proof band,
   Inter for body copy and button labels. Norca Rough and Martian Mono, which
   carry the rest of the site, do not appear on this page at all.

   No JavaScript. The marquee, the nav and every state below are CSS, which is
   also why nothing here depends on a measured --nav-h. */

:root {
  --cream:  #fcfbf7;   /* hero ground, and the illustration's own sky */
  --ink:    #0e1112;   /* all type */
  --green:  #3d843a;   /* the promise, headline only */
  --pink:   #f7bac2;   /* pill buttons */
  --yellow: #f7dd63;   /* proof band */
  --white:  #ffffff;   /* the AI section */

  /* The arc rises 57px across a 1440 frame, and it keeps that proportion at
     every width because an SVG's viewBox is its intrinsic aspect ratio. This
     is that same proportion as a percentage, for the band that has to leave
     room for the arcs biting into it — as PADDING, which resolves against
     width, the same thing the arc's height tracks. */
  --arc-pct: 3.9583%;  /* 57 / 1440 */

  --edge: clamp(20px, 5vw, 64px);

  /* ── The shared scale ──────────────────────────────────────────────────
     Extracted when the page went from four bands to eleven. Every value below
     was already living in the stylesheet twice or more by then, and a token
     that four sections read is the difference between one edit and four.

     `--wrap` is a width, not a length, and it works as a custom property
     because substitution is textual: `width: var(--wrap)` resolves the 100%
     against the element's own containing block, which is what is wanted.

     EVERY CLAMP THAT SETS A FONT SIZE KEEPS ITS MAX AT OR UNDER 2.5x ITS MIN,
     and that is a constraint rather than a preference. A clamp whose preferred
     term leans on `vw` stops growing when a reader zooms, because `vw` tracks
     the viewport and not the zoom level; the px floor is the part that keeps
     growing, so the range has to be narrow enough for the floor to take over
     before text is asked to reach 200%. A 4x range strands the type at its
     middle value and fails SC 1.4.4. Measured: 28 font-size clamps on this
     page, none over 2.5x.

     SPACING CLAMPS ARE NOT HELD TO IT — --edge below runs 3.2x on purpose,
     because a gutter that stops growing is a gutter, not unreadable text. */
  --body: clamp(15px, 1.25vw, 17px);          /* .ai__body and .get__body both */
  --h2:   clamp(28px, 3.6vw, 48px);           /* was .ai__title's alone */
  --band: clamp(56px, 6.4vw, 92px);           /* was .gets' padding-block */
  --wrap: min(1180px, 100% - 2 * var(--edge));
  --card-pad: clamp(22px, 2.4vw, 34px);
  /* One hairline value, and it is DECORATIVE, which is the only reason it is
     allowed to be this quiet. Measured, ink at 14% resolves to #dbdad7 on
     cream and reads 1.35:1 against it — nowhere near the 3:1 that a boundary
     carrying meaning would owe. It gets away with that because it carries
     none: every card on this page is a real list item with real spacing
     around it, and where a card means something more than its neighbours, on
     the recommended plan, the meaning is in the badge's words and a 2px ink
     edge at 18:1, never in this line. Don't promote it to load-bearing
     without taking it to 0.48, where it stops being a hairline. */
  --hair: rgba(14, 17, 18, 0.14);

  /* The sticky bar's height, and it is arithmetic rather than a measurement:
     a 44px control (forced, see .stickybar__go) + 2 x 10px of bar padding +
     the 1px top border. The bar is only built below 760px, but the token is
     declared here because the FOOTER is what has to reserve it, and a number
     typed in two places is a number that drifts. */
  --sticky-h: 65px;
}

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

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0;
  /* No horizontal scroll anywhere: every full-bleed thing on this page is
     width:100%, never 100vw — 100vw counts the scrollbar and the page does
     not, which overflows by exactly the scrollbar's width. */
  overflow-x: hidden;
}

img { max-width: 100%; }

h1, h2 {
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-weight: 400;
  margin: 0;
}

/* One ring for every focusable thing on the page. Round one shipped without
   any, which left keyboard users with only the browser default over a pink
   pill — nearly invisible.

   `summary` is on this selector because it is focusable and is NOT an anchor,
   so it fell straight through to that same browser default the moment the FAQ
   landed. Every focusable thing on the page is now one of these two. */
a:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── The pill ────────────────────────────────────────────────────────────
   A plain <a>, deliberately. The shared kit wraps every pill label in a
   .btn__label span so the type can scale on hover while the frame holds
   still, but that convention exists to work with the root stylesheet and
   script.js, neither of which this page loads. */
.pill {
  display: inline-block;
  /* THE LABEL SITS AT BODY SIZE, NOT ABOVE IT. Round one ran
     clamp(17px, 1.55vw, 22px), which tied the hero lede at 1440 and beat it
     everywhere below about 1100px — the pill floored at 17 while the lede
     floored at 16 and body copy at 15, so the button label was larger than the
     sentence arguing for it. A button is a control, not a heading; the nav's
     .pill--sm was the only one on the page that read correctly.

     14px of block padding on a ~23px line box gives a 51px control at the wide
     end and 49px at the narrow one, both still clear of the 44px minimum tap
     target.

     THE INLINE PADDING IS A CLAMP BECAUSE OF ONE LABEL, and that label has
     since been replaced: the AI band's 31-character `nowrap` CTA is now the
     page's shared 21-character one, which is why the override that used to
     sit at the foot of this file is gone (its epitaph is still down there).
     The clamp itself stays. It costs nothing, the root kit's pill carries one
     for the same reason, and the longest label on the page today is the plan
     cards' "Start with a Landing Page" at 25 characters. */
  padding: 14px clamp(24px, 2.2vw, 32px);
  border-radius: 56px;
  background: var(--pink);
  color: var(--ink);
  font-family: inherit;
  font-weight: 500;
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.3;
  text-decoration: none;
  transition: background-color 160ms ease, transform 160ms ease;
}

.pill:hover,
.pill:focus-visible {
  background-color: #f4a8b3;
  transform: translateY(-1px);
}

/* The nav's copy of the button. Same shape, one step down, so it reads as the
   quiet echo of the hero's ask rather than competing with it. Untouched by the
   trim above: this shorthand overrides both the base padding and the base
   font-size outright, and this bar was the one that already read right. */
.pill--sm {
  padding: 10px 22px;
  font-size: clamp(14px, 1.05vw, 16px);
}

@media (prefers-reduced-motion: reduce) {
  .pill { transition: none; }
  .pill:hover,
  .pill:focus-visible { transform: none; }
}

/* ── Hero ────────────────────────────────────────────────────────────────
   Exactly one viewport tall, with the illustration as its floor.

   svh, not vh: vh counts the mobile URL bar that retracts on scroll, so a vh
   hero is taller than the screen on first paint and pushes its own button out
   of frame — the reason the root stylesheet uses svh in all four of its
   full-height sections. */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;          /* clips the picture where it overruns the top */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--cream);
}

/* Bottom-anchored at its natural ratio, so the meadow always sits on the
   section's floor and the cream above it is the page's own ground rather than
   part of the picture. On a short screen the top of the picture is what gets
   clipped, which is sky. */
.hero__anim {
  /* Every geometry declaration below is shared with .hero__art on purpose:
     the overlay carries the same 2812x625 ratio, so identical positioning,
     object-fit and object-position line the two up at every width with no
     coordinate maths at all. Stacked one z-index above the art, still under
     the fade and the copy. */
  z-index: 0;
  /* THE RATIO IS FORCED, not inherited from the file. 2812 and 625 are
     coprime, so no integer downscale preserves 4.4992 exactly: at half size
     the overlay's own ratio is 4.5064 and `height: auto` drew it 1px short,
     which slid the whole layer 1px down the art. Declaring the ratio takes
     the height off the file's pixel count. Same idiom .hero__fade uses to
     stay glued to the picture. */
  aspect-ratio: 2812 / 625;
}

@media (prefers-reduced-motion: reduce) {
  /* A real stop, not a request. The motion lives in a separate file, so
     removing the layer removes the animation outright — the single-file
     version had to swap <source>s to manage the same thing. */
  .hero__anim { display: none; }
}

.hero__art,
.hero__anim {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
  width: 100%;
  height: auto;
  display: block;
  /* A full-bleed picture is always width/ratio tall, which grows with the
     viewport's WIDTH while its height does not. The cap only bites on wide,
     short screens, and cover spends the crop on the sky at the top, which the
     fade is covering anyway. */
  max-height: 56svh;
  object-fit: cover;
  /* Plain 50%, and the figure sits at 48% of the export — near enough that no
     override is owed. The current art is the BOWL cut: hills rising toward
     both edges, the yellow field arcing around the figure, cropped from a
     3072x1024 Magnific render through a 4.50 window placed so the head tops
     out at 46% of the height. That 46% is the whole ballgame: the button's
     clearance over the head is 0.54 x (viewportWidth / ratio), re-measured at
     73-114px across the four collision viewports after this art landed. A
     future export must keep the head on that line or the button lands on it
     again — the bug that cost two commits before this one.

     The img itself lives inside a <picture> now (typing-loop animation with a
     reduced-motion still); that wrapper takes no part in layout and creates
     no containing block, which is why every rule here still addresses the img
     directly and none of this file changed for it. */
  object-position: 50% 100%;
}

/* The straight cut, solved. The picture's top edge is a ruled line — in the
   last build it ran straight across the treetops — and this dissolves it into
   the cream.

   IT CARRIES THE PICTURE'S OWN ASPECT RATIO so it overlays the art exactly,
   which is what lets the gradient stops be percentages of the picture rather
   than of the viewport. Sized in vh instead, it would wash out the meadow's
   foot on a short screen and miss the seam entirely on a tall one.

   The picture's sky is pure white and the page's ground is #fcfbf7; the fade
   also covers that 3-value step, so no colour-matching of the export is
   needed. */
.hero__fade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  width: 100%;
  aspect-ratio: 2812 / 625;
  /* MUST MATCH .hero__art's cap, or the two boxes come apart on a wide screen
     and the gradient's stops land in the wrong places — the fade ended up
     101px taller than the picture at 1920, which put its 75%-opaque region
     where the picture's top edge was and let the treetops show through the
     sub. Same width, same ratio, same cap: same box. */
  max-height: 56svh;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    var(--cream) 0%,
    rgba(252, 251, 247, 0.98) 8%,
    rgba(252, 251, 247, 0.72) 20%,
    rgba(252, 251, 247, 0.28) 34%,
    rgba(252, 251, 247, 0) 46%
  );
}

/* Everything the reader touches sits above both. */
.nav,
.hero__copy { position: relative; z-index: 2; }

/* At its natural ratio the picture is a 4.2:1 strip, which on a phone is about
   90px of meadow at the foot of a 812px screen — a stripe, not a scene. Below
   this it is given a real height and allowed to crop sideways instead, which
   keeps the figure and the desk at a readable size. The fade follows it so the
   top edge is still dissolved.

   THIS RULE MUST NOT RESTATE object-position. It did, at 50%, which silently
   overrode the base rule's 33% and put the crop window on empty meadow with
   the figure cut off past the left edge — the one width where the horizontal
   position actually matters, since a phone is the only place the picture is
   cropped sideways at all. */
@media (max-width: 760px) {
  .hero__art,
  .hero__anim {
    height: clamp(240px, 42svh, 400px);
  }

  /* The picture no longer has its natural height here, so the copy's reserved
     space has to match the fixed one instead of the ratio. */
  .hero__copy { padding-bottom: clamp(240px, 42svh, 400px); }

  .hero__fade {
    aspect-ratio: auto;
    height: clamp(240px, 42svh, 400px);
    background: linear-gradient(
      to bottom,
      var(--cream) 0%,
      rgba(252, 251, 247, 0.9) 14%,
      rgba(252, 251, 247, 0.4) 32%,
      rgba(252, 251, 247, 0) 52%
    );
  }
}

/* ── Nav ─────────────────────────────────────────────────────────────────
   Inside the hero, transparent over the sky, and NOT sticky — see the note in
   the markup. Lockup left, links and the small pill right. */
/* 1fr auto 1fr, not a flex row: the lockup has to sit on the PAGE's centre
   line, and in a flex row it drifts by half the difference between the two
   clusters — which is large here, since the left is three links and the right
   is a link, a pill and two icons. The homepage's nav solves the same problem
   by taking its lockup out of flow entirely. */
.nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding: clamp(18px, 2.4vw, 30px) var(--edge);
}

/* Painted, not drawn: the SVG is a mask and the colour comes from a token, so
   the lockup follows the palette like the rest of the chrome. The
   aspect-ratio is the mark's own viewBox, so height never needs a second
   hard-coded number. Same idiom as the root nav's .nav__logo. */
.nav__logo {
  display: block;
  flex: 0 0 auto;
  width: clamp(104px, 9.5vw, 138px);
  aspect-ratio: 1906 / 853;
  background-color: var(--ink);
  -webkit-mask: url("/assets/logo.svg") no-repeat center / contain;
          mask: url("/assets/logo.svg") no-repeat center / contain;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.5vw, 24px);
}

.nav__links--start { justify-content: flex-start; }
.nav__links--end   { justify-content: flex-end; }

/* .nav__social and .nav__icon USED TO SIT HERE and are gone, not orphaned.
   The Instagram and Threads marks moved to the footer, so their rules moved
   with them and were renamed to match (.foot__social / .foot__icon, at the
   foot of this file). The old pair also ran a 40px target and an opacity
   fade; the footer's run 44px and step in tone, because this page has no
   opacity tier anywhere else. */
.nav__link {
  color: var(--ink);
  font-size: clamp(14px, 1.05vw, 16px);
  text-decoration: none;
  padding: 6px 2px;
  border-bottom: 1px solid transparent;
  transition: border-color 140ms ease;
}

.nav__link:hover,
.nav__link:focus-visible { border-bottom-color: var(--ink); }

/* Nothing in the bar may wrap. A two-line "Book a call" beside a two-line
   pill was what the right cluster did at 700 before the steps below. */
.nav__link,
.nav .pill { white-space: nowrap; }

/* The bar sheds one cluster at a time, widest and least useful first.

   1. The section links, which point at sections that do not exist yet.
      VISIBILITY, NOT DISPLAY: `display: none` takes them out of the grid, and
      three columns holding two items puts the lockup in the first cell and
      throws the whole bar left. Hidden this way the cell survives, the lockup
      stays centred, and the links are still gone for a screen reader. */
@media (max-width: 900px) {
  .nav__links--start { visibility: hidden; }
}

/* 2. The secondary text link. The pill says the same thing louder. */
@media (max-width: 820px) {
  .nav__links--end .nav__link { display: none; }
}

/* 3. Everything. Below this width the STICKY BAR at the foot of the screen is
      carrying both asks, and a nav pill saying "See plans" while a fixed bar
      three inches below says the same thing is one ask drawn twice.

      This replaces a 600px step that dropped the grid to two columns to shed
      the social icons. Those icons are in the footer now, so there is no third
      cluster left to wrap and no reason to restate the grid: one centred
      column holding the lockup is the whole bar here. */
@media (max-width: 760px) {
  .nav {
    grid-template-columns: 1fr;
    justify-items: center;
  }
  .nav__links { display: none; }
}

/* ── Hero copy ───────────────────────────────────────────────────────────*/
.hero__copy {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: clamp(24px, 4vh, 56px) var(--edge) 0;
  /* Reserves the picture's own height so the copy centres in the space ABOVE
     the meadow rather than in the whole section, which would land it on the
     grass. 22% is 1/4.499, the export's ratio, and a percentage works because
     padding resolves against the containing block's WIDTH — the same width
     the picture is sized from.

     THE CAP IS WHAT KEEPS THE HERO ONE VIEWPORT TALL. On a wide, short screen
     the picture is 475px of a 900px hero, and reserving all of it leaves the
     nav and the copy 90px too little; the section then grows past 100svh and
     the whole point is lost. Capped, the copy is allowed to sit over the top
     of the picture, which is where the fade is anyway.

     28, not 34: at 34 a 1280x720 laptop — an ordinary size, not a corner
     case — still came up 14px short and pushed the hero to 727.

     THE 17% FLOOR IS THE FIGURE'S HEAD. Widening the illustration fixed the
     button/head collision everywhere except 1600x800, which came out 45px
     clear against a 50px bar. The floor holds the button above the head line,
     and it is a percentage of WIDTH because that is exactly how the head line
     scales — the head sits a fixed fraction of the picture's drawn height
     above its foot, and that height is the width over the ratio. */
  padding-bottom: max(min(22%, 28svh), 16%);
}

.hero__title {
  /* Wide enough to hold two lines at full size. At a narrower measure it fell
     to three, and the third line pushed the sub and the button down onto the
     meadow. `ch` is safe HERE because the cap is on the heading itself, so it
     resolves against Libre Baskerville — on a wrapper it would resolve
     against the body font and be wrong by a third. */
  max-width: 34ch;
  margin: 0 auto;
  font-size: clamp(34px, 4.8vw, 68px);
  /* Not the frame's 0.877. The frame renders its two lines 69px apart at
     63px, which is 1.095, and at 0.877 a multi-line headline closes into a
     solid block. */
  line-height: 1.09;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.hero__promise { color: var(--green); }

.hero__sub {
  max-width: 46ch;
  margin: clamp(18px, 2.2vw, 30px) auto 0;
  font-size: clamp(16px, 1.5vw, 22px);
  line-height: 1.4;
  text-wrap: balance;
}

.hero__copy .pill { margin-top: clamp(24px, 3vw, 40px); }

/* ── The arc dividers ────────────────────────────────────────────────────
   One shape, used twice, and in opposite directions: the white rises into the
   yellow from below, and the illustration dips into it from above. The band
   is therefore PINCHED at its centre and thickest at its two edges.

   IT MUST BE POSITIONED OUT OF FLOW, ABOVE THE BAND'S OWN BOX. The obvious
   version — arc in flow with a negative margin-top — does not work, and fails
   silently: a margin on a block's first in-flow child COLLAPSES THROUGH to
   the parent, so the whole band moves up 57px instead and the band's own
   background paints behind the arc. Both dividers rendered as dead straight
   edges, which looks like a wrong path rather than a layout bug.

   No height is declared: an SVG with a viewBox carries that ratio as its
   intrinsic one, so width 100% gives height = width x 57/1440 at every size.
   preserveAspectRatio="none" only governs how the path stretches inside the
   box, not the box itself. */
.arc {
  position: absolute;
  left: 0;
  bottom: 100%;
  width: 100%;
  /* Closes the sub-pixel hairline between the arc's foot and the band's top
     edge on fractional device pixel ratios. */
  margin-bottom: -1px;
  fill: currentColor;
}

/* The top arc's horns land on the illustration's yellow flower field, which is
   close enough to the band's own yellow that the curve dissolves into it. The
   crop cannot avoid that — stopping while the grass is still green cuts the
   figure off at the shins — so the curve carries its own soft edge.

   IT IS A STROKE ON THE CURVE ALONE, NOT A SHADOW ON THE SHAPE. A
   `filter: drop-shadow` on the filled path casts from the whole silhouette,
   and that silhouette includes the box's full-width straight bottom edge; the
   result was a hard horizontal line ruled clean across the band wherever the
   horns were thinner than the shadow's offset. Stroking only the quadratic
   and letting the fill paint over its lower half leaves the soft edge and
   nothing else.

   The blur is safe here despite preserveAspectRatio="none": the arc's height
   always comes from its own intrinsic ratio, so the scale is uniform in both
   axes and the blur is never stretched. */
.arc__edge {
  fill: none;
  stroke: rgba(14, 17, 18, 0.22);
  stroke-width: 4;
  vector-effect: non-scaling-stroke;
  filter: blur(3px);
}

/* ── Proof band ──────────────────────────────────────────────────────────*/
.proof {
  position: relative;   /* the arc hangs off this */
  /* `color` feeds the arc's currentColor as well as the type below. */
  color: var(--yellow);
  background: var(--yellow);
  /* THE PADDING IS ASYMMETRIC BY EXACTLY ONE ARC, and that is what centres
     the type. The two arcs do not treat this box the same way: the bottom one
     eats 57px OUT of it at the centre, while the top one adds 57px ABOVE it at
     the edges. Both move the visible middle up by the same amount, so the
     band's real centreline sits half an arc above the box's centre — and
     symmetric padding, which is what this was, left the words 28px low.
     Measured, not guessed.

     The smaller base also thins the band from 192px to about 151 without
     touching the quote size. */
  padding-top: clamp(20px, 2.2vw, 32px);
  padding-bottom: calc(var(--arc-pct) + clamp(20px, 2.2vw, 32px));
}

.proof__viewport {
  overflow: hidden;
  color: var(--ink);
}

/* The marquee. Two identical halves and a travel of exactly -50%, so the
   frame it lands on is pixel-identical to the one it left. */
.proof__track {
  display: flex;
  width: max-content;
  /* 92s for one half's 4408px, so about 48px a second. At 46s it read as a
     news crawl rather than as a band of claims. */
  animation: proof-scroll 92s linear infinite;
}

.proof__group {
  display: flex;
  flex-shrink: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* THE SPACING IS PADDING ON EVERY ITEM, INCLUDING THE LAST ONE — never `gap`
   on the track or the group. With `gap`, nine items have eight gaps, so half
   the track is one set PLUS half a gap and the loop jumps by that much every
   pass. As padding carried by all nine, one half is exactly 9 x (item + pad)
   and -50% is exactly one set. The same trap .pagewall documents at length in
   the root stylesheet. */
.proof__item,
.proof__group li {
  flex: 0 0 auto;
  position: relative;
  padding-right: clamp(34px, 4.6vw, 66px);
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-size: clamp(16px, 1.7vw, 24px);
  line-height: 1.3;
  white-space: nowrap;
}

/* The dot follows EVERY item, not just the ones after the first: in an
   endless sequence each claim is followed by another, so `li + li::before`
   would drop the separator at each half's seam. */
.proof__group li::after {
  content: "";
  position: absolute;
  right: calc(clamp(34px, 4.6vw, 66px) / 2);
  top: 50%;
  width: 7.4px;
  height: 7.4px;
  margin-top: -3.7px;
  margin-right: -3.7px;
  border-radius: 50%;
  background: var(--ink);
}

@keyframes proof-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Stop, don't slow — matching all three of the root stylesheet's
   reduced-motion blocks. Parked at translateX(0) the first claims are simply
   sitting there, readable. */
@media (prefers-reduced-motion: reduce) {
  .proof__track { animation: none; }
}

/* ── The AI section ──────────────────────────────────────────────────────
   The frame insets this section's TYPE to a centred column (250 to 1190 of
   1440, so 940 wide) while letting the illustration hang out to the left of
   it, nearly to the page edge. That offset is the section's whole shape: the
   heading and the answer line up on one measure and the picture sits outside
   it, so aligning the picture with the text would flatten the section into an
   ordinary two-column row. */
.ai {
  position: relative;   /* the arc hangs off this */
  color: var(--white);
  background: var(--white);
  /* THE TOP SPACING IS PADDING ON THE SECTION, NOT MARGIN ON THE HEADING, and
     the difference is not cosmetic. As a margin it collapses out through
     .ai__wrap and through .ai itself — neither has a top border or padding to
     stop it — and becomes a margin on the section, which pushed .ai 66px down
     the page and left a cream gap under the band. The white arc then hung in
     that gap instead of rising into the yellow, so the band's bottom edge
     measured dead straight. Same trap that made both arcs render flat in the
     first build, arriving from the other direction.

     No bottom padding: the illustration's bottom edge IS the section's bottom
     edge, so the desk stands on it rather than floating above it. */
  padding-top: clamp(40px, 4.6vw, 66px);
  padding-bottom: 0;

  /* How far the illustration escapes the text column on its left. Capped at
     the frame's 185px, and otherwise limited to whatever room actually exists
     beside the column, less a gutter so it can never reach the viewport edge.
     The gutter also absorbs the scrollbar, which 100vw counts and the page
     does not. Below ~980px there is no room left and it resolves to 0, which
     is the stacked layout anyway. */
  --ai-bleed: clamp(0px, calc((100vw - 940px) / 2 - 24px), 185px);
}

.ai__wrap {
  width: min(940px, 100% - 2 * var(--edge));
  margin-inline: auto;
  color: var(--ink);
}

.ai__title {
  font-size: var(--h2);
  line-height: 1.083;
  letter-spacing: -0.04em;
  text-align: left;
}

.ai__row {
  display: grid;
  /* The first column is the part of the illustration INSIDE the text column;
     the picture itself is that plus the bleed. */
  grid-template-columns: minmax(0, 471px) minmax(0, 1fr);
  /* Start, not end. The two columns are wildly different heights — the
     picture is 369 tall against about 137 of copy — and bottom-aligning them
     drops the copy to the picture's feet, a good 150px below where the frame
     puts it. In the frame the copy sits high, beside the screen and its face,
     which is the pairing the section is making. */
  align-items: start;
  /* Capped at 42 so the right column clears 427px at 1440, which is what the
     button needs to stay on one line. */
  gap: clamp(20px, 2.9vw, 42px);
  margin-top: clamp(28px, 3.4vw, 48px);
}

.ai__art {
  display: block;
  width: calc(100% + var(--ai-bleed));
  max-width: none;      /* beats the global img cap, which would eat the bleed */
  height: auto;
  margin-left: calc(var(--ai-bleed) * -1);
}

.ai__aside {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  /* Drops the copy to where the frame has it: level with the monitor's face
     rather than with the top of the picture. Roughly a quarter of the
     illustration's height, and it tracks the picture because both scale off
     the viewport across the widths where this two-column layout applies. */
  padding-top: clamp(0px, 8.96vw, 129px);
}

/* This button is wider than the copy above it and, in the frame, wider than
   the column it sits in — it reaches further left than the text does while
   staying flush right. Left to wrap it becomes a two-line blob inside a 56px
   radius, which is the one thing a pill must never do. */
.ai__aside .pill { white-space: nowrap; }

.ai__body {
  /* Set so the three lines break where the frame breaks them. The binding line
     is the middle one, 361px at the 17px cap; at a narrower measure its last
     word drops and the paragraph becomes four lines ending on an orphaned
     "is.". A ch value drifts here — it is keyed to Inter's zero, not to this
     sentence.

     Re-measured when the cap came down from 18 to 17: still three lines, and
     better balanced than before (349 / 361 / 339 against 370 / 383 / 359), so
     the 390px measure stands. */
  max-width: 390px;
  margin: 0;
  /* --body is that one token, now that four sections read it. It ran to 18
     here and 17 on the cards once, a 1px difference at the cap that read as an
     accident rather than as a step. The hero lede is deliberately larger;
     these are all the same role. */
  font-size: var(--body);
  line-height: 1.222;
}

/* The frame sets the button hard against the paragraph's last line box, and
   round one shipped this at 0 to match. That only worked while the button was
   the frame's size; now that it carries 14px of block padding, zero closes the
   gap entirely and the pill's top edge runs into the copy. This is the
   descender space the frame had, restored explicitly. */
.ai__aside .pill { margin-top: 16px; }

/* ── What you get ────────────────────────────────────────────────────────
   Three cards and no heading, which is what the copy doc specifies for this
   section and not an omission. Cream against the white above it, and a
   straight boundary rather than an arc — the illustration above finishes
   flush against its section's foot, and a curve here would cut the desk. */
.gets {
  background: var(--cream);
  padding-block: var(--band);
}

.gets__wrap {
  width: var(--wrap);
  margin-inline: auto;
}

.gets__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(28px, 3.6vw, 52px);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Cut-outs on a transparent ground, so they sit on the cream with no box —
   the trap the AI computer hit, where a near-white generated background drew
   a visible rectangle.

   Each export was TRIMMED TO ITS OWN CONTENT and then re-padded into the same
   square, which is what makes the three read as a set. Generated straight out,
   each object filled its frame by a different amount, so at one CSS width the
   telephone drew noticeably larger than the calendar. Now the box is the
   common scale and the drawing inside it is the same size in all three. */
.get__icon {
  display: block;
  width: clamp(76px, 6.4vw, 94px);
  height: auto;
  margin-bottom: clamp(14px, 1.4vw, 20px);
}

.get__name {
  margin: 0 0 clamp(10px, 1vw, 14px);
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-weight: 400;
  font-size: clamp(20px, 1.75vw, 25px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  /* Balanced, so a three-word title does not leave one word alone on line
     two — these run to two lines at almost every width. */
  text-wrap: balance;
}

.get__body {
  margin: 0;
  font-size: var(--body);
  line-height: 1.5;
}

@media (max-width: 860px) {
  .gets__grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 999px) {
  .ai__row {
    grid-template-columns: minmax(0, 1fr);
    /* Stacked, the copy comes first and the picture still has to finish flush
       with the section's floor. */
    gap: clamp(20px, 4vw, 32px);
  }
  .ai__aside {
    order: -1;
    padding-top: 0;
  }
  .ai__aside .pill { margin-top: 18px; }
}

/* The max-width: 400px override that used to sit here is GONE, and its own
   comment is why. It existed for a single 31-character `nowrap` label in the
   AI band, "Let's take a look under the hood", which at the base size came to
   291px inside a 280px column at 320 and got clipped by body's overflow. The
   comment offered to retire the block if that link ever got a shorter label
   when it was wired up. It did: the band now carries the page's one CTA
   label, "See plans and pricing", 21 characters, which measures about 213px
   in that same column. The block went with the label.

   If a long `nowrap` label ever comes back, this is the trade that worked:
   one step down on that one pill, never a cut to the tracking. */

/* ── One rule for every band heading ─────────────────────────────────────
   Same idiom as the root stylesheet's shared display-heading rule: the size,
   the leading and the tracking of an h2 belong to the page, not to whichever
   section happens to be carrying one. .ai__title had these three values to
   itself until there were seven h2s, at which point keeping them per-section
   would have meant seven places to change one decision.

   ADD NEW BAND HEADINGS TO THIS SELECTOR rather than re-declaring the values.

   text-wrap: balance is on headings ONLY, never globally: engines cap it at a
   handful of lines (six in Chromium, ten in Firefox) and it costs layout work
   on every reflow, so a body paragraph gets nothing from it but the cost. */
.ai__title,
.how__title,
.social__title,
.plans__title,
.monthly__title,
.faq__title,
.cta__title {
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-weight: 400;
  font-size: var(--h2);
  line-height: 1.083;
  letter-spacing: -0.04em;
  text-wrap: balance;
}

/* ── The quiet pill ──────────────────────────────────────────────────────
   The plan cards' non-recommended CTAs. One card in that row carries the only
   solid button, which is the honest way to make a recommended tier dominant:
   the emphasis comes from the others stepping back rather than from a claim
   about what other people bought.

   THIS IS NOT THE PINK PILL'S CONTRAST FIX. That was raised and settled: the
   filled pill's boundary measures 1.59:1 on cream against the 3:1 that WCAG
   1.4.11 asks of a control, its label is fine at 11.5:1, and shipping it as
   drawn is a deliberate decision on the owner's part. This variant exists for
   hierarchy, and it gets an ink edge because a transparent button with no edge
   is not a button at all. */
.pill--quiet {
  background: transparent;
  border: 1.5px solid var(--ink);
}

.pill--quiet:hover,
.pill--quiet:focus-visible {
  background-color: var(--ink);
  color: var(--cream);
}

/* ── How it works ────────────────────────────────────────────────────────
   Cream on cream against the band above, held apart by spacing alone. An arc
   here would not be invisible in the figurative sense, it would be literally
   invisible: the divider paints `fill: currentColor` and cream on cream
   measures 1.04:1. The curve only exists where the ground actually changes,
   which on this page is the two yellow bands and nowhere else. */
.how {
  background: var(--cream);
  padding-block: var(--band);
}

.how__wrap {
  width: var(--wrap);
  margin-inline: auto;
}

.how__art {
  display: block;
  /* height: auto is NOT optional on any picture on this page. The markup
     carries width and height attributes to reserve layout space against CLS,
     and with BOTH dimensions definite the browser ignores aspect-ratio
     outright — the repo has a tile that rendered 900px tall for exactly this
     reason. Every img rule below repeats it, for the same reason. */
  height: auto;
  width: 100%;
  margin-block: clamp(28px, 3.4vw, 48px);
}

.how__list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(28px, 3.6vw, 52px);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The one place --green appears outside the hero, and it is the same promise
   said twice: "Live in 10 days" up there, "most of the work is mine" here.
   Nothing else on the page may reach for it.

   At this size the 4.45:1 it measures on cream is comfortably inside the 3:1
   that large text owes. It would NOT clear the 4.5:1 that body copy owes,
   which is why the token's note says headline only and means it. */
.step__num {
  margin: 0;
  padding-bottom: clamp(10px, 1.2vw, 16px);
  border-bottom: 1px solid var(--hair);
  color: var(--green);
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-size: clamp(40px, 4.4vw, 64px);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.step__name {
  margin: clamp(12px, 1.4vw, 20px) 0 clamp(8px, 1vw, 12px);
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-weight: 400;
  font-size: clamp(19px, 1.6vw, 23px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.step__body {
  margin: 0;
  font-size: var(--body);
  line-height: 1.5;
}

/* ── Social proof ────────────────────────────────────────────────────────
   Cream, and the last cream band before the money. Its bottom padding carries
   an extra --arc-pct because the plans band's arc hangs into it: an arc is
   positioned on the FOLLOWING section at `bottom: 100%`, so the room it needs
   is reserved here, by the band it overlaps.

   THAT RESERVATION MUST BE THE PERCENTAGE TOKEN, NEVER A PX VALUE. The arc's
   height comes from its own viewBox ratio, so it is 57px at 1440, 76 at 1920
   and 101 at 2560. A px reservation is correct at exactly one width. */
.social {
  background: var(--cream);
  padding-top: var(--band);
  padding-bottom: calc(var(--band) + var(--arc-pct));
}

.social__wrap {
  width: var(--wrap);
  margin-inline: auto;
}

/* The framing line, set at body size rather than as a caption on purpose. It
   says these are brand projects, in Ecuador, in translation, and a reader who
   skims past it will assume all three quotes are US website clients — the most
   flattering thing they could assume and the one thing the page has not
   earned. A note nobody reads is the same as no note. */
.social__note {
  max-width: 62ch;
  margin: clamp(14px, 1.6vw, 22px) 0 0;
  font-size: var(--body);
  line-height: 1.5;
}

.social__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 44px);
  margin: clamp(30px, 3.6vw, 52px) 0 0;
  padding: 0;
  list-style: none;
}

.quote {
  display: flex;
  flex-direction: column;
  padding-top: clamp(18px, 2vw, 26px);
  border-top: 2px solid var(--ink);
}

.quote__text {
  margin: 0;
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.45;
}

.quote__text p { margin: 0; }

/* Pushed to the card's floor so three quotes of unequal length still line
   their attributions up on one baseline. `margin-top: auto` inside a column
   flex container is what does it; the alternative, a fixed height on the
   quote, would clip the longest one. */
.quote__by {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: clamp(16px, 1.8vw, 24px) 0 0;
  margin-top: auto;
  font-size: clamp(13px, 1.05vw, 15px);
  line-height: 1.4;
}

.quote__name { font-weight: 500; }

/* #4a4d4e is the one step down from ink this page has, and it is measured:
   8.24:1 on cream and 8.53:1 on white, so a secondary line is quieter without
   being dim anywhere it lands. The page has no opacity-based tier and should
   not grow one — every quiet thing here steps in tone. */
.quote__where { color: #4a4d4e; }

/* ── The sample links ────────────────────────────────────────────────────
   Three outbound links, which on a conversion page is a cost worth naming:
   besides the booking link they are the only things here that can take a
   reader off the page. They earn it because this page sells websites and
   nothing else on it is one, and all three open in a new tab so the scroll
   that got the reader this far is not spent.

   The tag under each name is not decoration. Two of these are demonstration
   builds and one is a paying client's live site, and the label belongs on the
   work rather than in a footnote under the section. */
.samples {
  margin-top: clamp(40px, 4.6vw, 68px);
  padding-top: clamp(28px, 3vw, 40px);
  border-top: 1px solid var(--hair);
}

.samples__title {
  margin: 0 0 clamp(18px, 2vw, 26px);
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-weight: 400;
  font-size: clamp(19px, 1.6vw, 23px);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.samples__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 34px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sample__link {
  display: block;
  color: var(--ink);
  text-decoration: none;
}

.sample__shot {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--hair);
  border-radius: 10px;
  transition: transform 160ms ease;
}

.sample__link:hover .sample__shot,
.sample__link:focus-visible .sample__shot { transform: translateY(-3px); }

.sample__name {
  display: block;
  margin-top: 12px;
  font-weight: 500;
  font-size: clamp(15px, 1.2vw, 17px);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.sample__tag {
  display: block;
  margin-top: 2px;
  color: #4a4d4e;
  font-size: clamp(12px, 1vw, 14px);
}

@media (prefers-reduced-motion: reduce) {
  .sample__shot { transition: none; }
  .sample__link:hover .sample__shot,
  .sample__link:focus-visible .sample__shot { transform: none; }
}

/* ── Plans ───────────────────────────────────────────────────────────────
   The page's second and last yellow band. Both of its edges are arcs: its own
   at the top, and .monthly's rising into it from below, so the yellow is
   pinched at the centre exactly as the proof strip is. Same pair of paths,
   same reason.

   Top padding is a plain --band, because the top arc sits ABOVE this box and
   takes nothing out of it. Bottom padding carries an arc, because .monthly's
   bulges UP into this band by a full arc at the centre. */
.plans {
  position: relative;   /* the arc hangs off this */
  /* Feeds the arc's currentColor as well as the type. THE WRAP BELOW SETS IT
     BACK TO INK — miss that and the band lays out perfectly with every word in
     it invisible, which is the easiest way there is to break this page. */
  color: var(--yellow);
  background: var(--yellow);
  padding-top: var(--band);
  padding-bottom: calc(var(--band) + var(--arc-pct));
}

.plans__wrap {
  width: var(--wrap);
  margin-inline: auto;
  color: var(--ink);
}

/* ONE MARK FOR THE BAND, NOT ONE PER CARD, on both of the card bands. Three
   pictures inside three price cards would give every tier the same visual
   weight, and making one tier read louder than the other two is the only job
   the plans layout has; two inside the monthly cards would undo the same
   band's rule that rank there comes from having less. Beside the heading a
   mark is a marker, inside a card it is an argument. */
.plans__head,
.monthly__head {
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.6vw, 22px);
}

.plans__mark,
.monthly__mark {
  flex: 0 0 auto;
  display: block;
  width: clamp(56px, 5vw, 84px);
  height: auto;
}

/* Mobile-first, and that is structural rather than stylistic: the desktop row
   is the override, so the base can never lose an equal-specificity tie to it.
   The repo has that exact bug documented from the other direction.

   THE MARKUP ORDER IS THE MOBILE ORDER: Full Site, Landing Page, Custom. The
   centre-stage effect that makes a middle card get chosen is a HORIZONTAL
   phenomenon, and in a vertical stack the preference inverts to the edges —
   which matters, because most of the traffic this page is built for reads it
   as a stack. `order` restores the conventional row above 1000px and nowhere
   else, so what is seen and what is tabbed never disagree on a phone. */
.plans__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: stretch;
  gap: clamp(20px, 2.2vw, 30px);
  margin: clamp(30px, 3.6vw, 52px) 0 0;
  padding: 0;
  list-style: none;
}

.plan {
  display: flex;
  flex-direction: column;
  /* NO `height: 100%` HERE, and that is what buys the featured card its lift.
     A percentage height resolves against the grid AREA, which would pin the
     card's height to the row and turn the negative margin-top below into a
     card floating clear of its neighbours' floor, taking its button with it.
     Left to `align-items: stretch` with an auto height, the same margin makes
     the card TALLER instead: it starts 22px higher and still ends level, so
     all three buttons stay on one baseline. */
  padding: var(--card-pad);
  border: 1px solid var(--hair);
  border-radius: 16px;
  background: var(--cream);
}

/* The recommended tier, and every device here is an honest one: a badge that
   says what it means, a heavier edge, a lift, and the only solid button in the
   row. Not one of them claims anything about what other buyers did. */
.plan--pick {
  border: 2px solid var(--ink);
  background: var(--white);
}

.plan__badge {
  display: inline-block;
  align-self: start;
  margin: 0 0 clamp(12px, 1.4vw, 18px);
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--cream);
  font-size: clamp(12px, 1vw, 13px);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.plan__name {
  margin: 0;
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-weight: 400;
  font-size: clamp(20px, 1.7vw, 25px);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.plan__price {
  margin: clamp(6px, 0.8vw, 10px) 0 0;
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-size: clamp(34px, 3.4vw, 48px);
  line-height: 1.05;
  letter-spacing: -0.03em;
  /* Three prices in a column read as a column of prices only if their digits
     line up. Proportional figures put the 9s and the 1s on different rhythms
     and the three cards stop rhyming. */
  font-variant-numeric: tabular-nums;
}

.plan__line {
  margin: clamp(8px, 1vw, 12px) 0 0;
  font-size: var(--body);
  line-height: 1.4;
}

.plan__list {
  margin: clamp(16px, 1.8vw, 24px) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--body);
  line-height: 1.45;
}

.plan__list li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 10px;
}

/* A MASKED SHAPE, NOT A TEXT GLYPH. Generated content IS announced: a check
   character in `content` has a screen reader read "check mark" before every
   bullet, five times on the recommended card alone. An empty pseudo-element
   painting a mask is announced by nothing, and the meaning was always carried
   by the words beside it. */
.plan__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.35em;
  width: 15px;
  height: 11px;
  background: var(--ink);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 11'%3E%3Cpath d='M1 5.6L5.2 9.8L14 1' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 11'%3E%3Cpath d='M1 5.6L5.2 9.8L14 1' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* The first-year figure. `margin-top: auto` pushes it and the button below it
   to the card's floor, which is what puts three CTAs on one baseline across
   cards carrying five, four and three bullets. */
.plan__year {
  margin: clamp(18px, 2vw, 26px) 0 clamp(14px, 1.6vw, 20px);
  margin-top: auto;
  padding-top: clamp(14px, 1.6vw, 20px);
  border-top: 1px solid var(--hair);
  color: #4a4d4e;
  font-size: clamp(13px, 1.05vw, 15px);
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
}

.plan__year strong { color: var(--ink); font-weight: 500; }

/* Without this the column flex container's default `stretch` turns the pill
   into a full-width blob: a 300px button around four words, which reads as a
   band of colour rather than as a control. The root stylesheet has the same
   bug documented on its lead-magnet CTA. */
.plan__cta {
  align-self: start;
  text-align: center;
}

.plans__terms {
  max-width: 62ch;
  margin: clamp(26px, 3vw, 40px) 0 0;
  font-size: var(--body);
  line-height: 1.5;
}

/* ── Monthly plans ───────────────────────────────────────────────────────
   White, with its arc rising into the yellow above, and no other separation
   from the band before it. The build price and the monthly price are two
   halves of one number: a boundary that read as a change of subject would let
   a reader believe the money was finished one band early.

   Top spacing is PADDING ON THE SECTION, never a margin on the heading. A
   margin collapses out through the wrap and through the section itself,
   neither of which has anything to stop it, becomes a margin on the section,
   and opens a gap above the band for the arc to hang in — at which point the
   divider renders as a dead straight line and looks like a wrong SVG path.
   This file has been bitten by that twice, from two directions. */
.monthly {
  position: relative;   /* the arc hangs off this */
  color: var(--white);
  background: var(--white);
  padding-top: var(--band);
  padding-bottom: var(--band);
}

.monthly__wrap {
  width: var(--wrap);
  margin-inline: auto;
  color: var(--ink);    /* see the note on .plans__wrap */
}

.monthly__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
  gap: clamp(20px, 2.4vw, 34px);
  margin: clamp(30px, 3.6vw, 52px) 0 0;
  padding: 0;
  list-style: none;
}

/* Neither of these two is emphasised, and that is the point: the band above
   has already asked the reader to choose once. Rank here comes from these
   cards having less than the plan cards, not from a second card treatment. */
.care {
  padding: var(--card-pad);
  border: 1px solid var(--hair);
  border-radius: 16px;
}

.care__name {
  margin: 0;
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-weight: 400;
  font-size: clamp(20px, 1.7vw, 25px);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.care__price {
  margin: clamp(6px, 0.8vw, 10px) 0 0;
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-size: clamp(30px, 2.8vw, 40px);
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

/* The period, one step down and in the body face, so "$149" reads as the
   number and "/mo" as its unit rather than the two running together. */
.care__per {
  font-family: Inter, system-ui, sans-serif;
  font-size: clamp(14px, 1.15vw, 16px);
  letter-spacing: 0;
}

.care__line {
  margin: clamp(8px, 1vw, 12px) 0 0;
  font-size: var(--body);
  line-height: 1.4;
}

.care__list {
  margin: clamp(16px, 1.8vw, 24px) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--body);
  line-height: 1.45;
}

.care__list li {
  position: relative;
  padding-left: 18px;
  margin-bottom: 9px;
}

.care__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink);
}

.monthly__terms {
  max-width: 62ch;
  margin: clamp(26px, 3vw, 40px) 0 0;
  font-size: var(--body);
  line-height: 1.5;
}

/* ── FAQ ─────────────────────────────────────────────────────────────────
   Cream, and the last band before the closer. Native <details>, so the open
   state, the keyboard handling and the announcement of that state are the
   browser's job rather than script's — which matters more than usual here,
   because this page has no script at all to fall back on. */
.faq {
  background: var(--cream);
  padding-block: var(--band);
}

.faq__wrap {
  width: var(--wrap);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(28px, 3.4vw, 48px);
}

.faq__art {
  display: block;
  height: auto;
  /* Capped and left-aligned in the stacked layout, where a 900x1200 portrait
     at full column width would be most of a screen of illustration in front of
     the one band a hesitant reader actually came for. */
  width: clamp(150px, 34vw, 230px);
  margin-top: clamp(18px, 2vw, 26px);
}

.faq__list {
  border-top: 1px solid var(--hair);
}

.faq__item {
  border-bottom: 1px solid var(--hair);
}

/* The whole row is the target, not the words. Padding is what makes it one:
   at 15px of block padding on a ~24px line box the row measures 54px, clear of
   both the 24px that WCAG 2.5.8 requires at AA and the 44px it asks at AAA.

   NO `role="button"` ON THIS ELEMENT, ever. It reads like an improvement and
   is the opposite: it suppresses the open/closed state announcement in NVDA
   and VoiceOver, which is the one thing a summary is for.

   `list-style: none` AND the -webkit- pseudo-element, because `display: flex`
   alone does not remove the disclosure marker in every engine and neither
   removal works everywhere on its own. */
.faq__q {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 15px 0;
  list-style: none;
  cursor: pointer;
  font-family: "Libre Baskerville", Georgia, "Times New Roman", serif;
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.35;
}

.faq__q::-webkit-details-marker { display: none; }

.faq__q:hover { color: #3c3f40; }

/* A real aria-hidden <svg>, NOT `::after { content: "+" }`. Generated content
   is announced: the root stylesheet's accordion does exactly that and reads
   "Do I own the website, plus" in NVDA. An svg with aria-hidden is announced
   by nothing and draws better besides. */
.faq__chev {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  /* Nudged off the baseline the flex row aligns it to, so the chevron sits
     with the x-height rather than hanging under the text. */
  transform: translateY(3px);
  transition: transform 200ms ease;
}

.faq__item[open] .faq__chev { transform: translateY(3px) rotate(180deg); }

.faq__a {
  padding: 0 0 clamp(18px, 2vw, 26px);
  /* 62ch is the reading measure the whole page uses for prose. It is safe as a
     `ch` value here because the cap is on the element that sets the type, so
     it resolves against Inter rather than against whatever the wrapper is. */
  max-width: 62ch;
  font-size: var(--body);
  line-height: 1.55;
}

.faq__a p { margin: 0; }

/* The open/close animation, and it is enhancement in the strict sense: where
   `interpolate-size` is unsupported the whole block is skipped and the panel
   simply snaps, which is what <details> has always done and is perfectly fine.

   `allow-discrete` on content-visibility is what keeps the closing half of the
   transition visible; without it the panel is removed from rendering on the
   first frame and only the opening direction animates. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }

  .faq__item::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size 240ms ease, content-visibility 240ms allow-discrete;
  }

  .faq__item[open]::details-content { block-size: auto; }
}

/* THIS BLOCK MUST STAY AFTER THE @supports ABOVE. `@supports` contributes no
   specificity of its own, so which of the two transitions wins is decided by
   source order and nothing else. Moved up, reduced motion silently loses. */
@media (prefers-reduced-motion: reduce) {
  .faq__chev { transition: none; }
  .faq__item::details-content { transition: none; }
}

/* ── Final CTA ───────────────────────────────────────────────────────────
   Closes on a full-bleed illustration the way the page opened on one, at the
   hero meadow's own ratio, so the two pictures read as a pair holding the page
   between them.

   `padding-bottom: 0` is what makes it work: the picture's bottom edge IS the
   section's bottom edge, so the scene stands on the footer's ink rather than
   floating above a strip of cream. Same idiom as .ai, and the same reason. */
.cta {
  position: relative;
  overflow: hidden;
  background: var(--cream);
  padding-top: var(--band);
  padding-bottom: 0;
  text-align: center;
}

.cta__wrap {
  width: var(--wrap);
  margin-inline: auto;
}

.cta__body {
  max-width: 58ch;
  margin: clamp(16px, 2vw, 26px) auto 0;
  font-size: clamp(16px, 1.4vw, 19px);
  line-height: 1.5;
}

/* Row, not stack, and the two are deliberately unequal: a filled pill and a
   text link. A landing page converts on one ask, and two buttons of the same
   weight is two asks whatever the labels say. */
.cta__acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 2vw, 28px);
  margin-top: clamp(24px, 3vw, 38px);
}

.cta__alt {
  color: var(--ink);
  font-size: clamp(15px, 1.2vw, 17px);
  text-decoration: underline;
  text-underline-offset: 4px;
  /* Block padding rather than none, so the text link is a 44px target in its
     own right instead of a 20px one sitting next to a 50px button. */
  padding: 12px 4px;
}

.cta__note {
  margin: clamp(18px, 2vw, 26px) 0 0;
  color: #4a4d4e;
  font-size: clamp(13px, 1.05vw, 15px);
}

.cta__art {
  display: block;
  width: 100%;
  height: auto;
  /* THE CAP IS WHAT KEEPS THE CLOSER FROM OUT-PICTURING THE HERO. This frame
     is 2.5:1, so full-bleed it draws 570px tall at 1440 against the hero
     meadow's 320px — the page would end on an image nearly twice the size of
     the one it opens with, which reads as the argument restarting rather than
     finishing.

     max-height plus cover rather than a fixed height, so `height: auto`
     survives and the aspect-ratio trap stays shut. Bottom-anchored, because
     the top of this frame is the pale haze band the crop already spared and
     the bottom is the meadow and the figure. Exactly .hero__art's idiom.

     A flat 400 rather than a clamp on purpose: the natural height only reaches
     400 at about 1000px of viewport, so below that the cap never bites and a
     phone still sees the whole scene. */
  max-height: 400px;
  object-fit: cover;
  object-position: 50% 100%;
  margin-top: clamp(32px, 4vw, 60px);
}

/* ── Footer ──────────────────────────────────────────────────────────────
   The one ink band on the page, and deliberately the shortest section in the
   file. A landing page's footer is not a site map: everything in it either
   says who this is or offers the one action the page exists for. */
.foot {
  background: var(--ink);
  color: var(--cream);
  padding-block: clamp(40px, 4.4vw, 64px);
}

.foot__wrap {
  width: var(--wrap);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(16px, 1.8vw, 24px);
}

/* Painted through a mask like the nav's, so the same file serves both marks
   and the colour comes from a token. Cream on ink here rather than ink on
   cream: one drawing, two grounds. */
.foot__logo {
  display: block;
  width: clamp(104px, 9.5vw, 138px);
  aspect-ratio: 1906 / 853;
  background-color: var(--cream);
  -webkit-mask: url("/assets/logo.svg") no-repeat center / contain;
          mask: url("/assets/logo.svg") no-repeat center / contain;
}

.foot__line {
  max-width: 46ch;
  margin: 0;
  font-size: var(--body);
  line-height: 1.5;
}

.foot__acts {
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.6vw, 20px);
}

.foot__link {
  color: var(--cream);
  font-size: clamp(15px, 1.2vw, 17px);
  text-decoration: underline;
  text-underline-offset: 4px;
  padding: 12px 4px;
}

/* 44px targets drawing a 22px mark, the linkboard's convention, and the reason
   these two live down here rather than in the nav: above the fold they were
   the only links on the page that sent a warm reader away before a price. */
.foot__social {
  display: flex;
  align-items: center;
  gap: 2px;
}

.foot__social a {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  color: var(--cream);
  text-decoration: none;
}

.foot__icon {
  display: block;
  width: 22px;
  height: 22px;
}

/* #a8a698 is measured at 7.74:1 on ink, so the quietest line on the page
   still clears AA for normal text with room to spare. Stepped in tone, not in
   opacity, like every other quiet thing here. */
.foot__base {
  margin: 0;
  color: #a8a698;
  font-size: clamp(12px, 1vw, 14px);
}

/* ── The sticky mobile bar ───────────────────────────────────────────────
   Hidden by default and only ever built at the width where it earns its keep.
   The finished page is roughly six screens tall on a phone, and most of the
   traffic it is written for is on one, so without this a reader is almost
   never within reach of an ask.

   ITS HEIGHT IS A CONSTANT BECAUSE THE CONTROL'S HEIGHT IS FORCED. .pill--sm
   floors at 14px on a 1.3 line box with 10px of padding, which is a 38px
   control — under the 44px minimum target and 6px short of what the footer
   reserves below. `min-height` on the two children makes 44 true at every
   width, so --sticky-h stays true: 44 + 2 x 10 + the 1px border. */
.stickybar { display: none; }

@media (max-width: 760px) {
  .stickybar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px var(--edge);
    /* env() resolves to 0 under the default viewport-fit, so this is a no-op
       today and the correct value the moment anyone adds viewport-fit=cover.
       Deliberately NOT adding that: it would also let the bands run under the
       notch in landscape, which would mean a max() on the inline padding of
       every section on the page to buy a strip of cream behind a home
       indicator. */
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    background: var(--cream);
    border-top: 1px solid var(--hair);
  }

  .stickybar__go,
  .stickybar__alt {
    display: grid;
    place-items: center;
    min-height: 44px;
    white-space: nowrap;
  }

  .stickybar__go { flex: 1 1 auto; }

  .stickybar__alt {
    flex: 0 0 auto;
    padding-inline: 6px;
    color: var(--ink);
    font-size: clamp(14px, 1.05vw, 16px);
    text-decoration: underline;
    text-underline-offset: 4px;
  }

  /* The bar is fixed, so the last thing on the page has to reserve room for it
     or the copyright line sits underneath it forever. The reservation goes on
     the FOOTER rather than on body, because body's ground is cream and a
     reservation there would draw a cream strip below the ink. */
  .foot {
    padding-bottom: calc(clamp(40px, 4.4vw, 64px) + var(--sticky-h) + env(safe-area-inset-bottom, 0px));
  }
}

/* ── Responsive ──────────────────────────────────────────────────────────
   Everything past this point is a breakpoint. The plans grid is the exception
   that runs the other way: it is written mobile-first above, so its desktop
   row is a min-width query rather than a reset. */

/* The plan row, and the only place `order` appears on this page. Restoring the
   conventional Landing / Full Site / Custom reading order here is safe because
   at this width the row IS horizontal, which is the only arrangement where the
   centre position carries the preference the middle card is trading on. Below
   this the DOM order stands, so what is seen and what is tabbed agree.

   DO NOT EXTEND THIS QUERY DOWNWARD. The moment the grid stacks, `order` puts
   the recommended card in the middle of the tab sequence while the eye still
   reads it first. */
@media (min-width: 1000px) {
  .plans__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    /* A SUM, NOT A CHOICE: the 22px is the featured card's lift and the clamp
       is the real gap under the heading. With the lift alone the raised card
       sat against the heading and read as touching it. */
    padding-top: 22px;
  }

  .plan--landing { order: 1; }
  .plan--pick    { order: 2; }
  .plan--custom  { order: 3; }

  /* Grows upward rather than floating. See the note on .plan: with no
     percentage height, `align-items: stretch` keeps the bottom edge level and
     spends the whole 22px on the top, so the card is taller AND all three
     buttons still land on one baseline. */
  .plan--pick { margin-top: -22px; }

  .faq__wrap {
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    gap: clamp(40px, 5vw, 80px);
    align-items: start;
  }

  .faq__art {
    width: 100%;
    margin-top: clamp(24px, 2.6vw, 36px);
  }
}

/* One column for the two-up cards. 860 is the width .gets__grid already breaks
   at, and matching it means the page has one place where its card rows fold
   rather than three. */
@media (max-width: 860px) {
  .how__list,
  .social__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .monthly__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The sample tiles hold last, because three screenshots side by side still
   read at tablet width where three columns of prose would not. */
@media (max-width: 700px) {
  .samples__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(24px, 4vw, 34px);
  }
}

/* The plans heading's mark drops out below this. It is decoration beside a
   heading, and at a phone's width it takes a third of the line the heading
   needs. Removed rather than shrunk: a 40px version of it is a smudge. */
@media (max-width: 560px) {
  .plans__mark,
  .monthly__mark { display: none; }
}
