@layer site, viz-kit;

@import "viz-kit-b32NQdu.css";

/* Fontsource Montserrat 5.3.0, subset locally with alto/font. */
@font-face {
    font-family: "Montserrat Variable";
    font-style: normal;
    font-display: swap;
    font-weight: 100 900;
    src: url("../fonts/montserrat-latin-code-wght-normal-nRiflWp.woff2") format("woff2");
    unicode-range: U+0020-007E, U+00A0, U+00A9, U+00AB, U+00B6, U+00BB, U+00C9, U+00D7, U+00E9-00EA, U+2013-2014, U+2019, U+201C-201D, U+2026, U+2039-203A, U+2190-2192, U+21A9, U+2500, U+2502, U+2514, U+251C;
}

@layer site {
:root {
    /* Colors -- near-monochrome, one quiet accent */
    --bg: #0b0b0e;
    --text: #e4e4e7;
    /* floor: nothing dimmer */
    --text-muted: rgb(255 255 255 / 0.65);
    --border: #221f22;
    --accent: #a8a8b3;

    /* brand accent */
    --brand: #00b7ff;
    --brand-soft: #63d1ff;
    --paper: #f7f5f0;
    /* icon back layer, never text */
    --faint: #5b6478;

    --font-sans: "Montserrat Variable", "Avenir Next", "Segoe UI", system-ui, sans-serif;
    --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Menlo", "Consolas", monospace;

    /* --settled: the frame a mark holds at rest */
    --dur: 6s;
    --ease: cubic-bezier(0.65, 0, 0.35, 1);
    --settled: -4.8s;

    --brandmark-h: 1.3rem;
    --content-w: 46rem;
    --rail-w: 14rem;
    --footer-clearance: 6rem;
    --layout-gap: var(--space-8);
    --accent-line-height: 3px;
    --accent-line-radius: 1.5px;
    --accent-line-title-width: 4rem;
    --accent-line-heading-width: 2rem;

    /* reserved by the fixed topbar: wordmark plus its equal inset */
    --topbar-h: calc(var(--brandmark-h) * 121 / 90 + 2 * var(--space-5));

    /* Type scale, ratio 1.25 (major third). --text-sm is the floor. */
    --text-sm: 0.9rem;
    --text-base: 1rem;
    --text-lg: 1.25rem;
    --text-xl: 1.5625rem;
    --text-2xl: 1.953rem;
    --text-3xl: 2.441rem;
    --text-4xl: 3.052rem;

    /* Spacing scale, same ratio, base 0.5rem */
    --space-1: 0.5rem;
    --space-2: 0.625rem;
    --space-3: 0.781rem;
    --space-4: 0.977rem;
    --space-5: 1.221rem;
    --space-6: 1.526rem;
    --space-7: 1.907rem;
    --space-8: 2.384rem;
}

* {
    box-sizing: border-box;
    scrollbar-color: var(--brand) transparent;
    scrollbar-width: thin;
}

*::-webkit-scrollbar {
    width: 0.55rem;
    height: 0.55rem;
}

*::-webkit-scrollbar-track,
*::-webkit-scrollbar-corner {
    background: transparent;
}

*::-webkit-scrollbar-thumb {
    background: var(--brand);
    border-radius: 999px;
}

html {
    scroll-behavior: smooth;
    scroll-padding-block-start: 4rem;
}

[id] {
    scroll-margin-block-start: 4rem;
}

body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    line-height: 1.7;
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    padding-block-start: var(--topbar-h);
}

body:has(.package-brand) {
    --topbar-h: calc(2 * var(--space-5) + var(--brandmark-h) + 0.35rem + var(--text-xl) * 1.15);
}

body:has(.scope-long) {
    --topbar-h: calc(2 * var(--space-5) + var(--brandmark-h) + 0.35rem + var(--text-xl) * 2.3);
}

a {
    color: var(--text);
    text-decoration-color: var(--border);
    text-underline-offset: 0.2em;
}

a:hover {
    color: var(--accent);
}

:is(h1, h2, h3, h4, h5, h6) {
    font-weight: 400;
    text-wrap: balance;
}

strong, b {
    font-weight: 500;
}

h1, h2, h3, h4, h5, h6 {
    line-height: 1.25;
    margin-block-start: var(--space-8);
}

h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
h4 { font-size: var(--text-xl); }
h5 { font-size: var(--text-lg); }
h6 { font-size: var(--text-base); }

:is(h1, h2, h3, h4, h5, h6, section, article, p, ul, ol, pre, blockquote, table) {
    margin-block-end: 2.5rem;
}

header, footer {
    padding: var(--space-5);
}

.topbar {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: 30;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-5);
}

.altomark { color: var(--paper); display: block; }

.brandlockup { block-size: calc(var(--brandmark-h) * 121 / 90); inline-size: calc(var(--brandmark-h) * 346 / 90); }
.brandmark { block-size: var(--brandmark-h); inline-size: calc(var(--brandmark-h) * 346 / 90); }

.brand { display: flex; align-items: center; gap: 0.65rem; min-inline-size: 0; }
.brand .brandlink { display: inline-flex; text-decoration: none; }

.package-brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.35rem;
}

.package-brand-root {
    display: flex;
    align-items: center;
    gap: 0.65rem;
}

.brand-separator { color: var(--brand); font-size: var(--text-lg); line-height: 1; }
.brand .scope {
    display: flex;
    gap: 0.35em;
    color: var(--paper);
    font-size: var(--text-xl);
    font-weight: 500;
    letter-spacing: 0.12em;
    line-height: 1.15;
    text-decoration: none;
    text-transform: uppercase;
}
.brand .scope-long {
    flex-wrap: wrap;
    max-inline-size: 11ch;
    row-gap: 0;
}
.brand .scope:hover { color: var(--brand); }

.topbar .gh {
    display: inline-flex;
    color: var(--text-muted);
    transition: color 0.2s ease;
}

