/* ============================================================
   Landing page (Views/landing.ejs) — the logged-out marketing page at /.
   Ported from the "Landing Page" Claude Design file; values that map onto
   a token in tokens.css use the token, and the marketing-only sizes the
   design introduces (60px hero, 88px section rhythm) are kept literal.

   The design is desktop-only, so every breakpoint below is ours.
   ============================================================ */

/* The Meyer reset (cssReset.css) skips form controls, so buttons and inputs
   keep the UA font/box model unless we say otherwise. */
.landing-page button,
.landing-page input {
    font-family: inherit;
    box-sizing: border-box;
}

.landing-page {
    font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    color: var(--fd-text);
    background: var(--fd-surface);
}

/* This file only loads on the landing page, so touching the scroll root here is
   scoped by virtue of the stylesheet, not the selector. */
html {
    scroll-behavior: smooth;
}

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

/* The header is sticky and ~82px tall, so an un-offset anchor jump parks the
   section heading underneath it. */
.landing-page section[id] {
    scroll-margin-top: 96px;
}

/* footer.css already makes <body> the flex column and pins the footer with
   margin-top:auto — main just needs to absorb the slack. */
.landing-main {
    flex: 1;
}

/* Colour deliberately omitted: `.landing-page a` is (0,1,1) and would outrank
   every single-class component rule below it — .fd-btn--primary, .landing-nav-link,
   .landing-plan-cta — repainting them all link-blue. Every anchor on this page
   carries its own class, so the base rule only needs to kill underlines. */
.landing-page a {
    text-decoration: none;
}

/* ---------- Shared section furniture ---------- */

.landing-section {
    padding: 88px 40px;
}

.landing-section--sunken {
    background: var(--fd-bg);
    border-top: 1px solid var(--fd-border);
    border-bottom: 1px solid var(--fd-border);
}

.landing-container {
    max-width: 1040px;
    margin: 0 auto;
}

/* For blocks that earn more room (the section showcase, the seven-tile
   strip): the copy column stays at 1040, these go wider without a squeeze. */
.landing-container--wide {
    max-width: 1240px;
}

/* The owner's side of the product goes visually backstage: a full-bleed dark
   band (the #pricing treatment, inverted). Text colors inside are explicit
   light-on-dark hexes -- the --fd text tokens all assume a light surface. */
.landing-section--dark {
    background: var(--fd-text);
}

.landing-section-head {
    text-align: center;
    margin-bottom: 48px;
}

.landing-eyebrow {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--fd-text-muted);
}

.landing-section-head h2 {
    margin: 10px 0 0;
    font-size: 36px;
    font-weight: 700;
    letter-spacing: -0.8px;
    color: var(--fd-text);
}

.landing-section-head p {
    margin: 12px 0 0;
    font-size: 17px;
    color: var(--fd-text-secondary);
}

/* ---------- Buttons (design-system Button, variants used here) ---------- */

.fd-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-sizing: border-box;
    font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    border: 1px solid transparent;
    cursor: pointer;
    transition: var(--fd-transition);
}

/* The DS Button scales down on mousedown; :active is the CSS equivalent. */
.fd-btn:active {
    transform: scale(0.98);
}

.fd-btn--md {
    padding: 10px 18px;
    font-size: 14px;
    min-height: 42px;
    border-radius: var(--fd-radius-sm);
}

.fd-btn--lg {
    padding: 13px 22px;
    font-size: 15px;
    min-height: 48px;
    border-radius: var(--fd-radius);
}

.fd-btn--primary {
    background: var(--fd-primary);
    color: var(--fd-text-inverse);
    box-shadow: 0 1px 2px rgba(37, 99, 235, 0.18);
}

.fd-btn--primary:hover {
    background: var(--fd-primary-hover);
    color: var(--fd-text-inverse);
}

.fd-btn--secondary {
    background: var(--fd-surface);
    color: var(--fd-text);
    border-color: var(--fd-border);
    box-shadow: var(--fd-shadow-xs);
}

.fd-btn--secondary:hover {
    background: var(--fd-bg);
    color: var(--fd-text);
}

/* ---------- Header ---------- */

.landing-header {
    position: sticky;
    top: 0;
    z-index: 1000;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    width: 100%;
    padding: 20px 40px;
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
}

.landing-brand {
    font-size: 26px;
    font-weight: 700;
    color: var(--fd-text);
    letter-spacing: -0.5px;
    padding: 4px 0;
}

.landing-nav {
    display: flex;
    align-items: center;
    gap: 28px;
}

.landing-nav-link {
    font-size: 14.5px;
    font-weight: 500;
    color: var(--fd-text-secondary);
}

.landing-nav-link:hover {
    color: var(--fd-primary);
}

.landing-nav-divider {
    width: 1px;
    height: 22px;
    background: var(--fd-border);
}

.landing-nav-login {
    font-size: 14.5px;
    font-weight: 600;
    color: var(--fd-text);
}

.landing-nav-login:hover {
    color: var(--fd-primary);
}

/* Hamburger — hidden until the nav runs out of room (see breakpoints). */
.landing-nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius-sm);
    color: var(--fd-text);
    cursor: pointer;
    transition: var(--fd-transition);
}

.landing-nav-toggle:hover {
    background: var(--fd-bg);
    border-color: var(--fd-border-hover);
}

/* ---------- Hero ---------- */

.landing-hero {
    padding: 80px 40px;
    background: var(--fd-surface);
}

.landing-hero-inner {
    max-width: none;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    gap: 24px;
}

/* Copy left, phone showcase right. The ratio favours the phones because the
   full three-phone row is 2.64x one phone wide (centre + two 0.82x sides +
   two 14px gaps, nothing overlapping), while the copy is happy under 570px;
   both cells are minmax(0, ...) so a long word can't push the grid past its
   track. Below 1200px this collapses back to one centred column (see
   Responsive). */
