/*
 * baybay.baby — the landing page.
 *
 * Loaded only here. base.css supplies the tokens; everything below is the
 * wide marketing layout, which shares nothing with the 30rem app shell.
 *
 * One rule holds the page together: coral means feeding and mint means
 * sleep, everywhere, and neither colour is ever used for decoration. That is
 * what lets the day strip be read rather than merely looked at.
 */

/* --------------------------------------------------------------------------
   Page frame
   -------------------------------------------------------------------------- */

body.lp {
    background: var(--background);
    /* Clears the fixed demo dock on phones so the footer is never trapped
       underneath it. Zero everywhere the dock is hidden. */
    padding-bottom: var(--dock-space, 0);
}

/* The gutter is a custom property rather than a literal because one thing
   inside the wrap has to undo it: a horizontal rail wants to bleed to both
   screen edges, and it can only do that by knowing the number. */
.wrap {
    --wrap-pad: 1.15rem;
    width: 100%;
    max-width: 68rem;
    margin: 0 auto;
    padding: 0 var(--wrap-pad);
}

@media (min-width: 40rem) {
    .wrap { --wrap-pad: 1.5rem; }
}

.skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 0.7rem 1.1rem;
    background: var(--primary);
    color: #fff;
    border-radius: 0 0 var(--radius-sm) 0;
    text-decoration: none;
}

.skip:focus {
    left: 0;
    color: #fff;
}

/* A jump to #pricing must not land under the sticky bar. */
section[id] {
    scroll-margin-top: 5.5rem;
}

@media (prefers-reduced-motion: no-preference) {
    html:has(body.lp) { scroll-behavior: smooth; }
}

/* Every section states its own vertical rhythm in exactly one place, so a
   later rule cannot quietly win a specificity argument over padding. */
.band {
    padding: clamp(3.5rem, 9vw, 7rem) 0;
}

.band--dark {
    background: var(--dark);
    color: #dfe9dd;
}

.band--dark h2,
.band--dark h3 {
    color: #fff;
}

.band--tint {
    background: var(--light);
}

.band + .band--tint,
.band--tint + .band {
    border-top: 1px solid var(--border);
}

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */

.eyebrow {
    display: block;
    margin-bottom: 0.9rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted);
}

.band--dark .eyebrow {
    color: var(--accent);
}

.title {
    margin: 0 0 0.7rem;
    font-size: clamp(1.5rem, 3.4vw, 2.05rem);
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.15;
    color: var(--primary);
}

.lede {
    max-width: 34rem;
    margin: 0;
    color: var(--muted);
    font-size: 1rem;
    line-height: 1.65;
}

.band--dark .lede {
    color: #b7c8b5;
}

.section-head {
    margin-bottom: clamp(2rem, 4vw, 3rem);
}

.section-head--centred {
    text-align: center;
}

.section-head--centred .lede {
    margin-inline: auto;
}

/* --------------------------------------------------------------------------
   Navigation
   -------------------------------------------------------------------------- */

.nav {
    position: sticky;
    top: 0;
    z-index: 20;
    background: rgba(250, 252, 247, 0.88);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid transparent;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.nav.is-stuck {
    border-bottom-color: var(--border);
    box-shadow: 0 2px 12px rgba(31, 45, 32, 0.05);
}

.nav__inner {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    min-height: 4.25rem;
}

.nav__brand {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-right: auto;
    color: var(--primary);
    font-weight: 700;
    font-size: 1.1rem;
    letter-spacing: -0.02em;
    text-decoration: none;
}

.nav__brand img {
    width: 34px;
    height: 34px;
    border-radius: 50%;
}

.nav__links {
    display: flex;
    gap: 1.4rem;
}

.nav__links a {
    color: var(--muted);
    font-size: 0.85rem;
    text-decoration: none;
}

.nav__links a:hover {
    color: var(--primary);
}

.nav__end {
    display: flex;
    align-items: center;
    gap: 1.1rem;
}

.nav__quiet {
    color: var(--muted);
    font-size: 0.85rem;
    text-decoration: none;
    white-space: nowrap;
}

.nav__quiet:hover { color: var(--primary); }

/* --------------------------------------------------------------------------
   The bar's one button, and what it becomes

   The bar is sticky and the dock is fixed, so from the moment the dock rises
   they are both on screen offering the same demo — the exact duplication the
   dock was written to avoid, reintroduced by the bar outliving the hero.

   So the button changes hands rather than repeating: the dock keeps the demo,
   and the bar takes the source link, which on a phone is otherwise only
   behind the burger. Only on a phone — the dock never rises above 46rem, and
   the bar carries a "GitHub" link of its own above 62rem.

   `:has(.nav__cta--code)` guards the swap: before the repository is public
   there is no code button to swap in, and a bar that hid its demo button for
   nothing would leave a phone with a logo and a burger.
   -------------------------------------------------------------------------- */

/* Scoped to .nav rather than written bare, and not for tidiness: `.cta` sets
   `display: inline-flex` further down this file at the same specificity, so a
   bare `.nav__cta--code` loses on source order and the bar carries both
   buttons at once. The reveal below wins on specificity in turn. */
.nav .nav__cta--code { display: none; }

@media (max-width: 46rem) {
    .nav.is-docked:has(.nav__cta--code) .nav__cta--demo { display: none; }

    .nav.is-docked .nav__cta--code { display: inline-flex; }
}

/* --------------------------------------------------------------------------
   The drawer

   Below 62rem the five section links do not fit beside the brand and the
   demo button, and below 26rem the GitHub link did not either. They used to
   be dropped and that was the end of it: a phone got a logo and one green
   button, and every other way into the page — install, pricing, the FAQ, the
   source — simply did not exist. The burger is where they went.

   The two breakpoints are one breakpoint now. There is no width at which
   some of the links are on the bar and the rest are behind a button.
   -------------------------------------------------------------------------- */

.nav__burger {
    display: none;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    /* Optical, not geometric: the bar's right edge is the wrap gutter, and a
       centred glyph inside a 44px box reads as inset from it. */
    margin-right: -0.6rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--primary);
    cursor: pointer;
}

