/* site.css
   --------
   The shared component layer for seamside.com. The landing page and every
   generated /for/ (use-case) page link this file; learn.css and explore.css
   predate it and keep their own copies of the bar for now.

   What lives here is exactly what two or more pages use: tokens, fonts, the
   subpage back bar, the button pair, the media frame, the use-case cards, the
   frame-chip list, and the site footer. Page-specific styling stays on the
   page (landing inline CSS, use.css-free /for pages lean on this file alone).

   Bump the ?v= in every <link> that references this file when it changes:
   the stable URL caches hard. */

@font-face {
    font-family: "Geist";
    src: url("/fonts/Geist/Geist-Regular.woff2") format("woff2");
    font-weight: 400;
    font-display: swap;
}
@font-face {
    font-family: "Geist";
    src: url("/lib/fonts/Geist/Geist-Medium.woff2") format("woff2");
    font-weight: 500;
    font-display: swap;
}
@font-face {
    font-family: "Geist";
    src: url("/fonts/Geist/Geist-Bold.woff2") format("woff2");
    font-weight: 700;
    font-display: swap;
}
@font-face {
    font-family: "Fedro";
    src: url("/fonts/Fedro/fedro-medium.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Fedro";
    src: url("/fonts/Fedro/fedro-medium-italic.woff2") format("woff2");
    font-weight: 500;
    font-style: italic;
    font-display: swap;
}

:root {
    /* the ground and inks every page shares */
    --bg: #faf9f7;
    --band: #f3f1ee; /* one tone down: section bands, the explore ground */
    --ink: #1e2427;
    --muted: #8a9095;
    --secondary: #5a6166;
    --coral: #fa6c5d;
    --coral-strip: #e65849;
    --docs: #f0efed;
    /* the four brand channels (the orb's own palette) — identity, not status */
    --c1: #235880;
    --c2: #e8b018;
    --c3: #31b479;
    --c4: #fa6c5d;
    --ease: cubic-bezier(0.22, 0.9, 0.24, 1);
    --ease-soft: cubic-bezier(0.2, 0.72, 0.24, 1);
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    /* the shared nav's own height — lives here, not on the landing, because
       the bar is a shared component and .nav-in reads it on every page */
    --nav-h: 64px;
    /* the install card's own two: the BETA chip's plate, and the spring alias
       its press states use. They came across with the card from the landing. */
    --beta: #f6f6f6;
    --os-ease-spring: var(--spring);
    --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}
html,
body {
    min-height: 100%;
    background: var(--bg);
    color: var(--ink);
    font-family:
        "Geist",
        system-ui,
        -apple-system,
        sans-serif;
    -webkit-font-smoothing: antialiased;
}
html {
    scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}
i[class^="ph-"] {
    font-style: normal;
    line-height: 1;
    display: inline-block;
}
::selection {
    background: rgba(250, 108, 93, 0.25);
}

/* ── subpage back bar — the /learn idiom, same values as learn.css ──────── */
.lrn-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    margin: 0 auto;
    width: min(100%, 786px);
    height: 76px;
    z-index: 50;
    cursor: pointer;
    background: var(--bg);
}
.lrn-bar magic-orb {
    position: absolute;
    top: 22px;
    left: calc(50% - 16px);
    width: 32px;
    height: 32px;
    display: block;
    cursor: pointer;
}
.lrn-back {
    position: absolute;
    top: 22px;
    left: 80px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    color: var(--muted);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
}
.lrn-back i {
    font-size: 18px;
    transition: transform 0.25s var(--spring);
}
.lrn-back .t {
    opacity: 0;
    transform: translateX(-4px);
    margin-left: 2px;
    margin-top: -1px;
    white-space: nowrap;
    transition:
        opacity 0.22s ease,
        transform 0.22s var(--ease-soft);
}
@media (hover: hover) {
    .lrn-bar:hover .lrn-back {
        color: var(--ink);
    }
    .lrn-bar:hover .lrn-back i {
        transform: translateX(-2px);
    }
    .lrn-bar:hover .lrn-back .t {
        opacity: 1;
        transform: none;
    }
}
.lrn-back:active i {
    transform: translateX(-4px);
}

