/* ==========================================================================
   Kestrel: the landing page

   The second of two stylesheets, and the only page here that fetches it.
   assets/kestrel.css is a dashboard's: nav, cards, panels, feeds, charts,
   four thousand lines that every page behind the front door needs all of.
   This page needs about a tenth of that (the tokens, the chart, the live
   pill, the badge, the snippet block), and then several hundred rules of its
   own that no dashboard page will ever draw. Two files means neither pays
   for the other. See the note by $pageStyle in views/head.php.

   Loaded after the sheet it extends, which is what lets the token block
   below simply restate `--bg` and friends: same specificity, later file,
   so it wins without !important and without a single selector having to be
   made artificially heavy. The one exception is dark, where the sheet above
   qualifies its tokens twice over, hence `:root.lp:not([data-theme="light"])`
   rather than the plainer thing it looks like it should be.

   The look is the dashboard's, warmed. Same teal, same type stack, same
   figures with tabular numerals; a paper ground instead of a cool grey one,
   and radii and shadows about twice the size, because this page is six wide
   cards on a field rather than forty small ones in a grid. Everything on it
   is one of three shapes: a pill, a card, or a line of type, which is most
   of why it reads as calm next to the page it is advertising.
   ========================================================================== */

:root.lp {
    /* The page's own ground and the ink on it. Warm rather than neutral: the
       dashboard is a tool and is painted like one, and this is the thing in
       front of it. */
    --bg: #f4f1ea;
    --surface: #fffdf9;
    --border: #e7e1d5;
    --border-strong: #d8d0c1;
    --text: #15171b;
    --muted: #6d685e;
    --faint: #a29c90;

    /* The solid button, which is the one loud thing on the page, and its
       opposite, because in dark it is the page that is dark and the button
       that is not. Two tokens rather than a colour and a hard-coded white,
       so the pair inverts in one place. */
    --lp-ink: #16181d;
    --lp-on-ink: #fbfaf7;

    /* What the dashboard's own ground is, for the one element that has to
       hold a picture of the dashboard: the window down the page renders real
       cards inside itself, and cards painted on paper would not be a picture
       of anything. Restated rather than remembered, so see .lp-window, which
       hands them straight back to the tokens the cards read. */
    --lp-screen: #f6f7f9;
    --lp-screen-surface: #ffffff;
    --lp-screen-border: #e5e7ee;

    /* And what the two films in the hero are laid on, which is the one colour
       on this page that does not turn with the theme. It is behind a picture
       rather than under one: both films are a window on a near-black desktop,
       they are letterboxed by nothing, and the only moment this is visible at
       all is the frame before a decoder has anything to show. Light, that
       frame would be a white flash through the middle of the hero. So it is
       stated once here and never restated below. */
    --lp-film: #0b0d13;

    /* And what goes on top of it, for the one control that does: the disc in
       the corner of each film. Not `--lp-on-ink`, which is the pair of the
       solid button and inverts with everything else: over a picture that is
       near-black in both themes, half the time that token is near-black too. */
    --lp-on-film: #eef0f5;

    /* Three lifts, and which one a thing wears says what it is. Flat is a
       panel sitting on the page; lift is a card; float is a card that is
       meant to look as though it is in front of the page rather than on it,
       and only the two films in the hero wear it. */
    --lp-lift: 0 1px 2px rgba(38, 31, 18, 0.04), 0 10px 26px -14px rgba(38, 31, 18, 0.16);
    --lp-float: 0 2px 4px rgba(38, 31, 18, 0.04), 0 28px 60px -26px rgba(38, 31, 18, 0.3);
    /* And a fourth, which is not a fourth kind of thing: it is float with a
       hand under it. Worn by the film behind the film while a pointer is on
       it, and by nothing else. */
    --lp-float-lift: 0 3px 8px rgba(38, 31, 18, 0.05), 0 34px 74px -26px rgba(38, 31, 18, 0.34);

    --lp-round: 22px;
    --lp-round-sm: 13px;
    --lp-max: 1180px;
    --lp-gutter: clamp(1.15rem, 4vw, 2.5rem);
}

/* Dark, as the system preference: held off where light was chosen by hand.
   Qualified exactly as the sheet above qualifies its own, or that one wins on
   specificity and this page comes up in the dashboard's grey. */
@media (prefers-color-scheme: dark) {
    :root.lp:not([data-theme="light"]) {
        --bg: #0b0d11;
        --surface: #14171d;
        --border: #232833;
        --border-strong: #313746;
        --text: #e9ebf1;
        --muted: #979dab;
        --faint: #666c7a;
        --lp-ink: #eff0f4;
        --lp-on-ink: #12141a;
        --lp-screen: #0e1015;
        --lp-screen-surface: #171a22;
        --lp-screen-border: #252a37;
        --lp-lift: 0 0 0 1px rgba(255, 255, 255, 0.02);
        --lp-float: 0 24px 60px -28px rgba(0, 0, 0, 0.9);
        --lp-float-lift: 0 30px 72px -26px rgba(0, 0, 0, 0.95);
    }
}

/* Dark, as the explicit choice. Same values, deliberately: the same
   duplication the sheet above keeps, for the same reason: two mechanisms
   decide this and neither can be expressed in terms of the other. */
:root.lp[data-theme="dark"] {
    --bg: #0b0d11;
    --surface: #14171d;
    --border: #232833;
    --border-strong: #313746;
    --text: #e9ebf1;
    --muted: #979dab;
    --faint: #666c7a;
    --lp-ink: #eff0f4;
    --lp-on-ink: #12141a;
    --lp-screen: #0e1015;
    --lp-screen-surface: #171a22;
    --lp-screen-border: #252a37;
    --lp-lift: 0 0 0 1px rgba(255, 255, 255, 0.02);
    --lp-float: 0 24px 60px -28px rgba(0, 0, 0, 0.9);
    --lp-float-lift: 0 30px 72px -26px rgba(0, 0, 0, 0.95);
}

/* The hero's cards are meant to run off the right-hand edge, which means
   something has to stop the page scrolling sideways to follow them. `clip`
   rather than `hidden` on purpose: `hidden` would make the body a scroll
   container and take the sticky nav down with it. */
:root.lp,
.lp body {
    overflow-x: clip;
}

