/* ==========================================================================
   VERAPET — design system "C"
   One theme, two surface scopes: `.vp-sig` (dark, signature — header, hero, diagrams, footer) and
   `.vp-work` (light warm-paper — content, cards, forms, tables). No dark/light toggle: the scope a
   section is in is a design decision made once, in markup, not a user preference.
   Colours exist exactly once, as the --vp-* custom properties below; components never use a raw hex.
   Motion is used sparingly and every animation here has a `prefers-reduced-motion: reduce` fallback.
   ========================================================================== */

/* --- 1. Tokens --------------------------------------------------------- */

:root,
.vp-work {
    --vp-bg: #FBF7F2;
    --vp-tile: #FFFFFF;
    --vp-tile-2: #F4EDE4;
    --vp-field: #FFFFFF;
    --vp-line: #E8DED2;
    --vp-line-2: #D6C9BA;
    --vp-ink: #171413;
    --vp-body: #3B3431;
    /* WCAG 2.2 AA (ADR-022 decision 4):
       copper/gold/cyan/violet/muted are darkened from their first values so pill text at its own
       12%/20% tint, over both --vp-bg and --vp-tile, and the copper link colour over --vp-tile-2,
       all clear 4.5:1. Hues are unchanged; only lightness moved. Computed with a script, ratio table
       in the PR. --vp-danger and --vp-ink already cleared 4.5:1 unchanged. */
    --vp-muted: #675B54;
    --vp-copper: #874F26;
    --vp-gold: #77571C;
    --vp-cyan: #2A637E;
    --vp-violet: #6E5183;
    --vp-supporter: #9A3A55;
    --vp-blue: #3D6A8A;
    --vp-danger: #A8322A;
    --vp-btn: #171413;
    --vp-btn-ink: #F6F0E8;
    --vp-photo: #EFE6DA;
    /* A control boundary (input/select/checkbox) needs 3:1 against both --vp-field AND --vp-bg (a
       field can sit directly on the page background, not just its own tile) — not the decorative
       --vp-line/--vp-line-2 hairline contrast, which stays as it was, hairlines only. */
    --vp-field-line: #A58867;
    --vp-shadow: 0 1px 2px rgb(23 20 19 / .04), 0 12px 32px rgb(23 20 19 / .06);
    --vp-holo: linear-gradient(100deg, #3D6A8A 0%, #7A5A92 20%, #A35F2E 40%, #2F6F8E 60%, #7A5A92 80%, #3D6A8A 100%);
    color-scheme: light;
}

.vp-sig {
    --vp-bg: var(--c-canvas);
    --vp-tile: #171413;
    --vp-tile-2: #201B19;
    --vp-field: #100E0D;
    --vp-line: #2B2523;
    --vp-line-2: #3D3532;
    --vp-ink: #F6F0E8;
    --vp-body: #DDD2C5;
    /* Only --vp-muted needed a (small, lightened) move here — every other .vp-sig tone already
       cleared 4.5:1 for light text on a dark ground; see the :root block above for the fuller note. */
    --vp-muted: #A1968C;
    --vp-copper: #E0A06A;
    --vp-gold: #E8CFA4;
    --vp-cyan: #5FA8C9;
    --vp-violet: #B28EC7;
    --vp-supporter: #EDA3B5;
    --vp-blue: #3D6A8A;
    --vp-danger: #F2B8B5;
    --vp-btn: #F6F0E8;
    --vp-btn-ink: #0A0908;
    --vp-photo: #201B19;
    --vp-field-line: #6D5F5A;
    --vp-shadow: none;
    --vp-holo: linear-gradient(100deg, #F6F0E8 0%, #E8CFA4 16%, #5FA8C9 32%, #B28EC7 48%, #E0A06A 64%, #3D6A8A 80%, #F6F0E8 100%);
    color-scheme: dark;
}

.vp-sig,
.vp-work {
    background: var(--vp-bg);
    color: var(--vp-body);
}

:root {
    /* Brand raw stops — for the ring/wash/ambient gradients and the logo only. Every other rule
       uses the semantic --vp-* variables above, which flip between the two scopes; these do not. */
    --c-cream-50: #F6F0E8;
    /* The dark signature ground: .vp-sig's --vp-bg and the page canvas behind every layout. */
    --c-canvas: #0A0908;
    --c-gold-200: #E8CFA4;
    --c-copper-300: #E0A06A;
    --c-copper-400: #C8763C;
    --c-copper-500: #A35F2E;
    --c-dusk-300: #9C7F9A;
    --c-cream-600: #887C72;
    --c-cloud-blue: #3D6A8A;
    --c-cloud-cyan: #5FA8C9;
    --c-holo-violet: #B28EC7;
    --c-ink-800: #100E0D;
    --c-ink-cool: #0A121C;
    --c-ink-ember: #18120E;

    --font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
    --font-body: "Geist", ui-sans-serif, -apple-system, "Segoe UI", sans-serif;
    --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;

    /* Fluid type scale */
    --step--1: clamp(0.78rem, 0.76rem + 0.1vw, 0.84rem);
    --step-0: clamp(0.95rem, 0.92rem + 0.16vw, 1.05rem);
    --step-1: clamp(1.1rem, 1.04rem + 0.3vw, 1.3rem);
    --step-2: clamp(1.45rem, 1.3rem + 0.75vw, 1.9rem);
    --step-title: clamp(1.8rem, 1.5rem + 1.3vw, 2.6rem);
    --step-3: clamp(2.3rem, 1.8rem + 2.5vw, 3.9rem);
    --step-hero: clamp(2.6rem, 1.9rem + 3.8vw, 5rem);

    --tracking-wide: 0.14em;
    --tracking-wider: 0.22em;

    /* Space */
    --space-2xs: 0.25rem;
    --space-xs: 0.5rem;
    --space-sm: 0.75rem;
    --space-md: 1.25rem;
    --space-lg: 2rem;
    --space-xl: 3.25rem;
    --space-2xl: 5rem;

    /* Shape */
    --radius-sm: 0.5rem;
    --radius-md: 0.875rem;
    --radius-lg: 1.125rem;
    --radius-pill: 999px;
    --measure: 38rem;

    /* The floating app bar: its height and its gap from the viewport edge. --vp-bar-clear is the
       space a page reserves so its first content starts below the bar. */
    --vp-bar-h: 60px;
    --vp-bar-gap: 10px;
    --vp-bar-clear: calc(env(safe-area-inset-top) + var(--vp-bar-h) + 2 * var(--vp-bar-gap));

    /* Motion */
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --duration-fast: 140ms;
    --duration-slow: 320ms;

    --vp-touch-target: 48px;
}

* {
    box-sizing: border-box;
}

/* The canvas behind the page is the dark signature, not the paper: every layout starts and ends on
   a vp-sig surface (teaser shell, top bar and footer, auth backdrop), and the canvas is what a phone
   browser paints under its status bar and when the page is over-scrolled past either end.

   The canvas is html's background AND the body must stay transparent. iOS Safari does not paint the
   over-scroll (pull-to-refresh) area with html's colour alone: WebKit's
   LocalFrameView::documentBackgroundColor() blends the body's background over html's, so an opaque
   paper body made the rubber-band area paper even with this canvas in place. Each layout shell
   paints its own ground instead (.vp-sig for the teaser and auth, .vp-app--bar for the paper app). */
html {
    -webkit-text-size-adjust: 100%;
    background-color: var(--c-canvas);
}

/* The canvas colour alone is not enough under the floating app bar: iOS Safari paints its status bar
   with the colour it samples along the page's top row (WebKit's PageColorSampler), or, from Safari 26,
   extends a fixed element that touches the edge. There the top row is the paper body above the bar, so
   the status bar and the bar's gap read as a white band over a dark bar. On touch devices a fixed,
   opaque, canvas-coloured cap owns that edge (the status bar inset plus the bar's gap); the bar still
   floats over the page below it. Desktop browsers have no status bar to tint and keep the plain gap. */
.vp-topcap {
    display: none;
}

@media (hover: none) and (pointer: coarse) {
    .vp-topcap {
        display: block;
        position: fixed;
        inset-inline: 0;
        top: 0;
        height: calc(env(safe-area-inset-top) + var(--vp-bar-gap));
        z-index: 19;
        /* No `pointer-events: none`: Safari 26 looks for the fixed element at the edge, and a pass-through
           element reads as the paper page beneath it (elementFromPoint skips it). Nothing interactive sits
           in the cap's strip at rest; the page starts below --vp-bar-clear. */
        background-color: var(--c-canvas);
    }
}

/* The app bar is fixed and floats over the page, so an in-page #anchor must land below it. Only where
   the bar exists — not the teaser shell or the Auth host, which load this same stylesheet. */
html:has(.vp-app--bar) {
    scroll-padding-top: var(--vp-bar-clear);
}

body {
    margin: 0;
    font-family: var(--font-body);
    font-size: var(--step-0);
    line-height: 1.6;
    /* No background here on purpose — see the html rule above. */
    color: var(--vp-body);
}

img {
    max-width: 100%;
    display: block;
}

a {
    color: var(--vp-copper);
    text-decoration: none;
}

a:hover {
    color: var(--vp-ink);
}

:focus-visible {
    outline: 2px solid var(--vp-copper);
    outline-offset: 3px;
}

/* Routes.razor's <FocusOnNavigate Selector="h1"> moves focus to the new page's heading on every
   navigation so screen readers announce it — but a heading is not an interactive element, and
   several browsers' :focus-visible heuristic still draws the ring for that kind of programmatic
   focus. A non-interactive element made focusable only for this (tabindex="-1") must never show it. */
h1:focus,
h1:focus-visible,
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible {
    outline: none;
}

/* --- 2. Effects (mezichlupy.cz recipes) --------------------------------- */

/* Italic, animated gradient text. Falls back to a flat copper when background-clip:text is not
   supported, so the phrase never disappears — @supports guards the transparent-fill trick, it does
   not guard the animation (that is prefers-reduced-motion's job, below). */
.vp-holo {
    font-style: italic;
    font-family: var(--font-display);
    color: var(--vp-copper);
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
    .vp-holo {
        background-image: var(--vp-holo);
        background-size: 260% 100%;
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        animation: vp-holo 12s linear infinite;
    }
}

.vp-wash {
    font-style: italic;
    font-family: var(--font-display);
    color: var(--vp-copper);
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
    .vp-wash {
        background-image: linear-gradient(100deg, var(--c-cream-50) 0%, var(--c-gold-200) 18%, var(--c-copper-300) 36%, var(--c-copper-400) 52%, var(--c-dusk-300) 68%, var(--c-copper-300) 84%, var(--c-cream-50) 100%);
        background-size: 300% 100%;
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        animation: vp-holo 26s linear infinite;
    }
}

@keyframes vp-holo {
    from {
        background-position: 0% 50%;
    }

    to {
        background-position: 260% 50%;
    }
}

/* Gradient-border ring: two background-images layered, the first paints the fill inside the
   padding box, the second paints a slow-drifting gradient into the 1px border itself. */
.vp-ring {
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    background-image: linear-gradient(var(--vp-tile), var(--vp-tile)),
        linear-gradient(100deg,
            var(--c-copper-500) 0%, var(--c-copper-400) 7%, var(--c-copper-300) 13%, var(--c-cream-50) 17.5%,
            var(--c-copper-300) 22%, var(--c-copper-400) 29%, var(--c-dusk-300) 33.5%, var(--c-dusk-300) 38.5%,
            var(--c-copper-400) 43%, var(--c-gold-200) 47%, var(--c-copper-300) 52%, var(--c-copper-500) 59%,
            var(--c-copper-400) 66%, var(--c-cream-50) 73%, var(--c-copper-300) 79%, var(--c-copper-400) 86%,
            var(--c-dusk-300) 91%, var(--c-dusk-300) 96%, var(--c-copper-500) 100%);
    background-origin: border-box;
    background-clip: padding-box, border-box;
    background-size: auto, 300% 100%;
    animation: vp-drift 79s linear infinite;
}

.vp-ring-holo {
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    background-image: linear-gradient(var(--vp-tile), var(--vp-tile)),
        linear-gradient(100deg,
            var(--c-cloud-blue) 0%, var(--c-cloud-cyan) 14%, var(--c-holo-violet) 30%, var(--c-gold-200) 44%,
            var(--c-cloud-cyan) 58%, var(--c-holo-violet) 72%, var(--c-copper-300) 86%, var(--c-cloud-blue) 100%);
    background-origin: border-box;
    background-clip: padding-box, border-box;
    background-size: auto, 300% 100%;
    animation: vp-drift 47s linear infinite;
}

@keyframes vp-drift {
    from {
        background-position: 0 0, 0% 50%;
    }

    to {
        background-position: 0 0, 300% 50%;
    }
}

/* Ambient background wash for `.vp-sig` regions — two soft radial gradients that drift very slowly.
   isolation:isolate keeps the ::before's negative z-index from bleeding into a parent stacking
   context; overflow:hidden keeps the oversized (-20% inset) gradient from adding scroll. */
.vp-ambient {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.vp-ambient::before {
    content: "";
    position: absolute;
    inset: -20%;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(46% 34% at 50% 12%, rgb(200 118 60 / .16), transparent 100%),
        radial-gradient(38% 30% at 72% 38%, rgb(156 127 154 / .10), transparent 100%);
    animation: vp-ambient 71s ease-in-out infinite alternate;
}

@keyframes vp-ambient {
    from {
        transform: translate3d(-2%, -1%, 0) scale(1);
    }

    to {
        transform: translate3d(3%, 2%, 0) scale(1.12);
    }
}

/* Dark tinted glass for floating chrome (the app bar, the mobile bottom nav). Tints with the scope's
   own --vp-bg, so it belongs on a `.vp-sig` element. Without backdrop-filter it falls back to a
   near-opaque ground and still reads; the hairline and the inset top highlight give the edge. Does
   not clip overflow, so popovers anchored inside it stay visible. */
.vp-glass {
    border: 1px solid var(--vp-line-2);
    background-color: color-mix(in srgb, var(--vp-bg) 94%, transparent);
    box-shadow:
        0 var(--space-xs) var(--space-lg) color-mix(in srgb, var(--c-canvas) 45%, transparent),
        inset 0 1px 0 color-mix(in srgb, var(--vp-ink) 8%, transparent);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .vp-glass {
        /* 88%, not the sister brand's 62%: Smečka is dark end to end, but here the bar also floats
           over the paper workspace, where a thinner tint turns a muddy grey instead of dark glass. */
        background-color: color-mix(in srgb, var(--vp-bg) 88%, transparent);
        -webkit-backdrop-filter: blur(20px) saturate(160%);
        backdrop-filter: blur(20px) saturate(160%);
    }

    @media (prefers-reduced-transparency: reduce) {
        .vp-glass {
            background-color: color-mix(in srgb, var(--vp-bg) 94%, transparent);
            -webkit-backdrop-filter: none;
            backdrop-filter: none;
        }
    }
}

/* Tech / trust-diagram panels — always used inside a `.vp-sig` region. */
.vp-panel--tech {
    border: 1px solid var(--c-cloud-blue);
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, var(--c-ink-800), var(--c-ink-cool));
}

.vp-panel--haven {
    border: 1px solid var(--c-gold-200);
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, var(--c-ink-800), var(--c-ink-ember));
}

.vp-track {
    position: absolute;
    left: 28px;
    right: 28px;
    top: 27px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--c-cloud-cyan), var(--c-holo-violet) 50%, var(--c-cloud-blue));
    box-shadow: 0 0 12px rgb(77 208 225 / .35);
}