/* ── buttons — the pair every page draws from ───────────────────────────── */
/* The coral button is the landing install card's identity at button size,
   lifted from learn.css's .lrn-invite a. */
a.ss-btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 15px;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: #fff;
    background: var(--coral);
    text-decoration: none;
    padding: 12px 20px;
    border-radius: 12px;
    box-shadow: 0 10px 22px -10px
        color-mix(in srgb, var(--coral), transparent 45%);
    transition:
        transform 150ms var(--spring),
        filter 200ms ease,
        box-shadow 200ms ease;
}
a.ss-btn i {
    font-size: 16px;
    transition: transform 0.2s var(--spring);
}
a.ss-btn:hover {
    color: #fff;
    transform: translateY(-1px);
    filter: brightness(1.04);
    box-shadow: 0 14px 26px -10px
        color-mix(in srgb, var(--coral), transparent 38%);
}
/* Only an ARROW advances. The slide means "onward", which is why it reads
   right on ph-arrow-right and wrong on ph-download-simple — a glyph pointing
   down into a tray has no business drifting sideways. The button still lifts,
   brightens and grows its shadow, so the hover is felt either way. */
a.ss-btn:hover i.ph-arrow-right {
    transform: translateX(3px);
}
a.ss-btn:active {
    transform: scale(0.97);
}
/* the quiet companion: a plain confident text link with an advancing arrow */
a.ss-quiet {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 15px;
    font-weight: 500;
    color: var(--ink);
    text-decoration: none;
    transition: color 0.18s ease;
}
a.ss-quiet i {
    font-size: 14px;
    transition: transform 0.2s var(--spring);
}
a.ss-quiet:hover {
    color: var(--coral);
}
a.ss-quiet:hover i {
    transform: translateX(3px);
}
a.ss-quiet:active i {
    transform: translateX(1px);
}

/* ── media frame — the film / screenshot well ───────────────────────────── */
/* 16:9 like the app canvas. The shadow is structural: cream UI on a cream
   ground has no edge without it. When a video is wired up (.ss-media-play
   present), the play affordance sits over the poster; otherwise the frame is
   simply a picture. */
.ss-media {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: 20px;
    overflow: hidden;
    background: var(--docs);
    box-shadow:
        0 1px 2px rgba(30, 36, 39, 0.07),
        0 18px 44px -18px rgba(30, 36, 39, 0.28);
}
.ss-media img,
.ss-media video,
.ss-media iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border: 0;
    display: block;
}
.ss-media-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}
.ss-media-play i {
    font-size: 54px;
    color: #fff;
    text-shadow: 0 2px 14px rgba(0, 0, 0, 0.45);
    transition: transform 0.2s var(--spring);
}
.ss-media-play:hover i {
    transform: scale(1.08);
}
.ss-media-play:active i {
    transform: scale(0.95);
}

/* ── nav — the one bar, worn by every page ──────────────────────────────
   Promoted out of the landing's inline <style> so /learn/ and /explore/ wear
   the same header instead of a lone back caret. The download chip is VISIBLE
   by default here; the landing alone hides it until the masthead scrolls away
   (see index.html), because up there the masthead already carries the CTA. */
.nav {
    position: sticky;
    top: 0;
    z-index: 50;
    background: color-mix(in srgb, var(--bg), transparent 8%);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid rgba(30, 36, 39, 0.07);
    transition:
        background 260ms ease,
        box-shadow 260ms ease;
}
/* Past the masthead the bar firms up: the ask should never be more
   than one click away once someone is reading the middle. The
   download chip is in the markup from the start and only changes
   weight, so nothing shifts layout when the state flips. */