.landing-hero-grid {
    max-width: 1440px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.45fr);
    align-items: center;
    gap: 48px;
}

.landing-hero h1 {
    margin: 0;
    /* The authored <br> means "Your whole business," must sit on one line; it
       measures 8.8px of width per 1px of font size (528px at 60px). The copy
       track is (min(1440px, 100vw - 80px) - 48px) / 2.45 — 438px at the 1200px
       breakpoint up to 569px at the grid's cap — so the size tracks the
       viewport, keeping ~10px of slack throughout. Retune the middle term if
       this line's wording changes. */
    font-size: clamp(47px, calc(4.5vw - 7px), 62px);
    line-height: 1.06;
    font-weight: 700;
    letter-spacing: -1.8px;
    color: var(--fd-text);
    text-wrap: balance;
}

.landing-hero-sub {
    margin: 0;
    max-width: 640px;
    font-size: 20px;
    line-height: 1.6;
    color: var(--fd-text-secondary);
    text-wrap: pretty;
}

/* Audience caption under the phone showcase (one per set — see landing.ejs
   for why it is two forced lines and why that keeps the crossfade and layout
   stable). The transform on the side phones paints them 22px low without
   affecting layout, so the caption's top margin carries that visual offset. */
.landing-phone-caption {
    flex-basis: 100%;
    margin: 40px 0 0;
    text-align: center;
    font-size: 13px;
    line-height: 1.5;
}

.landing-phone-caption-lead,
.landing-phone-caption-tail {
    display: block;
}

.landing-phone-caption-lead {
    font-weight: 600;
    color: var(--fd-text-secondary);
}

.landing-phone-caption-tail {
    color: var(--fd-text-muted);
}

/* ---------- Hero phone showcase ---------- */

/*
   Three screenshots in a static phone bezel. The look is the editor preview's
   (.yl-phone-frame in yourPage.css) — black frame, 10px bezel, 40px/32px radii,
   --fd-shadow-xl plus a hairline ring — but sized off the image rather than off
   the viewport, which is all that class's width/height math does.

   Only a width is ever set. Height stays auto so each image's own 780x1418
   ratio drives the box: a screenshot can't be cropped or squashed here, and a
   later set shot at a different height needs no CSS. The width/height
   attributes on the <img> reserve that box before the bytes arrive.
*/
.landing-phones {
    /* The full row is 2.64W + 28px (centre + two 0.82W sides + two 14px gaps,
       all fully visible), and the phone track is (min(1440px, 100vw - 80px)
       - 48px) x 1.45 / 2.45 — so W tracks the viewport with ~6px of slack,
       from ~228px at the 1200px breakpoint to the 300px cap the 1440px grid
       allows. */
    --landing-phone-w: clamp(227px, calc(22.3vw - 40px), 300px);
    margin: 0;
}

/* column-gap, not gap: the caption below wraps onto its own full-width row,
   and a row-gap would stack on top of the caption's own margin. wrap is safe
   for the phones themselves — --landing-phone-w is clamped so the row always
   fits inside the hero padding, so only the flex-basis:100% caption ever
   wraps. */
.landing-phone-set {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    column-gap: 14px;
}

.landing-phone {
    flex: none;
    width: var(--landing-phone-w);
    padding: 10px;
    background: #000000;
    border-radius: 40px;
    box-shadow: var(--fd-shadow-xl), 0 0 0 1px rgba(0, 0, 0, 0.08);
}

.landing-phone img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 32px;
}

.landing-phone--center {
    position: relative;
    z-index: 2;
}

/* The outer two read as secondary: sized down for real (width, bezel and
   radii all x0.82, so the frame stays proportionate) and nudged below the
   centre phone's midline, fully visible beside it. Sized in layout, and flat
   on purpose: any transform that scales or rotates makes the GPU resample the
   painted raster a second time and soften the screenshots — a plain integer
   translate is the one transform that stays pixel-exact, so these render at
   full sharpness. */
.landing-phone--side {
    position: relative;
    z-index: 1;
    width: calc(var(--landing-phone-w) * 0.82);
    padding: 8px;
    border-radius: 33px;
    transform: translateY(22px);
}

.landing-phone--side img {
    border-radius: 26px;
}

/* ---------- Hero showcase rotation ---------- */

/* All sets share one grid cell: every set stays in flow, the container is as
   tall as the tallest visible set (identical 780x1418 images make that every
   set's height, so activation can never reflow anything), and no position swap
   is needed at the crossfade. z-index works on grid items without position. */
.landing-phone-stack {
    display: grid;
}

.landing-phone-set {
    grid-area: 1 / 1;
    z-index: 1;
    opacity: 0;
    pointer-events: none;
    /* Outgoing half of an asymmetric pair (incoming is on .is-active below):
       accelerate holds the outgoing set near opacity 1 early, decelerate gets
       the incoming one there fast, so the two sets' combined alpha stays ~1
       and the pixel-registered black bezels never grey at the midpoint. */
    transition: opacity 450ms cubic-bezier(0.4, 0, 1, 1);
}

/* This rule is load-bearing: .landing-phone-set's display:flex above is
   author-origin and beats the UA's [hidden] { display: none } regardless of
   specificity — without it the deferred sets would render as empty bezels for
   no-JS visitors. landing.js removes [hidden] only once a set is decoded. */
.landing-phone-set[hidden] {
    display: none;
}

.landing-phone-set.is-active {
    z-index: 2;                  /* incoming always paints over outgoing */
    opacity: 1;
    pointer-events: auto;
    transition: opacity 450ms cubic-bezier(0, 0, 0.2, 1);
}

/* Dots are dead weight without JS, so they ship invisible; visibility (not
   display) keeps the row's box reserved from first paint, so the JS reveal
   cannot shift the sections below the hero. */
.landing-phone-dots {
    display: flex;
    justify-content: center;
    gap: 4px;
    margin-top: 28px;
    visibility: hidden;
}