.vp-node {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--c-ink-cool);
    border: 1px solid var(--vp-line-2);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 14px;
    color: var(--vp-muted);
}

.vp-node--active {
    border-color: var(--vp-cyan);
    color: var(--vp-cyan);
    box-shadow: 0 0 16px rgb(95 168 201 / .45);
}

@media (prefers-reduced-motion: reduce) {

    .vp-holo,
    .vp-wash,
    .vp-ring,
    .vp-ring-holo,
    .vp-ambient::before {
        animation: none;
    }
}

/* --- 3. Fonts -----------------------------------------------------------
   Fraunces (display, variable — opsz/wght/SOFT/WONK, SIL OFL 1.1, fonts/Fraunces-OFL.txt), Geist
   (body) and Geist Mono, all vendored under wwwroot/fonts — no font CDN at runtime. Split into a
   latin and a latin-ext file per family/style so a Czech page (which needs latin-ext for diacritics)
   never pays for the glyphs a purely-ASCII page would not use, and vice versa. */

@font-face {
    font-family: "Fraunces";
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url("fonts/fraunces-var-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
        U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Fraunces";
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url("fonts/fraunces-var-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Fraunces";
    font-style: italic;
    font-weight: 300 700;
    font-display: swap;
    src: url("fonts/fraunces-italic-var-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
        U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Fraunces";
    font-style: italic;
    font-weight: 300 700;
    font-display: swap;
    src: url("fonts/fraunces-italic-var-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Geist";
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url("fonts/geist-var-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
        U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Geist";
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url("fonts/geist-var-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Geist Mono";
    font-style: normal;
    font-weight: 400 500;
    font-display: swap;
    src: url("fonts/geist-mono-var-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
        U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Geist Mono";
    font-style: normal;
    font-weight: 400 500;
    font-display: swap;
    src: url("fonts/geist-mono-var-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- 4. Type & layout utilities ------------------------------------------ */

.vp-display {
    font-family: var(--font-display);
    font-optical-sizing: auto;
    font-variation-settings: "SOFT" 20, "WONK" 1;
    color: var(--vp-ink);
    font-weight: 400;
    letter-spacing: -0.015em;
    margin: 0;
}

.vp-h1 {
    font-size: var(--step-hero);
    line-height: 1.03;
}

.vp-h2 {
    font-size: var(--step-title);
    line-height: 1.1;
}

.vp-h3 {
    font-size: var(--step-2);
    line-height: 1.15;
}

.vp-mono {
    font-family: var(--font-mono);
    letter-spacing: 0.08em;
}

.vp-eyebrow {
    display: block;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--vp-copper);
}

.vp-muted {
    color: var(--vp-muted);
}

.vp-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* A small set of one-property spacing utilities — the alternative to inline styles (src/Verapet.ClientShared/AGENTS.md §3)
   wherever a page needs one extra nudge that isn't already a named block's own rule. */
.vp-mt-md {
    margin-top: var(--space-md);
}

.vp-link-strong {
    font-weight: 500;
}

.vp-container {
    max-width: 1280px;
    margin-inline: auto;
    padding-inline: clamp(16px, 4vw, 96px);
}

/* A single narrow state card (404, error, cat-listings-coming-soon) — narrower than the page's own
   .vp-container so a one-line message doesn't stretch full width. */
.vp-container--narrow {
    max-width: 34rem;
}

/* The Supporters pages (/podporovatele and its checkout): one narrow column of cards, shared here
   rather than repeated in each page's scoped stylesheet. */
.supporters-page {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xl);
    width: 100%;
    max-width: 34rem;
    margin-inline: auto;
}

/* The vertical rhythm a full-bleed .vp-sig/.vp-work band wants for its own .vp-container content,
   independent of the page's own padding-block (§ Layout — MainLayout). */
.vp-container--band {
    padding-block: var(--space-2xl);
}

/* The page's own vertical rhythm. A section that needs the full viewport width (a `.vp-sig` hero,
   the trust diagram, the shelters band) sets `.vp-bleed` on itself and re-establishes `.vp-container`
   inside for its content — the standard `margin-inline: calc(50% - 50vw)` breakout, which works
   nested inside a centered `.vp-container` because nothing between it and the viewport clips
   overflow-x. This is the one mechanism every full-bleed section in this file uses. */
.vp-page {
    padding-block: var(--space-2xl) var(--space-2xl);
    display: flex;
    flex-direction: column;
    gap: var(--space-2xl);
}

/* A full-bleed section (.vp-bleed) that opens or closes the page must sit flush against the header
   or footer, not leave the page's own vertical padding as a light strip above/below it. */
.vp-page:has(> .vp-bleed:first-child) {
    padding-top: 0;
}

.vp-page:has(> .vp-bleed:last-child) {
    padding-bottom: 0;
}

/* The page's flex gap would show a light strip between two adjacent full-bleed bands. */
.vp-page > .vp-bleed + .vp-bleed {
    margin-top: calc(-1 * var(--space-2xl));
}

/* Under the floating app bar the page scrolls beneath the glass, so it reserves the bar's space
   itself: a plain page pads down, a page opening with a full-bleed band lets that band run up behind
   the bar and pads inside it. */
.vp-app--bar .vp-page {
    padding-top: calc(var(--vp-bar-clear) + var(--space-xl));
}

.vp-app--bar .vp-page > .vp-bleed:first-child {
    padding-top: var(--vp-bar-clear);
}

.vp-bleed {
    margin-inline: calc(50% - 50vw);
    width: 100vw;
}

.vp-stack {
    display: flex;
    flex-direction: column;
    gap: var(--gap, var(--space-md));
}

.vp-cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap, var(--space-sm));
}

.vp-grid {
    display: grid;
    gap: var(--space-lg);
    grid-template-columns: 1fr;
}

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

.vp-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.vp-grid--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.vp-grid--5 {
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

@media (max-width: 1023px) {

    .vp-grid--4,
    .vp-grid--5 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {

    .vp-grid--2,
    .vp-grid--3,
    .vp-grid--4,
    .vp-grid--5 {
        grid-template-columns: 1fr;
    }
}

.vp-table {
    width: 100%;
    border-collapse: collapse;
}

.vp-table th {
    font-family: var(--font-mono);
    text-transform: uppercase;
    font-size: 11px;
    letter-spacing: var(--tracking-wide);
    color: var(--vp-muted);
    text-align: left;
    padding: 12px 16px;
}

.vp-table td {
    padding: 12px 16px;
    border-top: 1px solid var(--vp-line);
}

.vp-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--vp-tile-2);
    flex-shrink: 0;
}

.vp-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--vp-copper);
    color: var(--vp-btn-ink);
    font-family: var(--font-mono);
    font-size: 11px;
}

.vp-icon {
    flex-shrink: 0;
}

.vp-mark {
    display: inline-block;
    flex: none;
    vertical-align: middle;
    --vp-mark-paper: var(--vp-tile);
}

.vp-animal-card__media .vp-mark {
    --vp-mark-paper: var(--vp-photo);
}

/* --- 5. Primitives -------------------------------------------------------
   Ui/*.razor render exactly these classes; every colour reference below is a --vp-* semantic token. */

.vp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font: inherit;
    font-weight: 600;
    border-radius: 10px;
    border: 0;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: transform var(--duration-fast) var(--ease-out), background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}

.vp-btn:active {
    transform: scale(0.97);
}

.vp-btn:disabled,
.vp-btn[aria-disabled="true"] {
    cursor: not-allowed;
    opacity: 0.5;
    pointer-events: none;
}

.vp-btn--sm {
    height: 36px;
    padding: 0 16px;
    font-size: var(--step--1);
}

.vp-btn--md {
    height: 44px;
    padding: 0 22px;
    font-size: var(--step-0);
}

.vp-btn--lg {
    height: 52px;
    padding: 0 28px;
    font-size: var(--step-1);
}

.vp-btn--full {
    width: 100%;
}

.vp-btn--primary {
    background: var(--vp-btn);
    color: var(--vp-btn-ink);
}

.vp-btn--secondary {
    background: transparent;
    color: var(--vp-ink);
    border: 1px solid var(--vp-line-2);
}

.vp-btn--ghost {
    background: transparent;
    color: var(--vp-copper);
    padding-inline: 4px;
}

.vp-btn--ring {
    color: var(--vp-ink);
}

/* .vp-btn's own `border: 0` (below) is a single-class rule declared after .vp-ring's (§2 Effects,
   earlier in the file) and wins the cascade at equal specificity, silently cancelling the gradient
   ring's `border: 1px solid transparent` — the ring background has no border-box left to paint into.
   The two-class selector here outranks both and restores it, regardless of source order. */
.vp-btn.vp-ring {
    border: 1px solid transparent;
}

.vp-logo {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: inherit;
}

.vp-logo__mark {
    flex-shrink: 0;
    display: block;
}

.vp-logo__word {
    font-size: 21px;
}

.vp-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    border: 1px solid currentColor;
    background: color-mix(in srgb, currentColor 12%, transparent);
    line-height: 1.6;
    /* A pill must size to its own content even inside a flex-column parent (the home entry tiles,
       AnimalCard, the shelters band) — without this it stretches to the parent's cross-axis width. */
    align-self: flex-start;
    justify-self: start;
    width: fit-content;
}

/* A pill doubling as a toggle button (the Marketplace quick filters) needs a selected state that
   doesn't depend on colour alone: a darker fill plus a bolder border. Padding drops by the same 1px
   the border grows on each side (border-box sizing) so the pill doesn't change size when it toggles. */
.vp-pill[aria-pressed="true"] {
    background: color-mix(in srgb, currentColor 20%, transparent);
    border-width: 2px;
    padding: 2px 9px;
}

.vp-pill--copper {
    color: var(--vp-copper);
}

.vp-pill--gold {
    color: var(--vp-gold);
}

.vp-pill--violet {
    color: var(--vp-violet);
}

.vp-pill--cyan {
    color: var(--vp-cyan);
}

.vp-pill--muted {
    color: var(--vp-muted);
}

.vp-pill--ink {
    color: var(--vp-ink);
}

.vp-pill--danger {
    color: var(--vp-danger);
}

.vp-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* Md (24px) is VpCard's own default Padding — set here too, on the base class, not only on
       `.vp-card--pad-*`, so a plain `class="vp-card"` element (several pages compose one by hand
       rather than through the component) is padded exactly the same way the component would render
       it. `.vp-card--pad-sm/lg` below still override it; `.vp-litter`/`.vp-animal-card` zero it back
       out because those manage their own inner padding around an edge-to-edge photo. */
    padding: 24px;
    border-radius: var(--radius-lg);
    background: var(--vp-tile);
    border: 1px solid var(--vp-line);
    box-shadow: var(--vp-shadow);
    /* `color: inherit` would tie `.vp-sig, .vp-work { color: var(--vp-body) }` (§1) on specificity
       and lose to source order when a card carries its own `.vp-work`/`.vp-sig` class (a workspace
       card sitting inside a signature backdrop, e.g. the Auth card) — the card would then keep the
       ambient scope's text colour instead of its own. `var(--vp-body)` reads the same custom
       property, but resolves it locally, so a card that switches scope switches its text colour
       with it, and a card that does not still inherits the ambient value exactly as before. */
    color: var(--vp-body);
    text-decoration: none;
}