.nav.stuck {
    background: color-mix(in srgb, var(--bg), transparent 2%);
    box-shadow: 0 1px 16px -6px rgba(30, 36, 39, 0.28);
}
.nav-in {
    max-width: 1000px;
    margin: 0 auto;
    height: var(--nav-h);
    padding: 0 30px;
    display: flex;
    align-items: center;
    gap: 26px;
}
.nav-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-size: 17px;
    font-weight: 500;
    letter-spacing: -0.02em;
    color: var(--ink);
    text-decoration: none;
    margin-right: auto;
}
.nav-brand magic-orb {
    width: 24px;
    height: 24px;
    display: block;
    view-transition-name: orb; /* travels to the subpage bars */
}
.nav-links {
    display: flex;
    align-items: center;
    gap: 22px;
}
.nav-links a {
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    color: var(--secondary);
    text-decoration: none;
    transition: color 0.18s ease;
}
.nav-links a:hover {
    color: var(--ink);
}
/* the nav's download: the coral identity at chip size */
.nav-dl {
    font-size: 14px;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: #fff;
    background: var(--coral);
    text-decoration: none;
    padding: 8px 14px;
    border-radius: 9px;
    /* A coral chip carrying a coral glow, so it reads as lit rather than
       painted on. At rest the glow is tight; on hover it blooms and the chip
       rises a pixel, and the brightness step is 1.08 — the design language's
       floor, because 1.05 is the "subtle hover" that reads as nothing.
       Brightness is safe here because this presses by scale(), not by the
       inset recipe (which brightness would wash out).
       ONE complete transition list — a second `transition:` at this
       specificity would replace it wholesale. */
    box-shadow: 0 2px 8px -4px color-mix(in srgb, var(--coral), transparent 40%);
    transition:
        transform 220ms var(--spring),
        box-shadow 280ms var(--ease-out),
        filter 200ms ease;
}
.nav-dl:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
    box-shadow: 0 9px 22px -8px color-mix(in srgb, var(--coral), transparent 25%);
}
/* the press is quick and the glow collapses with it, so the chip settles onto
   the bar rather than hovering above its own shadow */
.nav-dl:active {
    transform: scale(0.96);
    box-shadow: 0 1px 4px -2px color-mix(in srgb, var(--coral), transparent 45%);
    transition:
        transform 90ms var(--spring),
        box-shadow 90ms ease;
}
@media (max-width: 599px) {
    .nav-in {
        padding: 0 20px;
        gap: 18px;
    }
    .nav-links {
        gap: 15px;
    }
    .nav-dl {
        display: none; /* the masthead CTA is right there */
    }
}
/* the narrowest phones: four links don't fit beside the brand, and
   a nav that overflows sideways is worse than a shorter nav. Docs
   keeps its place in the footer and inside /learn. */
@media (max-width: 419px) {
    .nav-links {
        gap: 13px;
    }
    .nav-links a[href="/docs/"] {
        display: none;
    }
}

/* ── use-case cards — the ONE use-case component, on the landing AND on /for/ ──
   Three text runs: title, tagline, affordance. The frames that compose the space
   live on /for/<slug>/ — see design/website-redesign/density-pass.md. */
.uc-grid {
    /* auto-fit means no breakpoint list: 4-up on the landing's 1200 measure,
       2x2 on /for/'s narrower one, 1-up on phones, and new use cases going live
       are absorbed with no CSS change. */
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 20px;
}
/* the plate: the channel tint IS the card's boundary, so it takes no border
   (a border on a tinted card is double-encoding) */