.landing-phones.is-ready .landing-phone-dots {
    visibility: visible;
}

/* The button is the 28px hit area (WCAG 2.5.8 wants >=24); the span inside is
   the 8px visual dot. The active dot grows into a 22px pill inside the fixed
   button box, so the row's width never changes (7x28 + 6x4 = 220px). */
.landing-phone-dot {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    border-radius: var(--fd-radius-full);
}

.landing-phone-dot span {
    width: 8px;
    height: 8px;
    border-radius: var(--fd-radius-full);
    background: var(--fd-border-hover);
    transition: width 250ms cubic-bezier(0.4, 0, 0.2, 1),
                background 250ms cubic-bezier(0.4, 0, 0.2, 1);
}

.landing-phone-dot:hover span {
    background: var(--fd-text-muted);
}

.landing-phone-dot.is-active span {
    width: 22px;
    background: var(--fd-primary);
}

.landing-phone-dot:focus-visible {
    outline: 2px solid var(--fd-primary);
    outline-offset: 2px;
}

/* The screen chips are mobile-only chrome -- wide layouts show all three
   screens side by side, so there is nothing to switch. The <=760 block lays
   them out. */
.landing-phone-chips {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    /* Manual dot switches become instant cuts; landing.js separately never
       auto-advances under reduced motion. */
    .landing-phone-set,
    .landing-phone-set.is-active,
    .landing-phone-dot span {
        transition: none;
    }
}

/* ---------- Hero handle claim field ---------- */

.landing-claim {
    width: 100%;
    max-width: 560px;
    margin-top: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
}

.landing-claim-field {
    display: flex;
    align-items: center;
    width: 100%;
    border: 1.5px solid #e8eaed;
    border-radius: var(--fd-radius-sm);
    background: var(--fd-surface);
    overflow: hidden;
    transition: var(--fd-transition);
}

.landing-claim-field:focus-within {
    border-color: var(--fd-primary);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

.landing-claim-prefix {
    padding: 14px 0 14px 16px;
    font-size: 15px;
    color: #888;
    font-weight: 500;
    user-select: none;
    white-space: nowrap;
}

.landing-claim-input {
    flex: 1;
    min-width: 0;
    border: none;
    background: transparent;
    padding: 14px 4px;
    font-size: 15px;
    color: var(--fd-text);
    outline: none;
}

.landing-claim-submit {
    margin: 5px;
}

.landing-claim-note {
    margin: 0;
    font-size: 13.5px;
    color: var(--fd-text-muted);
}

/* The screenshot framing registry used to live here: one --crop-y per
   mid-page window onto a hero screenshot. Every one of those windows is
   gone -- the showcase shows full screens in a phone, the tile strip shows
   whole pages, and step 2 of #how now shows the editor control instead of a
   crop of its output. No mid-page image is cropped, so a re-shoot needs no
   offset re-tuning anywhere. */

/* ---------- How it works ---------- */

.landing-steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
}

.landing-step {
    display: flex;
    flex-direction: column;
    background: var(--fd-surface);
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius);
    padding: 28px;
    box-shadow: var(--fd-shadow);
}

/* Fixed-height slot pinned to the card bottom so the three cards stay equal
   however tall their copy runs. 176 = the tallest artifact (step 2's four-row
   section list, 155px) plus the 20px stand-off; the pill and the QR simply
   centre in the rest. */
.landing-step-artifact {
    margin-top: auto;
    padding-top: 20px;
    height: 176px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Step 2: a miniature of the page editor's section list. Grey inset panel,
   white rows -- the editor's own arrangement, so the shape is recognisable
   the first time an owner opens Your Page. */
.landing-step-sections {
    width: 100%;
    /* Never bites in the 3-up grid (the panel is ~185px there). It exists for
       the stacked widths, where an 800px-wide card would otherwise smear four
       12.5px rows across the whole thing; capped, the panel centres in the
       slot exactly as step 1's pill and step 3's QR already do. */
    max-width: 400px;
    background: var(--fd-bg);
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius);
    padding: 7px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.landing-step-sec {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
    background: var(--fd-surface);
    border: 1px solid var(--fd-border);
    border-radius: 8px;
}

/* The editor's reorder buttons, scaled: side by side with a 2px gap, each a
   bordered surface-coloured box (yourPage.css .yl-move-arrows/.yl-move-btn at
   26px; 17 here is the same proportion against a 24px chip as 26 is against
   the editor's 38px one). All six stay ONE shade on purpose -- the real list
   fades "up" on the first row and "down" on the last to 30%, which at this
   size would read as a rendering fault rather than as disabled state. */
.landing-step-sec-move {
    display: flex;
    gap: 2px;
    flex-shrink: 0;
}

.landing-step-sec-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 17px;
    height: 17px;
    border: 1px solid var(--fd-border);
    border-radius: 4px;
    background: var(--fd-surface);
    color: var(--fd-text-secondary);
}

/* Neutral, like the editor's .yl-comp-icon -- every section chip there is the
   same grey, so the accent tints the showcase cards use would be a landing-page
   invention. Keeps small-text contrast out of the argument too. */
.landing-step-sec-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border-radius: 7px;
    background: var(--fd-border-light);
    color: var(--fd-text-secondary);
}

.landing-step-sec-label {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--fd-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.landing-step-sec--add {
    justify-content: center;
    padding: 3px 8px;
    background: none;
    border-style: dashed;
    font-size: 11.5px;
    color: var(--fd-text-secondary);
}

/* Read-only echo of the hero claim field (step 1). */
.landing-step-pill {
    display: inline-flex;
    align-items: baseline;
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius-full);
    background: var(--fd-bg);
    padding: 18px 22px;
    font-size: 17px;
    white-space: nowrap;
}

.landing-step-pill-prefix {
    color: var(--fd-text-secondary);
}

.landing-step-pill-handle {
    color: var(--fd-text);
    font-weight: 600;
}