a.vp-card {
    transition: transform var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}

a.vp-card:hover {
    transform: translateY(-2px);
    border-color: var(--vp-line-2);
}

.vp-card--flat {
    box-shadow: none;
}

/* Ring cards get their fill and border from `.vp-ring`/`.vp-ring-holo` (§2) — this rule only clears
   the plain card's own border so the two do not fight. */
.vp-card--ring,
.vp-card--ring-holo {
    border-color: transparent;
    box-shadow: none;
}

.vp-card--pad-sm {
    padding: 16px;
}

.vp-card--pad-md {
    padding: 24px;
}

.vp-card--pad-lg {
    padding: 32px;
}

.vp-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.vp-field__label {
    font-size: 13px;
    color: var(--vp-muted);
}

.vp-field__required {
    color: var(--vp-danger);
}

.vp-field__hint {
    margin: 0;
    font-size: 13px;
    color: var(--vp-muted);
}

.vp-field__error,
.validation-message,
.validation-errors {
    margin: 0;
    font-size: 13px;
    color: var(--vp-danger);
}

.vp-input,
.vp-select {
    height: 48px;
    padding: 0 14px;
    background: var(--vp-field);
    color: var(--vp-ink);
    /* --vp-field-line, not --vp-line-2: a control boundary needs 3:1 against its own background
      ; --vp-line-2 is tuned for a decorative hairline contrast, not a functional one. */
    border: 1px solid var(--vp-field-line);
    border-radius: 10px;
    font: inherit;
    font-size: 16px;
    width: 100%;
}

.vp-input:focus-visible,
.vp-select:focus-visible {
    outline: none;
    border-color: var(--vp-copper);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--vp-copper) 20%, transparent);
}

.vp-input.invalid,
.vp-select.invalid,
.vp-input[aria-invalid="true"],
.vp-select[aria-invalid="true"] {
    border-color: var(--vp-danger);
}

.vp-check {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    cursor: pointer;
}

.vp-checkbox {
    width: 18px;
    height: 18px;
    border: 1px solid var(--vp-field-line);
    border-radius: 4px;
    background: var(--vp-field);
    accent-color: var(--vp-copper);
}

/* /register's account-type choice (Buyer/Breeder/Shelter) reuses .vp-checkbox on <input
   type="radio">; without this it inherits the square 4px radius above. */
input[type="radio"].vp-checkbox {
    border-radius: 50%;
}

.vp-checkbox:checked {
    border-color: var(--vp-copper);
}

.vp-checkbox:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--vp-copper) 20%, transparent);
}

.vp-alert {
    display: flex;
    gap: 12px;
    padding: 16px;
    border-radius: var(--radius-md);
    border: 1px solid currentColor;
}

.vp-alert__body {
    min-width: 0;
    overflow-wrap: anywhere;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.vp-alert__title {
    margin: 0;
    font-weight: 600;
    color: var(--vp-ink);
}

.vp-alert__content {
    color: var(--vp-body);
}

.vp-alert--info {
    color: var(--vp-cyan);
    background: color-mix(in srgb, var(--vp-cyan) 8%, transparent);
}

.vp-alert--success {
    color: var(--vp-cyan);
    background: color-mix(in srgb, var(--vp-cyan) 8%, transparent);
}

.vp-alert--warning {
    color: var(--vp-gold);
    background: color-mix(in srgb, var(--vp-gold) 8%, transparent);
}

.vp-alert--error {
    color: var(--vp-danger);
    background: color-mix(in srgb, var(--vp-danger) 8%, transparent);
}

.vp-skeleton {
    display: inline-block;
    /* Per-instance size is a custom-property setter (the inline custom-property exception, like the VpMenu
       anchor names), not a raw inline style — VpSkeleton sets --vp-skel-w/-h, this reads them. */
    width: var(--vp-skel-w, 100%);
    height: var(--vp-skel-h, 1em);
    background: linear-gradient(90deg, var(--vp-tile-2) 25%, var(--vp-line) 50%, var(--vp-tile-2) 75%);
    background-size: 200% 100%;
    animation: vp-shimmer 1.6s ease-in-out infinite;
}

.vp-skeleton--text {
    border-radius: 4px;
}

.vp-skeleton--rect {
    border-radius: var(--radius-md);
}

.vp-skeleton--circle {
    border-radius: 50%;
}

@keyframes vp-shimmer {
    from {
        background-position: 200% 0;
    }

    to {
        background-position: -200% 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .vp-skeleton {
        animation: none;
    }
}

.vp-menu {
    margin: 0;
    padding: 8px;
    border: 1px solid var(--vp-line);
    border-radius: var(--radius-md);
    background: var(--vp-tile);
    box-shadow: var(--vp-shadow);
    min-width: 220px;
    flex-direction: column;
    gap: 2px;

    /* Anchor positioning where supported. The anchor NAME itself is per-instance (VpMenu sets it
       inline as --vp-menu-{Id}) so two menu instances on one page don't fight over a shared
       anchor; only the positioning mechanics — which side, which offset — are the same for all of
       them and belong here. */
    position: absolute;
    inset: auto;
    top: anchor(bottom);
    right: anchor(right);
    margin-top: 8px;
}

@supports not (position-anchor: --a) {
    .vp-menu {
        position: fixed;
        inset: calc(var(--vp-bar-clear) - var(--vp-bar-gap)) 16px auto auto;
    }
}

/* A popover's UA stylesheet rule is `display: none` while closed; both states are stated explicitly
   here so an author rule can never again silently re-hide `:popover-open` or leave the closed state
   visible — `.vp-menu { display: flex }` used to do exactly the latter, all the time. */
.vp-menu:popover-open {
    display: flex;
}

.vp-menu:not(:popover-open) {
    display: none;
}

.vp-menu__trigger {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: inherit;
    background: transparent;
    border: 0;
    color: inherit;
    cursor: pointer;
    padding: 8px 10px;
    border-radius: 10px;
}

.vp-menu__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 0;
    background: transparent;
    font: inherit;
    text-align: left;
    color: var(--vp-body);
    cursor: pointer;
    width: 100%;
}

.vp-menu__item:hover {
    background: var(--vp-tile-2);
}

/* --- 6. Layout — MainLayout ------------------------------------------- */

.vp-app {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    /* `100vw` on .vp-bleed is the viewport width including the area a classic (non-overlay)
       scrollbar occupies, which is wider than the actually visible, scrollable area — clip it here
       rather than trying to size .vp-bleed around a scrollbar that may or may not be there. */
    overflow-x: clip;
}

/* The paper app paints its own ground: the body is transparent (see the html rule) so the canvas,
   not the paper, shows wherever a phone over-scrolls past the page. */
.vp-app--bar {
    background: var(--vp-bg);
}

.vp-topbar {
    /* Fixed, not sticky: the bar floats over the page instead of taking a row in it, so content
       scrolls beneath the glass and `.vp-app--bar .vp-page` reserves the space instead. */
    position: fixed;
    inset-inline: 0;
    top: calc(env(safe-area-inset-top) + var(--vp-bar-gap));
    z-index: 20;
    box-sizing: border-box;
    width: min(100% - 2 * clamp(16px, 4vw, 96px), 1280px - 2 * clamp(16px, 4vw, 96px));
    height: var(--vp-bar-h);
    margin-inline: auto;
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding-inline: var(--space-md);
    border-radius: var(--radius-lg);
}

.vp-topbar__nav {
    display: flex;
    gap: var(--space-2xs);
    flex-grow: 1;
    margin-inline-start: var(--space-md);
}

.vp-topbar__link {
    position: relative;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-pill);
    color: var(--vp-body);
    font-size: var(--step--1);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transition: color var(--duration-fast) var(--ease-out), background-color var(--duration-fast) var(--ease-out);
}

.vp-topbar__link:hover {
    color: var(--vp-ink);
    background-color: color-mix(in srgb, var(--vp-ink) 6%, transparent);
}

.vp-topbar__link--active {
    color: var(--vp-ink);
}

.vp-topbar__link--active::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 2px;
    width: 4px;
    height: 4px;
    margin-inline: auto;
    border-radius: 50%;
    background: var(--vp-copper);
}

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

@media (max-width: 767px) {
    .vp-topbar__nav {
        display: none;
    }
}

/* Phones keep both "Přihlásit se" and "Registrace" in the app bar: most visitors arrive on a phone and
   registering is what they came to do. The pair stays on one line, and below 420px the wordmark gives
   way to the logo mark (the link keeps its "Verapet – domů" label) so neither button clips. */
@media (max-width: 639px) {
    .vp-topbar .vp-cluster {
        flex-wrap: nowrap;
        gap: 4px;
    }

    .vp-topbar .vp-btn {
        white-space: nowrap;
    }

    .vp-topbar .vp-btn--primary {
        padding-inline: 16px;
    }
}

@media (max-width: 419px) {
    .vp-topbar .vp-logo__word {
        display: none;
    }
}

.vp-main {
    flex: 1;
}

.vp-footer {
    padding-block: var(--space-2xl);
    border-top: 1px solid var(--vp-line);
    font-size: 14px;
    color: var(--vp-muted);
}

/* Footer content lines up with the page's own .vp-container — same max-width, same inline padding
   — instead of running its own (narrower-looking) padding-inline edge to edge. */
.vp-footer__inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-md);
}

.vp-footer__brand {
    max-width: 540px;
}

.vp-footer__word {
    font-size: 22px;
}

.vp-footer__text {
    max-width: 540px;
}

/* The Mezi chlupy logo: a raster drawing on a transparent background, sized as a sign-off, not a
   second masthead. Opacity lifts to full on hover/focus so it reads as the link it is. */
.vp-footer__sister {
    align-self: center;
    opacity: 0.88;
    transition: opacity var(--duration-fast) var(--ease-out);
}

.vp-footer__sister:hover,
.vp-footer__sister:focus-visible {
    opacity: 1;
}

.vp-footer__sister img {
    display: block;
    width: 160px;
    height: auto;
}

.vp-bottomnav {
    display: none;
}

@media (max-width: 767px) {
    .vp-bottomnav {
        display: block;
        position: fixed;
        inset-inline: var(--vp-bar-gap);
        bottom: calc(env(safe-area-inset-bottom) + var(--vp-bar-gap));
        z-index: 20;
        padding: 6px clamp(8px, 3vw, 24px);
        border-radius: var(--radius-lg);
    }

    /* Room for the floating bottom nav so the last section of a page is never hidden behind it. */
    .vp-page {
        padding-bottom: calc(var(--space-2xl) + 64px);
    }

    .vp-app--bar .vp-page {
        padding-bottom: calc(var(--space-2xl) + 64px + var(--vp-bar-gap));
    }

    .vp-app--bar .vp-footer {
        padding-bottom: calc(var(--space-2xl) + 64px + var(--vp-bar-gap) + env(safe-area-inset-bottom));
    }
}

.vp-bottomnav__track {
    position: relative;
    display: flex;
}

/* One indicator slides to the active slot. The layout sets --vp-bottomnav-count (how many items the role gets)
   and --vp-bottomnav-active (the active index, -1 when the page is none of them) on the nav. */
.vp-bottomnav__indicator {
    position: absolute;
    top: 2px;
    left: 0;
    width: calc(100% / var(--vp-bottomnav-count, 1));
    height: 3px;
    border-radius: var(--radius-pill);
    background: var(--vp-copper);
    transform: translateX(calc(100% * var(--vp-bottomnav-active, 0)));
    transition: transform var(--duration-slow) var(--ease-out);
}

.vp-bottomnav[data-active="-1"] .vp-bottomnav__indicator {
    opacity: 0;
}

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

.vp-bottomnav__item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 8px 4px;
    color: var(--vp-muted);
    font-size: 11px;
    border-radius: 10px;
}

.vp-bottomnav__item--active {
    color: var(--vp-copper);
}

/* --- 7. Page furniture --------------------------------------------------- */

.vp-page-head {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    max-width: var(--measure);
}

.vp-lede {
    margin: 0;
    font-size: var(--step-1);
    color: var(--vp-muted);
    max-width: var(--measure);
}

.vp-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
}

.vp-section-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: var(--space-lg);
    flex-wrap: wrap;
}

.vp-state {
    align-items: center;
    text-align: center;
    padding: var(--space-2xl) var(--space-lg);
    gap: 10px;
}