.uc-card {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
    min-width: 0;
    padding: 14px 14px 18px;
    border-radius: 16px;
    background: color-mix(in srgb, var(--ch, var(--c1)) 10%, var(--bg));
    /* The same lift the frame chips have. Without it the tinted plate sat flat
       on the ground while the chips beside it floated, and the card — the thing
       that is actually a link — read as the LESS clickable of the two.
       ONE transition declaration: a second would replace this list wholesale. */
    box-shadow:
        0 1px 2px rgba(30, 36, 39, 0.06),
        0 6px 14px -9px rgba(30, 36, 39, 0.18);
    transition:
        transform 220ms var(--ease-out),
        box-shadow 0.32s ease;
}
/* shadow grows with the press-in, so the card stays a solid object */
.uc-card:hover {
    box-shadow:
        0 1px 2px rgba(30, 36, 39, 0.09),
        0 10px 22px -10px rgba(30, 36, 39, 0.26);
}
.uc-frame {
    display: block;
    border-radius: 10px;
    overflow: hidden;
    background: var(--docs);
    box-shadow:
        0 1px 2px rgba(30, 36, 39, 0.07),
        0 8px 20px -10px rgba(30, 36, 39, 0.22);
    transition: box-shadow 0.32s ease;
}
.uc-card:hover .uc-frame {
    box-shadow:
        0 1px 2px rgba(30, 36, 39, 0.09),
        0 12px 26px -10px rgba(30, 36, 39, 0.28);
}
.uc-frame img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    object-position: top center;
    display: block;
    transition:
        transform 380ms var(--ease-out),
        filter 220ms ease;
}
@media (hover: hover) {
    .uc-card:hover {
        transform: scale(0.978);
    }
    .uc-card:hover .uc-frame img {
        transform: scale(1.04);
        filter: brightness(1.05);
    }
}
.uc-card:active {
    transform: scale(0.95);
    transition: transform 60ms ease;
}
.uc-card h3 {
    font-family: "Fedro", Georgia, serif;
    font-weight: 500;
    font-size: 30px;
    line-height: 1.1;
    letter-spacing: -0.01em;
    margin-top: 18px;
    text-wrap: balance;
}
.uc-tag {
    font-size: 16px;
    line-height: 1.5;
    color: var(--secondary);
    margin-top: 8px;
    text-wrap: pretty;
}
/* a SPAN, not a button: the whole card is the anchor (see gen-use.mjs). It is
   pushed to the card's floor so a row of cards lines its affordances up. */
.uc-go {
    align-self: flex-start;
    margin-top: auto;
    padding-top: 18px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 15px;
    font-weight: 500;
    color: var(--ink);
    transition: gap 180ms var(--ease-out);
}
.uc-card:hover .uc-go {
    gap: 11px;
}

/* ── use-case page body ─────────────────────────────────────────────────── */
.uc-wrap {
    width: 100%;
    max-width: 726px;
    margin: 0 auto;
    /* 40px of bottom padding left the download row almost touching the footer
       rule; the invite is the page's last word and wants room after it */
    padding: 108px 30px 96px;
}
.uc-head {
    margin-bottom: 26px;
}
.uc-eyebrow {
    font-size: 15px;
    font-weight: 500;
    color: var(--ch, var(--c1));
    margin-bottom: 6px;
}
.uc-head h1 {
    font-family: "Fedro", Georgia, serif;
    font-weight: 500;
    font-size: clamp(32px, 4.4vw, 48px);
    line-height: 1.12;
    letter-spacing: -0.01em;
    text-wrap: balance;
}
.uc-head h1 em {
    font-style: italic;
}
.uc-lede {
    font-size: 18px;
    line-height: 1.7;
    color: rgba(30, 36, 39, 0.88);
    margin-top: 14px;
    max-width: 620px;
    text-wrap: pretty;
}
.uc-media {
    margin: 30px 0 10px;
}
.uc-caption {
    font-size: 13px;
    color: var(--muted);
    padding-top: 11px;
    line-height: 1.5;
}
/* section leads — serif chapter openings, the /learn idiom */
.uc-wrap h2 {
    font-family: "Fedro", Georgia, serif;
    font-weight: 500;
    font-size: 24px;
    line-height: 1.25;
    margin: 44px 0 12px;
    text-wrap: balance;
}
.uc-wrap > p,
.uc-story p {
    font-size: 16px;
    line-height: 1.75;
    color: rgba(30, 36, 39, 0.88);
    margin-bottom: 18px;
    text-wrap: pretty;
}