/* matched to the ALTO cap height, sitting on the same cap line */
.topbar .gh svg {
    inline-size: calc(var(--brandmark-h) * 84 / 90);
    block-size: calc(var(--brandmark-h) * 84 / 90);
    translate: 0 calc(var(--brandmark-h) * 3 / 90);
}
.topbar .gh:hover, .topbar .gh:focus-visible { color: var(--text); }

.layout {
    flex: 1;
    width: 100%;
    max-width: 72rem;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr;
    align-items: start;
}

.layout:has(.sidebar:empty) {
    grid-template-columns: 1fr;
    max-width: 96rem;
}

/* edge to edge, so the summary sits on the wordmark's margin */
.layout:has(.sidebar:not(:empty)) {
    grid-template-columns: var(--rail-w) minmax(0, 1fr) minmax(0, var(--content-w)) minmax(0, 1fr) var(--rail-w);
    max-width: none;
}

.layout:has(.sidebar:not(:empty)) .sidebar { grid-column: 1; }
.layout:has(.sidebar:not(:empty)) main { grid-column: 3; }

.sidebar:empty {
    display: none;
}

.sidebar {
    padding: var(--space-6) var(--space-5) 0;
    position: fixed;
    inset-block-start: var(--topbar-h);
    inset-inline-start: 0;
    inline-size: var(--rail-w);
    block-size: calc(100dvh - var(--topbar-h));
    overflow: hidden;
}

.sidebar:not(:empty) {
    display: flex;
    flex-direction: column;
}

/* Keep the full rail until the footer enters the viewport, then surrender only
   the footer's height. Browsers without view timelines reserve that clearance
   from the start while keeping the rail fixed. */
@media (min-width: 60.01rem) and (min-height: 42rem) and (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
        body { timeline-scope: --site-footer; }

        footer {
            view-timeline: --site-footer block;
        }

        .sidebar {
            contain: layout style;
            animation: sidebar-footer-clearance linear both;
            animation-timeline: --site-footer;
            animation-range: entry 0% entry 100%;
        }
    }
}

@media (min-width: 60.01rem) and (min-height: 42rem) and (prefers-reduced-motion: reduce) {
    .sidebar {
        block-size: calc(100dvh - var(--topbar-h) - var(--footer-clearance));
    }
}

@media (min-width: 60.01rem) and (min-height: 42rem) {
    @supports not (animation-timeline: view()) {
        .sidebar {
            block-size: calc(100dvh - var(--topbar-h) - var(--footer-clearance));
        }
    }
}

@keyframes sidebar-footer-clearance {
    from { block-size: calc(100dvh - var(--topbar-h)); }
    to { block-size: calc(100dvh - var(--topbar-h) - var(--footer-clearance)); }
}

.sidebar-navigation {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    flex: 1;
    min-block-size: 0;
    overflow-y: auto;
    scrollbar-color: rgb(0 183 255 / 0.02) transparent;
    scrollbar-width: thin;
}

.sidebar-navigation::-webkit-scrollbar {
    width: 0.3rem;
}

.sidebar-navigation::-webkit-scrollbar-thumb {
    background: rgb(0 183 255 / 0.02);
}

.sidebar:hover .sidebar-navigation {
    scrollbar-color: rgb(0 183 255 / 0.45) transparent;
}

.sidebar:hover .sidebar-navigation::-webkit-scrollbar-thumb {
    background: rgb(0 183 255 / 0.45);
}

.nav-documentation {
    flex: 0 0 auto;
    padding-block-start: 0;
}

.nav-toggle {
    display: none;
}

.nav-close,
.nav-backdrop {
    display: none;
}

/* When the mirrored right rail no longer fits, keep the real rail at the
   viewport edge and give all remaining room to the right side. */
@media (max-width: 74rem) {
    .layout:has(.sidebar:not(:empty)) {
        grid-template-columns: var(--rail-w) minmax(var(--layout-gap), 1fr) minmax(0, var(--content-w)) minmax(var(--layout-gap), 1fr);
    }

    .layout:has(.sidebar:not(:empty)) main { grid-column: 3; }
}

/* Once rail + content no longer fit, centre the content and dock the
   navigation behind its existing toggle. */
@media (max-width: 60rem) {
    .layout:has(.sidebar:not(:empty)) {
        grid-template-columns: minmax(var(--layout-gap), 1fr) minmax(0, var(--content-w)) minmax(var(--layout-gap), 1fr);
    }

    .layout:has(.sidebar:not(:empty)) .nav-toggle {
        display: inline-block;
        grid-column: 2;
        grid-row: 1;
        cursor: pointer;
        border: 0;
        background: transparent;
        padding-block: var(--space-3);
        color: var(--text-muted);
        font: inherit;
        text-align: start;
        text-transform: uppercase;
        letter-spacing: 0.1em;
        font-size: var(--text-sm);
    }

    .layout:has(.sidebar:not(:empty)) .nav-toggle:focus-visible,
    .nav-close:focus-visible {
        outline: 2px solid var(--brand);
        outline-offset: 0.25rem;
    }

    .layout:has(.sidebar:not(:empty)) main {
        grid-column: 2;
        grid-row: 2;
    }

    .sidebar:not(:empty) {
        position: fixed;
        inset-block: var(--topbar-h) 0;
        left: 0;
        width: 14rem;
        background: var(--bg);
        border-right: 1px solid var(--border);
        transform: translateX(-100%);
        visibility: hidden;
        pointer-events: none;
        transition: transform 0.2s ease, visibility 0s linear 0.2s;
        z-index: 20;
        overflow: hidden;
    }

    .sidebar.is-open {
        transform: translateX(0);
        visibility: visible;
        pointer-events: auto;
        transition-delay: 0s;
    }

    .nav-close {
        display: inline-block;
        align-self: flex-start;
        flex: 0 0 auto;
        margin-block-end: var(--space-4);
        border: 0;
        background: transparent;
        padding: 0;
        color: var(--text-muted);
        font: inherit;
        font-size: var(--text-sm);
        letter-spacing: 0.1em;
        text-transform: uppercase;
        cursor: pointer;
    }

    .nav-backdrop:not([hidden]) {
        display: block;
        position: fixed;
        inset: var(--topbar-h) 0 0;
        z-index: 19;
        border: 0;
        background: rgb(0 0 0 / 0.45);
    }

    body.nav-open {
        overflow: hidden;
    }
}