.vp-state > .vp-pill {
    align-self: center;
}

.vp-litter-dots {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.vp-litter-dots__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--vp-field-line);
}

.vp-litter-dots__dot--free {
    background: var(--vp-copper);
}

.vp-litter-dots__text {
    margin-inline-start: 5px;
    font-size: 13px;
    color: var(--vp-muted);
}

.vp-state__mark {
    color: var(--vp-muted);
}

.vp-state__code {
    font-family: var(--font-mono);
    font-size: 56px;
    color: var(--vp-line-2);
}

.vp-state__title {
    margin: 0;
}

.vp-state__body {
    margin: 0;
    max-width: 34rem;
}

.vp-state__actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: var(--space-sm);
}

/* --- 8. Home ("/") -------------------------------------------------------- */

.vp-hero {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xl);
    padding-block: var(--space-2xl);
}

.vp-hero__intro {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    max-width: 940px;
}

.vp-hero__lede {
    margin: 0;
    font-size: 20px;
    max-width: 640px;
    color: var(--vp-body);
}

.vp-entry-tile {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 32px;
    border-radius: var(--radius-lg);
    color: var(--vp-body);
}

/* The hero entry tiles aren't .vp-ring, so they paint their own tile background and border. */
.vp-entry-tile--plain {
    background: var(--vp-tile);
    border: 1px solid var(--vp-line-2);
}

/* The adoption tile is copper-toned but no longer the region's primary action (the search bar holds the ring). */
.vp-entry-tile--adopt {
    background: var(--vp-tile);
    border: 1px solid color-mix(in srgb, var(--vp-copper) 55%, transparent);
}

.vp-entry-tile__title {
    font-size: var(--step-2);
}

.vp-entry-tile__link {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 500;
    margin-top: 8px;
}

.vp-entry-tile__link--copper {
    color: var(--vp-copper);
}

.vp-entry-tile__link--gold {
    color: var(--vp-gold);
}

.vp-hero__search {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.vp-search {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
}

/* Species: native radios, visually hidden but focusable; the label's pill is what is seen. */
.vp-segmented {
    display: inline-flex;
    gap: 4px;
    margin: 0;
    padding: 4px;
    min-width: 0;
    border: 1px solid var(--vp-field-line);
    border-radius: 999px;
    background: var(--vp-field);
}

.vp-segmented__option {
    position: relative;
    display: inline-flex;
    cursor: pointer;
}

.vp-segmented__option input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

.vp-segmented__option span {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    padding: 0 18px;
    border-radius: 999px;
    font-size: 15px;
    font-weight: 500;
    color: var(--vp-body);
    transition: background-color .15s ease, color .15s ease;
}

.vp-segmented__option:hover span {
    color: var(--vp-ink);
}

.vp-segmented__option input:checked + span {
    /* Neutral, not copper: copper means shelter/adoption (AGENTS.md §4) and a species is neither. */
    background: var(--vp-btn);
    color: var(--vp-btn-ink);
}

.vp-segmented__option input:focus-visible + span {
    outline: 2px solid var(--vp-copper);
    outline-offset: 2px;
}

/* One rounded bar holding region, breed and the submit button. The .vp-ring on it supplies the boundary,
   which clears 3:1 only on a dark (.vp-sig) surface — on paper give it a --vp-field-line border instead. */
.vp-search__bar {
    display: flex;
    align-items: stretch;
    gap: 6px;
    width: 100%;
    max-width: 880px;
    padding: 6px;
    transition: box-shadow .15s ease;
}

.vp-search__bar:focus-within {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--vp-copper) 25%, transparent);
}

.vp-search__field {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-width: 0;
    padding: 6px 16px;
    border-radius: calc(var(--radius-lg) - 6px);
    cursor: text;
}

.vp-search__field + .vp-search__field::before {
    content: "";
    position: absolute;
    inset-block: 10px;
    inset-inline-start: -4px;
    border-inline-start: 1px solid var(--vp-line-2);
}

.vp-search__field:first-child {
    flex: 0 1 260px;
}

.vp-search__field--query {
    flex: 1 1 auto;
}

.vp-search__label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--vp-muted);
}

.vp-search__control {
    width: 100%;
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--vp-ink);
    font: inherit;
    font-size: 16px;
    text-overflow: ellipsis;
}

.vp-search__control:focus,
.vp-search__control:focus-visible {
    outline: none;
}

.vp-search__control option {
    background: var(--vp-field);
    color: var(--vp-ink);
}

.vp-search__control::placeholder {
    color: var(--vp-muted);
    opacity: 1;
}

.vp-search__field:focus-within {
    background: color-mix(in srgb, var(--vp-ink) 6%, transparent);
    /* The control's own outline is removed above; this is the visible focus indicator, the same solid
       copper the house .vp-input/.vp-select focus uses, drawn inside the field so the bar's shape holds. */
    box-shadow: inset 0 0 0 2px var(--vp-copper);
}

@media (max-width: 639px) {
    .vp-search__bar {
        flex-direction: column;
    }

    .vp-search__field:first-child {
        flex: 1 1 auto;
    }

    .vp-search__field + .vp-search__field::before {
        inset-block: -4px auto;
        inset-inline: 16px;
        border-inline-start: 0;
        border-block-start: 1px solid var(--vp-line-2);
    }

    .vp-search__bar .vp-btn {
        width: 100%;
    }
}

.vp-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
}

.vp-chips__label {
    font-size: 14px;
    color: var(--vp-muted);
}

.vp-chip {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 0 14px;
    border: 1px solid var(--vp-line-2);
    border-radius: 999px;
    background: color-mix(in srgb, var(--vp-ink) 4%, transparent);
    color: var(--vp-body);
    font-size: 14px;
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.vp-chip:hover {
    /* Neutral, not copper: a breed means neither shelter nor adoption (AGENTS.md §4). */
    background: color-mix(in srgb, var(--vp-ink) 8%, transparent);
    border-color: var(--vp-ink);
    color: var(--vp-ink);
}

/* Forced colours replace backgrounds, which is all that marks the checked species pill — give it a
   system-colour outline instead so the selection stays visible. */
@media (forced-colors: active) {
    .vp-segmented__option input:checked + span {
        outline: 2px solid CanvasText;
        outline-offset: -2px;
    }

    /* Forced colours also drop box-shadows, which carry the search's focus rings — mark focus with the
       system Highlight instead, outside the checked outline so the two stay distinguishable. */
    .vp-segmented__option input:focus-visible + span {
        outline: 2px solid Highlight;
        outline-offset: 2px;
    }

    .vp-search__field:focus-within {
        outline: 2px solid Highlight;
    }
}

@media (prefers-reduced-motion: reduce) {

    .vp-segmented__option span,
    .vp-search__bar,
    .vp-chip {
        transition: none;
    }
}

.vp-diagram {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xl);
    padding: var(--space-2xl);
}

.vp-diagram__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: var(--space-2xl);
    flex-wrap: wrap;
}

.vp-diagram__aside {
    margin: 0;
    max-width: 420px;
    color: var(--vp-muted);
}

.vp-diagram__nodes {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-lg);
}

.vp-diagram__node {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.vp-diagram__node-title {
    font-size: 24px;
}

.vp-diagram__node-body {
    margin: 0;
    color: var(--vp-muted);
    font-size: 15px;
}

/* Phone: a vertical timeline. Each step is a row (node | title + body), and a connector runs down the
   node column from one node to the next, so the line never crosses text. */
@media (max-width: 767px) {
    .vp-diagram {
        gap: var(--space-xl);
        padding: var(--space-md);
    }

    .vp-diagram__nodes {
        grid-template-columns: 1fr;
        gap: var(--space-lg);
    }

    .vp-track {
        display: none;
    }

    .vp-diagram__node {
        display: grid;
        grid-template-columns: 56px minmax(0, 1fr);
        column-gap: 16px;
        row-gap: 6px;
        align-items: start;
    }

    .vp-diagram__node > .vp-node {
        grid-row: 1 / span 2;
    }

    .vp-diagram__node-title {
        min-height: 56px;
        display: flex;
        align-items: center;
    }

    .vp-diagram__node:not(:last-child)::before {
        content: "";
        position: absolute;
        left: 27px;
        top: 56px;
        bottom: calc(-1 * var(--space-lg));
        width: 2px;
        border-radius: 2px;
        background: linear-gradient(180deg, var(--c-cloud-cyan), var(--c-holo-violet));
        box-shadow: 0 0 12px rgb(77 208 225 / .35);
    }
}

.vp-animal-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Zero out .vp-card's own default padding — the photo goes edge-to-edge; .vp-animal-card__body
       carries its own inner padding. */
    padding: 0;
}

.vp-animal-card {
    position: relative;
    transition: transform var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}

.vp-animal-card:hover {
    transform: translateY(-2px);
    border-color: var(--vp-line-2);
}

.vp-animal-card__link,
.vp-animal-card__link:hover {
    color: inherit;
    text-decoration: none;
}

.vp-animal-card__link::after {
    content: "";
    position: absolute;
    inset: 0;
}

.vp-animal-card__link:focus-visible {
    outline: none;
}

.vp-animal-card__link:focus-visible::after {
    outline: 2px solid var(--vp-copper);
    outline-offset: -2px;
    border-radius: var(--radius-lg);
}

.vp-animal-card__body a:not(.vp-animal-card__link) {
    position: relative;
    z-index: 1;
}

.vp-animal-card__media {
    height: 300px;
    background: var(--vp-photo);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    color: var(--vp-line-2);
}

.vp-animal-card__body {
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.vp-animal-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.vp-animal-card__placeholder-caption {
    font-size: 11px;
}

.vp-animal-card__title {
    font-size: 27px;
}

.vp-animal-card__meta {
    font-size: 14px;
    color: var(--vp-muted);
}

.vp-listing-card__price {
    font-family: var(--font-display);
    font-size: 20px;
    color: var(--vp-ink);
}

.vp-listing-card__seller {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    color: var(--vp-body);
}

.vp-badge-glyphs,
.vp-listing-card__seller .vp-pill {
    position: relative;
    z-index: 1;
}

.vp-badge-glyphs {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--vp-gold);
}

.vp-badge-glyphs > span[title] {
    display: inline-flex;
    cursor: help;
}

/* The Verapet Supporters badge: its own warm rose, deliberately not a verification tone (gold/cyan),
   because a subscription is not a check Verapet made. Same pill geometry as .vp-pill. */
.vp-supporter-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    border: 1px solid currentColor;
    color: var(--vp-supporter);
    background: color-mix(in srgb, currentColor 12%, transparent);
    line-height: 1.6;
    cursor: help;
    position: relative;
    z-index: 1;
}

.vp-supporter-badge--compact {
    padding: 1px 8px;
    text-transform: none;
}

.vp-badge-list__text,
.vp-listing-detail__note {
    margin: 4px 0 0;
    font-size: var(--step--1);
}

.vp-seller__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: flex-start;
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: var(--vp-tile);
    border: 1px solid var(--vp-line);
}

.vp-seller__mark--shelter {
    color: var(--vp-copper);
}

.vp-seller__mark--breeder {
    color: var(--vp-gold);
}

.vp-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-md);
}

.vp-facts {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 10px var(--space-lg);
    margin: 0;
}

.vp-facts dt {
    color: var(--vp-muted);
}

.vp-facts dd {
    margin: 0;
    color: var(--vp-ink);
}

.vp-listing-detail {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: var(--space-lg);
    align-items: start;
}

@media (max-width: 767px) {
    .vp-listing-detail {
        grid-template-columns: 1fr;
    }
}

.vp-listing-detail__price {
    font-family: var(--font-display);
    font-size: var(--step-2);
    color: var(--vp-ink);
}

.vp-listing-detail__description {
    white-space: pre-line;
}

/* The sign-in wall under a listing teaser: skeleton shapes blurred, the sign-in card overlapping its top.
   Both share one grid cell; the card sits above the blur (the blur's filter makes its own stacking context). */
.vp-gate {
    display: grid;
    margin-top: var(--space-lg);
}

.vp-gate > * {
    grid-area: 1 / 1;
}

.vp-gate__blur {
    filter: blur(6px);
    opacity: .7;
    pointer-events: none;
    user-select: none;
}

.vp-gate__card {
    position: relative;
    z-index: 1;
    align-self: start;
    justify-self: center;
    width: min(100%, 26rem);
    margin-block: var(--space-md) 0;
    margin-inline: auto;
    text-align: center;
    box-shadow: var(--vp-shadow);
}

.vp-gate__card .vp-cluster {
    justify-content: center;
}

.vp-photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: var(--space-md);
}

.vp-photo-grid__item {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    min-width: 0;
}

.vp-photo-grid__item img {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--radius-md);
    background: var(--vp-photo);
}

.vp-gallery {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    min-width: 0;
}

.vp-gallery--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 240px;
    background: var(--vp-photo);
    border-radius: var(--radius-lg);
    color: var(--vp-line-2);
    --vp-mark-paper: var(--vp-photo);
}

.vp-gallery__main {
    width: 100%;
    height: auto;
    max-height: 70vh;
    object-fit: contain;
    border-radius: var(--radius-md);
    background: var(--vp-photo);
}