/* ── frame chips — "a space is a mix of frames", made visible ───────────── */
/* The /learn features-grid recipe (icon tile + label + line), re-cut as the
   list of frames a use case composes. The page's one channel tints every
   tile: color is identity, and the identity here is the space's. */
.ss-frames {
    background: #f4f2ef;
    border-radius: 26px;
    padding: 28px;
    margin: 16px 0 10px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px 26px;
}
.ss-frame-chip {
    display: flex;
    gap: 13px;
    align-items: flex-start;
}
.ss-frame-chip .ico {
    width: 34px;
    height: 34px;
    border-radius: 9px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    background: color-mix(in srgb, var(--ch, var(--c1)) 15%, var(--bg));
    color: var(--ch, var(--c1));
}
.ss-frame-chip .lbl {
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.01em;
    margin-bottom: 3px;
}
.ss-frame-chip .line {
    font-size: 14.5px;
    line-height: 1.5;
    color: var(--secondary);
}

/* related links + the closing invitation (the /learn lockup) */
.uc-links {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 4px;
}
.uc-invite {
    margin-top: 52px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
}
.uc-invite p {
    margin: 0;
    font-size: 16px;
    line-height: 1.6;
    color: var(--secondary);
    max-width: 46ch;
}
/* was falling through to the browser default (underline blue) — the one link
   on the page that did not look like the rest of the site */
.uc-invite p a {
    color: var(--ink);
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
    transition: color 0.18s ease;
}
.uc-invite p a:hover {
    color: var(--coral);
}
/* the button never wraps its own label */
.uc-invite .ss-btn {
    flex: none;
    white-space: nowrap;
}

/* ── the install card — shared by the landing's #get and /download/ ──────────
   Promoted out of the landing's inline <style> when the card gained a second
   home. Markup comes from gen-install.mjs, behaviour from site/install.js;
   this is the third of those three pieces. Nothing here may assume the
   landing's surroundings. */
/* install card: coral body + darker platform strip, unified radius 20 */
.install {
    position: relative;
    z-index: 1;
    background: var(--coral);
    border-radius: 20px;
    overflow: hidden;
    scroll-margin-top: calc(var(--nav-h) + 16px);
    /* z-index pins the card's glow above its neighbors always — without it,
       the hover's transform+filter promote the card mid-interaction and the
       shadow visibly jumps from behind to in front */
    box-shadow: 0 12px 28px -10px
        color-mix(in srgb, var(--coral), transparent 55%);
    cursor: pointer;
    transition:
        transform 150ms var(--os-ease-spring),
        filter 200ms ease,
        box-shadow 200ms ease;
}
.install .body {
    padding: 24px 30px 16px;
}
.install .top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}
.install .rtg {
    font-size: 16px;
    color: #f6f6f6;
}
.beta {
    font-size: 12px;
    letter-spacing: 0.06em;
    background: var(--beta);
    color: var(--coral);
    padding: 4px 9px;
    border-radius: 5px;
    font-weight: 400;
}
.install .glyph {
    font-size: 34px;
    color: #f6f6f6;
    margin: 28px 0 8px;
    display: block;
    line-height: 1;
}
.install .cta {
    font-size: 20px;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: #fff;
}
.install .strip {
    background: var(--coral-strip);
}
.install .srow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 30px;
    height: 50px;
    cursor: pointer;
}
.install .strip .alts {
    display: flex;
    align-items: center;
    gap: 16px;
    color: rgba(255, 255, 255, 0.72);
    font-size: 20px;
}
.install .strip .go {
    display: flex;
    align-items: center;
    gap: 10px;
    color: rgba(255, 255, 255, 0.82);
    font-size: 20px;
}
.install .strip .go .golbl {
    font-size: 15px;
    color: rgba(255, 255, 255, 0.72);
    transition: color 0.18s ease;
}
/* narrow phones: the platform icons carry the meaning, the label
   just crowds the strip */