/* The real QR (step 3): the app's own generator output for frontdesk.page. */
.landing-step-artifact--qr {
    flex-direction: column;
}

.landing-step-qr {
    width: 144px;
    height: 144px;
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius);
    background: #ffffff;
    padding: 8px;
    box-sizing: border-box;
}

.landing-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--fd-radius-full);
    background: var(--fd-primary-light);
    color: var(--fd-primary);
    font-size: 14px;
    font-weight: 700;
}

.landing-step h3 {
    margin: 16px 0 8px;
    font-size: 17px;
    font-weight: 600;
    color: var(--fd-text);
}

.landing-step p {
    margin: 0;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--fd-text-secondary);
}

/* ---------- Page sections: section showcase ---------- */

/* Nine selector cards beside one hero-style phone. landing.js rotates the
   phone through the cards; a press shows that card's screen at once and the
   rotation re-anchors from it after a longer dwell instead of stopping for
   good -- deliberately unlike the hero (founder-specced). */
.landing-showcase {
    --showcase-phone-w: 300px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 56px;
    align-items: center;
}

/* position:relative so the rail-centering math (card.offsetLeft) is
   anchored to this box in the sub-1200px swipe layout. */
.landing-showcase-cards {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
}

/* The card is a real <button> (the whole surface is the control), so undo
   the UA chrome; spans play the h3/p roles because a button may contain
   only phrasing content. Without JS the cards are inert -- landing.js adds
   .is-ready before any of the pointer affordances below apply, so a no-JS
   visitor just reads them as the section list. */
.landing-showcase-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    padding: 18px;
    background: var(--fd-surface);
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius);
    box-shadow: var(--fd-shadow);
    font-family: inherit;
    color: inherit;
    cursor: default;
}

.landing-showcase-card .landing-feature-icon {
    width: 36px;
    height: 36px;
}

.landing-showcase-card-title {
    margin-top: 12px;
    font-size: 15px;
    font-weight: 600;
    color: var(--fd-text);
}

.landing-showcase-card-copy {
    margin-top: 5px;
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--fd-text-secondary);
}

.landing-showcase.is-ready .landing-showcase-card {
    cursor: pointer;
    transition: border-color 200ms cubic-bezier(0.4, 0, 0.2, 1),
                box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

.landing-showcase.is-ready .landing-showcase-card:hover:not(.is-active) {
    border-color: var(--fd-border-hover);
    box-shadow: var(--fd-shadow-lg);
}

.landing-showcase-card.is-active {
    border-color: var(--fd-text-secondary);
    box-shadow: 0 0 0 1px var(--fd-text-secondary), var(--fd-shadow);
}

.landing-showcase-card:focus-visible {
    outline: 2px solid var(--fd-primary);
    outline-offset: 2px;
}

/* landing.js adds this only when a pressed card's screen fetch outlives
   250ms (the hero chips' trick), so instant swaps never flicker. */
.landing-showcase-card.is-loading {
    opacity: 0.6;
}

.landing-showcase-stage {
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* The hero phone's exact chrome, under its own name: .landing-phone is
   entangled with the hero's rotation and mobile screen-stack rules. */
.landing-showcase-phone {
    width: var(--showcase-phone-w);
    padding: 10px;
    background: #000000;
    border-radius: 40px;
    box-shadow: var(--fd-shadow-xl), 0 0 0 1px rgba(0, 0, 0, 0.08);
}

/* All nine screens share one grid cell (the hero stack pattern): identical
   780x1418 images keep the cell pixel-stable, so the crossfade can never
   reflow. The radius clips on the stack, not the imgs, so the layers can't
   shear at the corners mid-fade. */
.landing-showcase-screens {
    display: grid;
    border-radius: 32px;
    overflow: hidden;
}

.landing-showcase-screen {
    display: block;
    grid-area: 1 / 1;
    z-index: 1;
    opacity: 0;
    /* The hero's asymmetric easing pair: outgoing holds near opacity 1
       early, incoming rises fast, so combined alpha stays ~1 mid-fade. */
    transition: opacity 450ms cubic-bezier(0.4, 0, 1, 1);
}

.landing-showcase-screen.is-active {
    z-index: 2;
    opacity: 1;
    transition: opacity 450ms cubic-bezier(0, 0, 0.2, 1);
}

/* Load-bearing, same as the hero's: display:block above is author-origin
   and would beat the UA's [hidden] rule, and deferred screens must not
   paint (or fetch) until landing.js decodes and unhides them. */
.landing-showcase-screen[hidden] {
    display: none;
}

.landing-showcase-screen img {
    display: block;
    width: 100%;
    height: auto;
}

@media (prefers-reduced-motion: reduce) {
    /* Card presses become instant cuts; landing.js separately never
       auto-rotates the showcase under reduced motion. */
    .landing-showcase-screen,
    .landing-showcase-screen.is-active {
        transition: none;
    }
}

/* Each card carries its accent as a pair of custom properties so the tint and
   the glyph can never drift apart. Indigo is the default. */
.landing-feature-icon {
    --icon: var(--fd-indigo);
    --icon-bg: var(--fd-indigo-light);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: var(--icon-bg);
    color: var(--icon);
}

.landing-feature-icon--success {
    --icon: var(--fd-success);
    --icon-bg: var(--fd-success-light);
}

.landing-feature-icon--primary {
    --icon: var(--fd-primary);
    --icon-bg: var(--fd-primary-bg);
}

.landing-feature-icon--pink {
    --icon: var(--fd-pink);
    --icon-bg: var(--fd-pink-light);
}

.landing-feature-icon--amber {
    --icon: var(--fd-amber);
    --icon-bg: var(--fd-amber-light);
}

.landing-feature-icon--purple {
    --icon: var(--fd-purple);
    --icon-bg: var(--fd-purple-light);
}

.landing-feature-icon--cyan {
    --icon: var(--fd-cyan);
    --icon-bg: var(--fd-cyan-light);
}

/* ---------- "Make it yours" band ---------- */

/* The theming claim with its evidence: all seven demo headers at once --
   the simultaneity comparison the rotating hero cannot make. Its own
   full-width sunken band now (was a boxed card inside #features), so the
   copy block centres like a section head and the strip takes the wide
   container. */
.landing-design-copy {
    max-width: 640px;
    margin: 0 auto 30px;
    text-align: center;
}

.landing-design h2 {
    margin: 0 0 12px;
    font-size: 36px;
    font-weight: 700;
    letter-spacing: -0.8px;
    color: var(--fd-text);
}

.landing-design p {
    margin: 0;
    font-size: 17px;
    line-height: 1.6;
    color: var(--fd-text-secondary);
    text-wrap: pretty;
}

.landing-brands {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 14px;
}

.landing-brands-item {
    min-width: 0;
}

/* --swatch (set inline per tile) is the tile's average color: the paint
   before hydration, and the whole tile under Save-Data. */
.landing-brands-tile {
    position: relative;
    display: block;
    aspect-ratio: 400 / 727;
    border-radius: 10px;
    overflow: hidden;
    border: 1px solid var(--fd-border);
    background: var(--swatch, var(--fd-bg));
}

.landing-brands-tile picture {
    position: absolute;
    inset: 0;
}

.landing-brands-tile img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* No bottom vignette. It existed to disguise a crop; the tile is the whole
   page now -- header to footer, the hero's phone screen without the phone --
   so there is no cut to disguise, and a fade would only dim the sections the
   strip exists to compare. */

/* ---------- "Behind the page" band ---------- */

/* The perspective flip: light page surfaces above, the owner's side goes
   dark -- a full-bleed .landing-section--dark band now (was a rounded panel
   inside #features). Light-on-dark colors are explicit hexes (checked at
   AA) because the --fd text tokens all assume a light surface. */
.landing-behind .landing-eyebrow {
    display: block;
    color: #94a3b8;
    text-align: center;
}

.landing-behind-headline {
    margin: 10px auto 0;
    font-size: 24px;
    font-weight: 650;
    letter-spacing: -0.5px;
    color: #ffffff;
    max-width: 640px;
    text-align: center;
}

/* Three across, not the old 2x2: with the Bookings item gone (it was a page
   section masquerading as a dashboard feature) a two-column grid leaves an
   orphan on the second row. One row of three sits square under the centered
   headline and makes the count read as deliberate. */
.landing-behind-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    margin-top: 36px;
}

/* Panels, not loose text columns. Three reasons: grid stretch equalises the
   heights (the copy runs 2-3 lines and the old bare columns left a ragged
   bottom edge), a bordered surface makes the row read as three parts of ONE
   dashboard rather than three stray paragraphs, and -- the load-bearing one --
   this is the container the planned dashboard screenshots drop into, so the
   follow-up shoot is an <img> inside the panel and not a re-layout.
   Surfaces are white alphas rather than hexes so they sit on the band's
   var(--fd-text) ground without hard-coding a second dark palette. */
.landing-behind-item {
    padding: 22px 20px;
    background: rgba(255, 255, 255, 0.045);
    border: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: var(--fd-radius);
}

/* The .landing-feature-icon chip from the light sections, restated in dark:
   same 10px radius and tinted-bg/colored-glyph idea, indigo alphas instead of
   the --fd-indigo-light token (which assumes a light surface). One tint for
   all three on purpose -- varying them would say "three unrelated features"
   where the headline says one dashboard. */
.landing-behind-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin-bottom: 14px;
    border-radius: 10px;
    background: rgba(99, 102, 241, 0.16);
    color: #a5b4fc;
}