.vp-gallery__strip {
    display: flex;
    gap: var(--space-sm);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: var(--space-xs);
}

.vp-gallery__strip li {
    flex: none;
    scroll-snap-align: start;
}

.vp-gallery__strip img {
    display: block;
    width: 96px;
    height: 72px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--vp-photo);
}

@media (prefers-reduced-motion: no-preference) {
    .vp-gallery__strip {
        scroll-behavior: smooth;
    }
}

.vp-listing-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
}

.vp-list-plain {
    list-style: none;
    margin: 0;
    padding: 0;
}

.vp-listing-row__close {
    flex-basis: 100%;
}

.vp-listing-row__main {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.vp-shelters {
    padding: var(--space-2xl);
}

@media (max-width: 767px) {
    .vp-shelters {
        padding: var(--space-md);
    }
}

.vp-shelters__copy {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.vp-shelters__body {
    margin: 0;
    font-size: 18px;
    max-width: 520px;
}

.vp-shelters__actions {
    margin-top: 8px;
}

/* --- 9. Ported components ------------------------------------------------- */

.vp-account-menu {
    display: inline-flex;
    align-items: center;
}

.vp-logout-form {
    margin: 0;
}

.vp-logout-button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 12px;
    border: 0;
    background: transparent;
    font: inherit;
    text-align: left;
    color: var(--vp-body);
    cursor: pointer;
    border-radius: 8px;
}

.vp-logout-button:hover {
    background: var(--vp-tile-2);
}

.vp-escrow {
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
}

.vp-escrow__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--space-md);
}

.vp-escrow__status {
    display: flex;
    align-items: center;
    gap: 12px;
}

.vp-escrow__shield {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--vp-cyan) 14%, transparent);
    color: var(--vp-cyan);
}

.vp-escrow__shield--pulse {
    animation: vp-pulse var(--duration-slow) var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
    .vp-escrow__shield--pulse {
        animation: none;
    }
}

@keyframes vp-pulse {
    0% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--vp-cyan) 45%, transparent);
    }

    100% {
        box-shadow: 0 0 0 14px color-mix(in srgb, var(--vp-cyan) 0%, transparent);
    }
}

.vp-escrow__kicker {
    display: block;
    font-family: var(--font-mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--vp-muted);
}

.vp-escrow__title {
    font-weight: 600;
    color: var(--vp-ink);
}

.vp-escrow__amount {
    text-align: right;
}

.vp-escrow__value {
    font-family: var(--font-mono);
    font-size: var(--step-1);
    color: var(--vp-ink);
}

.vp-count--await .vp-count__value {
    opacity: 0;
}

.vp-count__ticker {
    position: absolute;
}

.vp-escrow__steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.vp-escrow__step {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.vp-escrow__dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 1px solid var(--vp-line-2);
    color: var(--vp-muted);
    flex-shrink: 0;
}

.vp-escrow__step--done .vp-escrow__dot {
    background: var(--vp-cyan);
    border-color: var(--vp-cyan);
    color: var(--vp-btn-ink);
}

.vp-escrow__step--current .vp-escrow__dot {
    border-color: var(--vp-copper);
    color: var(--vp-copper);
}

.vp-escrow__label {
    display: block;
    font-weight: 600;
    color: var(--vp-ink);
}

.vp-escrow__desc {
    display: block;
    font-size: 13px;
    color: var(--vp-muted);
}

.vp-litter {
    display: grid;
    grid-template-columns: 1fr;
    overflow: hidden;
    /* Zero out .vp-card's own default padding — the photo goes edge-to-edge; .vp-litter__body
       carries its own inner padding. */
    padding: 0;
}

@media (min-width: 768px) {
    .vp-litter {
        grid-template-columns: 5fr 7fr;
    }
}

.vp-litter__media {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--vp-photo);
    overflow: hidden;
}

.vp-litter__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.vp-litter__availability {
    position: absolute;
    left: 12px;
    bottom: 12px;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    background: rgb(10 9 8 / .65);
    color: var(--c-cream-50);
    font-size: 12px;
}

.vp-heart {
    position: absolute;
    top: 12px;
    right: 12px;
}

.vp-heart button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 0;
    background: rgb(10 9 8 / .55);
    color: var(--c-cream-50);
    cursor: pointer;
}

.vp-heart--on button {
    color: var(--vp-copper);
}

.vp-heart--pop button {
    animation: vp-heart-pop var(--duration-slow) var(--ease-spring);
}

@keyframes vp-heart-pop {
    0% {
        transform: scale(1);
    }

    40% {
        transform: scale(1.25);
    }

    100% {
        transform: scale(1);
    }
}

.vp-heart__burst {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.vp-heart__burst span {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--vp-copper);
    animation: vp-burst var(--duration-slow) var(--ease-out) forwards;
}

@keyframes vp-burst {
    from {
        transform: translate(-50%, -50%) rotate(var(--angle, 0deg)) translateY(0);
        opacity: 1;
    }

    to {
        transform: translate(-50%, -50%) rotate(var(--angle, 0deg)) translateY(-22px);
        opacity: 0;
    }
}

.vp-heart__burst span:nth-child(1) {
    --angle: 0deg;
}

.vp-heart__burst span:nth-child(2) {
    --angle: 45deg;
}

.vp-heart__burst span:nth-child(3) {
    --angle: 90deg;
}

.vp-heart__burst span:nth-child(4) {
    --angle: 135deg;
}

.vp-heart__burst span:nth-child(5) {
    --angle: 180deg;
}

.vp-heart__burst span:nth-child(6) {
    --angle: 225deg;
}

.vp-heart__burst span:nth-child(7) {
    --angle: 270deg;
}

.vp-heart__burst span:nth-child(8) {
    --angle: 315deg;
}

@media (prefers-reduced-motion: reduce) {

    .vp-heart--pop button,
    .vp-heart__burst span {
        animation: none;
    }
}

.vp-litter__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding: 24px;
}

.vp-litter__skeleton-fill {
    flex-grow: 1;
}

.vp-litter__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-sm);
}

.vp-litter__breeder {
    display: flex;
    align-items: center;
    gap: 10px;
}

.vp-litter__breeder-name {
    font-weight: 600;
    color: var(--vp-ink);
}

.vp-litter__breeder-fci {
    display: block;
}

.vp-litter__title {
    margin: 0;
    font-size: var(--step-2);
}

.vp-litter__lineage {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--vp-muted);
    font-size: 14px;
}

.vp-litter__tests {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.vp-litter__actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

.vp-litter__assurance {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--vp-muted);
}

.vp-litter__footer {
    margin-top: auto;
}

.vp-verified {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--vp-gold) 14%, transparent);
    color: var(--vp-gold);
    font-size: 12px;
    font-weight: 600;
}

.vp-vault {
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
}

.vp-vault__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-md);
    flex-wrap: wrap;
}

.vp-vault__title {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--vp-ink);
}

.vp-vault__title h3 {
    margin: 0;
}

.vp-vault__test {
    display: block;
    font-weight: 600;
    color: var(--vp-ink);
}

.vp-vault__date {
    display: block;
    font-size: 12px;
    color: var(--vp-muted);
}

.vp-vault__table th:last-child,
.vp-vault__table td:last-child {
    text-align: right;
}

.vp-result {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--vp-cyan);
    font-family: var(--font-mono);
}

/* Loading keeps the button's width and colour — the label stays laid out (visibility, not
   display: none) and only the spinner draws, absolutely centred over the whole button. Deliberately
   NOT aria-disabled/opacity: those said "unavailable", and loading is not that. */
.vp-btn--loading {
    position: relative;
}

.vp-btn--loading .vp-btn__text {
    visibility: hidden;
}

.vp-btn__spinner {
    display: inline-block;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-right-color: transparent;
    animation: vp-spin 0.7s linear infinite;
}

/* Centred with top/left/margin, not transform — `transform` belongs to the spin animation
   alone. A `translate(-50%,-50%)` set here would only hold at animation-iteration boundaries: the
   animation's own `rotate()` keyframe REPLACES the element's whole transform value while running
   (transforms from unrelated rules don't compose with a running animation), so the centring offset
   would visibly drift away over each 0.7s cycle and snap back on loop. Margin is unaffected by that. */
.vp-btn--loading .vp-btn__spinner {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -8px 0 0 -8px;
}

@keyframes vp-spin {
    to {
        transform: rotate(360deg);
    }
}

@media (prefers-reduced-motion: reduce) {
    .vp-btn__spinner {
        animation-duration: 1.4s;
    }
}

/* --- 10. Marketplace / dashboard / demo ----------------------------------- */

.vp-filters {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.vp-filters__button-wrap {
    display: flex;
    align-items: flex-end;
}

.vp-results-meta {
    font-size: 14px;
}

.vp-num {
    font-family: var(--font-mono);
    color: var(--vp-ink);
}

.vp-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-lg);
    text-align: center;
}

@media (max-width: 767px) {
    .vp-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.vp-stat {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.vp-stat__value {
    font-family: var(--font-display);
    font-size: var(--step-2);
    color: var(--vp-ink);
}

/* An admin overview card has its label first: the value sinks to the card's foot so cards with a
   wrapped label still line their numbers up. Scoped to admin pages (the only ones with a subnav) so
   the breeder dashboard and marketplace stats keep their own layout. */
.vp-page:has(> .vp-subnav) .vp-stat > .vp-eyebrow + .vp-stat__value {
    margin-top: auto;
}

.vp-stat__value--accent {
    color: var(--vp-copper);
}

.vp-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-lg);
}

.vp-step__title {
    margin-top: 12px;
}

@media (max-width: 767px) {
    .vp-steps {
        grid-template-columns: 1fr;
    }
}

.vp-swatches {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-md);
}

.vp-guide-sample-text {
    max-width: var(--measure);
}

.vp-swatch {
    display: flex;
    align-items: center;
    gap: 12px;
}

.vp-swatch__chip {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    border: 1px solid var(--vp-line);
    background: var(--vp-token-color, var(--vp-copper));
    flex-shrink: 0;
}

.vp-swatch__meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 13px;
}

.vp-swatch__name {
    font-weight: 600;
    color: var(--vp-ink);
}

.vp-guide-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    padding: var(--space-lg);
}

.vp-guide-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    align-items: center;
}

/* --- 11. Auth ------------------------------------------------------------
   The backdrop, centred shell and logo of AuthLayout.razor, plus the card. They sit outside Blazor's
   CSS isolation because the sign-in throttle's static 429 page (Verapet.Auth SignInRejectionPage) wears
   the same chrome without rendering a component, and a scoped selector only matches elements a
   component rendered. */
.vp-auth-backdrop {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
}

.vp-auth-shell {
    width: 100%;
    max-width: 440px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-lg);
}

/* The account page's card is wider (.vp-auth-card--wide); the shell has to leave it the room. */
.vp-auth-shell--wide {
    max-width: 640px;
}

.vp-auth-logo {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-xs);
    color: inherit;
    text-decoration: none;
}

/* The owner-drawn logo, never recoloured; 128px is well above its 88px minimum. The page owns the h1,
   so the mark is a span here. */
.vp-auth-logo__mark {
    display: block;
    width: 128px;
}

.vp-auth-logo__mark img {
    display: block;
    width: 100%;
    height: auto;
}

.vp-auth-logo__word {
    font-size: var(--step-1);
    line-height: 1;
}

.vp-auth-footer {
    margin: 0;
    text-align: center;
    font-size: 13px;
}

.vp-auth-card {
    position: relative;
    width: 100%;
    max-width: 440px;
    /* Long unbreakable text (an e-mail address in an alert or the sign-out question) wraps
       instead of pushing past the card. */
    overflow-wrap: anywhere;
}

/* On small phones the card's 32px padding (VpSize.Lg) takes a fifth of the width; the auth pages are
   forms, so they get the room back. */
@media (max-width: 479px) {
    .vp-auth-card.vp-card--pad-lg {
        padding: 20px;
    }
}

/* The same thin holo stripe the e-mails carry under their header. A 3px-tall box cannot curve into
   the card's ~17px corners (the radii get clamped), so its ends stuck out square past the rounded
   corners. Instead the pseudo covers the whole card at the card's radius and a mask keeps only
   its top 3px, so the band follows the corner curve. Still no overflow clip on the card, which would
   cut off focus rings. */
.vp-auth-card::before {
    content: "";
    position: absolute;
    /* -1px: over the card's own 1px border, so no pale hairline shows above the band. */
    inset: -1px;
    padding-top: 4px;
    border-radius: var(--radius-lg);
    background: var(--vp-holo);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
    pointer-events: none;
}

/* "nebo" between the password form and the passkey button: centered text, hairline both sides. */
.vp-auth-divider {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    color: var(--vp-muted);
    font-size: 13px;
}

.vp-auth-divider::before,
.vp-auth-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--vp-line);
}

/* A handful of small, repeated patterns across every Account/*.razor page — a global utility
   here rather than nine near-identical page-scoped .razor.css files (CSS isolation, unlike
   .vp-auth-card above, DOES reach these: every one of these elements is authored directly in its
   own page's markup, not a child component's root — a shared file is simply less duplication). */