.nav__burger .ico {
    width: 1.5rem;
    height: 1.5rem;
}

.nav__burger:hover { background: var(--light); }

@media (max-width: 62rem) {
    .nav__links { display: none; }

    .nav__quiet { display: none; }

    .nav__burger { display: inline-flex; }
}

/* Both are siblings of the header rather than children of it — see the note
   in the template. `position: fixed` is not enough on its own: the bar's
   `backdrop-filter` makes it a containing block for fixed descendants too,
   so the panel has to be outside it as well as fixed.

   Above the dock (30) and the bar (20), because it covers both. */
.nav__scrim {
    position: fixed;
    inset: 0;
    z-index: 40;
    background: rgba(26, 61, 26, 0.38);
    opacity: 0;
    transition: opacity 0.22s ease;
}

.nav__drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 41;
    display: flex;
    flex-direction: column;
    width: min(19rem, 82vw);
    /* The inline padding is the page gutter; the block padding also clears
       the notch and the home indicator, since the panel runs full height. */
    padding: calc(0.9rem + env(safe-area-inset-top)) 1.25rem
             calc(1.25rem + env(safe-area-inset-bottom));
    background: var(--surface);
    border-left: 1px solid var(--border);
    box-shadow: -18px 0 40px rgba(27, 36, 28, 0.16);
    transform: translateX(100%);
    transition: transform 0.24s cubic-bezier(0.22, 0.68, 0.32, 1);
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* A class sets `display: flex` above, and the UA's `[hidden]` rule is a
   single attribute selector — it loses, and the "hidden" panel sits open
   over the page. This is the rule that actually closes it. */
.nav__scrim[hidden],
.nav__drawer[hidden] {
    display: none;
}

/* `hidden` comes off a frame before `.is-open` goes on, so the panel has a
   painted closed state to move away from. Toggling display alone would put
   it straight there with no transition at all. */
.nav__scrim.is-open { opacity: 1; }

.nav__drawer.is-open { transform: none; }

.nav__drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.5rem;
}

.nav__drawer-title {
    color: var(--muted-light);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.nav__drawer-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-right: -0.75rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--muted);
    cursor: pointer;
}

.nav__drawer-close .ico {
    width: 1.35rem;
    height: 1.35rem;
}

.nav__drawer-close:hover {
    background: var(--light);
    color: var(--primary);
}

.nav__drawer-links {
    display: flex;
    flex-direction: column;
}

/* Full-width rows with a rule between them. A drawer is a list of places,
   and the hairline does the separating that whitespace does on the wide bar
   without spending half the panel's height on gaps. */
.nav__drawer-links a {
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-size: 0.95rem;
    text-decoration: none;
}

.nav__drawer-links a:last-child { border-bottom: 0; }

.nav__drawer-links a:hover { color: var(--primary); }

/* At the foot of the panel, because it leaves the site — it is not one of
   the five places above it. */
.nav__drawer-quiet {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: auto;
    padding-top: 1.25rem;
    color: var(--muted);
    font-size: 0.85rem;
    text-decoration: none;
}

.nav__drawer-quiet:hover { color: var(--primary); }

/* It slides for everyone else; for anyone who asked for less motion it
   simply appears. */
@media (prefers-reduced-motion: reduce) {
    .nav__scrim,
    .nav__drawer {
        transition: none;
    }
}

/* The page behind the scrim must not scroll. Set on <body> by the script for
   as long as the drawer is open. */
body.nav-open {
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   Resume banner

   Sits above the hero, and only for a visitor who already has a demo open.
   Deliberately built from the brand greens and never from coral or mint:
   those two mean feeding and sleep everywhere else on this page, and a
   navigational bar that borrowed them would be the one place they meant
   nothing.

   Dark, for the same reason the closer and the footer are. On the warm
   off-white it was a pale strip carrying the same solid green pills as the
   header's "Try the demo", one row below it — so the only bar addressed to
   somebody who is already using the product read as a second line of
   navigation and disappeared. Inverted, its buttons borrow the light
   variants the dark sections further down already use, and the band is the
   first thing a returning visitor sees rather than the last.
   -------------------------------------------------------------------------- */

.resume {
    background: var(--dark);
}

.resume__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1.25rem;
    padding-top: 0.85rem;
    padding-bottom: 0.85rem;
}

.resume__note {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    color: #b7c8b5;
    font-size: 0.88rem;
    line-height: 1.45;
}

.resume__note b {
    color: #fff;
    font-weight: 600;
}

/* The sentence is wrapped rather than sitting bare beside the icon: a <b>
   next to a text node is two flex items, and on a phone the bold half and
   the rest of the line sat in columns instead of flowing. One element, one
   flex item, and min-width lets it wrap below its longest word. */
.resume__text {
    min-width: 0;
}