.landing-behind-item h3 {
    margin: 0 0 5px;
    font-size: 15px;
    font-weight: 600;
    color: #ffffff;
}

.landing-behind-item p {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.55;
    color: #cbd5e1;
}

/* ---------- Mid-page reveal motion (gated) ----------
   Base state is fully visible. The hidden pre-animation state exists ONLY
   under html.js-motion, which landing.js adds after the reduced-motion
   check passes AND the IntersectionObserver constructs -- so no-JS,
   reduced-motion, and script-error paths are all correct by construction. */

html.js-motion .zone-reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}

html.js-motion .zone-reveal.is-inview {
    opacity: 1;
    transform: none;
}

html.js-motion .landing-steps .landing-step:nth-child(2) {
    transition-delay: 80ms;
}

html.js-motion .landing-steps .landing-step:nth-child(3) {
    transition-delay: 160ms;
}

/* The strip "deals" its tiles left to right once the band is in view. */
html.js-motion .landing-design .landing-brands-item {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.45s ease-out, transform 0.45s ease-out;
}

html.js-motion .landing-design.is-inview .landing-brands-item {
    opacity: 1;
    transform: none;
}

html.js-motion .landing-design .landing-brands-item:nth-child(2) { transition-delay: 40ms; }
html.js-motion .landing-design .landing-brands-item:nth-child(3) { transition-delay: 80ms; }
html.js-motion .landing-design .landing-brands-item:nth-child(4) { transition-delay: 120ms; }
html.js-motion .landing-design .landing-brands-item:nth-child(5) { transition-delay: 160ms; }
html.js-motion .landing-design .landing-brands-item:nth-child(6) { transition-delay: 200ms; }
html.js-motion .landing-design .landing-brands-item:nth-child(7) { transition-delay: 240ms; }

/* ---------- Pricing ----------
   The head and container are the shared .landing-section-head / .landing-container--wide
   now, not bespoke copies of them, so this section keeps the page's rhythm for free. */

.landing-plans {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
    align-items: stretch;
}

.landing-plan {
    position: relative;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius-lg);
    padding: 32px;
    background: var(--fd-surface);
    box-shadow: var(--fd-shadow-xs);
    transition: var(--fd-transition);
}