.vp-auth-section-title {
    font-size: var(--step-1);
}

.vp-auth-passkey-name {
    margin: 0;
}

.vp-auth-passkey-meta {
    margin: 0;
    font-size: 13px;
}

.vp-auth-actions {
    text-align: center;
}

.vp-auth-note {
    margin: 0;
    text-align: left;
}

/* One-time codes: monospaced, centred, tall enough to read the digits at a glance. */
.vp-input.vp-otp {
    height: 52px;
    font-family: var(--font-mono);
    font-size: 22px;
    letter-spacing: 0.3em;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.vp-input.vp-otp.vp-otp--code {
    font-size: 18px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.vp-auth-note--sm {
    font-size: 13px;
}

/* Circuit reconnect dialog (Verapet.Web/Components/ReconnectModal.razor). Blazor sets one components-reconnect-*
   state class on it; the state shows its own buttons, and verapet.js writes the status text. */

.vp-reconnect {
    max-width: 380px;
    width: calc(100vw - 32px);
    padding: var(--space-lg) var(--space-md);
    border: 1px solid var(--vp-line);
    border-radius: var(--radius-lg);
    background: var(--vp-tile);
    color: var(--vp-body);
    box-shadow: var(--vp-shadow);
    text-align: center;
}

.vp-reconnect::backdrop {
    background: color-mix(in srgb, var(--vp-ink) 55%, transparent);
}

.vp-reconnect__body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
}

.vp-reconnect__status {
    margin: 0;
    color: var(--vp-ink);
    font-size: var(--step-1);
}

.vp-reconnect__actions {
    justify-content: center;
}

.vp-reconnect__act {
    display: none;
}

.vp-reconnect__pulse {
    position: relative;
    width: 56px;
    height: 56px;
}

.vp-reconnect__pulse span {
    position: absolute;
    inset: 0;
    border: 3px solid var(--vp-copper);
    border-radius: 50%;
    opacity: 0;
    animation: vp-reconnect-ripple 1.8s ease-out infinite;
}

.vp-reconnect__pulse span:last-child {
    animation-delay: .9s;
}

.components-reconnect-failed .vp-reconnect__act--failed,
.components-reconnect-resume-failed .vp-reconnect__act--resume-failed,
.components-reconnect-paused .vp-reconnect__act--paused {
    display: inline-flex;
}

.components-reconnect-failed .vp-reconnect__pulse,
.components-reconnect-resume-failed .vp-reconnect__pulse,
.components-reconnect-paused .vp-reconnect__pulse {
    display: none;
}

@keyframes vp-reconnect-ripple {
    0% {
        transform: scale(.3);
        opacity: 0;
    }

    15% {
        opacity: .9;
    }

    100% {
        transform: scale(1);
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .vp-reconnect__pulse span {
        animation: none;
        opacity: .5;
        transform: scale(.7);
    }
}

/* Admin backoffice */

.vp-dialog {
    max-width: 560px;
    width: calc(100vw - 32px);
    padding: 0;
    border: 1px solid var(--vp-line);
    border-radius: var(--radius-lg);
    background: var(--vp-tile);
    color: var(--vp-body);
    box-shadow: var(--vp-shadow);
}

.vp-dialog::backdrop {
    background: color-mix(in srgb, var(--vp-ink) 55%, transparent);
}

.vp-dialog__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-md) 0;
}

.vp-dialog__title {
    margin: 0;
    font-size: var(--step-1);
}

.vp-dialog__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--vp-muted);
    cursor: pointer;
}

.vp-dialog__close:hover {
    background: var(--vp-tile-2);
    color: var(--vp-ink);
}

.vp-dialog__close:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--vp-copper) 20%, transparent);
}

.vp-dialog__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-md) var(--space-md);
}

textarea.vp-input {
    height: auto;
    min-height: 6.5rem;
    padding: 12px 14px;
    resize: vertical;
}

.vp-row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-sm);
}

.vp-subnav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    border-bottom: 1px solid var(--vp-line);
    margin-bottom: var(--space-lg);
}

.vp-subnav__link {
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    color: var(--vp-muted);
    font-weight: 600;
    border-bottom: 2px solid transparent;
}

.vp-subnav__link:hover {
    color: var(--vp-ink);
    background: var(--vp-tile-2);
}

.vp-subnav__link--active {
    color: var(--vp-ink);
    border-bottom-color: var(--vp-copper);
}

.vp-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.vp-detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-md);
}

.vp-detail-grid dt {
    font-family: var(--font-mono);
    text-transform: uppercase;
    font-size: 11px;
    letter-spacing: var(--tracking-wide);
    color: var(--vp-muted);
}

.vp-detail-grid dd {
    margin: var(--space-2xs) 0 0;
    color: var(--vp-ink);
}

/* A wide table scrolls sideways inside this wrapper. The local-attached covers hide the edge shadows
   at the scroll ends, so a shadow shows only on a side that still has content beyond it; the first
   column stays pinned so a row keeps its name while it scrolls. --vp-scroll-bg is the surface behind
   the table (a card sets it to its own). */
.vp-table-scroll {
    --vp-scroll-bg: var(--vp-bg);
    overflow-x: auto;
    background:
        linear-gradient(to right, var(--vp-scroll-bg) 30%, transparent) left center / 32px 100% no-repeat local,
        linear-gradient(to left, var(--vp-scroll-bg) 30%, transparent) right center / 32px 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--vp-ink) 28%, transparent), transparent) left center / 12px 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--vp-ink) 28%, transparent), transparent) right center / 12px 100% no-repeat scroll;
}

.vp-card .vp-table-scroll {
    --vp-scroll-bg: var(--vp-tile);
}

.vp-table-scroll .vp-table th:first-child,
.vp-table-scroll .vp-table td:first-child {
    position: sticky;
    left: 0;
    /* The divider is a 1px background stripe at the cell's right edge: a collapsed-border table
       draws neither a box-shadow nor a border on a sticky cell that stays put while it scrolls. */
    background:
        linear-gradient(to left, var(--vp-line) 1px, transparent 1px) right / 100% 100% no-repeat,
        var(--vp-scroll-bg);
}

.vp-nowrap {
    white-space: nowrap;
}

.vp-mono {
    font-family: var(--font-mono);
    font-size: 0.92em;
}

/* Below 640px the users and audit tables become one card per row: each cell shows its column name
   (data-label) before its value, and the header row is kept for assistive technology only. */
@media (max-width: 639px) {
    .vp-table--stack thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
    }

    .vp-table--stack,
    .vp-table--stack tbody,
    .vp-table--stack tr,
    .vp-table--stack td {
        display: block;
    }

    .vp-table--stack tr {
        padding: var(--space-xs) 0;
        border-top: 1px solid var(--vp-line);
    }

    .vp-table--stack td {
        display: grid;
        grid-template-columns: 6.5rem minmax(0, 1fr);
        gap: var(--space-xs);
        padding: var(--space-2xs) var(--space-xs);
        border-top: 0;
        overflow-wrap: anywhere;
    }

    .vp-table--stack td::before {
        content: attr(data-label);
        font-family: var(--font-mono);
        text-transform: uppercase;
        font-size: 11px;
        letter-spacing: var(--tracking-wide);
        color: var(--vp-muted);
        padding-top: 2px;
    }

    .vp-table--stack td.vp-cell--empty {
        display: none;
    }

    .vp-table-scroll .vp-table--stack td:first-child {
        position: static;
        background: none;
        box-shadow: none;
    }
}

.vp-filter-form {
    align-items: flex-end;
}

.vp-filter-form > .vp-field {
    flex: 1 1 9rem;
    min-width: 0;
}

.vp-filter-form > .vp-btn,
.vp-filter-form > button {
    flex: 0 0 auto;
}

@media (max-width: 639px) {
    .vp-filter-form > .vp-field:first-child {
        flex-basis: 100%;
    }
}

/* Admin pages (the ones with the sub-navigation) sit closer together than the marketing pages'
   section rhythm: heading, sub-navigation and content read as one screen. */
.vp-page:has(> .vp-subnav) {
    gap: var(--space-md);
    padding-block: var(--space-xl);
}

/* Same specificity as the rule above and later in the file than the bar clearance (§6), so without this
   the admin pages' own padding would win and their heading would start underneath the fixed app bar. */
.vp-app--bar .vp-page:has(> .vp-subnav) {
    padding-top: calc(var(--vp-bar-clear) + var(--space-xl));
}

.vp-page:has(> .vp-subnav) > .vp-subnav {
    margin-bottom: 0;
}

.vp-audit-details {
    margin: 0;
    font-size: 13px;
}

.vp-audit-details > div {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
}

.vp-audit-details dt {
    color: var(--vp-muted);
}

.vp-audit-details dt::after {
    content: ":";
}

.vp-audit-details dd {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
    color: var(--vp-ink);
}

/* Charts (Ui/VpBarChart.razor): stacked SVG bars drawn in semantic tones. The numbers are always
   also offered as a table (.vp-chart__data), so colour is never the only carrier of a value. */

.vp-chart {
    margin: 0;
}

.vp-chart__frame {
    position: relative;
    height: 200px;
    margin: var(--space-xs) 0 var(--space-lg) 2.75rem;
}

.vp-chart__svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.vp-chart__grid {
    stroke: var(--vp-line);
    stroke-width: 1px;
    vector-effect: non-scaling-stroke;
}

.vp-chart__yaxis,
.vp-chart__xaxis {
    position: absolute;
    pointer-events: none;
}

.vp-chart__yaxis {
    top: 0;
    right: 100%;
    height: 100%;
}

.vp-chart__xaxis {
    top: 100%;
    left: 0;
    width: 100%;
}

.vp-chart__tick {
    position: absolute;
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1;
    color: var(--vp-muted);
    white-space: nowrap;
}

.vp-chart__yaxis .vp-chart__tick {
    right: 0;
    bottom: var(--pos);
    padding-right: var(--space-xs);
    transform: translateY(50%);
}

.vp-chart__xaxis .vp-chart__tick {
    left: var(--pos);
    padding-top: var(--space-xs);
    transform: translateX(-50%);
}

/* A segment is outlined in the surface colour, so two stacked tones never touch. */
.vp-chart__bar {
    stroke: var(--vp-tile);
    stroke-width: 2px;
    vector-effect: non-scaling-stroke;
}

.vp-chart__bar--copper { fill: var(--vp-copper); }
.vp-chart__bar--gold { fill: var(--vp-gold); }
.vp-chart__bar--violet { fill: var(--vp-violet); }
.vp-chart__bar--cyan { fill: var(--vp-cyan); }
.vp-chart__bar--muted { fill: var(--vp-muted); }
.vp-chart__bar--ink { fill: var(--vp-ink); }
.vp-chart__bar--danger { fill: var(--vp-danger); }

.vp-chart__legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-sm);
    margin: var(--space-xs) 0 0;
    padding: 0;
    list-style: none;
    color: var(--vp-body);
    font-size: 14px;
}

.vp-chart__total {
    font-family: var(--font-mono);
    font-size: 14px;
    color: var(--vp-ink);
}

.vp-chart__legend li {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
}

.vp-chart__swatch {
    display: inline-block;
    width: 16px;
    height: 16px;
    border-radius: 3px;
}

.vp-chart__swatch--copper { background: var(--vp-copper); }
.vp-chart__swatch--gold { background: var(--vp-gold); }
.vp-chart__swatch--violet { background: var(--vp-violet); }
.vp-chart__swatch--cyan { background: var(--vp-cyan); }
.vp-chart__swatch--muted { background: var(--vp-muted); }
.vp-chart__swatch--ink { background: var(--vp-ink); }
.vp-chart__swatch--danger { background: var(--vp-danger); }

.vp-chart__data summary {
    cursor: pointer;
    color: var(--vp-muted);
    font-weight: 600;
}

.vp-auth-card--wide {
    max-width: 640px;
}

/* --- 12. Pre-launch ------------------------------------------------------
   The teaser everyone but an administrator sees until launch (Pages/PreLaunch/Teaser.razor), the
   minimal shell MainLayout wears meanwhile, and the privacy / sign-up-link cards. The slider is a
   scroll-snap row that touch, trackpad and keyboard scroll natively; its prev/next arrows, dots and
   mouse drag come from verapet.slider (wwwroot/js/verapet.js), which scrolls only the row. */

.vp-teaser-shell .vp-page {
    padding-block: var(--space-xl);
    gap: var(--space-xl);
}

.vp-teaser-shell__team {
    align-self: center;
    color: var(--vp-muted);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.vp-teaser-shell__team:hover,
.vp-teaser-shell__team:focus-visible {
    color: var(--vp-ink);
}

.vp-teaser {
    display: flex;
    flex-direction: column;
    gap: var(--space-xl);
    width: 100%;
    max-width: 720px;
    margin-inline: auto;
}

.vp-teaser__masthead {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
    text-align: center;
}

/* Masthead lockup: the owner's logo and the wordmark read as one mark, on a soft warm glow. */
.vp-teaser__lockup {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    margin: 0;
}

.vp-teaser__lockup::before {
    content: "";
    position: absolute;
    inset: -18% -30% 22%;
    z-index: 0;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--c-gold-200) 18%, transparent), color-mix(in srgb, var(--c-copper-400) 8%, transparent) 55%, transparent 75%);
    filter: blur(6px);
}