/* Below the content width, the main column owns the row. */
@media (max-width: 46rem) {
    .layout:has(.sidebar:not(:empty)) {
        grid-template-columns: minmax(0, 1fr);
    }

    .layout:has(.sidebar:not(:empty)) .nav-toggle,
    .layout:has(.sidebar:not(:empty)) main {
        grid-column: 1;
    }

    .layout:has(.sidebar:not(:empty)) .nav-toggle {
        padding-inline: var(--space-5);
    }
}

.sidebar .nav-title {
    min-block-size: 2.5rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-size: var(--text-sm);
    line-height: 1.35;
    color: var(--text);
    margin: 0 0 0.2rem;
}

.sidebar ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.sidebar li ul {
    padding-inline-start: 0.75rem;
}

.sidebar li {
    margin: 0;
}

.sidebar li a {
    position: relative;
    display: block;
    padding-block: 0.2rem;
    padding-inline-start: 0.75rem;
    font-size: var(--text-sm);
    line-height: 1.4;
    color: var(--text-muted);
    text-decoration: none;
    transition: color 0.2s ease;
}

.sidebar li a:hover { color: var(--text); }

.sidebar li a::before {
    content: "";
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 0;
    inline-size: 2px;
    block-size: 1rem;
    border-radius: 1px;
    background: transparent;
    translate: 0 -50%;
    transition: background-color 0.2s ease;
}

.sidebar li a:is([aria-current="page"], [aria-current="true"], [aria-current="location"]) {
    color: var(--paper);
    letter-spacing: 0.015em;
}

.sidebar li a:is([aria-current="page"], [aria-current="true"], [aria-current="location"])::before {
    background: var(--brand);
}

main {
    padding: var(--space-6) var(--space-5);
    min-width: 0;
}

.layout:has(.sidebar:not(:empty)) main {
    padding-inline: 0;
}

@media (max-width: 46rem) {
    .layout:has(.sidebar:not(:empty)) main {
        padding-inline: var(--space-5);
    }
}

main > * {
    margin-inline: auto;
}

.main-signoff {
    font-size: var(--text-sm);
    margin: 0;
    text-transform: none;
}

.main-signoff span {
    color: var(--brand);
}

.pkg-head + article { margin-inline: auto; }

.pkg-head + article > p:first-of-type {
    font-size: 1.0625rem;
}

article, .prose {
    max-width: 46rem;
}

footer {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: baseline;
    gap: var(--space-5);
    margin-block-start: calc(var(--space-8) * 1.5);
    font-size: 0.65625rem;
    font-weight: 300;
    font-stretch: semi-condensed;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
}

footer .colophon,
footer nav { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; margin: 0; }
footer nav { justify-self: end; }
:is(footer, article) a {
    position: relative;
    text-decoration: none;
    transition: color 220ms ease-in;
}

:is(footer, article) a::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-end: -0.2rem;
    block-size: 2px;
    border-radius: 1px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 220ms ease-in;
}

:is(footer, article) a:hover,
:is(footer, article) a:focus-visible {
    transition-duration: 120ms;
    transition-timing-function: ease-out;
}

:is(footer, article) a:hover::after,
:is(footer, article) a:focus-visible::after {
    transform: scaleX(1);
    transition-duration: 120ms;
    transition-timing-function: ease-out;
}

footer a { color: var(--text-muted); }
footer a:hover,
footer a:focus-visible { color: var(--brand); }

article a { color: var(--brand); }
article a:hover,
article a:focus-visible { color: var(--brand-soft); }

.doc-pagination {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-5);
    margin-block-start: calc(var(--space-8) * 2);
    padding-block-start: var(--space-8);
    border-block-start: 1px solid var(--border);
}

.doc-pagination a {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    justify-self: start;
    min-block-size: 2.5rem;
    max-inline-size: 100%;
    line-height: 1.45;
}

.doc-pagination a::after {
    display: none;
}

.doc-pagination a.doc-pagination-next {
    grid-column: 2;
    justify-self: end;
    align-items: flex-end;
    text-align: end;
}

.doc-pagination-direction {
    color: var(--brand);
    font-size: 0.65625rem;
    font-weight: 300;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.doc-pagination-label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--paper);
    font-size: clamp(var(--text-lg), 4vw, var(--text-xl));
    line-height: 1.2;
}

.doc-pagination-arrow {
    font-family: var(--mono);
    font-size: 1.1em;
    font-weight: 300;
}

@media (max-width: 50rem) {
    footer {
        grid-template-columns: 1fr;
        justify-items: center;
        text-align: center;
    }

    footer .colophon,
    footer nav {
        justify-content: center;
        justify-self: center;
    }
}

.footer-brand { color: inherit; }
.footer-brand span { color: var(--text); transition: color 220ms ease-in; }
.footer-brand:hover span,
.footer-brand:focus-visible span { color: inherit; transition-duration: 120ms; }
.footer-separator { color: currentColor; opacity: 0.75; }

article :is(p, li, blockquote) { text-wrap: pretty; }

article :is(ul, ol) {
    padding-inline-start: 1.4rem;
}

article li {
    margin-block-end: var(--space-1);
}

article li:last-child {
    margin-block-end: 0;
}

article li > p {
    margin-block-end: var(--space-2);
}

article h2,
article h3 {
    position: relative;
}

article > h1 {
    position: relative;
    font-size: clamp(3.25rem, 7vw, 4.75rem);
    margin-block-start: 0;
    margin-block-end: calc(var(--space-8) * 1.5);
    padding-block-end: var(--space-3);
}

article > h1::after {
    content: "";
    position: absolute;
    inset-block-end: 0;
    inset-inline-start: 0;
    inline-size: var(--accent-line-title-width);
    block-size: var(--accent-line-height);
    border-radius: var(--accent-line-radius);
    background: var(--brand);
}