.lp body {
    background: var(--bg);
    color: var(--text);
    text-rendering: optimizeLegibility;
}

/* The ground, which is two things at almost no strength: a wash of the accent
   under the top of the page, and a vertical grain over all of it. Both are
   below the threshold at which anybody would name them, and that is the
   point: a flat field this large reads as unfinished, and a field with a
   pattern on it reads as decorated. Fixed and inert, so it costs no layout
   and catches no clicks. */
.lp body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: radial-gradient(120% 70% at 50% -12%, var(--accent-soft), transparent 62%);
}

/* The grain is the light theme's alone, and is added rather than taken away,
   which is the way round that keeps this readable. It is a warm brown at a
   sixtieth of an opacity, which does something to paper and nothing at all to
   a near-black field except cost a paint. Both mechanisms again, and the
   explicit one last so it beats the query it contradicts. */
@media (prefers-color-scheme: light) {
    :root.lp:not([data-theme="dark"]) body::before {
        background:
            radial-gradient(120% 70% at 50% -12%, var(--accent-soft), transparent 62%),
            repeating-linear-gradient(90deg, rgba(80, 66, 40, 0.016) 0 1px, transparent 1px 4px);
    }
}

:root.lp[data-theme="light"] body::before {
    background:
        radial-gradient(120% 70% at 50% -12%, var(--accent-soft), transparent 62%),
        repeating-linear-gradient(90deg, rgba(80, 66, 40, 0.016) 0 1px, transparent 1px 4px);
}

.lp-main,
.lp-nav,
.lp-foot {
    position: relative;
    z-index: 1;
}

/* --------------------------------------------------------------- the shell */

.lp-hero,
.lp-strip,
.lp-shot,
.lp-steps,
.lp-badges,
.lp-ai,
.lp-close {
    max-width: var(--lp-max);
    margin-inline: auto;
    padding-inline: var(--lp-gutter);
    /* The nav is pinned to the top of the window, so an anchor that lands a
       section's first line at the top of the window lands it underneath the
       nav. This is the height of the pill and the air around it, given back. */
    scroll-margin-top: 5.5rem;
}

/* And the jump to one is a scroll rather than a cut, where anybody has left
   that switched on. Scoped to this page: the dashboard's panes slide under a
   fixed nav of their own and have their own opinion about scrolling. */
@media (prefers-reduced-motion: no-preference) {
    :root.lp { scroll-behavior: smooth; }
}

.lp-h1 {
    margin: 0 0 1.15rem;
    font-size: clamp(2.6rem, 6.4vw, 4.4rem);
    font-weight: 640;
    line-height: 1.02;
    letter-spacing: -0.038em;
}

/* Balanced, because these are short headings in narrow columns and the
   default greedy wrap leaves a single word on the second line about half the
   time. It does nothing to the one above, which breaks where the markup says
   to: an explicit <br> is not a wrap and there is nothing to balance. */
.lp-h2 {
    margin: 0 0 0.85rem;
    font-size: clamp(1.65rem, 3.4vw, 2.5rem);
    font-weight: 620;
    line-height: 1.1;
    letter-spacing: -0.028em;
    text-wrap: balance;
}

.lp-lede {
    max-width: 34rem;
    margin: 0 0 2rem;
    color: var(--muted);
    font-size: clamp(1rem, 1.55vw, 1.13rem);
    line-height: 1.62;
}

.lp-sub {
    max-width: 38rem;
    margin: 0 0 0.9rem;
    color: var(--muted);
    font-size: 1.02rem;
    line-height: 1.62;
}

/* An inline `<code>` in this page's prose. A tinted pill rather than bare
   monospace, because these are filenames and tag names set inside sentences
   and the eye has to be told where each one ends. */
.lp-sub code,
.lp-step__text code {
    padding: 0.08em 0.28em;
    border-radius: 5px;
    background: var(--accent-soft);
    color: var(--text);
    font-family: var(--mono);
    font-size: 0.86em;
}

/* The badge standing where the eyebrow used to. Nothing is drawn around it
   (no card, no border, no tint), because a badge already is a pill on a plate
   and a second one behind it would be two badges. All this contributes is the
   space under it, and the small lift that says the thing is pressable, which a
   badge on somebody else's page has no way to say and this one does. */
.lp-hero__badge {
    display: inline-block;
    margin-bottom: 1.35rem;
    border-radius: 999px;
    line-height: 0;
    text-decoration: none;
    transition: transform 0.14s ease;
}

.lp-hero__badge:hover { transform: translateY(-1px); }

.lp-hero__badge:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

.lp-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 1.4rem;
    padding: 0.32rem 0.85rem 0.32rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    box-shadow: var(--lp-lift);
    color: var(--muted);
    font-size: 0.79rem;
    letter-spacing: 0.005em;
}

/* The same breathing dot the live pill wears, for the same reason: it is what
   says the sentence beside it is about now rather than about a claim. */
.lp-eyebrow i {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent);
    animation: lp-pulse 2.6s ease-in-out infinite;
}

@keyframes lp-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.28; }
}

/* ------------------------------------------------------------- the buttons */

.lp-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 0.95rem;
    border: 1px solid transparent;
    border-radius: 999px;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 560;
    letter-spacing: -0.008em;
    text-decoration: none;
    white-space: nowrap;
    transition: transform 0.14s ease, box-shadow 0.14s ease, background-color 0.14s ease;
}

.lp-btn--lg {
    padding: 0.62rem 0.68rem 0.62rem 1.25rem;
    font-size: 1rem;
}

.lp-btn--dark {
    background: var(--lp-ink);
    color: var(--lp-on-ink);
    box-shadow: var(--lp-lift);
}

.lp-btn--dark:hover {
    transform: translateY(-1px);
    box-shadow: var(--lp-float);
}

.lp-btn--ghost {
    border-color: var(--border-strong);
    background: var(--surface);
    color: var(--text);
}

.lp-btn--ghost:hover {
    border-color: var(--text);
}

/* The disc at the end of the loud button. Lifted straight off the reference
   this page is modelled on, and kept because it does a job: it turns the
   button into something with a direction, which is the difference between a
   label and an invitation. Painted with the ink's own colour at low alpha, so
   it inverts with the button rather than needing a token of its own. */