.vp-teaser__lockup picture {
    position: relative;
    z-index: 1;
    display: block;
    width: clamp(170px, 26vw, 220px);
}

.vp-teaser__lockup img {
    display: block;
    width: 100%;
    height: auto;
    filter: drop-shadow(0 18px 30px rgb(0 0 0 / .45));
}

.vp-teaser__wordmark {
    position: relative;
    z-index: 1;
    margin-top: 4px;
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(34px, 5.4vw, 46px);
    line-height: 1;
    letter-spacing: -0.01em;
    color: var(--vp-ink);
}

/* The warm wash (.vp-wash) is the tagline's one flourish; a little slower and lighter than a link's. */
.vp-teaser__tagline {
    margin: var(--space-2xs) 0 0;
    font-weight: 300;
    font-size: clamp(20px, 2.6vw, 24px);
    line-height: 1.3;
    animation-duration: 14s;
}

.vp-teaser__lede {
    margin: 0;
    max-width: 30rem;
    color: var(--vp-muted);
    text-wrap: balance;
}

.vp-teaser__ledger {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 14px;
    margin: 2px 0 0;
    padding: 0;
    list-style: none;
    font-size: 13px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--c-cream-600);
}

.vp-teaser__ledger li + li::before {
    content: "|";
    margin-right: 14px;
    color: var(--vp-line-2);
}

.vp-teaser__ledger em {
    font-size: 0.9em;
    font-style: italic;
    letter-spacing: 0.01em;
    text-transform: none;
}

@media (max-width: 560px) {
    .vp-teaser__ledger {
        flex-direction: column;
        gap: 4px;
    }

    .vp-teaser__ledger li + li::before {
        content: none;
    }
}

.vp-teaser__label {
    margin: 0 0 var(--space-sm);
    font-size: 13px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--c-cream-600);
}

.vp-teaser__slider {
    display: flex;
    flex-direction: column;
}

/* Phones: one slide at 86% width, so the next one peeks — that is the tease. */
.vp-teaser__track {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 86%;
    gap: 14px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    padding-bottom: var(--space-2xs);
}

.vp-teaser__track::-webkit-scrollbar {
    display: none;
}

/* A desktop mouse can drag the row (verapet.slider); while it does, snapping and smooth scrolling
   pause so the row follows the pointer, and text is not selected. */
@media (hover: hover) and (pointer: fine) {
    .vp-teaser__track {
        cursor: grab;
    }
}

html[data-vp-slider-dragging] {
    user-select: none;
}

.vp-teaser__track[data-dragging] {
    cursor: grabbing;
    scroll-snap-type: none;
    scroll-behavior: auto;
    user-select: none;
}

.vp-teaser__track:focus-visible {
    outline: 2px solid var(--vp-copper);
    outline-offset: 4px;
}

/* From 720px: 44% each, so the third slide visibly peeks past the second. */
@media (min-width: 720px) {
    .vp-teaser__track {
        grid-auto-columns: 44%;
    }
}

@media (prefers-reduced-motion: no-preference) {
    .vp-teaser__track {
        scroll-behavior: smooth;
    }
}

/* Mezi chlupy tile: a quiet raised surface with a hairline, no coloured stripe. */
.vp-teaser__slide {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-height: 208px;
    padding: 22px 22px 20px;
    scroll-snap-align: start;
    background: var(--vp-tile);
    border: 1px solid var(--vp-line);
    border-radius: 14px;
}

.vp-teaser__slide--cyan {
    --teaser-tone: var(--vp-cyan);
}

.vp-teaser__slide--gold {
    --teaser-tone: var(--vp-gold);
}

.vp-teaser__slide--copper {
    --teaser-tone: var(--vp-copper);
}

.vp-teaser__slide--violet {
    --teaser-tone: var(--vp-violet);
}

.vp-teaser__kicker {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: 14px;
    color: var(--teaser-tone, var(--vp-copper));
}

.vp-teaser__kicker .vp-eyebrow {
    font-family: var(--font-body);
    font-size: 14px;
    letter-spacing: normal;
    text-transform: none;
    color: var(--c-copper-300);
}

.vp-teaser__slide-title {
    margin: 2px 0 0;
    font-size: 24px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--vp-ink);
}

.vp-teaser__slide-body {
    margin: 0;
    color: var(--vp-body);
}

.vp-teaser__slide-link {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    margin-top: var(--space-2xs);
}

.vp-teaser__counter {
    margin-top: auto;
    padding-top: 10px;
    font-size: 13px;
    color: var(--c-cream-600);
}

/* Prev arrow, dots, next arrow — one centred row under the slides. */
.vp-teaser__controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    margin-top: var(--space-xs);
}

.vp-teaser__dots {
    display: flex;
}

/* A 24px hit area (WCAG 2.2 target size) around a 7px dot; aria-current marks "you are here". */
.vp-teaser__dot {
    box-sizing: border-box;
    width: 24px;
    height: 24px;
    padding: 8.5px;
    border: 0;
    border-radius: 50%;
    /* --vp-field-line, not --vp-line-2: a dot is a control state, so it needs 3:1 (WCAG 1.4.11). */
    background: var(--vp-field-line);
    background-clip: content-box;
    cursor: pointer;
}

.vp-teaser__dot[aria-current="true"] {
    background-color: var(--c-copper-300);
}

.vp-teaser__dot:hover,
.vp-teaser__dot:focus-visible {
    background-color: var(--vp-ink);
}

.vp-teaser__nav {
    display: inline-grid;
    place-items: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--vp-line);
    border-radius: 50%;
    background: var(--vp-tile);
    color: var(--vp-ink);
    cursor: pointer;
}

.vp-teaser__nav:hover:not([aria-disabled="true"]) {
    border-color: var(--vp-copper);
    color: var(--c-copper-300);
}

.vp-teaser__nav[aria-disabled="true"] {
    opacity: 0.35;
    cursor: default;
}

/* The arrows and dots need verapet.js (it adds .vp-js to <html>); without it they would be dead. */
html:not(.vp-js) .vp-teaser__controls {
    display: none;
}

.vp-teaser__dot:focus-visible,
.vp-teaser__nav:focus-visible {
    outline: 2px solid var(--vp-copper);
    outline-offset: 2px;
}

/* The one primary surface: a dark tile inside a copper gradient ring (masked 1px border). */
.vp-teaser__signup {
    position: relative;
    isolation: isolate;
    width: 100%;
    padding: 28px;
    background: var(--vp-field);
    border: 0;
    border-radius: 14px;
}

.vp-teaser__signup::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    padding: 1px;
    border-radius: inherit;
    background: linear-gradient(100deg, var(--c-copper-500), var(--c-copper-300) 20%, var(--c-cream-50) 28%, var(--c-copper-300) 36%, var(--c-copper-500) 60%, var(--c-dusk-300) 80%, var(--c-copper-500));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
}

.vp-teaser__signup-heading {
    margin: 0 0 6px;
    font-size: 26px;
    font-weight: 500;
    line-height: 1.25;
    color: var(--vp-ink);
}

.vp-teaser__signup-sub {
    margin: 0 0 18px;
    color: var(--vp-muted);
}

.vp-teaser__row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 10px;
}

.vp-teaser__email {
    flex: 1 1 220px;
}

/* The placeholder names the field for the eye; the label stays for assistive tech. */
.vp-teaser__email .vp-field__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
}

.vp-teaser__signup .vp-input {
    background: var(--vp-bg);
    border-color: var(--vp-line-2);
}

.vp-teaser__signup .vp-input::placeholder {
    color: var(--c-cream-600);
}

.vp-teaser__submit {
    flex: 0 0 auto;
    height: 48px;
    padding-inline: 22px;
}

@media (max-width: 560px) {
    .vp-teaser__submit {
        flex: 1 1 100%;
    }
}

.vp-teaser__signup .vp-check {
    align-items: flex-start;
    color: var(--vp-muted);
    font-size: 14px;
}

/* The label text wraps; without this the flex row shrinks the box below its 18px. */
.vp-teaser__signup .vp-checkbox {
    flex: none;
    margin: 3px 0 0;
    background: var(--vp-bg);
    border-color: var(--vp-line-2);
}

/* Links on these surfaces keep the brand colour in every state, visited included. */
.vp-teaser a:not(.vp-btn):not(.vp-wash):not(.vp-teaser__dot):not(.vp-public-link),
.vp-teaser-shell a:not(.vp-btn):not(.vp-wash):not(.vp-teaser-shell__team):not(.vp-public-link),
.vp-teaser__panel a:not(.vp-btn) {
    color: var(--vp-copper);
}

.vp-teaser a:not(.vp-btn):not(.vp-wash):not(.vp-teaser__dot):not(.vp-public-link):hover,
.vp-teaser-shell a:not(.vp-btn):not(.vp-wash):not(.vp-teaser-shell__team):not(.vp-public-link):hover,
.vp-teaser__panel a:not(.vp-btn):hover {
    color: var(--vp-copper);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.vp-teaser__closed {
    margin: 0;
    text-align: center;
}

.vp-teaser__panel {
    overflow-wrap: anywhere;
}

/* A reading page: a wider card than the state cards, body text held to a comfortable line. */
.vp-teaser__reading {
    max-width: calc(640px + 2 * clamp(16px, 4vw, 96px));
}

.vp-teaser__privacy h2 {
    margin-top: var(--space-sm);
}

.vp-teaser__section {
    font-size: var(--step-1);
    line-height: 1.2;
}

.vp-teaser__privacy p,
.vp-teaser__privacy ul {
    margin: 0;
    max-width: 70ch;
}

.vp-teaser__privacy ul {
    padding-left: 1.25rem;
}

.vp-teaser__version {
    font-size: 13px;
}

/* A legal text (Pages/Legal, rendered from Legal/*.md): the reading card's measure, numbered clauses as plain
   paragraphs, and the privacy policy's four-column table scrolling sideways on a phone instead of widening the page. */
.vp-legal h1 {
    font-family: var(--font-display);
    font-size: var(--step-2);
    line-height: 1.1;
    margin: 0;
}

.vp-legal h2 {
    font-family: var(--font-display);
    font-size: var(--step-1);
    line-height: 1.2;
    margin: var(--space-sm) 0 0;
}

.vp-legal p,
.vp-legal ul {
    margin: 0;
    max-width: 70ch;
}

.vp-legal ul {
    padding-left: 1.25rem;
}

.vp-legal table {
    display: block;
    overflow-x: auto;
    border-collapse: collapse;
    font-size: 14px;
}

.vp-legal th,
.vp-legal td {
    padding: 8px 12px;
    text-align: left;
    vertical-align: top;
    border-top: 1px solid var(--vp-line);
    min-width: 12ch;
}

.vp-legal th {
    color: var(--vp-muted);
}

/* The legal links under the site footer: one wrapping row, small and quiet. */
.vp-footer__legal {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    flex-basis: 100%;
    margin: 0;
    font-size: 13px;
}

/* Public pages (Pages/PreLaunch/ForShelters, ForBreeders, Story): the teaser's 720px column under a compact
   masthead and the section navigation, tone-edged cards (the slide tone classes set --teaser-tone: copper =
   shelters, gold = breeders, cyan = trust; the story's stage cards carry no edge) and the early-access block. No JavaScript involved. */
.vp-public {
    display: flex;
    flex-direction: column;
    gap: var(--space-xl);
    width: 100%;
    max-width: 720px;
    margin-inline: auto;
}

.vp-public-masthead {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
}

.vp-public-link.vp-public-masthead__home {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    color: var(--vp-ink);
    text-decoration: none;
}

.vp-public-masthead__logo {
    display: block;
    width: 96px;
}

.vp-public-masthead__logo img {
    display: block;
    width: 100%;
    height: auto;
}

.vp-public-masthead__wordmark {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 30px;
    line-height: 1;
    letter-spacing: -0.01em;
}

.vp-public-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 18px;
    font-size: 13px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.vp-public-link {
    color: var(--vp-muted);
    text-decoration: none;
}

.vp-teaser__ledger .vp-public-link {
    color: inherit;
}

.vp-public-nav__link[aria-current="page"] {
    color: var(--vp-ink);
}

.vp-public-link:hover,
.vp-public-link:focus-visible {
    color: var(--vp-ink);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.vp-public__hero {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    text-wrap: balance;
}

.vp-public__title {
    margin: 0;
    font-size: var(--step-title);
    line-height: 1.1;
    color: var(--vp-ink);
}

.vp-public__lede {
    margin: 0;
    max-width: 38rem;
    font-size: var(--step-1);
    color: var(--vp-body);
}

.vp-public__media {
    display: block;
}

.vp-public__media img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 14px;
    background: var(--vp-tile);
}

.vp-public__media--portrait {
    max-width: 360px;
    margin-inline: auto;
}

.vp-public__label {
    margin: 0 0 var(--space-sm);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 400;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--c-cream-600);
}