article h2 {
    margin-block-start: calc(var(--space-8) * 2);
    margin-block-end: var(--space-6);
}

article h2::before {
    content: "";
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: calc(100% + var(--space-3));
    inline-size: var(--accent-line-heading-width);
    block-size: var(--accent-line-height);
    border-radius: var(--accent-line-radius);
    background: var(--brand);
    translate: 0 -50%;
}

article h3 {
    margin-block-start: calc(var(--space-8) * 1.4);
    margin-block-end: var(--space-5);
}


/* own leading: body runs 1.7, which reads double-spaced in a <pre> */
article :is(pre, pre code) {
    font-family: var(--mono);
    font-size: var(--text-sm);
    line-height: 1.55;
}

article pre {
    border: 1px solid var(--border);
    border-radius: var(--space-1);
    padding: var(--space-4) var(--space-5);
    overflow-x: auto;
    tab-size: 4;
}

article pre code { display: block; }

/* colour, not a box. Sized in em so code inside a heading scales with it,
   floored at --text-sm so it never drops below the smallest type on the page. */
article :not(pre) > code {
    font-family: var(--mono);
    font-size: max(var(--text-sm), 0.9em);
    color: var(--brand-soft);
    overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------- tables */

article table {
    inline-size: 100%;
    border-collapse: collapse;
    margin-block-end: 2.5rem;
    font-size: var(--text-sm);
    line-height: 1.55;
}

article table:has(img) { table-layout: fixed; }

article table:has(img) img {
    display: block;
    inline-size: 100%;
    block-size: auto;
    outline: 1px solid rgb(255 255 255 / 0.1);
}

article :is(th, td) {
    text-align: start;
    vertical-align: top;
    padding: var(--space-3) var(--space-4);
    padding-inline-start: 0;
    border-block-end: 1px solid var(--border);
}

article :is(th, td):last-child { padding-inline-end: 0; }

article th {
    font-weight: 500;
    color: var(--text);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border-block-end-color: var(--text-muted);
    white-space: normal;
    overflow-wrap: anywhere;
}

article td { color: var(--text-muted); }
article tbody tr:last-child :is(th, td) { border-block-end: 0; }
article td code { overflow-wrap: anywhere; }

/* Keep reference columns readable while scrolling within narrow screens. */
@media (max-width: 51rem) {
    article table:not(:has(img)) {
        display: block;
        overflow-x: auto;
    }

    article table:not(:has(img)) :is(th, td) { min-inline-size: 12rem; }
}

/* ==================================================== the package marks */

:is(.icon, .card-icon) [data-anim] { transform-box: view-box; }
:is(.icon, .card-icon) [data-layer="primary"]   { stroke: var(--text); }
:is(.icon, .card-icon) [data-layer="secondary"] { stroke: var(--faint); }
:is(.icon, .card-icon) [data-layer="accent"]    { stroke: var(--brand); }
:is(.icon, .card-icon) [data-fill="accent"]     { fill: var(--brand); stroke: none; }
:is(.icon, .card-icon) .bg-fill                 { fill: var(--bg); stroke: none; }
:is(.icon, .card-icon) .trace { stroke-dasharray: 100; stroke-dashoffset: 100; }

/* ---- markdown: inline content slides right, under its block marker ---- */
@keyframes md-h { 0%, 5% { transform: translateX(0); } 15%, 85% { transform: translateX(16px); } 95%, 100% { transform: translateX(0); } }
@keyframes md-q { 0%, 25% { transform: translateX(0); } 35%, 85% { transform: translateX(16px); } 95%, 100% { transform: translateX(0); } }
@keyframes md-l { 0%, 45% { transform: translateX(0); } 55%, 85% { transform: translateX(16px); } 95%, 100% { transform: translateX(0); } }
[data-anim="md-h"] { animation: md-h var(--dur) var(--ease) infinite; }
[data-anim="md-q"] { animation: md-q var(--dur) var(--ease) infinite; }
[data-anim="md-l"] { animation: md-l var(--dur) var(--ease) infinite; }

/* ---- rst: each underline draws out to the exact length of its title ---- */
@keyframes rst-u1 { 0%, 6% { stroke-dashoffset: 100; } 22%, 86% { stroke-dashoffset: 0; } 94%, 100% { stroke-dashoffset: 100; } }
@keyframes rst-u2 { 0%, 26% { stroke-dashoffset: 100; } 42%, 86% { stroke-dashoffset: 0; } 94%, 100% { stroke-dashoffset: 100; } }
@keyframes rst-dot { 0%, 46% { opacity: 0; } 56%, 86% { opacity: 1; } 94%, 100% { opacity: 0; } }
@keyframes rst-name { 0%, 50% { stroke-dashoffset: 100; } 64%, 86% { stroke-dashoffset: 0; } 94%, 100% { stroke-dashoffset: 100; } }
@keyframes rst-body { 0%, 62% { stroke-dashoffset: 100; } 76%, 86% { stroke-dashoffset: 0; } 94%, 100% { stroke-dashoffset: 100; } }
[data-anim="rst-u1"] { animation: rst-u1 var(--dur) var(--ease) infinite; }
[data-anim="rst-u2"] { animation: rst-u2 var(--dur) var(--ease) infinite; }
[data-anim="rst-dot"] { animation: rst-dot var(--dur) var(--ease) infinite; opacity: 0; }
[data-anim="rst-name"] { animation: rst-name var(--dur) var(--ease) infinite; }
[data-anim="rst-body"] { animation: rst-body var(--dur) var(--ease) infinite; }

/* ---- frontmatter: the --- fence pushes the body down, the header fills the gap ---- */
@keyframes fm-slide { 0%, 15% { transform: translateY(0); } 35%, 85% { transform: translateY(32px); } 85.1%, 100% { transform: translateY(0); } }
@keyframes fm-fade { 0%, 20% { opacity: 0; } 40%, 85% { opacity: 1; } 85.1%, 100% { opacity: 0; } }
[data-anim="fm-slide"] { animation: fm-slide var(--dur) var(--ease) infinite; }
[data-anim="fm-fade"] { animation: fm-fade var(--dur) var(--ease) infinite; opacity: 0; }

/* ---- tree: a branch moves down, two children resolve under it ---- */
@keyframes tree-b-move { 0%, 10% { transform: translateY(0); } 20%, 85% { transform: translateY(20px); } 90%, 100% { transform: translateY(0); } }
@keyframes tree-stem { 0%, 10% { d: path("M 26 28 V 62"); } 20%, 85% { d: path("M 26 28 V 82"); } 90%, 100% { d: path("M 26 28 V 62"); } }
@keyframes tree-a1 { 0%, 20% { clip-path: inset(0 0 100% 0); opacity: 0; } 30%, 85% { clip-path: inset(0 0 0 0); opacity: 1; } 90%, 100% { clip-path: inset(0 0 100% 0); opacity: 0; } }
@keyframes tree-b1 { 0%, 65% { clip-path: inset(0 0 100% 0); opacity: 0; } 75%, 85% { clip-path: inset(0 0 0 0); opacity: 1; } 90%, 100% { clip-path: inset(0 0 100% 0); opacity: 0; } }
[data-anim="tree-b-move"] { animation: tree-b-move var(--dur) var(--ease) infinite; }
[data-anim="tree-stem"] { animation: tree-stem var(--dur) var(--ease) infinite; }
[data-anim="tree-a1"] { animation: tree-a1 var(--dur) var(--ease) infinite; }
[data-anim="tree-b1"] { animation: tree-b1 var(--dur) var(--ease) infinite; }

/* ---- json-patch: the pointer walks the tree, then the value it names changes ---- */
@keyframes jp-walk { 0%, 8% { transform: translateY(0); } 22%, 30% { transform: translateY(20px); } 44%, 88% { transform: translateY(40px); } 96%, 100% { transform: translateY(0); } }
@keyframes jp-old { 0%, 44% { opacity: 1; } 58%, 88% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes jp-new { 0%, 46% { stroke-dashoffset: 100; } 60%, 88% { stroke-dashoffset: 0; } 96%, 100% { stroke-dashoffset: 100; } }
[data-anim="jp-walk"] { animation: jp-walk var(--dur) var(--ease) infinite; }
[data-anim="jp-old"] { animation: jp-old var(--dur) var(--ease) infinite; }
[data-anim="jp-new"] { animation: jp-new var(--dur) var(--ease) infinite; }

/* ---- language: each entry unfolds its metadata ---- */
@keyframes lang-1 { 0%, 10% { opacity: 0; transform: translateX(-6px); } 22%, 88% { opacity: 1; transform: translateX(0); } 96%, 100% { opacity: 0; transform: translateX(-6px); } }
@keyframes lang-2 { 0%, 26% { opacity: 0; transform: translateX(-6px); } 38%, 88% { opacity: 1; transform: translateX(0); } 96%, 100% { opacity: 0; transform: translateX(-6px); } }
@keyframes lang-3 { 0%, 42% { opacity: 0; transform: translateX(-6px); } 54%, 88% { opacity: 1; transform: translateX(0); } 96%, 100% { opacity: 0; transform: translateX(-6px); } }
[data-anim="lang-1"] { animation: lang-1 var(--dur) var(--ease) infinite; opacity: 0; }
[data-anim="lang-2"] { animation: lang-2 var(--dur) var(--ease) infinite; opacity: 0; }
[data-anim="lang-3"] { animation: lang-3 var(--dur) var(--ease) infinite; opacity: 0; }

/* ---- twig code highlight: the template delimiters close, the code lights up inside ---- */
@keyframes tw-l { 0%, 6% { stroke-dashoffset: 100; } 24%, 88% { stroke-dashoffset: 0; } 96%, 100% { stroke-dashoffset: 100; } }
@keyframes tw-r { 0%, 14% { stroke-dashoffset: 100; } 32%, 88% { stroke-dashoffset: 0; } 96%, 100% { stroke-dashoffset: 100; } }
@keyframes tw-hl { 0%, 40% { opacity: 0; } 54%, 88% { opacity: 1; } 96%, 100% { opacity: 0; } }
[data-anim="tw-l"] { animation: tw-l var(--dur) var(--ease) infinite; }
[data-anim="tw-r"] { animation: tw-r var(--dur) var(--ease) infinite; }
[data-anim="tw-hl"] { animation: tw-hl var(--dur) var(--ease) infinite; opacity: 0; }

/* ---- commonmark: an extension slides in and lights up ---- */
@keyframes ext-slide { 0%, 15% { transform: translateX(0); } 25%, 85% { transform: translateX(-16px); } 95%, 100% { transform: translateX(0); } }
@keyframes ext-activate { 0%, 24% { stroke: var(--faint); opacity: 0.5; } 25%, 85% { stroke: var(--ink); opacity: 1; } 86%, 100% { stroke: var(--faint); opacity: 0.5; } }
[data-anim="ext-slide"] { animation: ext-slide var(--dur) var(--ease) infinite; }
[data-anim="ext-activate"] { animation: ext-activate var(--dur) var(--ease) infinite; }

/* ---- code highlight ---- */
@keyframes hl-1 { 0%, 10% { opacity: 0; } 15%, 90% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hl-2 { 0%, 25% { opacity: 0; } 30%, 90% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hl-3 { 0%, 40% { opacity: 0; } 45%, 90% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hl-4 { 0%, 55% { opacity: 0; } 60%, 90% { opacity: 1; } 100% { opacity: 0; } }
[data-anim="hl-1"] { animation: hl-1 var(--dur) ease-in-out infinite; opacity: 0; }
[data-anim="hl-2"] { animation: hl-2 var(--dur) ease-in-out infinite; opacity: 0; }
[data-anim="hl-3"] { animation: hl-3 var(--dur) ease-in-out infinite; opacity: 0; }
[data-anim="hl-4"] { animation: hl-4 var(--dur) ease-in-out infinite; opacity: 0; }

/* ---- code diff: added reads accent, removed reads faint and fades out ---- */
@keyframes diff-l2 { 0%, 25% { transform: translateY(0); } 35%, 100% { transform: translateY(16px); } }
@keyframes diff-l3 {
  0%, 10% { stroke: var(--faint); transform: translateY(0); opacity: 1; }
  15%, 25% { stroke: var(--faint); transform: translateY(0); opacity: 1; }
  35%, 65% { stroke: var(--faint); transform: translateY(16px); opacity: 1; }
  70%, 100% { stroke: var(--faint); transform: translateY(16px); opacity: 0; }
}
@keyframes diff-minus { 0%, 10% { opacity: 0; } 15%, 65% { opacity: 1; } 70%, 100% { opacity: 0; } }
@keyframes diff-lnew {
  0%, 25% { stroke: var(--c1); opacity: 0; }
  35%, 65% { stroke: var(--c1); opacity: 1; }
  70%, 100% { stroke: var(--faint); opacity: 1; }
}
@keyframes diff-plus { 0%, 25% { opacity: 0; } 35%, 65% { opacity: 1; } 70%, 100% { opacity: 0; } }
[data-anim="diff-l2"] { animation: diff-l2 var(--dur) var(--ease) infinite; }
[data-anim="diff-l3"] { animation: diff-l3 var(--dur) var(--ease) infinite; }
[data-anim="diff-minus"] { animation: diff-minus var(--dur) var(--ease) infinite; stroke: var(--c1); }
[data-anim="diff-lnew"] { animation: diff-lnew var(--dur) var(--ease) infinite; }
[data-anim="diff-plus"] { animation: diff-plus var(--dur) var(--ease) infinite; stroke: var(--c1); }

/* ---- favicon ---- */
@keyframes favicon-drop { 0%, 15% { opacity: 0; transform: translateY(-6px); } 35%, 75% { opacity: 1; transform: translateY(0); } 95%, 100% { opacity: 0; transform: translateY(6px); } }
[data-anim="favicon-drop"] { animation: favicon-drop var(--dur) var(--ease) infinite; }

/* ---- importmap ---- */
@keyframes map-path-1 { 0%, 5% { stroke-dashoffset: 80; opacity: 0; } 10%, 28% { stroke-dashoffset: 0; opacity: 1; } 33%, 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes map-path-2 { 0%, 33% { stroke-dashoffset: 80; opacity: 0; } 38%, 61% { stroke-dashoffset: 0; opacity: 1; } 66%, 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes map-path-3 { 0%, 66% { stroke-dashoffset: 80; opacity: 0; } 71%, 94% { stroke-dashoffset: 0; opacity: 1; } 98%, 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes map-source-A { 0%, 62% { opacity: 1; stroke: var(--ink); } 66%, 100% { opacity: 0; stroke: var(--faint); } }
@keyframes map-source-B { 0%, 62% { opacity: 0; stroke: var(--faint); } 66%, 100% { opacity: 1; stroke: var(--ink); } }
@keyframes map-target-Y { 0%, 28% { opacity: 1; stroke: var(--c1); } 33%, 100% { opacity: 0; stroke: var(--faint); } }
@keyframes map-target-Z { 0%, 28% { opacity: 0; } 33%, 95% { opacity: 1; stroke: var(--c1); } 98%, 100% { opacity: 0; } }
[data-anim^="map-path"] { stroke-dasharray: 80; }
[data-anim="map-path-1"] { animation: map-path-1 var(--dur) var(--ease) infinite; }
[data-anim="map-path-2"] { animation: map-path-2 var(--dur) var(--ease) infinite; }
[data-anim="map-path-3"] { animation: map-path-3 var(--dur) var(--ease) infinite; }
[data-anim="map-source-A"] { animation: map-source-A var(--dur) var(--ease) infinite; opacity: 1; }
[data-anim="map-source-B"] { animation: map-source-B var(--dur) var(--ease) infinite; opacity: 0; }
[data-anim="map-target-Y"] { animation: map-target-Y var(--dur) var(--ease) infinite; opacity: 0; }
[data-anim="map-target-Z"] { animation: map-target-Z var(--dur) var(--ease) infinite; opacity: 0; }

/* ---- scale ---- */
@keyframes sw1 { 0%, 5% { stroke-dashoffset: 16; } 15%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 16; } }
@keyframes sw2 { 0%, 10% { stroke-dashoffset: 12; } 20%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 12; } }
@keyframes sw3 { 0%, 15% { stroke-dashoffset: 8; } 25%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 8; } }
@keyframes sw4 { 0%, 20% { stroke-dashoffset: 4; } 30%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 4; } }
@keyframes sp1 { 0%, 35% { stroke-dashoffset: 64; } 50%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 64; } }
@keyframes sp2 { 0%, 40% { stroke-dashoffset: 32; } 55%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 32; } }
@keyframes sp3 { 0%, 45% { stroke-dashoffset: 16; } 60%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 16; } }
@keyframes sp4 { 0%, 50% { stroke-dashoffset: 8; }  65%, 85% { stroke-dashoffset: 0; } 90%, 100% { stroke-dashoffset: 8; } }
[data-anim="sw1"] { animation: sw1 var(--dur) var(--ease) infinite; stroke-dasharray: 16; }
[data-anim="sw2"] { animation: sw2 var(--dur) var(--ease) infinite; stroke-dasharray: 12; }
[data-anim="sw3"] { animation: sw3 var(--dur) var(--ease) infinite; stroke-dasharray: 8; }
[data-anim="sw4"] { animation: sw4 var(--dur) var(--ease) infinite; stroke-dasharray: 4; }
[data-anim="sp1"] { animation: sp1 var(--dur) var(--ease) infinite; stroke-dasharray: 64; }
[data-anim="sp2"] { animation: sp2 var(--dur) var(--ease) infinite; stroke-dasharray: 32; }
[data-anim="sp3"] { animation: sp3 var(--dur) var(--ease) infinite; stroke-dasharray: 16; }
[data-anim="sp4"] { animation: sp4 var(--dur) var(--ease) infinite; stroke-dasharray: 8; }

/* ---- bezier: the curve morphs, each handle lights up as it takes over ---- */
@keyframes bezier-morph {
  0%, 10% { d: path("M 24 88 C 24 53, 53 24, 88 24"); }
  25%, 40% { d: path("M 24 88 C 62 88, 53 24, 88 24"); }
  55%, 70% { d: path("M 24 88 C 62 88, 88 62, 88 24"); }
  85%, 90% { d: path("M 24 88 C 24 53, 88 62, 88 24"); }
  100% { d: path("M 24 88 C 24 53, 53 24, 88 24"); }
}
@keyframes bezier-h1 {
  0%, 10% { d: path("M 24 88 L 24 53"); }
  25%, 70% { d: path("M 24 88 L 62 88"); }
  85%, 100% { d: path("M 24 88 L 24 53"); }
}
@keyframes bezier-h2 {
  0%, 40% { d: path("M 88 24 L 53 24"); }
  55%, 90% { d: path("M 88 24 L 88 62"); }
  100% { d: path("M 88 24 L 53 24"); }
}
@keyframes bezier-c1 { 0%, 10% { transform: translate(0, 0); } 25%, 70% { transform: translate(38px, 35px); } 85%, 100% { transform: translate(0, 0); } }
@keyframes bezier-c2 { 0%, 40% { transform: translate(0, 0); } 55%, 90% { transform: translate(35px, 38px); } 100% { transform: translate(0, 0); } }
@keyframes bz-c1 {
  0%, 9% { stroke: var(--faint); fill: var(--bg); }
  10%, 25% { stroke: var(--c1); fill: var(--c1); }
  26%, 74% { stroke: var(--faint); fill: var(--bg); }
  75%, 85% { stroke: var(--c1); fill: var(--c1); }
  86%, 100% { stroke: var(--faint); fill: var(--bg); }
}
@keyframes bz-c2 {
  0%, 39% { stroke: var(--faint); fill: var(--bg); }
  40%, 55% { stroke: var(--c1); fill: var(--c1); }
  56%, 89% { stroke: var(--faint); fill: var(--bg); }
  90%, 100% { stroke: var(--c1); fill: var(--c1); }
}
[data-anim="bezier-morph"] { animation: bezier-morph var(--dur) var(--ease) infinite; }
[data-anim="bezier-h1"] { animation: bezier-h1 var(--dur) var(--ease) infinite; }
[data-anim="bezier-h2"] { animation: bezier-h2 var(--dur) var(--ease) infinite; }
[data-anim="bezier-c1"] { animation: bezier-c1 var(--dur) var(--ease) infinite; }
[data-anim="bezier-c2"] { animation: bezier-c2 var(--dur) var(--ease) infinite; }
[data-anim="bz-c1"] { animation: bz-c1 var(--dur) var(--ease) infinite; }
[data-anim="bz-c2"] { animation: bz-c2 var(--dur) var(--ease) infinite; }
/* ---- font: the metric lines a font file declares, drawn under a glyph ---- */
@keyframes ft-cap  { 0%, 10% { stroke-dashoffset: 100; } 26%, 88% { stroke-dashoffset: 0; } 96%, 100% { stroke-dashoffset: 100; } }
@keyframes ft-x    { 0%, 26% { stroke-dashoffset: 100; } 42%, 88% { stroke-dashoffset: 0; } 96%, 100% { stroke-dashoffset: 100; } }
@keyframes ft-base { 0%, 42% { stroke-dashoffset: 100; } 58%, 88% { stroke-dashoffset: 0; } 96%, 100% { stroke-dashoffset: 100; } }
[data-anim="ft-cap"]  { animation: ft-cap var(--dur) var(--ease) infinite; }
[data-anim="ft-x"]    { animation: ft-x var(--dur) var(--ease) infinite; }
[data-anim="ft-base"] { animation: ft-base var(--dur) var(--ease) infinite; }

/* these three have already undone themselves by 80% */
[data-pkg="code-diff"], [data-pkg="favicon"] { --settled: -3s; }
[data-pkg="bezier"] { --settled: -3.9s; }

/* a negative delay renders a paused animation mid-cycle, not at frame zero */
.card-icon [data-anim] { animation-delay: var(--settled); animation-play-state: paused; }
.card:hover .card-icon [data-anim] { animation-play-state: running; }

/* ============================================================ index page */

.masthead {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-5);
    margin-block: var(--space-8) calc(var(--space-8) * 2);
}