.lp-btn__disc {
    display: grid;
    flex: none;
    place-items: center;
    width: 1.65rem;
    height: 1.65rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--lp-on-ink) 18%, transparent);
}

.lp-btn--lg .lp-btn__disc {
    width: 1.9rem;
    height: 1.9rem;
}

.lp-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    margin-bottom: 1.1rem;
}

.lp-actions--centre {
    justify-content: center;
}

.lp-fineprint {
    margin: 0;
    color: var(--faint);
    font-size: 0.82rem;
}

/* ------------------------------------------------------------------ the nav

   A pill floating over the page rather than a bar across it. The page below
   is a column of wide cards on a field, and a full-width bar would lay a
   second horizontal edge over the top of that; as a pill it reads as one more
   card, which is what it is.

   Sticky rather than fixed, so it takes its own height out of the flow once
   at the top instead of sitting over the first line of the hero. */
.lp-nav {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    justify-content: center;
    padding: 0.85rem var(--lp-gutter);
    pointer-events: none;
}

.lp-nav__pill {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    max-width: 100%;
    padding: 0.4rem 0.4rem 0.4rem 1.05rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: color-mix(in srgb, var(--surface) 86%, transparent);
    box-shadow: var(--lp-lift);
    pointer-events: auto;
    -webkit-backdrop-filter: saturate(1.5) blur(14px);
    backdrop-filter: saturate(1.5) blur(14px);
}

.lp-nav__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-right: 0.6rem;
    color: var(--text);
    font-size: 1rem;
    font-weight: 640;
    letter-spacing: -0.022em;
    text-decoration: none;
}

.lp-nav__brand svg { color: var(--accent); }