.vp-public__cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-md);
}

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

.vp-public__cards--three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 900px) {
    .vp-public__cards--three {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 560px) {
    .vp-public__cards {
        grid-template-columns: minmax(0, 1fr);
    }
}

.vp-public__card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-xs);
    background: var(--vp-tile);
    border: 1px solid var(--vp-line);
    border-top: 3px solid var(--teaser-tone, var(--vp-copper));
    border-radius: 14px;
}

.vp-public__card--plain {
    border-top-color: var(--vp-line);
}

.vp-public__card-title {
    margin: 0;
    font-size: 22px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--vp-ink);
}

.vp-public__card-body {
    margin: 0;
    color: var(--vp-body);
}

.vp-public__steps {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: vp-public-step;
}

.vp-public__step {
    position: relative;
    padding-left: 52px;
    counter-increment: vp-public-step;
}

.vp-public__step::before {
    content: counter(vp-public-step);
    position: absolute;
    top: 0;
    left: 0;
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    font-family: var(--font-display);
    font-size: 18px;
    color: var(--vp-ink);
    border: 1px solid var(--vp-line-2);
    border-radius: 50%;
}

.vp-public__note {
    margin: var(--space-md) 0 0;
    max-width: 38rem;
    color: var(--vp-muted);
}

.vp-public__prose {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    max-width: 38rem;
}

.vp-public__prose p {
    margin: 0;
    color: var(--vp-body);
}

.vp-public__media + .vp-public__prose {
    margin-top: var(--space-md);
}

.vp-public__early {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

/* The breeders' ring is a still gold edge; the shelters' is the copper .vp-ring. */
.vp-public__early--gold {
    border: 1px solid transparent;
    background-image: linear-gradient(var(--vp-tile), var(--vp-tile)),
        linear-gradient(100deg, var(--c-gold-200), var(--c-copper-300) 50%, var(--c-gold-200));
    background-origin: border-box;
    background-clip: padding-box, border-box;
}

.vp-public__early-title {
    margin: 0;
    font-size: 26px;
    line-height: 1.2;
    color: var(--vp-ink);
}

.vp-public__early-body {
    margin: 0;
    color: var(--vp-body);
}

.vp-public__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
}

.vp-public__closing {
    margin: 0;
    text-align: center;
}

.vp-public__links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-md);
    margin: var(--space-md) 0 0;
    padding: 0;
    list-style: none;
}

.vp-public__links a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
}

/* Press kit (Pages/PreLaunch/Press): the facts as a term/value list and the files as a two-column grid of
   previews. A file drawn for a dark background previews on .vp-sig, the rest on .vp-work; swatches read the
   brand's raw stops through --swatch, set inline as a custom property. */
.vp-press__intro {
    margin: 0 0 var(--space-md);
}

.vp-press__facts {
    display: grid;
    grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
    margin: 0;
    border-top: 1px solid var(--vp-line);
}

.vp-press__facts dt,
.vp-press__facts dd {
    margin: 0;
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--vp-line);
}

.vp-press__facts dt {
    padding-right: var(--space-sm);
    font-size: 13px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--vp-muted);
}

.vp-press__facts dd {
    color: var(--vp-ink);
}

.vp-press__assets {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-lg) var(--space-md);
    margin: 0;
    padding: 0;
    list-style: none;
}

.vp-press__asset {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2xs);
    min-width: 0;
}

.vp-press__preview {
    display: grid;
    place-items: center;
    width: 100%;
    aspect-ratio: 4 / 3;
    padding: var(--space-md);
    border: 1px solid var(--vp-line);
    border-radius: 14px;
    overflow: hidden;
}

.vp-press__preview img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.vp-press__asset-title {
    margin: var(--space-xs) 0 0;
    font-family: var(--font-body);
    font-size: var(--step-0);
    font-weight: 600;
    color: var(--vp-ink);
}

.vp-press__meta {
    margin: 0;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--vp-muted);
}

.vp-press__download {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
}

.vp-press__colours {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-sm) var(--space-md);
    margin: 0;
    padding: 0;
    list-style: none;
}

.vp-press__colour {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    color: var(--vp-body);
}

.vp-press__swatch {
    flex: none;
    width: 40px;
    height: 40px;
    border: 1px solid var(--vp-line-2);
    border-radius: 50%;
    background: var(--swatch);
}

@media (max-width: 560px) {
    .vp-press__facts,
    .vp-press__assets,
    .vp-press__colours {
        grid-template-columns: minmax(0, 1fr);
    }

    .vp-press__facts dt {
        padding-bottom: 0;
        border-bottom: 0;
    }
}

/* --- Handover certificate -------------------------------------------------
   A trust surface: .vp-sig + .vp-ring on the article, cyan only for "verified", the seller pill
   carries gold (breeder) or copper (shelter). Single column by default, two party columns from
   480px up. */
.vp-certificate {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 24px 20px;
    color: var(--vp-body);
    break-inside: avoid;
}

.vp-certificate__top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
}

.vp-certificate__seal {
    display: inline-flex;
    color: var(--vp-cyan);
}

.vp-certificate__eyebrow {
    flex: 1;
    color: var(--vp-cyan);
}

.vp-certificate__id {
    font-size: 12px;
}

.vp-certificate__centre {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
}

.vp-certificate__photo {
    width: 160px;
    height: 160px;
    border-radius: var(--radius-lg);
    object-fit: cover;
}

.vp-certificate__mark {
    display: inline-flex;
    color: var(--vp-line-2);
}

.vp-certificate__name {
    margin: 0;
    font-size: 36px;
    color: var(--vp-ink);
    overflow-wrap: anywhere;
}

.vp-certificate__breed {
    margin: 0;
    color: var(--vp-muted);
}

.vp-certificate__parties {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    padding-block: 16px;
    border-block: 1px solid var(--vp-line);
}

.vp-certificate__party {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    min-width: 0;
}

.vp-certificate__party-name {
    font-family: var(--font-display);
    font-size: 20px;
    color: var(--vp-ink);
    overflow-wrap: anywhere;
}

.vp-certificate__date,
.vp-certificate__recorded {
    margin: 0;
    text-align: center;
}

.vp-certificate__recorded {
    font-size: 22px;
}

.vp-certificate__footer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font-size: 14px;
    color: var(--vp-muted);
    text-align: center;
}

.vp-certificate__footer .vp-icon {
    flex: none;
}

@media (min-width: 480px) {
    .vp-certificate {
        padding: 32px 28px;
    }

    .vp-certificate__parties {
        grid-template-columns: 1fr 1fr;
    }
}

/* Print: the certificate keeps its dark surface and holographic phrase (both background paints),
   stays on one page and stops animating; the tokens stay as they are. */
@media print {
    .vp-certificate {
        break-inside: avoid;
        print-color-adjust: exact;
        -webkit-print-color-adjust: exact;
    }

    .vp-certificate .vp-holo {
        animation: none;
    }
}

/* Lost pets: the map box, its Leaflet pins (vector shapes, coloured here so no hex lives in the script), list rows and facts. */
.lostpet-map {
    height: min(60vh, 28rem);
    min-height: 16rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--vp-line);
    background: var(--vp-photo);
    overflow: hidden;
    position: relative;
    z-index: 0;
    isolation: isolate;
}

.lostpet-pin {
    stroke: var(--vp-copper);
    fill: var(--vp-copper);
    fill-opacity: 0.75;
}

.lostpet-pin--sighting {
    stroke: var(--vp-violet);
    fill: var(--vp-violet);
}

.lostpet-pin--exact {
    stroke: var(--vp-ink);
    fill: var(--vp-ink);
}

.lostpet-pin--area,
.lostpet-pin--pick {
    stroke: var(--vp-cyan);
    fill: var(--vp-cyan);
}

.lostpet-radius {
    stroke: var(--vp-copper);
    fill: var(--vp-copper);
    fill-opacity: 0.12;
}

.lostpet-radius--area,
.lostpet-radius--pick {
    stroke: var(--vp-cyan);
    fill: var(--vp-cyan);
}

.lostpet-row {
    display: flex;
    gap: var(--space-md);
    align-items: center;
    flex-wrap: wrap;
}

.lostpet-row__main {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    flex: 1 1 14rem;
    min-width: 0;
}

.lostpet-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: var(--space-md);
    align-items: start;
}

/* Same shape as .vp-animal-card: the photo runs edge to edge on top at a fixed ratio, the body sits
   directly under it. */
.lostpet-card {
    gap: 0;
    padding: 0;
    overflow: hidden;
}

.lostpet-card__photo {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    height: auto;
    object-fit: cover;
    background: var(--vp-photo);
}

.lostpet-card__body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 20px;
    min-width: 0;
}

/* A file picker drawn as a button; the native input is hidden but stays focusable. */
.vp-file-pick {
    position: relative;
    align-self: flex-start;
    width: fit-content;
}

.vp-file-pick__input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    font-size: 0;
}

.vp-file-pick:has(.vp-file-pick__input:focus-visible) {
    border-color: var(--vp-copper);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--vp-copper) 20%, transparent);
}

.vp-file-pick[data-disabled],
.vp-file-pick:has(.vp-file-pick__input:disabled) {
    cursor: not-allowed;
    opacity: 0.5;
}

.vp-file-pick__input:disabled {
    cursor: not-allowed;
}

.lostpet-facts {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--space-xs) var(--space-md);
    margin: 0;
}

.lostpet-facts dt {
    color: var(--vp-muted);
}

.lostpet-facts dd {
    margin: 0;
}

.lostpet-description {
    white-space: pre-wrap;
    margin: 0;
}

.lostpet-files {
    color: var(--vp-muted);
    font-size: 14px;
}

.lostpet-fieldset {
    border: 0;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.lostpet-consent-points {
    margin: 0;
    padding-left: var(--space-lg);
}

.lostpet-quiet__summary {
    display: inline-block;
    cursor: pointer;
    font-size: 14px;
    color: var(--vp-muted);
    text-decoration: underline;
}

.lostpet-quiet__summary:hover {
    color: var(--vp-ink);
}

.lostpet-quiet__body {
    margin-top: var(--space-md);
    max-width: 40rem;
}

/* Social: the kennel showcase, the pet journal and the chats. Shared by the post and journal cards, the feed,
   the inbox and the moderation page, so they live here rather than in one component's stylesheet. */
.social-feed {
    align-items: start;
}

/* One journal entry on its own page reads as a document, not a one-card grid. */
.social-entry {
    max-width: 40rem;
}

/* A report can open a whole conversation, so it takes the full row of the queue grid. */
.social-mod__item--wide {
    grid-column: 1 / -1;
}

.social-post__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs) var(--space-md);
}

.social-post__photos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-xs);
    margin: 0;
    padding: 0;
}

.social-post__photos > li:first-child {
    grid-column: 1 / -1;
}

.social-post__photos img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--radius-md);
    background: var(--vp-photo);
}

.social-post__caption {
    margin: 0;
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.social-post__actions {
    align-items: center;
}

.social-shelves {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-lg);
}

.social-shelf {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
}

.social-shelves--compact {
    gap: var(--space-xs) var(--space-sm);
}

.social-follows {
    gap: var(--space-xs) var(--space-md);
}

.social-composer__files {
    gap: var(--space-xs);
}

/* The browser's file button as a small secondary pill; the browser's own "No file chosen" text is hidden because the
   chosen count and file list below say it. */
.social-composer input[type="file"] {
    padding: 8px 10px;
    color: transparent;
    cursor: pointer;
}

.social-composer input[type="file"]::file-selector-button {
    margin-right: var(--space-sm);
    padding: 6px 14px;
    border: 1px solid var(--vp-line-2);
    border-radius: 999px;
    background: transparent;
    color: var(--vp-ink);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.social-thread {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin: 0;
    padding: 0;
}

.social-msg {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
    max-width: 88%;
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--vp-line);
    border-radius: var(--radius-md);
    overflow-wrap: anywhere;
}

.social-msg--mine {
    align-self: flex-end;
    background: var(--vp-tile);
}

.social-msg--theirs {
    align-self: flex-start;
}

.social-msg__text {
    white-space: pre-wrap;
}

.social-msg__meta {
    font-size: 0.8125rem;
}

.social-inbox__item {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    color: inherit;
    text-decoration: none;
}

.social-inbox__item--unread {
    border-color: var(--vp-copper);
}

.social-inbox__top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-md);
}

.social-inbox__preview {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.social-mod__tabs {
    margin-block: var(--space-md);
}

.social-mod__item {
    gap: var(--space-sm);
}

/* The post or entry, its trust line and its decision buttons sit in one card; the inner card gives up its own frame. */
.social-mod__item--decided > .vp-card {
    padding: 0;
    border: 0;
    box-shadow: none;
    background: none;
}

.social-counter {
    margin: var(--space-2xs) 0 0;
    color: var(--vp-muted);
    font-size: 0.8125rem;
    text-align: right;
}
