/* Local page compositions for the Farnsworth marketing site.
   Kit components come from ui.css. Anything here that a second project needs should be
   promoted into the design-system kit per PATTERNS.md, not copied. */

/* Waitlist form. The row collapses to stacked below 560px, where a side-by-side input and
   button leaves the input too narrow to read a typed address in. */
.site-waitlist { margin-top: var(--ds-space-5); }
/* max-width caps how far flex: 1 1 20rem is allowed to grow. Without it the row has no
   upper bound and the input stretches to fill the full container width (measured 894px at
   1280px), while the lede above it is capped at 52ch (529px). margin-inline:auto keeps the
   now-bounded row centred, matching .site-hero__lede and .site-price. */
.site-waitlist__row {
  display: flex; gap: var(--ds-space-3); justify-content: center; flex-wrap: wrap;
  max-width: 34rem; margin-inline: auto;
}
/* The kit's .ds-input is width:100%. As a flex item that computes a hypothetical main size
   of the entire row, so the button wrapped onto its own line at every viewport width and
   the side-by-side layout described above could never actually happen. Measured at 1280px:
   the input rendered 1072px wide, the full content width.
   flex-basis carries the intended width instead, and width:auto is required or the kit's
   100% still wins. */
.site-waitlist__row .ds-input { width: auto; flex: 1 1 20rem; }
@media (max-width: 560px) {
  .site-waitlist__row { flex-direction: column; align-items: stretch; }
  /* flex-basis resolves against the main axis, which is vertical here, so leaving
     `flex: 1 1 20rem` in place would set a 20rem HEIGHT on the input. Reset it and let
     align-items:stretch size the width. */
  .site-waitlist__row .ds-input { flex: 0 1 auto; width: auto; }
}
.site-waitlist__status { margin-top: var(--ds-space-3); color: var(--ds-danger); font-size: var(--ds-text-sm); }
.site-waitlist__done { margin-top: var(--ds-space-3); }
.site-waitlist__note { margin-top: var(--ds-space-3); }
.site-waitlist__noscript { margin-top: var(--ds-space-3); }
/* GRE-252: Turnstile renders a fixed 300px widget. Inside the .ds-container's 24px gutter it ends at
   x=324 in a 320px viewport, a 4px horizontal overflow that shipped to production. Below the width where
   the fixed widget stops fitting (24 + 300 = 324px), scale it down to the form's content box; the parent
   clips the untransformed 300px layout box so it can't force a page-level horizontal scrollbar. Widths
   >= 360px (the next common breakpoint) fit the widget natively and are untouched. */
@media (max-width: 340px) {
  .site-waitlist { overflow-x: clip; }
  .site-waitlist .cf-turnstile { transform: scale(0.9); transform-origin: left center; }
}

/* The kit's .ds-nav sets display:flex, align-items and a gap, but no justify-content and no
   spacer, so without this the whole bar packs to the left and leaves roughly half the
   container empty. space-between pins the brand left and the CTA right; margin-inline:auto
   on the links centres them in what remains. Below 720px the kit hides .ds-nav__links
   entirely, so the auto margins stop applying; the .site-nav__cta rules further down also
   hide the bar CTA at that width, so space-between is left spreading just brand and toggle,
   which is the fit the 720px breakpoint below relies on. */
.site-nav { justify-content: space-between; }
.site-nav__links { margin-inline: auto; }

/* The kit's .ds-link underlines, which is correct for a link inside prose and wrong for
   navigation.
   .ds-nav__brand used to be in this selector too and has been dropped. It was justified as
   an anchor with no kit class falling through to the UA default underline, and both halves
   are now false: the kit does style .ds-nav__brand (display, align-items, flex-shrink, just
   no text-decoration), and since the wordmark swap the anchor's only child is an <img>, with
   no text for a decoration to draw on. Verified by forcing `text-decoration: underline` on
   the anchor and screenshotting it on / and /privacy/: byte-identical to the `none` state on
   both. assets.spec.ts keeps it that way by failing on any live-text wordmark. */
.site-nav__link,
.site-nav__link:hover { text-decoration: none; }

.site-hero .ds-hero__lede { max-width: 52ch; }
/* .ds-display is a flat token in the kit. This headline is short and centred, so a clamp
   stops a single line spanning an uncomfortable measure on a wide monitor. */
.site-hero .ds-display { font-size: clamp(2.25rem, 5.5vw, 4rem); text-wrap: balance; }

/* Fact strip: occupies the slot a competitor fills with a customer logo wall. */
.site-facts { padding: var(--ds-space-5) 0; border-block: 1px solid var(--ds-border); }
.site-facts__list {
  display: flex; flex-wrap: wrap; gap: var(--ds-space-3) var(--ds-space-6);
  margin: 0; padding: 0; list-style: none;
  font-size: var(--ds-text-sm); color: var(--ds-text-muted);
}

/* Screenshot slots. The aspect ratio is reserved from the start so dropping a real image
   in later is one src attribute and causes no layout shift. */
.site-shot { margin: var(--ds-space-6) auto 0; max-width: 60rem; }
.site-shot__slot {
  aspect-ratio: 16 / 10;
  border: 1px solid var(--ds-border);
  border-radius: var(--ds-radius-lg);
  background: var(--ds-surface-raised);
}
.site-shot figcaption { margin-top: var(--ds-space-3); text-align: center; }

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

/* Alternating feature rows. Text and slot side by side above 900px, stacked below, where
   a half-width screenshot is too small to read anything in. */