.masthead h1 { margin: 0 0 var(--space-8); }
.lockup { block-size: 7rem; inline-size: calc(7rem * 346 / 121); }

.lead {
    color: var(--text-muted);
    font-size: var(--text-lg);
    line-height: 1.7;
    max-inline-size: 52ch;
    text-wrap: balance;
    margin: 0;
}

.family { margin-block-end: calc(var(--space-8) * 1.5); }

.family-name {
    position: relative;
    font-size: var(--text-sm);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--text-muted);
    margin-block: calc(var(--space-8) * 2) var(--space-8);
    padding-inline-start: calc(var(--accent-line-heading-width) + var(--space-3));
}

.family-name::before {
    content: "";
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 0;
    inline-size: var(--accent-line-heading-width);
    block-size: var(--accent-line-height);
    border-radius: var(--accent-line-radius);
    background: var(--brand);
    translate: 0 -50%;
}

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 22.5rem), 1fr));
    gap: var(--space-4);
}

/* no border, no box: the card is its illustration and its spacing */
.card {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.9rem;
    padding: 2.5rem 1rem;
    text-decoration: none;
    transition: box-shadow 300ms ease-in-out;
}

/* scale is its own property, so it composes with the icon's translate */
.card .card-icon,
.card h3 { transition: scale 300ms ease-in-out; }
.card:hover .card-icon { scale: 1.06; }
.card:hover h3 { scale: 1.03; }

