/* ==========================================================================
   landing.css  —  KidSwaps landing pages  —  v2, S270
   Supersedes v1 @cdb9518 entirely. Rebuilt for the two-column editorial
   layout after v1's single-column version was judged too plain.

   Page-linked from each landing page's HEAD box. Never Site Settings.
   Its behaviour half is landing.js in the Before </body> box, on the SAME SHA.
   TWO PIN FIELDS. EDIT BOTH, EVERY TIME.

   Palette, hers S249. Nothing outside this list appears in this file.
     coral  #E54F25   yellow #EDA920   green #309359   navy #1C4A91
     pink   #F491A9   ink    #1E1A19   cream #EDECE0
   NAVY IS DELIBERATELY UNUSED. Her ruling: no filled masthead, top or bottom.

   INK IS ONE TOKEN, --landing-ink, set to #1E1A19, the site-wide value in
   header.css. Her S249 list names #211B1A and that is STILL UNRULED. One line
   to change. DO NOT introduce a third value.
   ========================================================================== */

:root {
  --landing-ink: #1E1A19;
  --landing-cream: #EDECE0;
  --landing-coral: #E54F25;
  --landing-amber: #EDA920;
  --landing-pink: #F491A9;
  --landing-muted: #75736E;
  --landing-hairline: #C9C7BC;
  --landing-placeholder: #CCCAC5;
}

/* --------------------------------------------------------------------------
   WRAP AND CARD
   The card is 1010 rather than the 1400 interior measure /faq uses, and that
   is deliberate: 1400 with a 660 reading column left ~700px of empty cream on
   the right, which is the fault this rebuild exists to fix. The column
   arithmetic is exact — 290 + 60 gap + 660 = 1010.
   width PLUS max-width, never margin:auto alone: auto margins with no width
   give the card the whole viewport below 1010 and put it against both edges.
   -------------------------------------------------------------------------- */

.landing-wrap {
  background-color: var(--landing-cream);
  padding: 56px 0 96px;
}

.landing-card {
  position: relative;
  width: calc(100% - 56px);
  max-width: 1010px;
  margin-left: auto;
  margin-right: auto;
}

/* --------------------------------------------------------------------------
   TITLE AND LEDE
   The title sits at the card's left edge. The lede runs wide beneath it and
   is set LARGER than body copy — that is what makes it read as an opening
   rather than an orphaned first paragraph, and it fills the space that sat
   empty when the lede was indented to the body column.
   Both are STATIC. They are above the fold on desktop, so animating them
   would either fire before anyone scrolls or flash empty on first paint.
   -------------------------------------------------------------------------- */

.landing-head {
  position: relative;
  padding-top: 8px;
}

.landing-eyebrow {
  margin: 0;
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--landing-muted);
}

.landing-masthead-heading,
.landing-head .landing-masthead-heading {
  margin: 14px 0 0;
  max-width: 70%;
  font-family: "Instrument Serif", Georgia, serif;
  font-style: normal;
  font-weight: 400;
  font-size: 56px;
  line-height: 1.06;
  letter-spacing: -0.01em;
  text-align: left;
  color: var(--landing-ink);
}

.landing-lede,
.landing-lede p {
  margin: 26px 0 0;
  max-width: 760px;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 20px;
  line-height: 1.7;
  color: var(--landing-ink);
}

/* --------------------------------------------------------------------------
   THE STAR
   A DIV, never an image, filled by clip-path with the pink placeholder — the
   same pattern as the two hero stars and the closet-standard star.
   WHEN HER PNG LANDS IT IS ONE PROPERTY SWAP ON THIS SAME ELEMENT: drop
   background-color and clip-path, add background-image, background-size
   contain, background-repeat no-repeat. NO DESIGNER WORK.

   THE SPIN IS AN INLINE `rotate:` WRITTEN BY landing.js ON SCROLL.
   There is deliberately NO rotate rule in this file — a stylesheet rule would
   lose to the inline value silently. And it is `rotate:` rather than
   `transform: rotate()`, which is what positions the hero stars.
   -------------------------------------------------------------------------- */

.landing-star {
  position: absolute;
  right: 0;
  top: 0;
  width: 88px;
  height: 88px;
  z-index: 2;
  pointer-events: none;
  background-color: var(--landing-pink);
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

/* --------------------------------------------------------------------------
   SECTIONS
   ONE SHAPE, REPEATED. Heading column left, everything else right. An image
   is a block INSIDE the right column, never a third column — a three-column
   row leaves the text around 380px, which is below the readable band. Two
   columns give it ~660 on every section whether it carries a photo or not.
   That sameness is what lets this template survive ten pages.
   -------------------------------------------------------------------------- */

.landing-section {
  display: grid;
  grid-template-columns: 290px 1fr;
  gap: 60px;
  align-items: start;
  margin-top: 46px;
  padding-top: 46px;
  border-top: 1px solid var(--landing-hairline);
}

.landing-section-heading,
.landing-section .landing-section-heading {
  margin: 0;
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 30px;
  line-height: 1.16;
  color: var(--landing-ink);
}

/* The amber rule as an ::after on the heading rather than its own element —
   one thing to place, and it cannot get orphaned by a copy edit. Same device
   as the browse filter headings S266, and it works for the same reason: a
   rule is a MARK, not text, so it carries no contrast obligation. Green and
   coral were both tried on that surface and rejected on the render.
   DO NOT RE-COLOUR THIS. */

.landing-section-heading::after {
  content: "";
  display: block;
  width: 32px;
  height: 3px;
  margin-top: 14px;
  background-color: var(--landing-amber);
}

.landing-section-body > *:first-child {
  margin-top: 0;
}

.landing-section-body p {
  margin: 0 0 1.1em;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 16px;
  line-height: 1.7;
  color: var(--landing-ink);
}

.landing-section-body p:last-child {
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   IMAGE
   A DIV with a placeholder fill, so the page is complete before any photo
   exists. SWAPPING IN A PHOTO IS ONE PROPERTY: drop background-color, add
   background-image. aspect-ratio rather than a fixed height, so it scales
   with the column at every width and needs no breakpoint of its own.
   -------------------------------------------------------------------------- */

.landing-image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  margin: 26px 0;
  border-radius: 10px;
  background-color: var(--landing-placeholder);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.landing-image.is-tall {
  aspect-ratio: 1 / 1;
}

/* --------------------------------------------------------------------------
   PULL QUOTE
   Rule down the left edge, from her second reference. Amber, matching the
   heading rule, so the page carries one accent rather than two.
   -------------------------------------------------------------------------- */

.landing-quote,
.landing-quote p {
  margin: 28px 0 0;
  padding-left: 20px;
  border-left: 3px solid var(--landing-amber);
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 24px;
  line-height: 1.35;
  color: var(--landing-ink);
}

/* --------------------------------------------------------------------------
   BUTTONS
   Coral primary, outlined ink secondary. Coral does six jobs site-wide as of
   her S264 ruling — knowing, not drift.
   -------------------------------------------------------------------------- */

.landing-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 32px 0 0;
}

.landing-cta-primary,
.landing-cta-row .landing-cta-primary {
  display: inline-block;
  padding: 15px 32px;
  border: 1px solid var(--landing-coral);
  border-radius: 50px;
  background-color: var(--landing-coral);
  color: var(--landing-cream);
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
  text-align: center;
  text-decoration: none;
}

.landing-cta-secondary,
.landing-cta-row .landing-cta-secondary {
  display: inline-block;
  padding: 15px 32px;
  border: 1px solid var(--landing-ink);
  border-radius: 50px;
  background-color: transparent;
  color: var(--landing-ink);
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
  text-align: center;
  text-decoration: none;
}

.landing-cta-primary:hover,
.landing-cta-row .landing-cta-primary:hover {
  background-color: #B23D22;
  border-color: #B23D22;
}

.landing-cta-secondary:hover,
.landing-cta-row .landing-cta-secondary:hover {
  background-color: var(--landing-ink);
  color: var(--landing-cream);
}

/* ==========================================================================
   MOTION
   HER S224 RULING, AND THE WHOLE DESIGN OF THIS BLOCK: NOTHING IS HIDDEN BY
   CSS ALONE. The how-it-works entrance hid four steps and revealed them on an
   observer, and when the observer did not fire the section rendered
   PERMANENTLY BLANK on the live page.

   So every hiding rule is scoped under html.landing-motion, a class landing.js
   sets as its FIRST act. Script never arrives, no flag, no hiding, page renders
   exactly as it does with no JavaScript at all.

   AND IT IS A KEYFRAME ANIMATION, NEVER A TRANSITION — S247, Claude's own
   regression. A transition only runs if the browser painted the start state
   first, and on a warm cache both states collapse into one frame: nothing
   animates and every gate passes. An animation makes no such bet.

   `both` fill is load-bearing: it holds the start state through any delay and
   the end state after, so nothing snaps back.

   The whole block sits inside prefers-reduced-motion: no-preference, so a
   reduced-motion reader never receives the hiding rule at all.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

  html.landing-motion .landing-section {
    opacity: 0;
  }

  html.landing-motion .landing-section.is-in {
    animation: landing-rise 0.5s cubic-bezier(.4, 0, .2, 1) both;
  }

}

@keyframes landing-rise {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ==========================================================================
   991 — tablet
   Two columns survive here on a narrower left rail: 240 + 44 + text still
   leaves the reading column above the readable floor at this width.
   ========================================================================== */

@media (max-width: 991px) {

  .landing-wrap {
    padding: 44px 0 76px;
  }

  .landing-masthead-heading,
  .landing-head .landing-masthead-heading {
    max-width: 88%;
    font-size: 46px;
  }

  .landing-lede,
  .landing-lede p {
    font-size: 19px;
  }

  .landing-star {
    width: 70px;
    height: 70px;
  }

  .landing-section {
    grid-template-columns: 240px 1fr;
    gap: 44px;
    margin-top: 40px;
    padding-top: 40px;
  }

  .landing-section-heading,
  .landing-section .landing-section-heading {
    font-size: 27px;
  }

}

/* ==========================================================================
   767 — phone
   ONE COLUMN. The heading sits above its own content, which is why this
   layout needs no rearranging on a phone — the grid collapses and the reading
   order is already right.
   Spacing is deliberately tighter than a desktop-scaled version would be: on
   a narrow column the same gaps read as gaps rather than as rhythm.
   ========================================================================== */

@media (max-width: 767px) {

  .landing-wrap {
    padding: 34px 0 60px;
  }

  .landing-card {
    width: calc(100% - 40px);
  }

  .landing-masthead-heading,
  .landing-head .landing-masthead-heading {
    max-width: 86%;
    font-size: 38px;
  }

  .landing-lede,
  .landing-lede p {
    margin-top: 18px;
    font-size: 17px;
  }

  .landing-star {
    width: 52px;
    height: 52px;
  }

  .landing-section {
    grid-template-columns: 1fr;
    gap: 14px;
    margin-top: 28px;
    padding-top: 26px;
  }

  .landing-section-heading,
  .landing-section .landing-section-heading {
    font-size: 25px;
  }

  .landing-section-heading::after {
    margin-top: 12px;
  }

  .landing-image {
    margin: 20px 0;
  }

  .landing-quote,
  .landing-quote p {
    margin-top: 22px;
    padding-left: 16px;
    font-size: 20px;
  }

  .landing-cta-row {
    display: block;
    margin-top: 26px;
  }

  .landing-cta-primary,
  .landing-cta-row .landing-cta-primary,
  .landing-cta-secondary,
  .landing-cta-row .landing-cta-secondary {
    display: block;
    width: 100%;
  }

  .landing-cta-secondary,
  .landing-cta-row .landing-cta-secondary {
    margin-top: 10px;
  }

}

/* ==========================================================================
   479 — small phone
   Webflow has four breakpoints and this file speaks at all four. home.css
   speaks at three and leaves below-479 to Webflow's own rules; on a page that
   is almost entirely type, the smallest phone is worth writing.
   ========================================================================== */

@media (max-width: 479px) {

  .landing-card {
    width: calc(100% - 32px);
  }

  .landing-masthead-heading,
  .landing-head .landing-masthead-heading {
    max-width: 100%;
    font-size: 34px;
  }

  .landing-eyebrow {
    font-size: 12px;
  }

  .landing-star {
    width: 44px;
    height: 44px;
  }

  .landing-section-heading,
  .landing-section .landing-section-heading {
    font-size: 23px;
  }

  .landing-quote,
  .landing-quote p {
    font-size: 19px;
  }

}


/* ==========================================================================
   ACCORDION  —  ADDED v3, S272
   Everything below this line is new. ROLLBACK IS DELETING FROM THIS COMMENT
   TO THE END OF THE FILE — nothing above it was edited, which is why append
   beat patching in place. Verified before shipping: the file ended at top
   level (depth 0, braces 56/56 comments-stripped), so these rules are NOT
   trapped inside the 479 block.

   THE COLLAPSE IS ARMED BY html.landing-ready, WHICH IS A DIFFERENT FLAG FROM
   html.landing-motion, AND THE DIFFERENCE IS LOAD-BEARING. landing-motion is
   only set when the reader has NOT asked for reduced motion. Arm the collapse
   off that flag and a reduced-motion reader gets rows that cannot open — the
   S224 failure in a new coat. landing-ready is set whenever the script runs
   at all, so: no script, no flag, every answer simply sits open and the page
   is a long readable document. BEHAVIOUR IS NOT MOTION.

   THE HEIGHT CHANGE IS A TRANSITION, NOT A KEYFRAME, AND THAT IS DELIBERATE.
   S247's rule is about ENTRANCES, which must fire on a page that may not have
   painted yet. This fires on a click, on a page that is demonstrably painted,
   which is exactly the case a transition is for.
   ========================================================================== */

.landing-q-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.landing-q {
  border-bottom: 1px solid var(--landing-hairline);
  padding-bottom: 16px;
  margin-bottom: 16px;
}

.landing-q:last-child {
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 0;
}

/* THE WHOLE ROW IS THE TAP TARGET, NOT THE WORDS. 44px is the floor she asked
   for on the header drawer; it is cheaper to build it in here than to be told
   about it later. */

.landing-q-toggle {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  min-height: 44px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.landing-question {
  margin: 0;
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 17px;
  line-height: 1.35;
  color: var(--landing-ink);
}

/* THE CHEVRON IS DRAWN, NOT A GLYPH — a character depends on whichever font
   arrives and sits off the optical centre. Two borders rotated 45deg, so it
   costs no asset and cannot 404. */

.landing-chevron {
  flex: none;
  width: 9px;
  height: 9px;
  margin-top: 6px;
  border-right: 2px solid #8a867e;
  border-bottom: 2px solid #8a867e;
  transform: rotate(45deg);
  transform-origin: 60% 60%;
  transition: transform 0.22s cubic-bezier(.4, 0, .2, 1);
}

.landing-q.is-open .landing-chevron {
  transform: rotate(225deg);
}

/* OPEN AND CLOSED HAVE TO BE TELLABLE APART AT A GLANCE — hers. Three signals
   move together rather than one: the chevron turns, the teaser goes from
   muted to full ink, and the amber rule appears down the left of the answer.
   NOT OPACITY ON TEXT — opacity multiplies against whatever is behind it and
   drifts between the cream card and any future tinted block. A stated colour
   does not. */

.landing-teaser,
.landing-section-body .landing-teaser {
  margin: 6px 0 0;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 16px;
  line-height: 1.6;
  color: var(--landing-muted);
  transition: color 0.22s ease;
}

.landing-q.is-open .landing-teaser,
.landing-section-body .landing-q.is-open .landing-teaser {
  color: var(--landing-ink);
}

/* ⚠⚠⚠ THE 0fr COLLAPSE, AND THE RULE IT OBEYS COST /old-home THREE VERSIONS:
   AN fr TRACK IS minmax(auto, flex), SO 0fr FLOORS AT THE ITEM'S MINIMUM
   CONTRIBUTION. min-height:0 takes the CONTENT minimum to zero and CANNOT
   TOUCH PADDING, MARGIN OR A HORIZONTAL BORDER — every one of those is
   unshrinkable and leaves a visible window, because overflow:hidden clips at
   the PADDING box, not the content box.

   SO .landing-answer CARRIES NO margin, NO padding-top, NO padding-bottom AND
   NO border-top/bottom. Its left padding and left border are horizontal and
   contribute nothing to a row track, so those are safe. All vertical spacing
   lives INSIDE the item, where the clip can eat it. */

.landing-answer-wrap {
  display: grid;
  grid-template-rows: 1fr;
}

html.landing-ready .landing-answer-wrap {
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows 0.3s cubic-bezier(.4, 0, .2, 1);
}

html.landing-ready .landing-q.is-open .landing-answer-wrap {
  grid-template-rows: 1fr;
}

.landing-answer {
  min-height: 0;
  margin: 0;
  padding: 0 0 0 16px;
  border-left: 2px solid var(--landing-amber);
}

.landing-answer > *:first-child {
  margin-top: 13px;
}

.landing-answer::after {
  content: "";
  display: block;
  height: 4px;
}

.landing-answer p {
  margin: 0 0 1.1em;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 15.5px;
  line-height: 1.68;
  color: var(--landing-muted);
}

.landing-answer p:last-child {
  margin-bottom: 0;
}

.landing-answer strong {
  font-weight: 600;
  color: var(--landing-ink);
}

@media (prefers-reduced-motion: reduce) {

  .landing-chevron,
  .landing-teaser,
  html.landing-ready .landing-answer-wrap {
    transition: none;
  }

}

/* --------------------------------------------------------------------------
   FIGURES
   Three facts under the masthead. A dot rather than a divider, so a fourth or
   a shorter third needs no arithmetic.
   -------------------------------------------------------------------------- */

.landing-figures {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 30px;
  margin-top: 26px;
}

.landing-figure {
  position: relative;
  padding-left: 16px;
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
  color: var(--landing-muted);
}

.landing-figure::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: var(--landing-amber);
}

/* --------------------------------------------------------------------------
   PHOTO EXAMPLES
   Photo whole, coloured rule beneath it, verdict and caption below — hers,
   chosen over a hover overlay, because hover does not exist on a phone.
   GREY DIVS UNTIL HER PHOTOS LAND, and the swap is one property: drop
   background-color, add background-image / size:cover.
   ⚠ THE RULE COLOUR IS THE ONLY THING SAYING ACCEPTED OR DECLINED IN COLOUR,
   AND THE CAPTION SAYS IT IN WORDS DIRECTLY UNDERNEATH. Never let the colour
   carry it alone.
   -------------------------------------------------------------------------- */

.landing-photos {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 18px 0 0;
}

.landing-photo {
  aspect-ratio: 1 / 1;
  border-radius: 6px;
  background-color: var(--landing-placeholder, #CCCAC5);
  background-size: cover;
  background-position: center;
}

.landing-photo-rule {
  width: 22px;
  height: 3px;
  border-radius: 2px;
  margin-top: 8px;
  background-color: var(--landing-muted);
}

.landing-photo-rule.is-accepted {
  background-color: #309359;
}

.landing-photo-rule.is-declined {
  background-color: #E54F25;
}

.landing-photo-caption,
.landing-answer .landing-photo-caption {
  margin: 6px 0 0;
  font-family: Quicksand, sans-serif;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--landing-muted);
}

.landing-photo-caption b {
  display: block;
  font-weight: 600;
  color: var(--landing-ink);
}

/* --------------------------------------------------------------------------
   NOTE BOX
   BORDERED, NEVER TINTED — hers. A tint would be a sixth surface colour on a
   page that has cream and nothing else.
   -------------------------------------------------------------------------- */

.landing-note-box {
  border: 1px solid var(--landing-ink);
  border-radius: 6px;
  padding: 16px 18px;
  margin-top: 26px;
}

.landing-note-box p,
.landing-section-body .landing-note-box p {
  margin: 0;
  font-family: Quicksand, sans-serif;
  font-size: 15px;
  line-height: 1.62;
  color: var(--landing-ink);
}

/* ==========================================================================
   THE CLOSET STANDARD — PAGE-SCOPED
   ⚠⚠⚠ EVERY RULE HERE IS WRITTEN AT TWO CLASSES, .landing-wrap.standard-page,
   FOR THE SAME REASON /faq's RULES ARE WRITTEN .faq-section.faq-page: it beats
   the shared rule AND IT CANNOT MATCH ON ANOTHER LANDING PAGE. Add the combo
   class in the Designer and leave it unstyled there.
   A MEDIA QUERY ADDS NO SPECIFICITY, so every breakpoint rule needs its own
   guarded twin. These sit AFTER the shared 991/767/479 blocks on purpose.
   ========================================================================== */

@media (max-width: 991px) {

  /* COLLAPSES AT 991, NOT 767. The shared template holds two columns down to
     767 and drops the reading column to 471px in this band — already logged
     as an open fault on the Bay Area page. These questions are longer, so it
     bites harder here. */

  .landing-wrap.standard-page .landing-section {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }

  .landing-wrap.standard-page .landing-section-heading,
  .landing-wrap.standard-page .landing-section .landing-section-heading {
    margin-bottom: 4px;
  }

}

@media (max-width: 767px) {

  .landing-wrap.standard-page .landing-question {
    font-size: 16px;
  }

  .landing-wrap.standard-page .landing-teaser,
  .landing-wrap.standard-page .landing-section-body .landing-teaser {
    font-size: 14.5px;
  }

  /* 2x2, NOT 4 ACROSS. Four across a phone column is roughly 82px a photo,
     which is too small to see the pilling these photos exist to show.
     Accepted on the top row, declined on the bottom, so it reads as a
     comparison rather than a sequence. */

  .landing-wrap.standard-page .landing-photos {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
  }

  .landing-wrap.standard-page .landing-figures {
    gap: 8px 0;
    flex-direction: column;
  }

}

/* =====================================================================
   v4 — S274. /the-closet-standard bottom block + accordion polish.
   Appended at TOP LEVEL, after the mobile blocks. A media query adds no
   specificity, so every rule here that has a mobile twin is restated in
   the 767 block at the foot of this section, or it wins at every width.
   ROLLBACK: delete from this comment to the end of the file.
   ===================================================================== */

/* --- NOTE BOX, option B: amber bar, no border. -----------------------
   Her S272 note said "bordered, not tinted". Nothing here is tinted; the
   border is replaced by the amber rule already used on open answers and
   under every section heading. HER CALL S274 — do not restore the border.
   landing-note-eyebrow / -heading / -body are Webflow TEXT BLOCKS, i.e.
   DIVS, so the existing ".landing-note-box p" rule never reached them.
   That is why all three lines rendered identically. */
.landing-note-box {
  border: 0;
  border-left: 3px solid var(--landing-amber);
  border-radius: 0;
  padding: 4px 0 4px 20px;
}
.landing-note-eyebrow {
  margin: 0 0 10px;
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--landing-amber);
}
.landing-note-heading {
  margin: 0 0 10px;
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 17px;
  line-height: 1.35;
  color: var(--landing-ink);
}
.landing-note-body {
  margin: 0 0 8px;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 15px;
  line-height: 1.62;
  color: var(--landing-ink);
}
.landing-note-box p,
.landing-section-body .landing-note-box p { margin: 0 0 8px; }
.landing-note-box p:last-child,
.landing-section-body .landing-note-box p:last-child { margin-bottom: 0; }

/* --- CLOSE, option 1: line on its own, buttons beneath, both left. ---
   The row was display:flex, so the paragraph was a flex item sitting in
   the same line as the buttons. It is now a block, with the two links
   wrapped in .landing-cta-btns. */
.landing-cta-row { display: block; margin-top: 34px; }
.landing-cta-row > p {
  margin: 0 0 16px;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 15px;
  line-height: 1.6;
  color: var(--landing-muted);
}
.landing-cta-btns { display: flex; flex-wrap: wrap; gap: 12px; }

/* --- CHEVRON: bolder and darker, hers. ------------------------------
   margin-top:0 pairs with align-items:center below; the old 6px existed
   to line it up against flex-start. */
.landing-chevron {
  width: 10px;
  height: 10px;
  margin-top: 0;
  border-right: 2.5px solid var(--landing-ink);
  border-bottom: 2.5px solid var(--landing-ink);
}

/* --- THE QUESTION-TO-TEASER GAP. ------------------------------------
   NOT padding. The toggle is min-height:44px with align-items:flex-start,
   so a ~22px void sat under the question. 44px IS THE PHONE TAP TARGET
   AND MUST NOT BE REDUCED — centring splits the slack above and below
   instead of dumping it all underneath. */
.landing-q-toggle { align-items: center; }

/* --- SECTION INTRO LINE. --------------------------------------------
   .landing-teaser does two jobs: the per-question teaser, and the intro
   under a section label ("What you send, is what you get."). The child
   combinator hits the intro ONLY. Do not loosen it to .landing-teaser. */
.landing-section-body > .landing-teaser { margin: 0 0 18px; }

/* --- MOBILE TWINS. Required, see the header note. -------------------- */
@media (max-width: 767px) {
  .landing-cta-row { margin-top: 26px; }
  .landing-cta-btns { display: block; }
}

/* =====================================================================
   v5 — S274. Note box to navy, separated from the section above, and the
   photo cells made safe for real images.
   ROLLBACK: delete from this comment to the end of the file.
   ===================================================================== */

/* --- NOTE BOX BAR: amber -> NAVY. HER RULING S274. -------------------
   Amber already does three jobs on this page (section rules, figure dots,
   the open-answer bar), which is why the box did not stand apart. Navy
   #1C4A91 is the one value in her seven with NO other job here, so it
   cannot be misread. Coral was available and rejected: it is the action
   colour and already carries six jobs. NOT a variable — navy has no
   token in :root, and adding one is a wider decision than this commit. */