.landing-plan:hover {
    border-color: var(--fd-border-hover);
    box-shadow: var(--fd-shadow-lg);
}

/* The featured card earns its prominence from elevation, not from transform: scale(),
   which would break the row's shared baselines and blur the text it enlarges. */
.landing-plan--featured {
    box-shadow: var(--fd-shadow-lg);
}

/* Drawn as an overlay rather than on the card itself so the featured card keeps
   the same box size as its neighbours and the row stays aligned. */
.landing-plan-ring {
    position: absolute;
    inset: -1px;
    border: 1px solid var(--fd-primary);
    border-radius: var(--fd-radius-lg);
    box-shadow: 0 0 0 1px var(--fd-primary), 0 8px 30px rgba(37, 99, 235, 0.1);
    pointer-events: none;
}

.landing-plan-badge {
    position: absolute;
    top: -12px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--fd-primary);
    color: var(--fd-text-inverse);
    font-size: 12px;
    font-weight: 600;
    padding: 4px 14px;
    border-radius: var(--fd-radius);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    white-space: nowrap;
}

.landing-plan h3 {
    margin: 0 0 8px;
    font-size: 20px;
    font-weight: 600;
    color: var(--fd-text);
}

.landing-plan-price {
    margin: 0 0 4px;
    font-size: 42px;
    font-weight: 700;
    color: var(--fd-text);
    line-height: 1.1;
    letter-spacing: -1px;
}

.landing-plan-price span {
    font-size: 16px;
    font-weight: 400;
    color: var(--fd-text-muted);
    letter-spacing: 0;
}

/* All four taglines ("For solo service providers", etc.) are single-line at every
   width from 901px up (the ≤900px single-column rule below already zeroes this),
   so no reserved height is needed to keep the divider rule on one baseline. */
.landing-plan-desc {
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
    color: var(--fd-text-secondary);
}

.landing-plan-cta {
    display: block;
    width: 100%;
    margin-top: 24px;
    padding: 12px 24px;
    border-radius: var(--fd-radius-sm);
    font-size: 15px;
    font-weight: 600;
    text-align: center;
    background: var(--fd-bg-secondary);
    color: var(--fd-text);
    transition: var(--fd-transition);
}

.landing-plan-cta:hover {
    background: var(--fd-border);
    color: var(--fd-text);
}

.landing-plan-cta:focus-visible {
    outline: 2px solid var(--fd-primary);
    outline-offset: 2px;
}

.landing-plan-cta--featured {
    background: var(--fd-primary);
    color: var(--fd-text-inverse);
    box-shadow: 0 1px 2px rgba(37, 99, 235, 0.18);
}

.landing-plan-cta--featured:hover {
    background: var(--fd-primary-hover);
    color: var(--fd-text-inverse);
}

/* flex:1 is what pins the CTA to the bottom of every card: this box takes all the
   leftover height, so a tier listing five changes and one listing nine still put
   their buttons on the same baseline, and the slack reads as room above the button
   rather than as a card that ran out of content. */
.landing-plan-body {
    flex: 1;
    padding-top: 16px;
    border-top: 1px solid var(--fd-border-light);
}

.landing-plan-inherits {
    margin: 0 0 12px;
    font-size: 13px;
    color: var(--fd-text-muted);
}

.landing-plan-inherits strong {
    font-weight: 600;
    color: var(--fd-text-secondary);
}

.landing-plan-features li {
    display: flex;
    gap: 10px;
    font-size: 14px;
    line-height: 1.45;
    color: var(--fd-text-secondary);
    padding: 7px 0;
}

.landing-plan-features li::before {
    content: "\2713";
    flex-shrink: 0;
    color: var(--fd-success);
    font-weight: 700;
}

.landing-extra-messages {
    margin: 28px 0 0;
    text-align: center;
    font-size: 14px;
    color: var(--fd-text-secondary);
}

.landing-extra-messages strong {
    font-weight: 600;
    color: var(--fd-text);
}

/* Matches the .landing-steps stagger; base state stays visible, so the hidden
   pre-animation state only ever exists under html.js-motion. */
html.js-motion .landing-plans .landing-plan:nth-child(2) {
    transition-delay: 80ms;
}

html.js-motion .landing-plans .landing-plan:nth-child(3) {
    transition-delay: 160ms;
}

html.js-motion .landing-plans .landing-plan:nth-child(4) {
    transition-delay: 240ms;
}

/* ---------- FAQ ---------- */

.landing-faq-container {
    max-width: 760px;
    margin: 0 auto;
}

.landing-faq-container h2 {
    margin: 0 0 40px;
    font-size: 36px;
    font-weight: 700;
    letter-spacing: -0.8px;
    color: var(--fd-text);
    text-align: center;
}

.landing-faq-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.landing-faq-item {
    background: var(--fd-surface);
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius);
    box-shadow: var(--fd-shadow);
}

.landing-faq-item summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 24px;
    cursor: pointer;
    font-size: 16px;
    font-weight: 600;
    color: var(--fd-text);
    list-style: none;
}

.landing-faq-item summary::-webkit-details-marker {
    display: none;
}