/* The icon keeps its size when the note wraps onto two lines. */
.resume__icon {
    display: inline-flex;
    flex: 0 0 auto;
    color: var(--primary);
}

.resume__icon svg {
    width: 17px;
    height: 17px;
}

.resume__links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* On a phone the chips sized themselves to their labels, so a slug like
   moss-acorn-4359 sat as a small target against a mostly empty row. Given
   the row to themselves they grow into it instead.

   The basis stays `auto` rather than 0, which matters more than it looks.
   A slug is at most "silver-starling-8987" — twenty characters, about 195px
   once the padding is on — so two of the long ones cannot share a 353px row
   and have to wrap. Flex decides where to break a line from the hypothetical
   size, and a zero basis makes that zero: every button would be dealt onto
   one line, never wrap, and then refuse to shrink below its own nowrap label
   and spill out of the bar. With `auto` they wrap when they must and fill
   whatever line they land on, at any count up to the five the query allows.

   The cost is that two buttons grow by the same amount rather than to the
   same width, so unequal labels stay unequal by the difference between them
   — around eight pixels for two real slugs, against text overflowing the
   button. Not a close call. */
@media (max-width: 46rem) {
    .resume__links {
        width: 100%;
    }

    .resume__links .cta {
        flex: 1 1 auto;
    }
}

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

.hero {
    position: relative;
    padding: clamp(2rem, 5vw, 3.5rem) 0 clamp(3rem, 7vw, 5rem);
    overflow: hidden;
}

/* A single soft wash behind the art, in the sleep mint. It is the only
   gradient on the page, which is what keeps it from reading as decoration. */
.hero::before {
    content: '';
    position: absolute;
    top: -14rem;
    right: -10rem;
    width: 42rem;
    height: 42rem;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(78, 205, 196, 0.16), transparent 62%);
    pointer-events: none;
}

.hero__grid {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 21rem);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}

@media (max-width: 58rem) {
    .hero__grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* A monospace face has no narrow glyphs to fall back on, so the longest line
   sets the floor: "logged in two taps" is 18 characters at roughly 0.55em of
   advance each after tracking, which is all that fits across a 390px phone.
   A larger minimum here widens the whole document rather than wrapping. */
.hero__title {
    margin: 0 0 1.1rem;
    font-size: clamp(1.6rem, 7.6vw, 3.9rem);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.05em;
    color: var(--primary);
}

/* The second line drops to the light end of the variable axis. One family,
   two voices — which is the whole typographic idea on this page. */
.hero__title em {
    display: block;
    font-style: normal;
    font-weight: 200;
    color: var(--secondary);
}

.hero__lede {
    max-width: 30rem;
    margin: 0 0 1.75rem;
    color: var(--muted);
    font-size: 1.05rem;
    line-height: 1.6;
}

.hero__ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0.9rem;
}

.hero__note {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted-light);
}

/* --------------------------------------------------------------------------
   The three objections

   Answered in the hero because a parent evaluating another baby app has
   exactly these three, in this order.
   -------------------------------------------------------------------------- */

.trust {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
    gap: 1.1rem 1.5rem;
    margin: 2.25rem 0 0;
    padding: 0;
    list-style: none;
}

.trust li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: 0 0.6rem;
    align-items: center;
}

.trust__icon {
    grid-row: span 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 50%;
}

.trust__icon .ico {
    width: 1.1rem;
    height: 1.1rem;
    vertical-align: 0;
}