.card:hover {
    box-shadow: 0 0 1px 0px #f000, 0 0 5px 5px #0008;
}

.card-bg {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    translate: -50% calc(-50% - 1rem);
    z-index: -1;
    inline-size: 7rem;
    block-size: 7rem;
    scale: 2.6;
    opacity: 0.045;
    color: var(--brand);
    pointer-events: none;
    filter: blur(0);
    transition: opacity 350ms ease, scale 350ms ease, filter 350ms ease;
}

/* the watermark pulls back so the animating mark owns the card */
.card:hover .card-bg {
    scale: 3;
    opacity: 0.028;
    filter: blur(0.375rem);
}

.card-icon {
    inline-size: 7rem;
    block-size: 7rem;
    overflow: visible;
    margin-block-end: 0.4rem;
    translate: 0 0.5rem;
}

.card h3 {
    font-size: var(--text-lg);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text);
    margin: 0;
}

.card .desc {
    display: -webkit-box;
    min-block-size: 3.2em;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    font-size: var(--text-base);
    line-height: 1.6;
    color: var(--text-muted);
    max-inline-size: 34ch;
    text-wrap: balance;
    margin: 0;
}

.card .req {
    display: inline-flex;
    flex-wrap: nowrap;
    justify-content: center;
    gap: 0.15em 0.2em;
    max-inline-size: 100%;
    white-space: nowrap;
    margin-block-start: auto;
    padding: 0.45rem 0.5rem;
    border-radius: 999px;
    background: #000;
    font-family: var(--mono);
    font-size: 0.75rem;
    line-height: 1.35;
    letter-spacing: 0.02em;
    color: var(--text-muted);
    transition: color 0.25s ease;
}