@media (max-width: 389px) {
    .install .strip .go .golbl {
        display: none;
    }
}

/* expanded state — the strip grows into the full platform panel */
.install .deep {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows 0.42s var(--ease-soft);
}
.install .deepin {
    overflow: hidden;
    min-height: 0;
    transition: opacity 0.3s ease 0.08s;
}
.install .body {
    transition: padding 0.42s var(--ease-soft);
}
.install.open .deep {
    grid-template-rows: 0fr;
}
.install.open .deepin {
    opacity: 0;
    transition: opacity 0.2s ease;
}
.install.open .body {
    padding-bottom: 29px;
}
.install.open {
    cursor: default;
}
.install .panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.5s var(--ease-soft);
}
.install .panelin {
    overflow: hidden;
    min-height: 0;
}
.install.open .panel {
    grid-template-rows: 1fr;
}

/* post-download state — the CTA collapses and the confirmation takes
   its place in the same well, so the card never changes shape abruptly */
.rtgd {
    display: none;
}
.install.sent .rtg {
    display: none;
}
.install.sent .rtgd {
    display: inline;
    font-size: 16px;
    color: #f6f6f6;
}
.install .done {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.5s var(--ease-soft);
}
.install .donein {
    overflow: hidden;
    min-height: 0;
    opacity: 0;
    transition: opacity 0.2s ease;
}
.install.sent .done {
    grid-template-rows: 1fr;
}
.install.sent .donein {
    opacity: 1;
    transition: opacity 0.32s ease 0.14s;
}
.install.sent .deep {
    grid-template-rows: 0fr;
}
.install.sent .deepin {
    opacity: 0;
    transition: opacity 0.2s ease;
}
.install.sent {
    cursor: default;
}
/* the filename is genuine data, so it reads in mono */
.install .dfile {
    margin-top: 8px;
    font-family: "Geist Mono", ui-monospace, monospace;
    font-size: 13px;
    letter-spacing: 0.02em;
    color: rgba(255, 255, 255, 0.72);
    overflow-wrap: anywhere;
}
/* retry / reset live in the strip, where the card already puts its
   secondary actions */
.install .drow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 18px;
    height: 0;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
    transition:
        height 0.34s var(--ease-soft),
        opacity 0.22s ease;
}
.install.sent .drow {
    height: 50px;
    opacity: 1;
    pointer-events: auto;
}
.install .drow .dact {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: 0;
    border-radius: 8px;
    padding: 8px 12px;
    font-family: inherit;
    font-size: 15px;
    color: rgba(255, 255, 255, 0.72);
    cursor: pointer;
    transition:
        background 140ms ease,
        color 0.18s ease;
}
.install .drow .dact i {
    font-size: 18px;
}
.install .drow .dact:active {
    background: rgba(0, 0, 0, 0.13);
}
/* one turn of the arrow acknowledges a retry that re-downloads the
   same file (where the browser itself shows nothing new) */