.lp-nav__links {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.lp-nav__links a {
    padding: 0.4rem 0.7rem;
    border-radius: 999px;
    color: var(--muted);
    font-size: 0.87rem;
    font-weight: 500;
    text-decoration: none;
}

.lp-nav__links a:hover {
    background: var(--accent-soft);
    color: var(--text);
}

.lp-nav__cta {
    margin-left: 0.35rem;
}

/* The theme control, in a bar that is already a pill.

   The buttons, the three states and the rule that lights the chosen one are
   all in assets/kestrel.css and are not repeated here: they key off the
   `data-theme-set` attribute rather than off a class, which is what lets the
   same control work in two navs that look nothing alike. What this undoes is
   only the container. .themeset draws its own ring and ground, which is right
   in the dashboard's flat bar and one ring too many inside a pill that has
   already drawn both — nested, it reads as a control that fell in.

   Sized against the links beside it rather than against the dashboard's,
   which is the other half of belonging here: 30px is the height of a nav link
   with its padding, so the row has one baseline instead of two. */
.lp-nav__theme {
    padding: 0;
    border: 0;
    background: none;
}

.lp-nav__theme .themeset__btn {
    width: 30px;
    height: 30px;
    color: var(--muted);
}

/* Hover matches the links, which is the same colour the lit segment carries.
   Written after the lit rule wins the tie between them on source order, and
   that is the right way round: a button under the cursor should answer the
   cursor, including the one already chosen. */
.lp-nav__theme .themeset__btn:hover {
    background: var(--accent-soft);
    color: var(--text);
}

/* ----------------------------------------------------------------- the hero

   Two columns, and the right-hand one is allowed past the page's own margin.
   That is the whole trick of a hero like this: a card that ends neatly inside
   the gutter reads as a diagram of the product, and one cut off by the edge of
   the window reads as a piece of it. */
.lp-hero {
    display: grid;
    grid-template-columns: minmax(0, 1.03fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center;
    max-width: calc(var(--lp-max) + 5rem);
    padding-top: clamp(3.5rem, 9vw, 6.5rem);
    padding-bottom: clamp(3rem, 7vw, 5.5rem);
}

/* The two films, laid out on a grid of their own so the overlap is a row and
   a column rather than a stack of measured offsets. Twelve columns because the
   one in front wants to start at the page's own margin and stop a hair short
   of the right-hand edge, while the one behind it starts a sixth of the way in
   and runs off past it, and twelfths are the coarsest grid that can say both
   of those without rounding one of them into the other.

   Which film is where is an attribute rather than a class, because the two
   swap: views/landing.php's script sets `data-at`, and every difference
   between a film in front and a film behind is written once, below. */
.lp-hero__art {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    align-items: start;
    margin-right: clamp(-4rem, -3vw, 0rem);
}

.lp-clip {
    position: relative;
    padding: 0.55rem 0.6rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: var(--lp-round);
    background: var(--surface);
    box-shadow: var(--lp-float);
}

/* Behind: up, over to the right, off the edge of the page, and a degree or so
   off square. The tilt is small on purpose. What it buys is that the pair
   stops reading as a diagram of a product and starts reading as two things
   left on a desk: an impression made at about a degree and a half. Past four
   it stops looking dropped and starts looking broken.

   The foot of it is covered by whatever is in front, which is why the title is
   at the top of the card and not under the picture: the strip of this that
   shows is its head and the top half of its first frame, and a card whose name
   is behind another card is a card nobody can choose. */
.lp-clip[data-at="back"] {
    z-index: 1;
    grid-column: 3 / -1;
    grid-row: 1;
    transform: rotate(1.4deg) scale(0.985);
}

/* In front: square, and that is the load-bearing line in this whole block.
   Everything else here is decoration, but a film of a terminal is read rather
   than glanced at, and two degrees of rotation puts every straight edge and
   every letter in it through a resample. The card behind is a picture and can
   lean; the one being watched cannot.

   Pulled up by a proportion of the grid's own width rather than by a measured
   distance, so the overlap is the same overlap at every size this is drawn at:
   a percentage margin resolves against the container's inline size, which
   here is the thing every other length on these two cards derives from. */
.lp-clip[data-at="front"] {
    z-index: 2;
    grid-column: 1 / 12;
    grid-row: 2;
    margin-top: -27%;
}

/* One line where there is room for one and two where there is not, decided by
   the bar itself rather than at a width somebody picked. A phone is where this
   runs out: the card behind is about three hundred pixels across there, and
   "Let Claude Code install it" beside a tag saying "In the terminal" is a hair
   more than that, so the tag drops under the title and both are whole. Which
   is the right answer, because a title truncated to "Let Claude Co…" is the
   one thing on that card doing any work. */
.lp-clip__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.45rem;
    margin: 0 0 0.5rem;
    padding: 0.1rem 0.2rem 0;
}

/* The floor under that: a title refuses to shrink below its own text, which is
   what pushes the tag onto a second line instead of eating the title. Capped
   at the width of the card, so a title longer than any card could hold still
   ellipsises rather than running out of the side of it. */
.lp-clip__title {
    min-width: min(100%, max-content);
    overflow: hidden;
    color: var(--text);
    font-size: 0.9rem;
    font-weight: 620;
    letter-spacing: -0.012em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Which of the two ways in this film is, said in a glyph and three or four
   words. It never changes and it is what tells the two cards apart at the
   distance a hero is read from: a window against a terminal, at opposite ends
   of the same short sentence. A duration used to be here and is now only in
   the button's name: it is worth knowing before you press play, and it is
   not worth the one chip a card this size has to spend. */
.lp-clip__tag {
    display: inline-flex;
    flex: none;
    gap: 0.32rem;
    align-items: center;
    margin-left: auto;
    padding: 0.16rem 0.55rem 0.16rem 0.45rem;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 560;
    white-space: nowrap;
}

.lp-clip__tag .icon {
    flex: none;
    color: var(--accent);
}

/* And what pressing the card would do, at the other end of the bar. A disc
   rather than a bare glyph, because on the card behind this is the only mark
   on the page that says the card is a control, and a play triangle floating
   loose beside a title reads as punctuation.

   Filled while it is stopped and quiet while it is running, which is the way
   round it has to be: the disc on the card behind is an invitation and the one
   on the card in front is a status. The strong colour goes to the film nobody
   is watching yet.

   `--lp-on-ink` for the glyph inside the filled state rather than a white,
   because the accent is a deep teal in light and a bright one in dark, and a
   white triangle on the second of those is a triangle nobody can see. That
   token is already the pair of "the strong colour" and turns with it. */
.lp-clip__mark {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 999px;
    background: var(--accent);
    color: var(--lp-on-ink);
}

.lp-clip[data-playing] .lp-clip__mark {
    background: var(--accent-soft);
    color: var(--accent);
}

/* Both marks are in the markup and one of them is always off. Nothing here
   builds an element or swaps an attribute on an <svg>: the script sets
   `data-playing` on the card and this decides the rest.

   `block` rather than the `inline` an <svg> would otherwise have, and it is
   not a choice: the mark is a flex container, so whatever is put here a flex
   item computes to `block` anyway. Written as what it will be. */
.lp-clip__mark .icon + .icon,
.lp-clip[data-playing] .lp-clip__mark .icon:first-child { display: none; }

.lp-clip[data-playing] .lp-clip__mark .icon + .icon { display: block; }

/* The picture. Its own ground is dark and stays dark in both themes, because
   what goes on it is dark: both films are a window on a near-black desktop,
   and a white box behind a film that has not decoded its first frame yet is a
   flash of the page showing through the middle of the hero. */
.lp-clip__screen {
    position: relative;
    overflow: hidden;
    border-radius: calc(var(--lp-round) - 0.55rem);
    background: var(--lp-film);
    line-height: 0;
}

.lp-clip__film {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    /* Safari clips a transformed child to the box and not to the radius, and
       the card behind this is transformed. The radius on the video itself is
       what actually rounds it there. */
    border-radius: inherit;
    object-fit: cover;
}

/* The one behind is dimmed rather than blurred or drained of colour: it is the
   same picture, one step further back. It comes up to full when a pointer is
   over it or the keyboard is on it, and that is the whole of the hint: a hero
   with a "click here" on it is a hero that did not manage to look clickable. */
.lp-clip[data-at="back"] .lp-clip__screen::after {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, var(--lp-film) 44%, transparent);
    content: "";
}

.lp-clip[data-at="back"]:hover .lp-clip__screen::after,
.lp-clip[data-at="back"]:focus-within .lp-clip__screen::after {
    opacity: 0;
}

/* No script, no panel, and then the browser's own controls, which the markup
   ships and the script takes away, are the only way either film can be played.
   They are only reachable while nothing is laid over them.

   `data-js` is set on the root element in views/head.php before this sheet is
   fetched, so this is settled a frame before anything is painted rather than
   after. */
.lp-clip__hit { display: none; }

[data-js] .lp-clip__hit {
    position: absolute;
    inset: 0;
    display: block;
    padding: 0;
    border: 0;
    border-radius: inherit;
    background: none;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}

.lp-clip__hit:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* Full screen, in the corner of the picture. Same bargain as the panel above:
   no script, no button, and then the browser's own controls carry their own
   way out of the page, which is the only one there can be.

   `z-index` because this sits inside the picture and the panel is a later
   sibling of it, so without one the panel takes every press aimed here. Three
   rather than one: the two cards number themselves 1 and 2, and this has to
   clear the dimming laid over the card behind as well as the panel over both.
   The card is a stacking context either way, so it goes no further than that.

   A pale disc rather than a dark one, blurred over whatever is behind it. Both
   films are a terminal on a near-black desktop and a dark chip on that is a
   control nobody can find; this one holds on the black and on the one frame in
   either film that is bright. */
.lp-clip__full { display: none; }

[data-js] .lp-clip__full {
    position: absolute;
    z-index: 3;
    top: 0.55rem;
    right: 0.55rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: color-mix(in srgb, var(--lp-on-film) 15%, transparent);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--lp-on-film) 14%, transparent);
    color: var(--lp-on-film);
    line-height: 0;
    -webkit-appearance: none;
    appearance: none;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    cursor: pointer;
}

.lp-clip__full:hover,
.lp-clip__full:focus-visible {
    background: var(--accent);
    box-shadow: none;
    color: var(--lp-on-ink);
}

/* Inside the outline rather than outside it: the picture clips to its own
   radius, and a ring drawn beyond the edge of a button in the corner of it is
   a ring with two sides missing. */
.lp-clip__full:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -4px;
}

/* Out and back in, on the same two glyphs the play mark uses: both in the
   markup, one of them always off, decided by the attribute the script sets
   when a display is handed over or given back. */