.trust__icon--green { background: #e8f2e6; color: var(--primary); }
.trust__icon--mint  { background: #e2f6f4; color: var(--sleep-dark); }
.trust__icon--amber { background: #fdf0e2; color: #b5730f; }

.trust b {
    align-self: end;
    font-size: 0.86rem;
    color: var(--text);
}

.trust span:last-child {
    align-self: start;
    font-size: 0.76rem;
    line-height: 1.4;
    color: var(--muted);
}

/* --------------------------------------------------------------------------
   Hero art — the phone

   Deliberately unobstructed. The screenshot's entire job is showing the two
   buttons and the elapsed pills; anything floated on top covers precisely the
   part worth looking at.
   -------------------------------------------------------------------------- */

.hero__art {
    display: flex;
    justify-content: center;
}

.phone {
    position: relative;
    width: 100%;
    max-width: 17.5rem;
    /* The extra top padding is the bezel the earpiece sits in, so the detail
       lands on the frame rather than on the screenshot. */
    padding: 1.5rem 0.6rem 0.9rem;
    background: #1b241c;
    border-radius: 2.4rem;
    box-shadow: 0 18px 40px rgba(27, 36, 28, 0.22);
}

.phone__speaker {
    position: absolute;
    top: 0.72rem;
    left: 50%;
    width: 3.2rem;
    height: 0.3rem;
    border-radius: 999px;
    background: #34443a;
    transform: translateX(-50%);
}

.phone img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 1.5rem;
}

@media (max-width: 58rem) {
    .hero__art .phone { max-width: 15.5rem; }
}

/* The pair in the screens section, where two have to sit side by side. */
.phone--sm {
    max-width: 15rem;
    padding: 1.15rem 0.5rem 0.7rem;
    border-radius: 1.9rem;
}

.phone--sm .phone__speaker {
    top: 0.55rem;
    width: 2.6rem;
}

.phone--sm img { border-radius: 1.2rem; }

/* --------------------------------------------------------------------------
   The hero on a phone

   Reordered rather than merely stacked. Stacked, the copy ran the full width
   and the screenshot landed below the fold, so the first thing a parent saw
   of a product whose whole claim is "two taps" was three lines of prose and
   the three objections spread over three tall rows.

   So the phone leads and is cut off at its waist. Half a screen is enough to
   read the two buttons and the elapsed pills, and the half it costs is what
   buys room for the title and the buttons to sit under it rather than after
   it. The three objections then run as one rail: side by side they are a
   glance, and the row that scrolls past the edge says there are three of
   them without spending three rows saying so.
   -------------------------------------------------------------------------- */

@media (max-width: 46rem) {
    .hero {
        padding-top: 1.25rem;
    }

    .hero__grid {
        gap: 1.75rem;
    }

    /* Source order is unchanged, so the copy is still what a screen reader
       and the crawler meet first. Only the painting order moves. */
    .hero__art {
        order: -1;
        align-items: flex-start;
    }

    /* A ratio rather than a fixed height is what keeps the crop in the same
       place at every width: the frame's height is a multiple of its own
       width, so the proportion of the screenshot on show never moves.

       1:1.75 cuts about 83% of the way down, part-way through the second
       recent entry. The cut lands inside a row on purpose — mid-row reads as
       "there is more below", where a cut in the gap between two rows reads
       as the end of the list.

       It was 1:1.15 while the screenshot ended at the day's totals, which
       stopped 133px short of the first entry and showed none of the list at
       all. Raising it costs about 160px of hero, which is why the title and
       the first button still have to clear the fold on a 844px phone —
       check that before raising it again. */
    .hero__art .phone {
        max-width: 16.5rem;
        aspect-ratio: 1 / 1.75;
        overflow: hidden;
        padding-bottom: 0;
        border-radius: 2.4rem 2.4rem 0 0;
        /* Ambient, with no downward offset: a shadow cast below a hard crop
           draws a bottom edge the phone is not supposed to have. */
        box-shadow: 0 0 34px rgba(27, 36, 28, 0.17);
    }

    .hero__lede {
        margin-bottom: 1.4rem;
    }

    /* Two full-width buttons, because side by side at this width they were
       two half-width buttons with the labels wrapping inside them. */
    .hero__ctas .cta--lg {
        flex: 1 0 100%;
        justify-content: center;
    }

    /* One rail instead of three rows. The negative margin is exactly the
       wrap's gutter, so the row runs edge to edge and the second card is
       visibly cut by the screen — the only honest way to say the row moves
       without printing an arrow next to it. */
    .trust {
        display: flex;
        gap: 0.6rem;
        margin: 1.6rem calc(var(--wrap-pad) * -1) 0;
        /* The vertical padding is the card shadow's room; without it the
           overflow clips the lift off the top and bottom edges. */
        padding: 0.35rem var(--wrap-pad);
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
    }

    .trust::-webkit-scrollbar { display: none; }

    /* Boxed here and only here. In the two-column layout these three sit in
       open space beneath the buttons and need no frame; in a scrolling row
       the frame is what makes each one a separate thing to swipe past. */
    .trust li {
        flex: 0 0 13rem;
        gap: 0 0.55rem;
        padding: 0.75rem 0.85rem;
        scroll-snap-align: start;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        box-shadow: var(--shadow);
    }
}

/* --------------------------------------------------------------------------
   The day strip — the page's signature

   One real day, midnight to midnight. Mint bars are sleep, coral ticks are
   feeds, and the positions come from the same seed data the demo is built
   from, so it is a reading of an actual day rather than an illustration.
   -------------------------------------------------------------------------- */

.daystrip {
    margin-top: clamp(2.5rem, 6vw, 4rem);
    padding: 1.25rem 1.3rem 1.1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.daystrip__caption {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
    margin-bottom: 0.85rem;
}

.daystrip__title {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted);
}

.daystrip__key {
    display: flex;
    gap: 1.1rem;
    font-size: 0.75rem;
    color: var(--muted);
}

.daystrip__key span {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.daystrip__key i {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 2px;
    font-style: normal;
}

.daystrip__key i.is-feed { background: var(--feed); }
.daystrip__key i.is-sleep { background: var(--sleep); }

.daystrip__band {
    position: relative;
    height: 3.8rem;
    background: var(--light);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

/* Faint rules every six hours, so the eye can find noon without a label. */
.daystrip__band::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: linear-gradient(to right, var(--border) 1px, transparent 1px);
    background-size: 25% 100%;
}

.daystrip__sleep {
    position: absolute;
    top: 0.7rem;
    height: 1.1rem;
    min-width: 3px;
    background: var(--sleep);
    border-radius: 3px;
}

/* Feeds are instants, not spans, so they are ticks. Wide enough to register
   as marks at a glance, which 3px was not. */
.daystrip__feed {
    position: absolute;
    bottom: 0.7rem;
    width: 5px;
    height: 1.1rem;
    margin-left: -2.5px;
    background: var(--feed);
    border-radius: 2px;
}

.daystrip__hours {
    position: relative;
    height: 1.2rem;
    margin-top: 0.45rem;
    font-size: 0.68rem;
    color: var(--muted-light);
}

.daystrip__hours span {
    position: absolute;
    transform: translateX(-50%);
}

.daystrip__hours span:first-child { transform: none; }
.daystrip__hours span:last-child { transform: translateX(-100%); }

.daystrip__summary {
    margin: 0.75rem 0 0;
    font-size: 0.85rem;
    color: var(--muted);
}

.daystrip__summary b {
    color: var(--text);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 46px;
    padding: 0.7rem 1.4rem;
    border: 1.5px solid var(--primary);
    border-radius: var(--radius-sm);
    background: var(--primary);
    color: #fff;
    font-family: var(--font);
    font-size: 0.92rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}

.cta .ico {
    width: 1rem;
    height: 1rem;
    vertical-align: 0;
}

.cta:hover {
    background: var(--primary-light);
    border-color: var(--primary-light);
    color: #fff;
    box-shadow: var(--shadow-lift);
}

.cta:active { transform: translateY(1px); }

.cta--sm {
    min-height: 40px;
    padding: 0.45rem 1rem;
    font-size: 0.85rem;
}

.cta--lg {
    min-height: 52px;
    padding: 0.8rem 1.6rem;
    font-size: 1rem;
}

.cta--ghost {
    background: transparent;
    border-color: var(--border);
    color: var(--primary);
}

.cta--ghost:hover {
    background: var(--surface);
    border-color: var(--accent);
    color: var(--primary);
    box-shadow: none;
}

.cta--light {
    background: #fff;
    border-color: #fff;
    color: var(--dark);
}

.cta--light:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--dark);
}

.cta--outline-light {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.35);
    color: #fff;
}