.install .drow .dact .rt.spin {
    animation: rt-spin 0.6s var(--ease-soft);
}
@keyframes rt-spin {
    to {
        transform: rotate(360deg);
    }
}
.plist {
    padding: 26px 30px 30px;
    display: block;
}
.plist .back {
    display: block;
    background: none;
    border: 0;
    padding: 4px 0;
    margin: 0 0 2px;
    color: #f6f6f6;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
.plist .back i {
    display: inline-block;
    transition:
        transform 0.2s var(--os-ease-spring),
        color 0.15s ease;
}
.plist .back:hover i {
    color: #fff;
    transform: translateX(-3px);
}
.plist .sec {
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.05em;
    color: #ff9485;
    margin: 32px 0 4px;
}
.plist .row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 8px 0;
    cursor: pointer;
    text-decoration: none;
    font-size: 20px;
    font-weight: 500;
    line-height: 1.3;
}
.plist .row i {
    font-size: 24px;
    color: rgba(246, 246, 246, 0.85);
    transition: color 0.15s ease;
}
.plist .row .nm {
    color: rgba(255, 255, 255, 0.92);
    transition: color 0.15s ease;
}
.plist .row em {
    font-style: normal;
    font-weight: 400;
}
.plist .row:hover i,
.plist .row:hover .nm {
    color: #fff;
}
.plist .row:active i,
.plist .row:active .nm {
    color: rgba(255, 255, 255, 0.7);
    transition: none;
}
/* disabled (coming-soon) rows — muted, inert; the chip carries the message */
.plist .row.off {
    cursor: default;
    pointer-events: none;
}
.plist .row.off i,
.plist .row.off .nm {
    color: rgba(255, 255, 255, 0.45);
}
.plist .soon {
    font-size: 12px;
    letter-spacing: 0.06em;
    background: rgba(0, 0, 0, 0.18);
    color: rgba(255, 255, 255, 0.6);
    padding: 3px 8px;
    border-radius: 5px;
    font-weight: 400;
    margin-left: 2px;
}
/* server row — terminal glyph + a copyable command well (mono = genuine data) */
.plist .srv {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 8px 0;
}
.plist .srv > i {
    font-size: 24px;
    color: rgba(246, 246, 246, 0.85);
}
.plist .cmd {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    background: rgba(0, 0, 0, 0.16);
    border-radius: 8px;
    padding: 11px 14px;
    cursor: pointer;
    transition: background 140ms ease;
}
.plist .cmd code {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: "Geist Mono", ui-monospace, monospace;
    font-size: 13px;
    letter-spacing: 0.02em;
    color: rgba(255, 255, 255, 0.85);
}
.plist .cmd .cp {
    font-size: 16px;
    color: rgba(246, 246, 246, 0.7);
    transition: color 0.15s ease;
}
.plist .cmd:hover {
    background: rgba(0, 0, 0, 0.22);
} /* darken-to-interact is this card's idiom (see .srow) */
.plist .cmd:hover .cp {
    color: #fff;
}
.plist .cmd:active {
    background: rgba(0, 0, 0, 0.26);
}
.plist .cmd.copied code {
    color: #fff;
}
.plist .cmd.copied .cp {
    color: #fff;
}
/* wave the list in once the panel opens; collapse fades flat */
.plist > * {
    opacity: 0;
    transform: translateY(6px);
    transition:
        opacity 0.3s var(--ease-soft),
        transform 0.3s var(--ease-soft);
}
.install.open .plist > * {
    opacity: 1;
    transform: none;
    transition-delay: calc(0.1s + var(--pi, 0) * 26ms);
}