.landing-note-box { border-left-color: #1C4A91; }
.landing-note-eyebrow { color: #1C4A91; }

/* --- SEPARATION FROM THE SECTION ABOVE. -----------------------------
   The box sat directly under the last question and read as part of that
   answer rather than as a standing instruction. Hairline is the SAME
   #C9C7BC already used between sections, so the page gains space, not a
   new device. The ::before spans from the bar's left edge outward. */
.landing-note-box { position: relative; margin-top: 52px; }
.landing-note-box::before {
  content: "";
  position: absolute;
  top: -26px;
  left: -3px;
  right: 0;
  height: 1px;
  background-color: var(--landing-hairline);
}

/* --- PHOTO CELLS: equal heights, and safe for real photos. -----------
   .landing-image already carries aspect-ratio 4/3, so the four images are
   locked to one height whatever the caption does. TWO THINGS WERE WRONG.
   (1) It also carries margin:26px 0, written for a standalone image in an
   answer, which was padding every cell from the inside.
   (2) The rule was written for a background-image DIV (background-size:
   cover). We built real <img> elements, and an <img> at width:100% with a
   forced aspect-ratio DISTORTS without object-fit. Nobody would have seen
   that until her photos landed, because a placeholder has no subject. */
.landing-photo .landing-image {
  margin: 0;
  height: auto;
  object-fit: cover;
  object-position: center;
}

/* --- MOBILE TWINS. The 767 block sets .landing-image margin:20px 0, and
   an appended bare rule beats a media query at equal specificity, so the
   scoped rule above already wins at every width. Restated for clarity
   only; the separation shrinks on a phone. -------------------------- */
@media (max-width: 767px) {
  .landing-note-box { margin-top: 40px; }
  .landing-note-box::before { top: -20px; }
  .landing-photo .landing-image { margin: 0; }
}

/* =====================================================================
   v6 — S274. Teaser tightened to the question, answer indented, and the
   amber line moved so it starts at the answer rather than at the question.
   ROLLBACK: delete from this comment to the end of the file.
   ===================================================================== */

/* --- TEASER CLOSER TO THE QUESTION, HERS. ---------------------------
   v4 centred the toggle so the 44px slack split above and below instead
   of dumping it all underneath. She wants it tighter still, and the only
   honest way is to drop the min-height — which is the TOUCH TARGET, so it
   goes on DESKTOP ONLY and the phone keeps its 44px below. A mouse does
   not need a 44px target; a thumb does. DO NOT make this bare. */
.landing-q-toggle { min-height: 0; }

/* --- ANSWER INDENTED, AND THE LINE STARTS AT THE ANSWER. ------------
   ⚠⚠⚠ THE LINE CANNOT BE MOVED WITH margin-top OR padding-top.
   .landing-answer is the grid item inside .landing-answer-wrap, which
   collapses to grid-template-rows:0fr. An fr track floors at the item's
   minimum contribution, and vertical margin AND padding are both
   unshrinkable — either one would leak that many pixels of open answer
   on every CLOSED row. That is the /old-home v43 fault exactly, and it
   is why this file already carries margin:0 with the spacing done as a
   first-child margin and an ::after the clip can eat.
   SO THE LINE BECOMES A BACKGROUND, WHICH CONTRIBUTES NO LAYOUT AT ALL.
   17px = the 13px first-child margin plus the 4px ::after.
   margin-LEFT is safe: the track is rows, so horizontal margin cannot
   floor it. */
.landing-answer {
  margin-left: 14px;
  border-left: 0;
  background-image: linear-gradient(var(--landing-amber), var(--landing-amber));
  background-repeat: no-repeat;
  background-size: 2px calc(100% - 17px);
  background-position: 0 13px;
}

/* --- MOBILE TWINS. An appended bare rule beats a media query at equal
   specificity, so the touch target is restored here, after it. -------- */
@media (max-width: 767px) {
  .landing-q-toggle { min-height: 44px; }
  .landing-answer { margin-left: 8px; }
}


/* =====================================================================
   v7 — S277. /how-it-works: the sub line, the cycle, the four beats,
   the CTA heading and its small print.
   ROLLBACK: delete from this comment to the end of the file.

   ⚠⚠⚠ THE CYCLE AND THE BEATS ARE `.landing-section` ELEMENTS WEARING A
   COMBO CLASS, AND THAT IS LOAD-BEARING, NOT TIDINESS. landing.js
   observes `.landing-section` AND NOTHING ELSE — read at the SHA — so a
   new block hidden at opacity:0 under any other class would never be
   revealed and would render PERMANENTLY BLANK on a live page. That is
   the /old-home S224 fault. Wearing the class inherits the observer,
   the entrance, the top hairline and the spacing, and cannot fail open.

   ⚠⚠ EVERY COMBO RULE HERE IS (0,2,0) AND THIS FILE ENDS *AFTER* ITS
   991/767/479 BLOCKS, so an appended combo beats a media query at equal
   specificity by source order and would win at every width. Every rule
   below that needs a mobile value restates it in its own @media block
   at the foot. ADD A RULE UP TOP, ADD ITS TWIN.

   ⚠ GREEN #309359 AND NAVY #1C4A91 ARE WRITTEN AS LITERALS. Neither has
   a :root variable — the same reason the note box writes navy twice
   (S274). Do not invent tokens for them here.

   ⚠⚠ THE HUB EYEBROW IS GONE — HER RULING S277. "And round again" read
   as a title for "The closet keeps rotating" rather than as the last
   beat of the sequence. The ring being a ring already says the loop.
   The phone rail lost its closing line with it, knowingly. There is
   deliberately NO .landing-ring-eyebrow rule; the element was deleted.

   ⚠⚠⚠ REVISED S278, IN PLACE, NOT STACKED AS A v8 — the same choice v7
   itself made across its four commits. Two changes: the ring's NUMBER
   and DOT swapped pseudos so every number sits in front of its label on
   one line, and the eyebrow went coral on this page only. Nothing was
   appended, so v6 is still a byte-exact prefix of this file and the
   rollback above is still "delete from this comment to the end".
   ===================================================================== */

/* ⚠⚠ THE EYEBROW IS CORAL ON /how-it-works AND NOWHERE ELSE — HER
   RULING S278. Written at THREE classes so it beats the bare
   .landing-eyebrow rule at the top of this file AND cannot reach the
   closet standard or the Bay Area page, whose eyebrows stay muted grey.
   The combo class goes on .landing-wrap in the Designer and is
   DELIBERATELY LEFT UNSTYLED THERE — the same device as
   .landing-wrap.standard-page and /faq's .faq-section.faq-page.
   ⚠⚠ SHE TOOK THE LEGIBILITY COST KNOWINGLY AND IN WRITING. Coral
   #E54F25 on this cream measures 3.23:1 where the muted grey it
   replaces measures 3.99, and at 13px BOTH are under the 4.5 bar, so
   contrast never separated them. HER WORDS: "i dont mind if its harder
   to read its decoration." DO NOT DARKEN IT, DO NOT SWAP IT BACK, AND
   DO NOT RAISE THE MEASUREMENT AGAIN.
   ⚠ COLOUR-ONLY IS SAFE HERE because the line is a label repeating the
   four beats named directly beneath it; it carries no fact of its own.
   ⚠ Coral is ALSO the travelling dot on this page's ring, so this page
   now carries coral twice. Flagged to her before she ruled. */
.landing-wrap.how-it-works-page .landing-eyebrow {
  color: var(--landing-coral);
}

.landing-sub,
.landing-head .landing-sub {
  margin: 10px 0 0;
  max-width: 62ch;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 18px;
  line-height: 1.5;
  color: var(--landing-ink);
}

/* =====================================================================
   THE CYCLE — ring above 767, vertical rail at 767 and below.
   HER RULING: dots on BOTH shapes, numbers on both.
   ===================================================================== */

.landing-section.landing-cycle {
  display: block;
}

.landing-ring {
  position: relative;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 1 / 1;
  margin: 8px auto 0;
}

/* ⚠⚠ THE CIRCLE IS inset:12% AND EVERY BEAT SITS AT A RADIUS OF 38%
   (50 − 12) OF THE BOX. Those two numbers are ONE fact expressed twice:
   move the inset and every --x/--y below is wrong by the difference,
   with nothing erroring. The percentages are cos/sin of the six angles
   at that radius — 50 ± 38·cos, 50 ± 38·sin — not values picked by eye.
   CHANGE THE INSET, RECOMPUTE THE SIX. */
/* ⚠⚠⚠ THIS RULE NO LONGER DRAWS THE DESKTOP CIRCLE AND IT MUST NOT BE
   DELETED. S279 gave the ring to an SVG, so this is display:none above
   767 — but AT 767 AND BELOW IT IS THE RAIL'S VERTICAL LINE, restyled
   in the mobile block at the foot as a 1px bar. Delete it as dead and
   the phone rail loses its spine, phone only, nothing erroring.
   ⚠ THE inset:12% BELOW STILL GOVERNS: every beat percentage is derived
   from it AND the SVG's arcs are drawn at that same radius. */
.landing-ring::before {
  content: "";
  display: none;
  position: absolute;
  inset: 12%;
  border: 1px solid var(--landing-hairline);
  border-radius: 50%;
}

/* ⚠⚠⚠ THE DOT AND THE LABEL ARE PLACED INDEPENDENTLY. THIS REPLACES A
   PAIRED --dx/--dy SCHEME THAT FAILED TWICE, AND THE REASON IT FAILED
   IS WORTH KEEPING: it put the label on the circle and then pushed the
   DOT back by the inverse offset, so the two only agreed if every
   number stayed in step — and a percentage in a `translate` resolves
   against THE ELEMENT'S OWN BOX, not the ring, so they never did.
   Worse, `--dx: 0` with no unit made `calc(0 * -1)` invalid, which
   silently dropped the WHOLE transform including the centring, on the
   two beats that looked most wrong. A dropped transform reports
   nothing anywhere.
   ▶ NOW: the beat is anchored so its EDGE sits 20px clear of the
   circle, and the dot is placed 20px back from that same edge. One
   number, one direction, per beat. A wrong value moves one thing
   visibly instead of dropping a transform.

   ⚠ THE TWO RADII ARE COS/SIN AT THE SIX ANGLES, NOT VALUES PICKED BY
   EYE. The circle is inset:12%, so its radius is 38% of the box:
   38·cos and 38·sin at -90, -30, 30, 90, 150, 210. CHANGE THE INSET
   AND RECOMPUTE ALL SIX. */
.landing-ring-beat {
  position: absolute;
  font-family: "Instrument Serif", Georgia, serif;
  font-weight: 400;
  font-size: 20px;
  line-height: 1.1;
  color: var(--landing-ink);
  white-space: nowrap;
}

/* THE NUMBER. Drawn by CSS, so the six labels stay plain text and she
   can edit any of them without touching a span.

   ⚠⚠⚠ THE NUMBER IS ::before AND THE DOT IS ::after — SWAPPED S278,
   AND THE SWAP *IS* THE FIX. She asked for the number in front of the
   label on one line at all six positions. Only the pseudo that renders
   FIRST can sit in the text flow, and the dot was using it. Absolute
   positioning does not care which pseudo it is, so the dot's six
   placement rules moved across word for word and NOT ONE OFFSET WAS
   RETUNED — which is what went wrong twice before v7 landed.

   ⚠⚠ WHY IT COULD NOT BE FIXED BY MOVING THE NUMBER. v7 placed it on
   the side AWAY from the ring — above at twelve, below at six, outboard
   on the four sides — because inboard is where the dot is. On beats 2
   and 3 the dot sits to the LEFT of the label, exactly where the number
   had to go, so an absolute number moved inboard lands ON the dot. The
   old comment said so in one line and it was right.

   ⚠⚠ INLINE, NEVER ABSOLUTE. Give this rule position:absolute and the
   number leaves the text flow, the fix silently undoes itself, and the
   beat boxes shrink back under the dots' anchors.

   ⚠ IT WIDENS EVERY BEAT BOX by the number plus its margin. That is
   harmless BY CONSTRUCTION and not by luck: the right pair is anchored
   by its LEFT edge and the left pair by its RIGHT edge, so both grow
   away from the circle; twelve and six are centred, so the number and
   the label stay centred as ONE UNIT while the dot, at 50% of that box,
   stays on the ring's axis. */
.landing-ring-beat::before {
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 12px;
  line-height: 1;
  color: var(--landing-muted);
  margin-right: 8px;
}

/* TWELVE AND SIX — centred on the vertical axis, label clear of the
   circle by 20px on its own bottom or top edge. */
.landing-ring-beat.is-1 {
  left: 50%;
  top: calc(50% - 38% - 20px);
  transform: translate(-50%, -100%);
}
.landing-ring-beat.is-1::after {
  left: 50%; bottom: -20px; transform: translate(-50%, 50%);
}

.landing-ring-beat.is-4 {
  left: 50%;
  top: calc(50% + 38% + 20px);
  transform: translateX(-50%);
}
.landing-ring-beat.is-4::after {
  left: 50%; top: -20px; transform: translate(-50%, -50%);
}

/* THE RIGHT PAIR — anchored by their LEFT edge, so the text runs away
   from the ring however long the label is. That is why a long label
   like "We inspect and grade" cannot creep back over the circle. */
.landing-ring-beat.is-2,
.landing-ring-beat.is-3 {
  left: calc(50% + 32.909% + 20px);
  transform: translateY(-50%);
  text-align: left;
}
.landing-ring-beat.is-2 { top: calc(50% - 19%); }
.landing-ring-beat.is-3 { top: calc(50% + 19%); }
.landing-ring-beat.is-2::after,
.landing-ring-beat.is-3::after {
  left: -20px; top: 50%; transform: translate(-50%, -50%);
}

/* THE LEFT PAIR — anchored by their RIGHT edge, mirror of the above.
   ⚠ `right`, never `left`: with `left` the box grows rightward and a
   longer label would push its own text over the circle. */
.landing-ring-beat.is-5,
.landing-ring-beat.is-6 {
  right: calc(50% + 32.909% + 20px);
  transform: translateY(-50%);
  text-align: right;
}
.landing-ring-beat.is-5 { top: calc(50% + 19%); }
.landing-ring-beat.is-6 { top: calc(50% - 19%); }
.landing-ring-beat.is-5::after,
.landing-ring-beat.is-6::after {
  right: -20px; top: 50%; transform: translate(50%, -50%);
}

/* THE DOT ON THE CIRCLE — ::after as of S278, see the number above.
   Its six placement rules are the ones above, unchanged from v7.
   ⚠ content:"" LIVES HERE AND ONLY HERE. Every per-beat rule above sets
   position only, so lose this and all six dots vanish at once. */
.landing-ring-beat::after {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--landing-amber);
}

/* THE SIX NUMBERS. Content only — the type is on the base ::before rule
   above and the position is the text flow, which is the whole point. */
.landing-ring-beat.is-1::before { content: "1"; }
.landing-ring-beat.is-2::before { content: "2"; }
.landing-ring-beat.is-3::before { content: "3"; }
.landing-ring-beat.is-4::before { content: "4"; }
.landing-ring-beat.is-5::before { content: "5"; }
.landing-ring-beat.is-6::before { content: "6"; }

.landing-ring-hub {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 66%;
  transform: translate(-50%, -50%);
  text-align: center;
}

.landing-ring-line {
  margin: 0;
  font-family: "Instrument Serif", Georgia, serif;
  font-weight: 400;
  font-size: 27px;
  line-height: 1.12;
  color: var(--landing-ink);
}

/* =====================================================================
   THE RING ART — S279. AN INLINE SVG IN A WEBFLOW EMBED, TRANSPLANTED
   FROM ring-lap-loop.html, THE FILE SHE APPROVED AT S278. The seven `d`
   attributes and the end dot's coordinates were lifted out of that file
   and machine-checked byte-identical; NOTHING WAS RETYPED.

   ⚠⚠⚠ THE SVG AND THE SIX BEATS DRAW THE SAME CIRCLE FROM TWO
   DIFFERENT SYSTEMS, AND THEY AGREE BY ARITHMETIC RATHER THAN BY LUCK.
   The viewBox is 0 0 420 420 and every arc has radius 159.60 — which IS
   50% − 12%, the inset:12% circle above, at 38% of the box. The six dot
   centres computed off the live percentages land on the SVG's arc
   endpoints to two decimal places, and they stay together at EVERY
   width because the two 20px offsets in the beat anchors cancel.
   ▶ CHANGE THE INSET AND THE SVG IS WRONG WITH NOTHING ERRORING. The
   dots drift off the arc ends and only a screenshot shows it.

   ⚠⚠ THE ART IS ABSOLUTE, NEVER width:100%. Webflow wraps embed code in
   a div.w-embed that SHRINK-WRAPS its content, so a percentage width
   resolves against a parent sizing itself from that same content, both
   settle at 0, and the SVG loads perfectly into a box with no area
   (S224). An absolutely positioned child leaves that wrapper's flow and
   sizes against .landing-ring, which is position:relative.

   ⚠⚠ THE DOTS ARE NOT IN THE SVG — they are .landing-ring-beat::after
   and they always were, in her mockup too. Moving them in would have
   emptied the PHONE RAIL, which reuses the same six pseudo-elements and
   reuses .landing-ring::before as its vertical line. The only thing
   S279 changed about them is size and colour, and both are gated to
   min-width:768 so the rail is untouched.
   ===================================================================== */
.landing-ring-art {
  display: none;
}

/* ⚠⚠⚠ COLOUR LIVES HERE AND NOWHERE ELSE, AND THE EMBED CARRIES NO
   stroke OR fill ATTRIBUTE ON PURPOSE. Each of these six values is used
   THREE times — the arc, the dot sitting on it, and the arrow's colour
   while it lays that arc. Three copies split across a pinned file and
   an unversioned Webflow field is how they drift, and the Webflow half
   has no rollback. */
.landing-ring-base    { stroke: var(--landing-hairline); }
.landing-ring-endmark { fill:   var(--landing-hairline); }

/* ⚠⚠⚠ EACH STRETCH IS PAINTED THE COLOUR OF THE DOT IT *LEAVES*, NEVER
   THE ONE IT REACHES — HER DESIGN, AND IT IS WHY 2 AND 5 ARE BOTH
   AMBER: those are the two beats THE CLOSET does rather than the
   member. It is also why the ring underneath had to go grey. She
   watched both forks on the live mockup and picked the grey ring,
   because an amber trail on an amber ring changes nothing on screen.
   ⚠ GREEN AND NAVY ARE LITERALS — neither has a :root token, the same
   reason the four beat icons write them as literals fifty lines below.
   Do not invent tokens for them here. */
.landing-ring-seg.is-1 { stroke: var(--landing-coral); }
.landing-ring-seg.is-2 { stroke: var(--landing-amber); }
.landing-ring-seg.is-3 { stroke: #309359; }
.landing-ring-seg.is-4 { stroke: #1C4A91; }
.landing-ring-seg.is-5 { stroke: var(--landing-amber); }
.landing-ring-seg.is-6 { stroke: var(--landing-pink); }

/* THE ARROW. A plain HTML div in the embed rather than SVG: the whole
   arm is inset:0 on the ring, so it rotates about the ring's centre and
   the arrow rides its top edge.

   ⚠⚠⚠ top IS 12%, NEVER 50.4px. Her mockup stage is a fixed 420 box, so
   it could write pixels; .landing-ring is fluid below 420 and a pixel
   top slides the arrow off the circle at every smaller width, silently.
   50.4 / 420 = 12%, the same inset as the circle above.

   ⚠ THE ARM IS opacity:0 AT REST AND display:none UNTIL THE min-width
   GATE. No script, no flag, no animation — and the failure is NO ARROW
   rather than an arrow stranded at twelve o'clock forever. */
.landing-ring-arm {
  display: none;
  position: absolute;
  inset: 0;
  opacity: 0;
}

.landing-ring-trav {
  position: absolute;
  left: 50%;
  top: 12%;
  width: 16px;
  height: 14px;
  margin: -7px 0 0 -8px;
  background: var(--landing-coral);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

/* =====================================================================
   THE RING ABOVE THE RAIL — POSITION, SIZE, ENTRANCE AND LAP.

   ⚠⚠⚠ THIS IS A min-width BLOCK, DELIBERATELY, AGAINST THIS FILE'S
   max-width HABIT, AND THE REASON IS SPECIFICITY RATHER THAN TASTE.
   Every animation below is filled `both`, and a filled animation WRITES
   A transform that beats a plain `transform: none` declaration outright
   — at any source order, in any media query. Twinning these the usual
   way would mean restating six per-beat overrides at matching
   specificity in the 767 block, and the file's own record says the last
   thing that went wrong on this rail was exactly such a list going half
   updated. A GATE THE RAIL NEVER ENTERS CANNOT GO HALF UPDATED.
   ===================================================================== */
@media (min-width: 768px) {

  .landing-ring::before { display: none; }

  .landing-ring-art {
    display: block;
    position: absolute;
    inset: 0;
  }

  .landing-ring-arm { display: block; }

  /* HER RULING: 14px dots on the ring. The rail keeps its 9px, which is
     why this sits inside the gate — the rail's dots are NOT centred by
     a transform (top:.62em, left:-30px), so a size change there would
     move them off the line. On the ring every dot is centred by its own
     translate, so size is free. */
  .landing-ring-beat::after { width: 14px; height: 14px; }

  .landing-ring-beat.is-1::after { background: var(--landing-coral); }
  .landing-ring-beat.is-2::after { background: var(--landing-amber); }
  .landing-ring-beat.is-3::after { background: #309359; }
  .landing-ring-beat.is-4::after { background: #1C4A91; }
  .landing-ring-beat.is-5::after { background: var(--landing-amber); }
  .landing-ring-beat.is-6::after { background: var(--landing-pink); }

  /* THE SEGMENTS' RESTING STATE, UNDER THE MOTION FLAG ONLY — AND THE
     NO-FLAG CASE IS A DELIBERATE CHOICE, NOT AN OVERSIGHT. Without
     html.landing-motion these carry no dash array, so they paint in
     full: a reduced-motion reader, or anybody whose script never
     arrived, gets a COMPLETE COLOURED RING sitting still rather than a
     grey one waiting for something that will never happen. Fail
     visible, never fail blank (her S224 rule). */
  html.landing-motion .landing-ring-seg {
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
  }

  /* ---------------------------------------------------------------
     THE ENTRANCE — ONE SHOT, ARMED BY `.is-in`.

     ⚠⚠⚠ IT ARMS OFF THE SECTION REVEAL AND NEVER OFF PAGE LOAD. Armed
     on load, she scrolls down to a ring that finished painting while
     she was reading the masthead — the S246 watchdog fault in a new
     place. `.is-in` is added once by landing.js's section observer and
     then unobserved, so this cannot replay.
     --------------------------------------------------------------- */
  html.landing-motion .landing-cycle.is-in .landing-ring-base {
    stroke-dasharray: 100;
    animation: landing-ring-trace 1.4s cubic-bezier(.4, 0, .2, 1) both;
  }

  html.landing-motion .landing-cycle.is-in .landing-ring-endmark {
    opacity: 0;
    animation: landing-ring-endin .3s linear 1.4s forwards;
  }

  html.landing-motion .landing-cycle.is-in .landing-ring-hub {
    animation: landing-ring-hubin .6s cubic-bezier(.4, 0, .2, 1) 1.55s both;
  }

  /* ⚠⚠⚠ EVERY ENTRANCE KEYFRAME CARRIES ITS ELEMENT'S OWN POSITIONING
     transform, AND THAT IS THE WHOLE REASON THERE ARE THREE POP
     KEYFRAMES AND THREE RISE KEYFRAMES INSTEAD OF ONE OF EACH. On this
     ring the dots and the labels are POSITIONED BY transform, so a
     keyframe animating a bare scale() or translateY() DELETES that
     positioning and throws the element across the section — the hero
     star's rule, arriving here. Her mockup could use one pop keyframe
     because its dots were placed with left/top and a pixel margin.
     ▶ IF YOU ADD A SEVENTH BEAT, IT NEEDS THE KEYFRAME MATCHING ITS
     OWN ANCHOR, NOT WHICHEVER ONE IS NEAREST IN THE LIST. */
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-1::after { animation: landing-ring-pop-1   .32s cubic-bezier(.4,0,.2,1) 0.000s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-1        { animation: landing-ring-rise-top .5s cubic-bezier(.4,0,.2,1) 0.140s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-2::after { animation: landing-ring-pop-234 .32s cubic-bezier(.4,0,.2,1) 0.243s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-2        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 0.383s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-3::after { animation: landing-ring-pop-234 .32s cubic-bezier(.4,0,.2,1) 0.486s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-3        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 0.626s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-4::after { animation: landing-ring-pop-234 .32s cubic-bezier(.4,0,.2,1) 0.728s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-4        { animation: landing-ring-rise-bot .5s cubic-bezier(.4,0,.2,1) 0.868s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-5::after { animation: landing-ring-pop-56  .32s cubic-bezier(.4,0,.2,1) 0.971s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-5        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 1.111s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-6::after { animation: landing-ring-pop-56  .32s cubic-bezier(.4,0,.2,1) 1.214s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-6        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 1.354s both; }

  /* ---------------------------------------------------------------
     THE LAP — FOREVER, ON ONE 10.00s CYCLE.

     ⚠⚠⚠ ONE DURATION, SHARED BY EVERY LOOPING ELEMENT. The six arcs,
     the arrow's travel and the arrow's colour all run 10.00s with their
     moments written as PERCENTAGES inside it. Give any one of them its
     own animation-duration and they never line up again — the arrow
     lays an arc that is already painted, or paints one it has not
     reached. The Earn coin on /old-home paid for this rule once.

     ⚠⚠ IT PAUSES WHEN THE RING LEAVES THE VIEWPORT rather than
     restarting: landing.js toggles `.is-lapping` on .landing-ring and
     the only thing that changes here is play-state. Restarting instead
     would drop every element back to 0% at once and re-run the 2.00s
     lead-in each time she scrolled past. A moving thing behind a reader
     three sections down is the motion that actually annoys people.
     --------------------------------------------------------------- */
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-1 { animation: landing-ring-lap-1 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-2 { animation: landing-ring-lap-2 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-3 { animation: landing-ring-lap-3 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-4 { animation: landing-ring-lap-4 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-5 { animation: landing-ring-lap-5 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-6 { animation: landing-ring-lap-6 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-arm      { animation: landing-ring-sweep 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-trav     { animation: landing-ring-hue 10.00s step-end 2.00s infinite; }

  html.landing-motion .landing-cycle.is-in .landing-ring-seg,
  html.landing-motion .landing-cycle.is-in .landing-ring-arm,
  html.landing-motion .landing-cycle.is-in .landing-ring-trav {
    animation-play-state: paused;
  }

  html.landing-motion .landing-cycle.is-in .landing-ring.is-lapping .landing-ring-seg,
  html.landing-motion .landing-cycle.is-in .landing-ring.is-lapping .landing-ring-arm,
  html.landing-motion .landing-cycle.is-in .landing-ring.is-lapping .landing-ring-trav {
    animation-play-state: running;
  }

}

/* THE RING'S KEYFRAMES. At top level on purpose — a @keyframes block
   inside the min-width gate would be unreachable to anything that ever
   needs it at another width, and keyframes cost nothing when nothing
   references them. */
@keyframes landing-ring-trace {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}

@keyframes landing-ring-endin {
  to { opacity: 1; }
}

@keyframes landing-ring-hubin {
  from { opacity: 0; transform: translate(-50%, calc(-50% + 8px)); }
  to   { opacity: 1; transform: translate(-50%, -50%); }
}

/* THE THREE POPS — see the warning above. Each ends on the exact
   transform its beat's ::after uses for positioning. */
@keyframes landing-ring-pop-1 {
  from { opacity: 0; transform: translate(-50%, 50%) scale(.4); }
  to   { opacity: 1; transform: translate(-50%, 50%) scale(1); }
}
@keyframes landing-ring-pop-234 {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.4); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes landing-ring-pop-56 {
  from { opacity: 0; transform: translate(50%, -50%) scale(.4); }
  to   { opacity: 1; transform: translate(50%, -50%) scale(1); }
}

/* THE THREE RISES — same rule, for the labels. 6px, no scale: a scale
   moves a left edge, which is what put /old-home's spine out. */
@keyframes landing-ring-rise-top {
  from { opacity: 0; transform: translate(-50%, calc(-100% + 6px)); }
  to   { opacity: 1; transform: translate(-50%, -100%); }
}
@keyframes landing-ring-rise-bot {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to   { opacity: 1; transform: translateX(-50%); }
}
@keyframes landing-ring-rise-side {
  from { opacity: 0; transform: translate(0, calc(-50% + 6px)); }
  to   { opacity: 1; transform: translateY(-50%); }
}

/* THE SIX ARC KEYFRAMES. The percentages are her file's, unchanged:
   .60s lead, 6.20s painting split six ways, 2.00s held fully coloured,
   .70s fade back to grey, .50s tail. The 95.0/95.1 pair is what resets
   a segment to hidden INSIDE the fade rather than snapping it back
   visibly — do not collapse those two stops into one. */
@keyframes landing-ring-lap-1 { 0%{stroke-dashoffset:100;opacity:1} 6.0%{stroke-dashoffset:100;opacity:1} 16.751%{stroke-dashoffset:0;opacity:1} 88.0%{stroke-dashoffset:0;opacity:1} 95.0%{stroke-dashoffset:0;opacity:0} 95.1%{stroke-dashoffset:100;opacity:1} 100%{stroke-dashoffset:100;opacity:1} }
@keyframes landing-ring-lap-2 { 0%{stroke-dashoffset:100;opacity:1} 16.751%{stroke-dashoffset:100;opacity:1} 27.503%{stroke-dashoffset:0;opacity:1} 88.0%{stroke-dashoffset:0;opacity:1} 95.0%{stroke-dashoffset:0;opacity:0} 95.1%{stroke-dashoffset:100;opacity:1} 100%{stroke-dashoffset:100;opacity:1} }
@keyframes landing-ring-lap-3 { 0%{stroke-dashoffset:100;opacity:1} 27.503%{stroke-dashoffset:100;opacity:1} 38.254%{stroke-dashoffset:0;opacity:1} 88.0%{stroke-dashoffset:0;opacity:1} 95.0%{stroke-dashoffset:0;opacity:0} 95.1%{stroke-dashoffset:100;opacity:1} 100%{stroke-dashoffset:100;opacity:1} }
@keyframes landing-ring-lap-4 { 0%{stroke-dashoffset:100;opacity:1} 38.254%{stroke-dashoffset:100;opacity:1} 49.006%{stroke-dashoffset:0;opacity:1} 88.0%{stroke-dashoffset:0;opacity:1} 95.0%{stroke-dashoffset:0;opacity:0} 95.1%{stroke-dashoffset:100;opacity:1} 100%{stroke-dashoffset:100;opacity:1} }
@keyframes landing-ring-lap-5 { 0%{stroke-dashoffset:100;opacity:1} 49.006%{stroke-dashoffset:100;opacity:1} 59.757%{stroke-dashoffset:0;opacity:1} 88.0%{stroke-dashoffset:0;opacity:1} 95.0%{stroke-dashoffset:0;opacity:0} 95.1%{stroke-dashoffset:100;opacity:1} 100%{stroke-dashoffset:100;opacity:1} }
@keyframes landing-ring-lap-6 { 0%{stroke-dashoffset:100;opacity:1} 59.757%{stroke-dashoffset:100;opacity:1} 68.0%{stroke-dashoffset:0;opacity:1} 88.0%{stroke-dashoffset:0;opacity:1} 95.0%{stroke-dashoffset:0;opacity:0} 95.1%{stroke-dashoffset:100;opacity:1} 100%{stroke-dashoffset:100;opacity:1} }

/* THE ARROW'S TRAVEL. `rotate:`, NEVER `transform: rotate()` — the arm
   is positioned by inset and carries no transform today, but the hero
   stars' rule is kept identical here so the two cannot drift, and a
   transform keyframe on anything positioned by one deletes the
   positioning. 346deg, not 360: it stops where the stroke stops. */
@keyframes landing-ring-sweep {
  0%    { rotate: 0deg;     opacity: 0; }
  5.99% { rotate: 0deg;     opacity: 0; }
  6.0%  { rotate: 0deg;     opacity: 1; }
  68.0% { rotate: 346.0deg; opacity: 1; }
  72.5% { rotate: 346.0deg; opacity: 0; }
  99.9% { rotate: 346.0deg; opacity: 0; }
  100%  { rotate: 0deg;     opacity: 0; }
}

/* THE ARROW'S COLOUR. step-end, so it changes at the seam rather than
   blending through it — the arrow is always the colour of the arc it is
   currently laying. THESE SIX MUST MATCH .landing-ring-seg ABOVE AND
   .landing-ring-beat::after ABOVE THAT. One fact, three places, and the
   only reason all three are in this file. */
@keyframes landing-ring-hue {
  0%       { background: #E54F25; }
  6.0%     { background: #E54F25; }
  16.751%  { background: #EDA920; }
  27.503%  { background: #309359; }
  38.254%  { background: #1C4A91; }
  49.006%  { background: #EDA920; }
  59.757%  { background: #F491A9; }
}

/* =====================================================================
   THE FOUR BEATS
   ===================================================================== */

.landing-section.landing-beats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 40px;
  align-items: start;
}

/* ⚠⚠ A PLACEHOLDER BOX, NOT AN ICON — her PNGs are not ready. Flat
   #CCCAC5, DELIBERATELY OUTSIDE THE SEVEN-COLOUR PALETTE so nobody
   later reads it as a design decision. Same device as the hero media
   half and the closet-standard photo panel.
   THE SWAP IS ONE PROPERTY ON THIS SAME ELEMENT: drop background-color,
   add background-image / background-size:contain / no-repeat. NO
   DESIGNER WORK when the artwork lands.
   ⚠ SIZE IT BY THE BOX, NOT BY THE FILE. Four PNGs will carry four
   different amounts of transparent padding, and height is a bad proxy
   for how big a mark looks — the marquee logos paid for that lesson. */
.landing-beat-icon {
  width: 26px;
  height: 26px;
  margin: 0 0 14px;
  background-color: var(--landing-placeholder);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border-radius: 3px;
}

.landing-beat-heading {
  position: relative;
  margin: 0;
  padding-bottom: 12px;
  font-family: "Instrument Serif", Georgia, serif;
  font-style: normal;
  font-weight: 400;
  font-size: 27px;
  line-height: 1.1;
  color: var(--landing-ink);
}

/* the amber rule, the same device /old-home uses under its step
   headings. A pseudo, never its own element — an element would become a
   third grid child and land somewhere else. */
.landing-beat-heading::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 36px;
  height: 3px;
  background: var(--landing-amber);
}

.landing-beat-body {
  margin: 14px 0 0;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 15px;
  line-height: 1.55;
  color: var(--landing-ink);
}

/* ⚠⚠ THESE FOUR ARE INERT WHILE THE ICON IS A PNG — a raster image
   cannot take `color`. KEPT ON PURPOSE, against §0's delete-inert-rules
   rule, because they are the record of her four-colour ruling from the
   S276 mockup (Send coral, Earn green, Swap navy, Repeat pink) and they
   go live again the day the icons are inline SVG. DO NOT DELETE THEM AS
   TIDYING, and do not read them as live styling either. */
.landing-beat.is-send   .landing-beat-icon { color: var(--landing-coral); }
.landing-beat.is-earn   .landing-beat-icon { color: #309359; }
.landing-beat.is-swap   .landing-beat-icon { color: #1C4A91; }
.landing-beat.is-repeat .landing-beat-icon { color: var(--landing-pink); }

/* =====================================================================
   THE CTA HEADING AND SMALL PRINT
   ===================================================================== */

.landing-cta-heading {
  margin: 0 0 22px;
  max-width: 18ch;
  font-family: "Instrument Serif", Georgia, serif;
  font-weight: 400;
  font-size: 34px;
  line-height: 1.08;
  color: var(--landing-ink);
}

.landing-cta-note {
  margin: 16px 0 0;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 13px;
  color: var(--landing-muted);
}

/* =====================================================================
   MOBILE TWINS — see the header note.
   ===================================================================== */

@media (max-width: 991px) {
  .landing-section.landing-beats { grid-template-columns: repeat(2, 1fr); gap: 36px 32px; }
  .landing-ring { max-width: 380px; }
  .landing-ring-beat { font-size: 18px; }
  .landing-ring-line { font-size: 24px; }
}

@media (max-width: 767px) {

  .landing-section.landing-beats { grid-template-columns: 1fr; gap: 30px; }

  /* HER MOCKUP: on the phone the icon sits BESIDE the heading on one
     line, not above it. Grid rather than flex so the body copy aligns
     to the heading's left edge and not to the icon's. */
  .landing-beat {
    display: grid;
    grid-template-columns: 26px 1fr;
    column-gap: 14px;
    align-items: center;
  }
  .landing-beat-icon { margin: 0; }
  .landing-beat-heading { grid-column: 2; }
  .landing-beat-body { grid-column: 2; }

  /* ⚠⚠⚠ THE RAIL IS A DIFFERENT LAYOUT, NOT A SMALLER RING — HERS.
     Everything positional is unwound: the circle, the absolute beats
     and the paired offsets all go, and the hub stops being a centre.
     A scaled ring puts 20px serif labels inside a 340px circle and they
     overlap. */
  .landing-ring {
    max-width: none;
    aspect-ratio: auto;
    margin: 4px 0 0;
    padding-left: 30px;
  }

  .landing-ring::before {
    inset: 10px auto 30px 4px;
    width: 1px;
    border: 0;
    border-radius: 0;
    background: var(--landing-hairline);
  }

  /* ⚠⚠ EVERY ANCHOR IS UNWOUND HERE, INCLUDING `right`. The desktop
     left pair is anchored by its right edge; left as static without
     clearing `right` leaves it pinned. */
  .landing-ring-beat,
  .landing-ring-beat.is-1,
  .landing-ring-beat.is-2,
  .landing-ring-beat.is-3,
  .landing-ring-beat.is-4,
  .landing-ring-beat.is-5,
  .landing-ring-beat.is-6 {
    position: static;
    left: auto;
    right: auto;
    top: auto;
    transform: none;
    display: block;
    margin: 0 0 18px;
    font-size: 21px;
    text-align: left;
    white-space: normal;
  }

  /* ⚠⚠⚠ THESE ARE THE DOTS AND THEY ARE ::after HERE TOO — the S278
     swap MUST be mirrored in this block. Leave the desktop swapped and
     this list unswapped and the rail silently styles the NUMBER with
     the dot's rules and drops the dots into the text: phone only,
     nothing errors, and this rail is the one surface nobody has
     watched. */
  .landing-ring-beat::after,
  .landing-ring-beat.is-1::after,
  .landing-ring-beat.is-2::after,
  .landing-ring-beat.is-3::after,
  .landing-ring-beat.is-4::after,
  .landing-ring-beat.is-5::after,
  .landing-ring-beat.is-6::after {
    top: .62em;
    left: -30px;
    right: auto;
    bottom: auto;
    transform: none;
  }

  /* ⚠ THE NUMBER NEEDS NO RULE HERE AS OF S278. v7 parked it in the
     30px gutter BELOW the dot; it is now inline in front of the label,
     the same as every desktop position, so the gutter holds the dot and
     nothing else. The old gutter rule was DELETED rather than left
     inert (§0). */

  .landing-ring-hub {
    position: static;
    width: auto;
    transform: none;
    text-align: left;
    margin-top: 22px;
  }

  /* THE RAIL'S SPINE. The SVG owns the circle above 767; here the same
     pseudo-element becomes the vertical bar, so display:block turns it
     back on — the base rule is display:none as of S279.
     ⚠ THE OLD `.landing-ring-trav { display: none }` LINE WENT WITH IT
     RATHER THAN BEING LEFT INERT (§0): the arrow's wrapper is
     display:none by default now and only the min-width gate turns it
     on, so the rail can never receive it. */
  .landing-ring::before { display: block; }

  .landing-ring-line { font-size: 23px; }

  .landing-sub, .landing-head .landing-sub { font-size: 17px; }
  .landing-cta-heading { font-size: 30px; }
}

@media (max-width: 479px) {
  .landing-ring-beat { font-size: 19px; }
  .landing-sub, .landing-head .landing-sub { font-size: 16px; }
  .landing-cta-heading { font-size: 27px; }
}

/* =====================================================================
   v8 — S279. THE PHONE PASS ON /how-it-works: accordion spacing, the
   CTA heading's wrap, and the two buttons side by side.
   ROLLBACK: delete from this comment to the end of the file. v7 is a
   byte-exact prefix and was machine-checked as one.

   ⚠⚠ EVERY RULE IN THIS SECTION LIVES INSIDE ITS OWN @media BLOCK AND
   NOT ONE IS APPENDED BARE. That is deliberate and it is the file's own
   rule read the right way round: a bare appended rule beats a media
   query at equal specificity by source order, so a mobile-only change
   written bare would have silently governed the desktop too. Written
   inside a query that sits AFTER the existing 767 blocks, it wins over
   them on source order and cannot reach any other width.
   ===================================================================== */

@media (max-width: 767px) {

  /* --- QUESTION → TEASER, TIGHTER. HERS, OFF HER OWN PHONE. ----------
     ⚠⚠⚠ THE GAP WAS TWO THINGS STACKED AND ONLY ONE OF THEM IS MOVABLE.
     The teaser carries a 6px top margin, and under it sits roughly 10px
     of slack from .landing-q-toggle's min-height:44px — which is THE
     THUMB TARGET and must never be reduced to close a gap.

     ⚠⚠⚠ SO THE MARGIN IS NEGATIVE, AND THAT IS THE ONLY HONEST WAY PAST
     THE FLOOR. -6px pulls the teaser's text up THROUGH the toggle's
     slack while the control itself stays a full 44px tall — the gap
     reads ~4px and the thumb target is untouched. It is safe here and
     ONLY here because the teaser sits OUTSIDE .landing-answer-wrap's
     collapsing track; a negative margin on anything inside that track
     would floor it and leak (see the answer rule below).
     ⚠ SCOPED UNDER .landing-q ON PURPOSE. .landing-teaser does two jobs
     on this page — the per-question teaser and the intro line under a
     section label — and only the first one lives inside a .landing-q.
     Loosen this to a bare .landing-teaser and the section intros lose
     their spacing too. */
  .landing-q .landing-teaser {
    margin-top: -6px;
  }

  /* --- TEASER → ANSWER, LOOSER. HERS. -------------------------------
     ⚠⚠⚠ THIS IS A MARGIN ON THE FIRST CHILD, NEVER ON .landing-answer.
     That element is the grid item inside a track that collapses to 0fr,
     an fr track floors at the item's minimum contribution, and vertical
     margin and padding are both unshrinkable — either one leaks that
     many pixels of open answer on EVERY CLOSED ROW, on every landing
     page. /old-home paid for this at home.css v43. A margin on the
     child is inside the clip and costs nothing.

     ⚠⚠ AND THE AMBER RULE MUST MOVE IN THE SAME EDIT. It is a
     background, not a border, sized against the first child's margin:
     16 top + the 4px ::after = 20. CHANGE ONE NUMBER WITHOUT THE OTHER
     AND THE LINE STARTS ABOVE WHERE THE TEXT DOES. These two are one
     value written twice and they are never tuned apart.
     ⚠ 16 REPLACED 22 WITHIN S279, off her own screenshot of the spacing
     she wanted. 22 shipped for about an hour; it is not a rollback
     target and there is nothing to restore. */
  .landing-answer > *:first-child {
    margin-top: 16px;
  }

  .landing-answer {
    background-size: 2px calc(100% - 20px);
    background-position: 0 16px;
  }

  /* --- THE CTA HEADING'S WRAP. --------------------------------------
     ⚠ THE BREAK AFTER "deserves a" WAS max-width:18ch, NOT THE VIEWPORT.
     18ch at 30px forces the first line short whatever the screen does.
     Off on the phone, and `text-wrap: balance` evens the lines instead
     of filling the first — a browser that does not know the property
     ignores it and renders today's wrap, so there is no fallback to
     build. The desktop keeps its 18ch measure, untouched. */
  .landing-cta-heading {
    max-width: none;
    text-wrap: balance;
  }

  /* --- THE TWO BUTTONS, SIDE BY SIDE AT HALF WIDTH. HERS. -----------
     ⚠⚠⚠ ONLY .landing-cta-btns BECOMES FLEX. .landing-cta-row HOLDS THE
     H2 AS WELL, so making the row flex would stand the heading beside
     the buttons. Read off Navigator, not assumed.
     ⚠ flex:1 1 0 WITH min-width:0 IS WHAT GIVES TRUE HALVES. Without
     min-width a flex item refuses to shrink below its content, so the
     longer label would take more than half and push the row wide.
     ⚠ 13px AND 8px OF SIDE PADDING ARE WHAT KEEP "See The Closet
     Standard" ON ONE LINE at 390px. align-items:stretch means the pills
     stay the same height if it ever does wrap on a narrower phone. */
  .landing-cta-btns {
    display: flex;
    flex-wrap: nowrap;
    gap: 10px;
    align-items: stretch;
  }

  .landing-cta-row .landing-cta-primary,
  .landing-cta-row .landing-cta-secondary,
  .landing-cta-btns .landing-cta-primary,
  .landing-cta-btns .landing-cta-secondary {
    display: inline-block;
    width: auto;
    flex: 1 1 0;
    min-width: 0;
    margin-top: 0;
    padding: 14px 8px;
    font-size: 13px;
    line-height: 1.25;
  }

}

/* =====================================================================
   v8b — S279, STILL INSIDE v8. THE AMBER LINE'S OFFSET AND THE RING'S
   LABEL FACE. Rollback is unchanged: delete from the v8 comment to the
   end of the file.
   ===================================================================== */

/* --- THE AMBER LINE, RAISED. HERS, TUNED ON HER OWN PAGE WITH THE
   DISPLAY-ONLY PROBE RATHER THAN GUESSED FROM A SCREENSHOT: top 11,
   trim 4, so 11 + 4 = 15.

   ⚠⚠⚠ THE OFFSET AND THE FIRST CHILD'S MARGIN ARE ONE VALUE WRITTEN
   TWICE AND THEY MOVE TOGETHER, ALWAYS. The line is a background, so it
   contributes no layout and will happily sit above or below the text
   with nothing erroring. Set one and not the other and the rule starts
   somewhere the words do not.

   ⚠⚠ THIS PAIR IS 11 ON THE DESKTOP AND 16 ON THE PHONE, and the twin
   below is what keeps it that way — a bare appended rule beats a media
   query at equal specificity by source order, so without it 11 would
   have governed both. IF THE PHONE READS TOO LOW TOO, the fix is to
   take the twin's two numbers to 11 and 15 as well; it is one edit and
   the pair still moves together. --------------------------------- */
.landing-answer > *:first-child {
  margin-top: 11px;
}

.landing-answer {
  background-size: 2px calc(100% - 15px);
  background-position: 0 11px;
}

/* --- THE RING'S LABELS GO SANS. HERS: "easier to read at a smaller
   size too", which is aimed at the phone ring that is not built yet as
   much as at this one.

   ⚠ FAMILY AND WEIGHT ONLY, NO SIZE CHANGE. Quicksand at a given size
   sets WIDER than Instrument Serif, so the six labels all grow a little
   — harmless by construction, because the right pair is anchored by its
   LEFT edge and the left pair by its RIGHT edge, so both grow AWAY from
   the circle and can never creep over it. Size was deliberately left
   alone so that if this reads wrong, the face is the only variable.

   ⚠ IT COSTS THE NUMBER-VERSUS-LABEL CONTRAST. The numbers were already
   Quicksand 500 at 12px, so number and label are now one family and are
   told apart by size and by the muted grey alone. Flagged, not a fault.

   ⚠ THE HUB LINE IS NOT TOUCHED — .landing-ring-line is still
   Instrument Serif at 40px. It is display type at the centre of the
   picture rather than a label to be read at a small size, so it was
   left out of this deliberately. One rule if she wants it too. */
.landing-ring-beat {
  font-family: Quicksand, sans-serif;
  font-weight: 500;
}

/* --- MOBILE TWIN. Required, see the note above. --------------------- */
@media (max-width: 767px) {
  .landing-answer > *:first-child {
    margin-top: 16px;
  }

  .landing-answer {
    background-size: 2px calc(100% - 20px);
    background-position: 0 16px;
  }
}


/* =====================================================================
   v9 — S280. /how-it-works: .landing-answer IS THE PARAGRAPH ITSELF.
   ROLLBACK: delete from this v9 comment to the end of the file.
   ⚠ REVISED IN PLACE, TWICE, RATHER THAN STACKED AS v10 — the first cut
   of this block named the wrong element and shipped a rule at the wrong
   specificity. Both corrections are folded in here so no dead reasoning
   survives. v8b is still a byte-exact prefix, machine-checked.

   ⚠⚠⚠ MEASURED, NOT DERIVED, AND THE FIRST READ WAS ONE LEVEL OFF.
     /how-it-works        6 rows, and `.landing-answer` is itself a
                          <p class="landing-answer"> — read live off
                          tagName, after a computed-style read came back
                          16px/27.2/ink and matched nothing this block
                          had written. Its prose sits in it as bare text
                          nodes; row 1 also holds one inline
                          <a class="seo-content-link">.
     /the-closet-standard 8 rows, `.landing-answer` is a DIV wrapping
                          real <p> children, and no answer opens with
                          the photo grid.

   SO ONE CLASS NAME WEARS TWO DIFFERENT ELEMENTS ON TWO PAGES, and every
   consequence follows from that. `.landing-answer p` cannot match on
   /how-it-works because there are no paragraphs INSIDE the answer — it
   IS the paragraph. `.landing-answer > *:first-child { margin-top }`
   lands on row 1's INLINE link, where a vertical margin does nothing,
   and on nothing at all in the other five. THAT is why the amber line
   read ~7.5px below the top of the words: the words had no top margin,
   the line did. The number was never wrong.

   ⚠⚠⚠ AND THE FIRST FIX FAILED ON SPECIFICITY, NOT ON SOURCE ORDER — it
   was written `.landing-answer` at (0,1,0) and `.landing-section-body p`
   at (0,1,1) was already styling that same element, so the appended rule
   LOST and the answers kept rendering 16px/1.7/ink. A bigger number, a
   later position or an !important war would all have been the wrong
   move. ▶ WHEN AN APPENDED RULE APPEARS NOT TO FIRE, COUNT THE
   SPECIFICITY OF WHAT ELSE MATCHES THAT ELEMENT BEFORE CHANGING A VALUE.

   ▶ THIS FILE HAS ALREADY MET THIS DISEASE ONCE — v4/v5, where the note
   box's heading and body were Text Blocks and `.landing-note-box p`
   never reached them. It was fixed by styling the real elements rather
   than rebuilding the markup, and that is what this block does too.

   ⚠⚠ WHY NOT padding-top ON .landing-answer: it is the grid item inside
   .landing-answer-wrap, which collapses to grid-template-rows:0fr, and
   vertical padding AND margin are both unshrinkable — either would leak
   that many pixels of open answer on every CLOSED row, on all three
   landing pages. The /old-home v43 fault exactly. A ::before BLOCK sits
   INSIDE the item where min-height:0 and the clip can eat it, which is
   the same trick the 4px ::after at the bottom already proves works.
   ===================================================================== */

/* --- THE TYPE, WRITTEN AT TWO CLASSES SO IT WINS OUTRIGHT. ------------
   ⚠⚠⚠ `.landing-answer-wrap .landing-answer` IS (0,2,0) AND THAT IS THE
   WHOLE POINT — it beats `.landing-section-body p` at (0,1,1) on
   SPECIFICITY, never on source order, so it cannot be silently undone by
   a later rule or by anything moving house. DO NOT "SIMPLIFY" IT BACK TO
   ONE CLASS. That is a loss, not a tie, and it loses silently.
   The wrap is the answer's own parent on BOTH pages, so one selector
   serves both. VALUES ARE COPIED FROM `.landing-answer p` UNCHANGED.
   ⚠ SAFE TO INHERIT, CHECKED CHILD BY CHILD: .landing-photo-caption sets
   its own family, size, line-height AND colour, its <b> sets weight and
   colour, .landing-photo / .landing-photo-rule hold no text, and
   `.landing-answer strong` is already declared above. Nothing downstream
   drifts.
   ⚠ ON /the-closet-standard THIS CHANGES NOTHING. There the wrap's child
   is the DIV, and `.landing-answer p` (0,1,1) still governs the real
   paragraphs inside it — with identical values. The `p` rules STAY; do
   not delete them, or a future rich-text answer loses its paragraph
   margins.
   ⚠⚠ THE margin:0 IS NOT DECORATION AND IT CLOSES A REAL EXPOSURE.
   `.landing-section-body p` also sets `margin: 0 0 1.1em`, and it was
   beating the base `.landing-answer { margin: 0 }` for the same
   specificity reason — a bottom margin THERE is unshrinkable and would
   floor the 0fr track, leaking ~17px of open answer under every closed
   row (the /old-home v43 fault). MEASURED S280: every closed row read
   0.0 and margin-bottom read 0px, so it has never leaked — but ONLY
   because `.landing-section-body p:last-child` at (0,2,1) happens to
   zero it, and that holds only while the answer is the LAST child of its
   wrap. A sibling added after it brings the leak back with nothing
   erroring. This rule removes the luck.
   ⚠ CONTRAST, NAMED AND KNOWINGLY ACCEPTED: --landing-muted on this
   cream reads ~4.0:1, under the 4.5 bar for 15.5px text. It is the same
   grey the closet standard's answers already use and it is what makes
   the two pages read as siblings. The lever is one value here. --------- */
.landing-answer-wrap .landing-answer {
  margin: 0;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 15.5px;
  line-height: 1.68;
  color: var(--landing-muted);
}

/* --- THE TOP GAP BECOMES A BLOCK SPACER INSIDE THE ITEM. --------------
   ⚠⚠⚠ THE SPACER AND THE AMBER LINE'S OFFSET ARE ONE VALUE WRITTEN TWICE
   AND THEY MOVE TOGETHER, ALWAYS — 11 desktop / 16 phone, matching the
   background-position and the calc(100% - N) already set at v8b. THE
   BACKGROUND IS THEREFORE UNCHANGED BY THIS COMMIT: the line already
   starts at 11, and now the words do too, so they align by construction
   rather than by tuning. DO NOT ALSO MOVE THE LINE TO 4 — that number
   was measured against text that had no top margin at all.
   ⚠ :first-child MATCHES ELEMENTS ONLY, so ::before does not become the
   first child and does not shift what that rule targets. The margin is
   zeroed rather than left in place, or a paragraph row would take 11
   from the spacer PLUS 11 from the margin.
   ⚠ ZERO IS THE SAME AT BOTH WIDTHS, so the first-child rule needs no
   mobile twin. THE SPACER DOES — a bare appended rule beats a media
   query at equal specificity by source order, so without the twin below
   11 would govern the phone as well. ---------------------------------- */
.landing-answer > *:first-child {
  margin-top: 0;
}

.landing-answer::before {
  content: "";
  display: block;
  height: 11px;
}

/* --- THE LINK IN ROW 1 KEEPS ITS JOB. CLAUDE'S CALL, REVERSIBLE, ONE
   RULE. With the answer text going muted grey the inline link would
   inherit the same grey and stop reading as clickable, so it takes the
   ink and an underline. ⚠ It is written at (0,1,1) so it beats
   `seo-content-link`, which removes the underline and sets nothing else
   (§0) — and beats the site-wide `All Links` tag selector outright. ---- */
.landing-answer a {
  color: var(--landing-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* --- MOBILE TWIN. Required, see the note above. --------------------- */
@media (max-width: 767px) {
  .landing-answer::before {
    height: 16px;
  }
}


/* =====================================================================
   v10 — S280. THE PHONE RING. THE RAIL IS REPLACED.
   ROLLBACK: delete from this v10 comment to the end of the file, which
   returns the vertical rail exactly as it was — every rail rule is
   still in place above and this block only overrides it.

   ⚠⚠⚠ HER RULING, AND IT REVERSES THE S277 RAIL: "id rather keep the
   same style as the desktop as much as possible" and "reduce the scale
   of everything so its proportionate". So this is NOT the two-part
   arrangement that was mocked first (dots on the circle, labels listed
   beneath) — it is the DESKTOP ARRANGEMENT at a smaller scale: labels
   outboard on the circle, numbers in front of them, hub line inside.

   ⚠⚠ WHAT THE SCALE COSTS, NAMED BEFORE IT SHIPPED AND ACCEPTED BY HER
   OFF A RENDERED MOCKUP AT A TRUE 381px:
     · four of the six labels WRAP to two lines where desktop has one
     · labels 13px against 15, hub line 18px against 40
     · the circle is roughly half its desktop diameter
   The alternative kept the scale and moved the labels off the circle.
   She chose arrangement over scale. DO NOT "CORRECT" IT BACK.

   ⚠⚠⚠ THE RAIL RULES ABOVE ARE NOT DELETED AND MUST NOT BE. They are
   what this block overrides, one property at a time, and they are the
   rollback. Deleting them and keeping this block leaves nothing to fall
   back to.
   ===================================================================== */

@media (max-width: 767px) {

  /* --- THE BOX. FLUID, SO THE LABELS' ROOM GROWS WITH THE SCREEN.
     ⚠⚠⚠ 62vw IS NOT A TASTE VALUE — IT IS WHAT KEEPS THE LONGEST LABEL
     OFF THE EDGE ON A SMALL PHONE. The side labels start at
     50% + 32.909% of THE BOX from centre, so a fixed box width would
     leave 74px for "We inspect" at 320px and 137px at 479px. A vw box
     keeps the two in step: the ring shrinks exactly as the screen does.
     Capped at 250 so it stops growing before the 767 boundary, where
     the desktop ring takes over at 420. ------------------------------ */
  .landing-ring {
    width: 62vw;
    max-width: 250px;
    aspect-ratio: 1 / 1;
    margin: 10px auto 0;
    padding-left: 0;
  }

  /* THE SVG DRAWS THE CIRCLE HERE TOO, exactly as it does on desktop,
     so the pseudo-element goes back to being nothing. It is the RAIL's
     vertical bar and the rail is gone. */
  .landing-ring::before { display: none; }

  .landing-ring-art {
    display: block;
    position: absolute;
    inset: 0;
  }

  /* ⚠⚠ THE SIX COLOURED ARCS ARE HIDDEN AND THE GREY BASE IS NOT.
     CLAUDE'S CALL, REVERSIBLE IN ONE LINE. The entrance and the lap
     live in the min-width:768 gate, and without html.landing-motion's
     dash-array the segments PAINT IN FULL — so leaving them visible
     would give the phone a permanently rainbow ring, which is not what
     the desktop looks like at rest. Grey ring, coloured dots, still:
     that IS the desktop at rest. Bringing the lap down here is now a
     separate, honest decision rather than an accident. */
  .landing-ring-seg { display: none; }

  /* --- THE SIX BEATS. Every anchor the rail unwound is wound back,
     including `right` — the rail set it to auto on all six and the left
     pair is anchored BY its right edge.
     ⚠⚠⚠ white-space GOES BACK TO normal, WHICH IS THE ONE REAL
     DEPARTURE FROM DESKTOP. Desktop keeps nowrap because a label there
     has the whole margin to run into; here it does not, so the side
     labels wrap and their max-width is what decides where.
     ⚠ THE CLEARANCE IS 10px HERE, NOT THE DESKTOP 20 — it is scaled
     with everything else. It appears in FOUR places per beat (the
     label's own offset and its dot's), so change one and change all. */
  .landing-ring-beat {
    font-size: 13px;
    line-height: 1.35;
    white-space: normal;
  }

  .landing-ring-beat::before { font-size: 11px; }

  .landing-ring-beat.is-1 {
    position: absolute;
    display: block;
    margin: 0;
    left: 50%;
    right: auto;
    top: calc(50% - 38% - 10px);
    transform: translate(-50%, -100%);
    text-align: center;
  }
  .landing-ring-beat.is-1::after {
    left: 50%; right: auto; top: auto; bottom: -10px;
    transform: translate(-50%, 50%);
  }

  .landing-ring-beat.is-4 {
    position: absolute;
    display: block;
    margin: 0;
    left: 50%;
    right: auto;
    top: calc(50% + 38% + 10px);
    transform: translateX(-50%);
    text-align: center;
  }
  .landing-ring-beat.is-4::after {
    left: 50%; right: auto; bottom: auto; top: -10px;
    transform: translate(-50%, -50%);
  }

  /* ⚠⚠⚠ THE max-width IS THE WHOLE FIT AND IT MIXES UNITS ON PURPOSE.
     50vw is half the screen, 32.909% resolves against THE RING BOX, and
     the 20px is the 10px clearance plus a 10px margin off the screen
     edge. So the label is given exactly the room left between the
     circle and the edge, at every width, with no breakpoint. Give it a
     fixed px value instead and it is right on one phone only. */
  .landing-ring-beat.is-2,
  .landing-ring-beat.is-3 {
    position: absolute;
    display: block;
    margin: 0;
    left: calc(50% + 32.909% + 10px);
    right: auto;
    transform: translateY(-50%);
    text-align: left;
    max-width: calc(50vw - 20px - 32.909%);
  }
  .landing-ring-beat.is-2 { top: calc(50% - 19%); }
  .landing-ring-beat.is-3 { top: calc(50% + 19%); }
  .landing-ring-beat.is-2::after,
  .landing-ring-beat.is-3::after {
    left: -10px; right: auto; bottom: auto; top: 50%;
    transform: translate(-50%, -50%);
  }

  .landing-ring-beat.is-5,
  .landing-ring-beat.is-6 {
    position: absolute;
    display: block;
    margin: 0;
    right: calc(50% + 32.909% + 10px);
    left: auto;
    transform: translateY(-50%);
    text-align: right;
    max-width: calc(50vw - 20px - 32.909%);
  }
  .landing-ring-beat.is-5 { top: calc(50% + 19%); }
  .landing-ring-beat.is-6 { top: calc(50% - 19%); }
  .landing-ring-beat.is-5::after,
  .landing-ring-beat.is-6::after {
    right: -10px; left: auto; bottom: auto; top: 50%;
    transform: translate(50%, -50%);
  }

  /* --- THE DOTS. 10px, scaled between the desktop ring's 14 and the
     rail's 9. Every one is centred by its own translate above, so the
     size is free to change without moving anything.
     ⚠ THE SIX COLOURS LIVE IN THE min-width:768 GATE, so they have to
     be restated here or every dot on the phone is the base amber. Same
     six values as the arcs and the desktop dots — THREE COPIES NOW, and
     a change to one is a change to three. */
  .landing-ring-beat::after { width: 10px; height: 10px; }

  .landing-ring-beat.is-1::after { background: var(--landing-coral); }
  .landing-ring-beat.is-2::after { background: var(--landing-amber); }
  .landing-ring-beat.is-3::after { background: #309359; }
  .landing-ring-beat.is-4::after { background: #1C4A91; }
  .landing-ring-beat.is-5::after { background: var(--landing-amber); }
  .landing-ring-beat.is-6::after { background: var(--landing-pink); }

  /* --- THE HUB GOES BACK TO THE CENTRE. 66% of the box, same as
     desktop, so it wraps to two lines inside the circle. 18px is the
     largest that clears the ring at 320px. */
  .landing-ring-hub {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 66%;
    transform: translate(-50%, -50%);
    text-align: center;
    margin-top: 0;
  }

  .landing-ring-line { font-size: 18px; }
}

/* --- THE 479 TWIN. Required: the existing 479 block sets the beat to
   19px and sits ABOVE this one, so without this the labels jump back up
   on a small phone. The box and the max-width need nothing — both are
   already fluid. ------------------------------------------------------ */
@media (max-width: 479px) {
  .landing-ring-beat { font-size: 12px; }
  .landing-ring-line { font-size: 17px; }
}


/* =====================================================================
   v11 — S280. THE PHONE RING'S TYPE. v10's SIZE NEVER FIRED.
   ROLLBACK: delete from this v11 comment to the end of the file, which
   returns v10 exactly.

   ⚠⚠⚠ THE FAULT, AND IT IS THE SECOND TIME IN ONE SESSION: v10 wrote
   `.landing-ring-beat { font-size: 13px }` at ONE class (0,1,0), while
   the rail block above sets its 21px inside a selector LIST that names
   `.landing-ring-beat.is-1` … `.is-6` at TWO classes (0,2,0). So the
   labels shipped at 21px on the phone and every gate passed — the file
   arrived, the rule was present, and it simply lost.
   ▶▶ THE RULE, PAID FOR TWICE TODAY: WHEN OVERRIDING A BLOCK THAT USES
   A SELECTOR LIST, MATCH THE HEAVIEST SELECTOR IN THAT LIST, NOT THE
   ONE THAT READS MOST NATURALLY. A bare class after a two-class rule is
   a LOSS, not a tie, and it loses in total silence.

   ⚠⚠ THREE OF THE FOUR FAULTS SHE SAW WERE ONE FAULT. At 21px "Fill
   your bag" wrapped and pushed up through the hairline above the ring,
   "Shop the closet" pushed down through the one below, and "They
   outgrow it" broke three ways and stranded "it". All of it is the size
   that never landed; the GEOMETRY was correct on her render — dots on
   the stroke, end mark placed, six colours right.

   ✅ AND HER RULING ON THE HUB, OFF THE SAME RENDER: it gets BIGGER and
   takes a line break. On desktop the hub is 40px against 15px labels —
   the biggest thing in the picture. v10 shipped 18px against a 21px
   label, which inverted the hierarchy at the one place the ring is
   supposed to be read from.
   ===================================================================== */

@media (max-width: 767px) {

  /* --- THE SIZE, THIS TIME AT TWO CLASSES SO IT WINS OUTRIGHT.
     ⚠ DO NOT "SIMPLIFY" THIS BACK TO `.landing-ring-beat`. That is the
     v10 rule and it does nothing. The six are named because the rail's
     unwind names all six. -------------------------------------------- */
  .landing-ring-beat.is-1,
  .landing-ring-beat.is-2,
  .landing-ring-beat.is-3,
  .landing-ring-beat.is-4,
  .landing-ring-beat.is-5,
  .landing-ring-beat.is-6 {
    font-size: 13px;
    line-height: 1.32;
  }

  /* THE NUMBER comes down with the label. The base rule is 12px, set at
     `.landing-ring-beat::before` (0,1,0) — nothing in the rail block
     touches it, so one class is enough HERE and only here. The margin
     shrinks with it or the number floats away from its own word. */
  .landing-ring-beat::before {
    font-size: 10px;
    margin-right: 5px;
  }

  /* --- THE HUB. Bigger, and narrowed so it breaks where she wants it.
     ⚠⚠⚠ THE WIDTH IS WHAT MAKES THE BREAK, NOT A <br>. The markup is a
     plain text element she edits herself, so the line break has to come
     from the box: 66% of the ring is wide enough to hold the sentence
     on one line at 18px and not at 24, which is why raising the size
     and narrowing the box are ONE change and not two. 58% puts "The
     closet keeps" on line one and "rotating" on line two at every phone
     width, because both the box and the type scale with vw together.
     ⚠ 24px IS THE CEILING AT 320px — the circle's inner width there is
     ~150px and a third line would touch the dots. */
  .landing-ring-hub {
    width: 58%;
  }

  .landing-ring-line {
    font-size: 24px;
    line-height: 1.06;
  }

  /* --- ROOM ABOVE AND BELOW. The top and bottom labels sit OUTSIDE the
     circle by design, so at 13px they need ~18px of clearance each or
     they crowd the section hairlines the way the 21px ones ran through
     them. This is margin on the ring, never padding on the beats —
     a beat's box is what its dot is positioned against. */
  .landing-ring {
    margin: 22px auto 18px;
  }
}

@media (max-width: 479px) {
  .landing-ring-beat.is-1,
  .landing-ring-beat.is-2,
  .landing-ring-beat.is-3,
  .landing-ring-beat.is-4,
  .landing-ring-beat.is-5,
  .landing-ring-beat.is-6 {
    font-size: 12px;
  }
  .landing-ring-line { font-size: 22px; }
}


/* =====================================================================
   v12 — S280. THE PHONE RING, THE SIZE THAT LETS BOTH THINGS FIT.
   ROLLBACK: delete from this v12 comment to the end of the file.

   ⚠⚠⚠ HER RULING: THE HUB LINE STAYS INSIDE THE CIRCLE. She was shown
   the alternative — move it below on the phone, which frees the circle
   to shrink and gives the line the whole column at 26px — and chose to
   keep the desktop arrangement intact. So the ring keeps its centre and
   the hub accepts a small size. DO NOT MOVE IT BELOW THE CIRCLE.

   ⚠⚠ THE ARITHMETIC THIS BLOCK IS SOLVING, SO IT IS NOT RE-DERIVED AND
   RE-TUNED BY EYE. Two things share one width and they pull opposite
   ways:
     · a side label gets  (viewport/2) − 20px − 32.909%·BOX
     · the hub line gets  (hub width %)·BOX, inside the circle
   Shrink the box and the labels breathe while the hub suffocates; grow
   it and the reverse. At 393px there is no box that gives the labels
   two lines AND the hub 22px. The settlement is a SMALLER BOX with a
   WIDER HUB: the hub takes a bigger share of a smaller circle.
   ▶ SO THE THREE NUMBERS BELOW ARE ONE DECISION. Change the box and the
   hub width and the hub size both need recomputing, or one of the two
   silently goes to three lines. -------------------------------------- */

@media (max-width: 767px) {

  /* 46vw, down from 62. At 393px that hands each side label ~117px
     instead of ~96, which is what takes "We inspect and grade" from
     four lines to two. Capped at 230 so it still stops growing before
     the desktop ring takes over at 768. */
  .landing-ring {
    width: 46vw;
    max-width: 230px;
    margin: 6px auto 14px;
  }

  /* THE HUB TAKES A BIGGER SHARE OF THE SMALLER CIRCLE — 72% against
     v11's 58%. ⚠ 72 IS A CEILING, NOT A TASTE VALUE: the circle's
     radius is 38% of the box, so a hub wider than 76% would put its
     text under the six dots. */
  .landing-ring-hub {
    width: 72%;
  }

  /* ⚠ 17px IS WHAT FITS "The closet keeps" ON ONE LINE AT 320px, the
     narrowest phone this has to hold, where the hub box is ~106px. It
     is smaller than v11's 24 and that is the cost she accepted when she
     kept the hub inside. Raising it breaks the line into three. */
  .landing-ring-line {
    font-size: 17px;
    line-height: 1.1;
  }
}

@media (max-width: 479px) {
  .landing-ring-line { font-size: 16px; }
}


/* =====================================================================
   v13 — S280. THE LABELS WERE NEVER GIVEN THE WIDTH. THE REAL FAULT.
   ROLLBACK: delete from this v13 comment to the end of the file.

   ⚠⚠⚠ AN ABSOLUTELY POSITIONED BOX ANCHORED BY `left` IS SHRINK-TO-FIT,
   AND THE SPACE IT IS OFFERED RUNS ONLY TO ITS CONTAINING BLOCK'S EDGE
   — NOT TO THE SCREEN'S. The beats are positioned against .landing-ring,
   which is 46vw. A right-pair label sits at left: 50% + 32.909% + 10px
   of that box, so the space left inside the box is
       BOX − (50% + 32.909% + 10px)  ≈  21px
   and the label collapses to its longest WORD. The left pair is the
   same fault mirrored through `right`.

   ⚠⚠⚠ AND max-width COULD NEVER HAVE FIXED IT. A max-width CAPS a
   width; it cannot GRANT space that was never offered. v10's
   `max-width: calc(50vw − 20px − 32.909%)` computed to ~117px and was
   simply never reached, so it looked like a value that did nothing —
   and three passes of type-shrinking were spent on a symptom.
   ✅ THE FIX IS `width`, WHICH REMOVES SHRINK-TO-FIT FROM THE QUESTION.
   The label then takes exactly the room between the circle and the
   screen edge, and the box is free to overflow its containing block,
   which is what an absolute box is allowed to do.

   ▶▶ THE RULE, GENERAL: WHEN AN ABSOLUTE BOX WRAPS HARDER THAN ITS
   max-width SAYS IT SHOULD, IT IS NOT BEING CAPPED — IT IS BEING OFFERED
   LESS. Print offsetWidth against the max-width; if the box is narrower
   than its own cap, the cap is not the thing deciding. Sibling of INERT
   RULES: every gate passes and the rule aims at nothing.
   ===================================================================== */

@media (max-width: 767px) {

  /* ⚠ `width`, NOT `max-width` — see above. The three terms are: half
     the screen, minus the 10px clearance plus a 10px margin off the
     screen edge, minus the label's own distance from centre (which is a
     PERCENTAGE OF THE RING BOX, so it scales with the ring). No
     breakpoint: the label is handed exactly what the circle leaves it,
     at every width. */
  .landing-ring-beat.is-2,
  .landing-ring-beat.is-3,
  .landing-ring-beat.is-5,
  .landing-ring-beat.is-6 {
    width: calc(50vw - 20px - 32.909%);
    max-width: none;
  }

  /* THE TOP AND BOTTOM PAIR ARE CENTRED, so they are offered the whole
     box either side of their own centre and were never starved. They
     take the full column instead of the box so a long label stays on
     one line, and translateX(-50%) keeps them centred on the axis. */
  .landing-ring-beat.is-1,
  .landing-ring-beat.is-4 {
    width: calc(100vw - 40px);
  }
}


/* =====================================================================
   v14 — S280. THE ENTRANCE AND THE LAP COME TO THE PHONE.
   ROLLBACK: delete from this v14 comment to the end of the file, which
   returns the phone to a static grey ring with coloured dots.

   ⚠⚠ THIS REVERSES v10's `.landing-ring-seg { display: none }`, WHICH
   WAS ALWAYS CONDITIONAL ON THIS. The arcs were hidden because without
   the lap they paint IN FULL and the phone would have shown a
   permanently rainbow ring that the desktop never shows. With the lap
   running there is nothing to hide from.

   ⚠⚠⚠ THESE DECLARATIONS ARE A **SECOND COPY** OF THE ONES INSIDE THE
   min-width:768 GATE, VALUE FOR VALUE. THE KEYFRAMES ARE NOT COPIED —
   they sit at top level and are shared, which is what keeps the two
   copies from drifting on the part that matters. IF A TIMING, A DELAY
   OR A PLAY-STATE CHANGES IN EITHER PLACE, CHANGE IT IN BOTH AND DIFF
   THEM. Same standing rule as the six dot colours in v10, and the same
   reason: the gate exists to protect the RAIL, which no longer runs
   here, but unpicking it is a structural edit to a proven, shipped
   block and this is not the session for that.
   ▶ THE HONEST TIDY-UP LATER: drop the min-width wrapper from the
   animation half entirely so one copy governs both widths. It is a
   deliberate job with its own verification, not a drive-by.

   ✅ WHY THE ENTRANCE KEYFRAMES NEED NO PHONE VARIANT: every pop and
   rise carries its element's OWN positioning transform, and the phone
   beats use the IDENTICAL transforms to the desktop ones — translate
   (-50%,-100%) at twelve, translateX(-50%) at six, translateY(-50%) on
   the four sides. Only the offsets differ, and offsets are not in the
   keyframes. If a future phone layout changes a beat's transform, its
   keyframe has to change with it or the beat will jump on entrance.

   ✅ AND THE LAP STILL PAUSES OFF-SCREEN. landing.js toggles
   `.is-lapping` on .landing-ring with no width test of its own, so the
   phone gets that behaviour for free and nothing moves behind a reader
   three sections down.
   ===================================================================== */

@media (max-width: 767px) {

  .landing-ring-seg { display: inline; }
  .landing-ring-arm { display: block; }

  html.landing-motion .landing-ring-seg {
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
  }

  /* THE ENTRANCE — one shot, armed by `.is-in` off the section reveal,
     never off page load. */
  html.landing-motion .landing-cycle.is-in .landing-ring-base {
    stroke-dasharray: 100;
    animation: landing-ring-trace 1.4s cubic-bezier(.4, 0, .2, 1) both;
  }

  html.landing-motion .landing-cycle.is-in .landing-ring-endmark {
    opacity: 0;
    animation: landing-ring-endin .3s linear 1.4s forwards;
  }

  html.landing-motion .landing-cycle.is-in .landing-ring-hub {
    animation: landing-ring-hubin .6s cubic-bezier(.4, 0, .2, 1) 1.55s both;
  }

  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-1::after { animation: landing-ring-pop-1    .32s cubic-bezier(.4,0,.2,1) 0.000s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-1        { animation: landing-ring-rise-top  .5s cubic-bezier(.4,0,.2,1) 0.140s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-2::after { animation: landing-ring-pop-234  .32s cubic-bezier(.4,0,.2,1) 0.243s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-2        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 0.383s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-3::after { animation: landing-ring-pop-234  .32s cubic-bezier(.4,0,.2,1) 0.486s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-3        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 0.626s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-4::after { animation: landing-ring-pop-234  .32s cubic-bezier(.4,0,.2,1) 0.728s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-4        { animation: landing-ring-rise-bot  .5s cubic-bezier(.4,0,.2,1) 0.868s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-5::after { animation: landing-ring-pop-56   .32s cubic-bezier(.4,0,.2,1) 0.971s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-5        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 1.111s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-6::after { animation: landing-ring-pop-56   .32s cubic-bezier(.4,0,.2,1) 1.214s both; }
  html.landing-motion .landing-cycle.is-in .landing-ring-beat.is-6        { animation: landing-ring-rise-side .5s cubic-bezier(.4,0,.2,1) 1.354s both; }

  /* THE LAP — forever, one 10.00s cycle shared by every looping element.
     ⚠ DO NOT GIVE ANY ONE OF THESE ITS OWN DURATION. Their moments are
     percentages inside that one cycle, so a different duration anywhere
     means the arrow lays an arc that is already painted. */
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-1 { animation: landing-ring-lap-1 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-2 { animation: landing-ring-lap-2 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-3 { animation: landing-ring-lap-3 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-4 { animation: landing-ring-lap-4 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-5 { animation: landing-ring-lap-5 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-seg.is-6 { animation: landing-ring-lap-6 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-arm      { animation: landing-ring-sweep 10.00s linear 2.00s infinite; }
  html.landing-motion .landing-cycle.is-in .landing-ring-trav     { animation: landing-ring-hue 10.00s step-end 2.00s infinite; }

  html.landing-motion .landing-cycle.is-in .landing-ring-seg,
  html.landing-motion .landing-cycle.is-in .landing-ring-arm,
  html.landing-motion .landing-cycle.is-in .landing-ring-trav {
    animation-play-state: paused;
  }

  html.landing-motion .landing-cycle.is-in .landing-ring.is-lapping .landing-ring-seg,
  html.landing-motion .landing-cycle.is-in .landing-ring.is-lapping .landing-ring-arm,
  html.landing-motion .landing-cycle.is-in .landing-ring.is-lapping .landing-ring-trav {
    animation-play-state: running;
  }
}


/* =====================================================================
   v15 — S280. BEATS 2 AND 6 WRAP TO TWO LINES. HERS.
   ROLLBACK: delete from this v15 comment to the end of the file.

   ⚠⚠ THE CAP IS IN `ch`, NOT PIXELS, AND THAT IS THE WHOLE TRICK. A ch
   is the width of the font's own "0", so a cap written this way SCALES
   WITH THE TYPE — the 479 block drops these labels to 12px and the cap
   comes down with them, keeping the same wrap. A px cap would be right
   at one size and wrong at the other, silently.

   ⚠⚠⚠ AND max-width WORKS HERE WHERE IT FAILED AT v13, WHICH IS NOT A
   CONTRADICTION: v13 set an explicit `width`, so there IS now a width
   to cap. A max-width can only ever narrow a width that exists; at v13
   the box was shrink-to-fit and there was nothing for it to act on.
   ▶ IF THIS CAP EVER APPEARS TO DO NOTHING, CHECK THAT v13's `width`
   IS STILL THERE FIRST.

   ⚠ 10ch IS CHOSEN AGAINST THE TWO LABELS, NOT PICKED ROUND: it breaks
   "We inspect / and grade" and "They / outgrow it". Widen it and beat 6
   goes back to one long line; narrow it and beat 6 strands "it" on a
   line of its own, which is the break she rejected at v11. THE TWO
   FAILURES SIT EITHER SIDE OF THIS VALUE.

   ⚠ BEAT 3 IS DELIBERATELY NOT CAPPED. "You earn credits" reads fine on
   one line and she named 2 and 6 only. The right side is therefore
   uneven by instruction, not by oversight — do not "balance" it. */

@media (max-width: 767px) {
  .landing-ring-beat.is-2,
  .landing-ring-beat.is-6 {
    max-width: 10ch;
  }
}

/* ==========================================================================
   /pricing  —  PAGE-SCOPED  —  v16, S281
   ⚠⚠⚠ EVERY RULE HERE IS WRITTEN AT TWO CLASSES, .landing-wrap.pricing-page,
   for the same reason .standard-page and .how-it-works-page are: it beats the
   shared rule AND IT CANNOT MATCH ON ANOTHER LANDING PAGE. Add the combo class
   in the Designer and LEAVE IT UNSTYLED THERE.

   HER RULING S281, off the C1 mockup: ink-outlined cards, two by two, with a
   COLOURED CAP across the top. The cap is a MARK, not a surface, so it carries
   no contrast obligation — the same reason the amber rule under the section
   headings works where coral and green both failed on /browse.

   ⚠⚠ MEASURED, NOT ASSUMED, AND IT IS WHY NOTHING HERE IS FILLED: cream on
   coral reads 3.23 and on green 3.25, both under the bar. Only navy takes
   cream (7.25). Ink passes on all four. IF A FILLED VARIANT IS EVER BUILT,
   INK TEXT ON EVERYTHING EXCEPT NAVY.

   ⚠ THE PLAN COLOUR IS ONE CUSTOM PROPERTY SET ON THE CARD and read by the
   cap. Re-assigning which plan is which colour is four lines in one place.
   Green on toys matches the meaning it already carries in signup; the others
   are free under her S236 palette ruling.
   ========================================================================== */

.landing-wrap.pricing-page .landing-plan-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.landing-wrap.pricing-page .landing-plan-card {
  --plan-colour: var(--landing-coral);
  position: relative;
  border: 1px solid var(--landing-ink);
  border-radius: 6px;
  padding: 0 0 22px;
  overflow: hidden;
}

.landing-wrap.pricing-page .landing-plan-card.is-basics     { --plan-colour: var(--landing-coral); }
.landing-wrap.pricing-page .landing-plan-card.is-toys       { --plan-colour: #309359; }
.landing-wrap.pricing-page .landing-plan-card.is-wardrobe   { --plan-colour: #1C4A91; }
.landing-wrap.pricing-page .landing-plan-card.is-everything { --plan-colour: var(--landing-amber); }

/* THE CAP IS ITS OWN ELEMENT, NOT A ::before, on purpose: the draw animates
   transform: scaleX and needs transform-origin: left, and an element is what a
   future session can find in Navigator. overflow:hidden on the card is what
   keeps it inside the radius. */

.landing-wrap.pricing-page .landing-plan-cap {
  display: block;
  height: 8px;
  background-color: var(--plan-colour);
  transform-origin: left center;
}

.landing-wrap.pricing-page .landing-plan-name {
  margin: 20px 20px 0;
  font-family: "Instrument Serif", Georgia, serif;
  font-style: normal;
  font-weight: 400;
  font-size: 26px;
  line-height: 1.1;
  color: var(--landing-ink);
}

.landing-wrap.pricing-page .landing-plan-swaps {
  margin: 6px 20px 0;
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 15px;
  line-height: 1.5;
  color: var(--landing-ink);
}

.landing-wrap.pricing-page .landing-plan-value {
  margin: 2px 20px 0;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  color: var(--landing-muted);
}

.landing-wrap.pricing-page .landing-plan-price {
  display: block;
  margin: 16px 20px 0;
  font-family: Quicksand, sans-serif;
  font-weight: 700;
  font-size: 24px;
  line-height: 1;
  color: var(--landing-ink);
}

.landing-wrap.pricing-page .landing-plan-price small {
  display: block;
  margin-top: 5px;
  font-weight: 500;
  font-size: 13px;
  color: var(--landing-muted);
}

/* --------------------------------------------------------------------------
   MOTION  —  M3, HERS. Each card rises, then its own cap draws 250ms behind it.
   Two beats a card, four cards, one sweep.

   ⚠⚠⚠ NO landing.js CHANGE. `.is-in` is already added to every .landing-section
   by the existing observer, once, and then unobserved. This whole block hangs
   off that class.

   ⚠⚠ THE 300ms BASE DELAY IS LOAD-BEARING, NOT TASTE: the section itself runs
   landing-rise for 0.5s, so a card starting at 0 races its own parent's fade
   and the stagger is invisible inside it.

   ⚠ KEYFRAMES, NEVER TRANSITIONS (S247), and `both` fill holds the start state
   through the delay so no card flashes early. Hidden ONLY under
   html.landing-motion inside prefers-reduced-motion — no script or reduced
   motion means four finished cards sitting still, never an empty section.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {

  html.landing-motion .landing-wrap.pricing-page .landing-plan-card { opacity: 0; }
  html.landing-motion .landing-wrap.pricing-page .landing-plan-cap  { transform: scaleX(0); }

  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card {
    animation: landing-plan-deal 0.55s cubic-bezier(.4, 0, .2, 1) both;
  }
  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-cap {
    animation: landing-plan-cap-draw 0.60s cubic-bezier(.4, 0, .2, 1) both;
  }

  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(1) { animation-delay: 0.30s; }
  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(2) { animation-delay: 0.42s; }
  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(3) { animation-delay: 0.54s; }
  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(4) { animation-delay: 0.66s; }

  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(1) .landing-plan-cap { animation-delay: 0.55s; }
  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(2) .landing-plan-cap { animation-delay: 0.67s; }
  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(3) .landing-plan-cap { animation-delay: 0.79s; }
  html.landing-motion .landing-wrap.pricing-page .landing-section.is-in .landing-plan-card:nth-child(4) .landing-plan-cap { animation-delay: 0.91s; }

}

@keyframes landing-plan-deal {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes landing-plan-cap-draw {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* --------------------------------------------------------------------------
   MOBILE TWINS. These sit AFTER the desktop rules above, which is what lets
   them win — this file ends at top level and an appended bare rule would
   otherwise beat a media query written earlier in the file by source order.
   The stagger is KEPT on one column, matching the FAQ rows and the ring.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  .landing-wrap.pricing-page .landing-plan-cards { grid-template-columns: 1fr; }
  .landing-wrap.pricing-page .landing-plan-name  { font-size: 24px; }
}

/* ==========================================================================
   /pricing  —  v17, S281.  TWO ADDITIONS, BOTH PAGE-SCOPED.
   ========================================================================== */

/* --------------------------------------------------------------------------
   THE BILLING NOTE
   ⚠ v16 styled this line as a `small` INSIDE .landing-plan-price, and WEBFLOW
   CANNOT MAKE ONE — its Text block is a div. So it is its own element with its
   own class. The v16 `small` rule is LEFT IN PLACE and is inert on this page;
   it is not deleted because it costs nothing and a hand-written embed could
   still use it. DO NOT read its presence as evidence the markup uses a `small`.
   -------------------------------------------------------------------------- */

.landing-wrap.pricing-page .landing-plan-note {
  margin: 5px 20px 0;
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.4;
  color: var(--landing-muted);
}

/* --------------------------------------------------------------------------
   THE SEO BLOCK — SPACING ONLY, DELIBERATELY NOT TYPE.
   ⚠⚠ HER S277 RULING STANDS: this block is the SAME ARTIFACT as the one on
   /browse, /clothing and /toys, and it renders through Webflow's own classes on
   all four. Restyling its type here would break that set. THESE RULES ADD ROOM
   AND NOTHING ELSE — no font, no size, no colour.

   ⚠⚠⚠ IT ONLY WORKS IF seo-content-bottom-of-page IS MOVED INSIDE
   .landing-card. Left where it is, outside .landing-wrap, NOTHING HERE MATCHES
   and the block renders on white against the card's cream. That is a Designer
   drag, not a code change, and it is the same move already owed on
   /how-it-works.

   ⚠ The hairline and the 46px echo .landing-section's own rhythm, so the block
   reads as the page's last section rather than as something stuck underneath.
   CLAUDE'S CALL, REVERSIBLE — delete these two rules and it is a plain gap.
   -------------------------------------------------------------------------- */

.landing-wrap.pricing-page .seo-content-bottom-of-page {
  display: block;
  margin-top: 46px;
  padding: 46px 0 0;
  border-top: 1px solid var(--landing-hairline);
}

.landing-wrap.pricing-page .seo-content-div {
  max-width: 660px;
  margin-left: 0;
  margin-right: auto;
  padding: 0;
}

@media (max-width: 767px) {
  .landing-wrap.pricing-page .seo-content-bottom-of-page {
    margin-top: 36px;
    padding-top: 36px;
  }
  .landing-wrap.pricing-page .landing-plan-note { margin-top: 4px; }
}

/* ==========================================================================
   /pricing  —  v18, S281.  FOUR FIXES, ALL PAGE-SCOPED.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. THE CARD HOVER, HERS.
   ⚠⚠⚠ IT CANNOT USE transform, AND THIS IS NOT A PREFERENCE. The v16 entrance
   runs `landing-plan-deal` with `both` fill, so the animation's end value —
   transform: translateY(0) — KEEPS APPLYING after it finishes and BEATS any
   declaration in the cascade. A hover written as translateY would verify
   clean, ship, and do absolutely nothing. Same family as INERT RULES.
   So the hover moves the border and lays a bar of the plan's own colour under
   the card. Both are properties the entrance never touches.

   ⚠ A TRANSITION IS CORRECT HERE, unlike the entrance: this fires on a state
   change on a page that has already painted, so there is no paint race to
   lose. S247's keyframe rule is about entrances.

   ⚠ HOVER DOES NOT EXIST ON A PHONE. This is decoration for a mouse and
   nothing on the card depends on it — the card is not a link, and the one CTA
   sits below the grid.
   -------------------------------------------------------------------------- */

.landing-wrap.pricing-page .landing-plan-card {
  transition: box-shadow 0.22s ease, border-color 0.22s ease;
}

.landing-wrap.pricing-page .landing-plan-card:hover {
  border-color: var(--plan-colour);
  box-shadow: 0 5px 0 -1px var(--plan-colour);
}

@media (prefers-reduced-motion: reduce) {
  .landing-wrap.pricing-page .landing-plan-card { transition: none; }
}

/* --------------------------------------------------------------------------
   2. ROOM ABOVE THE FOOTNOTE, HERS. The shared rule gives it 16px, which is
   correct under a paragraph and too tight under a 50px-tall pill.
   -------------------------------------------------------------------------- */

.landing-wrap.pricing-page .landing-cta-note {
  margin-top: 30px;
}

/* --------------------------------------------------------------------------
   3. DOTS ON THE INCLUDES LIST, HERS.
   ⚠⚠ IT NEEDS A COMBO CLASS IN THE DESIGNER: add `is-includes` alongside
   `landing-section` on that ONE section. Without it nothing here matches —
   the six lines are plain paragraphs with no class of their own, and a rule
   written at `.landing-section-body p` would put a dot on every paragraph on
   the page, including the closing line and the answers.

   ⚠ THE DOT IS THE SAME DEVICE AS .landing-figure::before — 6px, amber, on a
   pseudo — so the page carries one accent language rather than two. It is a
   MARK, not a bullet: the markup stays paragraphs, because a real list would
   need every line rebuilt as an li.
   -------------------------------------------------------------------------- */

.landing-wrap.pricing-page .landing-section.is-includes .landing-section-body p {
  position: relative;
  padding-left: 22px;
  margin-bottom: 1.35em;
}

.landing-wrap.pricing-page .landing-section.is-includes .landing-section-body p::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: var(--landing-amber);
}

/* --------------------------------------------------------------------------
   4. THE SEO BLOCK GOES FULL WIDTH — REVERSING v17, HERS.
   v17 capped it at a 660 reading measure. She wants the card's full width, so
   the cap is removed rather than left in and overridden. The spacing half of
   v17 stays: it is what puts the hairline and the room above it.
   -------------------------------------------------------------------------- */

.landing-wrap.pricing-page .seo-content-div {
  max-width: none;
}

@media (max-width: 767px) {
  .landing-wrap.pricing-page .landing-cta-note { margin-top: 24px; }
  .landing-wrap.pricing-page .landing-section.is-includes .landing-section-body p {
    padding-left: 20px;
    margin-bottom: 1.2em;
  }
}

/* ==========================================================================
   THE CLOSING BLOCK ON THE SPINE  —  v19, S281.
   ⚠⚠⚠ THE ONLY RULE IN THIS FILE'S RECENT HISTORY THAT IS **NOT**
   PAGE-SCOPED, AND THAT IS DELIBERATE — HER ASK WAS THAT THE OTHER LANDING
   PAGES DO NOT HIT THE SAME FAULT.

   THE FAULT, OFF HER LIVE RENDER: a full-width closing block puts a 34px
   ROMAN serif at the card's left edge, which is exactly where the ITALIC
   section headings sit. It reads as a section heading wearing the wrong
   style, and the right two-thirds of the row is empty. Moving the block onto
   the spine removes the collision rather than restyling around it.

   ⚠⚠⚠ THE CHILD COMBINATOR IS THE GUARD AND IT IS LOAD-BEARING.
   `.landing-card > .landing-cta-row` matches ONLY a closing block that is a
   DIRECT child of the card, i.e. one that is already full width. A
   .landing-cta-row nested INSIDE a .landing-section-body is already in the
   right-hand column, and a bare `.landing-cta-row` rule would push it a
   further 350px and wreck it. That shape is live on /how-it-works and the
   closet standard AND HAS NOT BEEN READ — the combinator means it does not
   have to be. DO NOT LOOSEN THIS TO ONE CLASS.

   ⚠ 350 IS NOT A ROUND NUMBER: it is the section grid's 290px rail plus its
   60px gap. CHANGE EITHER AND THIS MOVES WITH THEM.

   ⚠ THE EMPTY LEFT RAIL IS THE POINT, not an oversight. It is what keeps the
   block reading as a closer rather than as one more section.
   ========================================================================== */

.landing-card > .landing-cta-row {
  padding-left: 350px;
  margin-top: 52px;
  padding-top: 46px;
  border-top: 1px solid var(--landing-hairline);
}

/* --------------------------------------------------------------------------
   991 AND BELOW — THE INDENT GOES, and that is why this option was chosen
   over a centred one. The section grid collapses to one column here, so a
   350px indent would be indenting against a rail that no longer exists.
   Below 991 this block is byte-for-byte what shipped before v19.
   -------------------------------------------------------------------------- */

@media (max-width: 991px) {
  .landing-card > .landing-cta-row {
    padding-left: 0;
    margin-top: 44px;
    padding-top: 40px;
  }
}

@media (max-width: 767px) {
  .landing-card > .landing-cta-row {
    margin-top: 36px;
    padding-top: 36px;
  }
}


/* ==========================================================================
   v20 — /about, S284
   EVERY RULE BELOW IS WRITTEN .landing-wrap.about-page — THREE CLASSES, so it
   beats the shared landing rules on SPECIFICITY rather than on source order,
   and it CANNOT reach /how-it-works, /pricing or /the-closet-standard.
   about-page is a combo class added in the Designer and deliberately left
   unstyled there, the same device as .faq-page and .how-it-works-page.

   APPENDED AT TOP LEVEL. v19 is a BYTE-EXACT PREFIX of this file, so
   ROLLBACK IS DELETING FROM THIS COMMENT TO THE END OF THE FILE.
   ========================================================================== */

.landing-wrap.about-page {
  --about-navy: #1C4A91;
  --about-panel-text: #E9E7DC;
}

/* --------------------------------------------------------------------------
   MASTHEAD — headline left, answer block right, photo band beneath.
   GRID AREAS, NOT flex order and NOT duplicated markup: at 767 the band has
   to move ABOVE the headline, while the MARKUP order stays headline, answer,
   photo — so a crawler and an AI engine still read the headline and the
   answer paragraph first whatever a phone shows first. Areas do that with no
   wrapper element.
   ⚠ The answer block is NOT stretched to fill the card. At full width it runs
   ~100 characters a line, well past readable. The space is used by putting
   two elements side by side instead.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .landing-masthead {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  column-gap: 60px;
  align-items: end;
  grid-template-areas:
    "eyebrow eyebrow"
    "head    sub"
    "band    band";
}

.landing-wrap.about-page .landing-eyebrow {
  grid-area: eyebrow;
  color: var(--landing-coral);
}

.landing-wrap.about-page .landing-masthead-heading {
  grid-area: head;
  margin: 18px 0 0;
  max-width: none;
  font-size: 58px;
}

.landing-wrap.about-page .landing-sub {
  grid-area: sub;
  margin: 18px 0 6px;
  max-width: 44ch;
  font-size: 17px;
  line-height: 1.62;
}

/* --------------------------------------------------------------------------
   FOUNDER BAND — photo with the navy panel hanging off its bottom-left.
   ⚠⚠ THE -96px PULL AND THE 5/2 RATIO ARE ONE DECISION, HER RULING S284.
   The overlap is a fixed pixel value against a photo whose height scales with
   the column, so changing the ratio changes how much of the photo the panel
   covers. Change one, re-judge the other.
   ⚠ The photo is a DIV, never an Image element, so the page is complete before
   any photo exists. SWAPPING IN THE PHOTO IS ONE PROPERTY: drop
   background-color, add background-image / background-size:cover /
   background-position. NO DESIGNER WORK.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .landing-founder-band {
  grid-area: band;
  position: relative;
  margin-top: 46px;
}

.landing-wrap.about-page .landing-founder-photo {
  width: 100%;
  aspect-ratio: 5 / 2;
  background-color: var(--landing-placeholder);
}

.landing-wrap.about-page .landing-founder-panel {
  position: relative;
  z-index: 2;
  width: min(520px, 84%);
  margin: -96px 0 0 34px;
  padding: 34px 38px;
  background-color: var(--about-navy);
}

.landing-wrap.about-page .landing-founder-heading {
  margin: 0;
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 34px;
  line-height: 1.14;
  color: var(--landing-cream);
}

/* Same amber ::after device as .landing-section-heading, so the panel reads as
   a section of this page rather than as a foreign object. */

.landing-wrap.about-page .landing-founder-heading::after {
  content: "";
  display: block;
  width: 32px;
  height: 3px;
  margin-top: 14px;
  background-color: var(--landing-amber);
}

/* ⚠ THE STAR IS ABSOLUTE AGAINST THE PANEL, NOT THE BAND — the panel carries
   position:relative above. It sits between the heading and the body in the
   markup and must stay EMPTY: it is a clip-path shape, so anything inside it
   is cut into a five-pointed hole. */

.landing-wrap.about-page .landing-founder-star {
  position: absolute;
  right: 26px;
  top: 22px;
  width: 50px;
  height: 50px;
  z-index: 3;
  pointer-events: none;
  background-color: var(--landing-pink);
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

.landing-wrap.about-page .landing-founder-body {
  margin: 18px 0 0;
  max-width: 42ch;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 16px;
  line-height: 1.7;
  color: var(--about-panel-text);
}

/* --------------------------------------------------------------------------
   SECTIONS
   is-first drops the hairline and the top padding so the navy panel runs
   straight into the story — HER RULING S284. The combo is what keeps that off
   every other landing page.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .landing-section.is-first {
  margin-top: 52px;
  padding-top: 0;
  border-top: 0;
}

.landing-wrap.about-page .landing-section-link {
  display: inline-block;
  margin-top: 18px;
  padding-bottom: 3px;
  border-bottom: 2px solid var(--landing-amber);
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--landing-coral);
}

/* The Closet Standard link is INLINE inside its paragraph, made with Cmd+K, so
   it carries no class of its own and is reached through the paragraph. A
   background gradient rather than text-decoration, so the amber sits clear of
   the descenders. */

.landing-wrap.about-page .landing-section-body p a {
  color: var(--landing-ink);
  font-weight: 600;
  text-decoration: none;
  padding-bottom: 1px;
  background: linear-gradient(var(--landing-amber), var(--landing-amber)) no-repeat 0 100% / 100% 2px;
}

/* --------------------------------------------------------------------------
   THE CLOSE
   .landing-card > .landing-cta-row already carries the 350px spine indent and
   its own hairline from v19 — nothing here touches it. Only the lead
   paragraph and the button label are new.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .landing-cta-lead {
  margin: 0 0 26px;
  max-width: 46ch;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 17px;
  line-height: 1.6;
  color: var(--landing-ink);
}

.landing-wrap.about-page .landing-cta-label {
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
  color: inherit;
}

/* --------------------------------------------------------------------------
   WORKING TOGETHER
   Built on the SAME 290 + 60 rail as .landing-section, so it reads as another
   section addressed to a different reader rather than as a caption on the
   button. HER NOTE S284: it was sitting too close to the CTA.
   ⚠⚠ THE THREE CHILDREN ARE PLACED EXPLICITLY. Auto-placement would put the
   label in column 1, the body in column 2 and then the LINK BACK IN COLUMN 1
   on the next row, under the label — correct-looking markup, wrong column,
   nothing erroring.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .landing-partner-row {
  display: grid;
  grid-template-columns: 290px 1fr;
  gap: 60px;
  align-items: start;
  margin-top: 46px;
  padding-top: 34px;
  border-top: 1px solid var(--landing-hairline);
}

.landing-wrap.about-page .landing-partner-label {
  grid-column: 1;
  grid-row: 1;
  margin: 4px 0 0;
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--landing-muted);
}

.landing-wrap.about-page .landing-partner-body {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  max-width: 56ch;
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 15px;
  line-height: 1.65;
  color: var(--landing-ink);
}

.landing-wrap.about-page .landing-partner-link {
  grid-column: 2;
  grid-row: 2;
  justify-self: start;
  margin-top: 12px;
  padding-bottom: 3px;
  border-bottom: 2px solid var(--landing-amber);
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--landing-coral);
}

/* The SEO block is the SAME artifact as /browse, /clothing and /toys and keeps
   their type. Only its separation from the page above it is set here, scoped,
   so this cannot reach those three pages. */

.landing-wrap.about-page .seo-content-div {
  margin-top: 46px;
  padding-top: 30px;
  border-top: 1px solid var(--landing-hairline);
}

@media (max-width: 991px) {
  .landing-wrap.about-page .landing-masthead {
    grid-template-columns: 1fr;
    grid-template-areas:
      "eyebrow"
      "head"
      "sub"
      "band";
  }

  .landing-wrap.about-page .landing-masthead-heading {
    font-size: 46px;
  }

  .landing-wrap.about-page .landing-sub {
    max-width: 62ch;
    margin: 22px 0 0;
  }

  .landing-wrap.about-page .landing-partner-row {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .landing-wrap.about-page .landing-partner-label,
  .landing-wrap.about-page .landing-partner-body,
  .landing-wrap.about-page .landing-partner-link {
    grid-column: 1;
    grid-row: auto;
  }
}

/* ⚠⚠ AT 767 THE PHOTO MOVES ABOVE THE HEADLINE — HER RULING S284. Only the
   grid-template-areas line does it; the markup is untouched. */

@media (max-width: 767px) {
  .landing-wrap.about-page .landing-masthead {
    grid-template-areas:
      "eyebrow"
      "band"
      "head"
      "sub";
  }

  .landing-wrap.about-page .landing-masthead-heading {
    margin: 34px 0 0;
    font-size: 36px;
  }

  .landing-wrap.about-page .landing-sub {
    margin: 18px 0 0;
    font-size: 16px;
  }

  .landing-wrap.about-page .landing-founder-band {
    margin-top: 22px;
  }

  .landing-wrap.about-page .landing-founder-photo {
    aspect-ratio: 3 / 2;
  }

  .landing-wrap.about-page .landing-founder-panel {
    width: auto;
    margin: -56px 14px 0;
    padding: 26px 22px;
  }

  .landing-wrap.about-page .landing-founder-heading {
    font-size: 28px;
  }

  .landing-wrap.about-page .landing-founder-star {
    right: 18px;
    top: 14px;
    width: 40px;
    height: 40px;
  }

  .landing-wrap.about-page .landing-founder-body {
    font-size: 15px;
  }

  .landing-wrap.about-page .landing-section.is-first {
    margin-top: 34px;
  }

  .landing-wrap.about-page .landing-cta-primary {
    display: block;
    text-align: center;
  }
}


/* ==========================================================================
   v21 — /about, S284. TWO FIXES, BOTH PAGE-SCOPED.
   APPENDED AT TOP LEVEL. v20 is a BYTE-EXACT PREFIX of this file, so
   ROLLBACK IS DELETING FROM THIS COMMENT TO THE END OF THE FILE.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. THE PARTNER ROW'S LINK SAT 72px BELOW ITS OWN PARAGRAPH.
   `gap: 60px` is a SHORTHAND and sets ROW gap as well as column gap, so the
   link inherited 60px plus its own 12px margin. The column gap is the only
   one this row wants — the label and the body sit side by side, the link sits
   directly under the body.
   ▶ WHENEVER A GRID'S CHILDREN STACK IN ONE COLUMN, `gap` IS TWO VALUES, NOT
   ONE. Nothing errors and the row simply reads loose.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .landing-partner-row {
  column-gap: 60px;
  row-gap: 0;
}

/* --------------------------------------------------------------------------
   2. THE SEO BLOCK — LEFT, QUIETER, AND ON A READING MEASURE. HER RULING S284.

   ⚠⚠⚠ THIS KNOWINGLY REVERSES HER S277 RULING, WHICH IS RECORDED ABOVE IN
   THE /pricing BLOCK AS "the SAME ARTIFACT ... restyling its type here would
   break that set". SHE HAS RULED THE OTHER WAY: every SEO block on the site
   is to look like this one. /about is the first; /browse, /clothing and /toys
   are styled from browse-tool.js at runtime and are a THREE-PAGE PIN BUMP, so
   they are banked for the SEO run rather than done here. UNTIL THEY MOVE,
   THIS PAGE IS DELIBERATELY THE ODD ONE OUT.

   ⚠⚠ AND IT COLLIDES WITH HER v18 /pricing RULING, which took the cap OFF
   that page's block to make it full width. A 13px line across the full 1010
   card is ~130 characters, about double a readable measure. When the set
   moves, /pricing keeps its full width or that ruling is reversed too.
   HERS, UNSETTLED, NOT DECIDED HERE.

   ⚠ The heading is UNTOUCHED — already left, already matching the other
   pages, and only the body was ever centred.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .seo-content-div .body-text-dark {
  max-width: 78ch;
  text-align: left;
  font-size: 13px;
  line-height: 1.55;
  color: var(--landing-muted);
}


/* ==========================================================================
   v22 — /about, S284. THE SEO BLOCK BLENDS IN. HER RULING.
   APPENDED AT TOP LEVEL. v21 is a BYTE-EXACT PREFIX, so ROLLBACK IS DELETING
   FROM THIS COMMENT TO THE END OF THE FILE.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. THE BLOCK MOVES TO THE CARD'S LEFT EDGE.
   It was sitting indented because the shared `seo-content-div` CENTRES ITSELF
   with auto margins and a max-width — the same override /pricing already
   carries. HER RULING: it lines up with the text above it, which on this page
   is the W of WORKING TOGETHER, i.e. the card's own left edge, NOT the 350px
   spine the closing block sits on.
   ⚠ The reading measure is not lost: the 78ch cap from v21 lives on the body
   text, so removing the wrapper's cap changes WHERE the block starts and not
   how long its lines are.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .seo-content-div {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  padding-left: 0;
  padding-right: 0;
}

/* --------------------------------------------------------------------------
   2. THE HEADING STOPS BEING A HEADING TO LOOK AT. HER RULING, VERBATIM:
   "it doesnt need to stand out on the page at all, the point is actually for
   it all to blend in."
   It was Instrument Serif at 35px, the loudest thing on the lower half of the
   page, sitting on top of the quietest. Now it matches the body exactly.

   ⚠⚠ IT IS STILL AN <h2> AND THAT IS THE POINT — the tag is what a crawler
   and a screen reader read, and it is untouched. Only its appearance changes.
   A heading that looks like body text is still a heading; a paragraph styled
   to look like one is not.

   ⚠ Weight 500 rather than 400 is CLAUDE'S CALL, REVERSIBLE — one step of
   weight so the line is findable when you are scanning for it, with no size
   or colour difference at all. Take it to 400 and it is indistinguishable.
   -------------------------------------------------------------------------- */

.landing-wrap.about-page .seo-content-heading {
  margin: 0 0 14px;
  max-width: 78ch;
  font-family: Quicksand, sans-serif;
  font-style: normal;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.55;
  letter-spacing: 0;
  text-align: left;
  color: var(--landing-muted);
}

/* ============================================================================
   v23 — S285 — /terms-of-service
   Page-scoped under .landing-wrap.terms-page. Every selector in this block
   carries that combo, so nothing here can reach another landing page.

   TWO THINGS THIS EXISTS TO BEAT, both measured live at S285:
   1. .landing-section is a 290px / 660px grid. On this page the section has
      ONE child (the body), so the body took cell ONE and the document
      overflowed a 290px rail. A legal document reads as one column.
   2. Webflow's site-wide `All H2` TAG selector paints these headings
      #F2F1EB at weight 500. On cream that is near-invisible, and Instrument
      Serif ships ONE weight so 500 is a browser-FAKED bold.
      DO NOT FIX EITHER IN THE STYLE PANEL — All H2 reaches all 20 pages.
   -------------------------------------------------------------------------- */

.landing-wrap.terms-page .landing-section {
  display: block;
}

.landing-wrap.terms-page .landing-section-body {
  width: 100%;
  max-width: none;
}

/* The section headings. 400 is not a taste value — it is the only weight
   Instrument Serif has. Anything heavier is synthesised. */
.landing-wrap.terms-page .landing-richtext h2 {
  margin: 52px 0 16px;
  padding-top: 30px;
  border-top: 1px solid var(--landing-hairline);
  font-family: "Instrument Serif", serif;
  font-style: normal;
  font-weight: 400;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: -0.2px;
  color: var(--landing-ink);
}

.landing-wrap.terms-page .landing-richtext h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* Body. The measure cap is what stops a 1010px card running 130 characters
   to the line; the card itself is not narrowed, so the masthead is untouched. */
.landing-wrap.terms-page .landing-richtext p {
  margin: 0 0 14px;
  max-width: 72ch;
  font-family: Quicksand, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  color: var(--landing-ink);
}

/* The effective date is the first line of the document and reads as metadata
   rather than as a term. Muted, and it is the ONLY p rule keyed on position. */
.landing-wrap.terms-page .landing-richtext > p:first-child {
  margin-bottom: 34px;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--landing-muted);
}

@media screen and (max-width: 767px) {
  .landing-wrap.terms-page .landing-richtext h2 {
    margin-top: 40px;
    padding-top: 24px;
    font-size: 24px;
  }

  .landing-wrap.terms-page .landing-richtext p {
    max-width: none;
    font-size: 16px;
    line-height: 1.65;
  }
}

/* ============================================================================
   v24 — S286 — /privacy-policy
   Page-scoped under .landing-wrap.privacy-page. Every selector in this block
   carries that combo, so nothing here can reach another landing page.

   THE SAME TWO FAULTS v23 EXISTS TO BEAT, measured live at S286 on this page:
   1. .landing-section is a 290px / 660px grid. This page's section has ONE
      child (the body), so the body took cell ONE and the whole document
      rendered in a 290px rail. A legal document reads as one column.
   2. Webflow's site-wide `All H2` TAG selector paints these headings
      #F2F1EB at weight 500 — read back rgb(242,241,235)/500 on the live
      page. Near-invisible on cream, and Instrument Serif ships ONE weight
      so 500 is a browser-FAKED bold.
      DO NOT FIX EITHER IN THE STYLE PANEL — All H2 reaches all 20 pages.

   ⚠ ONE DELIBERATE DIFFERENCE FROM v23. The terms document opens with an h2,
   so v23 carries an h2:first-child rule killing the hairline above it. THIS
   document opens with two metadata lines and three intro paragraphs, so its
   first h2 is section 1 and it SHOULD carry a hairline. That rule is omitted
   rather than copied — it would have matched nothing and read as live.
   -------------------------------------------------------------------------- */

.landing-wrap.privacy-page .landing-section {
  display: block;
}

.landing-wrap.privacy-page .landing-section-body {
  width: 100%;
  max-width: none;
}

/* The section headings. 400 is not a taste value — it is the only weight
   Instrument Serif has. Anything heavier is synthesised. */
.landing-wrap.privacy-page .landing-richtext h2 {
  margin: 52px 0 16px;
  padding-top: 30px;
  border-top: 1px solid var(--landing-hairline);
  font-family: "Instrument Serif", serif;
  font-style: normal;
  font-weight: 400;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: -0.2px;
  color: var(--landing-ink);
}

/* Body. The measure cap is what stops a 1010px card running 130 characters
   to the line; the card itself is not narrowed, so the masthead is untouched. */
.landing-wrap.privacy-page .landing-richtext p {
  margin: 0 0 14px;
  max-width: 72ch;
  font-family: Quicksand, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  color: var(--landing-ink);
}

/* The entity line and the effective date are the two lines above the policy
   proper and read as metadata rather than as terms. Muted together.
   ⚠ KEYED ON POSITION, so it is the one rule here that breaks if a paragraph
   is ever inserted at the top of the Rich Text. Verified by effect at S286. */
.landing-wrap.privacy-page .landing-richtext > p:nth-child(1),
.landing-wrap.privacy-page .landing-richtext > p:nth-child(2) {
  margin-bottom: 6px;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--landing-muted);
}

.landing-wrap.privacy-page .landing-richtext > p:nth-child(2) {
  margin-bottom: 34px;
}

@media screen and (max-width: 767px) {
  .landing-wrap.privacy-page .landing-richtext h2 {
    margin-top: 40px;
    padding-top: 24px;
    font-size: 24px;
  }

  .landing-wrap.privacy-page .landing-richtext p {
    max-width: none;
    font-size: 16px;
    line-height: 1.65;
  }
}


/* ============================================================================
   v25 — S288 — /post/* BLOG POST TEMPLATE
   Page-scoped under .landing-wrap.blog-post-page. Every selector in this block
   carries that combo, so nothing here can reach another landing page.

   THE VALUES ARE TRANSPLANTED FROM blog-post-template-v4.html, THE ARTIFACT SHE
   APPROVED. Only the selectors changed: v4's names (.sheet, .inner, .head,
   .body, .note, .cta, .star, .figure) are generic, and this file is SITE-WIDE,
   so shipping them would put a rule called `.body` on all twenty pages. Every
   one is spelled out and prefixed blog-post-. The rules themselves are v4's.

   THREE THINGS THIS EXISTS TO BEAT, and all three are measured faults this
   project has already paid for on another page:
   1. Webflow's site-wide `All H2` TAG selector paints unclassed H2s #F2F1EB at
      weight 500. Every heading inside a Rich Text element is unclassed by
      construction, so the whole body meets it. Same fault as v23 and v24.
   2. Webflow's site-wide `All Links` styles every <a>, which is why an
      unclassed rich-text link renders browser-blue and underlined.
   3. .landing-wrap sets the page cream. A post sits on the DEEPER cream so the
      sheet reads as a sheet, so the ground is overridden here and nowhere else.

   ⚠⚠ THE EMPTY CASES ARE THE POINT OF THIS BLOCK, NOT AN AFTERTHOUGHT. She does
   not intend to use every element on every post, so each optional block has to
   disappear cleanly rather than leave a heading over nothing. PROVEN BY EFFECT
   S288 ON A REAL LEAN POST (zz-test-lean-post): a blank CMS field renders a
   GENUINELY EMPTY element — len 0, :empty true, no whitespace and no <br> — so
   :empty is a valid instrument here. That was read before these rules were
   written, not assumed.
   ⚠ AN IMAGE CANNOT BE :empty, because <img> is a void element. Webflow puts
   the class w-dyn-bind-empty on an image bound to a blank field, and that is
   what the two image rules key on.
   ============================================================================ */

.landing-wrap.blog-post-page {
  --blog-post-ground: #DEDBC8;
  --blog-post-navy: #1C4A91;
  --blog-post-measure: 68ch;
  background-color: var(--blog-post-ground);
}

/* ---------- the sheet ---------- */
/* ⚠⚠⚠ overflow:hidden IS LOAD-BEARING AND IS NOT TIDINESS — it is what clips
   the ribbon. The ribbon is 116% wide and pulled left 8% precisely so its two
   ends are always off the sheet, which is HER S231 RULE: a banner never shows a
   start or a stop. Remove this and both ends of the amber band appear. */
.landing-wrap.blog-post-page .blog-post-sheet {
  position: relative;
  max-width: 1080px;
  margin: 0 auto;
  overflow: hidden;
  background-color: var(--landing-cream);
  color: var(--landing-ink);
}

/* v4 FIX 1 — THE SHEET'S BOTTOM PADDING LIVES HERE, NEVER ON THE LAST BLOCK.
   Every block above it is optional, so hanging the bottom padding off any one
   of them means the sheet ends flush against the text on the posts that do not
   use it. ⚠ EVERY BREAKPOINT OVERRIDE OF THIS RULE MUST RESTATE THE BOTTOM
   VALUE or the shorthand resets it to zero. */
.landing-wrap.blog-post-page .blog-post-inner {
  padding: 0 76px 76px;
}

/* ---------- letterhead ribbon: identical on every post ---------- */
/* ⚠⚠ THE FOUR PHRASES MATCH THE ANNOUNCEMENT BAR'S, HER RULING S288, AND THE
   ANNOUNCEMENT-BAR COMPONENT IS DELIBERATELY NOT ON THIS PAGE. Two strips of
   the same four phrases on one page reads as a mistake. If the bar's copy ever
   changes, these four Text Blocks change with it — they are not bound to
   anything and nothing will tell you they have gone stale. */
.landing-wrap.blog-post-page .blog-post-ribbon-band {
  padding: 34px 0 0;
}

.landing-wrap.blog-post-page .blog-post-ribbon {
  width: 116%;
  margin-left: -8%;
  padding: 13px 0;
  background-color: var(--landing-amber);
  transform: rotate(-1.6deg);
}

.landing-wrap.blog-post-page .blog-post-ribbon-inner {
  display: flex;
  justify-content: center;
  gap: 56px;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--landing-ink);
}

/* ⚠ NO PLUS MARKS BETWEEN THE PHRASES, unlike the announcement bar. The bar's
   plus is amber on pink; here the ground IS amber, so an amber mark would be
   invisible. Claude's call, one rule to reverse. */
.landing-wrap.blog-post-page .blog-post-ribbon-phrase {
  color: inherit;
}

/* ---------- back link ---------- */
.landing-wrap.blog-post-page .back-link {
  display: inline-block;
  margin: 38px 0 0;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--landing-muted);
  text-decoration: none;
}

.landing-wrap.blog-post-page .back-link:hover {
  color: var(--landing-ink);
}

/* ---------- head ---------- */
.landing-wrap.blog-post-page .blog-post-head {
  position: relative;
  padding: 22px 0 0;
}

/* ⚠⚠ THE STAR MUST STAY EMPTY IN THE DESIGNER. It is drawn by a clip-path, so
   anything placed inside it is cut into a five-pointed hole. Her artwork later
   is ONE PROPERTY on this same element — drop background-color and clip-path,
   add background-image / size:contain / repeat:no-repeat. NO DESIGNER WORK. */
.landing-wrap.blog-post-page .blog-post-star {
  position: absolute;
  top: 26px;
  right: 0;
  width: 46px;
  height: 46px;
  background-color: var(--landing-pink);
  transform: rotate(-8deg);
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

.landing-wrap.blog-post-page .blog-post-eyebrow {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--landing-muted);
}

/* ⚠⚠⚠ THE H1 IS STYLED BY ITS OWN CLASS AND EVERY PROPERTY IS STATED, INCLUDING
   text-align. blog-heading is an OLD class carrying Webflow Style-panel values
   from the scratch layout — it was centred there. A rule that only sets the
   size inherits whatever else that class still holds. Same family as the
   /privacy-policy H1 that shipped bare at S286 and took Webflow's own heading
   styles unopposed at 95px, centred. */
.landing-wrap.blog-post-page .blog-heading {
  margin: 14px 0 0;
  max-width: 20ch;
  font-family: "Instrument Serif", Georgia, serif;
  font-weight: 400;
  font-size: 58px;
  line-height: 1.04;
  letter-spacing: -0.01em;
  text-align: left;
  color: var(--landing-ink);
}

.landing-wrap.blog-post-page .blog-post-date {
  margin: 20px 0 0;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--landing-muted);
}

/* ---------- lede ---------- */
/* Post Summary does three jobs — this lede, the blurb on the index, and the
   basis for the meta description. ONE FIELD, ONE PLACE TO EDIT IT. */
.landing-wrap.blog-post-page .blog-post-lede {
  margin: 28px 0 0;
  max-width: 60ch;
  font-size: 21px;
  line-height: 1.65;
  color: var(--landing-ink);
}

/* ---------- share image ---------- */
.landing-wrap.blog-post-page .blog-post-share-image {
  display: block;
  width: 100%;
  max-width: 440px;
  height: auto;
  margin: 44px 0 0;
  background-color: var(--landing-placeholder);
}

/* ---------- body: rich-text vocabulary, styled by TAG inside one class ------
   She writes naturally in the CMS editor and the design follows. There are no
   fixed slots in here and nothing to build per post. */

.landing-wrap.blog-post-page .blog-post-body {
  margin: 44px 0 0;
}

.landing-wrap.blog-post-page .blog-post-body p {
  margin: 0 0 17px;
  max-width: var(--blog-post-measure);
  font-size: 17px;
  line-height: 1.78;
  color: var(--landing-ink);
}

.landing-wrap.blog-post-page .blog-post-body h2 {
  position: relative;
  margin: 60px 0 20px;
  padding-top: 34px;
  border-top: 1px solid var(--landing-hairline);
  max-width: var(--blog-post-measure);
  font-family: "Instrument Serif", Georgia, serif;
  font-weight: 400;
  font-size: 31px;
  line-height: 1.14;
  letter-spacing: -0.2px;
  color: var(--landing-ink);
}

.landing-wrap.blog-post-page .blog-post-body h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -11px;
  width: 58px;
  height: 3px;
  background-color: var(--landing-amber);
}

/* v4 FIX 3 — AN H2 OPENING THE BODY HAS NOTHING ABOVE IT TO DIVIDE FROM, so its
   rule and its 94px of clearance both come off and it draws a hairline straight
   under the lede. Found only by rendering a post that starts with a heading
   instead of an intro paragraph. The amber mark stays. */
.landing-wrap.blog-post-page .blog-post-body h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.landing-wrap.blog-post-page .blog-post-body h3 {
  margin: 34px 0 10px;
  max-width: var(--blog-post-measure);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--landing-muted);
}

.landing-wrap.blog-post-page .blog-post-body ul {
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
  max-width: var(--blog-post-measure);
}

.landing-wrap.blog-post-page .blog-post-body ul li {
  position: relative;
  margin: 0 0 11px;
  padding-left: 24px;
  font-size: 17px;
  line-height: 1.7;
  color: var(--landing-ink);
}

.landing-wrap.blog-post-page .blog-post-body ul li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 11px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: var(--landing-amber);
}

/* ⚠ A NUMBERED LIST IS A DIFFERENT ELEMENT AND MUST NOT INHERIT THE BULLET.
   The dot above is scoped `ul li` on purpose — written as a bare `li` it draws
   an amber dot beside every number in an ordered list. */
.landing-wrap.blog-post-page .blog-post-body ol {
  margin: 0 0 20px;
  padding-left: 22px;
  max-width: var(--blog-post-measure);
}

.landing-wrap.blog-post-page .blog-post-body ol li {
  margin: 0 0 11px;
  font-size: 17px;
  line-height: 1.7;
  color: var(--landing-ink);
}

/* v4 FIX 4 — whatever ends the body drops its bottom margin, so the gap down to
   whatever comes next is ONE predictable number instead of depending on which
   element she happened to finish writing with. */
.landing-wrap.blog-post-page .blog-post-body > *:last-child {
  margin-bottom: 0;
}

/* ⚠⚠⚠ THE QUOTE'S WIDTH IS IN PIXELS, NEVER A ch CAP, AND THIS IS THE THIRD TIME
   A ch UNIT HAS MEASURED THE WRONG FONT ON THIS PROJECT. A ch is the zero glyph
   of the ELEMENT's own font: this blockquote inherits Quicksand 16px while its
   text renders at 33px Instrument Serif, so max-width:24ch computed to ~210px —
   about TWELVE characters of the face actually on screen — and the quote ran
   seven lines deep with a lake beside it. It looks like a design choice and it
   is arithmetic. 508px is 480px of text plus the 28px indent. */
.landing-wrap.blog-post-page .blog-post-body blockquote {
  position: relative;
  width: 508px;
  max-width: 100%;
  margin: 52px 0;
  padding: 0 0 0 28px;
  border-left: 3px solid var(--landing-coral);
}

.landing-wrap.blog-post-page .blog-post-body blockquote p {
  margin: 0;
  max-width: none;
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  font-size: 33px;
  line-height: 1.22;
}

.landing-wrap.blog-post-page .blog-post-body blockquote::after {
  content: "";
  position: absolute;
  right: -72px;
  top: 14px;
  width: 32px;
  height: 32px;
  background-color: var(--landing-amber);
  transform: rotate(12deg);
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

.landing-wrap.blog-post-page .blog-post-body a {
  color: var(--landing-ink);
  text-decoration: none;
  border-bottom: 2px solid var(--landing-amber);
}

/* Quicksand 700 is a REAL loaded face on this project, so a bold inside the
   body is genuine type rather than a browser-synthesised smear. */
.landing-wrap.blog-post-page .blog-post-body strong {
  font-weight: 700;
}

.landing-wrap.blog-post-page .blog-post-body img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 24px 0;
}

/* ---------- optional block: the note box ---------- */
.landing-wrap.blog-post-page .blog-post-note-box {
  margin: 44px 0;
  padding: 2px 0 2px 22px;
  border-left: 3px solid var(--blog-post-navy);
  max-width: var(--blog-post-measure);
}

.landing-wrap.blog-post-page .blog-post-note-heading {
  margin: 0 0 6px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--blog-post-navy);
}

.landing-wrap.blog-post-page .blog-post-note-body {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.68;
  color: var(--landing-ink);
}

/* ---------- optional block: sources ---------- */
/* The heading is TYPED, not bound — it reads "Sources" on every post. That is
   exactly why the heading and the list live inside one div: an empty Sources
   field would otherwise leave the word sitting over nothing, and the rule that
   hides it has to reach the WRAPPER. */
.landing-wrap.blog-post-page .blog-post-sources {
  margin: 58px 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--landing-hairline);
}

.landing-wrap.blog-post-page .blog-post-sources-heading {
  margin: 0 0 16px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--landing-muted);
}

.landing-wrap.blog-post-page .blog-post-sources-list ol {
  margin: 0;
  padding-left: 18px;
  max-width: var(--blog-post-measure);
}

.landing-wrap.blog-post-page .blog-post-sources-list li {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--landing-muted);
}

.landing-wrap.blog-post-page .blog-post-sources-list li:last-child {
  margin-bottom: 0;
}

/* The link is ink and bold, the annotation beside it stays muted, so the two
   separate without needing a class the CMS editor cannot give them. */
.landing-wrap.blog-post-page .blog-post-sources-list li a {
  color: var(--landing-ink);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1px solid var(--landing-hairline);
}

/* ---------- the CTA ---------- */
/* HER RULING: the CTA sits in the post body ABOVE Sources. Her reasoning —
   "sources is only for people looking for it." Do not move it below. */
.landing-wrap.blog-post-page .blog-post-cta {
  margin: 46px 0 0;
  font-size: 18px;
  line-height: 1.7;
  color: var(--landing-ink);
}

.landing-wrap.blog-post-page .blog-post-cta a {
  color: var(--landing-coral);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 2px solid var(--landing-amber);
}

/* ---------- optional block: keep reading ---------- */
/* THIS IS THE SEO MECHANISM, not decoration — it is what links posts to each
   other, and it runs off a multi-reference field pointing at Blog Posts itself.
   A wrong source renders posts perfectly and renders the WRONG ones. */
.landing-wrap.blog-post-page .blog-post-related {
  margin: 66px 0 0;
  padding: 28px 0 0;
  border-top: 1px solid var(--landing-hairline);
}

.landing-wrap.blog-post-page .blog-post-related-heading {
  margin: 0 0 22px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--landing-muted);
}

/* v4 FIX 5 — THE GRID DIVIDES BY HOWEVER MANY RELATED POSTS EXIST. It was three
   fixed columns, so one related post sat in a third of the width with two empty
   columns beside it — and EARLY POSTS HAVE EXACTLY ONE, so that is the state
   that would have shipped on the first thing she published. */
.landing-wrap.blog-post-page .blog-post-related-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 26px;
}

.landing-wrap.blog-post-page .blog-post-related-card {
  display: block;
  color: inherit;
  text-decoration: none;
}

.landing-wrap.blog-post-page .blog-post-related-thumb {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background-color: var(--landing-placeholder);
}

.landing-wrap.blog-post-page .blog-post-related-title {
  margin: 13px 0 0;
  font-family: "Instrument Serif", Georgia, serif;
  font-size: 20px;
  line-height: 1.2;
  color: var(--landing-ink);
}

.landing-wrap.blog-post-page .blog-post-related-date {
  margin: 5px 0 0;
  font-size: 12px;
  color: var(--landing-muted);
}

/* ---------- THE EMPTY CASES ----------
   ⚠⚠⚠ THIS IS THE HALF THAT MAKES THE TEMPLATE USABLE, AND IT IS INVISIBLE ON A
   FULL POST. She does not intend to use every element on every post, so every
   one of these has to be judged on the LEAN post, never on the rich one. Five
   faults in v4 were found that way and no other. */

/* A blank text field renders a genuinely empty element — read live S288. */
.landing-wrap.blog-post-page .blog-post-eyebrow:empty,
.landing-wrap.blog-post-page .blog-post-date:empty,
.landing-wrap.blog-post-page .blog-post-lede:empty,
.landing-wrap.blog-post-page .blog-post-note-heading:empty {
  display: none;
}

/* ⚠ AN IMAGE IS A VOID ELEMENT AND CAN NEVER BE :empty. Webflow marks an image
   bound to a blank field with w-dyn-bind-empty, and that is the only handle. */
.landing-wrap.blog-post-page .blog-post-share-image.w-dyn-bind-empty,
.landing-wrap.blog-post-page .blog-post-related-thumb.w-dyn-bind-empty {
  display: none;
}

/* ⚠⚠ THE NOTE BOX AND THE SOURCES BLOCK HIDE AS WHOLE BLOCKS, because each
   carries a border, a rule or a typed heading that would otherwise sit over
   nothing. Keyed on the block's SUBSTANCE — the note body and the sources list
   — so a note with a body and no heading still renders, which is a real case:
   they are two separate CMS fields and either can be left blank. */
.landing-wrap.blog-post-page .blog-post-note-box:has(.blog-post-note-body:empty),
.landing-wrap.blog-post-page .blog-post-sources:has(.blog-post-sources-list:empty) {
  display: none;
}

/* ⚠⚠⚠ KEEP READING CANNOT USE :empty AND THAT IS STRUCTURAL — its wrapper holds
   the typed heading and the collection list, so it is never empty even with
   zero related posts. Webflow renders its own .w-dyn-empty element instead,
   and that is what this keys on.
   ⚠ :has() IS THE ONLY WAY TO REACH A PARENT FROM A CHILD IN CSS. On a browser
   without it the heading renders over Webflow's default empty-state box —
   UGLY, NEVER A LIE, which is the direction this project accepts. */
.landing-wrap.blog-post-page .blog-post-related:has(.w-dyn-empty) {
  display: none;
}

.landing-wrap.blog-post-page .blog-post-related .w-dyn-empty {
  display: none;
}

/* ---------- tablet ---------- */
@media screen and (max-width: 1023px) {
  /* ⚠ THE BOTTOM VALUE IS RESTATED, or the shorthand resets it to zero. */
  .landing-wrap.blog-post-page .blog-post-inner {
    padding: 0 44px 64px;
  }

  .landing-wrap.blog-post-page .blog-heading {
    font-size: 47px;
  }

  /* ⚠⚠ width:auto IS LOAD-BEARING. Without it the 508px above survives into the
     tablet band and the quote stays narrow with a lake beside it — and the star
     it was making room for is hidden here anyway. */
  .landing-wrap.blog-post-page .blog-post-body blockquote {
    width: auto;
    max-width: var(--blog-post-measure);
  }

  .landing-wrap.blog-post-page .blog-post-body blockquote::after {
    display: none;
  }
}

/* ---------- phone ---------- */
@media screen and (max-width: 767px) {
  .landing-wrap.blog-post-page .blog-post-inner {
    padding: 0 22px 56px;
  }

  .landing-wrap.blog-post-page .blog-post-ribbon-band {
    padding-top: 24px;
  }

  /* Claude's call: the phrases tighten rather than the type shrinking, so the
     strip keeps the same height as it does on a desktop. */
  .landing-wrap.blog-post-page .blog-post-ribbon-inner {
    gap: 28px;
  }

  .landing-wrap.blog-post-page .blog-heading {
    font-size: 37px;
    max-width: 100%;
  }

  .landing-wrap.blog-post-page .blog-post-star {
    top: 22px;
    width: 32px;
    height: 32px;
  }

  .landing-wrap.blog-post-page .blog-post-lede {
    font-size: 18px;
  }

  .landing-wrap.blog-post-page .blog-post-body p,
  .landing-wrap.blog-post-page .blog-post-body ul li,
  .landing-wrap.blog-post-page .blog-post-body ol li {
    font-size: 16px;
  }

  .landing-wrap.blog-post-page .blog-post-body h2 {
    margin-top: 44px;
    padding-top: 28px;
    font-size: 25px;
  }

  .landing-wrap.blog-post-page .blog-post-body blockquote p {
    font-size: 24px;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid {
    grid-auto-flow: row;
    gap: 32px;
  }
}

/* ==========================================================================
   v26 — S289 — /post/* THE TYPE PASS AND THE PULL QUOTE
   APPENDED AT TOP LEVEL. v25 is a byte-exact prefix of this file, so the
   rollback is deleting from this comment to the end of the file.
   Every selector is scoped .landing-wrap.blog-post-page.
   ========================================================================== */

/* ---------- HER RULING S289: MEET THE FLOOR OF WHAT IS STANDARD ----------
   Body 17 -> 15 desktop and 16 -> 14 phone, lede 21 -> 18 and 18 -> 16, note
   body 15.5 -> 14. HEADINGS, THE PULL QUOTE, THE EYEBROWS AND THE SOURCE
   ANNOTATIONS ARE UNCHANGED — hers, so the page does not go top-heavy while
   staying a deliberate step above body size.

   ⚠⚠ THE MEASURE NEEDS NO EDIT AND MUST NOT GET ONE. --blog-post-measure is
   68ch and a ch is measured in the ELEMENT'S OWN FONT, so dropping a
   paragraph to 15px takes its cap from ~688px to ~607px by itself and the
   line length is held where it was. Writing a pixel cap here would freeze it
   and break the next time the size moves. The ch unit is honest on these
   elements ONLY because they render in the font they are declared in — see
   the blockquote below, where it is not.

   ⚠⚠⚠ THESE RULES SIT AFTER v25's @media BLOCKS AND THEREFORE BEAT THEM ON
   SOURCE ORDER AT EQUAL SPECIFICITY. Every one that has a phone twin has its
   twin restated in the @media block at the foot of this section. Add a rule
   here and ask whether it needs one, or it silently wins at every width. */

.landing-wrap.blog-post-page .blog-post-lede {
  font-size: 18px;
}

.landing-wrap.blog-post-page .blog-post-body p,
.landing-wrap.blog-post-page .blog-post-body ul li,
.landing-wrap.blog-post-page .blog-post-body ol li {
  font-size: 15px;
}

.landing-wrap.blog-post-page .blog-post-note-body {
  font-size: 14px;
}

/* ---------- THE PULL QUOTE: TYPE MOVED OFF THE p AND ONTO THE ELEMENT -----
   ⚠⚠⚠ A WEBFLOW RICH-TEXT BLOCKQUOTE HOLDS A BARE TEXT NODE, NOT A
   PARAGRAPH. Read live S289 on the first real post: blockquote.children.length
   is 0 and its innerHTML is the sentence itself. So v25's `blockquote p` rule
   — 33px Instrument Serif italic — MATCHED NOTHING and the quote rendered as
   18px Quicksand, i.e. smaller than the body around it. Every deploy gate had
   passed; the rule was aimed at an element that does not exist. Same family as
   the /how-it-works answers and the /the-closet-standard note box.
   THE FIX IS TO STYLE THE BLOCKQUOTE ITSELF. The box was never wrong: 508px,
   the coral border and the 28px indent were all live and measured correct. */

.landing-wrap.blog-post-page .blog-post-body blockquote {
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  font-size: 33px;
  line-height: 1.22;
  color: var(--landing-ink);
}

/* The p rule is KEPT AND POINTED AT inherit rather than deleted, so a quote
   that DOES arrive wrapped in a paragraph — two paragraphs in one blockquote
   would produce them — renders identically instead of falling back to body
   type. It must stay AFTER the v25 rule it supersedes. */
.landing-wrap.blog-post-page .blog-post-body blockquote p {
  margin: 0;
  max-width: none;
  font: inherit;
  color: inherit;
}

/* ---------- tablet ---------- */
@media screen and (max-width: 1023px) {
  /* ⚠⚠⚠ THE ch TRAP, CREATED BY THE FIX ABOVE AND CAUGHT BEFORE IT SHIPPED.
     v25 caps this quote at var(--blog-post-measure) = 68ch in the tablet band.
     That computed to ~688px while the blockquote inherited Quicksand 16px.
     Now the element itself is 33px Instrument Serif, so the SAME 68ch computes
     to ~970px — the quote would silently grow half as wide again, in one
     breakpoint only. 607px is the body's own new measure at 15px, computed
     rather than guessed, so the quote can never end up wider than the prose
     it sits inside. FOURTH TIME A ch UNIT HAS MEASURED THE WRONG FONT HERE. */
  .landing-wrap.blog-post-page .blog-post-body blockquote {
    max-width: 607px;
  }
}

/* ---------- phone ---------- */
@media screen and (max-width: 767px) {
  .landing-wrap.blog-post-page .blog-post-lede {
    font-size: 16px;
  }

  .landing-wrap.blog-post-page .blog-post-body p,
  .landing-wrap.blog-post-page .blog-post-body ul li,
  .landing-wrap.blog-post-page .blog-post-body ol li {
    font-size: 14px;
  }

  /* v25 puts the phone size on `blockquote p`, which matches nothing. Restated
     on the element, or the 33px above survives onto a phone. */
  .landing-wrap.blog-post-page .blog-post-body blockquote {
    font-size: 24px;
  }
}

/* ==========================================================================
   v27 — S289 — /post/* THE RIBBON MARQUEE, THE SHADOW, THE HEAD ENTRANCE,
   HOVER, AND THE BACK-LINK / EYEBROW SEPARATION
   APPENDED AT TOP LEVEL. v26 is a byte-exact prefix, so the rollback is
   deleting from this comment to the end of the file.
   Every selector is scoped .landing-wrap.blog-post-page.

   ⚠⚠⚠ EVERY HIDING RULE AND EVERY LOOP IN THIS SECTION IS GATED ON
   html.landing-motion, WHICH landing.js SETS AS ITS FIRST ACT. Script never
   arrives, or a reader prefers reduced motion, and the page renders exactly
   as it did before this commit: fully visible, ribbon static, nothing hidden.
   Failure lands on "no animation", never on "no content". Her S224 rule.
   ========================================================================== */

/* ---------- THE RIBBON BECOMES A SLOW MARQUEE — HER RULING S289 -----------
   It stops being a static letterhead and drifts. ~55s a lap, chosen slow on
   purpose: this strip sits above a long article rather than at the top of a
   landing page, and a brisk one beside body copy pulls the eye off the words.

   ⚠⚠⚠ IT NEEDS EIGHT PHRASES IN THE MARKUP, NOT FOUR — TWO IDENTICAL SETS.
   The animation slides exactly -50%, i.e. one whole set, so the strip is
   always covered and the loop has no seam. THE SET COUNT AND THE SLIDE
   DISTANCE ARE LOCKED TO EACH OTHER, the same lock the hero marquee carries:
   six sets there slide -16.6667%. Duplicate the four Text Blocks to eight and
   this reads seamlessly; put three sets in and the percentage must change
   with them or the strip jumps once per cycle — silently, and only on a
   screen wide enough to show the seam.

   ✅ THE WHOLE MARQUEE IS GATED ON :has(> :nth-child(5)), SO IT IS INERT
   UNTIL THE EIGHTH PHRASE EXISTS. That is deliberate: it means this file and
   the Designer edit can land in either order with no broken state in
   between. With four phrases the ribbon stays exactly as it is today. On a
   browser with no :has() support the whole rule is dropped and the ribbon is
   also static — ugly is not available here, only "unchanged".

   ⚠⚠ THE GAP MOVED OFF `gap` AND ONTO margin-right ON EACH PHRASE, AND THAT
   IS ARITHMETIC RATHER THAN STYLE. With flex `gap`, eight items carry SEVEN
   gaps, so 50% of the total is one set plus half a gap and the loop drifts by
   28px every lap. With a per-item right margin the total is exactly
   8 x (phrase + margin) and -50% is exactly one set. Do not "tidy" this back
   into a gap. */

.landing-wrap.blog-post-page .blog-post-ribbon {
  /* Soft lift, never a hard offset copy of the band. ⚠⚠ THE /old-home RIBBON
     PAID FOR THIS ONCE: a shadow there was raised past its written ceiling and
     laid a solid coral bar across the product cards, because a tilted band's
     wedge grows with viewport width and no shadow number can ever fill it.
     This one is a blur with almost no offset, so it reads as lift at every
     width and has nothing to chase. */
  box-shadow: 0 8px 22px rgba(30, 26, 25, 0.13);
}

.landing-wrap.blog-post-page .blog-post-ribbon-phrase {
  margin-right: 56px;
}

html.landing-motion .landing-wrap.blog-post-page
  .blog-post-ribbon-inner:has(> :nth-child(5)) {
  justify-content: flex-start;
  gap: 0;
  width: max-content;
  animation: blog-post-ribbon-drift 55s linear infinite;
}

/* ⚠⚠ A KEYFRAMES NAME IS GLOBAL TO THE PAGE AND THIS FILE IS SITE-WIDE — it
   is not namespaced by any selector, and the scope sweep this project relies
   on checks SELECTORS and is structurally blind to keyframes names. Prefix
   every one blog-post-. */
@keyframes blog-post-ribbon-drift {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ---------- THE BACK LINK AND THE EYEBROW STOP LOOKING ALIKE -------------
   HER RULING S289: both halves. They were 13px Quicksand 500 muted, one
   directly above the other, differing only in case. The back link is
   NAVIGATION and gets quieter; the eyebrow is PART OF THE POST and gets
   louder. Now separated on three axes at once — size, weight and colour —
   rather than on one. */

.landing-wrap.blog-post-page .back-link {
  /* ⚠ width:auto IS A GUARD, NOT A FIX. This link was found rendering as a
     720px inline-block wearing a shared Webflow class, which is what let a
     background land on it as a full-width bar. Fixed at source in the
     Designer S289; this line stops the same class handing it a width again. */
  width: auto;
  font-size: 12px;
  transition: color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* The arrow nudges left on hover — it is the only element on the page whose
   job is going backwards, so the motion says the same thing the word does. */
.landing-wrap.blog-post-page .back-link:hover {
  color: var(--landing-ink);
}

html.landing-motion .landing-wrap.blog-post-page .back-link {
  display: inline-block;
}

html.landing-motion .landing-wrap.blog-post-page .back-link:hover {
  transform: translateX(-3px);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
              color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ⚠ INK RATHER THAN CORAL — CLAUDE'S CALL, ONE VALUE TO REVERSE. Coral already
   does six jobs across this build and /how-it-works has just spent it on an
   eyebrow of its own; a seventh makes it a colour rather than a signal. Ink
   uppercase at 600 reads as a kicker attached to the headline, which is what
   this line is. */
.landing-wrap.blog-post-page .blog-post-eyebrow {
  font-weight: 600;
  letter-spacing: 0.2em;
  color: var(--landing-ink);
}

/* ---------- THE HEAD ENTRANCE ON LOAD ------------------------------------
   ⚠⚠⚠ A KEYFRAME ANIMATION, NEVER A TRANSITION. A transition only runs if the
   browser painted the start state before the class landed, so it is a race —
   and on a warm cache it LOSES: both states collapse into one frame, nothing
   moves, and every deploy gate still passes. That is the S247 hero fault
   exactly. An animation makes no such bet.

   ⚠⚠ `both` FILL IS LOAD-BEARING. It holds the start state through the delay
   so a staggered element cannot flash early, and the end state afterwards so
   nothing snaps back.

   ⚠ THESE ELEMENTS ARE ALL ABOVE THE FOLD, WHICH IS WHY THIS NEEDS NO
   OBSERVER. Anything below the fold wants a scroll reveal, and landing.js
   observes .landing-section ONLY — the blog blocks are not landing-sections
   and must never be given that class, because .landing-section is a
   290px/660px grid and it would put the whole post in a narrow rail. That is
   the fault /terms-of-service and /privacy-policy both shipped with. A scroll
   reveal here is a landing.js change, deliberately not in this commit. */

@keyframes blog-post-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

html.landing-motion .landing-wrap.blog-post-page .back-link,
html.landing-motion .landing-wrap.blog-post-page .blog-post-eyebrow,
html.landing-motion .landing-wrap.blog-post-page .blog-heading,
html.landing-motion .landing-wrap.blog-post-page .blog-post-date,
html.landing-motion .landing-wrap.blog-post-page .blog-post-lede,
html.landing-motion .landing-wrap.blog-post-page .blog-post-share-image {
  animation: blog-post-rise 0.7s cubic-bezier(0.4, 0, 0.2, 1) both;
}

html.landing-motion .landing-wrap.blog-post-page .back-link            { animation-delay: 0s; }
html.landing-motion .landing-wrap.blog-post-page .blog-post-eyebrow    { animation-delay: 0.08s; }
html.landing-motion .landing-wrap.blog-post-page .blog-heading         { animation-delay: 0.16s; }
html.landing-motion .landing-wrap.blog-post-page .blog-post-date       { animation-delay: 0.24s; }
html.landing-motion .landing-wrap.blog-post-page .blog-post-lede       { animation-delay: 0.32s; }
html.landing-motion .landing-wrap.blog-post-page .blog-post-share-image{ animation-delay: 0.40s; }

/* ⚠⚠ THE HOVER TRANSFORM ON THE BACK LINK AND THE ENTRANCE ANIMATION BOTH
   WRITE `transform` ON THE SAME ELEMENT, AND A FILLED ANIMATION WINS. Its end
   state translateY(0) keeps applying forever, so the hover nudge would verify
   clean and do nothing — the /pricing card-hover fault. The delay is 0s here,
   so the animation is finished within 0.7s of load; the nudge is written at a
   HEAVIER selector (html.landing-motion + :hover) to take the element back.
   ▶ IF A HOVER ON AN ANIMATED ELEMENT EVER APPEARS DEAD, THIS IS WHY. */

/* ---------- HOVER ---------- */
/* Body links fill their amber underline rather than moving. Nothing shifts, so
   a link inside a paragraph cannot reflow the line under the cursor. */
.landing-wrap.blog-post-page .blog-post-body a {
  transition: background-color 0.25s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.landing-wrap.blog-post-page .blog-post-body a:hover {
  background-color: rgba(237, 169, 32, 0.22);
}

/* The Keep reading cards lift. ⚠ THE TRANSFORM IS ON THE CARD, and the thumb
   carries its own scale inside an overflow:hidden box so the image grows
   INSIDE its frame rather than the frame growing. */
.landing-wrap.blog-post-page .blog-post-related-card {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.landing-wrap.blog-post-page .blog-post-related-thumb {
  transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}

html.landing-motion .landing-wrap.blog-post-page .blog-post-related-card:hover {
  transform: translateY(-4px);
}

html.landing-motion .landing-wrap.blog-post-page .blog-post-related-card:hover
  .blog-post-related-thumb {
  transform: scale(1.03);
}

/* ---------- phone ---------- */
@media screen and (max-width: 767px) {
  /* v25 tightens the strip with `gap` at this width. The marquee cannot use
     gap (see the arithmetic above), so the phone value moves onto the margin
     and the v25 gap rule is overridden to 0 by the marquee rule itself. */
  .landing-wrap.blog-post-page .blog-post-ribbon-phrase {
    margin-right: 28px;
  }

  /* A lighter shadow: on a phone the sheet fills the viewport, so the band is
     closer to the edge and a heavy shadow reads as a smudge. */
  .landing-wrap.blog-post-page .blog-post-ribbon {
    box-shadow: 0 6px 16px rgba(30, 26, 25, 0.11);
  }
}

/* ==========================================================================
   v28 — S290 — THE BLOG POST SCROLL REVEAL

   HER RULING S290, off a display-only preview on her own live post, both
   options watched at real size: PARAGRAPH BY PARAGRAPH, not block by block.
   Every heading, paragraph, quote and image in the body rises as it arrives,
   then the note box and Sources, then Keep reading. 19 elements on the first
   post. She was shown the 4-element block version first and picked this one.

   THE VALUES ARE v27's OWN — 14px over 0.7s on cubic-bezier(.4,0,.2,1) — and
   the keyframe is v27's `blog-post-rise`, REUSED RATHER THAN COPIED. One
   definition, so the head entrance and the scroll reveal cannot drift apart.

   ⚠⚠⚠ THE SHARE IMAGE IS DELIBERATELY NOT IN THIS SET AND v27 IS UNTOUCHED.
   It was nearly moved here: it starts 749px down the page, so on a short
   viewport its load entrance plays before the reader ever reaches it — the
   S246 shape, motion firing ahead of the eye. MOVING IT WOULD HAVE BEEN
   WORSE. The observer fires the moment an element intersects, so on load it
   would arrive at 0s, i.e. BEFORE the headline at 0.16s, breaking the head
   stagger to fix something nobody can see. It stays the last beat of the head
   at 0.40s. ▶ IF A FUTURE SESSION "TIDIES" IT INTO THIS LIST, THAT IS WHY IT
   SUDDENLY ARRIVES FIRST.

   ⚠⚠⚠ THE SELECTOR LIST BELOW EXISTS TWICE — HERE AND IN landing.js's
   blogPost(). CSS hides them, JS adds `.is-in` to reveal them. THEY MUST
   MATCH. Add a block here and not there and it is hidden forever with nothing
   erroring; add it there and not here and it simply never animates. Same
   shape as the star-spin list, which is five explicit selectors for the same
   reason. The hiding is the dangerous half.

   ⚠⚠ GATED ON html.landing-motion, WHICH landing.js SETS AS ITS FIRST ACT AND
   WITHHOLDS FROM A REDUCED-MOTION READER. Script blocked, script 404s, no
   IntersectionObserver, reduced motion, an exception on line one — no flag,
   no hiding, the post renders as a complete static document. Her S224 ruling.
   The failure lands on "no animation", never on "no article".

   ⚠⚠ THE ANIMATION IS ON `.blog-post-related`, NEVER ON ITS CARDS. The cards
   carry a hover transform (v27), and a `both`-filled animation's end state
   beats a hover declaration outright — the /pricing card fault, and the exact
   thing that made the share image unhideable during the S290 preview. Animate
   the parent and the cards' hover is untouched. DO NOT MOVE THIS DOWN A LEVEL.

   ⚠ THE NOTE BOX AND SOURCES SIT 158px APART, so they will always arrive as
   one event rather than two. Measured, not a fault, and no delay will
   separate them — they are on screen together.

   ⚠ `both` FILL IS LOAD-BEARING, as everywhere else in this file: it holds
   the start state through any delay and the end state after, so nothing
   snaps back.
   ========================================================================== */

html.landing-motion .landing-wrap.blog-post-page .blog-post-body > *,
html.landing-motion .landing-wrap.blog-post-page .blog-post-note-box,
html.landing-motion .landing-wrap.blog-post-page .blog-post-sources,
html.landing-motion .landing-wrap.blog-post-page .blog-post-related {
  opacity: 0;
}

html.landing-motion .landing-wrap.blog-post-page .blog-post-body > .is-in,
html.landing-motion .landing-wrap.blog-post-page .blog-post-note-box.is-in,
html.landing-motion .landing-wrap.blog-post-page .blog-post-sources.is-in,
html.landing-motion .landing-wrap.blog-post-page .blog-post-related.is-in {
  animation: blog-post-rise 0.7s cubic-bezier(0.4, 0, 0.2, 1) both;
}

/* ==========================================================================
   v29 — S291. Four fixes found on the first real render of post two.
   APPENDED AT TOP LEVEL. v28 is a byte-exact prefix, so ROLLBACK IS DELETING
   FROM THIS COMMENT TO THE END OF THE FILE.
   ========================================================================== */

/* ---------- 1. the eyebrow goes navy ----------
   HER RULING S291, replacing v27's ink. Navy #1C4A91 measures 8.6:1 on the
   cream, the only one of her seven that passes cleanly at this size, so
   nothing is traded for the colour. It is the first place navy does work as
   SMALL TYPE rather than as a section ground (the /old-home hero field, the
   /faq masthead) — so navy now carries two jobs on the site. */
.landing-wrap.blog-post-page .blog-post-eyebrow {
  color: #1C4A91;
}

/* ---------- 2. the H1 stops being title-cased ----------
   ⚠⚠⚠ THE CAPITALIZE IS NOT IN THIS FILE. It is on WEBFLOW'S OWN
   `All H1 Headings` TAG SELECTOR — read live S291, "1 on this page, 31 on
   other pages" — the same hazard class as `All Links` and `All H2`. READ IT,
   NEVER EDIT IT: clearing it in the Style panel re-cases every H1 on all
   twenty pages in one click.
   This beats it page-scoped, two classes and a class against a bare tag, and
   it cannot reach the other 31. It is the fourth property this rule has to
   take back off that selector, after size, alignment and margin — which is
   why the comment above the base rule says every property is stated. */
.landing-wrap.blog-post-page .blog-heading {
  text-transform: none;
}

/* ---------- 3. a source link is styled wherever it sits ----------
   ⚠⚠ THE EXISTING RULE WAS NEVER WRONG, IT WAS NOT MATCHING. It is written
   `.blog-post-sources-list li a`, so it needs the citation to be a LIST ITEM.
   Post one's Sources field is a numbered list of five and it matched. Post
   two's is a single PARAGRAPH, so there is no li, the rule reached nothing,
   and the link rendered browser-blue and underlined on a page where every
   other link is ink. Same family as S288 — the rule is fine and the markup is
   not the shape it expects.
   This one asks only that the link be inside the block. It is (0,3,1) against
   the existing (0,3,2), so the li rule still wins where it applies; the two
   set identical values, so there is nothing for them to disagree about. */
.landing-wrap.blog-post-page .blog-post-sources-list a {
  color: var(--landing-ink);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1px solid var(--landing-hairline);
}

/* ---------- 4. the two seams close up ----------
   Both were MEASURED on the live post at 1477px, not guessed, and neither was
   a stack: the body's last child contributes 0, so each gap is one value.
   Paragraph to Sources read 58px, all of it this margin. The 26px between the
   hairline and the citation is untouched — the rule should not crowd the text.
   ⚠ padding-bottom LONGHAND, never the shorthand. The base rule is
   `padding: 0 76px 76px`, so a shorthand here would restate the horizontal
   padding too and the two would drift the next time either changes. */
.landing-wrap.blog-post-page .blog-post-sources {
  margin-top: 32px;
}

.landing-wrap.blog-post-page .blog-post-inner {
  padding-bottom: 40px;
}

/* ⚠⚠⚠ THE TWINS ARE RESTATED AND THEY ARE NOT OPTIONAL. This file ends at top
   level but AFTER its 1023 and 767 blocks, so an appended bare rule beats a
   media query at equal specificity BY SOURCE ORDER. Without these two, 40px
   would apply at every width and the tablet and phone values above would
   silently stop working. */
@media screen and (max-width: 1023px) {
  .landing-wrap.blog-post-page .blog-post-inner {
    padding-bottom: 36px;
  }
}

@media screen and (max-width: 767px) {
  .landing-wrap.blog-post-page .blog-post-inner {
    padding-bottom: 32px;
  }
}

/* ==========================================================================
   v30 — S291. KEEP READING: A LEAD STORY WITH THE REST BESIDE IT.
   APPENDED AT TOP LEVEL. v29 is a byte-exact prefix, so ROLLBACK IS DELETING
   FROM THIS COMMENT TO THE END OF THE FILE.

   HER RULING, off four rounds of mockups: the first related post is a LEAD —
   1.5fr column, 3:2 image, larger title, its lede kept — and the rest are
   thumb-left rows at 1fr with hairlines between them. Columns align to the
   TOP and end where they end; level bottoms were shown and rejected, because
   levelling them means the row list decides the photograph's shape.
   ========================================================================== */

/* ---------- the two columns ----------
   ⚠⚠⚠ WEBFLOW REPEATS ONE COLLECTION ITEM, so the lead and the rows are THE
   SAME MARKUP and the difference is done entirely with :first-child. There is
   no second template to edit and no per-card class to add — which also means
   a rule written here reaches every card unless it is scoped to a position. */
.landing-wrap.blog-post-page .blog-post-related-grid {
  grid-auto-flow: row;
  grid-template-columns: 1.5fr 1fr;
  grid-auto-columns: auto;
  align-items: start;
  column-gap: 32px;
  row-gap: 0;
}

/* ⚠⚠ column-gap AND row-gap SEPARATELY, never the `gap` shorthand. The rows in
   the right column carry their own hairline spacing, and a shorthand row gap
   would stack on top of it — the S284 fault, where one `gap` opened 60px
   between a link and the paragraph above it and read as a taste failure. */

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item {
  grid-column: 2;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child {
  grid-column: 1;
  grid-row: 1;
}

/* ⚠⚠⚠ THE LEAD SPANS AS MANY ROWS AS THERE ARE ROWS BESIDE IT, AND THE COUNT
   HAS TO BE STATED. `grid-row: 1 / -1` does NOT work here — the rows are
   IMPLICIT, and -1 resolves to the end of the EXPLICIT grid, which is row one.
   It would ship looking correct on a four-card row and collapse on any other.
   So the span is set by counting the items with :has, largest last.
   ⚠ A browser without :has() gets a lead spanning one row and the remaining
   cards stacked beside it — untidy, never broken, which is the direction this
   project takes every time. */
.landing-wrap.blog-post-page .blog-post-related-grid:has(> .w-dyn-item:nth-child(2))
  > .w-dyn-item:first-child {
  grid-row: 1 / span 1;
}

.landing-wrap.blog-post-page .blog-post-related-grid:has(> .w-dyn-item:nth-child(3))
  > .w-dyn-item:first-child {
  grid-row: 1 / span 2;
}

.landing-wrap.blog-post-page .blog-post-related-grid:has(> .w-dyn-item:nth-child(4))
  > .w-dyn-item:first-child {
  grid-row: 1 / span 3;
}

/* ⚠⚠ THE ONE-CARD CASE IS THE COMMON ONE TODAY and it is the state the v4 fix
   was written for. A lead at 1.5fr with an empty column beside it reads as a
   missing card, so a lone related post takes the full width. */
.landing-wrap.blog-post-page .blog-post-related-grid:not(:has(> .w-dyn-item:nth-child(2)))
  > .w-dyn-item:first-child {
  grid-column: 1 / -1;
}

/* ---------- the lead ---------- */
.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child
  .blog-post-related-thumb {
  aspect-ratio: 3 / 2;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child
  .blog-post-related-title {
  margin-top: 16px;
  font-size: 23px;
  line-height: 1.15;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child
  .blog-post-related-lede {
  margin-top: 9px;
  font-size: 13px;
}

/* ---------- the rows beside it ---------- */
/* The card becomes thumb-left, text-right. The thumb is a FIXED 70px square
   with flex:none — a percentage width here would shrink as a title wrapped. */
.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-card {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-thumb {
  width: 70px;
  height: 70px;
  flex: none;
  aspect-ratio: auto;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-title {
  margin-top: 0;
  font-size: 15px;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-lede {
  margin-top: 6px;
  font-size: 11.5px;
  line-height: 1.55;
}

/* ⚠ THE HAIRLINE IS A TOP BORDER ON EVERY ROW BUT THE FIRST ONE IN THAT COLUMN
   — :nth-child(2) is the top of the right column, so it takes no rule and the
   dividers sit BETWEEN the rows rather than above the first. */
.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child) {
  padding-bottom: 16px;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:nth-child(n+3) {
  padding-top: 16px;
  border-top: 1px solid var(--landing-hairline);
}

/* ---------- the lede, which did not exist before this ---------- */
/* It replaced the date at S291. The base rule is the row size; the lead
   overrides it above. */
.landing-wrap.blog-post-page .blog-post-related-lede {
  margin: 6px 0 0;
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--landing-muted);
}

/* ---------- tablet ---------- */
/* ⚠⚠ THE LEAD SHAPE HOLDS AND THE COLUMNS TIGHTEN. Below 1023 the right column
   is narrow enough that a 70px thumb plus a wrapped title reads cramped, so
   the split moves toward even. */
@media screen and (max-width: 1023px) {
  .landing-wrap.blog-post-page .blog-post-related-grid {
    grid-template-columns: 1.25fr 1fr;
    column-gap: 24px;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child
    .blog-post-related-title {
    font-size: 20px;
  }
}

/* ---------- phone ---------- */
/* ⚠⚠⚠ ONE COLUMN, AND EVERY DESKTOP PLACEMENT RULE HAS TO BE TAKEN BACK — the
   grid-column, the grid-row span and the :has spans all lose their meaning in
   a single column, and a span left in place leaves empty rows behind it.
   HER RULING: NO CLAMP ON THE LEDE AT THIS WIDTH. The clamp existed to even
   three columns, and there are no columns here to even. */
@media screen and (max-width: 767px) {
  .landing-wrap.blog-post-page .blog-post-related-grid {
    grid-template-columns: 1fr;
    column-gap: 0;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item,
  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child {
    grid-column: 1;
    grid-row: auto;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child
    .blog-post-related-title {
    font-size: 20px;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child {
    padding-bottom: 22px;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:nth-child(2) {
    padding-top: 16px;
    border-top: 1px solid var(--landing-hairline);
  }
}

/* ==========================================================================
   v31 — S291. THE ROW CARD'S TEXT COLUMN. A v30 FAULT, FOUND ON THE FIRST
   REAL RENDER.
   APPENDED AT TOP LEVEL. v30 is a byte-exact prefix, so ROLLBACK IS DELETING
   FROM THIS COMMENT TO THE END OF THE FILE.

   ⚠⚠⚠ v30 MADE THE ROW CARD A FLEX CONTAINER WITH THREE CHILDREN — thumb,
   title, lede — so the title and the lede each became their own flex ITEM and
   split the remaining width between them. On a 358px column that left the
   title about 130px wide and "Why New Clothes Are Actually Dirty" wrapped to
   seven lines beside a 70px thumb.
   ▶ THE TEXT HAS TO BE ONE COLUMN, NOT TWO ITEMS. There is no wrapper element
   to give it — Webflow repeats one Collection Item and the three children are
   siblings — so the fix is a GRID rather than a flex row: one fixed 70px track
   for the thumb, one flexible track for the text, and the title and lede
   stacked in that second track by explicit placement.
   ========================================================================== */

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-card {
  display: grid;
  grid-template-columns: 70px minmax(0, 1fr);
  column-gap: 14px;
  row-gap: 0;
  align-items: start;
}

/* ⚠⚠ minmax(0, 1fr) RATHER THAN 1fr, AND IT IS LOAD-BEARING. A 1fr track has
   min-width:auto, so a long unbroken title pushes the column past its share
   and the thumb shrinks — the overflow this doc already records on grids. */

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-thumb {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-title {
  grid-column: 2;
  grid-row: 1;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-lede {
  grid-column: 2;
  grid-row: 2;
}

/* ⚠ THE THUMB SPANS BOTH ROWS so a two-line title does not pull the lede out
   from under it. And it keeps its own height — a grid item stretches by
   default, which would turn a 70px square into a 70px-wide column-height
   rectangle. */
.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-thumb {
  align-self: start;
}

/* ---------- the lead comes down a size ----------
   ⚠ 1.5fr put the lead image at 538x358 on a 1477px window, which is larger
   than it read at mockup scale and left the three rows looking incidental
   beside it. 1.25fr takes roughly 60px off the image and hands it to the rows,
   which is also what gives the title above room to stop wrapping. */
.landing-wrap.blog-post-page .blog-post-related-grid {
  grid-template-columns: 1.25fr 1fr;
}

/* ⚠⚠ THE PHONE BLOCK STILL WINS. It sets grid-template-columns:1fr later in
   the file, and this rule is bare, so source order keeps the single column
   below 767. Checked rather than assumed — a bare rule appended after a media
   query beats it at equal specificity, which is the trap v29 restated the
   inner padding twins for. */

/* ==========================================================================
   v32 — S291. THE PHONE BLOCK NEVER TOOK, AND A TYPE BUMP.
   APPENDED AT TOP LEVEL. v31 is a byte-exact prefix, so ROLLBACK IS DELETING
   FROM THIS COMMENT TO THE END OF THE FILE.

   ⚠⚠⚠ v31 SHIPPED A BARE `grid-template-columns: 1.25fr 1fr` AFTER THE 767
   BLOCK AND ITS OWN COMMENT CLAIMED THE PHONE RULE STILL WON. IT DID NOT.
   Read live at 390px: cols 192.219px 153.773px — two columns on a phone, the
   lead image crushed to 192 wide and the row titles wrapping to five lines at
   108px. THE COMMENT SAID "checked rather than assumed" AND IT WAS ASSUMED.
   This file ends at top level but AFTER its media queries, so an appended bare
   rule beats a media query at equal specificity BY SOURCE ORDER. That is the
   same trap v29 restated the inner-padding twins for, and it caught the very
   next commit.

   ⚠⚠ AND THE SPAN RULES BEAT THE PHONE BLOCK TOO, FOR A DIFFERENT REASON.
   `:has(> .w-dyn-item:nth-child(3))` takes the SPECIFICITY OF ITS ARGUMENT, so
   those rules outweigh the plain phone rule whatever the source order. v30
   tried to take the span back with a bare `grid-row: auto` and it was never
   heavy enough — the lead still read `1 / span 2` at 390px.
   ▶ A MEDIA QUERY ADDS NO SPECIFICITY. To take back a :has rule inside a
   breakpoint you must repeat the :has.
   ========================================================================== */

@media screen and (max-width: 767px) {
  .landing-wrap.blog-post-page .blog-post-related-grid {
    grid-template-columns: 1fr;
    column-gap: 0;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid:has(> .w-dyn-item:nth-child(2))
    > .w-dyn-item:first-child,
  .landing-wrap.blog-post-page .blog-post-related-grid:has(> .w-dyn-item:nth-child(3))
    > .w-dyn-item:first-child,
  .landing-wrap.blog-post-page .blog-post-related-grid:has(> .w-dyn-item:nth-child(4))
    > .w-dyn-item:first-child,
  .landing-wrap.blog-post-page .blog-post-related-grid:not(:has(> .w-dyn-item:nth-child(2)))
    > .w-dyn-item:first-child {
    grid-column: 1;
    grid-row: auto;
  }

  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item {
    grid-column: 1;
  }
}

/* ---------- the type comes up ----------
   The right column carries two short rows against a tall lead, so the text was
   sitting small in a lot of air. HER CALL: fill it. */
.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child
  .blog-post-related-lede {
  font-size: 14px;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-title {
  font-size: 16px;
}

.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-lede {
  font-size: 12.5px;
  line-height: 1.6;
}

/* ⚠ THESE THREE ARE BARE AND THEREFORE APPLY AT EVERY WIDTH, DELIBERATELY —
   they are sizes rather than placement, and nothing in the phone block sets
   them. The placement rules above are the ones that had to be repeated. */

/* ==========================================================================
   v33 — S291. THE PHONE PASS ON THE POST HEAD AND THE RELATED ROWS.
   APPENDED AT TOP LEVEL. v32 is a byte-exact prefix, so ROLLBACK IS DELETING
   FROM THIS COMMENT TO THE END OF THE FILE.
   Four things, all HER RULINGS off her own phone, all scoped to <=767.
   ========================================================================== */

@media screen and (max-width: 767px) {

  /* ---------- 1. the bands go ----------
     ⚠⚠ THE DEEPER CREAM IS NOT A FAULT — it is #DEDBC8, the --blog-post-ground
     the sheet sits on, and on desktop it is the whole point of the sheet
     design. On a phone the sheet runs full bleed, so the ground only shows as
     two stripes above and below and reads as a mistake.
     ▶ THE FIX IS THE GROUND, NOT THE SHEET. Setting the sheet transparent
     would hand the whole page to #DEDBC8, which is darker than the cream she
     approved. Taking the ground to the sheet's cream removes the seam and
     keeps the page the colour it already is. */
  .landing-wrap.blog-post-page {
    background-color: var(--landing-cream);
  }

  /* ---------- 2. the headline doubles ----------
     37px to 74px, HER CALL, phone only. */
  .landing-wrap.blog-post-page .blog-heading {
    font-size: 74px;
  }

  /* ---------- 3. the lede comes up under it ----------
     28px to 12px. The gap was set for a 37px headline; at 74 the two were
     drifting apart. */
  .landing-wrap.blog-post-page .blog-post-lede {
    margin-top: 12px;
  }

  /* ---------- 4. the related rows clamp to three lines ----------
     HER RULING, REVERSING HER EARLIER "no clamp on mobile" — and the reversal
     is correct rather than a drift, because the layout changed underneath it.
     That ruling was made when the phone cards were full-width stacked, where
     there was nothing to line the text up against. They are thumb-left rows
     now, and three lines lands about level with a 70px thumb, which is what
     she asked for.
     ⚠⚠ THE LEAD CARD IS DELIBERATELY EXCLUDED — :not(:first-child) — so the
     first story still shows its whole summary.
     ⚠⚠⚠ A CHARACTER CAP DOES NOT EXIST IN CSS. Webflow hands over the entire
     Post Summary and the browser only knows about lines, so a line clamp is
     the only way to stop text at a predictable height. ACCEPTED COST, NAMED
     BEFORE SHE RULED: a long summary ends mid-sentence with an ellipsis.
     ⚠ display:-webkit-box IS REQUIRED FOR THE CLAMP AND IT OVERRIDES THE GRID
     PLACEMENT'S DISPLAY, NOT ITS POSITION — the element keeps its grid-column
     and grid-row from v31, because placement belongs to the parent grid. */
  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
    .blog-post-related-lede {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* ==========================================================================
   v34 — S291. TYPE PASS ON THE PHONE, PLUS THE ROW TITLES OFF THE SERIF.
   APPENDED AT TOP LEVEL. v33 is a byte-exact prefix, so ROLLBACK IS DELETING
   FROM THIS COMMENT TO THE END OF THE FILE.
   ========================================================================== */

/* ---------- the row titles go to Quicksand, at every width ----------
   HER RULING: "the instrument font doesnt look great this small." She is right
   and it is a property of the face rather than a preference — Instrument Serif
   is a display serif with fine strokes and a single weight, so at 16px in a
   narrow column it thins out and loses its joins. Quicksand is a geometric
   sans built to hold at small sizes.
   ⚠⚠ THIS IS NOT SCOPED TO THE PHONE, DELIBERATELY. Those titles are 16px at
   every width, so the reason applies at every width. THE LEAD TITLE KEEPS THE
   SERIF — it is 23px and up, which is where that face belongs.
   ⚠ WEIGHT 600, NOT 700. Quicksand loads 300 to 700 on this site, so both are
   real faces and neither is synthesised; 600 sits beside the muted lede
   without shouting. */
.landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:not(:first-child)
  .blog-post-related-title {
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  line-height: 1.3;
}

@media screen and (max-width: 767px) {

  /* ---------- the headline's leading comes in ----------
     At 74px the old 1.04 gave 77px of leading and the lines drifted apart.
     0.92 lands at 68px, inside the 65-70 she asked for.
     ⚠ A RATIO, NOT A PIXEL VALUE — it stays correct if the size is ever
     adjusted, which on this headline it already has been twice today. */
  .landing-wrap.blog-post-page .blog-heading {
    line-height: 0.92;
  }

  /* ---------- the body headings double ----------
     25px to 50px, HER CALL. The leading has to come down with it: 50px type on
     the section default would have set far too loose, so 1.0 here. */
  .landing-wrap.blog-post-page .blog-post-body h2 {
    font-size: 50px;
    line-height: 1;
  }

  /* ---------- the space under Sources closes ----------
     ⚠⚠ THE SPACE IS NOT INSIDE THE SOURCES BLOCK AND MEASURING IT THERE FINDS
     NOTHING — the gap below the citation reads 0. What she is seeing is
     .blog-post-related's OWN 66px top margin sitting above its hairline, so
     the air belongs to Keep reading rather than to Sources.
     ▶ SAME SHAPE AS THE S284 GRID GAP: the space showed up on an element that
     was not creating it. 32px here, matching the Sources seam v29 set. */
  .landing-wrap.blog-post-page .blog-post-related {
    margin-top: 32px;
  }

  /* ---------- the lead related title grows ---------- */
  .landing-wrap.blog-post-page .blog-post-related-grid > .w-dyn-item:first-child
    .blog-post-related-title {
    font-size: 30px;
  }
}

/* =====================================================================
   v35 — S292 — THE BLOG INDEX (/blog)

   ROLLBACK: delete from this comment to the end of the file. v34 is a
   byte-exact prefix, machine-checked before this block was appended.

   PAGE-SCOPED under .collection-list-wrapper.blog-index-page, the combo
   added in the Designer and DELIBERATELY LEFT UNSTYLED there.
   collection-list-wrapper is a WEBFLOW DEFAULT NAME and is almost
   certainly worn on other pages — a bare rule here would reach them.

   ⚠ THE DESIGNER PAINTS THE CARD, NOT THIS FILE. Read live S292:
   .post-card carries background #FFF, radius 10px and padding 20px from
   the Style panel. Every rule below that turns one of those off is
   BEATING a live value at (0,3,0) against its (0,1,0), on specificity
   and never on source order. Clear them in the Style panel later and
   these rules go quiet on their own — they do not break.

   ⚠⚠ HER RULING S292: NO DATE ON THIS PAGE. .post-card-date is bound to
   Published date, which is EMPTY on every post today, so it already
   renders w-dyn-bind-empty at zero size. The display:none below is what
   stops it appearing UNSTYLED the day she fills that field in. One line
   to reverse.
   ===================================================================== */

/* ---------- the measure ----------
   One card per row at every width, hers. 760 is the reading measure the
   post template already uses for its body. */
.collection-list-wrapper.blog-index-page {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 24px;
  padding-right: 24px;
}

/* ---------- the card comes off ----------
   Cream on cream, so /blog and /post/… read as one publication.
   The hairline replaces the card edge as the thing separating posts. */
.collection-list-wrapper.blog-index-page .post-card {
  background-color: transparent;
  border-radius: 0;
  padding: 38px 0;
  border-top: 1px solid #C9C7BC;
  display: block;
  text-decoration: none;
  color: #1E1A19;
}

/* The list needs a rule under the last post as well as above the first,
   or the page ends on an open edge. */
.collection-list-wrapper.blog-index-page
  .w-dyn-item:last-child .post-card {
  border-bottom: 1px solid #C9C7BC;
}

/* ---------- the photo ----------
   ⚠ IT SHIPPED AS A 3.5:1 LETTERBOX — measured 640 x 180 live, which is
   why the photographs read as cropped strips. 3/2 is the post template's
   own share-image ratio.
   ⚠⚠ height:auto IS LOAD-BEARING: an explicit height set in the Designer
   BEATS aspect-ratio outright, and the fix would silently do nothing. */
.collection-list-wrapper.blog-index-page .post-card-image {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 10px;
  display: block;
}

/* ---------- the title ----------
   ⚠⚠⚠ font-weight 400 IS NOT OPTIONAL. An h2 defaults to bold and
   Instrument Serif SHIPS ONE WEIGHT, so bold here is a browser-
   synthesised fake — the fault that sat on .ks-wz-h for months. */
.collection-list-wrapper.blog-index-page .post-card-title {
  font-family: "Instrument Serif", Georgia, serif;
  font-weight: 400;
  font-size: 33px;
  line-height: 1.12;
  color: #1E1A19;
  margin: 22px 0 10px;
  text-transform: none;
  /* the hover rule lives on the underline colour, so the underline
     itself is declared here and starts invisible */
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
  transition: text-decoration-color 0.25s ease;
}

/* ---------- hover ----------
   ⚠⚠ AN UNDERLINE ON THE TEXT, NEVER A BACKGROUND GRADIENT ON THE
   HEADING. The h2 is a block at the full 712px measure, so a gradient
   rule would draw a line the width of the COLUMN rather than the width
   of the WORDS, and on a title that wraps it would underline only the
   last line at full width. text-decoration hugs the text and handles
   the wrap for free — and it needs NO extra span in the markup, so the
   Designer tree stays as it is. */
.collection-list-wrapper.blog-index-page .post-card:hover .post-card-title {
  text-decoration-color: #EDA920;
}

/* ---------- the lede ---------- */
.collection-list-wrapper.blog-index-page .post-card-summary {
  font-family: Quicksand, sans-serif;
  font-weight: 400;
  font-size: 15px;
  line-height: 1.62;
  color: #75736E;
  margin: 0;
}

/* ---------- the date stays off ---------- */
.collection-list-wrapper.blog-index-page .post-card-date {
  display: none;
}

/* ---------- phone ----------
   ⚠⚠⚠ THIS BLOCK MUST SIT AT THE FOOT OF THE v35 SECTION. landing.css
   ends at top level but AFTER its own breakpoint blocks, so a bare rule
   appended here beats a 767 rule earlier in the file by SOURCE ORDER.
   Every v35 rule with a phone twin declares that twin below, never
   above. */
@media screen and (max-width: 767px) {

  .collection-list-wrapper.blog-index-page {
    padding-left: 20px;
    padding-right: 20px;
  }

  .collection-list-wrapper.blog-index-page .post-card {
    padding: 30px 0;
  }

  .collection-list-wrapper.blog-index-page .post-card-title {
    font-size: 27px;
    margin: 18px 0 9px;
  }
}

/* =====================================================================
   v36 — S294. BULLETED LISTS IN A SECTION BODY.
   ROLLBACK: delete from this comment to the end of the file.

   Nothing in this file had ever spoken to a <ul>. Read live on
   /used-baby-clothes: markers rgb(33,27,26) (the site ink, inherited),
   li line-height 20px against body copy's 27.2px, ul padding-left 40px.
   All three are BROWSER DEFAULTS showing through, which is why a real
   list read tighter and plainer than the prose around it.

   ⚠⚠ THE MARKER IS A DRAWN ::before, NEVER ::marker. Her ruling was that
   it match .landing-figure::before — 6px, amber, round — and ::marker
   accepts neither width nor border-radius, so it structurally cannot.
   The values here are LIFTED from the two dots this file already draws
   (.landing-figure::before and the pricing includes dot), not chosen
   fresh: 6px, var(--landing-amber), padding-left 22px, top 0.62em.
   ONE ACCENT LANGUAGE, THREE PLACES.

   ⚠⚠⚠ THIS IS SITE-WIDE, NOT PAGE-SCOPED, AND THAT IS DELIBERATE — it is
   the landing template's list style from now on, so a list on any future
   landing page inherits it without a second rule. Scoped to
   .landing-section-body so it cannot reach the header, the footer or a
   rich-text list on a blog post.

   ⚠ 0.6em BETWEEN ITEMS IS CLAUDE'S CALL, REVERSIBLE. Body paragraphs sit
   1.1em apart; items in one list should read closer than two paragraphs
   or the list stops reading as a unit. The pricing includes list uses
   1.35em, but those are six standalone marketing lines, not a run of
   eight.
   ===================================================================== */

.landing-section-body ul {
  list-style: none;
  padding-left: 0;
  margin: 0 0 1.1em;
}

.landing-section-body ul li {
  position: relative;
  padding-left: 22px;
  margin-bottom: 0.6em;
  font-size: 16px;
  line-height: 1.7;
}

.landing-section-body ul li:last-child {
  margin-bottom: 0;
}

.landing-section-body ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: var(--landing-amber);
}

/* --- MOBILE TWIN. REQUIRED: this file ends at top level but AFTER its
   991/767/479 blocks, so a bare rule appended here beats every one of
   them on source order. Any value with a phone variant must restate it. */
@media (max-width: 767px) {
  .landing-section-body ul li {
    padding-left: 20px;
    margin-bottom: 0.55em;
  }
}

/* ==========================================================================
   v37 — S295. THE LANDING GROUND GOES WHITE.

   HER RULING: the middle of every page is white; the header and the footer
   carry the cream. The landing template was the only thing on the site still
   painting its ground #EDECE0, so on all eleven landing pages the footer sat
   on the same colour as the page above it and there was NO EDGE between them.
   That is what she reported, and it was never a footer fault.

   ⚠⚠ THE VARIABLE IS NOT TOUCHED, DELIBERATELY. --landing-cream is read SIX
   times and only ONE of them is the page ground: the other five are cream
   TEXT on coral and ink (the CTA label, its hover, the founder panel heading)
   and the blog post sheet's own fill. Changing #EDECE0 at line 22 would have
   turned all of those white-on-cream and blanked three labels. Read before
   changing a variable that looks like it means one thing.

   ⚠⚠ BLOG POSTS ARE UNAFFECTED AND MUST STAY THAT WAY. .landing-wrap.blog-post-page
   sets its own --blog-post-ground #DEDBC8 at TWO classes, so it beats this
   rule on specificity rather than on source order. A post keeps its deeper
   cream ground and its cream sheet.

   ⚠ APPENDED RATHER THAN EDITED AT LINE 42 so v36 stays a byte-exact prefix
   and the rollback is deleting from this comment to the end of the file.
   It ties with line 42 at (0,1,0) and wins on source order.

   ⚠ NO MOBILE TWIN IS OWED. Both breakpoint .landing-wrap rules (991 and 767)
   set padding only and no background, checked before this was written.
   -------------------------------------------------------------------------- */

.landing-wrap {
  background-color: #FFFFFF;
}

/* ============================================================================
   v38 — S296 · THE BLOG HEADLINE MEASURE
   ----------------------------------------------------------------------------
   HER CALL, off a live read on her own published post: the headline should sit
   a little wider than the lede. It was sitting NARROWER.

   MEASURED, NOT DERIVED. 1ch on this element is 26.68px at 58px Instrument
   Serif, so the shipped 20ch computed to 534px against the lede's 643px — 17%
   narrower. 26ch lands it at 694px, about 8% wider than the lede, which is what
   she asked for. Judged on the live render of two real posts, a short title and
   a long one.

   ⚠⚠ THE ch UNIT IS HONEST ON THIS ELEMENT AND THAT IS WHY IT STAYS A ch.
   A ch is measured in the element's OWN font, and here the element is
   Instrument Serif 58px and its text renders in Instrument Serif 58px. So the
   cap scales correctly with the 47px tablet size and keeps the same character
   count. Contrast the v26 blockquote, where the element inherited Quicksand
   and its text rendered 33px serif, and a ch cap was arithmetic pretending to
   be a design choice.

   ⚠⚠⚠ THE PHONE TWIN IS RESTATED BELOW AND IT IS LOAD-BEARING. This rule sits
   AFTER every @media block in the file, so at equal specificity it wins at
   every width on source order. The 767 block at v25 sets max-width:100% on
   this heading; without the twin, that is silently overridden and the phone
   headline picks up a 26ch cap it was never meant to have.
   -------------------------------------------------------------------------- */

.landing-wrap.blog-post-page .blog-heading {
  max-width: 26ch;
}

@media screen and (max-width: 767px) {
  .landing-wrap.blog-post-page .blog-heading {
    max-width: 100%;
  }
}