.cta--outline-light:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: #fff;
    color: #fff;
    box-shadow: none;
}

/* A third tier for the hero, and the only filled button on the page that is
   not the solid brand green. "Try the demo" is the ask and "Get the code" is
   the aside; this is neither, so it should not look like either.

   Sage, not coral and not mint. Those two mean feeding and sleep everywhere
   on this page and a button is neither — the rule the whole design rests on
   is that neither colour is ever spent on decoration. Amber was the other
   candidate and cannot be used: #b5730f on its cream is 3.5:1 and a solid
   amber under white is 3.9:1, both short of AA. This pairing is 5.2:1. */
.cta--soft {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--primary);
}

/* The fill stays put and the text deepens instead — 7.9:1 — because the
   inherited .cta:hover would swap in white on sage and drop it to 2:1. */
.cta--soft:hover {
    background: var(--accent);
    border-color: var(--accent-dark);
    color: var(--dark);
}

/* Phones only. Above this the same jump is already on the bar as "Pricing",
   and a button repeating a link that is visible on the same screen is the
   page asking twice. 46rem is where the hero becomes its phone layout, and
   where everything else on this page stops calling itself wide. */
.cta--phone { display: none; }

@media (max-width: 46rem) {
    .cta--phone { display: inline-flex; }
}

.cta[disabled] {
    opacity: 0.72;
    cursor: not-allowed;
}

.cta[disabled]:hover {
    transform: none;
    box-shadow: none;
}

/* --------------------------------------------------------------------------
   The day, as moments

   Each one is stamped with the time it happens, because the sequence is the
   argument: this is a day, in order, and logging it costs two minutes.
   -------------------------------------------------------------------------- */

.moments {
    display: grid;
    gap: 1px;
    background: var(--border);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}

/* Six moments, two columns, three full rows. An odd count here leaves a bare
   cell showing the grid's own background, so the count and the layout have to
   agree — add a seventh moment and this needs revisiting. */
@media (min-width: 46rem) {
    .moments { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.moment {
    display: flex;
    gap: 1rem;
    padding: 1.5rem 1.4rem;
    background: var(--surface);
}

.moment__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    background: var(--light);
    color: var(--secondary);
}

.moment__icon .ico {
    width: 1.15rem;
    height: 1.15rem;
    vertical-align: 0;
}

.moment--feed .moment__icon  { background: #fdeceb; color: var(--feed-dark); }
.moment--sleep .moment__icon { background: #e2f6f4; color: var(--sleep-dark); }

.moment__clock {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    font-variant-numeric: tabular-nums;
    color: var(--muted-light);
}

.moment--feed .moment__clock  { color: var(--feed); }
.moment--sleep .moment__clock { color: var(--sleep-dark); }

.moment h3 {
    margin: 0 0 0.3rem;
    font-size: 0.98rem;
}

.moment p {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--muted);
}

.tally {
    margin-top: clamp(2rem, 4vw, 3rem);
    text-align: center;
}

.tally img {
    display: block;
    margin: 0 auto 0.5rem;
}

.tally__lead {
    margin: 0 0 1.3rem;
    color: var(--muted);
    font-size: 0.95rem;
}

.tally__lead b {
    color: var(--primary);
    font-weight: 700;
}

.tally__note {
    margin: 0.85rem 0 0;
    font-size: 0.78rem;
    color: var(--muted-light);
}

/* --------------------------------------------------------------------------
   Features
   -------------------------------------------------------------------------- */

/* Fixed column counts rather than auto-fit: six cards over four columns
   strands two on their own row. */
.features {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
}

@media (min-width: 40rem) {
    .features { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 60rem) {
    .features { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.feature {
    display: flex;
    flex-direction: column;
    padding: 1.6rem 1.4rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.feature:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow);
}

/* The one place a gradient earns its keep: it makes six identical cards read
   as a set of tiles rather than a wall of text. */
.feature__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.9rem;
    height: 2.9rem;
    margin-bottom: 1.1rem;
    border-radius: 0.85rem;
    background: linear-gradient(140deg, var(--primary-light), var(--primary));
    color: #fff;
    box-shadow: 0 4px 10px rgba(45, 90, 45, 0.22);
}

.feature__icon .ico {
    width: 1.35rem;
    height: 1.35rem;
    vertical-align: 0;
}

.feature h3 {
    margin: 0 0 0.4rem;
    font-size: 0.98rem;
}

.feature p {
    margin: 0 0 1.2rem;
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--muted);
}

/* The three cards without a preview end on their paragraph. */
.feature p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Miniature interface, inside a feature card

   Drawn in CSS from the same tokens the application uses, so it cannot drift
   into showing something the app does not do. Decorative to a screen reader —
   the paragraph above each one says the same thing in words.
   -------------------------------------------------------------------------- */

/* The three previews are three different shapes — a sheet with two cards and
   a button, a pair of pills, a chart — and left to themselves they were 175,
   77 and 139 pixels tall. Bottom-aligning them lined up the one edge nobody
   looks at and left gaps of 19, 118 and 56 pixels above them, so the middle
   card read as a paragraph marooned above a strip.

   So the preview grows into whatever the paragraph leaves instead. The
   tallest one still sets the height of the row, the other two grow to meet
   it, and their contents sit centred in the space. No height is written down
   anywhere: swap any preview for a taller one and the row re-settles.

   `flex: 1 0 auto` rather than `flex: 1` — a zero basis would let a long
   paragraph squeeze a preview below its own content and push it out of the
   box. This way natural height is the floor and growth is the only change. */
.demo-ui {
    flex: 1 0 auto;
    display: grid;
    align-content: center;
    padding: 0.85rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--light);
}

.demo-ui__label {
    display: block;
    margin-bottom: 0.55rem;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--muted);
}