/* card interactions (PRECISION §4: cards lift, shadow grows) */
.install .srow {
    transition:
        background 140ms ease,
        height 0.34s var(--ease-soft),
        opacity 0.22s ease;
}
.install.open .srow,
.install.sent .srow {
    height: 0;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
}
.install .strip .alts,
.install .strip .go i {
    transition:
        transform 0.2s var(--os-ease-spring),
        color 0.18s ease;
}
@media (hover: hover) {
    /* coral card — picks up: lifts, brightens a touch, shadow grows.
       (collapsed only — the expanded panel is a surface, not a button) */
    .install:not(.open):not(.sent):hover {
        transform: translateY(-3px);
        filter: brightness(1.035);
        box-shadow: 0 16px 36px -14px
            color-mix(in srgb, var(--coral), transparent 44%);
    }
    /* secondary strip (inside the card) — darkens, icons brighten, arrow advances */
    .install .srow:hover {
        background: rgba(0, 0, 0, 0.07);
    }
    .install .srow:hover .alts {
        color: #fff;
    }
    .install .srow:hover .go .golbl {
        color: #fff;
    }
    .install .srow:hover .go i {
        transform: translateX(4px);
    }
    /* post-download: the two actions brighten individually */
    .install .drow .dact:hover {
        background: rgba(0, 0, 0, 0.07);
        color: #fff;
    }
}
/* press — the card presses IN from the lift (scale + shadow recedes) */
.install:not(.open):not(.sent):active {
    transform: scale(0.97);
    filter: brightness(0.99);
    box-shadow: 0 8px 20px -10px
        color-mix(in srgb, var(--coral), transparent 50%);
    transition:
        transform 100ms ease,
        box-shadow 100ms ease,
        filter 100ms ease;
}
.install .srow:active {
    background: rgba(0, 0, 0, 0.13);
}
.install .srow:active .go i {
    transform: translateX(2px);
}
@media (min-width: 760px) {
    .install .body {
        padding: 32px 44px 22px;
    }
    .install .glyph {
        margin-top: 32px;
        font-size: 40px;
    }
    .install .cta {
        font-size: 24px;
    }
    .install .srow {
        height: 60px;
        padding: 0 44px;
    }
    .install .drow {
        padding: 0 32px;
    }
    .install.sent .drow {
        height: 60px;
    }
    .plist {
        padding: 32px 44px 38px;
    }
    .install.open .body {
        padding-bottom: 34px;
    }
}

/* ── site footer — the sitemap, spoken plainly ──────────────────────────── */
.sf {
    /* No margin-top: it dates from when every page was one continuous cream
       ground and the footer needed pushing off the content. Now sections carry
       their own grounds, so a margin here renders as a strip of body background
       between the last band and the footer. The border-top plus .sf-in's own
       44px of padding are the separation. */
    border-top: 1px solid rgba(30, 36, 39, 0.08);
    background: var(--bg);
}
.sf-in {
    max-width: 786px;
    margin: 0 auto;
    padding: 44px 30px 28px;
}
.sf-cols {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
    gap: 28px;
}
.sf-brand .mark {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 17px;
    font-weight: 500;
    letter-spacing: -0.02em;
    color: var(--ink);
    text-decoration: none;
}
.sf-brand p {
    font-family: "Fedro", Georgia, serif;
    font-size: 14px;
    line-height: 1.5;
    color: rgba(30, 36, 39, 0.55);
    margin-top: 10px;
    max-width: 200px;
}
.sf-brand p em {
    font-style: italic;
}
.sf-col .h {
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.01em;
    margin-bottom: 12px;
}
.sf-col a {
    display: block;
    font-size: 14px;
    color: var(--secondary);
    text-decoration: none;
    padding: 4px 0;
    transition: color 0.18s ease;
}
.sf-col a:hover {
    color: var(--ink);
}
.sf-legal {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    flex-wrap: wrap;
    font-size: 11px;
    color: var(--muted);
    margin-top: 36px;
}
.sf-legal .sep {
    color: rgba(138, 144, 149, 0.55);
}
.sf-legal a {
    color: var(--muted);
    text-decoration: none;
    transition: color 0.18s ease;
}
.sf-legal a:hover {
    color: var(--ink);
}

/* ── mobile ─────────────────────────────────────────────────────────────── */
@media (max-width: 759px) {
    .lrn-bar {
        height: 62px;
    }
    .lrn-bar magic-orb {
        top: 15px;
    }
    .lrn-back {
        top: 15px;
        left: 20px;
    }
    .uc-wrap {
        padding: 88px 24px 32px;
    }
    .uc-head h1 {
        font-size: 30px;
    }
    .ss-frames {
        grid-template-columns: 1fr;
        padding: 24px 22px;
        gap: 20px;
    }
    .uc-invite {
        flex-direction: column;
        align-items: flex-start;
        gap: 16px;
    }
    .sf-cols {
        grid-template-columns: 1fr 1fr;
        gap: 24px;
    }
    .sf-brand {
        grid-column: 1 / -1;
    }
}