.lp-clip__full .icon + .icon,
.lp-clip[data-fullscreen] .lp-clip__full .icon:first-child { display: none; }

.lp-clip[data-fullscreen] .lp-clip__full .icon + .icon { display: block; }

/* What the picture is once it is the whole screen, and it is mostly things it
   stops being. The 16:9 it carries in the page is the shape of the film, not
   the shape of a display, so it comes off and the frame is fitted whole into
   whatever it has been given, letterboxed on its own ground, which is the
   colour it was always laid on. The rounded corners go with it for the same
   reason: they are the card's, and there is no card here. */
.lp-clip[data-fullscreen] .lp-clip__screen {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0;
}

.lp-clip[data-fullscreen] .lp-clip__film {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    border-radius: 0;
    object-fit: contain;
}

/* And the disc grows, because a two-rem target in the corner of a card is the
   same two-rem target in the corner of a thirty-inch display. */
.lp-clip[data-fullscreen] .lp-clip__full {
    top: 1.1rem;
    right: 1.1rem;
    width: 2.6rem;
    height: 2.6rem;
}

/* Motion, and nothing above this line is any. The tilt is a shape and stays
   whatever anybody has asked for; a card that rises under the pointer and a
   film that fades forward when it is chosen are movement, and movement that
   has to be switched off somewhere else is movement that comes back the first
   time these rules are reordered. Off by absence is off. */
@media (prefers-reduced-motion: no-preference) {
    .lp-clip {
        transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
                    box-shadow 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
    }

    .lp-clip__screen::after { transition: opacity 0.4s ease; }

    .lp-clip__full {
        transition: background-color 0.25s ease, box-shadow 0.25s ease, color 0.25s ease;
    }

    /* The one behind straightens and lifts, which says the pair are panels
       rather than a picture of some, and says it about the one it wants
       pressed. */
    .lp-clip[data-at="back"]:hover,
    .lp-clip[data-at="back"]:focus-within {
        transform: rotate(0.4deg) scale(1) translateY(-4px);
        box-shadow: var(--lp-float-lift);
    }

    /* Arriving in front. The swap itself cannot be tweened (a card changes
       grid cells and there is no half-way between two cells), so what is
       animated is the arrival: the card comes up out of the one behind it
       rather than appearing where it now is. Written on the state and not
       fired by a class, so it plays on the swap and once on load, which is
       the same event as far as the page is concerned. */
    .lp-clip[data-at="front"] {
        animation: lp-clip-forward 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
    }
}

@keyframes lp-clip-forward {
    from { transform: scale(0.972) translateY(8px); opacity: 0.4; }
    to { transform: none; opacity: 1; }
}

/* ---------------------------------------------------------------- the strip

   Where a page like this puts its customer logos, and the reason it is a
   sparkline per site instead is in views/landing.php. What it borrows from a
   logo strip is the treatment: quiet, moving, and faded out at both ends, so
   it reads as evidence noticed on the way past rather than a table to study.

   Two identical runs inside one rail, translated by exactly half the rail's
   width (which is one run), so the loop has no seam in it. */
.lp-strip {
    padding-block: clamp(1rem, 3vw, 2rem) clamp(2.5rem, 6vw, 4.5rem);
}

.lp-strip__label {
    margin: 0 0 1.15rem;
    color: var(--faint);
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    text-align: center;
    text-transform: uppercase;
}

.lp-strip__label b {
    color: var(--muted);
    font-weight: 640;
}