/* The figure under the name, the way a dashboard chart card sets it: same
   weights and the same light face for the number. */
.demo-ui__stat {
    display: block;
    margin: -0.35rem 0 0.6rem;
    font-size: 0.95rem;
    font-weight: 300;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--primary);
}

.demo-ui__choices {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem;
    margin-bottom: 0.5rem;
}

/* Cards, not chips: the icon sits above the word in the sheet, which is
   what makes the two readable at arm's length in the dark. */
.demo-ui__choice {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    padding: 0.5rem 0.4rem;
    border: 1.5px solid var(--border);
    border-radius: 0.5rem;
    background: var(--surface);
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--muted);
}

.demo-ui__choice .ico {
    width: 1.15rem;
    height: 1.15rem;
    vertical-align: 0;
}

/* Each type wears its colour before it is picked, so the pair reads at a
   glance rather than as two grey boxes. */
.demo-ui__choice--bottle .ico { color: var(--bottle); }
.demo-ui__choice--breast .ico { color: var(--breast); }

/* Picked, the card deepens into that same colour — it does not turn green.
   Green is this page's colour, not the sheet's. */
.demo-ui__choice--breast.is-on {
    border-color: var(--breast);
    background: var(--breast-tint);
    color: var(--breast-dark);
}

.demo-ui__choice--bottle.is-on {
    border-color: var(--bottle);
    background: var(--bottle-tint);
    color: var(--bottle-dark);
}

/* The tick is a corner badge in the app, not a glyph in front of the word:
   selection is carried by more than colour, without costing a line. */
.demo-ui__check {
    position: absolute;
    top: 0.15rem;
    right: 0.2rem;
    display: block;
    color: inherit;
}

.demo-ui__check .ico {
    width: 0.7rem;
    height: 0.7rem;
}

/* One round button, grey until a type is picked and then the colour of the
   thing it is about to save. Shrunk from the app's 116px, which is a thumb
   target rather than a proportion worth reproducing at this size. */