.card .req .cmd,
.card .req .pkg { color: var(--brand); white-space: nowrap; }
.card .req .cmd { color: var(--text-muted); }
.card:hover .req { color: var(--text); }
.card:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* ========================================================== package page */

/* The docked state of ALTO Package B, read off its own numbers at progress 1:
   title 88 - 26.4 = 61.6px, gaps 28 - 22 = 6px, bar 4 by 44. */
.pkg-head {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    max-width: 46rem;
    padding-inline: 0;
    padding-block: var(--space-8) calc(var(--space-8) * 2);
    margin-block-end: var(--space-8);
    border-block-end: 1px solid var(--border);
}

.pkg-hero {
    position: relative;
    inline-size: 100%;
    padding-block-start: 5rem;
}

.pkg-title {
    position: relative;
    z-index: 1;
    min-inline-size: 0;
}

.pkg-bar {
    display: block;
    inline-size: var(--accent-line-title-width);
    block-size: var(--accent-line-height);
    border-radius: var(--accent-line-radius);
    background: var(--brand);
    margin-block-end: var(--space-5);
}

.pkg-name {
    font-size: clamp(2.75rem, 5vw, 4rem);
    line-height: 0.94;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    font-weight: 400;
    color: var(--paper);
    text-wrap: balance;
    margin: 0;
}