.lp-strip__rail {
    display: flex;
    width: max-content;
    animation: lp-drift 60s linear infinite;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

.lp-strip__run {
    display: flex;
    gap: clamp(1.8rem, 4.5vw, 3.6rem);
    align-items: center;
    padding-right: clamp(1.8rem, 4.5vw, 3.6rem);
}

@keyframes lp-drift {
    to { transform: translateX(-50%); }
}

.lp-tick {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    opacity: 0.66;
}

.lp-tick__name {
    color: var(--text);
    font-size: 0.95rem;
    font-weight: 560;
    letter-spacing: -0.015em;
    white-space: nowrap;
}

/* Sized here rather than by the viewBox, exactly as the phone's sparkline is:
   the line is drawn with no aspect ratio to keep, so the box can be whatever
   the row has room for. */
.lp-tick__line {
    display: block;
    flex: none;
    width: 4.6rem;
    height: 1.5rem;
}

.lp-tick__line .chart--spark {
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
}

.lp-tick__line .chart--spark .chart__line { stroke-width: 2.4; }
.lp-tick__line .chart--spark .chart__area { opacity: 0.14; }

.lp-tick__figure {
    color: var(--muted);
    font-size: 0.83rem;
    font-weight: 560;
}

/* ----------------------------------------------------------------- the shot

   The product shot, which is the product: a window frame with the overview's
   own cards rendered live inside it. Everything in here has to look like the
   dashboard rather than like this page, so the window hands the dashboard's
   own three tokens straight back: every card, chart and chip below this line
   reads them and comes out painted as it is at the front door. */
.lp-shot {
    padding-bottom: clamp(3rem, 7vw, 5.5rem);
}

.lp-window {
    --bg: var(--lp-screen);
    --surface: var(--lp-screen-surface);
    --border: var(--lp-screen-border);

    overflow: hidden;
    border: 1px solid var(--lp-screen-border);
    border-radius: var(--lp-round);
    background: var(--lp-screen);
    box-shadow: var(--lp-float);
}

.lp-window__bar {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.62rem 0.95rem;
    border-bottom: 1px solid var(--lp-screen-border);
    background: var(--lp-screen-surface);
}

.lp-window__dots {
    display: flex;
    flex: none;
    gap: 0.34rem;
}

.lp-window__dots i {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: var(--border-strong);
}

.lp-window__where {
    overflow: hidden;
    padding: 0.12rem 0.7rem;
    border-radius: 999px;
    background: var(--lp-screen);
    color: var(--muted);
    font-size: 0.76rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The clock beside it. Never the thing that shrinks: the address can lose
   its tail to an ellipsis and still say where this is, while a time with
   its end cut off says nothing at all. */
.lp-window__clock {
    display: flex;
    flex: none;
    gap: 0.4rem;
    align-items: center;
    color: var(--muted);
    font-size: 0.72rem;
    white-space: nowrap;
}

/* The gap between the address and the time, drawn rather than typed: a
   separator that is punctuation is a separator a screen reader says. And
   only where there is an address to be separated from: a box that never
   named itself (see the view) leaves the time sitting on its own, and a
   lone bullet in front of it is a bullet separating nothing. */
.lp-window__where + .lp-window__clock::before {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--border-strong);
    content: "";
}

/* The one part of it that moves, so the one part in the page's own ink.
   The figures are tabular off .num, as every other digit in the window is,
   and here it earns it twice over: a seconds column that changes width
   every second is a bar that twitches. */
.lp-window__time {
    color: var(--text);
}

.lp-window__zone {
    font-size: 0.66rem;
    letter-spacing: 0.04em;
}

/* The range chip, pushed to the far end: what the frame is (left) and what it
   is showing (right), which is how a toolbar is read anyway.

   It is the dashboard's own .chip in its own on state, borrowed whole from
   the sheet above, so only the two things a bar this shallow needs saying
   differently are said here: it is smaller than a chip in a rail meant for
   fingers, and it does not grow the bar past the height of the address
   beside it. */
.lp-window__range {
    margin-left: auto;
    padding: 0.18rem 0.55rem;
    font-size: 0.72rem;
}

/* Cut off at the bottom, and faded rather than cropped. A page shown whole and
   small says "this is all there is"; one that runs out of the frame says there
   is more of it, which is true and is the thing a shot on a page like this is
   for. */
.lp-window__body {
    overflow: hidden;
    padding: 0.8rem;
}

/* And only where there is a row under the fold to run out into: the view
   adds this where it drew more cards than the grid is wide. Without it a
   single row of cards has its own feet faded off, which does not read as a
   page continuing; it reads as cards that failed to draw. */
.lp-window__body.is-cropped {
    max-height: min(62vh, 34rem);
    -webkit-mask-image: linear-gradient(#000 72%, transparent);
    mask-image: linear-gradient(#000 72%, transparent);
}

.lp-shot__cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.8rem;
}

.lp-shotcard {
    padding: 0.85rem 0.95rem 0.5rem;
    border: 1px solid var(--lp-screen-border);
    border-radius: var(--lp-round-sm);
    background: var(--lp-screen-surface);
}

.lp-shotcard__head {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.lp-shotcard__name {
    overflow: hidden;
    margin: 0;
    color: var(--text);
    font-size: 0.92rem;
    font-weight: 620;
    letter-spacing: -0.015em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lp-shotcard__head .livecount { margin-left: auto; }

.lp-shotcard__stats {
    display: flex;
    gap: 1.1rem;
    margin: 0.65rem 0 0.1rem;
}

.lp-stat {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.lp-stat b {
    color: var(--text);
    font-size: 1.15rem;
    font-weight: 640;
    letter-spacing: -0.022em;
}

.lp-stat span {
    color: var(--faint);
    font-size: 0.63rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* The split's two, and the same two the dashboard's own cards wear: a figure
   is the colour of its line, and the one that is not a line is the colour of
   something read rather than drawn. See .sitestat--ai in kestrel.css, which
   these are the window's copy of. */
.lp-stat--ai b { color: var(--ai); }
.lp-stat--quiet b { color: var(--faint); }

.lp-shotcard .chart { padding: 0.3rem 0 0; }

/* The key under it, which names the lines a card has no readout to name. The
   chart above already gives up the card padding it would take at the front
   door (this frame supplies its own, and a shot is smaller than the page it
   is of), and the key has to give up the same one or it stands indented from
   the plot it belongs to. */
.lp-shotcard .chartkey { padding: 0.15rem 0 0.1rem; }

/* ---------------------------------------------------------------- the steps

   Three cards, and the first is twice as wide because it is the one with
   something to show. Which is also why the numbers are set in the corner and
   not in the heading: a step is a step because of where it sits in the row,
   and a figure repeated in bold beside every title is a page counting at you. */
.lp-steps {
    padding-bottom: clamp(3rem, 7vw, 5.5rem);
}

.lp-steps__head,
.lp-ai__copy {
    margin-bottom: clamp(1.5rem, 3vw, 2.2rem);
}

.lp-steps__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 0.9rem;
    row-gap: 0.9rem;
}

/* The third column carries the card about the way in that costs the reader
   nothing, so it is given room to say so. Only where that card is the agent
   one: the fallback that stands in its place on an install without accounts
   is an ordinary third of the row, because there is nothing about it to lead
   with. */
.lp-steps__grid--lead {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.4fr);
}

.lp-step {
    display: flex;
    flex-direction: column;
    padding: 1.4rem 1.5rem;
    border: 1px solid var(--border);
    border-radius: var(--lp-round);
    background: var(--surface);
    box-shadow: var(--lp-lift);
}

/* ------------------------------------------- why there are no shared rows

   These three cards were laid out on five rows of a subgrid (number, heading,
   prose, code, caption), declared once on the row and opted into by each card,
   so that every horizontal line across the three was one line however the copy
   in any of them was rewritten.

   That was the right shape while the first two cards each closed with a second
   paragraph, because it sat in the same row as the third card's prompt: the two
   put a sentence where the third put a block, and all three finished level.
   Those paragraphs are gone. What the shared rows do now is hold the prompt a
   paragraph's height below the sentence it belongs to, and leave a hole in the
   two cards beside it, which is the raggedness the rows were for, arrived at
   from the other direction.

   So each card stacks its own children, which is what the no-subgrid fallback
   always did. The first two cards are the same shape as each other and are
   stretched to one height by the grid, as any two cells on a row are; the third
   is as tall as what is in it. Nothing here needs to know how tall its
   neighbour is any more, because nothing in it lines up with one.

   The one thing that goes with this: if the first two cards ever grow a second
   paragraph again, they will not line up with the third's prompt on their own,
   and the block above is what to put back. */

/* The number sits at the top and the title a fixed distance under it, in every
   card, so three titles across a row start on one line.

   It was `margin-bottom: auto`, with the number pinned to the top and
   everything else pushed to the foot of the card, which is the shape the page
   this was modelled on has. That shape only reads as deliberate when the three
   columns hold about the same number of words: anchored to the bottom, a card
   with one sentence starts its title lower than a card with three, and what a
   reader sees is not an arrangement but three headings that missed. Anchored to
   the top they cannot miss, whatever gets written in them later, which matters
   more here than it did there, because the copy in these will keep changing. */
.lp-step__num {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 1.65rem;
    color: var(--faint);
    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
}

/* The one chip on the row, at the far end of the lead card's number line. It
   is there to say why that card is bigger than the two beside it, which a card
   that is merely bigger never manages to say on its own. */
.lp-step__tag {
    padding: 0.16rem 0.62rem;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 0.7rem;
    font-weight: 640;
    letter-spacing: 0.005em;
    white-space: nowrap;
}

.lp-step__title {
    margin: 0 0 0.5rem;
    font-size: 1.22rem;
    font-weight: 620;
    letter-spacing: -0.022em;
}

.lp-step__text {
    margin: 0;
    color: var(--muted);
    font-size: 0.94rem;
    line-height: 1.6;
}

/* No card carries two of these at the moment. Left standing because it is the
   step a second one would want if any of them grows one, and because it is the
   same step the code block takes below. */
.lp-step__text + .lp-step__text { margin-top: 0.75rem; }

.lp-step__text a {
    color: var(--text);
    text-decoration-color: var(--border-strong);
    text-underline-offset: 3px;
}

.lp-step__text a:hover { text-decoration-color: var(--accent); }

/* The one thing on this row somebody takes away, and the only card that has
   one. Directly under the sentence that introduces it: it was `margin-top:
   auto`, which pushed it to the foot of the card, and that was worth doing
   only while the card's foot was a shared row with something in it in the two
   cards beside this one. Now it would push the prompt to the bottom of a card
   stretched to whatever height its neighbours settle at, which is the same
   prompt with a hole above it. */
.lp-step__code {
    display: flex;
    /* The step a second paragraph would take, for the same reason: what
       follows a paragraph is a paragraph's distance from it, whether it is
       prose or a box. */
    padding-top: 0.75rem;
}

.lp-step__code .snippet__box {
    display: flex;
    flex: 1;
    margin: 0;
}

.lp-step__code .snippet {
    display: flex;
    flex: 1;
    align-items: center;
    margin: 0;
    background: var(--bg);
}

/* Wrapped rather than scrolled, which is the one place on this box where that
   is the right answer for code. Everywhere else a snippet sits beside the
   thing it configures and somebody is about to copy it, so a line running off
   the edge is a line they can drag; here it is a picture of a tag, in a column
   a third of a row wide, and a tag whose interesting half is off the right-hand
   edge is a picture of nothing. */
.lp-step__code .snippet code {
    color: var(--muted);
    font-size: 0.69rem;
    line-height: 1.65;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.lp-step__code .snippet__copy { background: var(--bg); }

/* The lead card. Wider is the loud part; this is the quiet part: a wash of
   the accent off the top edge and an accent-tinted rule, which is as far as
   this page goes anywhere else and is enough to make one of three cards the
   one the eye lands on. */
.lp-step--lead {
    border-color: var(--accent-line);
    background:
        linear-gradient(180deg, var(--accent-soft), transparent 58%),
        var(--surface);
}

.lp-step__caption {
    margin: 0.55rem 0 0;
    color: var(--faint);
    font-size: 0.76rem;
    line-height: 1.5;
}

.lp-step__caption code {
    color: var(--muted);
    font-family: var(--mono);
    font-size: 0.95em;
}

/* --------------------------------------------------------------- the badges

   Two plates per badge, one shown. lib/Badge.php draws an `auto` badge light
   and carries a dark media query, which is the right mechanism for an image on
   somebody else's page and the wrong one here: this page's theme is an
   attribute somebody chose. So the stylesheet picks, in both directions, and
   the media query below is the only case where nobody has chosen. */
.lp-badges {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
    gap: clamp(1.5rem, 5vw, 4rem);
    align-items: center;
    padding-block: clamp(2rem, 5vw, 3.5rem) clamp(3rem, 7vw, 5.5rem);
}

.lp-badges__wall {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding: clamp(1.4rem, 3vw, 2.2rem);
    border: 1px solid var(--border);
    border-radius: var(--lp-round);
    background: var(--surface);
    box-shadow: var(--lp-lift);
}

/* The name over its badge, not out at the end of the row with it.

   These three are three different widths (that is the point of showing them),
   and a name pushed to the right-hand edge of the panel therefore sits a
   different distance from each one: touching the counter, a hand's width from
   the pill. At that distance it stops reading as the badge's name and starts
   reading as a word floating in the panel. Above it, it is the same half a
   line from all three, and the group reads as a captioned picture. */
.lp-badges__one {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.45rem;
}

.lp-badges__name {
    color: var(--faint);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* The tag, under a rule, because it is a different kind of thing from the
   three rows above it: those are what a badge looks like, this is how one gets
   onto a page. */
.lp-badges__code {
    margin-top: 0.4rem;
    padding-top: 1.2rem;
    border-top: 1px solid var(--border);
}

.lp-badges__code .snippet {
    margin: 0;
    border-color: var(--border);
}

.lp-badges__code .snippet__box { margin: 0; }

.lp-plate { display: none; }

/* A badge declares its own width in pixels, because that is what it is: a
   picture drawn to fit its own words. On a phone the widest of them is wider
   than the panel it is being shown in, so it is allowed to shrink: the
   viewBox is what keeps it in proportion while it does. Never to grow: at any
   width above its own it is drawn at exactly the size somebody would get. */
.lp-plate svg {
    display: block;
    max-width: 100%;
    height: auto;
}

.lp-plate--light { display: inline-flex; }

@media (prefers-color-scheme: dark) {
    :root.lp:not([data-theme="light"]) .lp-plate--light { display: none; }
    :root.lp:not([data-theme="light"]) .lp-plate--dark { display: inline-flex; }
}

:root.lp[data-theme="dark"] .lp-plate--light { display: none; }
:root.lp[data-theme="dark"] .lp-plate--dark { display: inline-flex; }
:root.lp[data-theme="light"] .lp-plate--light { display: inline-flex; }
:root.lp[data-theme="light"] .lp-plate--dark { display: none; }

/* ------------------------------------------------------------------- the AI */

.lp-ai {
    padding-bottom: clamp(3rem, 7vw, 5.5rem);
}

.lp-ai__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.9rem;
}

.lp-ai__card {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 1.3rem 1.4rem;
    border: 1px solid var(--border);
    border-radius: var(--lp-round);
    background: var(--surface);
    box-shadow: var(--lp-lift);
}

.lp-ai__figure {
    color: var(--text);
    font-size: clamp(1.9rem, 3.6vw, 2.5rem);
    font-weight: 660;
    letter-spacing: -0.035em;
    line-height: 1.05;
}

.lp-ai__label {
    color: var(--text);
    font-size: 0.98rem;
    font-weight: 580;
}

.lp-ai__note {
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.5;
}

/* ---------------------------------------------------------------- the close */

.lp-close {
    padding-block: clamp(3rem, 8vw, 6rem);
    text-align: center;
}

.lp-close__h {
    font-size: clamp(2rem, 5vw, 3.4rem);
}

.lp-close__sub {
    max-width: 40rem;
    margin-inline: auto;
    margin-bottom: 1.8rem;
    /* Centred text with a ragged last word is the one place `pretty` earns
       its keep: it is a longer paragraph than the page's other subheadings
       and it is the last thing anybody reads. */
    text-wrap: pretty;
}

/* --------------------------------------------------------------- the footer */

.lp-foot {
    border-top: 1px solid var(--border);
}

.lp-foot__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.7rem 1.6rem;
    max-width: var(--lp-max);
    margin-inline: auto;
    padding: 1.6rem var(--lp-gutter) 2.4rem;
}

.lp-foot__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--text);
    font-weight: 620;
    letter-spacing: -0.018em;
}

.lp-foot__brand svg { color: var(--accent); }

.lp-foot__links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.1rem;
}

.lp-foot__links a {
    color: var(--muted);
    font-size: 0.88rem;
    text-decoration: none;
}

.lp-foot__links a:hover { color: var(--text); }

.lp-foot__note {
    margin: 0 0 0 auto;
    color: var(--faint);
    font-size: 0.82rem;
}

/* ----------------------------------------------------------- narrower still

   The order the page falls apart in, widest first. The hero's two columns are
   the first thing to go, because the art is the one part of it that is not
   load-bearing; the shot's three cards go to two and then to one; and the
   marquee stops moving last, since a strip that scrolls is still readable on a
   phone in a way that a six-column grid is not. */

@media (max-width: 1080px) {
    /* The lead card gives its extra width back first. Three columns that all
       fit is worth more than one that stands out while the two beside it are
       squeezed into a word a line, and it keeps the shared rows, which is
       what the row is really carried by. */
    .lp-steps__grid--lead { grid-template-columns: repeat(3, minmax(0, 1fr)); }

    .lp-shot__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
    /* Straight from three columns to one, with no two-column stop in between.
       Two columns and three cards leaves the third on a line of its own with
       nothing to line up against, which reads worse than either arrangement
       either side of it. */
    .lp-steps__grid,
    .lp-steps__grid--lead {
        grid-template-columns: minmax(0, 1fr);
    }

    /* One card above another, so the gap that separated a number from its
       heading across a row has nothing left to line up with. */
    .lp-step__num { margin-bottom: 0.9rem; }
}

@media (max-width: 900px) {
    .lp-hero {
        grid-template-columns: minmax(0, 1fr);
        gap: 2.5rem;
        text-align: left;
    }

    .lp-hero__art {
        margin-right: calc(var(--lp-gutter) * -1);
    }

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

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

    .lp-nav__links { display: none; }

    /* With the links gone the bar is the brand, this and the button, and on
       the narrowest phone those three have to share about three hundred
       points. The theme control gives up the padding first, because it is
       three targets rather than one and shrinking it is cheaper than
       shortening the only thing on the bar anybody came to press. 26px is
       still comfortably over the 24 a fingertip needs. */
    .lp-nav__theme .themeset__btn { width: 26px; }
}

@media (max-width: 720px) {

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

    /* A phone's window bar is about three hundred pixels wide and the
       address has first claim on it. The time is the live part and stays;
       the date and the zone are what it is qualified by, and both are in
       the title for anybody who wants them. The chip loses its calendar for
       the same reason: the words beside it already say it is a date. */
    .lp-window__date,
    .lp-window__zone,
    .lp-window__range .icon { display: none; }

    /* One column of cards always continues below the fold, whether there
       are six of them or two, so the crop stops being conditional here and
       the class the view sets is beside the point. */
    .lp-window__body,
    .lp-window__body.is-cropped {
        max-height: 24rem;
        -webkit-mask-image: linear-gradient(#000 76%, transparent);
        mask-image: linear-gradient(#000 76%, transparent);
    }

    /* The film in front takes the whole column, and the column stops running
       off the page. On a phone the picture is about three hundred pixels wide
       and a terminal is being read in it, so every column of it is worth
       having, and a film cut off by the edge of the screen on the one device
       that cannot scroll sideways to see the rest is not a hero that carries
       on past the margin, it is a film with its right-hand third missing.

       What runs off instead is nothing: the card behind keeps its indent and
       ends where the front one does, so on a phone it peeks over the top
       rather than out of the side. Same stack, one axis. */
    .lp-hero__art { margin-right: 0; }

    .lp-clip[data-at="front"] {
        grid-column: 1 / -1;
        margin-top: -30%;
    }

    .lp-foot__note {
        margin-left: 0;
        flex-basis: 100%;
    }
}

/* Somebody who has asked their machine to stop moving things has asked this
   too. The strip becomes what it always was underneath: a row of sites, which
   wraps and centres rather than scrolling, with the second copy (there only
   to make the loop seamless) taken out of the page entirely. */
@media (prefers-reduced-motion: reduce) {
    .lp-strip__rail {
        flex-wrap: wrap;
        justify-content: center;
        width: 100%;
        animation: none;
        -webkit-mask-image: none;
        mask-image: none;
    }

    .lp-strip__run {
        flex-wrap: wrap;
        justify-content: center;
        row-gap: 1rem;
        padding-right: 0;
    }

    .lp-strip__run[aria-hidden] { display: none; }

    .lp-eyebrow i { animation: none; }

    .lp-btn { transition: none; }
}