.demo-ui__go {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.1rem;
    height: 3.1rem;
    margin: 0.6rem auto 0.15rem;
    border-radius: 50%;
    background: var(--breast);
    box-shadow: 0 5px 14px rgba(236, 111, 159, 0.4);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

/* Overrides the grid above rather than inheriting it: the pills belong on one
   line beside each other, and align-items keeps them centred now that the box
   is taller than they are. */
.demo-ui--pills {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 1.35rem 0.85rem;
}

.demo-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.35rem 0.8rem;
    border-radius: 999px;
    color: #fff;
    font-size: 0.8rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.demo-pill .ico {
    width: 0.85rem;
    height: 0.85rem;
    vertical-align: 0;
}

.demo-pill--feed  { background: var(--feed); }
.demo-pill--sleep { background: var(--sleep-dark); }

/* Bars standing on an axis rather than floating, which is the one thing
   that separated this from the chart it is drawn after. */
.demo-bars {
    display: flex;
    align-items: flex-end;
    gap: 0.35rem;
    height: 3.4rem;
    padding-bottom: 0.3rem;
    border-bottom: 1px solid var(--border);
}

.demo-bars i {
    flex: 1;
    border-radius: 2px 2px 0 0;
    background: var(--feed);
    opacity: 0.85;
}

/* --------------------------------------------------------------------------
   Screens
   -------------------------------------------------------------------------- */

.screens {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: clamp(2rem, 5vw, 3.5rem);
    max-width: 46rem;
    margin: 0 auto;
}

.screens__item {
    margin: 0;
    text-align: center;
}

.screens__item .phone {
    margin: 0 auto;
}

.screens figcaption {
    margin-top: 1.25rem;
    font-size: 0.82rem;
    line-height: 1.65;
    color: var(--muted);
    text-align: left;
}

.screens figcaption b {
    color: var(--primary);
}

/* --------------------------------------------------------------------------
   Comparison

   Set as a real monospace table. The typeface is doing the aligning, which is
   the reason to use a mono face for something other than code.
   -------------------------------------------------------------------------- */

.compare-scroll {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}

/* min-width is what forces the horizontal scroll rather than letting five
   columns of prose squeeze into a tablet's width one word per line. Raised
   from 38rem when the Baby Buddy column arrived. */
.compare {
    width: 100%;
    min-width: 48rem;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.compare th,
.compare td {
    padding: 0.85rem 1rem;
    text-align: left;
    border-bottom: 1px solid var(--border);
}

.compare thead th {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--muted);
    vertical-align: bottom;
}

.compare thead .col-ours img {
    display: block;
    margin-bottom: 0.3rem;
    border-radius: 50%;
}

.compare tbody tr:last-child th,
.compare tbody tr:last-child td {
    border-bottom: none;
}

.compare tbody th {
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
}

.compare tbody th .ico {
    width: 0.95rem;
    height: 0.95rem;
    margin-right: 0.4rem;
    color: var(--secondary);
}

.compare td {
    color: var(--muted);
}

/* The product's own column is the only one that gets a surface. Tinted from
   --accent rather than --light, which is too close to the section behind it
   to register as a highlight at all. */
.compare .col-ours {
    background: rgba(184, 216, 186, 0.26);
    color: var(--text);
    border-left: 1px solid var(--accent);
    border-right: 1px solid var(--accent);
}

.compare thead .col-ours {
    color: var(--primary);
    border-top-left-radius: var(--radius);
    border-top-right-radius: var(--radius);
}

.compare__mark {
    margin-right: 0.4rem;
    font-weight: 700;
}

.compare__mark--yes { color: var(--success); }
.compare__mark--no { color: var(--danger); }
.compare__mark--meh { color: #d69e2e; }

/* Below the tablet breakpoint the table stops being a table. Five columns of
   prose in a side-scrolling grid is unreadable on a phone, so each row becomes
   a small card and every cell wears the column name it came from. The markup
   is unchanged — the data-label on each cell carries the heading across, and
   the rule is written per-cell rather than per-column, so it took no edit when
   a fifth column was added. */
@media (max-width: 46rem) {
    .compare-scroll {
        overflow-x: visible;
        border: none;
        background: none;
    }

    .compare,
    .compare tbody,
    .compare tr,
    .compare th,
    .compare td {
        display: block;
        width: auto;
        min-width: 0;
    }

    /* The column headings move into the cells, so the head row is redundant —
       and hiding it this way keeps it out of the accessibility tree too, which
       is right, because the labels below now say the same thing. */
    .compare thead {
        display: none;
    }

    .compare tr {
        margin-bottom: 0.85rem;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        background: var(--surface);
        overflow: hidden;
    }

    .compare tbody th {
        padding: 0.8rem 1rem;
        background: var(--light);
        border-bottom: 1px solid var(--border);
        font-size: 0.88rem;
        white-space: normal;
    }

    /* The label sits above the value rather than beside it. A two-column
       grid here would make each cell's ✓/✕ span its own grid item and push
       the sentence onto a line of its own. */
    .compare td {
        padding: 0.7rem 1rem;
        font-size: 0.84rem;
        line-height: 1.55;
    }

    .compare td::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 0.1rem;
        font-size: 0.66rem;
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--muted-light);
    }

    .compare tbody tr:last-child td:last-child,
    .compare td:last-child {
        border-bottom: none;
    }

    /* Our column keeps its tint, now as the card's last band. */
    .compare .col-ours {
        border-left: none;
        border-right: none;
        border-top: 1px solid var(--accent);
    }

    .compare .col-ours::before {
        color: var(--primary);
    }
}

/* --------------------------------------------------------------------------
   Source
   -------------------------------------------------------------------------- */

.source__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: clamp(2rem, 5vw, 3.5rem);
    align-items: center;
}

.terminal {
    background: #0f1710;
    border: 1px solid #27392a;
    border-radius: var(--radius);
    overflow: hidden;
}

.terminal__bar {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.7rem 0.9rem;
    background: #162117;
    border-bottom: 1px solid #27392a;
}

.terminal__bar i {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: #2f4432;
}

.terminal__name {
    margin-left: 0.4rem;
    font-size: 0.72rem;
    color: #7d9880;
}

.terminal pre {
    margin: 0;
    padding: 1.1rem 1.2rem;
    overflow-x: auto;
    font-family: var(--font);
    font-size: 0.79rem;
    line-height: 1.85;
    color: #cfe0cd;
}