.landing-faq-chevron {
    flex-shrink: 0;
    color: var(--fd-text-muted);
    transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.landing-faq-item[open] .landing-faq-chevron {
    transform: rotate(180deg);
}

.landing-faq-item p {
    margin: 0;
    padding: 0 24px 22px;
    font-size: 15px;
    line-height: 1.65;
    color: var(--fd-text-secondary);
}

/* ---------- Closing CTA band ---------- */

.landing-cta {
    padding: 80px 40px;
    background: var(--fd-primary);
    border-top: 1px solid var(--fd-border);
    --band-text: rgba(255, 255, 255, 0.82);
}

.landing-cta-inner {
    max-width: 720px;
    margin: 0 auto;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
}

.landing-cta h2 {
    margin: 0;
    font-size: 38px;
    font-weight: 700;
    letter-spacing: -0.9px;
    color: var(--fd-text-inverse);
    line-height: 1.15;
    text-wrap: balance;
}

.landing-cta p {
    margin: 0;
    font-size: 18px;
    line-height: 1.6;
    color: var(--band-text);
}

.landing-cta-note {
    font-size: 14px !important;
}

.landing-cta .fd-btn {
    margin-top: 8px;
}

/* ============================================================
   Responsive
   ============================================================ */

/* Three phones beside the copy need ~1200px. Below that the hero folds back to
   one centred column with the showcase underneath — the layout this page had
   before the phones existed, plus a phone row. Must stay ABOVE the narrower
   blocks below: they override the phone width from here. */
@media screen and (max-width: 1199px) {

    .landing-hero-grid {
        display: block;
        max-width: none;
    }

    .landing-hero-inner {
        max-width: 820px;
        margin: 0 auto;
        align-items: center;
        text-align: center;
    }

    .landing-hero h1 {
        font-size: 60px;
    }

    .landing-claim {
        align-items: center;
    }

    .landing-phones {
        --landing-phone-w: 340px;
        max-width: 1200px;
        margin: 48px auto 0;
    }

    /* The showcase folds the same way the hero does: the cards become a
       swipe rail (scroll on the rail, never the page; negative margins let
       it bleed to the viewport edge through the section's side padding, and
       the next card's edge-peek is the swipe invitation) and the phone
       centres beneath it. landing.js keeps the active card in the middle of
       the rail and pauses the rotation while a finger is on it. */
    .landing-showcase {
        display: block;
        --showcase-phone-w: min(300px, 100%);
    }

    .landing-showcase-cards {
        display: flex;
        overflow-x: auto;
        gap: 12px;
        margin: 0 -40px;
        padding: 4px 40px;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        /* The rail scrolls by touch/drag; the OS scrollbar track under it is
           chrome nothing else on the page has, so it's suppressed here.
           scrollbar-width covers Firefox, -ms-overflow-style old Edge/IE,
           the pseudo-element covers Chrome/Safari. Scrolling still works --
           only the visible track is gone. */
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .landing-showcase-cards::-webkit-scrollbar {
        display: none;
    }

    .landing-showcase-card {
        flex: 0 0 min(250px, 82vw);
        scroll-snap-align: center;
    }

    .landing-showcase-stage {
        margin-top: 20px;
    }
}

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

    .landing-phones {
        --landing-phone-w: 300px;
    }

    .landing-section,
    .landing-hero,
    .landing-cta {
        padding-left: 24px;
        padding-right: 24px;
    }

    .landing-header {
        padding: 20px 24px;
    }

    /* The section padding narrowed to 24px above; the rail's edge-bleed
       follows it. */
    .landing-showcase-cards {
        margin: 0 -24px;
        padding-left: 24px;
        padding-right: 24px;
    }

    /* Four plan cards stop fitting on one row here; 2×2 until the ≤900px
       single-column rule takes over. */
    .landing-plans {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* The nav's six items stop fitting alongside the wordmark here. */
@media screen and (max-width: 900px) {

    .landing-phones {
        /* The flat row (2.64W + 28px) outgrows a fixed 280px below ~815px of
           viewport; the vw term hands back just enough to keep it inside the
           48px side padding down to the 760px single-phone switch. */
        --landing-phone-w: min(280px, calc(37.8vw - 29px));
    }
    .landing-nav-toggle {
        display: inline-flex;
    }

    .landing-nav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 4px;
        padding: 12px 24px 20px;
        background: var(--fd-surface);
        border-bottom: 1px solid var(--fd-border);
        box-shadow: var(--fd-shadow-md);
    }

    .landing-nav.is-open {
        display: flex;
    }

    .landing-nav-link,
    .landing-nav-login {
        padding: 12px 4px;
        font-size: 16px;
    }

    .landing-nav-divider {
        width: auto;
        height: 1px;
        margin: 8px 0;
    }

    .landing-nav .fd-btn {
        margin-top: 8px;
        width: 100%;
    }

    .landing-plans {
        grid-template-columns: 1fr;
        max-width: 460px;
        margin: 0 auto;
        gap: 32px;
    }

    .landing-steps {
        grid-template-columns: 1fr;
    }

    /* Three columns of owner-side copy squeeze to a ~200px measure here, so
       the row stacks a breakpoint earlier than the old 2x2 did (760px) and
       takes the .landing-plans treatment: one centred column at a readable
       width rather than 800px-wide lines of 13.5px text. */
    .landing-behind-grid {
        grid-template-columns: 1fr;
        max-width: 460px;
        margin-left: auto;
        margin-right: auto;
    }

    /* The header strip becomes a swipe rail; three tiles visible at once
       still proves the range. Rail-level overflow, so the page never
       scrolls sideways. */
    .landing-brands {
        display: flex;
        overflow-x: auto;
        gap: 12px;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        /* Same suppression as the showcase rail: the OS scrollbar track is
           chrome nothing else on the page has, so it's hidden here. */
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .landing-brands::-webkit-scrollbar {
        display: none;
    }

    .landing-brands-item {
        flex: 0 0 140px;
        scroll-snap-align: start;
    }
}

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

    .landing-phones {
        --landing-phone-w: 300px;
        margin-top: 48px;
    }

    /* All three screens of a set stack in the centre phone's footprint and
       the chip row below switches which one shows (landing.js) -- the desktop
       dissolve scoped one level down, inside a constant bezel. The sides are
       normalized to the centre's exact metrics so the swap stays
       pixel-registered, and visibility (not display) keeps the hidden screens
       out of the accessibility tree and tab order while still letting set 1's
       side images fetch here as they always have.
       The screen layers reuse the sets' asymmetric easing pair: the outgoing
       screen holds near opacity 1 early, the incoming rises fast, so combined
       alpha stays ~1 and the black bezel never greys mid-swap. */
    .landing-phone-set {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        /* The wide layout's 14px flex gap would leak in as a row gap between
           the phone and the chips; the chips row spaces itself instead. */
        gap: 0;
    }

    .landing-phone {
        grid-area: 1 / 1;
        z-index: 1;
        opacity: 0;
        visibility: hidden;
        transition: opacity 300ms cubic-bezier(0.4, 0, 1, 1),
                    visibility 0s 300ms;
    }

    .landing-phone--side {
        width: var(--landing-phone-w);
        padding: 10px;
        border-radius: 40px;
        transform: none;
    }

    .landing-phone--side img {
        border-radius: 32px;
    }

    .landing-phone.is-screen-active {
        z-index: 2;
        opacity: 1;
        visibility: visible;
        transition: opacity 300ms cubic-bezier(0, 0, 0.2, 1),
                    visibility 0s;
    }

    /* Chips live inside each set, so the labels ride the set crossfade
       instead of being relabelled by JS. Visibility gates them three ways at
       once: no-JS visitors keep the reserved box but never see dead buttons
       (the dots' trick), inactive sets' rows can't be tabbed into, and at a
       set swap the outgoing row vanishes as the incoming one appears -- two
       rows never double-expose mid-fade. */
    .landing-phone-chips {
        grid-row: 2;
        grid-column: 1;
        display: flex;
        gap: 6px;
        margin-top: 24px;
        visibility: hidden;
    }

    .landing-phones.is-ready .landing-phone-set.is-active .landing-phone-chips {
        visibility: visible;
    }

    /* One phone instead of three, so the caption sits closer; row 3 keeps it
       under the chips row, whose box is reserved even when JS never shows it. */
    .landing-phone-caption {
        grid-row: 3;
        grid-column: 1;
        margin-top: 20px;
    }

    .landing-phone-chip {
        min-height: 32px;
        padding: 6px 14px;
        /* text-secondary/text-muted, not muted/border-hover: 13px button
           labels need WCAG 1.4.3's 4.5:1 (secondary is 7.6:1 on white; muted
           is only 2.6:1), and the boundary should at least approach 3:1. */
        border: 1px solid var(--fd-text-muted);
        border-radius: var(--fd-radius-full);
        background: none;
        font-family: inherit;
        font-size: 13px;
        font-weight: 600;
        line-height: 1.2;
        color: var(--fd-text-secondary);
        cursor: pointer;
        transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1),
                    border-color 200ms cubic-bezier(0.4, 0, 0.2, 1),
                    color 200ms cubic-bezier(0.4, 0, 0.2, 1),
                    opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);
    }

    .landing-phone-chip.is-active {
        background: var(--fd-primary);
        border-color: var(--fd-primary);
        color: #ffffff;
    }

    /* landing.js adds this only once a tapped screen's fetch outlives 250ms,
       so instant swaps never flicker a loading state. */
    .landing-phone-chip.is-loading {
        opacity: 0.55;
    }

    .landing-phone-chip:focus-visible {
        outline: 2px solid var(--fd-primary);
        outline-offset: 2px;
    }

    .landing-phone-dots {
        margin-top: 24px;
    }

    .landing-section,
    .landing-cta {
        padding-top: 64px;
        padding-bottom: 64px;
    }

    .landing-hero {
        padding: 64px 24px 56px;
    }

    .landing-hero h1 {
        font-size: 44px;
        letter-spacing: -1.2px;
    }

    .landing-hero-sub {
        font-size: 17px;
    }

    .landing-section-head {
        margin-bottom: 36px;
    }

    .landing-section-head h2,
    .landing-faq-container h2 {
        font-size: 30px;
        letter-spacing: -0.6px;
    }

    .landing-cta h2 {
        font-size: 30px;
        letter-spacing: -0.6px;
    }

    .landing-cta p {
        font-size: 16px;
    }
}