.pkg-name a { color: inherit; text-decoration: none; }
.pkg-name a:hover { color: var(--brand); }

.pkg-tagline {
    inline-size: 60%;
    font-size: 1.2rem;
    line-height: 1.65;
    letter-spacing: 0.04em;
    color: rgb(247 245 240 / 0.75);
    text-wrap: balance;
    margin: var(--space-7) 0 0;
}

.pkg-visual {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 50%;
    display: grid;
    place-items: center;
    inline-size: 6.4rem;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
}

.pkg-bg {
    position: absolute;
    inset: 50% auto auto 50%;
    translate: -50% -50%;
    z-index: -1;
    inline-size: 6.4rem;
    block-size: 6.4rem;
    scale: 2.6;
    opacity: 0.05;
    color: var(--brand);
    pointer-events: none;
}

.pkg-head .icon {
    inline-size: clamp(4.8rem, 9.6vw, 7.2rem);
    block-size: clamp(4.8rem, 9.6vw, 7.2rem);
    overflow: visible;
}

@property --angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }

.composer {
    display: inline-block;
    margin-block-start: calc(var(--space-6) * 2);
    font-family: var(--mono);
    font-size: var(--text-sm);
    letter-spacing: 0.01em;
    color: var(--text-muted);
    cursor: pointer;
    padding: 1rem 1.75rem;
    border-radius: 999px;
    border: 0.125rem solid transparent;
    background: linear-gradient(var(--bg), var(--bg)) padding-box,
                conic-gradient(from var(--angle), var(--brand), var(--brand-soft), var(--brand)) border-box;
    animation: spin-border 8s linear infinite;
    transition: color 0.2s ease;
}

.composer:hover { color: var(--text); }
.composer .p { color: var(--brand); white-space: nowrap; }
.composer.ok { color: var(--brand); }
@keyframes spin-border { to { --angle: 360deg; } }

@media (max-width: 50rem) {
    article h2::before {
        inset-inline-end: auto;
        inset-inline-start: -1.25rem;
    }
}

@media (max-width: 51rem) {
    .pkg-visual {
        inline-size: 5.6rem;
    }

    .pkg-name {
        font-size: clamp(2.25rem, 10vw, 2.875rem);
        line-height: 0.96;
    }

    .pkg-tagline {
        inline-size: 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    :is(footer, article) a,
    :is(footer, article) a::after,
    .footer-brand span { transition: none; }
    .composer { animation: none; }
    .icon [data-anim] { animation-delay: var(--settled); animation-play-state: paused; }
    .card:hover .card-icon [data-anim] { animation-play-state: paused; }
}
}

.alto-highlight {
    padding: 1rem 1.5rem;
    border-radius: 0.65rem;
    overflow-x: auto;
    margin-inline: -1.5rem;
}

@media (max-width: 46rem) {
    .alto-highlight {
        margin-inline: max(-1.5rem, calc((100vi - 100%) / -2));
    }
}

/* Catalog items keep their parent visible without expanding the catalog. */
.doc-breadcrumbs { margin-bottom: 1.5rem; font-size: .875rem; }
.doc-breadcrumbs ol { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; list-style: none; }
.doc-breadcrumbs li + li::before { content: "/"; margin-right: .5rem; opacity: .5; }