.terminal .c { color: #6f8b72; }
.terminal .p { color: var(--accent); }

.stack {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 1.5rem 0;
    padding: 0;
    list-style: none;
}

.stack li {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.36rem 0.8rem;
    border: 1px solid #334b36;
    border-radius: 100px;
    font-size: 0.76rem;
    color: #c3d6c1;
}

.stack .ico {
    width: 0.9rem;
    height: 0.9rem;
    color: var(--accent);
    vertical-align: 0;
}

.source__ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* On a phone the two of them want about 367px between them and have 353, so
   they were already breaking onto two lines — just at their label widths,
   which left the second one hanging short under the first. Stacked properly
   they are two full-width targets, the same shape the hero's buttons take at
   this width. Column rather than `flex: 1 0 100%` because stacking is the
   intent; the full width is what stretch then gives for free. */
@media (max-width: 46rem) {
    .source__ctas {
        flex-direction: column;
    }
}

.source__soon {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 1.1rem 0 0;
    font-size: 0.8rem;
    color: #7d9880;
}

/* --------------------------------------------------------------------------
   Pricing
   -------------------------------------------------------------------------- */

.plans {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 1.15rem;
    max-width: 44rem;
    margin: 0 auto;
}

.plan {
    display: flex;
    flex-direction: column;
    padding: 1.7rem 1.5rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.plan--feature {
    border-color: var(--accent);
    box-shadow: var(--shadow);
}

.plan__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    margin-bottom: 1rem;
    border-radius: 0.8rem;
    background: var(--light);
    color: var(--primary);
}

.plan__icon .ico {
    width: 1.25rem;
    height: 1.25rem;
    vertical-align: 0;
}

.plan--feature .plan__icon {
    background: linear-gradient(140deg, var(--primary-light), var(--primary));
    color: #fff;
}

.plan__name {
    margin: 0 0 0.75rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--muted);
}

.plan__price {
    display: flex;
    align-items: baseline;
    gap: 0.3rem;
    margin-bottom: 0.3rem;
    color: var(--primary);
}

.plan__amount {
    font-size: 2.6rem;
    font-weight: 300;
    letter-spacing: -0.05em;
    line-height: 1;
}

.plan__period {
    font-size: 0.85rem;
    color: var(--muted);
}

.plan__blurb {
    margin: 0 0 1.3rem;
    font-size: 0.85rem;
    color: var(--muted);
}

.plan ul {
    flex: 1;
    margin: 0 0 1.5rem;
    padding: 0;
    list-style: none;
    font-size: 0.86rem;
}

.plan li {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    padding: 0.32rem 0;
    color: var(--text);
}

.plan li .ico {
    width: 0.95rem;
    height: 0.95rem;
    margin-top: 0.28rem;
    color: var(--secondary);
    vertical-align: 0;
}

.plan__after {
    margin: 0.7rem 0 0;
    text-align: center;
    font-size: 0.76rem;
    color: var(--muted-light);
}

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

   Two columns from the tablet breakpoint up, and the answers are set narrower
   than the band so a line does not run the full width of a desktop — nine
   answers at 90 characters a line is a wall, and the whole point of the
   section is that a reader can find the one question they came with.
   -------------------------------------------------------------------------- */

.faq {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.6rem 3rem;
}

@media (min-width: 46rem) {
    .faq {
        grid-template-columns: repeat(2, 1fr);
    }
}

.faq__item {
    max-width: 34rem;
}

.faq__q {
    margin: 0 0 0.4rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
}

.faq__a {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.65;
    color: var(--muted);
}

/* --------------------------------------------------------------------------
   Closing invitation
   -------------------------------------------------------------------------- */

.closer {
    padding: clamp(3rem, 7vw, 5rem) 0;
    background: var(--dark);
    text-align: center;
}

.closer img {
    display: block;
    margin: 0 auto 1.1rem;
}

.closer .title {
    color: #fff;
}

.closer .lede {
    max-width: 32rem;
    margin: 0 auto 1.75rem;
    color: #b7c8b5;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.foot {
    padding: clamp(2.5rem, 6vw, 4rem) 0 3rem;
    background: #16311a;
    color: #b7c8b5;
    font-size: 0.85rem;
}

.foot__top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1.25rem;
    padding-bottom: 1.6rem;
    border-bottom: 1px solid #2b4130;
}

.foot__brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: #fff;
    font-weight: 700;
    text-decoration: none;
}

.foot__brand img {
    width: 32px;
    height: 32px;
    border-radius: 50%;
}

.foot__links {
    display: flex;
    flex-wrap: wrap;
    gap: 1.3rem;
}

.foot a {
    color: #b7c8b5;
    text-decoration: none;
}

.foot a:hover {
    color: #fff;
    text-decoration: underline;
}

.foot__bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.6rem;
    padding-top: 1.5rem;
    color: #7d9880;
    font-size: 0.78rem;
}

.foot__bottom p { margin: 0; }

/* --------------------------------------------------------------------------
   The demo dock

   Phones only, and only once the hero button has scrolled away. A parent
   reading this one-handed should never have to hunt back up the page for the
   one action worth taking.
   -------------------------------------------------------------------------- */

.dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: none;
    padding: 0.7rem 1rem calc(0.7rem + env(safe-area-inset-bottom));
    background: rgba(250, 252, 247, 0.94);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--border);
    transform: translateY(110%);
    transition: transform 0.22s ease;
}

.dock.is-up { transform: none; }

.dock .cta { width: 100%; }

@media (max-width: 46rem) {
    .dock { display: block; }

    /* Reserve the dock's height so it never covers the last of the footer. */
    body.lp { --dock-space: 4.75rem; }
}

/* --------------------------------------------------------------------------
   Motion

   One orchestrated entrance, nothing else. Anything scroll-triggered would
   fight a page whose whole argument is that it does not waste your time.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
    .rise {
        animation: rise 0.5s cubic-bezier(0.22, 0.68, 0.32, 1) backwards;
    }

    .rise:nth-child(1) { animation-delay: 0.04s; }
    .rise:nth-child(2) { animation-delay: 0.12s; }
    .rise:nth-child(3) { animation-delay: 0.2s; }
}

@keyframes rise {
    from { opacity: 0; transform: translateY(0.6rem); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .dock { transition: none; }
}