/* After the <=760 block on purpose: the screen-layer transitions are declared
   there at equal specificity, so this reset must win on source order. Chip
   taps become instant cuts; landing.js separately never runs the set-1 tour
   under reduced motion. */
@media screen and (max-width: 760px) and (prefers-reduced-motion: reduce) {
    .landing-phone,
    .landing-phone.is-screen-active,
    .landing-phone-chip {
        transition: none;
    }
}

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

    .landing-phones {
        /* min(), not a flat 280px: at 320px-wide viewports the 16px hero
           padding leaves 288px, and a fixed frame would push a scrollbar. */
        --landing-phone-w: min(280px, 100%);
    }

    .landing-section,
    .landing-hero,
    .landing-cta {
        padding-left: 16px;
        padding-right: 16px;
    }

    .landing-header {
        padding: 16px;
    }

    .landing-nav {
        padding: 12px 16px 20px;
    }

    .landing-brand {
        font-size: 22px;
    }

    .landing-hero h1 {
        font-size: 36px;
        letter-spacing: -1px;
    }

    /* "frontdesk.page/" + a usable input + the button no longer share a line —
       drop the button beneath the field rather than crushing the input. */
    .landing-claim-field {
        flex-wrap: wrap;
    }

    .landing-claim-input {
        flex-basis: 0;
    }

    .landing-claim-submit {
        flex-basis: 100%;
        margin: 0 5px 5px;
    }

    /* The section padding is 16px here; the showcase rail's edge-bleed
       follows it, and the phone takes the hero's own small-screen cap. */
    .landing-showcase-cards {
        margin: 0 -16px;
        padding-left: 16px;
        padding-right: 16px;
    }

    .landing-showcase {
        --showcase-phone-w: min(280px, 100%);
    }

    .landing-plan {
        padding: 24px;
    }

    .landing-faq-item summary {
        padding: 18px;
        font-size: 15px;
    }

    .landing-faq-item p {
        padding: 0 18px 20px;
        font-size: 14px;
    }
}