.site-feature { display: grid; gap: var(--ds-space-6); align-items: center; }
.site-feature + .site-feature { margin-top: var(--ds-space-8); }
/* width:100% is load-bearing, not tidiness. `.site-shot` carries `margin-inline: auto` to
   centre itself in a normal block flow, and inside a grid track that auto margin resolves
   the figure to its max-content width, which for a figure whose only child is an empty
   aspect-ratio box is zero. Rendered, the placeholders collapsed to about 3px and were
   invisible while every test stayed green. */
.site-feature .site-shot { margin-top: 0; width: 100%; }
@media (min-width: 900px) {
  .site-feature { grid-template-columns: 1fr 1fr; }
  /* nth-of-type, not nth-child. The section's <h2> is a sibling of these rows, so
     nth-child counts it as position 1 and every .site-feature lands on the opposite parity
     from the one it reads as in source. The visible effect is that the FIRST row of each
     section renders reversed, and #accounts, which has a single row and no alternation to
     justify a direction, renders shot-left for no reason at all. nth-of-type counts only
     the divs, so parity matches source order. */
  .site-feature:nth-of-type(even) .site-feature__body { order: 2; }
}
.site-feature__body .ds-card__title { margin-bottom: var(--ds-space-3); }
.ds-grid .ds-card__title { margin-bottom: var(--ds-space-2); }

.site-price { max-width: 32rem; margin-inline: auto; text-align: center; }
.site-price__figure { margin-bottom: var(--ds-space-3); }
.site-price .ds-hero__actions { margin-top: var(--ds-space-5); }
.site-price__note { max-width: 52ch; margin: var(--ds-space-6) auto 0; text-align: center; }

/* <details> rather than a JS accordion: it is keyboard accessible, findable by the
   browser's own in-page search when open, and needs no script at all. */
.site-faq { max-width: 46rem; margin-inline: auto; }
.site-faq__item { border-bottom: 1px solid var(--ds-border); padding: var(--ds-space-4) 0; }
.site-faq__item summary { cursor: pointer; font-weight: 500; }
.site-faq__item summary:focus-visible { outline: none; box-shadow: var(--ds-focus-ring); }
.site-faq__item p { margin-top: var(--ds-space-3); }

.site-legal { max-width: 46rem; padding-block: var(--ds-space-8); }
.site-legal .ds-h2 { margin-top: var(--ds-space-6); margin-bottom: var(--ds-space-3); }
.site-legal .ds-prose + .ds-prose { margin-top: var(--ds-space-4); }
.site-legal ul.ds-prose { padding-left: var(--ds-space-5); }
/* The kit's reset is `* { margin: 0; }`, so an element only gets space above it from a rule
   that names it. ".ds-prose + .ds-prose" above covers paragraph-to-paragraph, but the page's
   opening block is h1, then a ".ds-help" dateline, then the first ".ds-prose" paragraph, and
   ".ds-help" carries neither class the sibling rule matches. Rendered, both pages crammed
   the dateline against the title and the opening paragraph against the dateline with zero
   gap, the only place on either page without the vertical rhythm the rest of the content
   has. These two rules close that gap without touching the h2 or prose-to-prose spacing the
   brief specified. */
.site-legal .ds-h1 + .ds-help { margin-top: var(--ds-space-2); }
.site-legal .ds-help + .ds-prose { margin-top: var(--ds-space-4); }

/* The bar carries the CTA above 720px; the collapsed menu carries it below, because the bar
   physically cannot hold all three children at that width. Derived from measurements taken
   2026-08-03 against the real fonts, at v0.7.1 button metrics: brand 192.7 + gap 24 +
   toggle 40 + gap 24 + CTA 150.2 = 430.9 against 327 available at 375px.

   Shrinking the mark is not an alternative: keeping the CTA leaves the wordmark an 88.8px
   budget at 375px and 33.8px at 320px, which at its 7.4111:1 aspect means a 12.0px and a
   4.6px tall mark. A short "Join" label at .ds-btn--sm metrics measured 59.9px and still
   overflowed 320px by about 45px.

   Equal specificity with .ds-btn, (0,1,0), resolved by source order: styles.css loads after
   ui.css on every page, so these win. 720px is the kit's own breakpoint, the one that hides
   .ds-nav__links and reveals the toggle; assets.spec.ts asserts the kit still reveals the
   toggle at exactly that width, so a kit bump moving it fails here rather than silently
   desynchronising these rules from the collapse they are timed against. */
.site-nav__cta-menu { display: none; }
@media (max-width: 720px) {
  .site-nav__cta { display: none; }
  .site-nav__cta-menu { display: inline-flex; }
}

/* The wordmark is 7.4111:1 and ui.css gives it a fixed height (--ds-brand-foot-h, 32px) with
   width:auto, so reset.css's `img { max-width: 100% }` can only take width off it. The mark
   in a track narrower than 237.2px is not smaller, it is DISTORTED: measured 203.00 x 32.00
   at 721px and 218.66 x 32.00 at 768px against a natural 237.14 x 32.00, letterforms
   compressed and the hand-kern with them. Spanning the full row gives it the container.
   823px, not the kit's 720px, because that is where the squeeze actually ends. The kit's
   `repeat(auto-fit, minmax(9rem, 1fr))` with a 32px gap gives the three-item row a track of
   (C - 64) / 3, where C is .ds-container's content width, viewport minus its 2 x 24px
   padding. That first reaches 237.2px at C = 775.5, i.e. a 823.5px viewport. Measured: 823px
   renders 237.00 and 824px renders 237.33, so 823 is the last width that needs the span. */
@media (max-width: 823px) {
  .ds-footer__id { grid-column: 1 / -1; }
}
