/* Tokenbasis nach B-7 (P1).
   Die Namen der bestehenden Tokens bleiben unveraendert; es gibt keinen Rename.
   Geaendert werden in P1 nur Werte: die Rollen fuer Seite, Flaeche, Inset,
   Fussbereich, Rahmen, Text, Akzentflaeche, Akzentrahmen, Fokus, Buttontext,
   Kartenschatten, Basisschrift, Fokusoffset und Inhaltsbreite uebernehmen die
   Werte aus docs/design-drafts/upbiddr-light-draft-b-7.html (Tokens :root und
   html[data-theme="dark"]). Rollen ohne B-7-Gegenstueck (Chip, Rang-, Wert- und
   Bidflaechen) behalten ihren Wert.

   Neu sind nur Rollen, fuer die es bisher kein Token gab: Akzentschrift,
   angehobene Flaeche, Bedien- und Starkrahmen, blasse Schrift, der Rahmen des
   grossen Buttons und der Mittelstopp der Markenlinie, Schatten, Bewegung,
   Schriftgewichte, Headerhoehe, die Statusfarben und die fuer spaetere Pakete
   reservierten Rollen Akzent-tief und Tuerkis.

   --accent bleibt die Fuellfarbe #1463f3 in beiden Themes. Das hellere B-7-Blau
   des Dark Mode liegt deshalb auf --accent-text, damit das gepinnte Paar
   --button-text auf --accent weiter mindestens 4.5 erreicht.

   Beide Themebloecke fuehren dieselben Tokennamen, wie
   tests/Feature/StylesheetTokenIntegrityTest.php es verlangt. */
:root {
    --background: #fbfcfe;
    --surface: #ffffff;
    --surface-2: #f2f5fa;
    --border: #e1e7f0;
    --footer: #f1f4f9;
    --foreground: #0d1526;
    --muted: #4d5a70;
    --accent: #1463f3;
    --accent-soft: #edf4ff;
    --accent-border: #1463f3;
    --accent-gradient-from: #1463f3;
    --accent-gradient-to: #08cdb8;
    --chip: #f2f4f8;
    --chip-border: #e4e7ee;
    --shadow: 0 1px 2px rgba(13, 21, 38, 0.04), 0 3px 10px rgba(13, 21, 38, 0.07);
    --rank1-bg: linear-gradient(165deg, #f7f7fa 0%, #ffffff 64%);
    --rank1-border: #e5e5ea;
    --rank2-bg: #ffffff;
    --rank2-border: #e5e5ea;
    --bid-bg: #f6f9ff;
    --bid-border: #dfe8f7;
    --focus: #1463f3;
    --button-text: #ffffff;
    /* S1-Strukturtokens. In beiden Themes bewusst identisch. */
    --space-1: .25rem;
    --space-2: .5rem;
    --space-3: .75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --space-8: 4rem;
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 18px;
    --font-family-base: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    --focus-ring-width: 2px;
    --focus-ring-offset: 2px;
    --max-content-width: 1180px;
    --motion-base: 200ms;
    /* B-7 P1: neue Rollen. */
    --accent-text: #1463f3;
    --surface-raised: #ffffff;
    --border-control: #8792a6;
    --border-strong: #d3dbe8;
    --text-faint: #636e84;
    --button-lg-border: #9ca7b9;
    --brand-rule-mid: #0fb8b0;
    --shadow-card-strong: 0 2px 4px rgba(13, 21, 38, 0.05), 0 8px 20px rgba(13, 21, 38, 0.1);
    --shadow-overlay: 0 2px 6px rgba(13, 21, 38, 0.1), 0 8px 20px rgba(13, 21, 38, 0.16);
    --motion-fast: 150ms;
    --motion-slow: 260ms;
    --motion-ease: cubic-bezier(.22, .68, .32, 1);
    --font-weight-medium: 560;
    --font-weight-heading: 720;
    --header-height: 4rem;
    --positive: #0a6b4a;
    --positive-soft: #e2f4ee;
    --warning: #7f5209;
    --warning-soft: #fbf1dc;
    --danger: #9d2020;
    --danger-soft: #fae8e8;
    /* B-7 Reserve fuer spaetere Pakete. */
    --accent-deep: #0c46b8;
    --teal: #0a7d72;
    --teal-soft: #e4f7f4;
    /* B-7 full pass: remaining B-7 roles. Neutral field focus, the soft and
       quiet decorative borders, the active favourite heart and the tabular
       figure face of ranks and amounts. */
    --focus-neutral: #55617a;
    --border-soft: #a8b0be;
    --border-quiet: #d3dbe8;
    --heart: #d81e5b;
    --move-control: #818da1;
    --grad-text-from: var(--accent-gradient-from);
    --grad-text-to: var(--accent-gradient-to);
    --live: lab(58 -54.64 46.24);
    --font-family-num: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    /* U44 (operator list 2026-10-21): the borders of the grey surfaces and of
       the one box alone on a page. */
    --border-muted: #d6dde9;
    --border-quiet-muted: #c5cdd9;
    --border-strong-muted: #c5cdd9;
    --border-solo: #d6dde9;
    /* U44.19 to U44.22 (operator list 2026-10-21): the three box groups, each
       styled in one place: the light content boxes (--box-light-*), the
       darker content boxes (--box-muted-*) and the cards with the hover
       shadow (--box-card-*). Each member rule of a group takes its look from
       these tokens only; nested, dashed and overlay boxes keep their own
       rules. The full list of each group: docs/plans/
       2026-10-21-betreiberliste-u00-u83.md, section 4.2. */
    --box-light-border: var(--border);
    --box-light-shadow: var(--shadow);
    --box-muted-bg: var(--surface-2);
    --box-muted-border: var(--border);
    --box-muted-shadow: var(--shadow);
    --box-card-border: var(--border);
    --box-card-shadow: var(--shadow);
    --box-card-shadow-hover: var(--shadow-card-strong);
    color-scheme: light;
}

html[data-theme="dark"] {
    --background: #0a0f18;
    --surface: #131a27;
    --surface-2: #0e1522;
    --border: #262f3e;
    --footer: #070c14;
    --foreground: #e9eef7;
    --muted: #9aa7bd;
    --accent: #1463f3;
    --accent-soft: #0e2138;
    --accent-border: #3d7fe0;
    --accent-gradient-from: #1463f3;
    --accent-gradient-to: #08cdb8;
    --chip: #22252b;
    --chip-border: #343841;
    --shadow: 0 1px 0 rgba(255, 255, 255, 0.03);
    --rank1-bg: linear-gradient(180deg, #1b1b20 0%, #1b1b20 72%);
    --rank1-border: #2b2b32;
    --rank2-bg: #1b1b20;
    --rank2-border: #2b2b32;
    --bid-bg: #141922;
    --bid-border: #26303d;
    --focus: #6ea8ff;
    --button-text: #ffffff;
    /* S1-Strukturtokens. In beiden Themes bewusst identisch. */
    --space-1: .25rem;
    --space-2: .5rem;
    --space-3: .75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --space-8: 4rem;
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 18px;
    --font-family-base: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    --focus-ring-width: 2px;
    --focus-ring-offset: 2px;
    --max-content-width: 1180px;
    --motion-base: 200ms;
    /* B-7 P1: neue Rollen. */
    --accent-text: #5b9dff;
    --surface-raised: #18202f;
    --border-control: #5e6a7b;
    --border-strong: #343d4f;
    --text-faint: #76839a;
    --button-lg-border: #747f91;
    --brand-rule-mid: #0fb8b0;
    --shadow-card-strong: 0 1px 3px rgba(0, 0, 0, 0.35);
    --shadow-overlay: 0 2px 8px rgba(0, 0, 0, 0.6), 0 10px 24px rgba(0, 0, 0, 0.5);
    --motion-fast: 150ms;
    --motion-slow: 260ms;
    --motion-ease: cubic-bezier(.22, .68, .32, 1);
    --font-weight-medium: 560;
    --font-weight-heading: 720;
    --header-height: 4rem;
    --positive: #4ec79c;
    --positive-soft: #0a2a20;
    --warning: #e0b167;
    --warning-soft: #2a2114;
    --danger: #ff9090;
    --danger-soft: #2d1717;
    /* B-7 Reserve fuer spaetere Pakete. */
    --accent-deep: #9cc4ff;
    --teal: #5fd8c7;
    --teal-soft: #0c2b28;
    /* B-7 full pass: remaining B-7 roles. */
    --focus-neutral: #a7b3c6;
    --border-soft: #4b5464;
    --border-quiet: #2b3546;
    --heart: #ff7a9c;
    --move-control: #5f6b7c;
    --grad-text-from: #6ea8ff;
    --grad-text-to: #5fd8c7;
    --live: lab(58 -54.64 46.24);
    --font-family-num: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    --border-muted: #232c3b;
    --border-quiet-muted: #2c3546;
    --border-strong-muted: #353d4f;
    --border-solo: #2d3544;
    --box-light-border: var(--border);
    --box-light-shadow: var(--shadow);
    --box-muted-bg: var(--surface-2);
    --box-muted-border: var(--border);
    --box-muted-shadow: var(--shadow);
    --box-card-border: var(--border);
    --box-card-shadow: var(--shadow);
    --box-card-shadow-hover: var(--shadow-card-strong);
    color-scheme: dark;
}

* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    min-height: 100%;
}

body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--background);
    color: var(--foreground);
    font-family: var(--font-family-base);
    line-height: 1.5;
}

a {
    color: var(--foreground);
}

button:focus-visible,
a:focus-visible,
.theme-toggle:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.skip-link {
    position: absolute;
    left: 0.75rem;
    top: -3rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    padding: 0.4rem 0.7rem;
    z-index: 20;
}

.skip-link:focus {
    top: 0.75rem;
}

.site-header {
    position: sticky;
    top: 0;
    z-index: 8;
    background: var(--background);
    border-bottom: 1px solid var(--border);
}

.header-inner,
main,
.footer-inner {
    width: min(var(--max-content-width), calc(100% - 2rem));
    margin: 0 auto;
}

.header-inner {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem 1rem;
    align-items: center;
    justify-content: space-between;
    padding: 0.85rem 0;
}

.brand {
    font-weight: 750;
    letter-spacing: -0.04em;
    text-decoration: none;
}

.menu-toggle {
    display: none;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--foreground);
    border-radius: 0.75rem;
    padding: 0.35rem 0.7rem;
}

.text-nav {
    display: flex;
    gap: 0.9rem;
}

.text-nav a {
    text-decoration: none;
}

.share-box {
    margin-top: 1.5rem;
    padding: 1rem;
    border: 1px solid var(--border);
    border-radius: 1rem;
    background: var(--surface);
}

.share-box input {
    width: 100%;
    margin: 0.5rem 0;
}

@media (max-width: 720px) {
    .menu-toggle {
        display: inline-flex;
    }

    .header-tools {
        display: none;
        width: 100%;
        flex-direction: column;
        align-items: flex-start;
    }

    .header-tools.is-open {
        display: flex;
    }

    .card-main {
        display: block;
    }

    .bid {
        width: 100%;
        margin-top: 1rem;
    }
}

.header-tools,
.icon-nav,
.footer-nav,
.chips,
.stats,
.card-left {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem;
    align-items: center;
}

.theme-toggle {
    appearance: none;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--foreground);
    border-radius: 999px;
    min-height: 2.25rem;
    padding: 0 0.9rem;
    cursor: pointer;
    font: inherit;
}

.icon-nav a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 0.9rem;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--foreground);
    text-decoration: none;
}

main {
    flex: 1;
    padding: 1.6rem 0 2.5rem;
}

h1 {
    font-size: clamp(1.7rem, 4vw, 2.2rem);
    font-weight: 700;
    letter-spacing: -0.04em;
}

h2 {
    font-size: 1.15rem;
}

.area-chip,
.chip,
.rank-badge,
.badge {
    display: inline-flex;
    align-items: center;
    min-height: 1.7rem;
    padding: 0 0.55rem;
    border-radius: 0.7rem;
    border: 1px solid var(--chip-border);
    background: var(--chip);
    font-size: 0.8rem;
}

.notice,
.bid-note {
    color: var(--muted);
    margin: 0.45rem 0;
}

.ranking-section {
    margin-top: 1.8rem;
}

.ranking-list {
    display: grid;
    gap: 1rem;
}

.listing {
    display: grid;
}

.ranking-card {
    background: var(--surface);
    border: 1px solid var(--box-card-border);
    border-radius: 16px;
    padding: 1rem;
    box-shadow: var(--box-card-shadow);
}

.ranking-card--rank1 {
    background: var(--rank1-bg);
    border-color: var(--rank1-border);
}

.ranking-card--rank2 {
    background: var(--rank2-bg);
    border-color: var(--rank2-border);
}

.card-main {
    display: grid;
    grid-template-columns: 3.6rem minmax(0, 1fr) minmax(11.5rem, 13.5rem);
    gap: 1rem;
    align-items: start;
}

.card-left {
    flex-direction: column;
}

.logo {
    width: 52px;
    height: 52px;
    border-radius: 16px;
    display: grid;
    place-items: center;
    font-weight: 750;
    background: linear-gradient(145deg, #d6e6ff, #b8efe6);
}

html[data-theme="dark"] .logo {
    background: linear-gradient(145deg, #12395f, #1b1b20);
}

.logo--free {
    background: linear-gradient(145deg, #f3f4f6, #e5e7eb);
}

html[data-theme="dark"] .logo--free {
    background: linear-gradient(145deg, #1a1a1f, #2b2b32);
}

.listing-name {
    margin: 0;
    font-size: 1.35rem;
    letter-spacing: -0.04em;
}

.target-link {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.75rem;
    margin: 0.35rem 0 0.55rem;
}

.copy-target {
    appearance: none;
    border: 1px solid var(--chip-border);
    background: var(--chip);
    color: var(--foreground);
    border-radius: 999px;
    padding: 0.15rem 0.7rem;
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

.copy-target-status {
    color: var(--muted);
    font-size: 0.85rem;
}

.target-clicks {
    margin: 0 0 0.45rem;
    color: var(--muted);
    font-size: 0.9rem;
}

.profile-name {
    margin: 0.15rem 0 0.45rem;
    color: var(--muted);
}

.badge {
    border-radius: 999px;
    font-weight: 700;
}

.badge--sponsored {
    background: var(--accent);
    color: var(--button-text);
    border-color: transparent;
}

.badge--free {
    background: var(--chip);
}

.details-toggle {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--foreground);
    font: inherit;
    font-weight: 650;
    cursor: pointer;
    padding: 0;
}

.chevron::before {
    content: "⌄";
}

.details-toggle[aria-expanded="true"] .chevron::before {
    content: "⌃";
}

.bid,
.free-slot {
    border-radius: 16px;
    padding: 0.85rem 0.9rem;
}

.bid {
    background: var(--bid-bg);
    border: 1px solid var(--bid-border);
}

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

.bid-amount {
    margin: 0.15rem 0 0.55rem;
    font-size: 1.5rem;
    font-weight: 750;
    letter-spacing: -0.04em;
}

.outbid {
    appearance: none;
    width: 100%;
    min-height: 2.35rem;
    border: 0;
    border-radius: 14px;
    background: var(--accent);
    color: var(--button-text);
    font: inherit;
    font-weight: 700;
}

.outbid:disabled {
    opacity: 0.72;
    cursor: not-allowed;
}

.free-slot {
    background: var(--surface-2);
    border: 1px dashed var(--border);
    color: var(--muted);
}

.detail-wrap {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transform: translateY(-8px);
    transition: grid-template-rows 220ms ease, opacity 220ms ease, transform 220ms ease;
}

.listing.is-open .detail-wrap {
    grid-template-rows: 1fr;
    opacity: 1;
    transform: translateY(-4px);
}

.detail-clip {
    overflow: hidden;
    min-height: 0;
}

.detail-panel {
    margin: 0 0.6rem 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-top: 0;
    border-radius: 0 0 16px 16px;
    padding: 0.95rem 1rem;
    color: var(--muted);
}

.detail-panel h4 {
    margin: 0 0 0.2rem;
    color: var(--foreground);
}

.site-footer {
    margin-top: auto;
    background: var(--footer);
    border-top: 1px solid var(--border);
}

.footer-inner {
    padding: 1.2rem 0 1.4rem;
    color: var(--muted);
}

.footer-brand {
    margin: 0 0 0.5rem;
    color: var(--foreground);
    font-weight: 650;
}

.footer-nav {
    gap: 0.85rem 1rem;
    margin-bottom: 0.6rem;
}

@media (max-width: 760px) {
    .card-main {
        grid-template-columns: 3.5rem minmax(0, 1fr);
    }

    .bid,
    .free-slot {
        grid-column: 1 / -1;
    }

    .detail-panel {
        margin: 0;
    }
}

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

.auth-form {
    display: grid;
    gap: 0.7rem;
    max-width: 24rem;
}

.auth-form label {
    font-weight: 650;
}

.auth-form input[type="email"],
.auth-form input[type="text"],
.auth-form input[type="url"],
.auth-form select,
.auth-form textarea {
    min-height: 2.5rem;
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    padding: 0 0.8rem;
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
}

.login-code-digits {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.login-code-digits input {
    width: 2.5rem;
    min-height: 2.5rem;
    text-align: center;
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
}


.auth-form button {
    appearance: none;
    min-height: 2.5rem;
    border: 0;
    border-radius: 0.75rem;
    background: var(--accent);
    color: var(--button-text);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.listing-filters {
    display: grid;
    gap: 0.7rem;
    max-width: 24rem;
    margin: 0 0 1.6rem;
}

.listing-filters label {
    font-weight: 650;
}

.listing-filters input[type="text"],
.listing-filters select {
    min-height: 2.5rem;
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    padding: 0 0.8rem;
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
}

.listing-filters button:where(:not(.btn)) {
    appearance: none;
    min-height: 2.5rem;
    border: 0;
    border-radius: 0.75rem;
    background: var(--accent);
    color: var(--button-text);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.listing-empty {
    color: var(--muted);
}

.listing-group {
    margin: 0 0 1.6rem;
}

.listing-group h2 {
    margin: 0 0 0.7rem;
}

.private-listing {
    margin: 0 0 1rem;
    padding: 0.85rem 0.9rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
}

.private-listing p {
    margin: 0.2rem 0;
}

.profile-page {
    display: grid;
    gap: 1rem;
}

.profile-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.85rem 1rem;
}

.profile-tabs a[aria-current="page"] {
    font-weight: 700;
}

.profile-card-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.85rem;
}

.profile-card-list li {
    margin: 0;
    padding: 0.85rem 0.9rem;
    background: var(--surface);
    border: 1px solid var(--box-card-border);
    border-radius: 16px;
}

.profile-card-list p {
    margin: 0.2rem 0 0;
    color: var(--muted);
}

/* Platforms landing page.
   Additive block. Every selector below is new and is used only by
   resources/views/platforms/index.blade.php and
   resources/views/platforms/partials/mini-card.blade.php. No existing global,
   private or admin selector, token, theme block or responsive rule is
   overridden here.

   B-7 platforms (.pf-grid, .pf-box, .pf-head, .mini and the quiet call to
   action, docs/design-drafts/upbiddr-light-draft-b-7.html l.993-1027 and
   l.3306-3398), translated to the existing token names. Like the B-7
   .pf-box:hover (l.1001) the box carries the shared .is-hover-lift of the
   B-7 surfaces block: border and shadow only, nothing moves.
   Each platform heading and call to action is the real filtered list link
   /rankings?platform=slug. */

.platforms-page {
    display: grid;
    gap: var(--space-4);
}

.platforms-page > h1 {
    margin: 0;
}

/* UI02: the intro of Platforms and Leaderboards uses the full width. */
.platforms-intro {
    color: var(--muted);
    margin: 0;
}

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

.platforms-box {
    position: relative;
    overflow: hidden;
    display: grid;
    align-content: start;
    gap: .5rem;
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--box-light-shadow);
}

/* B-7 brand hairline of the platform box, the same line as on a card. */
.platforms-box::before {
    content: "";
    position: absolute;
    top: 0;
    left: 14%;
    right: 14%;
    height: 3px;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
}

/* B-7 .pf-head: the platform name on the left, the number of its public
   cards on the right. */
.platforms-box-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
    margin: 0 0 .25rem;
}

.platforms-box-count {
    flex: none;
    margin: 0;
    color: var(--text-faint);
    font-size: .76rem;
}

.platforms-box-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.028em;
}

.platforms-box-link {
    color: var(--foreground);
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.platforms-box-link:hover {
    color: var(--accent-text);
}

.platforms-mini-card-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .4rem;
}

.platforms-mini-card-item {
    margin: 0;
    padding: 0;
}

/* All three teaser cards share exactly these rules. There is deliberately no
   rank dependent size, colour, typography, border or shadow. */
.platforms-mini-card {
    display: grid;
    grid-template-columns: auto 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: .65rem;
    padding: .5rem .6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--foreground);
    text-decoration: none;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.platforms-mini-card:hover {
    border-color: var(--accent-border);
    background-color: var(--accent-soft);
}

.platforms-mini-card-rank {
    min-width: 1.8rem;
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.platforms-mini-card-logo {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: .78rem;
    font-weight: var(--font-weight-heading);
}

.platforms-mini-card-title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: .9rem;
}

.platforms-mini-card-value {
    color: var(--muted);
    font-family: var(--font-family-num);
    font-size: .84rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.platforms-empty {
    margin: .2rem 0 .45rem;
    color: var(--muted);
    font-size: .89rem;
}

.platforms-cta {
    margin: .25rem 0 0;
}

.platforms-cta-link {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    color: var(--accent-text);
    font-size: .89rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.platforms-cta-link:hover {
    color: var(--accent-deep);
}

/* B-7 .nav-quiet arrow: the same arrow icon as on the home page; it sits 2px
   lower and moves 3px on hover. */
.platforms-cta-arrow {
    flex: none;
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 3.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    transform: translateY(2px);
    transition: transform var(--motion-base) var(--motion-ease);
}

.platforms-cta-link:hover .platforms-cta-arrow {
    transform: translate(3px, 2px);
}

@media (min-width: 761px) {
    .platforms-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Promotion bar (Package B). Additive, namespaced, tokens only. It takes the
   slot and the look of the former staging demo banner above the header: in
   the flow, not sticky. The sanitised content holds only strong, em, b, i,
   br and links; long words and addresses wrap instead of widening the page. */
.promotion-bar {
    margin: 0;
    padding: 0.5rem 1rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    color: var(--foreground);
    font-size: 0.85rem;
    line-height: 1.4;
    text-align: center;
}

.promotion-bar a {
    color: var(--accent-text);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.promotion-bar a:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.promotion-bar.promotion-bar--admin {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

.promotion-bar-source {
    margin: 0;
    white-space: pre-wrap;
}

/* Public ranking card refresh.
   Additive and namespaced. Every selector below starts with .rankshell and is
   used only by resources/views/rankings/partials/card.blade.php. No existing
   global, private or admin selector is redefined, no token is declared here and
   no theme block is opened. Colours come from existing tokens only.

   B-7 RankingCard (.rcard, docs/design-drafts/upbiddr-light-draft-b-7.html
   l.597-758): surface, one pixel border, large radius, light card shadow and
   no movement at all. Hover and keyboard focus come from the shared
   .is-hover-lift contract in the B-7 surfaces block; the card never shifts.
   Logo, rank, title, teaser, chips, value zone and the Details disclosure
   follow the B-7 sizes. Every card carries the same treatment: nothing here
   marks a position, a payment or a quality. The values below are the B-7
   mobile card; the wider column grid lives in the B-7 surfaces block, because
   this block holds a single media rule. */
.rankshell {
    position: relative;
    padding: var(--space-4);
    border-color: var(--box-card-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-card-shadow);
    overflow: hidden;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

/* B-7 brand hairline, identical on every card: it marks the surface, never a
   position, a payment or a quality. */
.rankshell::before {
    content: "";
    position: absolute;
    top: 0;
    left: 14%;
    right: 14%;
    height: 3px;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
}

/* The first three places of every visible list share one identical
   treatment: the larger rank number and the decorative TOP n corner ribbon
   below. The card itself keeps exactly the layout, border and surface of
   every other card. There is no per rank variant, no medal, no crown, no
   star and no winner wording anywhere. */

/* TOP n corner ribbon (operator decision 2026-10-03). The shell is the local
   stack of a top three card: both back tabs sit behind the opaque card
   (z-index 0), the card in the middle (z-index 1) and the band in front of it
   (z-index 2). Every part is aria-hidden and takes no pointer events. The
   geometry is measured from the outer top left card corner; narrow screens
   show the same ribbon at 80 percent through one scale, wider ones at full
   size. */
.rankshell-ribbon-shell {
    position: relative;
    isolation: isolate;
    display: grid;
}

.rankshell-ribbon-shell > .rankshell {
    z-index: 1;
}

.rankshell-ribbon-backs,
.rankshell-ribbon {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    pointer-events: none;
    transform: scale(.8);
    transform-origin: 0 0;
}

.rankshell-ribbon-backs {
    z-index: 0;
}

.rankshell-ribbon {
    z-index: 2;
}

/* Back tabs: only their small overhang past the card edge stays visible. The
   tab colour is the element itself; its own before element is the fold line
   only, kept above an optional local overlay by the isolated tab. */
.rankshell-ribbon-back {
    position: absolute;
    isolation: isolate;
    pointer-events: none;
}

.rankshell-ribbon-back--top {
    top: -3px;
    left: 51px;
    width: 58px;
    height: 9px;
    border-radius: 3.5px 8px 0 0;
    background: var(--teal);
}

.rankshell-ribbon-back--left {
    top: 51px;
    left: -3px;
    width: 9px;
    height: 58px;
    border-radius: 3.5px 0 0 8px;
    background: var(--accent-deep);
}

.rankshell-ribbon-back::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    background: linear-gradient(135deg, transparent 34.56px, var(--foreground) 35.56px, transparent 38.06px);
    opacity: .25;
    pointer-events: none;
}

/* Band: centred on the corner diagonal and turned about its own centre; the
   corner viewport only trims its two outer ends. */
.rankshell-ribbon-viewport {
    position: absolute;
    top: -3px;
    left: -3px;
    width: 180px;
    height: 180px;
    overflow: hidden;
}

.rankshell-ribbon-band {
    position: absolute;
    top: 18.5px;
    left: -65px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 205px;
    height: 40px;
    background: linear-gradient(90deg, var(--accent-gradient-from), var(--accent-gradient-to));
    transform: rotate(-45deg);
    transform-origin: center;
}

/* Exactly two fine light edges along the long band edges. */
.rankshell-ribbon-band::before,
.rankshell-ribbon-band::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--button-text);
    opacity: .32;
}

.rankshell-ribbon-band::before {
    top: 3px;
}

.rankshell-ribbon-band::after {
    bottom: 3px;
}

.rankshell-ribbon-text {
    position: relative;
    z-index: 1;
    color: var(--button-text);
    font-size: 1.0625rem;
    font-weight: 700;
    letter-spacing: .04em;
    line-height: 1;
    white-space: nowrap;
}

/* Band shadow: an empty, transparent copy of the band silhouette inside the
   card. The overflow of the card clips it to the card surface, so it never
   falls on the page or on a back tab, and it lies above the logo and below
   the band. Its transform origin is the outer card corner. */
.rankshell-ribbon-shadow {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    width: 205px;
    height: 40px;
    background: transparent;
    box-shadow: 0 2px 3px var(--foreground);
    opacity: .24;
    pointer-events: none;
    transform: scale(.8) translate(34.5px, 35.5px) rotate(-45deg) translate(-103.5px, -21px);
    transform-origin: -1px -1px;
}

.rankshell .card-main {
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    gap: var(--space-3);
}

.rankshell .card-left {
    align-items: center;
    gap: .4rem;
}

.rankshell .logo {
    width: 3.4rem;
    height: 3.4rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: 1.15rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.03em;
    object-fit: cover;
}

.rankshell .rank-badge {
    justify-content: center;
    min-width: 2.3rem;
    min-height: 1.6rem;
    padding: 0 .55rem;
    border-color: transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: .84rem;
}

.rankshell-rank-num {
    font-weight: var(--font-weight-heading);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

.rankshell-top-three .rankshell-rank-num {
    font-size: 1.4rem;
    line-height: 1;
}

.rankshell-rank-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border-width: 0;
}

.rankshell .card-mid {
    min-width: 0;
}

.rankshell .listing-name {
    margin: 0 0 .32rem;
    font-size: 1.08rem;
    font-weight: var(--font-weight-heading);
    line-height: 1.24;
    letter-spacing: -.032em;
}

.rankshell .listing-name a {
    color: var(--foreground);
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.rankshell .listing-name a:hover {
    color: var(--accent-text);
}

/* B-7 teaser: on the card the description is clamped, to two lines on narrow
   screens and to one line from the wider grid on; the full text stays in the
   Details panel below the card. */
.rankshell .card-mid > p:not([class]) {
    display: -webkit-box;
    max-width: 100%;
    margin: 0 0 .6rem;
    overflow: hidden;
    color: var(--muted);
    font-size: .92rem;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
}

/* B-7 external link icon in the card title (.b4-extlink): a local inline
   icon that scales with the title; a word joiner in the markup keeps it from
   wrapping onto a line of its own. */
.rankshell-extlink {
    display: inline-block;
    flex: none;
    width: .72em;
    height: .72em;
    margin-left: .28em;
    vertical-align: -.04em;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* B-7 chips: small metadata pills, one colour world for every facet. */
.rankshell .chips {
    gap: .35rem;
    margin: 0 0 .55rem;
}

/* B-7 mobile chips (l.1749, l.1766): on narrow screens a long value wraps
   inside its chip instead of being cut; the B-7 surfaces block keeps the
   single line with ellipsis from the wider grid on. */
.rankshell-meta,
.rankshell-facet {
    display: inline-flex;
    align-items: center;
    min-height: 1.85rem;
    max-width: min(100%, 18rem);
    padding: .25rem .55rem;
    overflow: visible;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--muted);
    font-size: .735rem;
    line-height: 1.25;
    text-overflow: clip;
    white-space: normal;
}

/* A facet with a real public filter target is a link to that filtered list;
   the B-7 chips carry their value, the field name is the tooltip. */
.rankshell a.rankshell-facet,
.rankshell a.rankshell-meta {
    text-decoration: none;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}

.rankshell a.rankshell-facet:hover,
.rankshell a.rankshell-meta:hover {
    border-color: var(--accent-border);
    background-color: var(--accent-soft);
    color: var(--accent-text);
}

/* B-7 .rc-stats (RK-02/RK-09, S-02/S-04): Saved (with the heart), Clicks and
   Created as plain text, then the Details trigger on a list card. The
   statistics share the regular gap (1.4rem, twice the former .7rem) inside
   their own group; the row places Details at exactly twice that gap (2.8rem).
   A column gap only exists between items on the same line, so a Details
   trigger that wraps starts its line without any indent. */
.rankshell .stats {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem 2.8rem;
    margin: 0;
    color: var(--text-faint);
    font-size: .8rem;
}

.rankshell .stats-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem 1.4rem;
    min-width: 0;
}

.rankshell-stat {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    line-height: 1.2;
}

/* A32: the icon of each statistic (heart, eye, clock) sits in front of its
   text and is centred on the text line by the inline-flex row of .rankshell-stat. The
   heart of Saved is display only: faint, and red and filled while the
   current account has saved the card. */
.rankshell .rankshell-stat-icon {
    display: inline-flex;
    flex: none;
    align-items: center;
    color: var(--text-faint);
}

.rankshell .rankshell-fav-mark.is-saved {
    color: var(--heart);
}

.rankshell .rankshell-fav-mark.is-saved .ico {
    fill: currentColor;
}

/* RK-06: the visible statistic text is the tooltip trigger, the same B-7
   .b7-info button, bubble and script as the info icon, without the icon. */
/* K-01: unlike the info icon (flex: none), the statistic text may shrink to
   its longest word where its line is too narrow, so that it can wrap. */
.rankshell .b7-info.b7-info--text {
    flex: 0 1 auto;
    width: auto;
    height: auto;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: inherit;
    font: inherit;
    line-height: inherit;
    vertical-align: baseline;
    text-decoration: none;
}

.rankshell .b7-info.b7-info--text:hover,
.rankshell .b7-info.b7-info--text[aria-expanded="true"] {
    background: transparent;
    color: var(--accent-text);
}

/* K-01 (R-01/A-04, operator approval 2026-10-28): a statistic text stays on
   one line wherever it fits; only a text wider than its line (an enlarged
   default font size) breaks between whole words (U53), it is never cut. */
.rankshell .b7-info--text .b7-info__label {
    white-space: normal;
}

/* The statistic text is its own target: the enlarged hit area of the info
   icon on account and profile surfaces (.rd) never reaches over the heart
   or a neighbouring statistic. */
.rankshell .b7-info.b7-info--text::before {
    content: none;
}

/* A32: the one favourite action of the card, a square heart button in the
   B-7 .fav style (l.1053-1080) at the height of the small action buttons
   beside it: "Open card page" and "View profile" under "Card & profile", or
   "View profile" on the detail card. The plain .btn surface; a saved card
   gives it a red, filled heart (U83: no accent box). The B-7 pop runs once
   a save is confirmed: the heart sinks and overshoots, and a ring of the
   button's own radius grows evenly from its centre on all four sides. The
   detail panel pads the row by more than the ring grows, so the clipping
   wrapper of the panel never cuts it. */
.rankshell .rankshell-fav-form {
    display: inline-flex;
    margin: 0;
}

.rankshell .rankshell-fav {
    position: relative;
    width: 2.75rem;
    padding: 0;
    color: var(--text-faint);
}

/* U83 (operator list 2026-10-21): a saved heart is red, while border and
   background stay those of the unsaved button. */
.rankshell .rankshell-fav[aria-pressed="true"] {
    color: var(--heart);
}

.rankshell .rankshell-fav[aria-pressed="true"] .ico {
    fill: currentColor;
}

.rankshell .rankshell-fav[aria-busy="true"] {
    cursor: progress;
}

.rankshell .rankshell-fav.is-pop .ico {
    animation: preview-favpop 420ms var(--motion-ease);
}

.rankshell .rankshell-fav.is-pop::after {
    content: "";
    position: absolute;
    inset: -2px;
    border: 2px solid var(--heart);
    border-radius: var(--radius-md);
    pointer-events: none;
    animation: preview-burst 480ms var(--motion-ease) forwards;
}

/* B-7 .disc: the Details trigger is an accent text button with the plus and
   minus swap, never underlined. */
.rankshell-toggle:not([hidden]) {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 2.75rem;
    padding: .55rem 0;
    border-radius: var(--radius-sm);
    color: var(--accent-text);
    font-size: .85rem;
    font-weight: var(--font-weight-medium);
    transition: color var(--motion-fast) var(--motion-ease);
}

.rankshell-toggle:hover {
    color: var(--accent-deep);
}

.rankshell-chevron {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 16px;
    height: 16px;
}

.rankshell-chevron > svg {
    position: absolute;
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease);
}

.rankshell-toggle[aria-expanded="false"] .rankshell-minus {
    opacity: 0;
    transform: rotate(-90deg) scale(.6);
}

.rankshell-toggle[aria-expanded="true"] .rankshell-plus {
    opacity: 0;
    transform: rotate(90deg) scale(.6);
}

/* B-7 subcard (.subcard, .subcard-in): the Details panel is an inset surface
   inside its card. Without JavaScript it stays open and the trigger stays
   hidden, as in the B-7 noscript rule. Once the script marks the card
   foldable, the panel folds with the B-7 grid row animation, and a folded
   panel is hidden, so its links leave the tab order. */
.rankshell .detail-wrap {
    grid-template-rows: 1fr;
    opacity: 1;
    transform: none;
    transition: none;
}

.rankshell.is-foldable .detail-wrap {
    grid-template-rows: 0fr;
    visibility: hidden;
}

.rankshell.is-foldable.is-open .detail-wrap {
    grid-template-rows: 1fr;
    visibility: visible;
}

/* Motion only once the folded state has been applied, so the panels do not
   visibly fold away on page load. */
.rankshell.is-settled .detail-wrap {
    transition: grid-template-rows var(--motion-slow) var(--motion-ease), visibility 0s linear var(--motion-slow);
}

.rankshell.is-settled.is-open .detail-wrap {
    transition: grid-template-rows var(--motion-slow) var(--motion-ease), visibility 0s linear 0s;
}

.rankshell .detail-panel {
    margin: .75rem 0 0;
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--foreground);
    font-size: .92rem;
}

.rankshell .detail-panel h3 {
    margin: 0 0 .3rem;
    color: var(--foreground);
    font-size: .85rem;
    font-weight: var(--font-weight-heading);
}

.rankshell .detail-panel > p {
    margin: 0 0 .8rem;
    color: var(--muted);
    font-size: .88rem;
}

/* B-7 .linkrow and .linkbox: the target in a framed box next to its copy
   button. */
.rankshell .detail-panel .target-link {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: .5rem;
    margin: 0 0 .8rem;
}

/* RK-08: Visit target sits right of Copy target link in the target row; the
   button keeps its words whole (the row breaks long target URLs). K-11
   (R-01/A-04, operator approval 2026-10-28): it stays on one line where it
   fits and wraps between whole words only where the row has no room for it
   (an enlarged default font size). */
.rankshell .detail-panel .target-link .btn {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    min-height: 2.75rem;
    word-break: normal;
}

/* RK-10: the heading of the card and profile actions, like the other
   headings of the Details panel. */
.rankshell .detail-panel .rankshell-actions-heading {
    margin-top: .2rem;
}

.rankshell-linkbox {
    display: inline-flex;
    flex: 1 1 18rem;
    align-items: center;
    gap: .5rem;
    min-width: 0;
    min-height: 2.75rem;
    padding: 0 .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--accent-text);
    font-size: .89rem;
    text-decoration: none;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.rankshell-linkbox:hover {
    background-color: var(--accent-soft);
}

.rankshell-url {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rankshell .copy-target:not([hidden]) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    min-height: 2.75rem;
    padding: 0 1.05rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .93rem;
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.rankshell .copy-target:hover {
    background-color: var(--surface-2);
}

.rankshell .copy-target-status {
    align-self: center;
    color: var(--text-faint);
    font-size: .8rem;
}

/* B-7 action row of the subcard: open the card page, copy and share the card
   link, visit the target. A paragraph whose button the script left hidden
   takes no place in the row. */
.rankshell-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
}

.rankshell-actions > p {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin: 0;
}

.rankshell-actions > p:has(> button[hidden]) {
    display: none;
}

.rankshell-actions .copy-target-status:empty {
    display: none;
}

/* B-7 touch targets (l.1758-1766): every action of the subcard is at least
   44px high on narrow screens; the B-7 surfaces block returns them to the
   small button height from the wider grid on. */
.rankshell-actions .copy-target:not([hidden]),
.rankshell-actions .btn--sm {
    min-height: 2.75rem;
}

.rankshell-actions .copy-target:not([hidden]) {
    padding: 0 .8rem;
    font-size: .84rem;
}

/* B-7 value zone (.rc-value): no box of its own. On narrow screens it is a
   grid under a thin divider, labels on top, the value on the left and the
   action on the right; the B-7 surfaces block moves it into the right column.
   The origin label (B-7 .lbl-origin) sits above the value. */
.rankshell .bid {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: .2rem .75rem;
    margin: 0;
    padding: var(--space-3) 0 0;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: transparent;
}

.rankshell-labels {
    display: flex;
    grid-column: 1 / -1;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .3rem;
    margin: 0 0 .25rem;
}

.rankshell-origin {
    display: inline-flex;
    align-items: center;
    min-height: 1.15rem;
    padding: 0 .4rem;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
    font-size: .64rem;
    font-weight: var(--font-weight-medium);
    letter-spacing: .02em;
    line-height: 1;
    white-space: nowrap;
}

.rankshell .bid-label {
    grid-column: 1;
    margin: 0;
    color: var(--text-faint);
    font-size: .65rem;
    letter-spacing: .04em;
    line-height: 1.3;
    text-transform: uppercase;
}

.rankshell .bid-amount {
    grid-column: 1;
    margin: 0;
    font-family: var(--font-family-num);
    font-size: 1.28rem;
    font-weight: var(--font-weight-heading);
    font-variant-numeric: tabular-nums;
    letter-spacing: -.04em;
    line-height: 1.05;
}

.rankshell .bid-note {
    grid-column: 2;
    grid-row: 2 / span 2;
    align-self: end;
    margin: 0;
}

/* B-7 .rc-claim: the full primary button; on narrow screens with a narrower
   padding and text (l.1738), so the value keeps its line. */
.rankshell .bid-note .btn {
    padding-inline: .75rem;
    font-size: .86rem;
}

/* Claim rank: the two actions of a card value (Claim rank, Increase value)
   side by side, wrapping below each other when the column is narrow. They sit
   in their own row under label and amount (full grid width), so the value zone
   does not break apart on narrow screens; from 761px the value zone is a flex
   column and these grid placements have no effect. */
.rankshell .bid-note--pair {
    grid-column: 1 / -1;
    grid-row: auto;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.rankshell .bid-note--pair .btn {
    flex: 1 1 auto;
}

@media (prefers-reduced-motion: reduce) {
    .rankshell,
    .rankshell .listing-name a,
    .rankshell a.rankshell-facet,
    .rankshell a.rankshell-meta,
    .rankshell-toggle:not([hidden]),
    .rankshell-chevron > svg,
    .rankshell-toggle[aria-expanded="false"] .rankshell-minus,
    .rankshell-toggle[aria-expanded="true"] .rankshell-plus,
    .rankshell.is-settled .detail-wrap,
    .rankshell.is-settled.is-open .detail-wrap,
    .rankshell-linkbox,
    .rankshell .copy-target:not([hidden]) {
        transition: none;
        transform: none;
    }
}

/* Public content pages (B-7). Home page and the static info pages About, FAQ,
   Rules, Contact, Imprint and Privacy. Additive and namespaced: every selector
   starts with .home- or .info-page, only existing tokens, no media rule and no
   motion. The layout adapts through clamp() and auto-fit grids. The two hero
   actions are B-7 buttons from the foundation block; this block only lays out
   their row. */
/* U23 (operator list 2026-10-21): the hero sits close above the three home
   cards (the gap of the cards themselves), so both read as one area. */
.home-hero {
    position: relative;
    overflow: hidden;
    display: grid;
    justify-items: center;
    gap: var(--space-3);
    margin: 0 0 var(--space-4);
    padding: clamp(var(--space-6), 7vw, var(--space-8)) clamp(var(--space-4), 5vw, var(--space-6));
    text-align: center;
    background: var(--surface);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-xl);
    box-shadow: var(--box-light-shadow);
}

.home-hero::before {
    content: "";
    position: absolute;
    top: 0;
    left: 14%;
    right: 14%;
    height: 3px;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from), var(--accent-gradient-to));
}

.home-hero h1 {
    margin: 0;
    font-size: clamp(2.6rem, 7vw, 4.3rem);
    line-height: 1.05;
    letter-spacing: -.05em;
}

/* UI02 (operator order 2026-10-24): slogan, subtitle and subline use the
   full width of the hero (its padding stays); the closing phrase of the
   slogan stays together as one unit and may only wrap inside itself when
   the line is too short for it. */
.home-slogan {
    margin: 0;
    font-size: clamp(1.2rem, 3.5vw, 1.45rem);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.03em;
}

.home-slogan-phrase {
    display: inline-block;
    max-width: 100%;
}

.home-subtitle {
    margin: 0;
    color: var(--muted);
    font-size: 1.05rem;
    text-wrap: balance;
}

/* NK21 (operator list 2026-10-23): the subline under the subtitle, a little
   smaller and fainter; UI02: without a measure of its own. */
.home-subline {
    margin: 0;
    color: var(--text-faint);
    font-size: .95rem;
    text-wrap: balance;
}

.home-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    min-width: 0;
    margin: var(--space-5) 0 0;
}

.home-cards {
    display: grid;
    grid-template-columns: minmax(min(100%, 16rem), 1fr);
    gap: var(--space-4);
    margin: 0 0 var(--space-7);
}

.home-card {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--box-light-shadow);
}

.home-card h3 {
    margin: 0;
    font-size: 1.04rem;
    letter-spacing: -0.02em;
}

.home-card p {
    margin: 0;
    color: var(--muted);
    font-size: .88rem;
}

.home-card p + p {
    margin-top: .35rem;
}

/* The link paragraph closes every card at its bottom edge, whatever the text
   length above it; the cards of a row keep the stretched grid height. The
   padding keeps the former minimum distance to the text. */
.home-card > p:last-child {
    margin-top: auto;
    padding-top: .35rem;
}

/* A26 (Q26.1): the heading of a home block takes the full width; only the
   short subtitle sentence keeps the 62ch reading width of the B-7 .sec-head
   (l.359), see below. */
.home-sec-head {
    margin: 0 0 var(--space-5);
}

.home-sec-head h2 {
    margin: .7rem 0 0;
    font-size: clamp(1.5rem, 3.4vw, 2.05rem);
    line-height: 1.12;
    letter-spacing: -0.035em;
}

/* B-7 .sec-head p (l.359-377): the short subtitle sentence under the eyebrow
   and the heading of a home block. Its width is the former 62ch of the head,
   measured in the head's type size (this sentence is set at .95rem). */
/* UI02: the subtitle of a home block uses the full width of the block. */
.home-sec-head p:not(.home-eyebrow) {
    margin: .45rem 0 0;
    color: var(--muted);
    font-size: .95rem;
}

/* Home figures block under the three cards: the section head above the
   statistics row of partials/site-stats. */
.home-figures {
    margin: 0 0 var(--space-7);
}

.home-figures .pv-stats {
    margin: 0;
}

/* Home figures only: the head and its subtitle sentence (see the rule after
   the top-5 block) use the full content width; the 62ch cap of the subtitle
   stays for every other home block. */
.home-figures .home-sec-head {
    max-width: none;
}

/* Home figures only: the site-wide visitor group and the four public figures
   each form their own row over the full content width, boxes evenly
   distributed. The space between the rows and the space between the boxes
   of a row are one token, var(--space-3), the gap of .pv-stats. Each group
   keeps its row shape as long as its boxes keep the B-7 box minimum of
   .pv-stats, 11rem: the three visitor boxes stay one row of three, the four
   figures two rows of two; only below that width does every box of the group
   take the full width. The term (… - 100%) * 999 is a step: very large
   while the group is narrower than the width it needs, negative from there
   on. So a row never ends with a lone box, without a media query. The four
   figures share one row in the surfaces block from 981px on. */
.home-figures .pv-stats--home {
    display: flex;
    flex-direction: column;
}

.home-figures .pv-stats-group {
    display: grid;
    gap: var(--space-3);
    min-width: 0;
}

.home-figures .pv-stats-group--visitors {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(11rem, (3 * 11rem + 2 * var(--space-3) - 100%) * 999)), 1fr));
}

/* 34% is more than a third of the group: never three columns, always two. */
.home-figures .pv-stats-group--figures {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(34%, (2 * 11rem + var(--space-3) - 100%) * 999)), 1fr));
}

/* Home top-5 block: its head and subtitle keep the full width they had when
   the 62ch cap (the B-7 .sec-head width) still sat on the whole head and
   "The five highest ranking cards right now" wrapped early on wide
   viewports. Since A26 no home heading is capped. */
.home-top-cards .home-sec-head {
    max-width: none;
}

/* The subtitles of these two blocks keep their full width (A26 moved the cap
   from the head to the subtitle). */
.home-figures .home-sec-head p:not(.home-eyebrow),
.home-top-cards .home-sec-head p:not(.home-eyebrow) {
    max-width: none;
}

/* Operator decision: .home-eyebrow now follows the B-7 draft's .eyebrow
   (l.361-367 of the draft) type values, ending the earlier deliberate
   deviation. */
.home-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin: 0;
    padding: .3rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: .71rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .14em;
    text-transform: uppercase;
}

.home-eyebrow::before {
    content: "";
    width: 14px;
    height: 2px;
    border-radius: 1px;
    background: linear-gradient(90deg, var(--accent-gradient-from), var(--accent-gradient-to));
}

/* B-7 .grad: the brand gradient on a key phrase of a large heading. As with
   the primary button, the teal end is light against the page; the limit is
   documented and not claimed to pass the text contrast threshold. */
.home-grad {
    background: linear-gradient(90deg, var(--grad-text-from), var(--grad-text-to));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

/* U-01 (Bestandsaudit 2026-10, P2): the steps keep the same block distance
   as every other block of the home page (space-7); hero -> top cards keep
   their own decided 16px (U23.01). */
.home-steps {
    margin: 0 0 var(--space-7);
}

.home-steps ol {
    display: grid;
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.home-steps li {
    min-width: 0;
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--box-light-shadow);
}

.home-steps h3 {
    margin: .6rem 0 .3rem;
    font-size: .85rem;
}

.home-steps li p {
    margin: 0;
    color: var(--muted);
    font-size: .88rem;
}

/* B-7 P1: the top ranking cards preview reuses the real card partial and the
   existing .ranking-list grid; this rule only carries the section's own
   bottom rhythm (NK28: the arrow link under the list is .home-more). */
.home-top-cards {
    margin: 0 0 var(--space-7);
}

/* NK23 (operator list 2026-10-23): the three boxes with their own section
   head keep the bottom rhythm the box row had on its own. */
.home-benefits {
    margin: 0 0 var(--space-7);
}

.home-benefits .home-cards {
    margin: 0;
}

/* NK28: "View all rankings" and "View all FAQs", the arrow links of the
   home cards, right-aligned at the outer edge of their block. */
.home-more {
    display: flex;
    justify-content: flex-end;
    margin: var(--space-4) 0 0;
}

/* NK28: the honest example card stands in the top block while there is no
   public card, with the heading look it has beside the empty list. */
.home-top-cards .ranking-example > h2 {
    margin: 0 0 var(--space-3);
    color: var(--foreground);
    font-size: 1rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

/* NK27: the latest activity, the box row of /rankings under its head. */
.home-activity {
    margin: 0 0 var(--space-7);
}

.home-activity-note {
    margin: 0;
    color: var(--text-faint);
    font-size: .88rem;
}

/* NK25: four answers in two columns where two fit next to each other (each
   column at least 34%, so never three), one column otherwise; the boxes of
   the home steps. */
.home-faq {
    margin: 0 0 var(--space-7);
}

.home-faq-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(34%, 20rem)), 1fr));
    gap: var(--space-4);
}

.home-faq-item {
    min-width: 0;
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--box-light-shadow);
}

.home-faq-item h3 {
    margin: 0 0 .35rem;
    font-size: .95rem;
    letter-spacing: -0.01em;
}

.home-faq-item p {
    margin: 0;
    color: var(--muted);
    font-size: .88rem;
}

/* NK26: the two closing actions, centred as one group; they wrap below each
   other where the row is too narrow for both. */
.home-cta {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    min-width: 0;
    margin: 0 0 var(--space-7);
}

/* UI03 (operator order 2026-10-24): the content pages share the width of
   About and FAQ; a confirmation page keeps 52rem through .info-page--narrow.
   Order 2026-10-29, point 1: 55rem (880px at the unchanged root size, was
   66rem). With the 1.375rem margin of .nav-main the left content edge meets
   the start of the first menu item from 1212px; between 981px and 1211px
   the header shrinks with the window and the two lines differ (accepted,
   B4). */
.info-page {
    display: grid;
    gap: var(--space-4);
    max-width: 55rem;
    margin: 0 auto;
}

.info-page.info-page--narrow {
    max-width: 52rem;
}

.info-page h1 {
    margin: 0;
}

/* UI02 (operator order 2026-10-24): the text under the title uses the full
   width of the page container (the former 70ch cap is gone). */
.info-page > p {
    margin: 0;
    color: var(--muted);
    font-size: 1.08rem;
}

.info-page .listing-group {
    margin: 0;
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--box-light-shadow);
}

.info-page .listing-group h2,
.info-page .listing-group h3 {
    margin: 0 0 var(--space-3);
}

/* UI02: the paragraphs of a group (About, FAQ answers, the sitemap note)
   use the full width of their box. Text breaks only between whole words
   (U53/K1): an overlong word or URL scrolls sideways inside its paragraph. */
.info-page .listing-group p {
    margin: 0 0 var(--space-3);
    overflow-x: auto;
}

.info-page .listing-group ul {
    margin: 0;
    padding-left: var(--space-5);
}

/* B-7 accordion (.acc): each question is a quiet framed block; the native
   details element stays the disclosure, so it opens without JavaScript. */
.info-page .listing-group details {
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.info-page .listing-group details + details {
    margin-top: var(--space-2);
}

.info-page .listing-group details p {
    margin: 0 var(--space-4) var(--space-4);
    color: var(--muted);
}

.info-page .listing-group summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: .85rem 1rem;
    list-style: none;
    cursor: pointer;
    font-weight: var(--font-weight-medium);
}

.info-page .listing-group > :last-child {
    margin-bottom: 0;
    padding-bottom: 0;
}

.info-page .notice {
    padding: var(--space-3) var(--space-4);
    color: var(--foreground);
    background: var(--accent-soft);
    border-left: 3px solid var(--accent-border);
    border-radius: var(--radius-md);
}

/* Contact form preview while sending is not switched on: the fields of the
   active form as one disabled fieldset, with the B-7 disabled look
   (.btn[disabled]: opacity .45, not-allowed cursor). */
.info-page .contact-form-off {
    min-width: 0;
    margin: 0 0 var(--space-3);
    padding: 0;
    border: 0;
}

.info-page .contact-form-off input:disabled,
.info-page .contact-form-off select:disabled,
.info-page .contact-form-off textarea:disabled,
.info-page .contact-form-off button:disabled {
    opacity: .45;
    cursor: not-allowed;
}

/* B-7 foundation. Shared components from docs/design-drafts/upbiddr-light-draft-b-7.html,
   translated to the existing token names: row, buttons, card, lede, alert and
   empty state. Only component classes are styled here, never bare elements, so
   member and admin surfaces are not restyled by accident.

   Primary button, B-7 .btn--primary: a blue to teal to blue gradient twice as
   wide as the button, white text, a transparent border in every state and no
   shadow. U43 (operator list 2026-10-21): only the home hero button
   (.btn--hero) keeps the B-7 hover, the gradient sliding to the other side;
   every other primary button keeps its gradient in place and darkens by
   about 12 percent on hover (the overlay of the operator package section at
   the end of this file). On press it darkens slightly. The focus ring is the
   shared one.
   Documented limit, confirmed by the operator: white text reaches about 5.1:1
   on the blue end and only about 2.0:1 on the teal end. That is below the 4.5:1
   text threshold and is not claimed to pass it.

   Secondary button, B-7 .btn.btn--lg: surface, one pixel border, primary text;
   on hover the inset surface and the control border; on press a mix of inset and
   strong border. Transitions are switched off under reduced motion. */
.row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    min-height: 2.75rem;
    padding: 0 1.05rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .93rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease);
}

.btn:hover {
    background-color: var(--surface-2);
    border-color: var(--border-control);
}

.btn:active {
    background-color: color-mix(in srgb, var(--surface-2) 80%, var(--border-strong));
}

.btn[disabled],
.btn[aria-disabled="true"] {
    opacity: .45;
    cursor: not-allowed;
}

.btn--sm {
    min-height: 2.2rem;
    padding: 0 .8rem;
    font-size: .84rem;
}

.btn--lg {
    min-height: 3.1rem;
    padding: 0 1.5rem;
    border-color: var(--button-lg-border);
    font-size: 1rem;
}

.btn--lg:hover {
    border-color: var(--border-control);
}

.btn--ghost {
    border-color: transparent;
    background: transparent;
}

.btn--ghost:hover {
    border-color: var(--border);
    background: var(--surface-2);
}

.btn--danger {
    border-color: color-mix(in srgb, var(--danger) 32%, var(--border));
    color: var(--danger);
}

.btn--danger:hover {
    border-color: var(--danger);
    background: var(--danger-soft);
}

.btn--primary {
    border-color: transparent;
    background-color: var(--accent-gradient-from);
    background-image: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--accent-gradient-to) 50%, var(--accent-gradient-from) 100%);
    background-size: 200% 100%;
    background-position: 0% 50%;
    background-repeat: no-repeat;
    background-origin: border-box;
    background-clip: border-box;
    color: var(--button-text);
    transition: background-position var(--motion-slow) var(--motion-ease), filter var(--motion-fast) var(--motion-ease);
}

.btn--primary:hover,
.btn--primary:active,
.btn--primary:focus,
.btn--primary:focus-visible {
    border-color: transparent;
}

.btn--primary:hover {
    background-color: var(--accent-gradient-from);
    background-image: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--accent-gradient-to) 50%, var(--accent-gradient-from) 100%);
}

.btn--primary:active {
    filter: brightness(.94);
}

.card {
    position: relative;
    padding: var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.card--lift:hover {
    border-color: var(--border-strong);
    box-shadow: var(--box-card-shadow-hover);
}

.card--hair {
    overflow: hidden;
}

.card--hair::before {
    content: "";
    position: absolute;
    top: 0;
    left: 14%;
    right: 14%;
    height: 3px;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
}

.lede {
    color: var(--muted);
    font-size: 1.08rem;
}

.alert {
    display: flex;
    gap: .75rem;
    padding: .85rem 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    font-size: .89rem;
}

.alert--info {
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
    background: var(--accent-soft);
}

.alert--ok {
    border-color: color-mix(in srgb, var(--positive) 30%, transparent);
    background: var(--positive-soft);
}

.alert--warn {
    border-color: color-mix(in srgb, var(--warning) 30%, transparent);
    background: var(--warning-soft);
}

.alert--err {
    border-color: color-mix(in srgb, var(--danger) 30%, transparent);
    background: var(--danger-soft);
}

.alert strong {
    display: block;
}

.alert .ico {
    flex: none;
    margin-top: .1rem;
}

.empty {
    padding: var(--space-7) var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    text-align: center;
}

.empty p {
    max-width: 46ch;
    margin: .45rem auto var(--space-4);
    color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
    .btn,
    .btn--primary,
    .card {
        transition: none;
    }
}

/* B-7 site chrome. Skip link, header, menu and footer from
   docs/design-drafts/upbiddr-light-draft-b-7.html (header l.286-354, tooltip
   l.936-951, footer l.1029-1040), translated to the existing token names.

   Without JavaScript the bar shows the brand and the account link, and the
   menu list sits below it as plain links that wrap, so every header
   destination stays reachable. The theme and menu buttons only appear once
   public/js/app.js has set the js class; that class also turns the list into
   the B-7 menu panel and, from 981px, shows the main navigation in the bar.
   Search and notifications have no product function and are not rendered.
   The primary menu action shares the documented contrast limit of the primary
   button in the foundation block. */
.skip-link {
    top: -4rem;
    padding: .6rem .9rem;
    border-color: var(--border-control);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-overlay);
    color: var(--foreground);
    text-decoration: none;
}

/* Without JavaScript the header scrolls with the page: it carries the whole
   menu list then, and it could not hide on scroll. Q12.2 / A12 (UIR-12): the
   prefixed blur keeps the frosted bar in older WebKit (Safari 17 and before);
   a compatibility addition, not checked in a shipped Safari. */
.site-header {
    position: static;
    background: color-mix(in srgb, var(--background) 88%, transparent);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    backdrop-filter: blur(12px) saturate(140%);
    border-bottom-color: var(--border-strong);
    transition: transform var(--motion-slow) var(--motion-ease);
}

.js .site-header {
    position: sticky;
}

.site-header.is-hidden {
    transform: translateY(-101%);
}

.hdr-in {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 var(--space-4);
    width: min(var(--max-content-width), calc(100% - 2rem));
    min-height: var(--header-height);
    margin: 0 auto;
}

.brand {
    display: inline-flex;
    color: var(--foreground);
    font-size: 1.24rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.045em;
    text-decoration: none;
}

/* Operator decision: the word mark is the two local, theme-aware logo
   images (upbiddr-logo-full-dark.svg for the light theme, -light.svg for the
   dark theme), swapped by data-theme only. Only one of the two is ever
   shown; the accessible name comes once from the visually-hidden text next
   to them. */
.brand-logo {
    display: block;
    height: 1.75rem;
    width: auto;
}

.brand-logo--on-dark {
    display: none;
}

html[data-theme="dark"] .brand-logo--on-light {
    display: none;
}

html[data-theme="dark"] .brand-logo--on-dark {
    display: block;
}

/* Order 2026-10-29, point 1: 1.375rem (22px), so the start of the first
   menu item meets the left edge of the 55rem content pages on desktop. The
   bar only shows from 981px. */
.nav-main {
    display: none;
    gap: .15rem;
    margin-left: 1.375rem;
}

.nav-main a {
    position: relative;
    margin-inline: .55rem;
    padding: .42rem .2rem;
    border-radius: var(--radius-sm);
    color: var(--muted);
    font-size: .92rem;
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.nav-main a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: .1rem;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
    transform: scaleX(0);
    transform-origin: center;
    transition: transform var(--motion-base) var(--motion-ease);
}

.nav-main a:hover,
.nav-main a[aria-current] {
    color: var(--foreground);
}

.nav-main a[aria-current] {
    font-weight: var(--font-weight-medium);
}

.nav-main a:hover::after,
.nav-main a[aria-current]::after {
    transform: scaleX(1);
}

/* K-03 (R-01/A-04, operator approval 2026-10-28): where the tools do not fit
   on one line (an enlarged default font size on a narrow screen), the last
   ones move to a second line at the right edge; otherwise nothing changes. */
.hdr-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .25rem;
    margin-left: auto;
}

.iconbtn,
.hdr-stats,
.site-header .theme-toggle {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--foreground);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.site-header .theme-toggle {
    display: none;
}

/* NK36 (operator list 2026-10-23): the theme button shows with the script;
   while scripting is enabled it already keeps its place from the first
   paint (see the NK section at the end), so the header does not shift, but
   only as an invisible place: public/js/app.js sets .js once the button
   switches the theme, so a blocked, failed or not yet loaded script never
   leaves a button that does nothing. The menu button is the summary of the
   native menu disclosure and shows with or without the script. */
.js .site-header .theme-toggle {
    display: inline-grid;
    visibility: visible;
}

.menu-d > summary.hdr-menu {
    list-style: none;
}

.menu-d > summary.hdr-menu::-webkit-details-marker {
    display: none;
}

.iconbtn:hover,
.hdr-stats:hover,
.site-header .theme-toggle:hover {
    background-color: var(--surface-2);
    border-color: var(--border-strong);
}

.iconbtn:active,
.hdr-stats:active,
.site-header .theme-toggle:active,
.iconbtn[aria-expanded="true"],
.hdr-stats[aria-expanded="true"],
.menu-d[open] > .hdr-menu {
    background-color: var(--accent-soft);
    border-color: var(--accent-border);
}

.iconbtn[aria-expanded="true"],
.hdr-stats[aria-expanded="true"],
.menu-d[open] > .hdr-menu {
    color: var(--accent-text);
}

/* A57: back to top, a B-7 icon button (.iconbtn) on the surface with the
   resting card shadow, so it reads over any content. Without the script it
   is the last line of the page, on the right; with it, it floats in the
   lower right corner above the safe area and only shows once the page is
   scrolled. UI-03 (operator decision 2026-10-21): it stays in that corner
   also over the footer at the end of the page; the bottom row of the
   footer keeps the room the button needs on its right (below). */
.to-top-wrap {
    display: flex;
    justify-content: flex-end;
    margin: 0;
    padding: 0 var(--space-4) var(--space-4);
}

.to-top {
    border-color: var(--border);
    background-color: var(--surface);
    box-shadow: var(--shadow);
}

.js .to-top-wrap {
    padding: 0;
}

.js .to-top {
    position: fixed;
    right: max(1rem, env(safe-area-inset-right));
    bottom: max(1rem, env(safe-area-inset-bottom));
    z-index: 40;
    opacity: 0;
    visibility: hidden;
    transform: translateY(.5rem);
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base), background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.js .to-top.is-shown {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s, background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

/* The header overlays (menu, login window, statistics) sit above it. */
.js body:has(.site-header.is-overlay-open) .to-top {
    visibility: hidden;
}

/* UI-03: at the end of the page the button covers the lower right corner of
   the viewport (its 2.75rem plus the corner gap). Only the bottom row of
   the footer reaches into that band; it keeps exactly the part of the
   button's width that lies over the footer content (none where the page
   margin beside the centred footer is wider than the button), plus a
   .5rem gap. */
.js .f-bottom {
    padding-inline-end: max(0px, calc(max(1rem, env(safe-area-inset-right)) + 3.25rem - max((100vw - var(--max-content-width)) / 2, 1rem)));
}

.ico {
    flex: none;
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.ico--sm {
    width: 15px;
    height: 15px;
}

.swap {
    position: relative;
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
}

.swap > * {
    position: absolute;
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease);
}

.t-sun,
html[data-theme="dark"] .t-moon,
.hdr-menu .m-x,
.menu-d[open] > .hdr-menu .m-bars {
    opacity: 0;
    transform: scale(.65) rotate(-35deg);
}

html[data-theme="dark"] .t-sun,
.menu-d[open] > .hdr-menu .m-x {
    opacity: 1;
    transform: none;
}

.tip-bub {
    position: absolute;
    top: 50%;
    right: calc(100% + .45rem);
    z-index: 1;
    padding: .32rem .6rem;
    border-radius: var(--radius-sm);
    background: var(--foreground);
    color: var(--surface);
    font-size: .76rem;
    line-height: 1.3;
    white-space: nowrap;
    opacity: 0;
    transform: translateY(-50%) translateX(4px);
    pointer-events: none;
    transition: opacity var(--motion-fast) var(--motion-ease), transform var(--motion-fast) var(--motion-ease);
}

.iconbtn:hover .tip-bub,
.iconbtn:focus-visible .tip-bub,
.hdr-stats:hover .tip-bub,
.hdr-stats:focus-visible .tip-bub,
.site-header .theme-toggle:hover .tip-bub,
.site-header .theme-toggle:focus-visible .tip-bub {
    opacity: 1;
    transform: translateY(-50%);
}

/* The menu button names itself like the other header icons; while its panel
   is open the tooltip gives way, so it never covers the menu. */
.menu-d[open] > .hdr-menu .tip-bub,
.hdr-stats[aria-expanded="true"] .tip-bub {
    opacity: 0;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* NK36 (operator list 2026-10-23): the panel of the native menu disclosure.
   It is only rendered while the disclosure is open, so it is the dropdown
   panel with and without the script; the script adds its motion. */
.menu-panel {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 1;
    display: block;
    width: min(20rem, calc(100vw - 2rem));
    margin-top: .5rem;
    padding: .5rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
}

.menu-nav {
    display: block;
}

.menu-link {
    display: flex;
    align-items: center;
    gap: .65rem;
    min-height: 2.75rem;
    padding: .6rem .7rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--foreground);
    font-size: .95rem;
    text-decoration: none;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.menu-link:hover {
    background-color: var(--surface-2);
    border-color: var(--border);
}

.menu-sep {
    display: block;
    height: 1px;
    margin: .45rem .3rem;
    background: var(--border);
}

.menu-actions {
    display: grid;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
    gap: .5rem;
    padding: .3rem;
}

/* With the script the rendered panel waits closed until .is-open. */
.js .menu-panel {
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px) scale(.985);
    pointer-events: none;
}

.js .menu-panel.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

/* Motion only once the closed state has been applied, so the static list does
   not fade out on page load. */
.js .menu-panel.is-ready {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base);
}

.js .menu-panel.is-ready.is-open {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s;
}

/* NK09 (operator list 2026-10-23): the icon and title row of the menu and
   the account window, the head row of the statistics and the login window. */
.menu-pop-title {
    display: flex;
    align-items: center;
    gap: .65rem;
    margin: 0;
    padding: .35rem .5rem .6rem;
    color: var(--foreground);
    font-size: .9rem;
    font-weight: var(--font-weight-heading);
    line-height: 1.3;
}

.menu-pop-icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
}

.site-footer {
    background: var(--footer);
    border-top-color: var(--border);
}

.footer-inner {
    width: min(var(--max-content-width), calc(100% - 2rem));
    padding: var(--space-7) 0 var(--space-5);
    color: var(--muted);
}

.f-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
}

.footer-brand {
    margin: 0;
    color: var(--foreground);
    font-size: 1.24rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.045em;
}

/* U31 (operator list 2026-10-21): the footer word mark links to the home
   page like the header brand; the link keeps the image size and the focus
   ring of every link. */
.footer-brand-link {
    display: inline-flex;
    color: inherit;
    text-decoration: none;
}

.footer-nav {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: var(--space-5);
    margin: 0;
}

.footer-nav h2 {
    margin: 0 0 var(--space-3);
    color: var(--text-faint);
    font-size: .73rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .09em;
    text-transform: uppercase;
}

.footer-nav ul {
    display: grid;
    gap: .35rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: .89rem;
}

.footer-nav a {
    color: var(--muted);
    text-decoration: none;
}

.footer-nav a:hover {
    color: var(--accent-text);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* The electronic withdrawal function link: always in the link colour. */
.footer-nav a.f-link--accent {
    color: var(--accent-text);
}

/* A43/A56: below 761px the three link groups are light native accordions
   (B-7 .disc with its plus and minus) and Contract Withdrawal stands on its
   own under them; the columns show from 761px only (media rule below). The
   hidden variant is display: none, so only the visible links take focus. */
.footer-nav .f-col {
    display: none;
}

.f-accs {
    display: grid;
}

.f-acc {
    border-bottom: 1px solid var(--border-soft);
}

.f-acc > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-height: 2.75rem;
    padding: .45rem 0;
    color: var(--text-faint);
    cursor: pointer;
    list-style: none;
}

.f-acc > summary::-webkit-details-marker {
    display: none;
}

.footer-nav .f-acc > summary h2 {
    margin: 0;
}

.f-acc > summary:hover {
    color: var(--accent-text);
}

.f-acc[open]:not([data-disclosure-closing]) > summary .b7-chev__plus {
    opacity: 0;
    transform: rotate(90deg) scale(.6);
}

.f-acc[open]:not([data-disclosure-closing]) > summary .b7-chev__minus {
    opacity: 1;
    transform: none;
}

.f-acc > ul {
    padding-bottom: var(--space-4);
}

.f-acc-extra {
    margin: var(--space-4) 0 0;
    font-size: .89rem;
}

.f-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-4);
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-soft);
    color: var(--text-faint);
    font-size: .8rem;
}

.f-bottom p {
    margin: 0;
}

@media (min-width: 761px) {
    .footer-nav {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .footer-nav .f-col {
        display: block;
    }

    .f-accs {
        display: none;
    }
}

@media (min-width: 981px) {
    /* NK36: the main navigation shows from 981px with or without the script. */
    .nav-main {
        display: flex;
    }

    .f-grid {
        grid-template-columns: minmax(0, 1.3fr) minmax(0, 2.8fr) minmax(0, 1.9fr);
    }
}

@media (max-width: 400px) {
    .brand {
        font-size: 1.05rem;
    }

    .site-header .brand-logo {
        height: 1.5rem;
    }

    .hdr-tools {
        gap: 0;
    }

    .iconbtn,
    .hdr-stats,
    .site-header .theme-toggle {
        width: 2.5rem;
        height: 2.5rem;
    }

    /* U19: the login window intent line steps its font down so that it
       stays on one line (the base rule follows later, hence the window
       scope). */
    .login-pop .login-pop-lede {
        font-size: .76rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .site-header,
    .nav-main a,
    .nav-main a::after,
    .iconbtn,
    .hdr-stats,
    .site-header .theme-toggle,
    .swap > *,
    .tip-bub,
    .menu-link,
    .js .menu-panel.is-ready,
    .js .menu-panel.is-ready.is-open,
    .js .to-top,
    .js .to-top.is-shown {
        transition: none;
    }
}

/* B-7 surfaces. The remaining surfaces of docs/design-drafts/upbiddr-light-draft-b-7.html
   on the existing markup, translated to the existing token names: the footer
   copy, social row and benefits list (B-7 footer l.4542-4593, l.1600-1631),
   the header login window (B-7 .pop and .menu-panel), the shared hover lift
   (.card--lift, .rcard), the rankings page (filter bar, card grid, Details
   panel, share box, card contexts), the public profile and the private,
   login and admin surfaces (card, field, table, button).

   Scope: every selector starts with one of the namespaces listed in
   tests/Feature/B7SurfacesStylesheetTest.php. The member, login and admin
   views keep their plain markup; the layout names their surface on the main
   wrapper (.surface--member, .surface--auth, .surface--admin), and the rules
   below give the bare elements inside the B-7 look. A hidden element stays
   hidden: no rule sets display on a bare element without :not([hidden]).

   Hover lift. .is-hover-lift is an opt-in class next to .card--lift, never a
   replacement. It goes on a card whose purpose is its link or links: the
   public ranking card, the ranking entries of a public profile, the three
   home benefit cards (B-7 .card--lift, l.2061) and the platform boxes (B-7
   .pf-box:hover, l.1001). Pure information surfaces such as the rules card,
   the steps and the info pages never carry it. The stronger border and shadow appear on
   hover only on devices that really hover, and on keyboard focus inside;
   nothing moves, and reduced motion drops the transition.

   Primary actions. The login and filter buttons use the B-7 primary button of
   the foundation block, with its documented contrast limit: white text reaches
   about 5.1:1 on the blue end and only about 2.0:1 on the teal end, which is
   below the 4.5:1 text threshold and is not claimed to pass it. */

/* Footer. */
.f-about {
    display: grid;
    align-content: start;
    gap: var(--space-3);
    min-width: 0;
}

.f-promo {
    max-width: 34ch;
    margin: 0;
    color: var(--muted);
    font-size: .89rem;
}

.b7-gradef {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.b7-gradef__from {
    stop-color: var(--accent-gradient-from);
}

.b7-gradef__to {
    stop-color: var(--accent-gradient-to);
}

.f-social-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .55rem;
}

.f-social__label {
    color: var(--muted);
    font-size: .84rem;
}

.f-social {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.f-social__link {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-sm);
    color: var(--text-faint);
    transition: color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.f-social__link:hover {
    color: var(--accent-text);
    background-color: var(--accent-soft);
}

.f-social__link svg {
    width: 18px;
    height: 18px;
}

/* The brand marks are filled shapes. Hover and keyboard focus colour them in
   the Upbiddr gradient; the surface change stays, so the state never depends
   on colour alone. */
.b7-brand {
    fill: currentColor;
    stroke: none;
}

.f-social__link:hover .b7-brand,
.f-social__link:focus-visible .b7-brand {
    fill: url(#b7-social-grad);
}

.f-social__link .tip-bub {
    top: auto;
    right: auto;
    bottom: calc(100% + .45rem);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
}

.f-social__link:hover .tip-bub,
.f-social__link:focus-visible .tip-bub {
    opacity: 1;
    transform: translateX(-50%);
}

.f-why {
    min-width: 0;
}

.f-why h2 {
    margin: 0 0 var(--space-3);
    color: var(--text-faint);
    font-size: .73rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .09em;
    text-transform: uppercase;
}

.f-benefits {
    display: grid;
    gap: .35rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: .89rem;
}

.f-benefits li {
    display: flex;
    align-items: flex-start;
    gap: .4rem;
    color: var(--muted);
}

.f-benefits__icon {
    flex: none;
    width: 15px;
    height: 15px;
    margin-top: .22rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    color: var(--accent-text);
}

/* AFR-2 (Q55), UI-02 (operator decision 2026-10-21): the payment methods of
   the public footer, one wrapping list of equal text chips (Cards with the
   generic card symbol, then the method names; no brand marks), whose last
   item is the closing "and more – powered by Stripe" as plain text: it wraps
   with the chips, never on a row of its own by force. The chips use the
   surface tokens of both themes. Information only, nothing here is
   interactive. */
.f-pay {
    display: flex;
    align-items: center;
    min-width: 0;
    min-height: 2.75rem;
    padding-block: var(--space-2);
}

.f-pay__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.f-pay__item {
    display: flex;
    flex: none;
    align-items: center;
}

.f-pay__item--text {
    gap: .25rem;
    height: 1.5rem;
    padding: 0 .375rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    /* NK15 (operator list 2026-10-23): text and card symbol in the muted colour. */
    color: var(--muted);
    font-size: .6875rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
}

.f-pay__card {
    width: 14px;
    height: 14px;
}

/* K-03 (R-01/A-04, operator approval 2026-10-28): the closing line moves to
   the next line as a whole as before; only where it is wider than a whole
   line (an enlarged default font size) it breaks between whole words. */
.f-pay__more {
    color: var(--muted);
    font-size: .8rem;
}

/* B-7 fields: .field holds a label and a control, .inp is the B-7 input.
   Hover takes the inset surface; focus keeps the B-7 neutral field focus, a
   darker neutral edge on the inset surface instead of a coloured or browser
   ring. That neutral focus is the confirmed B-7 contract for input fields:
   a one pixel edge change plus the surface change. */
.field {
    margin: 0 0 var(--space-4);
}

.field > label:not([hidden]) {
    display: block;
    margin: 0 0 .35rem;
    font-size: .83rem;
    font-weight: var(--font-weight-medium);
}

.inp {
    width: 100%;
    max-width: 100%;
    min-height: 2.75rem;
    padding: .55rem .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .93rem;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.inp:hover {
    background-color: var(--surface-2);
}

.inp:focus {
    outline: none;
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.inp:focus-visible {
    outline: none;
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.inp[readonly] {
    background: var(--surface-2);
    color: var(--muted);
}

/* Login window. Hidden by its attribute until the script runs; from then on
   the closed window is hidden from pointer, keyboard and assistive technology
   alike. Its surface, size and motion are the B-7 menu panel; the head row is
   the B-7 panel head with the icon box of the notification panel. */
.js .login-pop {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 1;
    width: min(20rem, calc(100vw - 2rem));
    margin-top: .5rem;
    padding: .5rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px) scale(.985);
    pointer-events: none;
}

.js .login-pop.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.js .login-pop.is-ready {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base);
}

.js .login-pop.is-ready.is-open {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s;
}

.login-pop-title {
    display: flex;
    align-items: center;
    gap: .65rem;
    margin: 0;
    padding: .35rem .5rem .6rem;
    font-size: .9rem;
    font-weight: var(--font-weight-heading);
    line-height: 1.3;
}

.login-pop-icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
}

.login-pop-form {
    padding: 0 .5rem .5rem;
}

.login-pop-form .field {
    margin-bottom: var(--space-3);
}

/* U19 (operator list 2026-10-21): the intent line of the login page above the
   email title of the login window, on one line; up to 400px the font steps
   down so that it fits (measured in tests/js/operator-package-a.test.mjs).
   K-02 (R-01/A-04, operator approval 2026-10-28, the one exception to U19):
   where the sentence does not fit into the window (an enlarged default font
   size), it breaks between whole words instead of running past the window
   and widening the page. */
.login-pop-lede {
    margin: 0 0 var(--space-3);
    color: var(--muted);
    font-size: .84rem;
    line-height: 1.4;
}

.login-pop-submit {
    width: 100%;
}

/* Hover lift. */
.is-hover-lift {
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

/* A29: the home hero takes the hover shadow of the B-7 card lift
   (.card--lift), without any movement. A28: the latest activity boxes of
   the rankings page keep their normal shadow and take the same hover
   shadow; the box row has room for it (see .hscroll-track). */
.home-hero,
.ranking-page .b4-feed-card,
.home-activity .b4-feed-card {
    transition: box-shadow var(--motion-base) var(--motion-ease);
}

/* UI04 (operator order 2026-10-24): the activity cards of the home page
   take the same focus and hover shadow as those of /rankings. */
.ranking-page a.b4-feed-card:focus-visible,
.home-activity a.b4-feed-card:focus-visible {
    box-shadow: var(--box-card-shadow-hover);
}

.is-hover-lift:focus-visible,
.is-hover-lift:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):focus-visible) {
    box-shadow: var(--box-card-shadow-hover);
}

/* Rankings page. */
.ranking-page {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}

.ranking-page > h1 {
    margin: 0;
}

.ranking-page > p {
    margin: 0;
}

.ranking-page > p > a {
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.ranking-page > p > a:hover {
    color: var(--accent-deep);
}

/* B-7 list head: the title on the left, the share button top right. The
   statistics row and the notice follow below the head at full width. */
.ranking-page .ranking-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
}

/* A26: the title box has no reading width of its own; it spans the head
   up to the share button, so a long title and the info bubble use the
   row. Body text widths elsewhere stay. */
.ranking-page .ranking-intro {
    display: grid;
    gap: .35rem;
    min-width: 0;
}

.ranking-page .ranking-intro h1 {
    margin: 0 0 .2rem;
}

/* The single list notice under the head: the smaller notice type of the
   former second notice, over the full width of the rankings content. The
   grid gap of .ranking-page spaces it; the global .notice rule stays as it
   is. */
.ranking-page .ranking-notice {
    margin: 0;
    color: var(--text-faint);
    font-size: .76rem;
}

/* Rankings statistics row: the B-7 boxes of .pv-stats (minimum 11rem) on the
   full width. Up to the width at which all six boxes fit in one row the row
   has exactly three columns (26% is more than a quarter of the row), so six
   boxes form two rows of three and three boxes one full row; from that width
   on the .pv-stats rule applies unchanged. Below 26% = 11rem (container 677px)
   the 11rem minimum wins and the row is the same as before. The term
   (… - 100%) * 999 is a step: very large below that width, negative from it
   on. No media query. */
.ranking-page .pv-stats--rankings {
    grid-template-columns: repeat(auto-fit, minmax(max(min(11rem, 100%), min(26%, (6 * 11rem + 5 * var(--space-3) - 100%) * 999)), 1fr));
}

/* Without JavaScript the share box is an ordinary box below the head. With it,
   the popover trigger (2.75rem) sits vertically centred on the h1 line box
   next to it: the offset repeats the exact h1 rule below (its clamp()
   font-size times the inherited 1.5 line-height) rather than a guessed
   constant, so it keeps tracking the title at every width. */
.ranking-page .rankings-share {
    position: relative;
    flex: none;
    margin-top: calc((clamp(1.7rem, 4vw, 2.2rem) * 1.5 - 2.75rem) / 2);
}

.ranking-page .ranking-head:has(.rankings-share:not(.is-popover)) {
    flex-wrap: wrap;
}

.ranking-page .rankings-share:not(.is-popover) {
    flex-basis: 100%;
    margin-top: 0;
}

/* B-7 .sharebtn: a square icon box; open, it carries the accent. */
.ranking-page .rankings-share-btn:not([hidden]) {
    display: inline-grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}

.ranking-page .rankings-share-btn:hover {
    border-color: var(--border-control);
    background-color: var(--surface-2);
}

.ranking-page .rankings-share-btn[aria-expanded="true"] {
    border-color: var(--accent);
    background-color: var(--accent-soft);
    color: var(--accent-text);
}

/* B-7 .pop in the style of the menu panel: closed until opened, motion only
   once the closed state is settled. */
.ranking-page .rankings-share.is-popover .rankings-share-panel {
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    z-index: 5;
    width: min(30rem, calc(100vw - 2rem));
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px) scale(.985);
    pointer-events: none;
}

.ranking-page .rankings-share.is-popover .rankings-share-panel.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.ranking-page .rankings-share.is-popover .rankings-share-panel.is-ready {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base);
}

.ranking-page .rankings-share.is-popover .rankings-share-panel.is-ready.is-open {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s;
}

.ranking-page .rankings-share.is-popover .share-box {
    gap: .45rem;
    padding: var(--space-4);
    border-color: var(--border-strong);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
}

.ranking-page .rankings-share.is-popover .share-box h2 {
    font-size: .85rem;
}

.ranking-page .rankings-share.is-popover .share-box > p {
    color: var(--text-faint);
    font-size: .76rem;
}

.ranking-page .rankings-share.is-popover .share-box > p:has(> a) {
    display: none;
}

.ranking-page .rankings-share.is-popover .share-box button:not([hidden]) {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
}

/* B-7 filter bar (.fbar-wrap). The five native selects and the Apply button
   of the plain GET form stay fully usable without JavaScript: the fields then
   wrap onto further lines. With the script the row scrolls sideways with a
   hidden scrollbar, the chevron buttons and fading edges appear only when
   there is more to scroll, and Apply stays on the right. As in B-7 the field
   shows its value only; the label stays for assistive technology. The option
   list of a native select is drawn by the browser and the system; only the
   closed field follows B-7. */
.ranking-page .listing-filters {
    display: block;
    max-width: none;
    margin: 0;
}

.ranking-page .filter-bar {
    position: relative;
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem;
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

/* A30: a bar whose fields scroll sideways is a calm inset, without the
   shadow; its side fades take the same surface. */
.ranking-page .filter-bar.is-scrollable {
    border: 1px solid var(--border-soft);
    background: var(--box-muted-bg);
    box-shadow: none;
}

.ranking-page .filter-scroll {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
}

.ranking-page .filter-track {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}

.ranking-page .filter-bar.is-scrollable .filter-track {
    flex-wrap: nowrap;
    margin: -.15rem;
    padding: .15rem;
    overflow-x: auto;
    scrollbar-width: none;
}

.ranking-page .filter-bar.is-scrollable .filter-track::-webkit-scrollbar {
    display: none;
}

.ranking-page .filter-fade {
    position: absolute;
    top: -.15rem;
    bottom: -.15rem;
    width: calc(2rem + .15rem);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--motion-base) var(--motion-ease);
}

.ranking-page .filter-fade.is-on {
    opacity: 1;
}

.ranking-page .filter-fade--left {
    left: -.15rem;
    background: linear-gradient(90deg, var(--surface), transparent);
}

.ranking-page .filter-fade--right {
    right: -.15rem;
    background: linear-gradient(270deg, var(--surface), transparent);
}

.ranking-page .filter-bar.is-scrollable .filter-fade--left {
    background: linear-gradient(90deg, var(--surface-2), transparent);
}

.ranking-page .filter-bar.is-scrollable .filter-fade--right {
    background: linear-gradient(270deg, var(--surface-2), transparent);
}

/* B-7 .fnav: a square icon box with a chevron. */
.ranking-page .filter-nav:not([hidden]) {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 2.35rem;
    height: 2.35rem;
    min-height: 0;
    padding: 0;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), opacity var(--motion-fast) var(--motion-ease);
}

/* The visible box keeps its B-7 size; a transparent layer of .2rem beyond
   the outer border edge on each side makes the target 2.75rem (44px), the
   B-7 touch size (l.1760). The offset starts at the padding edge, so it also
   covers the 1px border. It stays inside the .5rem gap and padding of the
   bar, so it covers neither the scrolling track nor the Apply button, and a
   hidden chevron has none. */
.ranking-page .filter-nav:not([hidden])::after {
    content: "";
    position: absolute;
    inset: calc(-.2rem - 1px);
}

.ranking-page .filter-nav:hover {
    background-color: var(--surface-2);
}

.ranking-page .filter-nav[disabled] {
    opacity: .32;
    cursor: default;
}

.ranking-page .filter-field {
    position: relative;
    flex: none;
    max-width: 100%;
}

/* Without the script the bar wraps: a field never grows wider than the row,
   and Apply moves below the fields only when the row is full. */
.ranking-page .filter-bar:not(.is-scrollable) {
    flex-wrap: wrap;
}

.ranking-page .filter-bar:not(.is-scrollable) .listing-filters select,
.ranking-page .filter-bar:not(.is-scrollable) select {
    max-width: 100%;
}

.ranking-page .listing-filters label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* B-7 .fsw-btn on the native select, with the two stacked B-7 chevrons. */
.ranking-page .listing-filters select {
    appearance: none;
    field-sizing: content;
    max-width: 100%;
    min-height: 2.2rem;
    padding: 0 1.9rem 0 .7rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background-color: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .86rem;
    white-space: nowrap;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}

.ranking-page .listing-filters select:hover {
    background-color: var(--surface-2);
}

.ranking-page .listing-filters select:focus {
    outline: none;
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.ranking-page .listing-filters select:focus-visible {
    outline: none;
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.ranking-page .listing-filters option {
    background-color: var(--surface);
    color: var(--foreground);
}

.ranking-page .filter-chev {
    position: absolute;
    top: 50%;
    right: .7rem;
    display: inline-grid;
    gap: 1px;
    justify-items: center;
    color: var(--text-faint);
    transform: translateY(-50%);
    pointer-events: none;
}

.ranking-page .filter-chev svg {
    display: block;
    width: 11px;
    height: 7px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.1;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.ranking-page .filter-chev-up {
    opacity: .55;
}

/* B-7 .fsw-btn.is-set: a field with a chosen value is marked. */
.ranking-page .listing-filters select:has(option:checked:not([value=""])) {
    border-color: var(--accent);
    background-color: var(--accent-soft);
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

.ranking-page .filter-field:has(option:checked:not([value=""])) .filter-chev {
    color: var(--accent-text);
}

.ranking-page .listing-filters .filter-bar button[type="submit"] {
    flex: none;
    min-height: 2.35rem;
    padding: 0 .75rem;
    font-size: .86rem;
}

/* B-7 list separator (.b4-sep): purely visual structure after the first ten
   places; it says nothing about quality, success or value. */
.ranking-page .ranking-sep {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin: var(--space-2) 0;
}

.ranking-page .ranking-sep::before,
.ranking-page .ranking-sep::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--border-strong);
}

.ranking-page .ranking-sep-label {
    flex: none;
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .7rem;
    font-weight: var(--font-weight-medium);
    letter-spacing: .16em;
    text-transform: uppercase;
}

/* B-7 control row above the list: the time range on the left where it
   exists, the result count, the active filters as facet chips and the reset
   on the right. Every value comes from the validated filter state. */
.ranking-page .ranking-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3) var(--space-4);
    margin: var(--space-4) 0;
}

.ranking-page .ranking-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-left: auto;
}

.ranking-page .ranking-results {
    color: var(--text-faint);
    font-size: .76rem;
}

/* P1g: an active filter chip is a plain link that removes exactly its own
   value, derived from .chip; the border pill and its "×" keep the same look
   the earlier read-only span had. */
.ranking-page .chip--facet {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    min-height: 1.85rem;
    padding: 0 .55rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--muted);
    font-size: .735rem;
    line-height: 1.25;
    text-decoration: none;
    transition: border-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}

.ranking-page .chip--facet:hover {
    border-color: var(--border-control);
    color: var(--foreground);
}

/* A20b: inside the summary every item has the height of a facet chip, so
   wrapped rows keep the same gap; the reset is no taller than a chip and an
   invisible layer above and below it, inside the row gap, keeps its touch
   target at 2.75rem. Only the count of a narrow portrait screen is taller
   (A20c). The chip group adds no box of its own outside A20d. */
.ranking-page .ranking-summary .ranking-results {
    line-height: 1.85rem;
}

.ranking-page .ranking-summary .ranking-facets {
    display: contents;
}

.ranking-page .ranking-summary .ranking-reset {
    position: relative;
    min-height: 1.85rem;
    padding: 0 .7rem;
}

.ranking-page .ranking-summary .ranking-reset::after {
    content: "";
    position: absolute;
    inset: -.5rem 0;
}

/* B-7 empty state (.empty): the icon box, the sentence as its heading, a
   calm explanation and two actions. */
.ranking-page .ranking-empty h2 {
    margin: 0;
    color: var(--foreground);
    font-size: 1.04rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

.ranking-page .ranking-empty p {
    max-width: 46ch;
    margin: .45rem auto var(--space-4);
    color: var(--muted);
}

.ranking-page .ranking-empty-icon {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    margin: 0 auto .6rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-faint);
}

.ranking-page .ranking-empty .ranking-empty-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    margin-bottom: 0;
}

/* P1a example card beside an empty list: the section wrapper and its
   heading only. The card itself (rankings/partials/example-card.blade.php)
   reuses the real card classes below (.rankshell, .card-main, .chips, .bid,
   ...), so it needs no card-shaped rules of its own here. */
.ranking-page .ranking-example {
    margin: var(--space-5) 0 0;
}

.ranking-page .ranking-example > h2 {
    margin: 0 0 var(--space-3);
    color: var(--foreground);
    font-size: 1rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

/* P1a demo brand mark: the example card is the only .rankshell that shows
   the Upbiddr brand mark instead of a target logo, so its logo box gets a
   neutral fill and its image fills the box without cropping the mark. */
.rankshell.example-card .logo {
    background: var(--surface-2);
}

.rankshell.example-card .logo img {
    width: 100%;
    height: 100%;
    padding: var(--space-2);
    object-fit: contain;
}

/* "Open in this ranking" anchors a list card by id (#card-{slug}); the
   sticky header must not then cover it. */
.rankshell[id] {
    scroll-margin-top: calc(var(--header-height) + 1rem);
}

/* B-7 page row under the list: the shown range on the left, the page links
   as small B-7 buttons on the right; the current page carries the accent. */
.ranking-page .ranking-pages {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin: var(--space-4) 0 0;
}

.ranking-page .ranking-showing {
    margin: 0;
    color: var(--text-faint);
    font-size: .76rem;
}

.ranking-page .ranking-pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .3rem;
}

.ranking-page .ranking-pagination .btn {
    min-height: 2.75rem;
    min-width: 2.75rem;
}

.ranking-page .ranking-pagination .btn[aria-current="page"] {
    border-color: var(--accent);
    background-color: var(--accent-soft);
    color: var(--accent-text);
}

.ranking-page .ranking-page-gap {
    padding: 0 .2rem;
    color: var(--text-faint);
}

/* B-7 filter field (.fsw-btn) built by the script from each native select:
   only as wide as its value, the two stacked chevrons turn their weight when
   the panel opens, and a chosen value is marked. The native select stays in
   the form and carries the value. */
.ranking-page .filter-field .b7-fsw-btn {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    min-height: 2.75rem;
    padding: 0 .7rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background-color: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .86rem;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}

.ranking-page .filter-field .b7-fsw-btn:hover,
.ranking-page .filter-field .b7-fsw-btn[aria-expanded="true"] {
    background-color: var(--surface-2);
}

.ranking-page .filter-field .b7-fsw-btn.is-set {
    border-color: var(--accent);
    background-color: var(--accent-soft);
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

.b7-fsw-chev {
    display: inline-grid;
    flex: none;
    gap: 1px;
    justify-items: center;
    color: var(--text-faint);
}

.ranking-page .filter-field .b7-fsw-btn.is-set .b7-fsw-chev,
.ranking-page .filter-field .b7-fsw-btn[aria-expanded="true"] .b7-fsw-chev {
    color: currentColor;
}

.b7-fsw-chev svg {
    display: block;
    width: 11px;
    height: 7px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.1;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: opacity var(--motion-base) var(--motion-ease);
}

.ranking-page .filter-field .b7-fsw-btn[aria-expanded="false"] .filter-chev-up {
    opacity: .55;
}

.ranking-page .filter-field .b7-fsw-btn[aria-expanded="true"] .filter-chev-up {
    opacity: 1;
}

.ranking-page .filter-field .b7-fsw-btn[aria-expanded="true"] .filter-chev-down {
    opacity: .3;
}

/* B-7 .fpanel: the option panel of a filter field. It lives outside the
   scrolling row, so it is never cut off, stays closed and out of reach until
   it is opened, and moves only once the script marked it ready. */
.b7-fpanel {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 50;
    width: min(18.5rem, calc(100vw - 1.75rem));
    max-height: min(19rem, calc(100vh - 8rem));
    padding: .4rem;
    overflow: auto;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    transform: translateY(-6px) scale(.985);
}

.b7-fpanel.is-ready {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base);
}

.b7-fpanel.is-open {
    visibility: visible;
    opacity: 1;
    pointer-events: auto;
    transform: none;
}

.b7-fpanel.is-ready.is-open {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s;
}

/* A22: a group head has more room above it to its divider; the options of
   a labelled group sit slightly indented against it (the same hierarchy as
   the statistics panel). */
.b7-fgroup-label {
    margin-top: .3rem;
    padding: .8rem .6rem .3rem;
    border-top: 1px solid var(--border);
    color: var(--text-faint);
    font-size: .69rem;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.b7-fgroup:first-child .b7-fgroup-label {
    margin-top: 0;
    border-top: 0;
}

.b7-fgroup:has(> .b7-fgroup-label) > .b7-fopt {
    /* Order 2026-10-29, point 8: 1.6rem (was .95rem). */
    padding-left: 1.6rem;
}

/* NK05 (operator list 2026-10-23): the options of a filter or selection
   panel keep a small distance to each other, so the hover fill of an option
   never touches the accent frame of the selected one directly. Options
   hidden by the search (NK16) take no gap. */
.b7-fgroup {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.b7-fopt {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    width: 100%;
    min-height: 2.75rem;
    padding: .48rem .6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--foreground);
    font: inherit;
    font-size: .87rem;
    text-align: left;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.b7-fopt:hover {
    border-color: var(--border);
    background-color: var(--surface-2);
}

.b7-fopt[aria-selected="true"] {
    border-color: var(--accent);
    background-color: var(--accent-soft);
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

.b7-fcount {
    flex: none;
    color: var(--text-faint);
    font-size: .76rem;
    font-weight: var(--font-weight-medium);
}

/* NK16 (operator list 2026-10-23): the search field at the top of an option
   panel, in the B-7 field look (.inp) with the magnifier of the B-7 header
   search on the right; while it holds text the magnifier gives way to the
   clear button. It stays at the top while the list scrolls under it, and a
   focused option scrolls into view below it. Options and groups without a
   match are hidden; the note says when nothing matches. */
.b7-fpanel.has-search {
    scroll-padding-top: 3.25rem;
}

.b7-fsearch {
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0 calc(-.4rem - 1px);
    padding: 0 calc(.4rem + 1px) .4rem;
    background: var(--surface);
}

.b7-fsearch[hidden] {
    display: none;
}

.b7-fsearch .b7-fsearch__input {
    min-height: 2.5rem;
    padding: .45rem 2.5rem .45rem .7rem;
    font-size: .87rem;
}

.b7-fsearch .b7-fsearch__input::placeholder {
    color: var(--text-faint);
    opacity: 1;
}

.b7-fsearch__ico {
    position: absolute;
    top: calc(1.25rem - 7.5px);
    right: calc(.4rem + 1px + .75rem);
    color: var(--text-faint);
    pointer-events: none;
}

.b7-fsearch.has-query .b7-fsearch__ico {
    display: none;
}

.b7-fsearch__clear {
    position: absolute;
    top: .375rem;
    right: calc(.4rem + 1px + .375rem);
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.b7-fsearch__clear:hover {
    background-color: var(--surface-2);
    color: var(--foreground);
}

.b7-fsearch__clear[hidden],
.b7-flist .b7-fgroup[hidden],
.b7-flist .b7-fopt[hidden] {
    display: none;
}

.b7-fempty {
    margin: 0;
    padding: .55rem .6rem .65rem;
    color: var(--muted);
    font-size: .86rem;
}

/* B-7 .b7-info: a small info icon whose bubble explains a setting. Hover and
   keyboard focus show it through this rule, the script adds click and tap,
   Escape and the outside click. Layout containment keeps the closed bubble
   from widening the page. */
.b7-info {
    position: relative;
    z-index: 7;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 1.05rem;
    height: 1.05rem;
    margin-left: .3rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--text-faint);
    vertical-align: super;
    cursor: pointer;
    contain: layout;
    transition: color var(--motion-fast) var(--motion-ease);
}

.b7-info:hover,
.b7-info[aria-expanded="true"] {
    color: var(--accent-text);
}

.b7-info svg {
    width: 1.05rem;
    height: 1.05rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.b7-info__bub {
    position: absolute;
    bottom: calc(100% + .45rem);
    left: 50%;
    z-index: 1;
    width: max-content;
    max-width: min(19rem, calc(100vw - 2.5rem));
    padding: .4rem .6rem;
    border-radius: var(--radius-sm);
    background: var(--foreground);
    color: var(--surface);
    font-size: .76rem;
    font-weight: 400;
    line-height: 1.4;
    letter-spacing: normal;
    text-align: left;
    text-transform: none;
    opacity: 0;
    pointer-events: none;
    transform: translateX(-50%) translateY(4px);
    transition: opacity var(--motion-fast) var(--motion-ease), transform var(--motion-fast) var(--motion-ease);
}

.b7-info:hover .b7-info__bub,
.b7-info:focus-visible .b7-info__bub,
.b7-info[aria-expanded="true"] .b7-info__bub {
    opacity: 1;
    transform: translateX(-50%);
}

.b7-info.b7-info--below .b7-info__bub {
    top: calc(100% + .45rem);
    bottom: auto;
    transform: translateX(-50%) translateY(-4px);
}

.b7-info.b7-info--below:hover .b7-info__bub,
.b7-info.b7-info--below:focus-visible .b7-info__bub,
.b7-info.b7-info--below[aria-expanded="true"] .b7-info__bub {
    transform: translateX(-50%);
}

.ranking-page .listing-filters button[type="submit"],
.surface--auth .auth-form:has(> input:not([type="hidden"])) button,
.surface--auth main > form:only-of-type button,
.surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"],
.surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"] {
    min-height: 2.75rem;
    padding: 0 1.05rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background-color: var(--accent-gradient-from);
    background-image: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--accent-gradient-to) 50%, var(--accent-gradient-from) 100%);
    background-size: 200% 100%;
    background-position: 0% 50%;
    background-repeat: no-repeat;
    background-origin: border-box;
    color: var(--button-text);
    font: inherit;
    font-size: .93rem;
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    transition: background-position var(--motion-slow) var(--motion-ease), filter var(--motion-fast) var(--motion-ease);
}

.ranking-page .listing-filters button[type="submit"]:active,
.surface--auth .auth-form:has(> input:not([type="hidden"])) button:active,
.surface--auth main > form:only-of-type button:active,
.surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]:active,
.surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]:active {
    filter: brightness(.94);
}

.ranking-page .ranking-list {
    gap: var(--space-4);
}

.ranking-page .listing-empty {
    margin: 0;
    padding: var(--space-7) var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    text-align: center;
}

/* B-7 card page (.detail-2col): the card, its ranking contexts and the way
   back on the left; the value card and the share card on the right from the
   wider grid on. The card itself carries no rank and no value zone here; its
   About and Target part is flat inside the card instead of an inset panel. */
.ranking-page .card-detail {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: var(--space-4);
}

.ranking-page .card-detail-main,
.ranking-page .card-detail-side,
.ranking-page .card-detail-more {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    min-width: 0;
}

/* A column is never wider than the page: its one track may shrink, and so
   may every part inside it, so a larger text size wraps instead of widening
   the whole card page. */
.ranking-page .card-detail-main > *,
.ranking-page .card-detail-side > *,
.ranking-page .card-detail-more > * {
    min-width: 0;
}

.ranking-page .card-detail .card-main {
    grid-template-columns: auto minmax(0, 1fr);
}

.ranking-page .card-detail .listing-name {
    font-size: 1.55rem;
    letter-spacing: -.038em;
    line-height: 1.16;
}

/* RK-11: more room between the title and the chips of the detail card. The
   teaser below the title is hidden here (the full description stands under
   About), so the title itself carries the space: 1.5rem instead of .32rem. */
.ranking-page .card-detail .rankshell .listing-name {
    margin-bottom: var(--space-5);
}

/* P4a private favourite heart, detail page only. Derived from B-7 .fav
   (docs/design-drafts/upbiddr-light-draft-b-7.html:1053-1066) in radius,
   surface, pressed heart colour and icon glyph, sized larger for touch
   (2.75rem vs B-7's 2.2rem). The resting border uses --border instead of
   B-7's --border-control, and the pressed border uses flat --accent-soft
   instead of B-7's colour-mix; both await the visual acceptance. No
   transition and no pop animation, so the reduced-motion rule above stays
   untouched. */
.ranking-page .ranking-fav-form {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.ranking-page .ranking-fav {
    width: 2.75rem;
    height: 2.75rem;
    flex: none;
    display: inline-grid;
    place-items: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text-faint);
    cursor: pointer;
}

.ranking-page .ranking-fav svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.ranking-page .ranking-fav[aria-pressed="true"] {
    color: var(--heart);
    border-color: var(--accent-soft);
    background-color: var(--accent-soft);
}

.ranking-page .ranking-fav[aria-pressed="true"] svg {
    fill: currentColor;
}

.ranking-page .ranking-fav-status {
    font-size: .8rem;
    color: var(--text-faint);
}

/* The full description stands under About; B-7 shows no teaser here. */
.ranking-page .card-detail .card-mid > p:not([class]) {
    display: none;
}

.ranking-page .card-detail .rankshell-labels--detail {
    justify-content: flex-end;
    margin: 0 0 .3rem;
    padding: 0;
}

/* U3 (wish 19): on the card page the identity (left) and the Free or Sponsored
   label (right) share one row at the top of the card, level with the top of the
   picture. On a narrow screen the label wraps below the identity and stays on
   the right; without an identity the label alone stays on the right. */
.ranking-page .card-detail .rankshell-identrow {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .15rem .75rem;
    min-width: 0;
    margin: 0 0 .3rem;
}

.ranking-page .card-detail .rankshell-identrow .rc-ident {
    flex: 0 1 auto;
    margin: 0;
}

.ranking-page .card-detail .rankshell-identrow .rankshell-labels--detail {
    flex: none;
    margin: 0 0 0 auto;
}

.ranking-page .card-detail .detail-panel {
    margin: var(--space-4) 0 0;
    padding: var(--space-4) 0 0;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: transparent;
}

.ranking-page .ranking-contexts {
    padding: var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.ranking-page .ranking-contexts h2,
.ranking-page .preview-dstats-block h2 {
    margin: 0 0 var(--space-3);
    font-size: .85rem;
}

/* B-7 .b4-ctx boxes: the rank large, the context below it. */
.ranking-page .ranking-contexts .chips {
    display: grid;
    align-items: stretch;
    grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
    gap: .6rem;
}

.ranking-page .card-ctx {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .5rem;
    margin: 0;
    padding: var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
}

.ranking-page .card-ctx-rank {
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: 2.05rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.045em;
    line-height: 1;
}

.ranking-page .card-ctx-text {
    color: var(--muted);
    font-size: .88rem;
}

/* B-7 .b4-ctx .btn: the way into the filtered list sits at the bottom of the
   box. */
.ranking-page .card-ctx .card-ctx-open {
    position: relative;
    margin-top: auto;
}

/* SHARE-CTX-B2: the way into the list of one context sits in its row at the
   bottom of the box (the context share icon left the row on 2026-10-14, SH-02). */
.ranking-page .card-ctx .card-ctx-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-top: auto;
}

/* The two small buttons of the row use a narrower side padding, so link and
   icon still share one row in the narrowest three-column context box. */
.ranking-page .card-ctx .card-ctx-actions .btn--sm {
    padding: 0 .5rem;
}

/* B-7 "Other ranking cards in this ranking" (.b4-neigh, .b4-nrow): rank,
   initial, name with a shortened teaser and the value; the card itself is the
   dashed row. */
.ranking-page .card-neighbours {
    margin: var(--space-5) 0 0;
}

.ranking-page .card-neighbours > h2 {
    margin: 0 0 .6rem;
    font-size: 1.04rem;
}

.ranking-page .card-neighbour-list {
    display: grid;
    gap: .4rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ranking-page .card-neighbour {
    display: grid;
    grid-template-columns: 2.6rem 2.5rem minmax(0, 1fr) auto;
    align-items: center;
    gap: .75rem;
    padding: .55rem .75rem;
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease);
}

.ranking-page .card-neighbour--current {
    border-style: dashed;
    border-color: var(--border-control);
    background: var(--surface-2);
}

.ranking-page .card-neighbour-rank,
.ranking-page .card-neighbour-value {
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .92rem;
    font-variant-numeric: tabular-nums;
}

.ranking-page .card-neighbour-value {
    color: var(--muted);
    font-size: .9rem;
}

.ranking-page .card-neighbour-logo {
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: .85rem;
    font-weight: var(--font-weight-heading);
}

.ranking-page .card-neighbour-title {
    display: flex;
    align-items: baseline;
    gap: .35rem;
    min-width: 0;
    overflow: hidden;
    font-size: .93rem;
}

/* Positioned, so the visually hidden ", this card" text of the current row
   stays inside the clipped name instead of widening the page. */
.ranking-page .card-neighbour-name {
    position: relative;
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    font-weight: var(--font-weight-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ranking-page .card-neighbour-sep {
    flex: none;
    color: var(--text-faint);
}

.ranking-page .card-neighbour-teaser {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    color: var(--text-faint);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* K-10 (R-01/A-04, operator approval 2026-10-28): where the screen is at
   most 19.9 times the browser's default font size wide (an enlarged default
   font size; with 16px only below 319px), each neighbour row stands in three
   lines: rank and picture, then name and teaser over the whole row, then the
   value. Rank, picture, gaps and padding take 8.85rem of the row; above the
   bound the name keeps at least the room it has at 16px on a 320px screen.
   The list keeps its rows inside the page. Order, links, texts, picture and
   value stay; the two-column card page from 981px never meets it.
   Order 2026-10-29, point 8 together with K-09: inside the same bound the
   entries of the open share targets list of the public pages keep their
   former .95rem start.
   With an enlarged default font size the 1.6rem start made the list (as
   wide as its widest entry there) reach so far past a narrow screen that the
   focus ring of a target left the screen; at 16px every screen from 319px
   keeps the 1.6rem start of point 8. */
@media (max-width: 980px) and (max-width: 19.9em) {
    .ranking-page .share-box .share-drop a.share-drop__item,
    .surface .share-box .share-drop a.share-drop__item {
        padding-left: .95rem;
    }

    .ranking-page .card-neighbour-list {
        grid-template-columns: minmax(0, 1fr);
    }

    .ranking-page .card-neighbour {
        grid-template-columns: 2.6rem minmax(0, 1fr);
    }

    .ranking-page .card-neighbour-logo {
        justify-self: start;
    }

    .ranking-page .card-neighbour-title,
    .ranking-page .card-neighbour-value {
        grid-column: 1 / -1;
    }
}

/* B-7 back link (.nav-quiet--back): the arrow moves 3px to the left on hover. */
.ranking-page .card-detail-back {
    margin: 0;
    font-size: .88rem;
}

.ranking-page .card-detail-backlink {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.ranking-page .card-detail-backlink:hover {
    color: var(--accent-deep);
}

.ranking-page .card-detail-backarr {
    stroke-width: 3.8;
    transform: translateY(-1px);
    transition: transform var(--motion-base) var(--motion-ease);
}

.ranking-page .card-detail-backlink:hover .card-detail-backarr {
    transform: translate(-3px, -1px);
}

/* The framed boxes of the card page that hold an operable control (the ranking
   contexts, the value card and the share box; the same list of controls as the
   boxes of the redesign, an info icon excluded: a box whose only control is an
   info icon has no hover) take the strong card shadow on hover in the
   (hover: hover) block, with the resting edge unchanged; a keyboard focus
   inside gives them the same shadow and never a different edge (N6). The
   statistics box holds no control and has no hover. */
.ranking-page .card-detail .ranking-contexts,
.ranking-page .card-detail .card-detail-value,
.ranking-page .card-detail .share-box {
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.ranking-page .card-detail .ranking-contexts:has(:is(a, button:not(.b7-info), input, select, textarea, summary):focus-visible),
.ranking-page .card-detail .card-detail-value:has(:is(a, button:not(.b7-info), input, select, textarea, summary):focus-visible),
.ranking-page .card-detail .share-box:has(:is(a, button:not(.b7-info), input, select, textarea, summary):focus-visible) {
    box-shadow: var(--shadow-card-strong);
}

/* B-7 value card (.card.inset with .b4-dvalue): label and amount centred, the
   primary action across the card. */
.ranking-page .card-detail-value {
    padding: var(--space-5);
    border: 1px solid var(--box-muted-border);
    border-radius: var(--radius-lg);
    background: var(--box-muted-bg);
    box-shadow: var(--box-muted-shadow);
    text-align: center;
}

.ranking-page .card-detail-value-label {
    margin: 0;
    color: var(--text-faint);
    font-size: .76rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.ranking-page .card-detail-amount {
    margin: .2rem 0 var(--space-4);
    font-family: var(--font-family-num);
    font-size: 1.55rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.04em;
    line-height: 1.05;
}

.ranking-page .card-detail-action {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin: 0;
}

.ranking-page .card-detail-action .btn {
    flex: 1 1 auto;
}

/* B-7 share surface on the rankings list, the card page and the profile. Its
   copy and share buttons and the share targets carry the local B-7 icons;
   everything else of the share box stays as it is. */
.ranking-page .share-box,
.profile-page .share-box {
    display: grid;
    gap: .45rem;
    margin: 0;
    padding: var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.ranking-page .share-box h2,
.profile-page .share-box h2 {
    margin: 0;
    font-size: 1.05rem;
}

.ranking-page .share-box p,
.profile-page .share-box p {
    margin: 0;
    color: var(--muted);
    font-size: .89rem;
}

.ranking-page .share-box a,
.profile-page .share-box a {
    color: var(--accent-text);
}

.ranking-page .share-box input,
.profile-page .share-box input {
    width: 100%;
    min-height: 2.75rem;
    margin: 0;
    padding: .55rem .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--muted);
    font: inherit;
    font-size: .93rem;
}

.ranking-page .share-box button,
.ranking-page .share-box .copy-target,
.profile-page .share-box button {
    justify-self: start;
    min-height: 2.75rem;
    padding: .35rem .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease);
}

/* B-7 share controls carry their local icon in front of the text (l.3514-
   3520); a control the script left hidden stays hidden. */
.ranking-page .share-box button:not([hidden]),
.ranking-page .share-box .copy-target,
.profile-page .share-box button:not([hidden]) {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
}

.ranking-page .share-box button:hover,
.ranking-page .share-box .copy-target:hover,
.profile-page .share-box button:hover {
    background-color: var(--surface-2);
}

.ranking-page .share-box .copy-target-status,
.profile-page .share-box .copy-target-status {
    color: var(--muted);
    font-size: .84rem;
}

/* Copy link and native share sit next to each other (P1); the three social
   targets already share this same row layout through .chips. */
.ranking-page .share-box .share-actions,
.profile-page .share-box .share-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .55rem;
    align-items: center;
}

/* 2026-10-14: on the card page the shown actions (Share card, Copy URL,
   Preview image) share the whole panel width; hidden and no-script controls
   take no part, a narrow screen wraps them and every row is filled again. */
.ranking-page .share-box .share-actions > :not([hidden]) {
    flex: 1 1 0;
    min-width: max-content;
    justify-content: center;
    text-align: center;
}

/* K-09 (R-01/A-04, operator approval 2026-10-28): on the card page the share
   box keeps its one column at its own width, so a part that needs more room
   no longer widens all the others and the page. An action keeps its one line
   where it fits; where it does not, it takes the row and its label wraps
   between whole words, and the share targets field wraps its label the same
   way. The account panel, the profile and the rankings list keep their share
   boxes as they are. */
.ranking-page .card-detail .share-box {
    grid-template-columns: minmax(0, 1fr);
}

.ranking-page .card-detail .share-box .share-actions > :not([hidden]) {
    min-width: fit-content;
}

.ranking-page .card-detail .share-box .share-more--drop > summary {
    white-space: normal;
}

/* A quiet decorative divider between the three social targets; it carries no
   meaning of its own and is hidden from assistive technology. */
.ranking-page .share-box .share-target-sep {
    color: var(--border-strong);
}

/* The older dark rule for the free logo is more specific than the card block;
   in B-7 every card logo carries the same blue to teal surface. */
html[data-theme="dark"] .rankshell .logo {
    border-color: var(--border-strong);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
}

/* U3 (wish 19): on the card page a picture stands without the tile behind it and
   without a frame; the radius stays. The letter fallback (span.logo) keeps its
   tile. */
.ranking-page .card-detail .rankshell img.logo {
    border-color: transparent;
    background: none;
}

/* Dark TOP n ribbon: the band and its white text stay unchanged. The band
   shadow uses the strong dark card shadow at full opacity, both back tabs get
   a local dark overlay inside the tab and the fold line turns dark. */
html[data-theme="dark"] .rankshell-ribbon-shadow {
    opacity: 1;
    box-shadow: var(--shadow-card-strong);
}

html[data-theme="dark"] .rankshell-ribbon-back--top::after,
html[data-theme="dark"] .rankshell-ribbon-back--left::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: var(--background);
    opacity: .6;
    pointer-events: none;
}

html[data-theme="dark"] .rankshell-ribbon-back::before {
    background: linear-gradient(135deg, transparent 34.56px, var(--background) 35.56px, transparent 38.06px);
}

/* Home. The steps carry the B-7 numbered square (.road-n in .g4) from the
   list's own step counter, so the markup stays one plain ordered list. The
   card links are the quiet B-7 function link (.nav-quiet) with its arrow icon:
   no underline, a calm colour change and an arrow that moves 3px on hover. The
   links in the rules card are B-7 prose links. The grids follow B-7 .g3, .g4
   and .g2: one, two and four columns. */
.home-steps ol {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    counter-reset: home-step;
}

.home-steps li {
    counter-increment: home-step;
}

.home-steps li::before {
    content: counter(home-step);
    display: inline-grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-family: var(--font-family-num);
    font-size: 1rem;
    font-weight: var(--font-weight-heading);
}

/* K-06 (R-01/A-04, operator approval 2026-10-28): below the four columns,
   where the screen is at most 19.5 times the browser's default font size
   wide (an enlarged default font size; with 16px only up to 312px), the
   steps stand in one column. Two columns leave each step about half the
   width less 4.5rem of padding, gap and margin, too little for its longest
   word there. Order, numbers, texts and spacing stay; it overrides the two
   columns above by source order, the four columns from 981px never meet it. */
@media (max-width: 980px) and (max-width: 19.5em) {
    .home-steps ol {
        grid-template-columns: minmax(0, 1fr);
    }
}

.home-link {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.home-link:hover {
    color: var(--accent-deep);
}

.home-arr {
    stroke-width: 3.8;
    transform: translateY(2px);
    transition: transform var(--motion-base) var(--motion-ease);
}

.home-link:hover .home-arr {
    transform: translate(3px, 2px);
}

/* Info and legal pages: one column track that may shrink, so a larger text
   size wraps inside the page instead of widening it. */
.info-page {
    grid-template-columns: minmax(0, 1fr);
}

/* Info and legal pages: B-7 prose links, underlined with some air and a
   calm colour change. */
.info-page a {
    color: var(--accent-text);
    text-decoration-thickness: 1px;
    text-underline-offset: .22em;
    transition: color var(--motion-fast) var(--motion-ease);
}

.info-page a:hover {
    color: var(--accent-deep);
}

.info-page .listing-group li + li {
    margin-top: .35rem;
}

/* About: the three explaining parts as numbered B-7 cards side by side from
   the wider grid on, the limits as the B-7 rules card and the further pages
   as quiet function links with the arrow. */
.info-page .about-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    counter-reset: about-part;
}

.info-page .about-grid > .listing-group {
    counter-increment: about-part;
}

.info-page .about-grid > .listing-group::before {
    content: counter(about-part);
    display: inline-grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    margin: 0 0 .6rem;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-family: var(--font-family-num);
    font-size: 1rem;
    font-weight: var(--font-weight-heading);
}

.info-page .about-grid h2,
.info-page .about-grid h3,
.info-page .about-limits h2,
.info-page .about-more h2 {
    font-size: 1.04rem;
    letter-spacing: -0.02em;
}

.info-page .about-grid p,
.info-page .about-limits li {
    color: var(--muted);
    font-size: .92rem;
}

.info-page .about-more ul {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem var(--space-5);
    padding: 0;
    list-style: none;
}

.info-page .about-more li + li {
    margin-top: 0;
}

.info-page a.about-link {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.info-page .about-arr {
    stroke-width: 3.8;
    transform: translateY(2px);
    transition: transform var(--motion-base) var(--motion-ease);
}

.info-page a.about-link:hover .about-arr {
    transform: translate(3px, 2px);
}

/* About (P1): the ranking position notice moves out of the three-box grid and
   sits small underneath it, without the blue left border of the shared
   .info-page .notice; that rule and every other use of .notice stay
   untouched. */
.info-page .about-note {
    max-width: 70ch;
    margin: 0;
    color: var(--muted);
    font-size: .82rem;
}

/* A12: the B-7 accordion icon pair (.disc .chev, l.735-738) of every native
   disclosure, from partials/disc-chev: a 16px box with the two B-7 icons
   (ico--sm) on top of each other. The minus waits turned away and small; each
   disclosure turns the plus away and the minus in while it is open, the
   reverse when it closes (also while the disclosure script still animates a
   closing panel, data-disclosure-closing). The icons draw in currentColor, as
   in B-7. */
.b7-chev {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 16px;
    height: 16px;
}

.b7-chev > svg {
    position: absolute;
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease);
}

.b7-chev__minus {
    opacity: 0;
    transform: rotate(-90deg) scale(.6);
}

/* FAQ: the B-7 accordion marker. Plus and minus sit on top of each other at
   the right edge; opening turns the plus away and fades it out while the
   minus turns in, closing does the reverse, exactly as the two B-7 icons do.
   The browser's own disclosure triangle is replaced. */
.info-page .listing-group summary::-webkit-details-marker {
    display: none;
}

.info-page .listing-group details > summary {
    position: relative;
    padding-right: 2.75rem;
}

.info-page .listing-group summary > .b7-chev {
    position: absolute;
    top: 50%;
    right: 1rem;
    transform: translateY(-50%);
}

.info-page .listing-group details[open]:not([data-disclosure-closing]) > summary .b7-chev__plus {
    opacity: 0;
    transform: rotate(90deg) scale(.6);
}

.info-page .listing-group details[open]:not([data-disclosure-closing]) > summary .b7-chev__minus {
    opacity: 1;
    transform: none;
}

/* B-7 accordion motion: the answer opens with the B-7 subcard grid animation
   and the marker turns while plus becomes minus. Only browsers that know the
   details content box animate; every other browser opens the native details
   at once. Reduced motion drops both. */
.info-page .listing-group details {
    interpolate-size: allow-keywords;
}

.info-page .listing-group details::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size var(--motion-slow) var(--motion-ease), content-visibility var(--motion-slow) allow-discrete;
}

.info-page .listing-group details[open]::details-content {
    block-size: auto;
}

/* A12: a details element taken over by the disclosure script (marked
   data-disclosure-ready) gets its height animated by the script in every
   browser, so its content box no longer moves: one height animation, never
   two. Without the script the rules above stay in charge. */
.info-page .listing-group details[data-disclosure-ready]::details-content {
    transition: none;
}

.info-page .listing-group summary:hover {
    color: var(--accent-text);
}

/* SHARE-CTX-B2 "More ways to share": the same quiet accordion as the FAQ. The
   native details element stays the disclosure, so it opens and closes without
   JavaScript, by keyboard and in every browser. Both namespaces are listed
   because the owner card page carries the surface wrapper only. */
.ranking-page .share-box .share-more,
.surface .share-box .share-more {
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    interpolate-size: allow-keywords;
}

.ranking-page .share-box .share-more > summary,
.surface .share-box .share-more > summary {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: .85rem 2.75rem .85rem 1rem;
    list-style: none;
    cursor: pointer;
    font-weight: var(--font-weight-medium);
}

.ranking-page .share-box .share-more > summary::-webkit-details-marker,
.surface .share-box .share-more > summary::-webkit-details-marker {
    display: none;
}

.ranking-page .share-box .share-more > .chips,
.surface .share-box .share-more > .chips {
    margin: 0 var(--space-4) var(--space-4);
}

/* The marker is the FAQ plus and minus (b7-chev): both sit on top of each
   other at the right edge, opening turns the plus away while the minus turns
   in. */
.ranking-page .share-box .share-more > summary > .b7-chev,
.surface .share-box .share-more > summary > .b7-chev {
    position: absolute;
    top: 50%;
    right: 1rem;
    transform: translateY(-50%);
}

.ranking-page .share-box .share-more[open]:not([data-disclosure-closing]) > summary .b7-chev__plus,
.surface .share-box .share-more[open]:not([data-disclosure-closing]) > summary .b7-chev__plus {
    opacity: 0;
    transform: rotate(90deg) scale(.6);
}

.ranking-page .share-box .share-more[open]:not([data-disclosure-closing]) > summary .b7-chev__minus,
.surface .share-box .share-more[open]:not([data-disclosure-closing]) > summary .b7-chev__minus {
    opacity: 1;
    transform: none;
}

/* The content opens with the FAQ block size animation (interpolate-size above)
   where the browser knows the details content box; every other browser opens
   the details at once. Reduced motion drops it. */
.ranking-page .share-box .share-more::details-content,
.surface .share-box .share-more::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size var(--motion-slow) var(--motion-ease), content-visibility var(--motion-slow) allow-discrete;
}

.ranking-page .share-box .share-more[open]::details-content,
.surface .share-box .share-more[open]::details-content {
    block-size: auto;
}

/* A12: the disclosure script animates the height of a details element it
   has taken over (data-disclosure-ready); its content box stays still. */
.ranking-page .share-box .share-more[data-disclosure-ready]::details-content,
.surface .share-box .share-more[data-disclosure-ready]::details-content {
    transition: none;
}

.ranking-page .share-box .share-more > summary:hover,
.ranking-page .share-box .share-more > summary:focus-visible,
.surface .share-box .share-more > summary:hover,
.surface .share-box .share-more > summary:focus-visible {
    color: var(--accent-text);
}

/* Public profile. */
.profile-page > h1 {
    margin: 0;
}

.profile-page .logo {
    width: 76px;
    height: 76px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    object-fit: cover;
}

/* 2026-10-14 / A45: the share targets dropdown (share-more--drop) of the
   card page and of the account panel reads as a field of the rankings filter
   (.b7-fsw-btn): its height, border, surface and the stacked chevron pair
   (.b7-fsw-chev) that turns its weight while the list is open; no plus and
   minus. The native details element stays the disclosure (Escape, outside
   click and leaving focus close it with the script). Its open list floats on
   the layer of the share popover (5): above the card content, below the
   tooltip layer and the sticky header. */
.ranking-page .share-box .share-more--drop,
.surface .share-box .share-more--drop {
    position: relative;
    border: 0;
    background: none;
}

.ranking-page .share-box .share-more--drop::details-content,
.surface .share-box .share-more--drop::details-content {
    overflow: visible;
    transition: none;
}

.ranking-page .share-box .share-more--drop > summary,
.surface .share-box .share-more--drop > summary {
    display: inline-flex;
    justify-content: flex-start;
    gap: .45rem;
    min-height: 2.75rem;
    padding: 0 .7rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background-color: var(--surface);
    color: var(--foreground);
    font-size: .86rem;
    font-weight: normal;
    white-space: nowrap;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}

/* UI-10 (operator decision 2026-10-21): in the account share box the
   dropdown is as high as the share buttons above it (.rd .rd-card .share-box
   buttons, 2.2rem at every width). */
.surface .share-box .share-more--drop > summary {
    min-height: 2.2rem;
}

.ranking-page .share-box .share-more--drop > summary:hover,
.ranking-page .share-box .share-more--drop[open] > summary,
.surface .share-box .share-more--drop > summary:hover,
.surface .share-box .share-more--drop[open] > summary {
    background-color: var(--surface-2);
    color: var(--foreground);
}

.ranking-page .share-box .share-more--drop[open] > summary .b7-fsw-chev,
.surface .share-box .share-more--drop[open] > summary .b7-fsw-chev {
    color: currentColor;
}

.ranking-page .share-box .share-more--drop > summary .filter-chev-up,
.surface .share-box .share-more--drop > summary .filter-chev-up {
    opacity: .55;
}

.ranking-page .share-box .share-more--drop[open] > summary .filter-chev-up,
.surface .share-box .share-more--drop[open] > summary .filter-chev-up {
    opacity: 1;
}

.ranking-page .share-box .share-more--drop[open] > summary .filter-chev-down,
.surface .share-box .share-more--drop[open] > summary .filter-chev-down {
    opacity: .3;
}

/* The open list in the look of the filter option panel (.b7-fpanel,
   .b7-fopt): the highlighted "Share on" title, a divider and the targets.
   A22 (Q22.2): as under a group title of the filter panels, the targets are
   indented .35rem against the title. */
.ranking-page .share-box .share-more--drop > .share-drop,
.surface .share-box .share-more--drop > .share-drop {
    position: absolute;
    top: calc(100% + .35rem);
    left: 0;
    z-index: 5;
    width: min(18.5rem, 100vw - 2rem);
    padding: .4rem;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
}

/* K-09 (operator approval 2026-10-28) and L-1 (layout closure 2026-10-29):
   on the card page the open share targets list is never wider than the share
   box, on every screen width, so it no longer reaches past the screen edge.
   On a narrow screen this also holds with 16px; where the box is wider than
   18.5rem the list keeps its width. It is never narrower than its widest
   entry (icon, name and padding), so every target name stays whole. */
.ranking-page .card-detail .share-box .share-more--drop > .share-drop {
    width: min(18.5rem, 100%);
    min-width: min-content;
}

.ranking-page .share-box .share-drop__title,
.surface .share-box .share-drop__title {
    margin: 0;
    padding: .45rem .6rem .55rem;
    border-bottom: 1px solid var(--border);
    color: var(--foreground);
    font-size: .87rem;
    font-weight: var(--font-weight-heading);
}

.ranking-page .share-box .share-drop__list,
.surface .share-box .share-drop__list {
    display: grid;
    gap: .1rem;
    margin: .3rem 0 0;
    padding: 0;
    list-style: none;
}

.ranking-page .share-box a.share-drop__item,
.surface .share-box a.share-drop__item {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: 2.75rem;
    /* Order 2026-10-29, point 8: 1.6rem in (was .95rem). */
    padding: .48rem .6rem .48rem 1.6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--foreground);
    font-size: .87rem;
    text-decoration: none;
}

.ranking-page .share-box a.share-drop__item:hover,
.ranking-page .share-box a.share-drop__item:focus-visible,
.surface .share-box a.share-drop__item:hover,
.surface .share-box a.share-drop__item:focus-visible {
    border-color: var(--border);
    background-color: var(--surface-2);
    color: var(--accent-text);
}

/* B-7 tabs: the current tab carries the accent colour and the brand line. */
.profile-tabs {
    gap: .15rem;
    max-width: 100%;
    overflow-x: auto;
    border-bottom: 1px solid var(--border);
    scrollbar-width: none;
}

.profile-tabs a {
    position: relative;
    padding: .62rem 1rem;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    color: var(--muted);
    font-size: .92rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--motion-fast) var(--motion-ease);
}

.profile-tabs a:hover {
    color: var(--foreground);
}

.profile-tabs a[aria-current="page"] {
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

.profile-tabs a[aria-current="page"]::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 3px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
}

.profile-card-list {
    gap: var(--space-3);
}

.profile-card-list li {
    padding: var(--space-4) var(--space-5);
    border-color: var(--box-card-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-card-shadow);
}

.profile-card-list a {
    color: var(--foreground);
    font-size: 1.05rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.profile-card-list a:hover {
    color: var(--accent-text);
}

.profile-card-list p {
    font-size: .89rem;
}

/* Private, login and admin surfaces: B-7 typography, cards, fields, tables
   and buttons on the plain markup. */
.surface main > h1 {
    margin: 0 0 var(--space-4);
}

.surface main h2 {
    margin: var(--space-5) 0 var(--space-3);
    font-size: 1.1rem;
    letter-spacing: -.02em;
}

.surface main p,
.surface main li {
    max-width: 72ch;
}

.surface main a {
    color: var(--accent-text);
    text-underline-offset: .22em;
}

.surface main a:hover {
    color: var(--accent-deep);
}

.surface main > section,
.surface main > nav {
    margin: 0 0 var(--space-4);
    padding: var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.surface main > section > h2:first-child,
.surface main > nav > h2:first-child {
    margin-top: 0;
}

.surface main ul,
.surface main ol {
    padding-left: var(--space-5);
}

.surface main li + li {
    margin-top: .35rem;
}

.surface main label:not([hidden]) {
    display: block;
    margin: 0 0 .35rem;
    font-size: .83rem;
    font-weight: var(--font-weight-medium);
}

.surface main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea) {
    max-width: 100%;
    min-height: 2.75rem;
    padding: .55rem .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .93rem;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

/* A45: a native admin select keeps its native list (no script select on the
   admin pages); its closed field takes the look of the rankings filter field:
   the height, edge and surface above and the stacked chevron pair, drawn
   here with the gradient technique of the redesigned select fallback (an up
   chevron above a lighter down chevron is not possible natively). The open
   list itself stays the browser's own and cannot be styled. */
.surface--admin main select:not([multiple]):not([size]) {
    padding: 0 2.25rem 0 .7rem;
    font-size: .86rem;
    background-image:
        linear-gradient(135deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(135deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%);
    background-position: calc(100% - 1.05rem) calc(50% - 4px), calc(100% - .75rem) calc(50% - 4px), calc(100% - 1.05rem) calc(50% + 4px), calc(100% - .75rem) calc(50% + 4px);
    background-repeat: no-repeat;
    background-size: 5px 5px;
    -webkit-appearance: none;
    appearance: none;
}

/* The B-7 neutral field focus: no browser ring, no outline and no shadow, a
   darker neutral edge on the inset surface (N5: the one pixel inner outline of
   the keyboard focus is gone; forced colours turns the edge into a system
   colour in the rule after the field rules). */
.surface main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea):focus,
.ranking-page .share-box input:focus,
.profile-page .share-box input:focus {
    outline: none;
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.surface main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea):focus-visible,
.ranking-page .share-box input:focus-visible,
.profile-page .share-box input:focus-visible {
    outline: none;
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.surface main :is(input, textarea)[readonly] {
    width: 100%;
    background: var(--surface-2);
    color: var(--muted);
}

/* B-7 .inp fills its field; consecutive fields keep the B-7 field spacing. */
.surface--member main form :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea),
.surface--admin main form :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea) {
    width: 100%;
    margin-bottom: var(--space-3);
}

.surface main textarea {
    min-height: 5.5rem;
    resize: vertical;
}

.surface main :is(input[type="checkbox"], input[type="radio"]) {
    accent-color: var(--accent);
}

.surface main button {
    min-height: 2.75rem;
    padding: 0 1.05rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .93rem;
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    /* A10: this rule is stronger than .btn--primary, so its list also names
       the gradient slide and the press filter of the B-7 primary button; a
       neutral button has neither and nothing changes for it. */
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), background-position var(--motion-slow) var(--motion-ease), filter var(--motion-fast) var(--motion-ease);
}

.surface main button:hover {
    background-color: var(--surface-2);
}

.surface main button[disabled] {
    opacity: .45;
    cursor: not-allowed;
}

/* The B-7 info icon keeps its own small round form on the member pages. */
.surface main .b7-info {
    width: 1.05rem;
    height: 1.05rem;
    min-height: 0;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--text-faint);
    font-size: inherit;
}

.surface main .b7-info:hover,
.surface main .b7-info[aria-expanded="true"] {
    background: transparent;
    color: var(--accent-text);
}

/* B-7 .inset: on the member and admin surfaces a form with its own fields is
   one grouped panel. */
.surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="file"], input[type="checkbox"], input[type="radio"], select, textarea)),
.surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="file"], input[type="checkbox"], input[type="radio"], select, textarea)) {
    margin: 0 0 var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.surface main form :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], select, textarea) {
    background-color: var(--surface);
}

.surface main fieldset {
    min-width: 0;
    margin: 0 0 var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.surface main legend {
    padding: 0 .35rem;
    font-size: .83rem;
    font-weight: var(--font-weight-medium);
}

.surface main summary {
    cursor: pointer;
    font-weight: var(--font-weight-medium);
}

/* A12: an admin disclosure is a B-7 .disc trigger (l.725-738): the label
   and, right after it, the 16px chev box (b7-chev) with plus and minus
   crossing over; the native details element stays the disclosure. */
.surface--admin main details > summary {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    list-style: none;
}

.surface--admin main details > summary::-webkit-details-marker {
    display: none;
}

.surface--admin main details[open]:not([data-disclosure-closing]) > summary .b7-chev__plus {
    opacity: 0;
    transform: rotate(90deg) scale(.6);
}

.surface--admin main details[open]:not([data-disclosure-closing]) > summary .b7-chev__minus {
    opacity: 1;
    transform: none;
}

.surface main code {
    padding: .1rem .35rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    font-size: .92em;
}

.surface main img {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

/* B-7 table. A wide table scrolls inside the main area, never the page. */
.surface main table {
    width: 100%;
    margin: 0 0 var(--space-4);
    border-collapse: collapse;
    background: var(--surface);
    font-size: .88rem;
}

.surface main :is(th, td) {
    padding: .62rem .7rem;
    border-bottom: 1px solid var(--border);
    text-align: left;
    vertical-align: top;
}

.surface main th {
    color: var(--text-faint);
    font-size: .73rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .08em;
    text-transform: uppercase;
}

.surface main td {
    font-variant-numeric: tabular-nums;
}

.surface--admin main {
    overflow-x: auto;
}

.surface main dl {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .25rem var(--space-4);
}

.surface main dt {
    color: var(--text-faint);
    font-size: .83rem;
}

.surface main dd {
    margin: 0 0 .5rem;
}

/* Messages. Q21.1 / A21a (E1, E2, operator approval 2026-10-20): a message
   at its content takes the B-7 alert box of its kind (.alert--*, l.586-595):
   the padding, the 30% border and the soft background of the kind, the text
   in the foreground colour. A paragraph that names no kind takes the box of
   its role (an alert is an error, a status an information); a paragraph of
   a kind (rd-flash--*, alert--*, the field error line .err) keeps the look
   of its kind, so the role never overrides the kind. The exclusion adds no
   weight (:where), so the role box keeps its long-standing weight against
   the other rules. */
.surface main p[role="alert"]:where(:not(.rd-flash):not(.alert):not(.err)) {
    max-width: none;
    margin: .35rem 0 var(--space-3);
    padding: .85rem 1rem;
    border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
    border-radius: var(--radius-md);
    background: var(--danger-soft);
    color: var(--foreground);
    font-size: .89rem;
}

.surface main p[role="status"]:where(:not(.rd-flash):not(.alert):not(.err)),
.surface main .share-context-state,
.surface main .share-context-status {
    max-width: none;
    padding: .85rem 1rem;
    border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
    font-size: .89rem;
}

/* Inline flash: what the script turns into a toast. Without the script it is
   the visible message. The kind is the look; the role is the announcement.
   Q21.1 / A21a (E2): a message that names its kind (rd-flash--ok, --info,
   --warn, --err) takes the B-7 box of that kind on every surface, the admin
   pages and the redesigned pages without a surface class included. */
:is(.surface, .rd) main :is(p, ul).rd-flash {
    max-width: none;
    margin: 0 0 var(--space-4);
    padding: .85rem 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--foreground);
    font-size: .89rem;
}

/* A list of form errors in one box (the social preview entries) keeps its
   bullets inside the box. */
:is(.surface, .rd) main ul.rd-flash {
    padding-left: 2.2rem;
}

:is(.surface, .rd) main :is(p, ul).rd-flash.rd-flash--ok {
    border-color: color-mix(in srgb, var(--positive) 30%, transparent);
    background: var(--positive-soft);
}

:is(.surface, .rd) main :is(p, ul).rd-flash.rd-flash--info {
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
    background: var(--accent-soft);
}

:is(.surface, .rd) main :is(p, ul).rd-flash.rd-flash--warn {
    border-color: color-mix(in srgb, var(--warning) 30%, transparent);
    background: var(--warning-soft);
}

:is(.surface, .rd) main :is(p, ul).rd-flash.rd-flash--err {
    border-color: color-mix(in srgb, var(--danger) 30%, transparent);
    background: var(--danger-soft);
}

/* Q21.1 / A21a (E1): the one field error line of B-7 (.err, l.553-554) on
   every surface, rendered by partials/field-error (and by the select script
   for a required select): danger colour, small type and the decorative icon,
   directly at its field and named by its aria-describedby. */
:is(.surface, .rd) main :is(p, span).err {
    display: flex;
    gap: .35rem;
    align-items: center;
    max-width: none;
    margin: .35rem 0 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--danger);
    font-size: .8rem;
}

/* B-7 message icon (l.586-595) of the login messages: a decorative icon in
   front of the text, so the meaning never rests on colour alone. */
.surface--auth main p:is([role="alert"], [role="status"]):not(.err) > svg {
    margin-right: .45rem;
    vertical-align: -.15em;
}

/* An email field with an error takes the B-7 invalid border (l.538); its
   error text is named by aria-describedby in the view. */
.surface--auth .auth-form > input[aria-invalid="true"] {
    border-color: var(--danger);
}

.surface main caption {
    padding: 0 0 var(--space-2);
    color: var(--muted);
    font-size: .89rem;
    text-align: left;
}

/* Choice controls: a label that wraps a checkbox or radio is one calm row
   with a comfortable hit area, not a bold field label. */
.surface main label:not([hidden]):has(> :is(input[type="checkbox"], input[type="radio"])) {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: 2.75rem;
    margin: 0;
    font-size: .93rem;
    font-weight: 400;
}

.surface main label:not([hidden]) > :is(input, select, textarea) {
    margin-top: .35rem;
    font-weight: 400;
}

/* A14: the B-7 checkbox (.cbx, l.1128-1140) of the admin forms and of the
   header login window, the same markup and states as the redesigned pages
   (.rd .cbx): the native input stays in the label, invisible but focusable,
   so the label click, the keyboard, required, disabled and aria-invalid keep
   working; the box draws the check with a stroke dash. The label row itself
   keeps the layout of its surface. Its focus ring is the shared one and sits
   with the .rd .cbx rules. */
.surface--admin .cbx,
.login-pop .cbx {
    position: relative;
    cursor: pointer;
}

.login-pop .cbx {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    font-size: inherit;
}

/* The remember line of the header login window takes the B-7 checkbox size
   (.88rem) for the label and its privacy link alike. */
.login-pop .login-remember {
    font-size: .88rem;
}

.surface--admin .cbx > input,
.login-pop .cbx > input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
}

.surface--admin .cbx__box,
.login-pop .cbx__box {
    display: grid;
    flex: none;
    place-items: center;
    width: 1.3rem;
    height: 1.3rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-sm);
    background: var(--surface);
    transition: background-color var(--motion-base) var(--motion-ease), border-color var(--motion-base) var(--motion-ease);
}

.surface--admin .cbx__box svg,
.login-pop .cbx__box svg {
    width: 14px;
    height: 14px;
    fill: none;
    stroke: var(--button-text);
    stroke-width: 2.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.surface--admin .cbx__box svg path,
.login-pop .cbx__box svg path {
    stroke-dasharray: 20;
    stroke-dashoffset: 20;
    transition: stroke-dashoffset var(--motion-slow) var(--motion-ease);
}

.surface--admin .cbx > input:checked + .cbx__box,
.login-pop .cbx > input:checked + .cbx__box {
    border-color: var(--accent);
    background-color: var(--accent);
}

.surface--admin .cbx > input:checked + .cbx__box svg path,
.login-pop .cbx > input:checked + .cbx__box svg path {
    stroke-dashoffset: 0;
}

.surface--admin .cbx > input[aria-invalid="true"] + .cbx__box,
.login-pop .cbx > input[aria-invalid="true"] + .cbx__box {
    border-color: var(--danger);
}

.surface--admin .cbx > input:disabled + .cbx__box,
.login-pop .cbx > input:disabled + .cbx__box {
    opacity: .45;
}

.surface--admin .cbx:has(> input:disabled),
.login-pop .cbx:has(> input:disabled) {
    cursor: default;
}

.surface main input[type="file"] {
    max-width: 100%;
    font: inherit;
    font-size: .93rem;
}

.surface main input[type="file"]::file-selector-button {
    min-height: 2.2rem;
    margin-right: var(--space-3);
    padding: 0 .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

/* N5: the file input has no outline either; its keyboard focus shows on the
   button part through the neutral edge and the inset surface (same border
   width as at rest, so nothing shifts). */
.surface main input[type="file"]:focus-visible::file-selector-button {
    border-color: var(--focus-neutral);
    background: var(--surface-2);
}

/* Spacing between stacked single button forms and inline buttons. */
.surface main form + form {
    margin-top: var(--space-3);
}

.surface main button + button {
    margin-left: var(--space-2);
}

.surface--member main .auth-form,
.surface--admin main .auth-form {
    gap: .35rem;
}

.surface--member main form > p,
.surface--admin main form > p {
    margin: 0 0 var(--space-3);
}

/* A bare link list in a navigation card, such as the admin range and page
   links, gets touch sized targets. */
.surface main > nav > a:not([hidden]) {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    margin-right: var(--space-3);
}

.surface main .listing-empty {
    padding: var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    text-align: center;
}

/* The six code digit boxes only exist for the script. Without it they stay
   hidden, as their attribute says; the older layout rule for the row would
   otherwise show them next to the real code field. */
.surface--auth .login-code-digits[hidden] {
    display: none;
}

/* The login pages sit in one B-7 card. */
.surface--auth main {
    max-width: 30rem;
    margin-top: var(--space-6);
    margin-bottom: var(--space-6);
    padding: var(--space-6) var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-xl);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.surface--auth .auth-form {
    max-width: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    border: 0;
    background: transparent;
}

.surface--auth .auth-form label:not([hidden]) {
    margin: 0;
}

.surface--auth .auth-form > input:not([type="hidden"]) {
    width: 100%;
}

/* The send button of the login page matches the header login window: the
   full width B-7 primary button with the mail icon. */
.surface--auth .auth-form .login-page-submit {
    width: 100%;
    margin-top: var(--space-3);
}

.surface--auth .login-code-digits input[type="text"] {
    width: 2.75rem;
    padding: 0;
    text-align: center;
}

/* P2 login steps (B-7 .steps, l.1171-1173): a quiet line with two dots and
   the step text. The step is set by the server; nothing moves. */
.surface--auth .b7-steps {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-4);
    color: var(--muted);
    font-size: 0.82rem;
}

.surface--auth .b7-step-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 999px;
    background: var(--border-strong);
}

.surface--auth .b7-step-dot--on {
    background: var(--accent);
}

/* The six code boxes sit centred under their label. */
.surface--auth .login-code-digits {
    justify-content: center;
}

/* Step 2: the email form behind a native disclosure. */
.surface--auth .b7-login-switch {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

/* The summary keeps its native display, so the browser's own disclosure
   marker stays visible; the padding gives it a comfortable touch height. */
.surface--auth .b7-login-switch > summary {
    padding: var(--space-2) 0;
    cursor: pointer;
    font-weight: var(--font-weight-medium);
}

.surface--auth .b7-login-switch[open] > summary {
    margin-bottom: var(--space-3);
}

/* B-7 toast (.toaster and .toast, l.904-934): a card with an icon box and
   the status text. On narrow screens it sits under the header across the
   width (l.1755), from the wider grid on at the top right. It only exists
   with the script, only repeats the visible status and is hidden from
   assistive technology; the status element next to the button stays the
   announcement. */
.b7-toaster {
    position: fixed;
    z-index: 80;
    top: calc(var(--header-height) + 1rem);
    right: .9rem;
    left: .9rem;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .6rem;
    pointer-events: none;
}

.b7-toast {
    display: flex;
    align-items: center;
    gap: .7rem;
    width: 100%;
    padding: .75rem .95rem;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
    color: var(--foreground);
    font-size: .89rem;
    font-weight: var(--font-weight-medium);
    opacity: 0;
    transform: translateY(-10px) scale(.98);
    pointer-events: auto;
    cursor: pointer;
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-slow) var(--motion-ease);
}

.b7-toast.is-on {
    opacity: 1;
    transform: none;
}

.b7-toast-icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
}

.b7-toast--ok .b7-toast-icon {
    border-color: color-mix(in srgb, var(--positive) 30%, transparent);
    background: var(--positive-soft);
    color: var(--positive);
}

.b7-toast--err .b7-toast-icon {
    border-color: color-mix(in srgb, var(--danger) 30%, transparent);
    background: var(--danger-soft);
    color: var(--danger);
}

.b7-toast-text {
    min-width: 0;
}

/* Contact form (active form and disabled preview alike): the B-7 .field and
   .inp components in the two column B-7 .grid.g2 layout. One column by
   default; from 761px, in the media rule below, name and email share a row,
   while topic, message and the button always span the full width. The
   message is a tall, vertically resizable field. Focus keeps the B-7 .inp
   look (darker edge and surface, documented operator decision). Existing
   tokens only. */
.info-page .contact-form {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0 var(--space-4);
    margin: 0;
}

.info-page .contact-form .field {
    min-width: 0;
}

.info-page .contact-form__wide {
    grid-column: 1 / -1;
}

.info-page .contact-form textarea.inp {
    min-height: 12rem;
    line-height: 1.5;
    resize: vertical;
}

.info-page .contact-form .inp[aria-invalid="true"] {
    border-color: var(--danger);
}

.info-page .contact-form__hint {
    max-width: none;
    margin: .35rem 0 0;
    color: var(--text-faint);
    font-size: .78rem;
}

.info-page .contact-form__actions {
    margin: 0;
}

/* P1 account shell (B-7 menu panel and .b4-nrow rows, derived): the sidebar
   only shows from the desktop breakpoint up; below it the account icon opens
   the account menu or, without JavaScript, links to the dashboard. No motion. */
.b7-shell {
    width: min(var(--max-content-width), calc(100% - 2rem));
    margin: 0 auto;
}

.b7-shell-main > main {
    width: 100%;
}

.b7-side {
    display: none;
}

/* P1: the admin navigation has no header menu, so below the desktop width
   it stays visible above the page content. */
.b7-side--admin {
    display: block;
    padding-top: 1.6rem;
}

.b7-side-nav {
    padding: var(--space-3);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.b7-side-group,
.b7-acct-group {
    margin: var(--space-3) .7rem .25rem;
    color: var(--muted);
    font-size: .75rem;
    font-weight: var(--font-weight-medium);
    letter-spacing: .04em;
    text-transform: uppercase;
}

.b7-side-group:first-child,
.b7-acct-group:first-child {
    margin-top: .25rem;
}

/* NK05 (operator list 2026-10-23): a small distance between the entries, so
   the hover fill of an entry never touches the accent frame of the current
   one directly. */
.b7-side-list,
.b7-acct-list {
    display: grid;
    gap: 3px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.b7-side-link,
.b7-acct-link {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 2.75rem;
    padding: .55rem .7rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: none;
    color: var(--foreground);
    font: inherit;
    font-size: .93rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.b7-side-link:hover,
.b7-acct-link:hover {
    background-color: var(--surface-2);
    border-color: var(--border);
}

.b7-side-link[aria-current="page"],
.b7-acct-link[aria-current="page"] {
    border-color: var(--accent-border);
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

/* U2: the mobile account menu shows the same decorative icons as the sidebar
   (spacing); NK09 gives them the colour of the menu window icons. */
.b7-acct-link {
    gap: .65rem;
}

/* NK09 (operator list 2026-10-23): the icons of the account window take the
   colour of the icons of the menu window: the text colour of their entry. */
.b7-acct-link .ico {
    flex: none;
    color: inherit;
}

.b7-side-logout {
    margin: var(--space-3) 0 0;
    padding: var(--space-3) 0 0;
    border-top: 1px solid var(--border);
}

.b7-acct-menu:not([hidden]) {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 1;
    display: block;
    width: min(20rem, calc(100vw - 2rem));
    max-height: calc(100vh - var(--header-height) - 2rem);
    margin-top: .5rem;
    padding: .5rem;
    overflow-y: auto;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
}

.b7-acct-sep {
    display: block;
    height: 1px;
    margin: .45rem .3rem;
    background: var(--border);
}

/* P1 dashboard: tiles, the profile status badge row and the mobile logout. */
.surface main .b7-tiles {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-4);
    padding: 0;
    list-style: none;
}

.surface main .b7-tiles > li {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    max-width: none;
    margin: 0;
    padding: var(--space-4);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.surface main .b7-tile-value {
    color: var(--foreground);
    font-size: 1.35rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

.surface main .b7-start > summary {
    cursor: pointer;
}

.surface main .b7-start > summary > h2 {
    display: inline;
    margin: 0;
}

.surface main .b7-start[open] > summary {
    margin-bottom: var(--space-3);
}

.surface main .b7-dash-logout {
    margin: var(--space-4) 0 0;
}

@media (min-width: 761px) {
    .surface main .b7-tiles {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    /* S-07: from 761px the detail card title keeps .75rem to the chips;
       below it stays at the mobile 1.5rem. */
    .ranking-page .card-detail .rankshell .listing-name {
        margin-bottom: .75rem;
    }

    .info-page .contact-form {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .ranking-page .listing-filters .filter-bar button[type="submit"] {
        padding: 0 1.05rem;
        font-size: .93rem;
    }

    .rankshell {
        padding: var(--space-5);
    }

    .rankshell-ribbon-backs,
    .rankshell-ribbon {
        transform: none;
    }

    .rankshell-ribbon-shadow {
        transform: translate(34.5px, 35.5px) rotate(-45deg) translate(-103.5px, -21px);
    }

    .rankshell-ribbon-text {
        font-size: .9rem;
        letter-spacing: .08em;
    }

    .rankshell .card-main {
        grid-template-columns: 4.5rem minmax(0, 1fr) 12.5rem;
        gap: var(--space-4) var(--space-5);
    }

    .rankshell .logo {
        width: 4.5rem;
        height: 4.5rem;
        font-size: 1.5rem;
    }

    .rankshell .rank-badge {
        min-width: 2.7rem;
        min-height: 1.85rem;
        font-size: 1.1rem;
    }

    .rankshell .listing-name {
        font-size: 1.28rem;
    }

    .rankshell .card-mid > p:not([class]) {
        -webkit-line-clamp: 1;
        line-clamp: 1;
    }

    .rankshell .bid {
        grid-column: auto;
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: .1rem;
        height: 100%;
        padding: 0;
        border-top: 0;
        text-align: right;
    }

    .rankshell-labels {
        justify-content: flex-end;
        margin: 0 0 auto;
        padding-bottom: .9rem;
    }

    .rankshell-origin {
        min-height: 1.25rem;
        padding: 0 .45rem;
        font-size: .68rem;
    }

    .rankshell .bid-label {
        font-size: .72rem;
        letter-spacing: .07em;
    }

    .rankshell .bid-amount {
        font-size: 1.55rem;
    }

    .rankshell .bid-note {
        margin-top: .8rem;
    }

    /* A50 (Q50.4/Q50.5): a closed period card has no actions, so its value
       label and amount stand vertically centred in the space below the
       labels instead of at the foot of the zone. */
    .rankshell .bid--archive > .rankshell-labels {
        margin-bottom: 0;
    }

    .rankshell .bid--archive > .bid-label {
        margin-top: auto;
    }

    .rankshell .bid--archive > .bid-amount {
        margin-bottom: auto;
    }

    .surface main dl {
        grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    }

    .surface main dd {
        margin: 0;
    }

    .ranking-page .chip--facet {
        min-height: 1.45rem;
        line-height: 1;
    }

    /* UI-10 (operator decision 2026-10-21): only the rankings filter fields
       (the list and the archive page), the dropdown of the public share box
       beside its 2.2rem share buttons and the pagination keep the small
       height here; the admin selects stay as high as the light buttons
       (.btn) and the account share dropdown has its own rule. */
    .ranking-page .filter-field .b7-fsw-btn,
    .ranking-page .share-box .share-more--drop > summary,
    .ranking-page .ranking-pagination .btn {
        min-height: 2.2rem;
    }

    .ranking-page .ranking-pagination .btn {
        min-width: 2.2rem;
    }

    /* A20b: the summary rows keep the chip height from 761px on; the touch
       layer of the reset reaches 2.2rem, inside the row gap. */
    .ranking-page .ranking-summary .ranking-results {
        line-height: 1.45rem;
    }

    .ranking-page .ranking-summary .ranking-reset {
        min-height: 1.45rem;
    }

    .ranking-page .ranking-summary .ranking-reset::after {
        inset: -.375rem 0;
    }

    .b7-fopt {
        min-height: 0;
    }

    .rankshell-meta,
    .rankshell-facet {
        min-height: 1.45rem;
        padding: 0 .55rem;
        overflow: hidden;
        line-height: 1;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .rankshell-toggle:not([hidden]) {
        min-height: 0;
        padding: .3rem 0;
    }

    .rankshell-actions .copy-target:not([hidden]),
    .rankshell-actions .btn--sm,
    .ranking-page .share-box button,
    .ranking-page .share-box .copy-target,
    .profile-page .share-box button {
        min-height: 2.2rem;
    }

    /* A32: the heart button stays square at the small button height. */
    .rankshell .rankshell-fav {
        width: 2.2rem;
    }

    .rankshell .bid-note .btn {
        padding-inline: 1.05rem;
        font-size: .93rem;
    }

    .b7-toaster {
        top: 1.75rem;
        right: 1.75rem;
        left: auto;
        max-width: min(24rem, calc(100vw - 3.5rem));
    }

    /* U14 (operator list 2026-10-21): on the desktop card page the value of
       the card is larger, its label a little larger. */
    .ranking-page .card-detail-amount {
        font-size: 1.75rem;
    }

    .ranking-page .card-detail-value-label {
        font-size: .85rem;
    }
}

@media (min-width: 981px) {
    .info-page:has(> .about-grid) {
        max-width: 55rem;
    }

    /* AFR-2 (Q55), UI-02: with the payment row the footer grid gets a
       second row. The about column spans both and pushes the Follow row
       down; the payment row starts under Explore, Help and Legal and, since
       the provider note is gone (2026-10-21), also takes the width under the
       checkpoints, so the chips and the closing text fit in one row on
       wide screens. Both rows end on the same line as Follow. */
    .f-grid--pay {
        grid-template-columns: minmax(0, 1.1fr) minmax(0, 3.2fr) minmax(0, 1.7fr);
        grid-template-rows: auto auto;
    }

    .f-grid--pay .f-about {
        display: flex;
        flex-direction: column;
        grid-row: 1 / span 2;
    }

    .f-grid--pay .f-social-row {
        margin-top: auto;
    }

    .f-grid--pay .footer-nav {
        grid-column: 2;
        grid-row: 1;
    }

    .f-grid--pay .f-pay {
        grid-column: 2 / span 2;
        grid-row: 2;
        align-self: end;
    }

    .f-grid--pay .f-why {
        grid-column: 3;
        grid-row: 1;
    }

    .b7-shell {
        display: grid;
        grid-template-columns: 15rem minmax(0, 1fr);
        gap: var(--space-5);
        align-items: start;
    }

    .b7-side {
        display: block;
        padding: 1.6rem 0 2.5rem;
    }

    .surface main .b7-tiles {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    .surface main .b7-dash-logout {
        display: none;
    }

    /* Home figures: the four public figures share one row. */
    .home-figures .pv-stats-group--figures {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    /* A18: the box rows keep the slot width of a four-column grid, so one
       to three boxes never stretch; Platforms shows at most three boxes and
       leaves the fourth slot free. Below 981px the columns of the box rows
       stay as they are. */
    .ranking-page .b4-feed {
        grid-auto-columns: calc((100% - 3 * var(--space-3)) / 4);
    }

    /* Order 2026-10-29, point 14: the four home activity boxes in one row. */
    .home-activity .home-activity-grid > .b4-feed {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .platforms-page .b4-active {
        grid-auto-columns: calc((100% - 3 * var(--space-4)) / 4);
    }

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

    /* U49 (operator list 2026-10-21): two columns: the card and its rankings
       on the left, the neighbours and the way back below them in the same
       column; value and share on the right over both rows. The second row
       takes the remaining height, so nothing opens a gap under the card. */
    .ranking-page .card-detail {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
        grid-template-rows: auto 1fr;
    }

    .ranking-page .card-detail-main,
    .ranking-page .card-detail-more {
        grid-column: 1;
    }

    .ranking-page .card-detail-side {
        grid-column: 2;
        grid-row: 1 / span 2;
    }

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

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

    .rankshell .card-main {
        grid-template-columns: 5.5rem minmax(0, 1fr) 15.5rem;
    }

    .rankshell .logo {
        width: 76px;
        height: 76px;
        font-size: 1.65rem;
    }
}

/* K-12 (R-01/A-04, operator approval 2026-10-28, a partial correction): from
   981px the four steps need a screen about 34.9 times the default font size
   wide plus the borders and a scrollbar for their longest word
   ("invitations."); below 36em they keep the two columns of the narrower
   screens (with 16px, 20px and 24px never). With a default font size above
   about 34px the 1180px page width leaves four columns too little room at
   every width; that rest stays open. Order, numbers, texts and spacing
   stay. */
@media (min-width: 981px) and (max-width: 36em) {
    .home-steps ol {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* B-7 P2 #ranking-output wrapper: the wrapper markup keeps the same grid and
   gap .ranking-page itself already used for the list, pagination, empty
   state, example and staging activity directly, so wrapping them changes no
   spacing, with or without JavaScript. */
.ranking-page .ranking-output {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}

/* B-7 P2 ranking skeleton (docs/design-drafts/upbiddr-light-draft-b-7.html
   l.978-983 .sk/.sk-line, l.3147-3164 tpl-skeleton): the placeholder card
   shown inside #ranking-output while a progressive filter request is in
   flight. It renders only from the <template id="ranking-skeleton"> markup
   a script inserts; without JavaScript it never appears and the filter form
   stays a plain GET. */
.ranking-page .ranking-sk-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-card-shadow);
}

.ranking-page .ranking-sk-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.ranking-page .ranking-sk {
    display: block;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-sm);
    background: linear-gradient(90deg, var(--surface-2) 25%, color-mix(in srgb, var(--surface-2) 55%, var(--surface)) 50%, var(--surface-2) 75%);
    background-size: 200% 100%;
    animation: ranking-shim 1.4s ease-in-out infinite;
}

.ranking-page .ranking-sk-line {
    width: 100%;
    height: .8rem;
}

.ranking-page .ranking-sk-line--short {
    width: 55%;
}

@keyframes ranking-shim {
    from {
        background-position: 200% 0;
    }
    to {
        background-position: -200% 0;
    }
}

@media (hover: hover) {
    .is-hover-lift:hover {
        border-color: var(--border-strong);
        box-shadow: var(--box-card-shadow-hover);
    }

    /* A32: a real hover over an unsaved heart button darkens the heart on
       the hovered .btn surface (B-7 .fav:hover); a saved heart stays red,
       and a touch leaves no hover state behind. */
    .rankshell .rankshell-fav:not([aria-pressed="true"]):hover {
        color: var(--muted);
    }

    /* U44 (operator list 2026-10-21): of the framed boxes only the cards that
       lead to a card keep a hover shadow, the reduced card hover: the
       neighbour rows of the card page and the activity cards of /rankings
       and, UI04 (operator order 2026-10-24), of the home page. The context,
       value and share boxes of the card page and the home hero are content
       boxes and have none. */
    .ranking-page a.card-neighbour:hover,
    .ranking-page a.b4-feed-card:hover,
    .home-activity a.b4-feed-card:hover {
        box-shadow: var(--box-card-shadow-hover);
    }
}

@media (prefers-reduced-motion: reduce) {
    .f-social__link,
    .js .login-pop.is-ready,
    .js .login-pop.is-ready.is-open,
    .is-hover-lift,
    .home-hero,
    .ranking-page .b4-feed-card,
    .home-activity .b4-feed-card,
    .ranking-page .listing-filters select,
    .ranking-page .listing-filters button[type="submit"],
    .ranking-page .rankings-share-btn:not([hidden]),
    .ranking-page .chip--facet,
    .ranking-page .rankings-share.is-popover .rankings-share-panel.is-ready,
    .ranking-page .rankings-share.is-popover .rankings-share-panel.is-ready.is-open,
    .profile-page .rd-profile-share.is-popover .share-box.is-ready,
    .profile-page .rd-profile-share.is-popover .share-box.is-ready.is-open,
    .ranking-page .filter-fade,
    .ranking-page .filter-nav:not([hidden]),
    .ranking-page .card-detail-backlink,
    .ranking-page .card-detail-backarr,
    .inp,
    .surface--auth .auth-form:has(> input:not([type="hidden"])) button,
    .surface--auth main > form:only-of-type button,
    .surface--member main form:has(:is(input[type="text"],
    input[type="email"],
    input[type="url"],
    input[type="number"],
    input[type="file"],
    select,
    textarea)) button[type="submit"],
    .surface--admin main form:has(:is(input[type="text"],
    input[type="email"],
    input[type="url"],
    input[type="number"],
    input[type="file"],
    select,
    textarea)) button[type="submit"],
    .ranking-page .share-box button,
    .ranking-page .share-box .copy-target,
    .profile-page .share-box button,
    .profile-tabs a,
    .profile-card-list a,
    .surface main :is(input[type="text"],
    input[type="email"],
    input[type="url"],
    input[type="number"],
    input[type="date"],
    input[type="datetime-local"],
    input[type="search"],
    input:not([type]),
    select,
    textarea),
    .surface main button,
    .platforms-box-link,
    .platforms-mini-card,
    .platforms-cta-link,
    .platforms-cta-arrow,
    .home-link,
    .home-arr,
    .ranking-page .card-neighbour,
    .ranking-page .card-detail .ranking-contexts,
    .ranking-page .card-detail .card-detail-value,
    .ranking-page .card-detail .share-box,
    .ranking-page .filter-field .b7-fsw-btn,
    .b7-fsw-chev svg,
    .b7-fpanel.is-ready,
    .b7-fpanel.is-ready.is-open,
    .b7-fopt,
    .b7-info,
    .b7-info__bub,
    .info-page .about-arr,
    .b7-chev > svg,
    .surface--admin .cbx__box,
    .surface--admin .cbx__box svg path,
    .login-pop .cbx__box,
    .login-pop .cbx__box svg path,
    .ranking-page .share-box .share-more--drop > summary,
    .surface .share-box .share-more--drop > summary,
    .info-page a,
    .b7-toast,
    .b7-fsearch__clear {
        transition: none;
    }

    /* Its own rule: a browser without ::details-content (older Firefox,
       Firefox ESR) drops a whole selector list that names it, so these
       stay apart from the list above. */
    .info-page .listing-group details::details-content,
    .ranking-page .share-box .share-more::details-content,
    .surface .share-box .share-more::details-content,
    .info-page .listing-group details[data-disclosure-ready]::details-content,
    .ranking-page .share-box .share-more[data-disclosure-ready]::details-content,
    .surface .share-box .share-more[data-disclosure-ready]::details-content,
    .ranking-page .share-box .share-more--drop::details-content,
    .surface .share-box .share-more--drop::details-content {
        transition: none;
    }

    .ranking-page .ranking-sk {
        animation: none;
    }

    /* A42 (PK3): no movement under reduced motion: the arrow of a forward
       link (B-7 .nav-quiet) keeps its resting place on hover; the colour
       change stays. */
    .platforms-cta-link:hover .platforms-cta-arrow,
    .home-link:hover .home-arr,
    .info-page a.about-link:hover .about-arr {
        transform: translateY(2px);
    }

    /* The same for the back arrow of the card page (B-7 .nav-quiet--back). */
    .ranking-page .card-detail-backlink:hover .card-detail-backarr {
        transform: translateY(-1px);
    }
}

/* P3: the profile form. The profile type as B-7 pick cards (.pick), the
   visibility as a B-7 switch (.switch), the image field as a dropzone that
   keeps the native file input visible, and the passive "Profile details"
   hint. No transition and no new media query; the switch shows the keyboard
   focus on its visible track. */
.b7-pick {
    display: grid;
    gap: .5rem;
    margin: 0;
    padding: 0;
    border: 0;
}

.b7-pick label:not([hidden]) {
    display: flex;
    gap: .65rem;
    align-items: flex-start;
    margin: 0;
    padding: .7rem .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    font-weight: 400;
    cursor: pointer;
}

.b7-pick label:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.surface .b7-pick label:not([hidden]) > input[type="radio"] {
    flex: none;
    margin: .2rem 0 0;
    accent-color: var(--accent);
}

.b7-pick strong {
    display: block;
}

.b7-switch {
    position: relative;
    display: inline-flex;
    gap: .6rem;
    align-items: center;
    margin: 0;
    font-weight: 400;
    cursor: pointer;
}

.surface .b7-switch > input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
}

.b7-switch__track {
    position: relative;
    flex: none;
    width: 2.7rem;
    height: 1.55rem;
    border: 1px solid var(--border-control);
    border-radius: 999px;
    background: var(--surface-2);
}

.b7-switch__track::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: var(--text-faint);
}

.b7-switch > input:checked + .b7-switch__track {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.b7-switch > input:checked + .b7-switch__track::after {
    background: var(--accent);
    transform: translateX(1.12rem);
}

.b7-switch > input:focus-visible + .b7-switch__track {
    box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--focus);
}

.b7-drop {
    display: grid;
    gap: .45rem;
    margin: 0 0 var(--space-3);
    padding: var(--space-4);
    border: 1px dashed var(--border-control);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
}

.b7-drop[data-drop-active] {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.b7-drop > p {
    margin: 0;
}

.b7-drop__current {
    display: flex;
    align-items: center;
}

.surface .b7-drop .b7-drop__img {
    width: 4.5rem;
    height: 4.5rem;
    border-radius: var(--radius-lg);
    background: none;
    object-fit: cover;
}

.b7-drop__placeholder {
    width: 3rem;
    height: 3rem;
    fill: none;
    stroke: var(--text-faint);
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.b7-drop__preview img {
    display: block;
    width: 4.5rem;
    height: 4.5rem;
    border-radius: var(--radius-lg);
    object-fit: cover;
}

.b7-drop__status {
    color: var(--muted);
    font-size: .89rem;
}

.b7-drop__crop {
    display: grid;
    gap: .55rem;
    max-width: 16rem;
}

.b7-drop__crop p {
    margin: 0;
}

.b7-drop__crop-title {
    font-weight: 600;
}

.b7-drop__canvas {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-lg);
    background: var(--surface);
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
}

.b7-drop__canvas:focus-visible {
    outline: none;
    border-color: var(--focus-neutral);
    box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--focus);
}

.b7-drop__range {
    display: grid;
    gap: .2rem;
}

.b7-drop__range input {
    width: 100%;
    margin: 0;
    accent-color: var(--accent);
}

.b7-drop__range-note,
.b7-drop__crop-hint,
.b7-drop__crop-note {
    color: var(--muted);
    font-size: .89rem;
}

.b7-details-hint ul {
    margin: 0;
    padding-left: 1.2rem;
}

.profile-page .profile-ident {
    display: flex;
    flex-wrap: wrap;
    gap: .45rem;
    align-items: baseline;
    margin: 0 0 var(--space-2);
}

.profile-page .profile-ident__name {
    font-weight: var(--font-weight-heading);
}

.profile-page .profile-ident__handle {
    color: var(--text-faint);
}

.profile-page .profile-bio {
    margin: 0 0 var(--space-2);
}

.profile-page .profile-location {
    margin: 0 0 var(--space-3);
    color: var(--muted);
}

/* U3: the share popover of the public profile head. Without JavaScript the share
   box is an ordinary part of the head card. With it the box becomes the popover
   of the head's square share button, in the pattern of the rankings share
   popover: absolute, layer 5 (below the header, above the page), closed until
   opened, motion only once the closed state is settled. Where it sits (below
   the button, within the card on narrow screens and right-aligned to the
   button from the wider grid on) is decided in the redesign block. */
.profile-page .rd-profile-share.is-popover .share-box {
    position: absolute;
    z-index: 5;
    gap: .45rem;
    margin: 0;
    padding: var(--space-4);
    border-color: var(--border-strong);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px) scale(.985);
    pointer-events: none;
}

.profile-page .rd-profile-share.is-popover .share-box.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.profile-page .rd-profile-share.is-popover .share-box.is-ready {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base);
}

.profile-page .rd-profile-share.is-popover .share-box.is-ready.is-open {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s;
}

.profile-page .rd-profile-share.is-popover .share-box h2 {
    font-size: .85rem;
}

.profile-page .rd-profile-share.is-popover .share-box > p {
    color: var(--text-faint);
    font-size: .76rem;
}

.profile-page .rd-profile-share.is-popover .share-box > p:has(> a) {
    display: none;
}

/* B-7 staging previews. Sample elements of later functions from
   docs/design-drafts/upbiddr-light-draft-b-7.html, each with a visible
   .preview-tag marker (B-7 .ann .ann--later): the home statistics and the
   latest activity list (B-7 .b4-stats, .b4-feed), the live line of the
   rankings page (B-7 .b4-live) and the sample figures of a ranking card. They
   are rendered only behind App\Support\StagingPreviewGate, so these rules have
   nothing to style on a live surface. Namespace .preview-, existing tokens
   only. The online dot pulses like B-7 .b4-dot; reduced motion stops it and
   leaves the ring visible. */
.preview-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-6);
}

.preview-stat {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: .3rem;
    margin: 0;
    padding: var(--space-4);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.preview-stat-label {
    color: var(--text-faint);
    font-size: .73rem;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.preview-stat-value {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: 1.45rem;
    font-weight: var(--font-weight-heading);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.03em;
}

.preview-online {
    color: var(--live);
}

.preview-dot,
.pv-dot {
    position: relative;
    flex: none;
    width: .5rem;
    height: .5rem;
    aspect-ratio: 1;
    border-radius: 50%;
    background-color: var(--live);
}

.preview-dot::after,
.pv-dot::after {
    content: "";
    position: absolute;
    inset: -3px;
    border: 2px solid var(--live);
    border-radius: 50%;
    opacity: 0;
    animation: preview-pulse 2400ms var(--motion-ease) infinite;
}

@keyframes preview-pulse {
    0% {
        transform: scale(.65);
        opacity: .9;
    }

    70% {
        transform: scale(1.25);
        opacity: 0;
    }

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

/* Public statistic boxes (home, rankings; B-7 .b4-stats, l.1230-1278): one
   tile per figure. The info icon sits inside the tile at its top right and
   stays an ordinary focusable button; the value sits at the bottom, so the
   values of a row line up whatever the label length. The green dot marks the
   online estimate only and shares the B-7 .b4-dot look and its reduced motion
   rule above. Existing tokens only. */
.pv-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-6);
}

.pv-stats--rankings {
    margin: 0;
}

.pv-stat {
    position: relative;
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 0;
    margin: 0;
    padding: var(--space-4);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.pv-stat > .b7-info {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    margin: 0;
    vertical-align: baseline;
}

/* The icon sits at the right edge of the tile, so its bubble opens towards
   the left instead of centred. Its width never exceeds the content width of
   its own tile (the tile is the size container, 100cqw), so the bubble of a
   tile in the first column never leaves the view, with or without the
   script. public/js/app.js still measures it as everywhere. */
.pv-stat > .b7-info .b7-info__bub {
    right: -.35rem;
    left: auto;
    max-width: min(19rem, 100cqw);
    transform: translateY(4px);
}

.pv-stat > .b7-info:is(:hover, :focus-visible, [aria-expanded="true"]) .b7-info__bub {
    transform: none;
}

.pv-label {
    padding-right: 1.6rem;
    color: var(--text-faint);
    font-size: .73rem;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.pv-value {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin-top: auto;
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: 1.45rem;
    font-weight: var(--font-weight-heading);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.03em;
}

.pv-stats--rankings .pv-value {
    font-size: 1.05rem;
}

.pv-value--muted {
    color: var(--muted);
    font-family: inherit;
    font-size: .95rem;
    font-weight: var(--font-weight-medium);
    letter-spacing: 0;
}

.preview-live {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .3rem .55rem;
    margin: 0 0 .5rem;
    padding: .3rem .75rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--muted);
    font-size: .82rem;
}

.preview-live-num {
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-medium);
}

.preview-online .preview-live-num {
    color: inherit;
}

.preview-live-sep {
    color: var(--border-control);
}

.preview-activity {
    margin: 0 0 var(--space-7);
}

.preview-feed {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
    gap: var(--space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.preview-feed-card {
    display: grid;
    grid-template-columns: 2.5rem minmax(0, 1fr);
    align-items: start;
    gap: .5rem;
    padding: var(--space-4);
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-card-shadow);
}

.preview-feed-logo {
    display: grid;
    grid-row: span 2;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: .9rem;
    font-weight: var(--font-weight-heading);
}

.preview-feed-title {
    overflow: hidden;
    min-width: 0;
    font-size: .93rem;
    font-weight: var(--font-weight-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.preview-feed-foot {
    display: flex;
    flex-wrap: wrap;
    grid-column: 2;
    align-items: baseline;
    gap: .3rem .6rem;
}

.preview-feed-val {
    font-family: var(--font-family-num);
    font-size: 1.02rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -0.02em;
}

.preview-feed-delta {
    padding: 0 .35rem;
    border: 1px solid color-mix(in srgb, var(--positive) 26%, transparent);
    border-radius: var(--radius-sm);
    background: var(--positive-soft);
    color: var(--positive);
    font-family: var(--font-family-num);
    font-size: .78rem;
    line-height: 1.5;
}

.preview-feed-time {
    color: var(--text-faint);
    font-size: .78rem;
}

/* The visible marker of every staging preview (B-7 .ann .ann--later): a
   sample value, an example entry or a later function is never mistaken for
   live data. .preview-note is the one line that names a whole sample block.
   The marker of the preview heart only shows once the script has revealed
   the heart itself. */
.preview-tag {
    display: inline-flex;
    flex: none;
    align-items: center;
    max-width: 100%;
    margin: 0 .35rem 0 0;
    padding: .16rem .5rem;
    border: 1px solid var(--accent-border);
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: .67rem;
    font-weight: var(--font-weight-medium);
    letter-spacing: .07em;
    line-height: 1.2;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
}

.preview-note {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    margin: 0 0 var(--space-3);
    color: var(--muted);
    font-size: .82rem;
}

.preview-fav[hidden] + .preview-fav-tag {
    display: none;
}

/* B-7 card statistics (.b4-dstats). */
.preview-dstats-block {
    padding: var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.preview-dstats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
    gap: .6rem;
}

.preview-dstat {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    margin: 0;
    padding: .6rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.preview-dstat-value {
    font-family: var(--font-family-num);
    font-size: 1.15rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
}

.preview-dstat-label {
    color: var(--text-faint);
    font-size: .75rem;
}

/* B-7 "Most active platforms" (.b4-active): three equal boxes on another
   surface than the platform teasers, with no brand line. */
.preview-active {
    margin: var(--space-6) 0 0;
}

.preview-sec-head {
    max-width: 62ch;
    margin: 0 0 var(--space-5);
}

.preview-sec-head h2 {
    margin: .7rem 0 0;
    font-size: clamp(1.5rem, 3.4vw, 2.05rem);
    line-height: 1.12;
    letter-spacing: -0.035em;
}

.preview-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin: 0;
    padding: .3rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: .71rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .14em;
    text-transform: uppercase;
}

.preview-eyebrow::before {
    content: "";
    width: 14px;
    height: 2px;
    border-radius: 1px;
    background: linear-gradient(90deg, var(--accent-gradient-from), var(--accent-gradient-to));
}

.preview-grad {
    background: linear-gradient(90deg, var(--grad-text-from), var(--grad-text-to));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

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

.preview-act {
    display: flex;
    flex-direction: column;
    gap: .45rem;
    padding: var(--space-4);
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
}

.preview-act-name {
    color: var(--foreground);
    font-size: 1.02rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -0.025em;
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.preview-act-name:hover {
    color: var(--accent-text);
}

.preview-act-rank,
.preview-act-time {
    color: var(--text-faint);
    font-size: .78rem;
}

.preview-act-rank {
    font-family: var(--font-family-num);
}

.preview-act-metric {
    color: var(--muted);
    font-size: .82rem;
}

.preview-act-mini {
    display: grid;
    grid-template-columns: auto 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: .65rem;
    padding: .5rem .6rem;
    border-radius: var(--radius-md);
    background: var(--surface);
}

.preview-act-mini-rank {
    color: var(--text-faint);
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
}

.preview-act-mini-logo {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: .78rem;
    font-weight: var(--font-weight-heading);
}

.preview-act-mini-title {
    overflow: hidden;
    min-width: 0;
    font-size: .9rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.preview-act-mini-value {
    color: var(--muted);
    font-size: .84rem;
    font-variant-numeric: tabular-nums;
}

/* The synthetic owner line of a card (B-7 .rc-ident): name, separator and
   handle. It is plain text; there is no profile behind a sample.

   .example-ident and its children carry the identical look for the P1a
   example card beside an empty list: unlike this preview-ident row, that
   card is not gated, so it keeps its own, non "preview-" class names rather
   than the staging-only ones the marker tests above tie to the gate. */
.preview-ident,
.example-ident {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .45rem;
    min-height: 1.2rem;
    margin: 0 0 .22rem;
    line-height: 1.2;
}

.preview-uname,
.example-uname {
    color: var(--foreground);
    font-size: .89rem;
    font-weight: var(--font-weight-heading);
}

.preview-sep,
.example-sep {
    color: var(--text-faint);
    font-size: .9rem;
}

.preview-handle,
.example-handle {
    color: var(--text-faint);
    font-size: .8rem;
}

/* P6: the real public identity line of a card, "Username · @profile name"
   (B-7 .rc-ident). Same look as the example line; a long username is cut
   with an ellipsis, and only the @profile name is a link. */
.rc-ident {
    display: flex;
    align-items: baseline;
    gap: .45rem;
    min-width: 0;
    min-height: 1.2rem;
    margin: 0 0 .22rem;
    line-height: 1.2;
}

.rc-ident-uname {
    min-width: 0;
    overflow: hidden;
    color: var(--foreground);
    font-size: .89rem;
    font-weight: var(--font-weight-heading);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rc-ident-sep {
    flex: none;
    color: var(--text-faint);
    font-size: .9rem;
}

.rc-ident-handle {
    flex: none;
    color: var(--text-faint);
    font-size: .8rem;
}

a.rc-ident-handle {
    color: var(--accent-text);
    text-decoration: none;
}

a.rc-ident-handle:hover,
a.rc-ident-handle:focus-visible {
    text-decoration: underline;
    text-underline-offset: .18em;
}

/* RK-07: on the full ranking card and the detail card the identity line is
   light grey (B-7 .rc-ident), its profile link turns blue on hover and on
   keyboard focus (with the global focus ring). Only inside the card.
   A47: the username itself, as text and as link, has the foreground
   colour on every ranking card; the @profile name stays light grey. */
.rankshell .rc-ident-handle {
    color: var(--text-faint);
}

.rankshell .rc-ident-uname {
    color: var(--foreground);
}

.rankshell a.rc-ident-uname,
.rankshell a.rc-ident-handle {
    color: var(--text-faint);
    text-decoration: none;
    transition: color var(--motion-fast) var(--motion-ease);
}

.rankshell a.rc-ident-uname {
    color: var(--foreground);
}

.rankshell a.rc-ident-uname:hover,
.rankshell a.rc-ident-uname:focus-visible,
.rankshell a.rc-ident-handle:hover,
.rankshell a.rc-ident-handle:focus-visible {
    color: var(--accent-text);
    text-decoration: none;
}

/* B-7 favourite heart (.fav): a like button feel, a short dip and overshoot
   and a ring that runs out once. The pressed state lives in the page view
   only; nothing is saved or sent. The touch target stays 44px on narrow
   screens while the visible box is smaller. A32: the P1a example card has no
   toggle of its own any more; its Saved heart is the display heart of a
   real card. */
.preview-fav:not([hidden]) {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
    transition: color var(--motion-fast) var(--motion-ease);
}

.preview-fav::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    transform: translate(-50%, -50%);
    pointer-events: none;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.preview-fav svg {
    position: relative;
    width: 16px;
    height: 16px;
    stroke-width: 1.8;
}

.preview-fav:hover {
    color: var(--muted);
}

.preview-fav:hover::before {
    background-color: var(--surface-2);
}

.preview-fav[aria-pressed="true"] {
    color: var(--heart);
}

.preview-fav[aria-pressed="true"]::before {
    border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
    background-color: var(--accent-soft);
}

.preview-fav[aria-pressed="true"] svg {
    fill: currentColor;
}

.preview-fav.is-pop svg {
    animation: preview-favpop 420ms var(--motion-ease);
}

.preview-fav.is-pop::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 2.1rem;
    height: 2.1rem;
    margin: -1.05rem 0 0 -1.05rem;
    border: 2px solid var(--heart);
    border-radius: var(--radius-md);
    pointer-events: none;
    animation: preview-burst 480ms var(--motion-ease) forwards;
}

/* B-7 time range (.segs), the real calendar period switch (PR B): plain
   links; a sliding surface and the brand line sit under the current one once
   the script has placed them. Without the script the current link carries
   the same surface itself. The reset countdown sits right beside it in the
   type of the results count. */
.range-switch {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem var(--space-3);
    min-width: 0;
}

.range-segs {
    position: relative;
    display: inline-flex;
    max-width: 100%;
    padding: .25rem;
    overflow-x: auto;
    border: 1px solid var(--border-soft);
    /* A31: the outer radius of the filter bar (radius-lg); the surface inside
       is concentric with it: the outer radius less the border and the
       padding, so both curves run parallel. No new token. */
    border-radius: var(--radius-lg);
    background: var(--surface-2);
    scrollbar-width: none;
}

.range-segs::-webkit-scrollbar {
    display: none;
}

.range-segs-thumb {
    position: absolute;
    top: .25rem;
    bottom: .25rem;
    left: 0;
    width: 0;
    border: 1px solid var(--border);
    border-radius: calc(var(--radius-lg) - .25rem - 1px);
    background: var(--surface);
    box-shadow: var(--shadow);
}

.range-segs-ink {
    position: absolute;
    bottom: .25rem;
    left: 0;
    z-index: 2;
    width: 0;
    height: 3px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
}

.range-segs:not(.is-ready) .range-segs-thumb,
.range-segs:not(.is-ready) .range-segs-ink {
    display: none;
}

.range-segs.is-ready .range-segs-thumb,
.range-segs.is-ready .range-segs-ink {
    transition: transform var(--motion-base) var(--motion-ease), width var(--motion-base) var(--motion-ease);
}

.range-segs a {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    min-height: 2.5rem;
    padding: .35rem .8rem .55rem;
    border-radius: calc(var(--radius-lg) - .25rem - 1px);
    color: var(--muted);
    font-size: .84rem;
    text-decoration: none;
    white-space: nowrap;
}

.range-segs a:hover {
    color: var(--foreground);
}

.range-segs a[aria-current="page"] {
    color: var(--foreground);
    font-weight: var(--font-weight-medium);
}

.range-segs:not(.is-ready) a[aria-current="page"] {
    background: var(--surface);
    box-shadow: var(--shadow);
}

/* Narrow screens: side padding and type shrink with the viewport (no extra
   media rule), so all four segments fit at 360px and the current one is
   never cut off; from about 600px on the values above apply unchanged. */
.range-segs a {
    padding-right: clamp(.4rem, 2.2vw, .8rem);
    padding-left: clamp(.4rem, 2.2vw, .8rem);
    font-size: clamp(.78rem, 3.4vw, .84rem);
}

.ranking-page .ranking-reset {
    margin: 0;
    color: var(--text-faint);
    font-size: .76rem;
    font-variant-numeric: tabular-nums;
}

.ranking-page .ranking-reset-end {
    margin-left: .35rem;
}

.ranking-page .ranking-period-note {
    margin: var(--space-3) 0;
}

/* Calendar ranking archive (PR C): the Leaderboards overview and the full
   list of a closed period. Only existing tokens and components: the period
   boxes reuse the surface, border and radius of the list's empty state, the
   Closed / Partial label is the card's own origin label (.rankshell-origin),
   the tabs are the period switch (.range-segs) and the cards are the shared
   full ranking card. No media query: the head wraps by itself. */
.ranking-archive .archive-boxes {
    display: grid;
    gap: var(--space-5);
    margin: var(--space-4) 0 0;
}

.ranking-archive .archive-box {
    display: grid;
    gap: var(--space-4);
    padding: clamp(var(--space-3), 3vw, var(--space-5));
    border: 1px solid var(--box-muted-border);
    border-radius: var(--radius-lg);
    background: var(--box-muted-bg);
}

.ranking-archive .archive-box-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-3);
}

.ranking-archive .archive-box-head h2,
.ranking-archive .archive-period-head h2 {
    margin: 0;
    font-size: 1.05rem;
}

/* UI-04 and UI-05 (operator decision 2026-10-21): the info icon of a box or
   group title sits right beside the title text, raised to its top like a
   superscript. Only the icon moves: its size and hit area, the bubble and
   its position over the icon stay those of .b7-info. */
.ranking-archive .archive-box-title {
    display: flex;
    align-items: flex-start;
    min-width: 0;
}

.ranking-archive .archive-box-title > .b7-info,
.ranking-page .ranking-contexts .ranking-contexts-group > .b7-info {
    margin-top: -.15rem;
    margin-left: .15rem;
}

.ranking-archive .archive-period-span {
    margin: 0;
    color: var(--muted);
    font-size: .85rem;
}

.ranking-archive .archive-status {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}

.ranking-archive .archive-box-note {
    margin: 0;
    color: var(--muted);
}

.ranking-archive .archive-box-actions {
    margin: 0;
}

/* Live box (Package C): the running period before the closed boxes, in the
   same box look. The dot is the existing B-7 online dot (.pv-dot, --live,
   its reduced motion rule stops the pulse); the word "Live" carries the
   meaning in the positive text colour, so nothing relies on colour alone.
   The countdown is the period switch's own .ranking-reset. */
.ranking-archive .archive-box--live {
    margin: var(--space-4) 0 0;
    border-color: var(--border-strong);
}

.ranking-archive .archive-box--live + .archive-boxes {
    margin-top: var(--space-5);
}

.ranking-archive .archive-live {
    gap: .4rem;
}

.ranking-archive .archive-live-text {
    color: var(--positive);
    font-size: .78rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .06em;
    text-transform: uppercase;
}

.ranking-archive .archive-live-intro {
    margin: 0;
    color: var(--muted);
}

.ranking-archive .archive-live-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-4);
}

.ranking-archive .archive-live-count {
    color: var(--muted);
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
}

.ranking-archive .archive-live-meta .ranking-reset {
    margin: 0;
}

.ranking-archive .archive-period-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-3);
    margin: 0 0 var(--space-3);
}

.ranking-archive .archive-back {
    margin: 0 0 var(--space-3);
}

/* B-7 latest activity in this ranking (.b4-feed--ranked). */
.preview-ranked {
    margin: var(--space-5) 0 0;
}

.preview-ranked > h2 {
    margin: 0 0 var(--space-3);
    font-size: 1rem;
}

.preview-feed-head {
    display: flex;
    align-items: baseline;
    gap: .45rem;
    min-width: 0;
}

.preview-feed-rank {
    flex: none;
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .93rem;
}

/* B-7 example card beside an empty list (.b4-democard): the card language
   with a dashed edge. */
.preview-demo {
    margin: var(--space-5) 0 0;
}

.preview-demo > h2 {
    margin: 0 0 var(--space-3);
    font-size: 1rem;
}

.preview-democard {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-4) var(--space-5);
    padding: var(--space-5);
    border: 1px dashed var(--border-control);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow);
}

.preview-democard-left {
    display: flex;
    flex: none;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
}

.preview-democard-logo {
    display: grid;
    place-items: center;
    width: 3.4rem;
    height: 3.4rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: linear-gradient(145deg, var(--surface-2), var(--teal-soft));
    color: var(--accent-deep);
    font-size: 1.15rem;
    font-weight: var(--font-weight-heading);
}

.preview-democard-rank {
    font-family: var(--font-family-num);
    font-size: 1.1rem;
    font-weight: var(--font-weight-heading);
    font-variant-numeric: tabular-nums;
}

.preview-democard-mid {
    flex: 1 1 18rem;
    min-width: 0;
}

.preview-democard-mid p {
    margin: 0 0 .5rem;
}

.preview-democard-title {
    font-size: 1.2rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.032em;
    line-height: 1.24;
}

.preview-democard-teaser {
    color: var(--muted);
    font-size: .92rem;
}

.preview-democard-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}

.preview-democard-chips span {
    display: inline-flex;
    align-items: center;
    min-height: 1.45rem;
    padding: 0 .55rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--muted);
    font-size: .735rem;
}

.preview-democard-stats {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem .75rem;
    color: var(--text-faint);
    font-size: .8rem;
}

.preview-democard-value {
    display: flex;
    flex: 1 1 12rem;
    flex-direction: column;
    align-items: flex-end;
    gap: .35rem;
    text-align: right;
}

.preview-democard-label {
    display: inline-flex;
    align-items: center;
    min-height: 1.25rem;
    padding: 0 .45rem;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
    font-size: .68rem;
    font-weight: var(--font-weight-medium);
}

.preview-democard-vlabel {
    color: var(--text-faint);
    font-size: .72rem;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.preview-democard-amount {
    font-family: var(--font-family-num);
    font-size: 1.55rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.04em;
    line-height: 1.05;
}

/* B-7 ranking contexts in the Details panel of a list card (.ctxrow): the
   context chips carry the lighter B-7 edge and lead to their filtered list. */
.preview-ctxrow {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin: 0 0 .8rem;
}

.preview-ctx {
    display: inline-flex;
    align-items: center;
    min-height: 1.85rem;
    padding: .25rem .55rem;
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--muted);
    font-size: .735rem;
    line-height: 1.25;
    text-decoration: none;
}

.preview-ctxrow a.preview-ctx:hover {
    border-color: var(--accent-border);
    background-color: var(--accent-soft);
    color: var(--accent-text);
}

@keyframes preview-favpop {
    0% {
        transform: scale(1);
    }

    30% {
        transform: scale(.82);
    }

    60% {
        transform: scale(1.18);
    }

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

@keyframes preview-burst {
    0% {
        transform: scale(.72);
        opacity: .85;
    }

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

@media (prefers-reduced-motion: reduce) {
    .preview-dot::after,
    .pv-dot::after {
        animation: none;
        opacity: 1;
        transform: none;
    }

    .preview-fav:not([hidden]),
    .preview-fav::before,
    .preview-act-name,
    .range-segs.is-ready .range-segs-thumb,
    .range-segs.is-ready .range-segs-ink {
        transition: none;
    }

    .preview-fav.is-pop svg,
    .rankshell .rankshell-fav.is-pop .ico {
        animation: none;
    }

    .preview-fav.is-pop::after,
    .rankshell .rankshell-fav.is-pop::after {
        display: none;
        animation: none;
    }
}

/* Pressed stepper of the target control, dark theme. The pressed fill of the
   redesign block is a light border token, which in the dark theme is lighter
   than the resting surface. Here the pressed button gets the darker page
   background instead. The rule sits outside the redesign block, which may not
   name the theme, and wins by its longer selector, not by order; it also
   outranks the hover fill. The light theme keeps the rule of the block. A38
   (PK3): the order buttons of the link list share it. */
html[data-theme="dark"] .rd .rd-target__step:not([hidden]):active:not(:disabled),
html[data-theme="dark"] .rd .rd-move__btn:not([hidden]):active:not(:disabled) {
    background-color: var(--background);
}

/* UI package (operator decision of 2026-10-12): Claim rank, Increase,
   account, images, Contract Withdrawal and the local calendar. These rules
   sit in front of the white surfaces and the redesign blocks and win by
   their scoped selectors, not by order. */
/* UI package (operator decision of 2026-10-12): Claim rank and Increase.

   Page head: a lede that runs over the full width of the page container. It
   is set as its own row under the head grid (partials/page-head, ledeWide), so
   it does not share the width with the actions column (CR-02, IN-02). */
.rd .rd-head__lede.rd-head__lede--wide {
    max-width: none;
}

/* CR-01: the tiles of "Card to pass" carry no shadow of their own, at rest and
   in every state; other stat tiles keep theirs. */
.rd main section[aria-labelledby="claim-reference-heading"] .rd-stat,
.rd main section[aria-labelledby="claim-reference-heading"] .rd-stat:hover {
    box-shadow: none;
}

/* CR-04/CR-05: the two choice sections (bare structure, .rd-bare). Heading and
   note sit close together, the content after the note keeps the full step;
   the section itself gets more room above its heading. Only the margins of the
   direct children are set, so the gap and the margins add up to exactly the
   documented values: heading to note .5rem, note to content and content to
   content 1rem, 1.5rem above the heading. */
.rd main .rd-stack > section.rd-claim-list {
    gap: var(--space-2);
    margin-top: var(--space-2);
}

.rd main section.rd-claim-list > * {
    margin: 0;
}

.rd main section.rd-claim-list > * + :not(.rd-note) {
    margin-top: var(--space-2);
}

/* CR-07: the free slot hint runs over the full width of its box. */
.rd main .rd-claim-slot > p {
    max-width: none;
}

/* CR-06/CR-08/CR-15/CR-17: the shadow hierarchy of the choice lists. The
   section is bare (no frame, no shadow, no lift). The list box directly in a
   section and every card row of a list, also inside the "more" and
   "unavailable" accordions, are white surfaces (see the white surfaces block)
   with the normal shadow at rest and the strong shadow on keyboard focus
   (here) and on hover (the one lift rule of the hover block). Both values are the existing tokens; a hovered row inside a hovered
   box shows the two planned layers, never two shadows on one surface. */
.rd main .rd-claim-list > .rd-rows {
    padding: var(--space-3);
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--box-card-shadow);
    transition: box-shadow var(--motion-base) var(--motion-ease);
}

.rd main .rd-claim-list .rd-rows > li.rd-row {
    box-shadow: var(--box-card-shadow);
}

.rd main .rd-claim-list > .rd-rows:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):focus-visible),
.rd main .rd-claim-list .rd-rows > li.rd-row:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):focus-visible) {
    box-shadow: var(--box-card-shadow-hover);
}

/* A51: in "Create a new card" the list is no box: no surface, border,
   shadow, hover shadow or padding, so every link row takes the full width
   with its own shadow and hover. The other lists keep their box; the
   section element outweighs the white surface rule below. */
.rd main section.rd-claim-list--create > .rd-rows,
.rd main section.rd-claim-list--create > .rd-rows:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):focus-visible) {
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}


/* U34 (operator list 2026-10-21): the own cards under "Use one of your
   cards" stand on their own like the link rows of "Create a new card": the
   list has no box, every card row keeps its own surface and shadow. */
.rd main section.rd-claim-list--own > .rd-rows,
.rd main section.rd-claim-list--own > .rd-rows:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):focus-visible) {
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

/* CR-12: "Signed in as" follows the page head closely. */
.rd main > .rd-head:has(+ .rd-note--identity) {
    margin-bottom: var(--space-2);
}

.rd main > .rd-note.rd-note--identity {
    margin: 0 0 var(--space-4);
}

/* CR-13: the names of the two cards and the value to pass as small labelled
   rows below the figures. One column on a narrow screen, label and value side
   by side from 761px. */
.rd main .rd-claim-details {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2);
    justify-self: stretch;
    width: 100%;
    margin: 0 0 var(--space-4);
}

.rd main .rd-claim-details__row {
    display: grid;
    gap: .1rem;
    min-width: 0;
}

.rd main .rd-claim-details dt {
    color: var(--muted);
    font-size: .84rem;
}

.rd main .rd-claim-details dd {
    margin: 0;
    font-weight: var(--font-weight-medium);
}


/* CR-16: in the attribute box of the card forms the info icon of a field sits
   directly after its label, not at the far edge; tooltip and focus are those
   of the info tip itself, which has no shadow. */
.rd fieldset.rd-attrs .rd-field-head {
    justify-content: flex-start;
}

/* AC-01: Copy and Public Card sit side by side in one row and wrap on a
   narrow screen. */
.rd .rd-card .rd-copy-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.rd .rd-card .rd-copy-actions > .copy-target-status {
    margin-left: 0;
}

/* 2026-10-14: in the "Public ranking card URL" box only, Copy card URL and
   Public card share the whole field width (the status line is visually
   hidden and takes no part). */
.rd .rd-card--public-url .rd-copy-actions > .copy-target:not([hidden]) {
    flex: 1 1 0;
    min-width: max-content;
    justify-content: center;
}

/* AC-03: the tables of "My ranking increases" and "Payments" and their
   stacked rows on a narrow screen carry no shadow; the sections are static
   (rd-static), so no wrapper lifts on hover either, and the wrapper itself
   (a framed section of the page styles) rests without a shadow. */
.rd main > section.rd-stack.rd-stack--increases,
.rd main > section.rd-stack.rd-stack--payments,
.rd main section.rd-stack.rd-stack--increases .rd-table,
.rd main section.rd-stack.rd-stack--increases .rd-table tr,
.rd main section.rd-stack.rd-stack--payments .rd-table,
.rd main section.rd-stack.rd-stack--payments .rd-table tr {
    box-shadow: none;
}

/* IM-01 (UI package, 2026-10-12): one rule for every logo tile of the site.
   A picture that is shown stands without the placeholder surface and frame;
   the radius stays. Without a picture, and after a picture failed to load
   (public/js/app.js hides it and takes the image state off its box), the
   tile keeps or gets back its placeholder surface, frame and letter or icon.
   Only the fixed modifier classes of the views carry the image state. */
img.logo.logo--img,
html[data-theme="dark"] img.logo.logo--img {
    border-color: transparent;
    background: none;
}

img.logo.logo--img[hidden],
.card-neighbour-logo > img.logo--img[hidden],
.rd :is(.rd-row__logo, .rd-mini__logo) > img.logo--img[hidden] {
    display: none;
}

.ranking-page .card-neighbour-logo.card-neighbour-logo--img,
.rd .rd-mini__logo.rd-mini__logo--img {
    overflow: hidden;
    border-color: transparent;
    background: none;
}

.ranking-page .card-neighbour-logo > img.logo--img,
.rd .rd-mini__logo > img.logo--img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* UI package (2026-10-12): Contract Withdrawal.

   WD-01: the introduction runs over the full width of the page. */
.info-page > p.info-page__lede--wide {
    max-width: none;
}

/* WD-11: the early start hint with its info icon next to the text. */
.info-page .withdrawal-early {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-3);
    align-items: start;
}

.info-page .withdrawal-early__text > :last-child {
    margin-bottom: 0;
}

/* WD-05: the heading of the description box stands inside the box (the
   legend pattern of the attribute box), not on its frame; fieldset and
   legend stay. WD-06: more room after the hint. WD-07: more room below the
   date, the amount and the card name. */
.info-page .contact-form fieldset.withdrawal-describe > legend {
    float: left;
    width: 100%;
    margin: 0 0 var(--space-2);
    padding: 0;
    font-size: 1.04rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

.info-page .contact-form fieldset.withdrawal-describe > legend + * {
    clear: both;
}

.info-page .contact-form fieldset.withdrawal-describe > #withdrawal-describe-hint {
    margin: 0 0 var(--space-4);
}

.info-page .contact-form fieldset.withdrawal-describe > .field:not(:last-child) {
    margin: 0 0 var(--space-4);
}

/* WD-14/WD-15: the receipt is centred; "Case reference:" is the clear label
   and the reference follows it on the same line without an indent. */
.rd .rd-center.withdrawal-receipt .rd-return-facts dt {
    color: var(--foreground);
    font-weight: var(--font-weight-heading);
}

.rd .rd-center.withdrawal-receipt .rd-return-facts dd {
    margin: 0;
    padding: 0;
}

/* WD-08/WD-09: the local calendar of the date fields (public/js/app.js,
   rd-datepicker). It only exists with the script; without it the field stays
   the native or text field of the server. Tokens only, so the dark theme
   follows; it works with and without the redesign surface (admin). */
.rd-dp {
    position: relative;
    display: block;
    min-width: 0;
}

/* The field keeps room on the right for the calendar button; the repeated
   class and :root outweigh the field rules of the page styles. */
:root .rd-dp > input.rd-dp__input.rd-dp__input {
    width: 100%;
    padding-right: 2.9rem;
}

.rd-dp .rd-dp__toggle {
    position: absolute;
    top: 50%;
    right: .3rem;
    display: grid;
    place-items: center;
    width: 2.3rem;
    height: 2.3rem;
    margin: 0;
    padding: 0;
    transform: translateY(-50%);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--accent-text);
    cursor: pointer;
}

.rd-dp .rd-dp__toggle:hover,
.rd-dp.is-open .rd-dp__toggle {
    background: var(--accent-soft);
}

.rd-dp button:focus-visible {
    outline: var(--focus-ring-width, 2px) solid var(--focus);
    outline-offset: 1px;
}

.rd-dp .rd-dp__dialog {
    position: absolute;
    z-index: 30;
    top: calc(100% + .35rem);
    left: 0;
    width: min(21rem, calc(100vw - 2rem));
    padding: var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
    color: var(--foreground);
    text-align: left;
}

.rd-dp .rd-dp__dialog[hidden] {
    display: none;
}

.rd-dp .rd-dp__dialog .rd-dp__head {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-2);
}

.rd-dp .rd-dp__dialog .rd-dp__title {
    max-width: none;
    margin: 0;
    font-weight: var(--font-weight-heading);
    text-align: center;
}

.rd-dp .rd-dp__dialog .rd-dp__nav,
.rd-dp .rd-dp__dialog .rd-dp__day,
.rd-dp .rd-dp__dialog .rd-dp__apply,
.rd-dp .rd-dp__dialog .rd-dp__clear,
.rd-dp .rd-dp__dialog .rd-dp__close {
    margin: 0;
    font: inherit;
    cursor: pointer;
}

.rd-dp .rd-dp__dialog .rd-dp__nav {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--foreground);
}

.rd-dp .rd-dp__dialog .rd-dp__grid {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
    table-layout: fixed;
    background: transparent;
    font-size: 1rem;
}

.rd-dp .rd-dp__dialog .rd-dp__grid th {
    padding: 0 0 .25rem;
    border: 0;
    letter-spacing: normal;
    text-transform: none;
    color: var(--muted);
    font-size: .74rem;
    font-weight: var(--font-weight-medium);
    text-align: center;
}

.rd-dp .rd-dp__dialog .rd-dp__grid td {
    padding: 1px;
    border: 0;
    text-align: center;
    vertical-align: middle;
}

.rd-dp .rd-dp__dialog .rd-dp__day {
    display: grid;
    place-items: center;
    width: 100%;
    min-width: 0;
    min-height: 2.75rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--foreground);
    font-size: .9rem;
    font-variant-numeric: tabular-nums;
}

.rd-dp .rd-dp__dialog .rd-dp__day--out {
    color: var(--text-faint);
}

.rd-dp .rd-dp__dialog .rd-dp__day[aria-current="date"] {
    border-color: var(--accent-border);
}

.rd-dp .rd-dp__dialog .rd-dp__day:hover {
    background: var(--surface-2);
}

.rd-dp .rd-dp__dialog .rd-dp__day.is-selected {
    border-color: var(--accent-border);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-weight: var(--font-weight-heading);
}

.rd-dp .rd-dp__dialog .rd-dp__day[aria-disabled="true"] {
    color: var(--text-faint);
    cursor: not-allowed;
}

.rd-dp .rd-dp__dialog .rd-dp__note {
    max-width: none;
    margin: var(--space-2) 0 0;
    color: var(--muted);
    font-size: .84rem;
}

.rd-dp .rd-dp__dialog .rd-dp__note[hidden] {
    display: none;
}

.rd-dp .rd-dp__dialog .rd-dp__time {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-2);
    margin: var(--space-3) 0 0;
}

.rd-dp .rd-dp__dialog .rd-dp__time-field {
    display: grid;
    font-weight: var(--font-weight-medium);
    gap: .2rem;
    margin: 0;
    color: var(--muted);
    font-size: .8rem;
}

.rd-dp .rd-dp__dialog .rd-dp__time-input {
    width: 3.6rem;
    max-width: 3.6rem;
    min-height: 2.75rem;
    margin: 0;
    padding: 0 .4rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    text-align: center;
}

.rd-dp .rd-dp__dialog .rd-dp__foot {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
    margin: var(--space-3) 0 0;
}

.rd-dp .rd-dp__dialog .rd-dp__apply,
.rd-dp .rd-dp__dialog .rd-dp__clear,
.rd-dp .rd-dp__dialog .rd-dp__close {
    min-height: 2.75rem;
    padding: 0 .9rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font-size: .88rem;
    font-weight: var(--font-weight-medium);
}

.rd-dp .rd-dp__dialog .rd-dp__apply {
    border-color: var(--accent-border);
    background: var(--accent-soft);
    color: var(--accent-text);
}

.rd-dp .rd-dp__dialog .rd-dp__nav:hover,
.rd-dp .rd-dp__dialog .rd-dp__clear:hover,
.rd-dp .rd-dp__dialog .rd-dp__close:hover {
    background: var(--surface-2);
}

/* PK5 (A06): the group headings of the admin navigation carry a light
   tinted background from the existing tokens, so the groups read as
   sections. Admin sidebar only; the account sidebar stays as it is. Light
   and dark come from the token pairs. */
.b7-side--admin .b7-side-nav .b7-side-group {
    margin: var(--space-3) 0 .35rem;
    padding: .35rem .7rem;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    color: var(--foreground);
}

.b7-side--admin .b7-side-nav .b7-side-group:first-child {
    margin-top: 0;
}

/* PK5 (A36): the admin only staging protection warning above the page.
   Warning tokens, light and dark from the token pairs; it wraps on narrow
   screens and never covers the header. */
.admin-staging-warning {
    margin: 0;
    padding: .55rem 1rem;
    border-bottom: 1px solid var(--warning);
    background: var(--warning-soft);
    color: var(--foreground);
    font-size: .875rem;
    line-height: 1.45;
    text-align: center;
}

.admin-staging-warning a {
    color: var(--foreground);
    font-weight: var(--font-weight-medium);
    text-decoration: underline;
}

.admin-staging-warning a:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

/* PK5 (A21f): severity label of a current finding. The text names the
   severity; the tint only repeats it. Tokens only, light and dark. */
.admin-severity {
    display: inline-block;
    padding: .1rem .5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--foreground);
    font-size: .8rem;
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
}

.admin-severity--critical {
    border-color: var(--danger);
    background: var(--danger-soft);
}

.admin-severity--warning,
.admin-severity--unverifiable {
    border-color: var(--warning);
    background: var(--warning-soft);
}

.admin-severity--info {
    border-color: color-mix(in srgb, var(--accent) 40%, transparent);
    background: var(--accent-soft);
}

.admin-severity--ok {
    border-color: color-mix(in srgb, var(--positive) 40%, transparent);
    background: var(--positive-soft);
}

/* Like every wide admin table it scrolls inside the main area on small
   screens instead of breaking codes character by character. */
.admin-findings {
    min-width: 46rem;
}

.admin-findings code {
    white-space: nowrap;
}

.admin-findings .admin-findings__label,
.admin-findings .admin-findings__hint {
    min-width: 14rem;
}

/* PK5 (A08): bullet help below an admin form field. */
.admin-field-help {
    margin: .25rem 0 .75rem;
    padding-left: 1.2rem;
    color: var(--muted);
    font-size: .85rem;
    line-height: 1.45;
}

.admin-field-help li + li {
    margin-top: .15rem;
}

/* PK7 (A52): the group headings inside the ranking contexts of a card page,
   All-time and each running calendar period, above the unchanged B-7
   context boxes (.card-ctx). The info tip of a period group names its
   period and UTC span. */
.ranking-page .ranking-contexts .ranking-contexts-group {
    display: flex;
    align-items: flex-start;
    gap: 0;
    margin: var(--space-4) 0 var(--space-2);
    color: var(--muted);
    font-size: .8rem;
    font-weight: var(--font-weight-heading);
}

.ranking-page .ranking-contexts h2 + .ranking-contexts-group {
    margin-top: 0;
}

/* UI-05 (operator decision 2026-10-21): the period tabs (the B-7 period
   switch, .range-segs, as plain links) under the heading, the all-time
   group under them and the one period area below it, which holds the
   chosen period's group or a neutral note (loading, no place, not
   available, not readable, not loaded with a retry). */
.ranking-page .ranking-contexts .ranking-contexts-tabs {
    margin: 0 0 var(--space-3);
}

/* Order 2026-10-29, point 13: the number of places of a period tab right of
   its name, lighter and in the regular weight also on the current tab. */
.ranking-page .ranking-contexts .ranking-contexts-tab-count {
    color: var(--text-faint);
    font-weight: 400;
}

/* NK07 (operator list 2026-10-23): the tabs take the look of the profile
   tabs and only one group stands below them, so the first heading or note
   of the visible group starts right under the tab line. */
.ranking-page .ranking-contexts :is(h2, .ranking-contexts-tabs) + .ranking-contexts-all-time > .ranking-contexts-group,
.ranking-page .ranking-contexts .ranking-contexts-period > .ranking-contexts-note:first-child,
.ranking-page .ranking-contexts .ranking-contexts-period > .ranking-contexts-period-group > :is(.ranking-contexts-group, .ranking-contexts-note):first-child {
    margin-top: 0;
}

.ranking-page .ranking-contexts .ranking-contexts-note {
    margin: var(--space-4) 0 0;
    color: var(--muted);
    font-size: .89rem;
}

.ranking-page .ranking-contexts .ranking-contexts-note .ranking-contexts-retry {
    margin-left: .35rem;
}

/* SH-01 to SH-16 (operator decisions 2026-10-14): the share panel of the
   ranking card detail pages, its image preview, the owner context list and
   statistics, the one owner URL field, the profile link actions and the
   saved items. Only existing tokens and no new media query. The parts of
   the owner pages that are .rd only, and their hover rules, close the
   redesign block below. */

/* The infobox of the share panels: what the share image and the message
   carry. The first line is the heading, the second the current rank line. */
.ranking-page .share-info,
.rd .rd-card .share-info {
    display: grid;
    gap: .15rem;
    margin: 0;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.ranking-page .share-info .share-info__head,
.rd .rd-card .share-info .share-info__head {
    margin: 0;
    color: var(--foreground);
    font-size: .89rem;
    font-weight: var(--font-weight-heading);
}

.ranking-page .share-info .share-info__line,
.rd .rd-card .share-info .share-info__line {
    margin: 0;
    color: var(--muted);
    font-size: .89rem;
}

.ranking-page .share-box .share-form,
.rd .rd-card .share-box .share-form {
    display: grid;
    gap: .55rem;
    min-width: 0;
    margin: 0;
}

/* The long context choice: label above, the field over the whole width. The
   native select is the field without the script; with it the existing
   select combobox (.rd-sel-btn and the option list of the filter panel)
   takes its place. */
.ranking-page .share-box .share-context {
    display: grid;
    gap: .35rem;
    min-width: 0;
}

.ranking-page .share-box .share-context > label {
    color: var(--foreground);
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
}

.ranking-page .share-box .fsel > select:not(.rd-sel-native) {
    width: 100%;
    min-width: 0;
    min-height: 2.2rem;
    margin: 0;
    padding: 0 2.25rem 0 .7rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .86rem;
    text-overflow: ellipsis;
    -webkit-appearance: none;
    appearance: none;
}

/* The context field of the public share panel uses the select combobox of
   the owner pages (.rd-sel-btn opening the option list .b7-fpanel of the
   filter panel) in the same look; these rules are the share box copies of
   the .rd .fsel rules of the redesign block, which stays .rd only. As on
   every field, the neutral edge and the inset surface mark the focus (forced
   colours: the system highlight, in the forced colours rule). */
.ranking-page .share-box .fsel {
    position: relative;
    display: flex;
    width: 100%;
    max-width: 100%;
    min-width: 0;
}

/* A45 (Q45.7): without the script the native select shows the stacked
   chevron pair of the rankings filter as a static drawing over the whole
   field (the gradient technique of the admin selects); a native select has
   no open state to show, and its option list stays the browser's own. */
.ranking-page .share-box .fsel::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(135deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(135deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%);
    background-position: calc(100% - 1.05rem) calc(50% - 4px), calc(100% - .75rem) calc(50% - 4px), calc(100% - 1.05rem) calc(50% + 4px), calc(100% - .75rem) calc(50% + 4px);
    background-repeat: no-repeat;
    background-size: 5px 5px;
    pointer-events: none;
}

/* A45 (Q45.7, UIR-6): the keyboard focus draws the pair in the text colour,
   as on the redesigned pages (.rd .fsel:focus-within::after). */
.ranking-page .share-box .fsel:focus-within::after {
    background-image:
        linear-gradient(135deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%),
        linear-gradient(135deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%);
}

.ranking-page .share-box .fsel > .rd-sel-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .45rem;
    width: 100%;
    min-width: 0;
    min-height: 2.2rem;
    margin: 0;
    padding: 0 .7rem;
    overflow: hidden;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background-color: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .86rem;
    font-weight: 400;
    text-align: left;
    cursor: pointer;
}

.ranking-page .share-box .rd-sel-btn__text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ranking-page .share-box .fsel > .rd-sel-btn:hover,
.ranking-page .share-box .fsel > .rd-sel-btn:focus-visible,
.ranking-page .share-box .fsel > .rd-sel-btn[aria-expanded="true"] {
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.ranking-page .share-box .fsel > .rd-sel-btn:focus-visible {
    outline: none;
}

/* A45: with the button the field shows the stacked chevron pair of the
   rankings filter (built by the script, with its open state) instead of the
   static pair of the native select. */
.ranking-page .share-box .fsel:has(> .rd-sel-btn)::after {
    content: none;
}

.ranking-page .share-box .fsel > .rd-sel-btn .filter-chev-up {
    opacity: .55;
}

.ranking-page .share-box .fsel > .rd-sel-btn[aria-expanded="true"] .b7-fsw-chev {
    color: currentColor;
}

.ranking-page .share-box .fsel > .rd-sel-btn[aria-expanded="true"] .filter-chev-up {
    opacity: 1;
}

.ranking-page .share-box .fsel > .rd-sel-btn[aria-expanded="true"] .filter-chev-down {
    opacity: .3;
}

.ranking-page .share-box .fsel > select.rd-sel-native {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 1px;
    height: 1px;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    opacity: 0;
    pointer-events: none;
}

.share-dialog .share-dialog__x:hover {
    border-color: var(--muted);
    color: var(--foreground);
}

/* Elements that only make sense without the script. */
.js .ranking-page .share-box .share-actions > .share-nojs,
.js .rd .rd-card .share-box .share-actions > .share-nojs,
.js .ranking-page .share-box .share-form > .share-nojs {
    display: none;
}

.ranking-page .share-box .share-note,
.rd .rd-card .share-box .share-note {
    margin: 0;
    color: var(--muted);
    font-size: .84rem;
}

.ranking-page .share-box .share-note:empty,
.rd .rd-card .share-box .share-note:empty {
    display: none;
}

.ranking-page .share-box input,
.profile-page .share-box input {
    min-width: 0;
}

/* The share image preview (B-7 .modal with .b4-modalhead and .b4-close),
   wider than the B-7 36rem so the 1734x907 image stays readable; the image
   keeps its ratio and is never cropped. */
.share-dialog {
    width: min(56rem, calc(100vw - 2rem));
    max-width: none;
    max-height: calc(100vh - 2rem);
    margin: auto;
    padding: var(--space-5);
    overflow: auto;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface);
    color: var(--foreground);
    box-shadow: var(--shadow-overlay);
}

.share-dialog::backdrop {
    background: rgba(9, 14, 24, .45);
}

.share-dialog .share-dialog__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .6rem;
    margin: 0 0 var(--space-4);
}

.share-dialog .share-dialog__head h2 {
    margin: 0;
    font-size: 1.04rem;
    line-height: 1.58;
}

.share-dialog .share-dialog__x {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: calc(1.04rem * 1.58);
    height: calc(1.04rem * 1.58);
    padding: 0;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
}

/* The visible box is one heading line high; its hit area grows by 10px up,
   right and down (to about 44px high), never over the heading. */
.share-dialog .share-dialog__x::after {
    content: "";
    position: absolute;
    inset: -10px -10px -10px 0;
}

.share-dialog .share-dialog__x svg {
    width: 58%;
    height: 58%;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
}

.share-dialog .share-dialog__x:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

/* UI19 (operator order 2026-10-24): the closing button of the two share
   image dialogs carries a long and a short label; one of them is shown
   (Close on a phone, see NK-PHONE), the other is not rendered. */
.share-dialog .share-dialog__close-narrow {
    display: none;
}

.share-dialog .share-dialog__frame {
    display: grid;
    place-items: center;
    min-height: 6rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.share-dialog .share-dialog__img {
    display: block;
    width: 100%;
    max-width: 100%;
    height: auto;
    object-fit: contain;
}

.share-dialog .share-dialog__img[hidden] {
    display: none;
}

.share-dialog .share-dialog__state {
    margin: 0;
    padding: var(--space-4);
    color: var(--muted);
    font-size: .89rem;
    text-align: center;
}

.share-dialog .share-dialog__state:empty {
    display: none;
}

.share-dialog .share-dialog__foot {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .55rem;
    margin: var(--space-4) 0 0;
}

/* A58: the X prompt in the share dialog language, with the B-7 .modal
   width (36rem) and the B-7 .b7-followhead lead (2.05rem mark, about
   1.7rem on very narrow screens, here fluid instead of a further media
   query). The mark is the unchanged A44 partial. */
.share-dialog.x-prompt {
    width: min(36rem, calc(100vw - 2rem));
}

.x-prompt .x-prompt__lead {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    min-width: 0;
}

.x-prompt .x-prompt__mark {
    display: inline-flex;
    flex: none;
    width: clamp(1.7rem, 8.5vw, 2.05rem);
    height: clamp(1.7rem, 8.5vw, 2.05rem);
    color: var(--foreground);
}

.x-prompt .x-prompt__mark svg {
    width: 100%;
    height: 100%;
}

.x-prompt .x-prompt__lead h2 {
    margin: 0 0 .15rem;
}

.x-prompt .x-prompt__body {
    margin: 0;
    white-space: pre-line;
}

/* Q21.1 / A21a: the failed save of "Don't show again" is a warning (the
   dialog stays usable): the B-7 warning box. */
.x-prompt .x-prompt__error {
    margin: 0;
    padding: .85rem 1rem;
    border: 1px solid color-mix(in srgb, var(--warning) 30%, transparent);
    border-radius: var(--radius-md);
    background: var(--warning-soft);
    color: var(--foreground);
    font-size: .89rem;
}

.x-prompt .x-prompt__error[hidden] {
    display: none;
}

/* UI-01 (operator decision 2026-10-21): no focus ring inside the X prompt.
   It opens with the focus on its heading (a static target, tabindex -1),
   which shows nothing; a keyboard focus on a control is shown without a
   ring: Close turns into the inverted foreground tile, the follow link and
   "Don't show again" underline their text (the light button also takes the
   inset surface). Only this dialog; with forced colours a system outline
   stays, since fills and text decoration may not be shown there. */
.share-dialog.x-prompt #x-prompt-title:focus {
    outline: none;
}

.share-dialog.x-prompt :is(a, button):focus-visible {
    outline: none;
}

.share-dialog.x-prompt .share-dialog__x:focus-visible {
    border-color: var(--foreground);
    background: var(--foreground);
    color: var(--surface);
}

.share-dialog.x-prompt .share-dialog__foot .btn:focus-visible {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: .2em;
}

.share-dialog.x-prompt .share-dialog__foot .btn:not(.btn--primary):focus-visible {
    background-color: var(--surface-2);
}

@media (forced-colors: active) {
    .share-dialog.x-prompt :is(a, button):focus-visible {
        outline: 2px solid CanvasText;
        outline-offset: 2px;
    }
}

.x-prompt-admin__body {
    white-space: pre-line;
}

/* ==========================================================================
   Package A (operator decisions 2026-10-16): platform statistics window and
   page, rankings quick filters and controls, B-7 latest activity
   (.b4-feed--ranked) and most active platforms (.b4-active). Every rule is
   namespaced to its new element; colours come from the existing tokens.
   ========================================================================== */

/* The icon box of the statistics window title: the same box as the icon of
   the login window title. */
.stats-pop .stats-pop-icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
}

/* Statistics window: the surface, size and motion of the B-7 menu panel
   (like the login window), the head row of the B-7 notification panel and
   its closing quiet link. Hidden by its attribute until the script runs. */
.js .stats-pop {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 1;
    width: min(23rem, calc(100vw - 2rem));
    /* A25: at most the height that is really visible (dynamic viewport,
       100vh where dvh is unknown) below the header and above the bottom
       safe area; the content scrolls inside, so "View all statistics"
       always stays reachable. */
    max-height: calc(100vh - var(--header-height) - 1.5rem - env(safe-area-inset-bottom, 0px));
    max-height: calc(100dvh - var(--header-height) - 1.5rem - env(safe-area-inset-bottom, 0px));
    overscroll-behavior: contain;
    margin-top: .5rem;
    padding: .5rem;
    overflow-y: auto;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px) scale(.985);
    pointer-events: none;
}

/* A25: the head and "View all statistics" keep their place; only the
   figures between them scroll when the window is lower than its content. */
.js .stats-pop:not([hidden]) {
    display: flex;
    flex-direction: column;
}

.js .stats-pop > * {
    flex: none;
}

.js .stats-pop > .stats-pop-body {
    flex: 0 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.js .stats-pop.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.js .stats-pop.is-ready {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base);
}

.js .stats-pop.is-ready.is-open {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s;
}

.stats-pop-title {
    display: flex;
    align-items: center;
    gap: .65rem;
    margin: 0;
    padding: .35rem .5rem .6rem;
    font-size: .9rem;
    font-weight: var(--font-weight-heading);
    line-height: 1.3;
}

.stats-pop-title:focus {
    outline: none;
}

.stats-pop-title:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
    border-radius: var(--radius-sm);
}

.stats-pop-body {
    min-height: 2.75rem;
}

.stats-pop-body[aria-busy="true"] .stats-panel {
    opacity: .6;
}

.stats-pop-state {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .5rem .6rem;
    color: var(--muted);
    font-size: .86rem;
}

.stats-pop-state p {
    margin: 0;
}

.stats-pop-state--error {
    margin-bottom: .35rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--foreground);
}

.stats-pop .menu-sep {
    display: block;
    height: 1px;
    margin: .45rem .3rem;
    background: var(--border);
}

.stats-pop-more {
    margin: 0;
    padding: .2rem .5rem .4rem;
}

/* A42 (Q42.4): "View all statistics" is a forward link like "See all
   rankings in this platform" (.platforms-cta-link with its arrow, B-7
   .nav-quiet): look, hover and the still arrow under reduced motion come
   from there; this rule keeps only the touch height of the window. */
.stats-pop-link {
    min-height: 2.75rem;
}

/* NK32 (operator list 2026-10-23): "View all statistics" has no descender,
   so the 2px drop of the shared arrow made it sit too low; in the window it
   is lifted back to the centre of the text. The independent translate keeps
   the hover move and its reduced motion rule of the shared arrow. */
.stats-pop-link .platforms-cta-arrow {
    translate: 0 -2px;
}

/* The statistics panel: the group heads of the filter windows
   (.b7-fgroup-label), light separators between the figures, the value on
   the right in the tabular figure face. */
.stats-panel {
    display: block;
}

/* A22: more room above a group head to its divider, and the figure names
   slightly indented against the group heads (page and header window). */
/* UI11 (operator order 2026-10-24): no group heading of the statistics page
   or window carries a top line any more (UI11.1 to UI11.3); the rows carry
   the dividers instead (below). A heading that follows a group keeps some
   room above it, so it stands apart from the rows before it (UI11.6). */
.stats-group-label {
    margin: .3rem 0 0;
    padding: .8rem .6rem .3rem;
    color: var(--text-faint);
    font-size: .69rem;
    font-weight: 400;
    letter-spacing: .1em;
    line-height: 1.4;
    text-transform: uppercase;
}

.stats-group:first-child .stats-group-label {
    margin-top: 0;
}

.stats-group + .stats-group .stats-group-label {
    margin-top: var(--space-3);
}

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

.stats-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .25rem .75rem;
    min-height: 2.5rem;
    /* Order 2026-10-29, point 8: the figures sit 1.6rem in (was .95rem)
       against the .6rem of their group heads, on the statistics page and in
       the statistics window alike. The card statistics box sets its own
       inline padding. */
    padding: .5rem .6rem .5rem 1.6rem;
}

/* UI11.4/UI11.5 gave every row of the statistics panel a line below it.
   Order 2026-10-29, point 7: the rows of the statistics page and of the
   statistics window have no line any more. The card statistics box keeps
   its lines between the rows. */
.card-detail-stats .stats-row + .stats-row {
    border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

.stats-name {
    min-width: 0;
    color: var(--muted);
    font-size: .88rem;
}

.stats-value {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: .92rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
}

.stats-value--muted {
    color: var(--text-faint);
    font-family: inherit;
    font-size: .82rem;
    font-weight: 400;
}

/* C-1 (U05.04): the card link of the largest recorded increase, a quiet
   text link after the value in the body face. */
.stats-value-link {
    color: var(--accent-text);
    font-family: var(--font-family-base);
    font-size: .8rem;
    font-weight: 400;
    text-decoration: none;
    white-space: nowrap;
}

.stats-value-link:hover {
    text-decoration: underline;
}

/* A22: the panel takes the content width of the page (52rem at most, the
   smaller real width below) and has no extra space above it. */
.statistics-page .stats-panel {
    padding: .5rem;
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
}

.statistics-page .stats-group-label {
    font-size: .74rem;
}

/* Order 2026-10-29, point 9: on the public statistics page only (not in the
   statistics window, not on the admin statistics page) the Profiles head has
   no space above it at any width. Point 10 sets its padding from 761px. */
.statistics-page--public .stats-panel > [aria-labelledby="stats-group-profiles"] .stats-group-label {
    margin-top: 0;
}


/* Info bubbles of the rankings titles and the statistics panel open below
   the icon, their top left corner at the icon (operator decision T03); the
   script still keeps them inside the viewport. A shown bubble lifts its own
   icon above the neighbouring icons, locally only. */
.ranking-intro .b7-info .b7-info__bub,
.stats-panel .b7-info .b7-info__bub {
    top: calc(100% + .45rem);
    bottom: auto;
    left: 0;
    transform: translateY(-4px);
}

.ranking-intro .b7-info:hover .b7-info__bub,
.ranking-intro .b7-info:focus-visible .b7-info__bub,
.ranking-intro .b7-info[aria-expanded="true"] .b7-info__bub,
.stats-panel .b7-info:hover .b7-info__bub,
.stats-panel .b7-info:focus-visible .b7-info__bub,
.stats-panel .b7-info[aria-expanded="true"] .b7-info__bub {
    transform: none;
}

.ranking-intro .b7-info.b7-info--below .b7-info__bub,
.stats-panel .b7-info.b7-info--below .b7-info__bub {
    transform: translateY(-4px);
}

.ranking-intro .b7-info.b7-info--below:is(:hover, :focus-visible, [aria-expanded="true"]) .b7-info__bub,
.stats-panel .b7-info.b7-info--below:is(:hover, :focus-visible, [aria-expanded="true"]) .b7-info__bub {
    transform: none;
}

.ranking-intro .b7-info:is(:hover, :focus-visible, [aria-expanded="true"]),
.stats-panel .b7-info:is(:hover, :focus-visible, [aria-expanded="true"]) {
    z-index: 8;
}

/* The clipping title box spans the head up to the share button, so a shown
   bubble opens at its icon instead of being pushed back into the width of
   the title text (T03). */
.ranking-page .ranking-head > .ranking-intro {
    flex: 1 1 auto;
}

/* The bubble opens towards the right of its icon, so a closed bubble must
   not widen the page: the title row and the statistics panel clip
   horizontally (never vertically), and the script keeps a shown bubble
   inside them. U-02 (Bestandsaudit 2026-10, P2): the same for the closed
   bubbles of the statistics list heads and of the saved state of the
   account pages, which widened narrow pages in Firefox; only while the
   script runs, which keeps a shown bubble inside these boxes (without it
   a shown bubble keeps its former place and is never cut). */
.ranking-page .ranking-intro,
.statistics-page .stats-panel > .stats-group,
.js .statistics-page .stats-lists,
.js .rd .rd-saved,
.js .rd .rd-saves__head {
    overflow-x: clip;
}

/* B-01 / U-02 without the script (audit remainder 2026-10-28): in the same
   two boxes a closed bubble takes no room, so it cannot widen the page in
   Firefox; hover and keyboard focus show it at its former place. Only the
   fade out ends at once. The fade in starts from the closed look; with
   reduced motion the existing rule takes the transition away, so a start
   style moves nothing there. The script keeps the clip above instead. */
html:not(.js) :is(.statistics-page .stats-lists, .rd .rd-saved, .rd .rd-saves__head) .b7-info__bub {
    display: none;
}

html:not(.js) :is(.statistics-page .stats-lists, .rd .rd-saved, .rd .rd-saves__head) .b7-info:is(:hover, :focus-visible) .b7-info__bub {
    display: block;
}

@starting-style {
    html:not(.js) :is(.statistics-page .stats-lists, .rd .rd-saved, .rd .rd-saves__head) .b7-info:is(:hover, :focus-visible) .b7-info__bub {
        opacity: 0;
        transform: translateX(-50%) translateY(4px);
    }
}

/* K-08 (R-01/A-04, operator approval 2026-10-28): on the wide card page,
   where the screen is at most 47 times the browser's default font size wide
   (an enlarged default font size; never with 16px or 20px, where 47em is
   below 981px), the centred closed bubbles of the card statistics reach past
   the page edge. There the box clips horizontally
   while the script runs (as U-02), which keeps a shown bubble inside it;
   without the script a closed bubble takes no room (as B-01) and hover and
   keyboard focus show it at its former place. */
@media (min-width: 981px) and (max-width: 47em) {
    .js .ranking-page .card-detail-stats {
        overflow-x: clip;
    }

    html:not(.js) .ranking-page .card-detail-stats .b7-info__bub {
        display: none;
    }

    html:not(.js) .ranking-page .card-detail-stats .b7-info:is(:hover, :focus-visible) .b7-info__bub {
        display: block;
    }

    @starting-style {
        html:not(.js) .ranking-page .card-detail-stats .b7-info:is(:hover, :focus-visible) .b7-info__bub {
            opacity: 0;
            transform: translateX(-50%) translateY(4px);
        }
    }
}

/* Q12.2 / A12 (UIR-9): the reset of the colour of the card name link and of
   the shadow of the claim list sits here, after their own rules of equal
   weight, so it wins. */
@media (prefers-reduced-motion: reduce) {
    .js .stats-pop.is-ready,
    .js .stats-pop.is-ready.is-open,
    .rankshell a.rc-ident-uname,
    .rankshell a.rc-ident-handle,
    .rd main .rd-claim-list > .rd-rows {
        transition: none;
    }
}

/* T11: the page keeps its width when a vertical scrollbar appears (classic
   scrollbars take the gutter from the start; overlay scrollbars take none).
   No script compensates a scrollbar anywhere, so nothing is doubled. */
html {
    scrollbar-gutter: stable;
}

/* T06/T10: the control row of the rankings and leaderboards pages has no
   outer space of its own; the grid gap of .ranking-page spaces it. */
.ranking-page .ranking-controls {
    margin: 0;
}

/* T07, A16, A20a, rebuilt by UI08 (operator order 2026-10-24): the control
   row of the rankings page is one wrapping flex row of three parts: the
   period switch (its segments scroll sideways where the row is too narrow),
   the metadata group .ranking-meta (the countdown of a running period and
   the result count) and the summary with the chips of the chosen filters
   and their reset. Each part moves to the next line as a whole when it does
   not fit beside the parts before it, so the countdown and the count always
   wrap together; on one line every part is centred to the switch. The
   group grows into the rest of its line (the countdown at its start, the
   count at its end) and never gets wider than the line; only where the
   group alone is wider than a line do the count and then the countdown
   wrap inside it. */
.ranking-page .ranking-controls:has(.range-switch) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-2) var(--space-3);
}

.ranking-page .ranking-controls .range-switch {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
}

/* Order 2026-10-29, point 6: the switch takes the full width in exactly the
   moment the metadata group (countdown and count) wraps below it, at every
   width and orientation and for every countdown length. Both may grow; on a
   shared line the metadata group takes nearly all free room (as before), so
   the switch keeps its own width; alone on its line the switch takes the
   whole line, and its segments share it.
   A04 (order 2026-11-01): this applies to the rankings list only. The
   leaderboards (main.ranking-archive) have a switch without a metadata group
   beside it, so the rule made their switch always full width; there the
   switch keeps the compact width of its segments. */
.ranking-page:not(.ranking-archive) .ranking-controls:has(.range-switch) .range-switch {
    flex-grow: 1;
}

.ranking-page:not(.ranking-archive) .ranking-controls:has(.range-switch) .range-segs {
    display: flex;
    width: 100%;
}

.ranking-page:not(.ranking-archive) .ranking-controls:has(.range-switch) .range-segs > a {
    flex: 1 1 auto;
    justify-content: center;
}

.ranking-page .ranking-meta {
    display: flex;
    flex: 10000 1 auto;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem var(--space-3);
    min-width: 0;
    max-width: 100%;
}

.ranking-page .ranking-meta > .ranking-reset {
    min-width: 0;
    margin: 0;
    line-height: 1.85rem;
}

.ranking-page .ranking-meta > .ranking-results {
    margin-left: auto;
    line-height: 1.85rem;
    white-space: nowrap;
}

.ranking-page .ranking-controls:has(.range-switch) .ranking-summary {
    flex: 0 1 auto;
    justify-content: flex-end;
    min-width: 0;
    max-width: 100%;
    margin-left: auto;
}

/* UI08: the chips and the reset wrap inside their own group, right aligned
   beside or below the metadata group. */
.ranking-page .ranking-controls:has(.range-switch) .ranking-summary .ranking-facets {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem;
    min-width: 0;
    max-width: 100%;
}

/* A08 (order 2026-11-01): once the chips and the reset wrap onto a line of
   their own (marked .is-own-line by public/js/app.js, measured on the
   unmarked row), they are centred and the gap above them is var(--space-3):
   the row gap of this flex row is var(--space-2), so the margin adds the
   difference. The auto margins centre the group without a flex basis of its
   own, so the mark never decides where the group wraps. Without the script
   the group keeps its former place. */
.ranking-page .ranking-controls:has(.range-switch) .ranking-summary.is-own-line {
    justify-content: center;
    margin-top: calc(var(--space-3) - var(--space-2));
    margin-right: auto;
    margin-left: auto;
}

.ranking-page .ranking-controls:has(.range-switch) .ranking-summary.is-own-line .ranking-facets {
    justify-content: center;
}

/* UI08: without chosen filters the summary holds nothing and takes no
   place (no gap, no empty line). */
.ranking-page .ranking-controls:has(.range-switch) .ranking-summary:not(:has(.ranking-facets)) {
    display: none;
}

.ranking-page .ranking-summary .ranking-results {
    white-space: nowrap;
}

.ranking-page .ranking-summary .chip--facet {
    min-width: 0;
    max-width: 100%;
}

.ranking-page .ranking-summary .chip--facet .chip-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ranking-page .range-switch .range-segs {
    max-width: 100%;
}

/* The segment row scrolls inside the switch; the soft fades of the filter
   bar show on a side with more segments. A07 (order 2026-11-01): the fades
   are gone from the rankings list switch; only the leaderboards switch
   (main.ranking-archive) keeps them, unchanged. */
.ranking-archive .range-switch .range-segs.is-scrollable {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 1.25rem, #000 calc(100% - 1.25rem), transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 1.25rem, #000 calc(100% - 1.25rem), transparent 100%);
}

.ranking-archive .range-switch .range-segs.is-scrollable.is-at-start {
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 1.25rem), transparent 100%);
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 1.25rem), transparent 100%);
}

.ranking-archive .range-switch .range-segs.is-scrollable.is-at-end {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 1.25rem, #000 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 1.25rem, #000 100%);
}

.ranking-archive .range-switch .range-segs.is-scrollable.is-at-start.is-at-end {
    -webkit-mask-image: none;
    mask-image: none;
}

@media (max-width: 760px) {
    /* A45: the share panel's context field keeps the height of the rankings
       filter field: 2.2rem from 761px (its base rule), 2.75rem below. */
    .ranking-page .share-box .fsel > select:not(.rd-sel-native),
    .ranking-page .share-box .fsel > .rd-sel-btn {
        min-height: 2.75rem;
    }

    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary .ranking-reset {
        max-width: 100%;
    }

    /* A48: the value zone of a list card on a narrow screen. The Free or
       Sponsored label on the left, the value label and the amount on the
       right, then --space-3 (with the row gap) to the two actions. Each
       action is 2.75rem high, which is also its touch target, with .5rem
       between them; the texts, links and amounts stay. */
    .rankshell .bid {
        grid-template-columns: auto minmax(0, 1fr);
        grid-template-areas: "origin vlabel" "origin amount" "actions actions";
    }

    /* A50 (Q50.4/Q50.5): without actions the zone keeps only its two rows:
       the Free or Sponsored label beside the value label and the amount,
       which stand centred on it. */
    .rankshell .bid--archive {
        grid-template-areas: "origin vlabel" "origin amount";
    }

    .rankshell .bid > .rankshell-labels {
        grid-area: origin;
        align-self: center;
        margin: 0;
    }

    .rankshell .bid > .bid-label,
    .rankshell .bid > .bid-amount {
        justify-self: end;
        min-width: 0;
        text-align: right;
    }

    .rankshell .bid > .bid-label {
        grid-area: vlabel;
    }

    .rankshell .bid > .bid-amount {
        grid-area: amount;
    }

    .rankshell .bid > .bid-note--pair {
        grid-area: actions;
        margin-top: calc(var(--space-3) - .2rem);
    }

    .rankshell .bid-note--pair .btn {
        min-height: 2.75rem;
    }
}

/* A20c/d: a narrow portrait screen. Landscape keeps the row above.
   U59 (operator list 2026-10-21, the layout the operator preferred; it
   replaces c "summary above the switch" and keeps d as its general form):
   the switch first, over the full width, its segments sharing the row so
   none is hidden at the end; below it the countdown of a running period on
   the left and the count on the right in one row (without a countdown the
   count alone on the right); the chips and the reset centred in the row
   below. The rows keep one equal gap; countdown and count share one line
   height. UI08 (operator order 2026-10-24): the countdown and the count
   form the metadata group of the flex row above, so no grid is needed. */
@media (max-width: 760px) and (orientation: portrait) {
    /* UI08: the same flex row; the switch, the metadata group and the
       chips each take a line of their own. Point 6 (2026-10-29): the
       metadata group and the chips take a line each; so the switch stands
       alone and takes the full width through the rule above. */
    .ranking-page .ranking-controls:has(.range-switch) {
        gap: var(--space-3);
    }

    /* A08: the row gap is already var(--space-3) here. */
    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary.is-own-line {
        margin-top: 0;
    }

    .ranking-page .ranking-controls:has(.range-switch) .ranking-meta,
    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary {
        flex-basis: 100%;
    }

    .ranking-page .ranking-controls:has(.range-switch) .range-segs > a {
        padding-right: .4rem;
        padding-left: .4rem;
    }

    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary,
    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary .ranking-facets {
        justify-content: center;
    }

    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary {
        margin-left: 0;
    }
}

/* T05: the last separator of a page (TOP 40, 60 …) sits close to the page
   row below it; the other separators keep their space. */
.ranking-page .ranking-list > .ranking-sep:last-child {
    margin-bottom: 0;
}

.ranking-page .ranking-list:has(> .ranking-sep:last-child) + .ranking-pages {
    margin-top: var(--space-2);
}

/* R01/R02: the submit fallback. It reads "Apply" on small screens, its name
   stays "Apply filters"; the script hides it only while the automatic
   update is bound (is-auto-apply). */
@media (max-width: 760px) {
    .ranking-page .filter-apply-suffix {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }
}

.ranking-page .listing-filters.is-auto-apply .filter-apply {
    display: none;
}

/* R07: a filter field never grows wider than the visible row; a long chosen
   label shortens inside its button instead of covering its neighbour. */
.ranking-page .filter-field .b7-fsw-btn {
    max-width: 100%;
}

.ranking-page .filter-field .b7-fsw-txt {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (max-width: 760px) {
    .ranking-page .filter-bar.is-scrollable .filter-field {
        max-width: min(100%, 15rem);
    }
}

/* R03/R04: the quick filters primary button, only wider than 768px (A15) and
   only once the script has shown it; its window is the B-7 menu panel. The
   button keeps the gradient of .btn--primary: the old filter rule above sets
   its flat colour only on the buttons that are no .btn. */
.ranking-page .quick-filters {
    position: relative;
    flex: none;
}

.ranking-page .quick-filters-btn {
    display: none;
    min-height: 2.35rem;
    white-space: nowrap;
}

@media (min-width: 769px) {
    .ranking-page .quick-filters-btn:not([hidden]) {
        display: inline-flex;
    }
}

.ranking-page .quick-filters-panel {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 30;
    width: min(18rem, calc(100vw - 2rem));
    margin-top: .5rem;
    padding: .5rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px) scale(.985);
    pointer-events: none;
}

.ranking-page .quick-filters-panel.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.ranking-page .quick-filters-panel.is-ready {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear var(--motion-base);
}

.ranking-page .quick-filters-panel.is-ready.is-open {
    transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease), visibility 0s linear 0s;
}

@media (max-width: 768px) {
    .ranking-page .quick-filters {
        display: none;
    }
}

.ranking-page .quick-filters-title {
    margin: 0;
    padding: .55rem .6rem .3rem;
    color: var(--text-faint);
    font-size: .69rem;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.ranking-page .quick-filters-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* UI07 (operator order 2026-10-24): the entries sit indented .35rem
   against the title, as the options under a group title of the filter
   panels and the targets of the share menu; the title stays where it is. */
.ranking-page .quick-filters-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    min-height: 2.75rem;
    /* Order 2026-10-29, point 8: 1.6rem in (was .95rem). */
    padding: .48rem .6rem .48rem 1.6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--foreground);
    font-size: .9rem;
    text-decoration: none;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.ranking-page a.quick-filters-link:hover {
    background-color: var(--surface-2);
    border-color: var(--border);
}

.ranking-page a.quick-filters-link[aria-current="true"] {
    border-color: var(--accent-border);
    background-color: var(--accent-soft);
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

.ranking-page .quick-filters-link--unavailable {
    color: var(--text-faint);
    cursor: default;
}

.ranking-page .quick-filters-state {
    font-size: .74rem;
}

/* Horizontal box rows (latest activity, most active platforms): equal
   columns over the full width where they fit, sideways scrolling without a
   visible scrollbar where they do not, the next box partly visible, and the
   soft fades of the filter bar only towards a side with more boxes. */
.hscroll {
    position: relative;
    min-width: 0;
}

.hscroll-track {
    /* The containing block of every visually hidden text inside, so nothing
       absolutely positioned escapes the sideways scroll into the page.
       A28: a sideways scroll also clips vertically at its padding edge, so
       the row keeps room for the box shadow and its hover (the stronger
       shadow reaches furthest below) and for the focus ring; the same
       negative margin keeps the boxes, the widths and the scroll geometry
       where they were.
       U80 (operator list 2026-10-21): the cause of the cut shadow ends was
       this clip (overflow-x: auto makes the row a scroll container that clips
       on both axes) with a padding smaller than the card hover shadow
       (0 8px 20px: 20px to the sides, 28px below). The room now follows the
       shadow: 28px below, and to the sides 1rem, the page gutter of a narrow
       screen, so the row never widens the page; the last 4px of the blur
       there carry well under one percent of opacity. */
    position: relative;
    margin: -.75rem -1rem -1.75rem;
    padding: .75rem 1rem 1.75rem;
    overflow-x: auto;
    list-style: none;
    scroll-snap-type: x proximity;
    scroll-padding-inline: 1rem;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.hscroll-track::-webkit-scrollbar {
    display: none;
    height: 0;
}

.hscroll-track > * {
    scroll-snap-align: start;
    min-width: 0;
}

.hscroll-fade {
    position: absolute;
    top: 0;
    bottom: 0;
    /* A28/U80: from the outer edge of the row, which reaches 1rem beyond. */
    width: 3rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--motion-base) var(--motion-ease);
}

.hscroll-fade.is-on {
    opacity: 1;
}

.hscroll-fade--left {
    left: -1rem;
    background: linear-gradient(90deg, var(--background), transparent);
}

.hscroll-fade--right {
    right: -1rem;
    background: linear-gradient(270deg, var(--background), transparent);
}

/* B-7 .b4-feed .b4-feed--ranked: four equal block cards. */
.ranking-page .ranking-activity {
    display: grid;
    gap: var(--space-3);
    min-width: 0;
}

.ranking-page .ranking-activity-heading {
    margin: 0;
    font-size: 1rem;
}

.ranking-page .ranking-activity-note {
    margin: 0;
    color: var(--text-faint);
    font-size: .86rem;
}

.b4-feed {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(15rem, 1fr);
    gap: var(--space-3);
}

.b4-feed-item {
    display: grid;
}

.b4-feed-card {
    display: grid;
    grid-template-columns: 2.5rem minmax(0, 1fr);
    align-items: start;
    gap: .5rem;
    padding: var(--space-4);
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-card-shadow);
}

a.b4-feed-card {
    color: inherit;
    text-decoration: none;
}

a.b4-feed-card:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.b4-feed-logo {
    display: grid;
    grid-row: span 2;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: .9rem;
    font-weight: var(--font-weight-heading);
}

.b4-feed-logo.b4-feed-logo--img {
    border-color: transparent;
    background: none;
}

.b4-feed-logo > img.logo--img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* A picture the logo fallback hid stays hidden: the display rule above
   must not bring a broken picture back next to the letter tile. */
.b4-feed-logo > img.logo--img[hidden] {
    display: none;
}

.b4-feed-head {
    display: flex;
    align-items: baseline;
    gap: .45rem;
    min-width: 0;
}

.b4-feed-rank {
    flex: none;
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .93rem;
}

.b4-feed-title {
    min-width: 0;
    overflow: hidden;
    font-size: .93rem;
    font-weight: var(--font-weight-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.b4-feed-foot {
    display: flex;
    flex-wrap: wrap;
    grid-column: 2;
    align-items: baseline;
    gap: .3rem .6rem;
}

.b4-feed-val {
    font-family: var(--font-family-num);
    font-size: 1.02rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

.b4-feed-delta {
    padding: 0 .35rem;
    border: 1px solid color-mix(in srgb, var(--positive) 26%, transparent);
    border-radius: var(--radius-sm);
    background: var(--positive-soft);
    color: var(--positive);
    font-family: var(--font-family-num);
    font-size: .78rem;
    line-height: 1.5;
}

.b4-feed-time {
    color: var(--text-faint);
    font-size: .78rem;
}

/* B-7 .b4-active: three equal boxes on another surface than the platform
   teasers, without a brand line; the order carries the activity rank. */
.b4-active-section {
    display: grid;
    gap: var(--space-3);
    min-width: 0;
    margin: 0 0 var(--space-5);
}

.b4-active-heading {
    margin: 0;
    font-size: 1rem;
}

.b4-active-note {
    margin: 0;
    color: var(--text-faint);
    font-size: .86rem;
}

.b4-active {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(15rem, 1fr);
    gap: var(--space-4);
}

.b4-act {
    display: flex;
    flex-direction: column;
    gap: .45rem;
    padding: var(--space-4);
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--box-muted-bg);
}

.b4-act__name {
    color: inherit;
    font-size: 1.02rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.025em;
    text-decoration: none;
}

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

.b4-act__metric {
    color: var(--muted);
    font-size: .82rem;
}

.b4-act__time {
    color: var(--text-faint);
    font-size: .78rem;
}

.b4-act .mini {
    display: flex;
    align-items: center;
    gap: .65rem;
    min-height: 2.75rem;
    padding: .5rem .6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: var(--surface);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.b4-act .mini:hover {
    border-color: var(--accent-border);
    background: var(--accent-soft);
}

.b4-act .mini .r {
    flex: none;
    min-width: 1.8rem;
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .82rem;
    white-space: nowrap;
}

.b4-act .mini .l {
    display: grid;
    flex: none;
    place-items: center;
    width: 28px;
    height: 28px;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: .78rem;
}

.b4-act .mini .l.mini__logo--img {
    border-color: transparent;
    background: none;
}

.b4-act .mini .l > img.logo--img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.b4-act .mini .l > img.logo--img[hidden] {
    display: none;
}

.b4-act .mini .t {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    font-size: .9rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.b4-act .mini .v {
    flex: none;
    color: var(--muted);
    font-family: var(--font-family-num);
    font-size: .84rem;
}

@media (max-width: 760px) {
    .b4-feed,
    .b4-active {
        grid-auto-columns: minmax(15rem, 82%);
    }
}

@media (prefers-reduced-motion: reduce) {
    .hscroll-fade,
    .b4-act .mini,
    .ranking-page .quick-filters-panel.is-ready,
    .ranking-page .quick-filters-panel.is-ready.is-open,
    .ranking-page .quick-filters-link {
        transition: none;
    }
}

/* Share panel example image (SHARE-CTX-B1). The only new component of the
   share panel: a figure with the fixed local example share image. Everything
   else of the panel reuses the share box, its buttons, field and targets. The
   image keeps its 1734 x 907 ratio through the width and height attributes;
   no media rule and no motion. */
.share-demo {
    display: grid;
    gap: .45rem;
    margin: 0;
}

.share-demo img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

/* The example image is a link that opens its own example dialog. */
.share-demo .share-demo__open {
    display: block;
    border-radius: var(--radius-md);
    cursor: zoom-in;
}

.share-demo figcaption {
    color: var(--muted);
    font-size: .84rem;
}

/* N white surfaces (UI corrections N, operator decision of 2026-10-09). The only
   place of the stylesheet outside the first token blocks that writes the
   literal colour #ffffff, and only for the nine surfaces listed below, each
   scoped to its own page: the account preview frame and, inside it, the
   profile head card and the profile card rows; the owner rows of "My cards";
   the empty states of "My increases" and "Payments"; the redeem inset of the
   points page; the list box and the card rows of the two choice lists of
   Claim rank (UI package, operator decision of 2026-10-12). Public profiles and every other box keep their token surface.
   The rules sit in front of the redesign block, so they win by their longer
   selectors, not by order. No important flag and no other literal colour.

   U36 (operator list 2026-10-21) supersedes this for three of them in the
   dark theme: the preview frame (with its head card and card rows), the owner
   rows of "My cards" and the redeem inset of the points page are white in the
   light theme only and take their dark token surfaces in the dark theme.

   Dark mode keeps the other surfaces white (operator wish). Everything inside a
   white surface must stay readable, so in the dark theme the surface renders
   its subtree with the values of the light theme: the same token names as the
   first :root block carry the light values (a mirror of that block, pinned by
   a test), the text colour is the light theme text colour and the colour
   scheme of the native controls is light. The shadow tokens are not touched. */
html:not([data-theme="dark"]) .rd main .rd-inset.rd-preview,
html:not([data-theme="dark"]) .rd main .rd-inset.rd-preview .rd-card.rd-profile-head,
html:not([data-theme="dark"]) .rd main .rd-inset.rd-preview .profile-card-list > .rd-row.rd-row--novalue,
html:not([data-theme="dark"]) .rd main .rd-stack.rd-stack--cards .rd-row.rd-row--owner,
.rd main section.rd-stack.rd-stack--increases .rd-empty,
.rd main section.rd-stack.rd-stack--payments .rd-empty,
html:not([data-theme="dark"]) .rd main .rd-inset.rd-stack.rd-inset--points,
.rd main .rd-claim-list > .rd-rows,
.rd main .rd-claim-list .rd-rows > li.rd-row {
    background: #ffffff;
}

html[data-theme="dark"] .rd main section.rd-stack.rd-stack--increases .rd-empty,
html[data-theme="dark"] .rd main section.rd-stack.rd-stack--payments .rd-empty,
html[data-theme="dark"] .rd main .rd-claim-list > .rd-rows,
html[data-theme="dark"] .rd main .rd-claim-list .rd-rows > li.rd-row {
    color: var(--foreground);
    color-scheme: light;
    --background: #fbfcfe;
    --surface: #ffffff;
    --surface-2: #f2f5fa;
    --border: #e1e7f0;
    --footer: #f1f4f9;
    --foreground: #0d1526;
    --muted: #4d5a70;
    --accent-soft: #edf4ff;
    --accent-border: #1463f3;
    --chip: #f2f4f8;
    --chip-border: #e4e7ee;
    --bid-bg: #f6f9ff;
    --bid-border: #dfe8f7;
    --focus: #1463f3;
    --accent-text: #1463f3;
    --surface-raised: #ffffff;
    --border-control: #8792a6;
    --border-strong: #d3dbe8;
    --text-faint: #636e84;
    --positive: #0a6b4a;
    --positive-soft: #e2f4ee;
    --warning: #7f5209;
    --warning-soft: #fbf1dc;
    --danger: #9d2020;
    --danger-soft: #fae8e8;
    --accent-deep: #0c46b8;
    --teal: #0a7d72;
    --teal-soft: #e4f7f4;
    --focus-neutral: #55617a;
    --border-soft: #a8b0be;
    --border-quiet: #d3dbe8;
    --heart: #d81e5b;
    --move-control: #818da1;
    --grad-text-from: var(--accent-gradient-from);
    --grad-text-to: var(--accent-gradient-to);
    /* U44.19 to U44.22: the group borders follow the light border of this
       island. */
    --box-light-border: var(--border);
    --box-card-border: var(--border);
}

/* B-7 redesign surfaces. The shared components of the premium redesign,
   derived from docs/design-drafts/upbiddr-light-draft-b-7.html and translated
   to the existing token names; this block declares no token of its own.

   Scope: every selector starts with .rd, the root class the layout puts on
   #main for the routes of App\Support\RedesignSurface. Header and footer sit
   outside #main, so these rules cannot reach them. The only selectors that do
   not start with .rd are the documented exceptions for elements outside
   #main: the toaster and its two new toast variants (.b7-toaster,
   .b7-toast--rd, .b7-toast--info, .b7-toast--warn, .b7-toast__text,
   .b7-toast__close), the header tooltip that gives way while a header overlay
   is open (.site-header.is-overlay-open .tip-bub, visibility only), the one
   tooltip layer rule that lowers every info tooltip while an overlay is open
   (html.rd-overlay-open .b7-info, z-index only; the script sets the class on
   the root element) and the header login field that the script marks after a failed check
   (.login-pop .inp[aria-invalid], .login-pop .rd-shake). The long-standing
   .b7-toast, .b7-toast--ok and .b7-toast--err rules are not touched, so the
   copy toast of the protected pages looks exactly as before.

   Layers. Tooltip 7 (N2: below the sticky header, so a tooltip never appears
   above the header or its area; above every content layer, which stays at 5 or
   below), lowered to 3 by the single exception rule below only while the menu,
   the login window, the account menu or the rankings share popover is open;
   then tooltip 3, rankings share popover 5, header context 8, skip link 20,
   filter panel 50, toaster 80. This
   block sets no other z-index. No container of this block (card, row,
   mini card, inset) may form a stacking context: no transform, filter,
   opacity below one, isolation, will-change or contain paint on them, so a
   tooltip inside one is never trapped under its neighbour. Cards react on
   hover with border and shadow only, never with a movement. A tooltip does
   not belong in an accordion body: the details content clips its box.

   Motion. Only opacity, transform, colour and the accordion height
   (interpolate-size and the details content box, the pattern of the FAQ).
   Every transition and animation of this block is switched off again in its
   own reduced motion rule at the end, where the cascade keeps it behind the
   rules it must override. The forced colours rule at the very end gives cards,
   toasts, segments and badges a system colour outline, the checked checkbox
   and the tab ink their system colours.

   No inline style is needed anywhere: the composition bar and the tab ink get
   their numbers from the script (data-cents and measured positions); without
   the script the bar stays hidden and its legend shows the exact amounts. */

/* Layers. The single exception to the .rd scope for a layer: while an overlay
   is open the script marks the root element, and every info tooltip gives way
   to the overlay (z-index only). */
html.rd-overlay-open .b7-info {
    z-index: 3;
}

/* Page head: eyebrow or breadcrumb, headline, one sentence, at most two
   actions of which one is primary. */
.rd .rd-head {
    display: grid;
    gap: .55rem;
    min-width: 0;
    margin: 0 0 var(--space-5);
}

.rd .rd-head__top {
    display: grid;
    gap: var(--space-3);
    min-width: 0;
}

.rd .rd-head h1 {
    margin: 0;
    font-size: clamp(1.6rem, 4vw, 1.9rem);
    font-weight: var(--font-weight-heading);
    letter-spacing: -.035em;
    line-height: 1.15;
}

.rd .rd-head__lede {
    max-width: 62ch;
    margin: 0;
    color: var(--muted);
    font-size: 1.02rem;
}

.rd .rd-head__actions {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    min-width: 0;
}

.rd .rd-head__actions .btn {
    width: 100%;
}

.rd .rd-head__eyebrow {
    display: inline-flex;
    align-items: center;
    justify-self: start;
    gap: .45rem;
    padding: .3rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: .71rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .14em;
    text-transform: uppercase;
}

.rd .rd-crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .15rem .4rem;
    margin: 0;
    padding: 0;
    color: var(--text-faint);
    font-size: .84rem;
    list-style: none;
}

.rd .rd-crumbs li {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-width: 0;
    margin: 0;
}

.rd .rd-crumbs li:not(.rd-crumbs__parent) {
    display: none;
}

.rd .rd-crumbs__parent::before {
    content: "\2039";
    color: var(--text-faint);
}

.rd .rd-crumbs a {
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.rd .rd-crumbs a:hover {
    text-decoration: underline;
    text-underline-offset: .2em;
}

.rd .rd-crumbs [aria-current="page"] {
    color: var(--muted);
}

/* A link that is a button keeps its button colours: the surface rule that
   colours every link of the main area with the accent would otherwise turn
   the label of a primary button blue on blue. */
.rd main a.btn,
.rd main a.btn:hover {
    color: var(--foreground);
}

.rd main a.btn--danger,
.rd main a.btn--danger:hover {
    color: var(--danger);
}

.rd main a.btn--primary,
.rd main a.btn--primary:hover {
    color: var(--button-text);
}

/* Section card, its quiet inset and the layout helpers. */
.rd .rd-card {
    position: relative;
    display: grid;
    gap: var(--space-4);
    align-content: start;
    min-width: 0;
    padding: var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    outline: 1px solid transparent;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.rd .rd-card--hair::before {
    content: "";
    position: absolute;
    top: 0;
    left: 14%;
    right: 14%;
    height: 3px;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
}

.rd .rd-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .4rem .75rem;
    min-width: 0;
}

.rd .rd-card > :is(h2, h3) {
    margin: 0;
    font-size: 1.04rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

.rd .rd-card__head :is(h2, h3) {
    margin: 0;
    font-size: 1.04rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

.rd .rd-card__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

.rd .rd-inset {
    min-width: 0;
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.rd .rd-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    align-items: start;
}

.rd .rd-grid > * {
    min-width: 0;
}

.rd .rd-stack {
    display: grid;
    gap: var(--space-4);
    min-width: 0;
}

/* Stat tiles (B-7 .b4-stat): a small label, a large tabular figure. Two
   columns on a 360px screen through the minimum of the track. */
.rd .rd-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-5);
    padding: 0;
    list-style: none;
}

/* Three tiles (the ranking cards page): two columns on a narrow screen with
   the last, odd tile across both; the server marks that tile, so no
   position selector is needed. From 761px all three share one row. */
.rd .rd-stats--odd {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.rd .rd-stats--odd > .rd-stat--last {
    grid-column: 1 / -1;
}

/* UI-11 (operator decision 2026-10-21): on the points page of a card the
   two tiles stand one above the other, and the Points link follows them
   directly, in the gap of their stack. */
.rd .rd-redeem__facts > .rd-stats {
    grid-template-columns: minmax(0, 1fr);
    margin: 0;
}

.rd .rd-redeem__facts > p {
    margin: 0;
}

.rd .rd-stat {
    position: relative;
    display: flex;
    margin: 0;
    flex-direction: column;
    gap: .3rem;
    min-width: 0;
    padding: var(--space-4);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    color: inherit;
    text-decoration: none;
    outline: 1px solid transparent;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.rd .rd-stat__label {
    color: var(--text-faint);
    font-size: .73rem;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.rd .rd-stat__value {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: 1.45rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.03em;
    line-height: 1.2;
}

.rd .rd-stat__note {
    color: var(--muted);
    font-size: .8rem;
}

.rd .rd-more {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    color: var(--accent-text);
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.rd .rd-more::after {
    content: "\203A";
    display: inline-block;
    transition: transform var(--motion-fast) var(--motion-ease);
}

.rd a:hover > .rd-more::after,
.rd a.rd-more:hover::after {
    transform: translateX(2px);
}

/* Badges (B-7 .badge) in the four meanings plus the neutral one. The meaning
   never rests on colour alone: every badge carries its word. */
.rd .rd-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .55rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
    font-size: .74rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.2;
    white-space: nowrap;
    outline: 1px solid transparent;
}

.rd .rd-badge--ok {
    border-color: color-mix(in srgb, var(--positive) 30%, transparent);
    background: var(--positive-soft);
    color: var(--positive);
}

.rd .rd-badge--warn {
    border-color: color-mix(in srgb, var(--warning) 30%, transparent);
    background: var(--warning-soft);
    color: var(--warning);
}

.rd .rd-badge--err {
    border-color: color-mix(in srgb, var(--danger) 30%, transparent);
    background: var(--danger-soft);
    color: var(--danger);
}

.rd .rd-badge--neutral {
    border-color: var(--border-quiet);
    background: var(--surface-2);
    color: var(--muted);
}

.rd .rd-row__meta > .rd-badge {
    max-width: 100%;
    white-space: normal;
}

.rd a.chip:hover,
.rd button.chip:hover {
    border-color: var(--border-quiet);
    background-color: var(--accent-soft);
    color: var(--accent-text);
}

/* Row card (B-7 .rcard and .b4-nrow): logo slot, title with meta chips and
   stats, value zone, actions. Mobile first: logo and text on top, value zone
   and actions below across the full width. The owner and the public variant
   share the structure; the public one is a quiet link surface. */
.rd .rd-row {
    position: relative;
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    grid-template-areas:
        "logo main"
        "value value"
        "actions actions";
    gap: var(--space-3);
    min-width: 0;
    padding: var(--space-4);
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-card-shadow);
    outline: 1px solid transparent;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.rd .rd-row__logo {
    grid-area: logo;
    display: grid;
    place-items: center;
    width: 3.4rem;
    height: 3.4rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-text);
    font-size: 1.15rem;
    font-weight: var(--font-weight-heading);
}

.rd .rd-row__logo img {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
    border-radius: 0;
    object-fit: cover;
}

.rd .rd-row__main {
    grid-area: main;
    display: grid;
    gap: .4rem;
    align-content: start;
    min-width: 0;
}

.rd .rd-row__title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
    line-height: 1.25;
}

.rd .rd-row__title a {
    color: inherit;
    text-decoration: none;
}

.rd .rd-row--public .rd-row__title a::after {
    content: "";
    position: absolute;
    inset: 0;
}

.rd .rd-row__text {
    margin: 0;
    color: var(--muted);
    font-size: .89rem;
}

.rd .rd-row__meta {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    min-width: 0;
}

.rd .rd-row__stats {
    display: flex;
    flex-wrap: wrap;
    gap: .2rem 1rem;
    margin: 0;
    padding: 0;
    color: var(--muted);
    font-size: .84rem;
    list-style: none;
}

.rd .rd-row__stats li {
    margin: 0;
}

.rd .rd-row__stats li:has(> .b7-info) {
    display: inline-flex;
    align-items: center;
}

.rd .rd-row__value {
    grid-area: value;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: .35rem .75rem;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

.rd .rd-row__amount {
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: 1.28rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.03em;
}

.rd .rd-row__label {
    color: var(--text-faint);
    font-size: .68rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.rd .rd-row__actions {
    grid-area: actions;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    position: relative;
}

.rd .rd-row__actions .btn {
    width: 100%;
}

/* A15 (order 2026-11-01): in the link list of Account > Links the two
   actions of a row stand side by side at every width; they wrap only when
   both do not fit (very narrow screens, large zoom). Other action groups
   keep their own layout.
   Order 2026-11-04 (F6): the action row uses the width of the card, but
   every button keeps the width of its label plus its own padding, left
   aligned, also a single Manage button; no button grows to share the row.
   A button wider than the row shrinks and wraps its label instead of
   overflowing. */
.rd .rd-rows--links .rd-row__actions {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-start;
}

.rd .rd-rows--links .rd-row__actions .btn {
    flex: 0 1 auto;
    width: auto;
    max-width: 100%;
}

/* Mini card (B-7 .mini): a compact link row with rank, logo, title, value. */
.rd .rd-mini {
    display: flex;
    align-items: center;
    gap: .65rem;
    min-width: 0;
    min-height: 2.75rem;
    padding: .5rem .6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: inherit;
    text-decoration: none;
    outline: 1px solid transparent;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.rd a.rd-mini:hover {
    border-color: var(--accent-border);
    background: var(--accent-soft);
}

.rd .rd-mini__rank {
    flex: none;
    min-width: 1.8rem;
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .82rem;
    white-space: nowrap;
}

.rd .rd-mini__logo {
    display: grid;
    flex: none;
    place-items: center;
    width: 28px;
    height: 28px;
    overflow: hidden;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-text);
    font-size: .78rem;
}

.rd .rd-mini__title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    font-size: .9rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rd .rd-mini__value {
    flex: none;
    color: var(--muted);
    font-family: var(--font-family-num);
    font-size: .84rem;
    font-variant-numeric: tabular-nums;
}

/* Empty state (B-7 .empty): icon box, heading, one sentence, the next step. */
.rd .rd-empty {
    display: grid;
    justify-items: center;
    gap: .45rem;
    padding: var(--space-7) var(--space-5);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    text-align: center;
    outline: 1px solid transparent;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.rd .rd-empty__icon {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    margin: 0 0 .15rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-faint);
}

.rd .rd-empty :is(h2, h3) {
    margin: 0;
}

.rd .rd-empty p {
    max-width: 46ch;
    margin: 0 0 var(--space-3);
    color: var(--muted);
}

/* Confirm and danger card: a centred card for an irreversible step. The
   destructive action is never the primary button. */
.rd .rd-confirm {
    width: min(34rem, 100%);
    margin: var(--space-5) auto;
}

.rd .rd-card--danger {
    border-color: color-mix(in srgb, var(--danger) 30%, var(--border));
}

.rd .rd-card--danger .rd-card__head :is(h2, h3) {
    color: var(--danger);
}

/* Tabs with a sliding ink. The static underline of the current tab stays
   the no-script look; once the script has placed the ink it takes over. The
   ink gets its position only after the first paint, so it never slides in. */
.rd .profile-tabs {
    position: relative;
    flex-wrap: nowrap;
}

.rd .profile-tabs a {
    flex: none;
    white-space: nowrap;
}

.rd main > .profile-tabs {
    margin: 0 0 var(--space-4);
    padding: 0;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.rd main .profile-tabs a {
    color: var(--muted);
}

.rd main .profile-tabs a:hover {
    color: var(--foreground);
}

.rd main .profile-tabs a[aria-current="page"] {
    color: var(--accent-text);
}

.rd .rd-tab-ink {
    position: absolute;
    left: 0;
    bottom: -1px;
    width: 0;
    height: 3px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--brand-rule-mid) 55%, var(--accent-gradient-to) 100%);
    pointer-events: none;
}

.rd .profile-tabs.has-ink a[aria-current="page"]::after {
    content: none;
}

.rd .profile-tabs.has-ink.is-ink-ready .rd-tab-ink {
    transition: transform var(--motion-base) var(--motion-ease), width var(--motion-base) var(--motion-ease);
}

/* Accordion (B-7 .acc) on the native details element, the technique of the
   FAQ: plus and minus cross over, and where the browser knows the details
   content box the answer opens in height; every other browser opens it at
   once. It works without the script. */
.rd .rd-acc {
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-md);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    outline: 1px solid transparent;
    interpolate-size: allow-keywords;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.rd .rd-acc + .rd-acc {
    margin-top: .5rem;
}

.rd .rd-acc > summary {
    position: relative;
    min-height: 2.75rem;
    padding: .8rem 2.75rem .8rem 1rem;
    cursor: pointer;
    font-weight: var(--font-weight-medium);
    list-style: none;
}

.rd .rd-acc > summary::-webkit-details-marker {
    display: none;
}

.rd .rd-acc > summary:hover {
    color: var(--accent-text);
}

.rd .rd-acc > summary:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
    border-radius: var(--radius-md);
}

.rd .rd-acc > summary > .b7-chev {
    position: absolute;
    top: 50%;
    right: 1rem;
    transform: translateY(-50%);
}

.rd .rd-acc[open]:not([data-disclosure-closing]) > summary .b7-chev__plus {
    opacity: 0;
    transform: rotate(90deg) scale(.6);
}

.rd .rd-acc[open]:not([data-disclosure-closing]) > summary .b7-chev__minus {
    opacity: 1;
    transform: none;
}

.rd .rd-acc::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size var(--motion-slow) var(--motion-ease), content-visibility var(--motion-slow) allow-discrete;
}

.rd .rd-acc[open]::details-content {
    block-size: auto;
}

/* A12: the disclosure script animates the height of an accordion it has
   taken over (data-disclosure-ready); its content box stays still. */
.rd .rd-acc[data-disclosure-ready]::details-content {
    transition: none;
}

.rd .rd-acc__body {
    display: grid;
    gap: var(--space-3);
    padding: 0 1rem 1rem;
}

/* Form controls. They keep the long-standing neutral B-7 field focus (a
   darker edge on the inset surface) and nothing else: no ring, no outline and
   no shadow (N5). Forced colours turns the edge into a system colour in its
   own rule. Placeholder, caret, selection and autofill follow the tokens. */
.rd ::selection {
    background: color-mix(in srgb, var(--accent) 24%, transparent);
}

.rd main :is(input, textarea) {
    caret-color: var(--accent);
}

.rd main :is(input, textarea)::placeholder {
    color: var(--text-faint);
    opacity: 1;
}

.rd :is(input[type="checkbox"], input[type="radio"]) {
    accent-color: var(--accent);
}

.rd main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input[type="file"], input:not([type]), select, textarea):focus-visible {
    outline: none;
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.rd main :is(input, textarea, select):-webkit-autofill,
.rd main :is(input, textarea, select):-webkit-autofill:hover,
.rd main :is(input, textarea, select):-webkit-autofill:focus {
    -webkit-text-fill-color: var(--foreground);
    caret-color: var(--foreground);
    box-shadow: 0 0 0 100rem var(--surface) inset;
}

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

.rd main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input[type="file"], input:not([type]), select, textarea)[aria-invalid="true"]:focus-visible {
    border-color: var(--danger);
}

.rd main :is(input, select, textarea):disabled {
    background: var(--surface-2);
    color: var(--text-faint);
    cursor: not-allowed;
    opacity: .6;
}

.rd main :is(input, textarea)[readonly] {
    cursor: default;
}

/* Select chevron. A select sits in a .fsel wrapper that draws one chevron of
   the faint text token, so it always sits at the vertical middle of the
   field, whatever the field's height is. A select outside a wrapper keeps a
   centred gradient chevron as the fallback. */
.rd main select:not([multiple]):not([size]) {
    padding-right: 2.25rem;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--muted) 50%, var(--muted) 58%, transparent 58%),
        linear-gradient(135deg, transparent 42%, var(--muted) 42%, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 1.05rem) 50%, calc(100% - .75rem) 50%;
    background-repeat: no-repeat;
    background-size: 6px 6px, 6px 6px;
    -webkit-appearance: none;
    appearance: none;
    text-overflow: ellipsis;
}

.rd .fsel {
    position: relative;
    display: flex;
    width: 100%;
    max-width: 100%;
    min-width: 0;
}

.rd main .fsel > select:not([multiple]):not([size]) {
    width: 100%;
    min-width: 0;
    min-height: 2.75rem;
    margin: 0;
    padding: 0 2.25rem 0 .7rem;
    background-image: none;
    font-size: .86rem;
}

/* A45 (Q45.7): the native select without the script shows the static
   chevron pair of the rankings filter, as in the share box above; the
   keyboard focus draws it in the text colour (the system text colour in
   forced colours). */
.rd .fsel::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(135deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%),
        linear-gradient(135deg, transparent 42%, var(--text-faint) 42%, var(--text-faint) 58%, transparent 58%);
    background-position: calc(100% - 1.05rem) calc(50% - 4px), calc(100% - .75rem) calc(50% - 4px), calc(100% - 1.05rem) calc(50% + 4px), calc(100% - .75rem) calc(50% + 4px);
    background-repeat: no-repeat;
    background-size: 5px 5px;
    pointer-events: none;
}

.rd .fsel:focus-within::after {
    background-image:
        linear-gradient(135deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%),
        linear-gradient(45deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%),
        linear-gradient(135deg, transparent 42%, currentColor 42%, currentColor 58%, transparent 58%);
}

.rd .fsel:has(> select:disabled)::after {
    opacity: .5;
}

/* Select combobox (progressive). With the script the visible field of a
   select is a button that opens the option list of the filter panel
   (.b7-fpanel); the native select stays in the form, clipped under the
   button, so the browser still validates and submits it. The panel lives in
   the body: its few own rules name the panel class and set only the list
   look (the active option and the disabled option). Without the script the
   native select above is all there is. */
.rd .fsel > .rd-sel-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .45rem;
    width: 100%;
    min-width: 0;
    min-height: 2.75rem;
    margin: 0;
    padding: 0 .7rem;
    overflow: hidden;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background-color: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .86rem;
    font-weight: 400;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.rd .rd-sel-btn__text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rd .fsel > .rd-sel-btn:focus-visible,
.rd .fsel > .rd-sel-btn[aria-expanded="true"] {
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.rd .fsel > .rd-sel-btn:focus-visible {
    outline: none;
}

/* A45: with the button the field shows the stacked chevron pair of the
   rankings filter (built by the script) instead of the static pair of the
   native select; the upper chevron gains weight and the lower one fades
   while the list is open. Without the script the native select keeps the
   static pair (Q45.7), as a native select has no open state to show. */
.rd .fsel:has(> .rd-sel-btn)::after {
    content: none;
}

.rd .fsel > .rd-sel-btn .filter-chev-up {
    opacity: .55;
}

.rd .fsel > .rd-sel-btn[aria-expanded="true"] .b7-fsw-chev {
    color: currentColor;
}

.rd .fsel > .rd-sel-btn[aria-expanded="true"] .filter-chev-up {
    opacity: 1;
}

.rd .fsel > .rd-sel-btn[aria-expanded="true"] .filter-chev-down {
    opacity: .3;
}

.rd .fsel > .rd-sel-btn:disabled .b7-fsw-chev {
    opacity: .5;
}

.rd .fsel > .rd-sel-btn[aria-invalid="true"] {
    border-color: var(--danger);
}

.rd .fsel > .rd-sel-btn[aria-invalid="true"]:focus-visible {
    border-color: var(--danger);
}

.rd .fsel > .rd-sel-btn:disabled {
    background-color: var(--surface-2);
    color: var(--text-faint);
    cursor: not-allowed;
    opacity: .6;
}

.rd main .fsel > select.rd-sel-native:not([multiple]):not([size]) {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 1px;
    height: 1px;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    opacity: 0;
    pointer-events: none;
}

.rd-sel-panel .b7-fopt.is-active {
    border-color: var(--border);
    background-color: var(--surface-2);
    outline: 1px solid transparent;
}

.rd-sel-panel .b7-fopt[aria-disabled="true"] {
    border-color: transparent;
    background-color: transparent;
    color: var(--text-faint);
    cursor: not-allowed;
}

.rd-sel-panel .b7-fopt[aria-selected="true"].is-active {
    border-color: var(--accent);
    background-color: var(--accent-soft);
}

.rd main input[type="file"]::file-selector-button {
    min-height: 2.2rem;
    margin-right: .75rem;
    padding: 0 .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.rd main input[type="file"]::file-selector-button:hover {
    background: var(--surface-2);
}

.rd main input[type="file"]:focus-visible::file-selector-button {
    border-color: var(--focus-neutral);
    background: var(--surface-2);
}

.rd main .rd-card form:not([hidden]) {
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
}

/* The foot line of a counted field: the hint on the left, the counter on the
   right. The counter only shows once the script made it live; the row has a
   fixed height, so nothing jumps while typing. */
.rd .rd-field-foot {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    min-height: 1.25rem;
    margin: .35rem 0 0;
    color: var(--text-faint);
    font-size: .78rem;
    line-height: 1.25rem;
}

.rd .rd-field-foot__hint {
    min-width: 0;
}

.rd .rd-field-foot__hint--over {
    color: var(--danger);
}

/* A10 (order 2026-11-01): a field note as the hint of the foot line (the
   profile name tip) keeps the line of the counter. */
.rd .rd-field-foot > .rd-field-note {
    margin: 0;
}

.rd .rd-count {
    display: none;
    flex: none;
    font-family: var(--font-family-num);
    font-variant-numeric: tabular-nums;
}

.rd .rd-count.is-live {
    display: inline-block;
    min-width: 4.4ch;
    text-align: right;
}

.rd .rd-count--over {
    color: var(--danger);
    font-weight: var(--font-weight-medium);
}

/* Handle field with its fixed at sign. Display only: nothing is checked. */
.rd .rd-adorn {
    position: relative;
    display: flex;
    align-items: center;
}

.rd .rd-adorn__prefix {
    position: absolute;
    left: .8rem;
    color: var(--text-faint);
    font-weight: var(--font-weight-medium);
    pointer-events: none;
}

.rd main .rd-adorn > input {
    padding-left: 1.9rem;
}

/* Live check of the profile name (G2). The icon sits inside the field on the
   right and is decoration only: the status line below the field says the same
   in words, so the state never depends on colour or on the icon. Without the
   script no state class is ever set, so nothing of this shows. Success colour
   only for "available", danger for "unavailable" and "invalid", muted for the
   rest. The icons draw with currentColor, so forced colours keeps them. */
.rd main .rd-handle-field .rd-adorn > input {
    padding-right: 2.4rem;
}

.rd .rd-handle-state {
    position: absolute;
    right: .8rem;
    display: inline-flex;
    align-items: center;
    color: var(--text-faint);
    pointer-events: none;
}

.rd .rd-handle-state__ico {
    display: none;
}

.rd .rd-handle-state__wait {
    position: relative;
}

.rd .rd-handle-state__wait::after {
    content: "";
    position: absolute;
    inset: -3px;
    border: 2px solid var(--border-control);
    border-radius: 50%;
    opacity: 0;
    animation: preview-pulse 1200ms var(--motion-ease) infinite;
}

.rd .rd-handle-field.is-available .rd-handle-state__ico--ok,
.rd .rd-handle-field.is-unavailable .rd-handle-state__ico--bad,
.rd .rd-handle-field.is-invalid .rd-handle-state__ico--bad,
.rd .rd-handle-field.is-unchecked .rd-handle-state__ico--off {
    display: block;
}

.rd .rd-handle-field.is-checking .rd-handle-state__wait {
    display: inline-flex;
}

.rd .rd-handle-field.is-available .rd-handle-state {
    color: var(--positive);
}

.rd .rd-handle-field.is-unavailable .rd-handle-state,
.rd .rd-handle-field.is-invalid .rd-handle-state {
    color: var(--danger);
}

.rd .rd-handle-field.is-available .rd-handle-status {
    color: var(--positive);
}

.rd .rd-handle-field.is-unavailable .rd-handle-status,
.rd .rd-handle-field.is-invalid .rd-handle-status {
    color: var(--danger);
}

/* Checkbox (B-7 .cbx): the native input stays in the markup and keeps the
   keyboard; the box draws the check with a stroke dash. */
.rd .cbx {
    position: relative;
    display: inline-flex;
    align-items: flex-start;
    gap: .6rem;
    margin: 0;
    cursor: pointer;
    font-size: .88rem;
    font-weight: 400;
}

.rd .cbx > input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
}

.rd .cbx__box {
    display: grid;
    flex: none;
    place-items: center;
    width: 1.3rem;
    height: 1.3rem;
    margin-top: .1rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-sm);
    background: var(--surface);
    transition: background-color var(--motion-base) var(--motion-ease), border-color var(--motion-base) var(--motion-ease);
}

.rd .cbx__box svg {
    width: 14px;
    height: 14px;
    fill: none;
    stroke: var(--button-text);
    stroke-width: 2.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.rd .cbx__box svg path {
    stroke-dasharray: 20;
    stroke-dashoffset: 20;
    transition: stroke-dashoffset var(--motion-slow) var(--motion-ease);
}

.rd .cbx > input:checked + .cbx__box {
    border-color: var(--accent);
    background-color: var(--accent);
}

.rd .cbx > input:checked + .cbx__box svg path {
    stroke-dashoffset: 0;
}

.rd .cbx > input:focus-visible + .cbx__box {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

/* A14: the same shared focus ring for the B-7 checkbox of the admin forms
   and of the header login window (their other rules sit in the surfaces
   block, which keeps only the neutral field outline). */
.surface--admin .cbx > input:focus-visible + .cbx__box,
.login-pop .cbx > input:focus-visible + .cbx__box {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.rd .cbx > input[aria-invalid="true"] + .cbx__box {
    border-color: var(--danger);
}

.rd .cbx > input:disabled + .cbx__box {
    opacity: .45;
}

/* Choice cards (B-7 .pick) for a radio group, and the existing switch with a
   short slide of its track and knob. */
.rd .rd-pick {
    display: grid;
    gap: .5rem;
    margin: 0;
    padding: 0;
    border: 0;
}

.rd .rd-pick label:not([hidden]) {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    margin: 0;
    padding: .7rem .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    cursor: pointer;
    font-weight: 400;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.rd .rd-pick label:hover {
    background-color: var(--surface-2);
}

.rd .rd-pick label:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.rd .rd-pick label:has(input:focus-visible) {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.rd .b7-switch__track {
    transition: background-color var(--motion-base) var(--motion-ease), border-color var(--motion-base) var(--motion-ease);
}

.rd .b7-switch__track::after {
    transition: transform var(--motion-base) var(--motion-ease), background-color var(--motion-base) var(--motion-ease);
}

/* Composition bar of a ranking value. The segment widths are the exact cent
   amounts as flex-grow, set by the script from data-cents; no percentage and
   no rounding. Without the script only the legend shows. No animation. */
.rd .rd-compose {
    display: grid;
    gap: .6rem;
    min-width: 0;
}

.rd .rd-compose__bar {
    display: none;
    gap: 2px;
    height: .7rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
}

.rd .rd-compose__bar.is-ready {
    display: flex;
}

.rd .rd-compose__seg {
    flex: 1 1 0;
    min-width: 3px;
    background: var(--accent);
    outline: 1px solid transparent;
}

.rd .rd-compose__seg--points {
    background: var(--teal);
}

.rd .rd-compose__seg--coop {
    background: var(--warning);
}

.rd .rd-compose__seg--legacy {
    background: repeating-linear-gradient(135deg, var(--border-soft) 0 4px, var(--surface-2) 4px 8px);
}

.rd .rd-compose__legend {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1rem;
    margin: 0;
    padding: 0;
    color: var(--muted);
    font-size: .84rem;
    list-style: none;
}

.rd .rd-compose__legend li {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin: 0;
}

.rd .rd-compose__swatch {
    flex: none;
    width: .7rem;
    height: .7rem;
    border-radius: 2px;
    background: var(--accent);
    outline: 1px solid transparent;
}

.rd .rd-compose__swatch--points {
    background: var(--teal);
}

.rd .rd-compose__swatch--coop {
    background: var(--warning);
}

.rd .rd-compose__swatch--legacy {
    background: repeating-linear-gradient(135deg, var(--border-soft) 0 3px, var(--surface-2) 3px 6px);
}

/* Motion hooks. A field that failed gets one short shake on top of its text
   and its aria-invalid; a heart the server just saved pops once. The script
   adds both classes; neither is ever set before the server answered. */
@keyframes rd-shake {
    0%,
    100% {
        transform: translateX(0);
    }

    20% {
        transform: translateX(-5px);
    }

    40% {
        transform: translateX(5px);
    }

    60% {
        transform: translateX(-3px);
    }

    80% {
        transform: translateX(3px);
    }
}

.rd .rd-shake,
.login-pop .rd-shake {
    animation: rd-shake 320ms var(--motion-ease) 1;
}

.login-pop .inp[aria-invalid="true"] {
    border-color: var(--danger);
}

.rd .rd-fav-pop {
    position: relative;
}

.rd .rd-fav-pop svg {
    animation: preview-favpop 420ms var(--motion-ease);
}

.rd .rd-fav-pop::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 2.1rem;
    height: 2.1rem;
    margin: -1.05rem 0 0 -1.05rem;
    border: 2px solid var(--heart);
    border-radius: var(--radius-md);
    pointer-events: none;
    animation: preview-burst 480ms var(--motion-ease) forwards;
}

/* Tooltips inside the redesigned pages: in after a short delay, out at once.
   The protected pages keep the long-standing tooltip motion. */
.rd .b7-info__bub {
    transition: none;
}

.rd .b7-info:hover .b7-info__bub,
.rd .b7-info:focus-visible .b7-info__bub {
    transition: opacity var(--motion-fast) var(--motion-ease) 120ms, transform var(--motion-fast) var(--motion-ease) 120ms;
}

.rd .b7-info[aria-expanded="true"] .b7-info__bub {
    transition: opacity var(--motion-fast) var(--motion-ease), transform var(--motion-fast) var(--motion-ease);
}

/* Header tooltips give way while a header overlay (menu, login window,
   account menu, rankings share popover) is open, so a tooltip never covers
   the overlay. The script sets the state class; this is the only rule of
   this block that reaches the header, and it only hides. */
.site-header.is-overlay-open .tip-bub {
    visibility: hidden;
}

/* Toasts and the toaster. New variants only; the long-standing toast, ok and
   err rules stay as they are. A redesign toast carries a text and a close
   button, and no pointer cursor, because it closes through its button. */
.b7-toast--rd {
    align-items: flex-start;
    cursor: default;
    outline: 1px solid transparent;
}

.b7-toast--info .b7-toast-icon {
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
    background: var(--accent-soft);
    color: var(--accent-text);
}

.b7-toast--warn .b7-toast-icon {
    border-color: color-mix(in srgb, var(--warning) 30%, transparent);
    background: var(--warning-soft);
    color: var(--warning);
}

/* A13: the B-7 toast body (.tbody, .ttitle, .tmsg, l.932-934): a short
   title in the heading weight above the message in the secondary colour. */
.b7-toast__body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
    padding-top: .15rem;
}

.b7-toast__title {
    margin: 0;
    font-size: .89rem;
    font-weight: var(--font-weight-heading);
    line-height: 1.3;
}

.b7-toast__text {
    margin: 0;
    color: var(--muted);
    font-size: .83rem;
    font-weight: normal;
    line-height: 1.4;
}

.b7-toast__close {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 1.4rem;
    height: 1.4rem;
    margin: .3rem 0 0 auto;
    padding: 0;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
    transition: color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.b7-toast__close::after {
    content: "";
    position: absolute;
    inset: -12px;
}

.b7-toast__close:hover {
    border-color: var(--muted);
    color: var(--foreground);
}

.b7-toast__close:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.b7-toast__close svg {
    width: .8rem;
    height: .8rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
}

.rd .rd-actions {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    min-width: 0;
}

.rd .rd-actions .btn {
    width: 100%;
}

.rd .rd-actions .btn--sm {
    min-height: 2.75rem;
}

/* R2: the account surfaces. Buttons first. A button in the main area gets the
   neutral surface look from the long-standing member rule, which is stronger
   than the B-7 button classes; these rules give a button the look its class
   names, and a secondary submit button of a form with fields keeps the quiet
   look instead of the primary gradient. */
.rd main button.btn {
    border-color: var(--border-control);
    background-color: var(--surface);
    background-image: none;
    color: var(--foreground);
}

.rd main button.btn:hover {
    background-color: var(--surface-2);
}

.rd main button.btn--sm {
    min-height: 2.2rem;
    padding: 0 .8rem;
    font-size: .84rem;
}

.rd main button.btn--danger {
    border-color: color-mix(in srgb, var(--danger) 32%, var(--border));
    color: var(--danger);
}

.rd main button.btn--danger:hover {
    border-color: var(--danger);
    background-color: var(--danger-soft);
}

.rd main button.btn--primary {
    border-color: transparent;
    background-color: var(--accent-gradient-from);
    background-image: linear-gradient(90deg, var(--accent-gradient-from) 0%, var(--accent-gradient-to) 50%, var(--accent-gradient-from) 100%);
    background-size: 200% 100%;
    background-position: 0% 50%;
    background-repeat: no-repeat;
    background-origin: border-box;
    color: var(--button-text);
}

.rd main button.btn--primary:hover {
    background-color: var(--accent-gradient-from);
}

.rd main form button.btn:not(.btn--primary)[type="submit"] {
    border-color: var(--border-control);
    background-color: var(--surface);
    background-image: none;
    color: var(--foreground);
}

.rd main form button.btn:not(.btn--primary)[type="submit"]:hover {
    background-color: var(--surface-2);
}

/* The danger button of a form keeps its danger look: the quiet submit rule
   above is as specific as it is, so these two repeat the danger colours. */
.rd main form button.btn.btn--danger[type="submit"] {
    border-color: color-mix(in srgb, var(--danger) 32%, var(--border));
    color: var(--danger);
}

.rd main form button.btn.btn--danger[type="submit"]:hover {
    border-color: var(--danger);
    background-color: var(--danger-soft);
}

.rd .rd-card :where(p, dl, ul, ol) {
    margin: 0;
}

.rd .rd-card form {
    display: grid;
    gap: var(--space-4);
    min-width: 0;
}

.rd .rd-card .field {
    margin: 0;
}

.rd main > .rd-bare {
    margin: 0 0 var(--space-4);
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.rd main > .rd-card,
.rd main > .rd-grid,
.rd main > .rd-preview {
    margin: 0 0 var(--space-4);
}

/* Page head: the title block, the status badges and the tab bar spacing. */
.rd .rd-head__title {
    display: grid;
    gap: .55rem;
    justify-items: start;
    min-width: 0;
}

.rd .rd-head__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    max-width: none;
    margin: 0;
}

.rd .rd-head__handle {
    color: var(--muted);
    font-weight: var(--font-weight-medium);
}

.rd .rd-head__lede .b7-info {
    margin-left: .15rem;
    vertical-align: .25em;
}

.rd .b7-info::before {
    content: "";
    position: absolute;
    inset: -.5rem;
}

.rd .rd-head:has(+ .profile-tabs) {
    margin-bottom: var(--space-3);
}

.rd .rd-badge .ico {
    width: .85rem;
    height: .85rem;
}

/* Account sidebar: a quiet group label and a decorative icon per entry. The
   current entry keeps its accent frame and soft fill; NK13 (operator list
   2026-10-23) removed the gradient stripe at its left edge. The state stays
   aria-current (with forced colours: the system frame of the entry). */
.rd .b7-side-nav .b7-side-group {
    margin: .25rem .7rem .5rem;
    color: var(--text-faint);
}

.rd .b7-side-link {
    position: relative;
    gap: .65rem;
}

.rd .b7-side-link .ico {
    color: var(--text-faint);
}

.rd .b7-side-link:hover .ico,
.rd .b7-side-link[aria-current="page"] .ico {
    color: var(--accent-text);
}

.rd .b7-side-link[aria-current="page"] {
    background: var(--accent-soft);
}

.rd .b7-side-logout .b7-side-link {
    color: var(--muted);
}

/* Overview tiles keep the plain list of the long-standing markup (a list of
   links with a number); here it is drawn as the stat tiles. The whole tile is
   the link through the stretched label. */
.rd main .b7-tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-5);
}

.rd main .b7-tiles > li:last-child {
    grid-column: 1 / -1;
}

.rd main .b7-tiles > li.rd-stat {
    position: relative;
    gap: .3rem;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.rd .rd-stat > a {
    flex: 1 1 auto;
    align-content: end;
    color: var(--text-faint);
    font-size: .73rem;
    letter-spacing: .07em;
    text-decoration: none;
    text-transform: uppercase;
}

.rd .rd-stat > a::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--radius-lg);
}

.rd .rd-stat:has(> a:focus-visible) {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.rd .rd-stat .b7-tile-value {
    font-family: var(--font-family-num);
    font-size: 1.45rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.03em;
    line-height: 1.2;
}

.rd .rd-stat > .rd-more {
    padding-top: .3rem;
    font-size: .95rem;
}

/* NK11 (operator list 2026-10-23): the "Earn points" tile. Its title reads
   like the label of the other tiles; the arrow link "Invite others" (the
   B-7 arrow link of the platforms page) is the link and still covers the
   whole tile. */
.rd .rd-stat--cta > .rd-stat__title {
    flex: 1 1 auto;
    align-content: end;
    color: var(--text-faint);
    font-size: .73rem;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.rd .rd-stat--cta > a.platforms-cta-link {
    flex: none;
    align-self: start;
    padding-top: .3rem;
    color: var(--accent-text);
    font-size: .95rem;
    letter-spacing: normal;
    text-transform: none;
}

.rd .rd-next {
    font-size: 1.02rem;
}

.rd .rd-note {
    max-width: none;
    color: var(--muted);
    font-size: .84rem;
}

.rd .rd-quiet {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.rd .rd-quiet:hover {
    text-decoration: underline;
    text-underline-offset: .2em;
}

/* The checklist: an icon box, the label and, below it, the step's own link. */
.rd .b7-start > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    min-height: 2.75rem;
    list-style: none;
}

.rd .b7-start > summary::-webkit-details-marker {
    display: none;
}

.rd .b7-start > summary > h2 {
    margin: 0;
    font-size: 1.04rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

/* A45 (Q45.7): the chevron on the right is the stacked pair of the rankings
   filter (partials/select-chev) instead of a turning single chevron: the
   upper one gains weight and the lower one fades while the checklist is
   open, as on the share dropdown. */
.rd .b7-start > summary .b7-fsw-chev {
    margin-right: .2rem;
}

.rd .b7-start > summary .filter-chev-up {
    opacity: .55;
}

.rd .b7-start[open] > summary .b7-fsw-chev {
    color: currentColor;
}

.rd .b7-start[open] > summary .filter-chev-up {
    opacity: 1;
}

.rd .b7-start[open] > summary .filter-chev-down {
    opacity: .3;
}

.rd .rd-checklist {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rd .rd-check {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: .75rem;
    row-gap: .15rem;
    align-items: center;
    max-width: none;
    margin: 0;
    padding: .65rem 0;
    border-top: 1px solid var(--border);
}

.rd .rd-check:first-child {
    border-top: 0;
}

.rd .rd-check__icon {
    display: grid;
    grid-row: span 2;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-faint);
    outline: 1px solid transparent;
}

.rd .rd-check--done .rd-check__icon {
    border-color: color-mix(in srgb, var(--positive) 30%, transparent);
    background: var(--positive-soft);
    color: var(--positive);
}

.rd .rd-check__label {
    min-width: 0;
    font-size: .93rem;
}

.rd .rd-check--done .rd-check__label {
    color: var(--muted);
}

.rd .rd-check > a {
    grid-column: 2;
    justify-self: start;
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
}

/* Missing profile fields as chips that jump to the field. */
.rd .rd-missing {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    max-width: none;
}

.rd .rd-missing__prefix {
    margin-right: .2rem;
    color: var(--muted);
    font-size: .84rem;
}

.rd .rd-missing a.chip {
    min-height: 2.2rem;
    text-decoration: none;
}

/* Activity: the time in its own column on wide screens. */
.rd .rd-activity {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rd .rd-activity > li {
    display: grid;
    gap: .15rem;
    max-width: none;
    margin: 0;
    padding: .7rem 0;
    border-top: 1px solid var(--border);
}

.rd .rd-activity > li:first-child {
    border-top: 0;
}

.rd .rd-activity time {
    white-space: nowrap;
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .78rem;
    font-variant-numeric: tabular-nums;
}

.rd .rd-activity__body {
    min-width: 0;
    font-size: .93rem;
}

.rd .rd-sep--time {
    display: none;
}

.rd .rd-empty--flat {
    border: 0;
    background: none;
    box-shadow: none;
}

.rd .rd-pager {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    max-width: none;
    margin: 0;
}

.rd .rd-pager .btn {
    min-height: 2.75rem;
}

/* Fields of the account forms. */
.rd .rd-field-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin: 0 0 .35rem;
}

.rd .rd-field-head label {
    margin: 0;
}

.rd .rd-field-head__aside {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}

.rd .rd-field-note {
    max-width: none;
    margin: .35rem 0 0;
    color: var(--text-faint);
    font-size: .78rem;
}

.rd .field :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea) {
    margin-bottom: 0;
}

.rd main .rd-fieldset {
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.rd main fieldset.rd-attrs {
    display: grid;
    gap: var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.rd .rd-attrs__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}

.rd .rd-label {
    display: block;
    margin: 0 0 .35rem;
    font-size: .83rem;
    font-weight: var(--font-weight-medium);
}

.rd .rd-value {
    font-weight: var(--font-weight-medium);
}

.rd .rd-pick input[type="radio"] {
    flex: none;
    margin: .2rem 0 0;
}

.rd .rd-pick strong {
    display: block;
}

.rd .rd-saved {
    color: var(--muted);
}

.rd .rd-kv {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .15rem;
}

.rd .rd-kv dd {
    margin: 0 0 .5rem;
}

.rd .rd-source-title {
    font-weight: var(--font-weight-heading);
}

.rd .rd-facts {
    display: grid;
    gap: var(--space-3);
    padding: 0;
    list-style: none;
}

.rd .rd-facts > li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: .65rem;
    align-items: start;
    max-width: none;
    margin: 0;
    font-size: .89rem;
}

.rd .rd-facts__icon {
    display: grid;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--accent-text);
    outline: 1px solid transparent;
}

/* The preview frame: the public profile component inside a dashed inset
   with a "Preview" badge, so it is never mistaken for the live page. */
.rd .rd-preview {
    display: grid;
    gap: var(--space-4);
    padding: var(--space-5);
    border-style: dashed;
    border-color: var(--border-control);
    outline: 1px solid transparent;
}

.rd .rd-preview__badge {
    justify-self: start;
}

.rd .logo.logo--img {
    border-color: transparent;
    background: none;
}

/* Row cards of the link list: a link has no rank and no click figure, so the
   value zone only carries the position choice. Without it (a single link) the
   row has no value zone at all. */
.rd .rd-rows,
.rd .rd-minis {
    display: grid;
    gap: var(--space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.rd .rd-rows > li,
.rd .rd-minis > li {
    max-width: none;
    margin: 0;
}

.rd .rd-minis {
    gap: .4rem;
}

.rd main form.rd-rows-form:not([hidden]) {
    display: grid;
    gap: var(--space-4);
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
}

.rd .rd-row.rd-row--novalue {
    grid-template-areas:
        "logo main"
        "actions actions";
}

.rd .rd-row .rd-row__value {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
}

.rd .rd-row__logo .ico {
    color: var(--accent-text);
}

/* Saved items: a compact card row with the heart that removes the item. */
.rd .rd-fav {
    display: flex;
    align-items: center;
    gap: .35rem;
    min-width: 0;
    padding: .15rem .3rem .15rem 0;
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-card-shadow);
    outline: 1px solid transparent;
    transition: border-color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease);
}

.rd .rd-fav > .rd-mini {
    flex: 1 1 auto;
    min-height: 3.25rem;
    padding-left: .85rem;
    background: transparent;
}

.rd .rd-fav form {
    display: block;
    margin: 0;
}

/* UI20 (operator order 2026-10-24): in the Cards tab of Favorites a hovered,
   tapped or pressed card lights its whole frame, the heart's area included,
   on every device (SH-14 did so only on a device that hovers, so a phone
   framed the inner link alone). The inner link then adds no frame, no fill
   and no tap highlight of its own; focus keeps N6 (the card's shadow and the
   ring of the focused link or heart). The Profiles tab is unchanged. */
.rd .rd-minis--fav-cards > .rd-fav > a.rd-mini {
    -webkit-tap-highlight-color: transparent;
}

.rd .rd-minis--fav-cards > .rd-fav > a.rd-mini:is(:hover, :active) {
    border-color: transparent;
    background: transparent;
}

.rd .rd-minis--fav-cards > .rd-fav:is(:hover, :active) {
    border-color: var(--accent-border);
}

.rd main button.rd-heart {
    display: inline-grid;
    place-items: center;
    width: 2.75rem;
    min-height: 2.75rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--heart);
}

/* U37 (operator list 2026-10-21): on the favourites page the heart shows a
   red border on hover. The heart exists only there. */
.rd main button.rd-heart:hover {
    border-color: var(--heart);
    background: var(--danger-soft);
}

.rd .rd-heart .ico {
    width: 1.15rem;
    height: 1.15rem;
    fill: currentColor;
}

.rd .rd-unavailable {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
}

.rd .rd-unavailable p {
    margin: 0;
}

.rd .rd-unavailable form {
    margin: 0;
}

.rd .rd-card__foot .btn {
    width: 100%;
}

.rd .rd-rows-form > .rd-card__foot {
    padding-top: 0;
    border-top: 0;
}

/* R3: the ranking cards, rewards and checkout surfaces. A head action with a
   tooltip, the form of a state changing head action and the plain alert
   paragraph of a refused step, which keeps its markup and gets the flash look. */
.rd .rd-head__action {
    display: flex;
    align-items: center;
    gap: .4rem;
    min-width: 0;
}

.rd .rd-head__action .btn {
    flex: 1 1 auto;
}

.rd .rd-head__actions form {
    display: block;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
}

.rd main > p[role="alert"]:where(:not(.rd-flash):not(.alert):not(.err)) {
    margin: 0 0 var(--space-4);
    padding: .85rem 1rem;
    border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
    border-radius: var(--radius-md);
    background: var(--danger-soft);
    color: var(--foreground);
    font-size: .89rem;
}

.rd .rd-card .auth-form {
    grid-template-columns: minmax(0, 1fr);
    max-width: none;
}

.rd main > .rd-stack,
.rd main > .rd-acc {
    margin: 0 0 var(--space-4);
}

.rd .rd-stack > h2 {
    margin: 0;
    font-size: 1.15rem;
    letter-spacing: -.02em;
}

.rd .rd-inset :is(h2, h3):where(:not(.listing *)) {
    margin: 0;
    font-size: .95rem;
    font-weight: var(--font-weight-heading);
}

.rd .rd-inset > p {
    margin: 0;
}

.rd .share-context-state {
    margin: 0;
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.rd .rd-text {
    color: var(--muted);
}

.rd .rd-stats--tight {
    margin: 0;
}

.rd .rd-stat > p {
    margin: 0;
}

.rd .rd-stat__value--big {
    font-size: 2rem;
}

.rd .rd-valuebig {
    display: grid;
    gap: .2rem;
}

/* A label and its value as two sibling paragraphs (the contract of the points
   pages): the first is the quiet label, the next one the figure. */
.rd .rd-pair {
    display: grid;
    gap: .2rem;
}

.rd .rd-pair > p {
    margin: 0;
    color: var(--text-faint);
    font-size: .73rem;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.rd .rd-pair > p + p {
    color: var(--foreground);
    font-family: var(--font-family-num);
    font-size: 1.45rem;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.03em;
    line-height: 1.2;
    text-transform: none;
}

.rd .rd-pair--big > p + p {
    font-size: 2rem;
}

/* Free or Sponsored and the free slot label (B-7 .lbl-origin): small, lean and
   all in the same look. The slot label has a quiet accent; it is not the
   Sponsored label. */
.rd .rd-origin {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    min-height: 1.25rem;
    padding: 0 .45rem;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--muted);
    font-size: .68rem;
    font-weight: var(--font-weight-medium);
    letter-spacing: .02em;
    line-height: 1;
    white-space: nowrap;
}

.rd .rd-origin--slot {
    border-color: var(--accent-border);
    background: var(--accent-soft);
    color: var(--accent-text);
}

/* The owner row: title and teaser first, then the value zone, then the facts
   (platform, category, created, link interactions, saved), then the actions.
   One column on a narrow screen; from 761px the value zone sits at the right. */
.rd .rd-row.rd-row--owner {
    grid-template-areas:
        "logo main"
        "value value"
        "facts facts"
        "actions actions";
}

.rd .rd-row__facts {
    grid-area: facts;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .9rem;
    min-width: 0;
    margin: 0;
    padding: 0;
    color: var(--text-faint);
    font-size: .8rem;
    list-style: none;
}

.rd .rd-row__facts li {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    margin: 0;
}

.rd .rd-row__value .rd-compose {
    flex: 1 1 100%;
}

.rd .rd-compose--mini {
    margin-top: .2rem;
}

.rd .rd-compose--mini .rd-compose__legend {
    flex-direction: column;
    gap: .15rem;
}

.rd .rd-compose__track {
    height: .7rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
}

/* Tables with a card alternative: on a narrow screen every row is a card, its
   cells labelled by the column heading (data-label); the heading row is hidden
   but stays for assistive technology. From 761px it is a real table. */
.rd .rd-table,
.rd .rd-table tbody,
.rd .rd-table tr,
.rd .rd-table :is(th, td) {
    display: block;
}

.rd .rd-table {
    width: 100%;
    font-size: .9rem;
}

.rd .rd-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.rd .rd-table tr {
    display: grid;
    gap: .35rem;
    margin: 0 0 var(--space-3);
    padding: var(--space-4);
    border: 1px solid var(--box-light-border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--box-light-shadow);
    outline: 1px solid transparent;
}

.rd .rd-table :is(th, td) {
    padding: 0;
    border: 0;
    font-weight: 400;
    text-align: left;
}

.rd .rd-table th[scope="row"] {
    color: var(--foreground);
    font-size: .95rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: normal;
    text-transform: none;
}

.rd .rd-table__actions .btn {
    min-height: 2.75rem;
    white-space: normal;
}

.rd .rd-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    color: var(--text-faint);
    font-size: .68rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.rd .rd-table__num {
    font-family: var(--font-family-num);
    font-variant-numeric: tabular-nums;
}

.rd .rd-table__actions form {
    display: inline-block;
    margin: .25rem .5rem .25rem 0;
    padding: 0;
    border: 0;
    background: none;
}

.rd .rd-table__actions form + form {
    margin-top: 0;
}

.rd .rd-table__actions > a {
    margin: .25rem 0;
}

.rd .rd-table__actions:not(:has(form, a)) {
    display: none;
}

.rd .rd-table__actions .rd-actions-pair {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: .5rem;
    max-width: 100%;
    margin: .25rem .5rem .25rem 0;
    vertical-align: top;
}

.rd .rd-table__actions .rd-actions-pair form {
    margin: 0;
}

.rd .rd-card .rd-table tr {
    box-shadow: none;
}

/* The owner record: the ranking value, the content, the URL and the lists. */
.rd .rd-card__head .logo {
    flex: none;
}

.rd .rd-linkbox {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .6rem;
    min-width: 0;
    min-height: 2.75rem;
    padding: .45rem .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    font-size: .89rem;
}

.rd .rd-linkbox__url {
    min-width: 0;
    color: var(--accent-text);
}

.rd .rd-attrs-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .6rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rd .rd-attrs-list li {
    display: grid;
    gap: .1rem;
    margin: 0;
    padding: .6rem .8rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.rd .rd-ctx,
.rd .rd-rules {
    display: grid;
    gap: .5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rd .rd-ctx li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .5rem;
    margin: 0;
    padding: .55rem 0;
    border-top: 1px solid var(--border);
}

.rd .rd-ctx li:first-child {
    border-top: 0;
}

.rd .rd-rules {
    padding-left: 1.1rem;
    list-style: disc;
}

.rd .rd-rules li {
    margin: 0;
}

.rd .rd-pick legend {
    margin: 0 0 .5rem;
    padding: 0;
    font-size: .83rem;
    font-weight: var(--font-weight-medium);
}

/* A legend that repeats the card heading above it stays for assistive
   technology and is not shown (the share page). */
.rd .rd-pick legend.visually-hidden {
    margin: -1px;
}

/* The copy box of the public card URL, the share panel and the referral link
   inside a card. A hidden copy button stays hidden until the script shows it. */
.rd .rd-card input[readonly] {
    width: 100%;
    min-width: 0;
}

.rd .rd-card .copy-target:not([hidden]) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    min-height: 2.2rem;
    padding: 0 .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    cursor: pointer;
}

.rd .rd-card .copy-target:not([hidden]):hover {
    background: var(--surface-2);
}

.rd .rd-card .copy-target-status {
    margin-left: .5rem;
    color: var(--muted);
    font-size: .84rem;
}

.rd .rd-card [data-public-card-invite-label]:not([hidden]) {
    display: grid;
    gap: .25rem;
}

.rd .rd-card [data-public-card-invite-label]:not([hidden]) > label {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-weight: 400;
}

.rd .rd-card > .share-box {
    display: grid;
    gap: .55rem;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
}

.rd .rd-card .share-box h2 {
    margin: 0;
    font-size: .95rem;
}

.rd .rd-card .share-box .share-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .45rem;
}

.rd .rd-card .share-box .share-actions > :not([hidden]) {
    flex: 1 1 0;
    min-width: max-content;
    margin-left: 0;
    justify-content: center;
}

.rd .rd-card .share-box :is(button, a.copy-target):not([hidden]) {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    min-height: 2.2rem;
    padding: 0 .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    cursor: pointer;
}

.rd .rd-card .share-box input {
    margin: 0;
}

.rd .rd-card .share-box .chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .55rem;
    margin: .5rem 0 0;
}

/* A centred system style card (payment return, invoice unavailable): an icon
   box, a badge, the headline, a sentence and the way on. */
.rd .rd-center {
    width: min(40rem, 100%);
    margin: var(--space-6) auto;
    justify-items: center;
    text-align: center;
}

.rd .rd-center h1 {
    margin: 0;
    font-size: clamp(1.4rem, 4vw, 1.7rem);
    font-weight: var(--font-weight-heading);
    letter-spacing: -.03em;
}

.rd .rd-center .rd-inset {
    width: 100%;
}

.rd .rd-center p {
    max-width: 46ch;
    margin: 0;
    color: var(--muted);
}

/* The fact box of the payment return page: each term and its value share one
   centred line over the full width of the box, in one column at every width
   (the generic definition list of the member surface is overridden here only). */
.rd .rd-center .rd-return-facts { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); width: 100%; margin: 0; text-align: center; }
.rd .rd-center .rd-return-facts dt,
.rd .rd-center .rd-return-facts dd { display: inline; margin: 0; font-size: .89rem; }
.rd .rd-center .rd-return-facts dt { color: var(--muted); }
.rd .rd-center .rd-return-facts dd { color: var(--foreground); font-weight: var(--font-weight-medium); }

.rd .rd-center .rd-actions {
    justify-content: center;
}

.rd .rd-icon-box {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--accent-text);
    outline: 1px solid transparent;
}

/* Checkout: the information as a definition list, the consent inset with the
   two checkboxes and the privacy sentence. */
.rd .rd-dl {
    display: grid;
    gap: .25rem;
    margin: 0;
}

.rd .rd-dl dt {
    margin: var(--space-3) 0 0;
    font-size: .93rem;
    font-weight: var(--font-weight-heading);
}

.rd .rd-dl dt:first-child {
    margin-top: 0;
}

.rd .rd-dl dd {
    margin: 0;
    color: var(--muted);
    font-size: .89rem;
}

.rd .rd-consent {
    display: grid;
    gap: var(--space-3);
}

.rd .rd-consent__item {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: .35rem .4rem;
    min-width: 0;
}

/* Order 2026-10-29, point 18: the Terms and Conditions link is part of the
   label text (a click on the link opens the Terms and never toggles the
   box), so both consent lines share one layout and their error messages
   start at the edge of the checkbox. The former rules of a link beside the
   label (U61.02 and its line rules) are gone. */
.rd .rd-consent__item > .err {
    flex: 1 1 100%;
}

/* R4: the login pages. A centred 30rem card (the long-standing login main
   element), an icon box, the headline and one line of intent. The code step
   has no stepper: the heading above the field is its visible label, the six
   boxes shrink so they fit a 360px screen, and the plain code field of the
   no-script page is centred in the same large figures. A wrong code shakes
   once on top of its error text. */
.rd.surface--auth main {
    text-align: center;
}

.rd.surface--auth main h1 {
    margin: 0 0 .4rem;
    font-size: clamp(1.5rem, 4vw, 1.8rem);
    letter-spacing: -.035em;
    line-height: 1.15;
}

.rd .rd-auth__icon {
    margin: 0 auto var(--space-3);
}

.rd .rd-auth__lede {
    max-width: 34ch;
    margin: 0 auto var(--space-4);
    color: var(--muted);
}

.rd .rd-auth__heading {
    margin: var(--space-4) 0 var(--space-3);
    font-size: 1.04rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
    text-align: center;
}

.rd.surface--auth main .auth-form {
    grid-template-columns: minmax(0, 1fr);
    text-align: left;
}

.rd.surface--auth main .field > .err {
    justify-content: center;
    text-align: center;
}

.rd.surface--auth main .auth-form .field {
    margin-bottom: 0;
}

/* UI-07 (operator decision 2026-10-21): on the login page only, the
   remember line keeps just the gap of the form grid above and below it; its
   privacy link is not underlined, but stays recognisable by the accent
   colour and the medium weight, and is underlined again on hover and on
   keyboard focus (the focus ring stays). The header login window keeps its
   own line unchanged. */
.rd.surface--auth main .login-remember {
    margin: 0;
}

.rd.surface--auth main .login-remember a {
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.rd.surface--auth main .login-remember a:is(:hover, :focus-visible) {
    text-decoration: underline;
}

.rd.surface--auth main .field > input:not([hidden]) {
    width: 100%;
}

.rd .login-code-digits {
    flex-wrap: nowrap;
    justify-content: center;
    gap: .45rem;
    margin: 0 0 .35rem;
}

.rd .login-code-digits input[type="text"] {
    flex: 1 1 0;
    width: 0;
    min-width: 0;
    max-width: 3.1rem;
    min-height: 3.25rem;
    font-family: var(--font-family-num);
    font-size: 1.35rem;
    font-variant-numeric: tabular-nums;
}

.rd .login-code-form input[name="code"] {
    text-align: center;
    font-family: var(--font-family-num);
    font-size: 1.35rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: .35em;
}

/* A09: the resend button is the light B-7 button (.btn) with the hint line
   above it. P1 / A09 (order 2026-11-02): it looks the same with and without
   a code error; there is no accent edge. */
.rd .rd-auth__resend-hint {
    margin: var(--space-3) 0 0;
    text-align: center;
}

.rd .rd-auth__resend-hint + .login-page-submit {
    margin-top: var(--space-2);
}

/* Order 2026-11-04 (F5), narrowed by P1 / A09 (order 2026-11-02, operator
   decision replacing F5-c): the two states of the resend button, scoped to
   this one button. The frame is the frame of the "Use a different email"
   disclosure below (its --border-control at 45 % over the card surface).
   (a) While the countdown runs (disabled) the text is lighter than the
       active text; (b) once it ended, the text is the disclosure text
       (--text-faint). A code error changes neither state: no blue frame and
       no blue text; the error stays at the code field. The colours are
       explicit, so the opacity of a disabled .btn stays 1; hover changes
       only the background and the focus ring stays the global one. */
.rd main form.auth-form button.btn.rd-auth__resend[type="submit"] {
    border-color: color-mix(in srgb, var(--border-control) 45%, var(--surface));
    color: var(--text-faint);
}

.rd main form.auth-form button.btn.rd-auth__resend[type="submit"]:disabled {
    opacity: 1;
    color: color-mix(in srgb, var(--text-faint) 60%, var(--surface));
}

/* A11: the switch to another email is a quiet disclosure without a resting
   or a hover shadow (.rd-static keeps it out of the lift rules); the focus
   ring of its summary stays.
   Order 2026-10-29, point 16 (B10): on the login page the switch reads as a
   secondary option. Its frame takes the colour the "Resend email in …"
   button shows while it counts down (its --border-control frame at the .45
   opacity of a disabled button over the card surface); its text and plus
   sign take --text-faint, the lightest text colour of the page (not the
   faded colour of the disabled countdown text itself). The opacity of the
   whole control stays 1; hover and the focus ring stay as for every
   accordion. */
.rd .rd-auth__switch {
    margin-top: var(--space-4);
    border-color: color-mix(in srgb, var(--border-control) 45%, var(--surface));
    text-align: left;
    box-shadow: none;
}

.rd .rd-auth__switch > summary {
    color: var(--text-faint);
}

/* D-2 (U18.07): the two answers of the agreement step side by side, Sign out
   (light) on the left and Continue (primary) on the right, each half of the
   row (the B-7 .row with a fixed single line). */
.rd .rd-auth__choice {
    flex-wrap: nowrap;
    margin-top: var(--space-4);
}

.rd .rd-auth__choice > form,
.rd .rd-auth__choice > .btn {
    flex: 1 1 0;
    min-width: 0;
}

.rd .rd-auth__choice > form .btn {
    width: 100%;
}

.rd .login-consent-agree {
    margin: 0;
    text-align: left;
}

/* The centred narrow card of the guest pages and the form inside it. */
.rd .rd-center.rd-center--narrow {
    width: min(30rem, 100%);
}

.rd .rd-center .rd-form-left {
    justify-self: stretch;
    width: 100%;
    text-align: left;
}

.rd .rd-center .rd-form-left button.btn {
    width: 100%;
}

/* The report page: the link title in a quiet box, the closed categories as
   choice cards. */
.rd main > .rd-card.rd-confirm {
    margin: var(--space-5) auto var(--space-4);
}

.rd main > .rd-card.rd-center {
    margin: var(--space-6) auto var(--space-4);
}

.rd .rd-card .contact-form {
    gap: var(--space-4);
}

.rd .rd-confirm h1 {
    margin: 0;
    font-size: clamp(1.4rem, 4vw, 1.7rem);
    font-weight: var(--font-weight-heading);
    letter-spacing: -.03em;
    text-align: center;
}

.rd .rd-confirm > p {
    max-width: none;
}

.rd .rd-report__link {
    margin: 0;
    font-weight: var(--font-weight-heading);
}

.rd .rd-confirm form.auth-form button.btn {
    width: 100%;
}

.rd .rd-confirm > p:last-child {
    text-align: center;
}

/* The public profile: the head card with the logo, the name block and the
   aside (saved count, heart, jump to the share box), then the tabs and the
   row cards. The picture has no tile behind it; the letter tile keeps its
   fill. */
.rd .rd-profile-head {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: var(--space-3) var(--space-4);
}

.rd .rd-profile-head__main {
    display: grid;
    gap: .4rem;
    align-content: start;
    min-width: 0;
}

/* U3: the title row. The username is the big headline, the @handle sits beside
   it, smaller and muted; on a narrow screen the handle may wrap below it. */
.rd .rd-profile-head__titlerow {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .1rem .65rem;
    min-width: 0;
}

.rd .rd-profile-head__main :is(h1, h2) {
    min-width: 0;
    margin: 0;
    font-size: clamp(1.7rem, 4.6vw, 2.2rem);
    font-weight: var(--font-weight-heading);
    letter-spacing: -.035em;
    line-height: 1.15;
}

.rd .rd-profile-head__handle {
    min-width: 0;
    color: var(--muted);
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
}

/* NK03 (operator list 2026-10-23): the saved chip as well, so the
   preview's inset paragraph margin (.rd .rd-inset p) no longer lifts it
   above the location chip. */
.rd .rd-profile-head__main :is(.profile-bio, .profile-location, .profile-saved) {
    margin: 0;
}

.rd .rd-profile-head__main .profile-location {
    display: flex;
}

.rd .rd-profile-head__main .profile-location .chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    max-width: 100%;
}

.rd .rd-profile-head__main .profile-location .chip > span {
    white-space: nowrap;
}

.rd .logo--fallback {
    color: var(--accent-text);
    font-size: 1.7rem;
}

.rd .rd-profile-head__aside {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    min-width: 0;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

.rd .rd-profile-head__aside .ranking-page {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
}

/* U3: the square share button (B-7 .sharebtn, the look of the rankings share
   button). Open, it carries the accent. Without the script it stays hidden. */
.rd .rd-sharebtn:not([hidden]) {
    display: inline-grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}

.rd .rd-sharebtn[aria-expanded="true"] {
    border-color: var(--accent);
    background-color: var(--accent-soft);
    color: var(--accent-text);
}

/* U3: without the script the share box is the last part of the head card, under
   a hairline. With it, it is the popover: below the button, inside the card on a
   narrow screen (the card is the anchor), at the button from the wider grid on. */
.rd .rd-profile-head > .share-box {
    grid-column: 1 / -1;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

.rd .rd-profile-share.is-popover .share-box {
    top: auto;
    right: var(--space-3);
    left: var(--space-3);
    width: auto;
    max-width: none;
    margin-top: .5rem;
}

/* A39 (PK3): the chip row of the name block: the location chip and, at its
   right, the saved count as a chip of its own, the heart icon and the text on
   one line; on a narrow screen the second chip wraps below the first. */
.rd .rd-profile-head__chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    min-width: 0;
}

.rd .rd-profile-head__chips > p {
    display: flex;
    min-width: 0;
    max-width: 100%;
    margin: 0;
}

/* UI-06 (operator decision 2026-10-21): the saved count chip carries the
   colour role of the location chip beside it (muted); the heart icon draws
   in currentColor and follows it in both themes. */
.rd .rd-profile-head__main .profile-saved .chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    color: var(--muted);
    white-space: nowrap;
}

/* The aside without a shown share button and without the heart (a guest
   without the script) is not drawn: no empty bar under the name block. */
.rd .rd-profile-head__aside:not(:has(.rd-sharebtn:not([hidden]), .ranking-fav-form)) {
    display: none;
}

.rd main.profile-page > .rd-card,
.rd main.profile-page > .profile-tabs {
    margin: 0;
}

/* A34 (PK3): a link card of a profile has three areas: the logo, the title
   column and, at the right, the small type pill, vertically centred to the
   whole card. */
.rd .profile-card-list > .rd-row.rd-row--novalue {
    grid-template-columns: 3.4rem minmax(0, 1fr) auto;
    grid-template-areas: "logo main kind";
}

.rd .profile-card-list .rd-row__title {
    color: var(--foreground);
}

.rd .profile-card-list .rd-row__stats li {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.rd .rd-row__report {
    position: relative;
    margin: 0;
}

.rd .rd-row__report a {
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
    color: var(--muted);
}

.rd .rd-row__report a:hover {
    color: var(--accent-text);
}

/* Content pages: contact (the form beside "Other ways to reach us"), the
   about limits as an icon list, the FAQ list "On this page" and the legal
   reading pages. */
.rd .info-page:has(> .rd-detail),
.rd .info-page:has(> .rd-toc-layout) {
    max-width: 55rem;
}

.rd .rd-icon-box--sm {
    flex: none;
    width: 2.2rem;
    height: 2.2rem;
    border-color: var(--border-strong);
}

.rd :is(.rd-mini__logo, .rd-icon-box--sm):has(> img:not([hidden])) {
    border-color: transparent;
}

.rd .rd-linkbox__text {
    display: grid;
    gap: .1rem;
    min-width: 0;
}

.rd .about-limits ul {
    display: grid;
    gap: .55rem;
    padding: 0;
    list-style: none;
}

.rd .about-limits li {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    max-width: none;
}

.rd .rd-bullet {
    flex: none;
    margin-top: .15rem;
    color: var(--accent-text);
}

.rd .rd-toc-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}

.rd .rd-toc-body {
    display: grid;
    gap: var(--space-4);
    min-width: 0;
}

/* UI02: a group of the FAQ is a grid item; it may become narrower than an
   overlong word in it, which then scrolls inside its paragraph (U53/K1)
   instead of widening the column. */
.rd .rd-toc-body > .listing-group {
    min-width: 0;
}

/* Order 2026-10-29, point 2: "On this page" is a quiet menu box (the muted
   box surface and the quiet frame of the statistics list tiles) with a
   divider between its entries; long entries wrap between their words. The
   FAQ list shows from 981px only (as before); the Rules list also stands
   above the text below 981px (.rd-toc-side--static-narrow), not sticky. */
.rd .rd-toc-side {
    display: none;
    min-width: 0;
    padding: var(--space-4);
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--box-muted-bg);
}

.rd .rd-toc-side.rd-toc-side--static-narrow {
    display: block;
}

.rd .rd-toc-side__title {
    margin: 0 0 .6rem;
    color: var(--text-faint);
    font-size: .73rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .08em;
    text-transform: uppercase;
}

.rd .rd-toc-side ol {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rd .rd-toc-side li {
    min-width: 0;
    margin: 0;
    padding: .45rem 0;
    font-size: .9rem;
}

.rd .rd-toc-side li:first-child {
    padding-top: 0;
}

.rd .rd-toc-side li:last-child {
    padding-bottom: 0;
}

.rd .rd-toc-side li + li {
    border-top: 1px solid var(--border-quiet);
}

.rd .rd-toc-body > .listing-group,
.rd .rd-legal-section :is(h2, h3) {
    scroll-margin-top: calc(var(--header-height) + 1rem);
}

.rd .rd-toc__list {
    display: grid;
    gap: .4rem;
    margin: 0;
    padding: 0;
    /* The list adds no numbers of its own (and since 2026-10-29, point 17,
       the link texts carry none either). */
    list-style: none;
}

.rd .rd-toc__list li {
    margin: 0;
}

.rd .rd-toc__list a {
    text-decoration: none;
}

.rd .rd-toc__list a:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.rd .rd-toc__list a:focus-visible {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* UI02: the paragraphs and list items of the legal documents use the full
   width of their section (the former 72ch cap is gone). Text breaks only
   between whole words (U53/K1): an overlong URL or word scrolls sideways
   inside its paragraph instead of widening a narrow screen. A list item
   keeps a visible overflow, so its outside marker is never clipped. */
.rd .rd-legal-section :is(p, li) {
    line-height: 1.65;
}

.rd .rd-legal-section p {
    overflow-x: auto;
}

.rd .rd-legal-section .rd-address {
    margin: 0 0 var(--space-3);
    padding-bottom: var(--space-4);
}

.rd .rd-listing-create {
    margin-top: var(--space-4);
}

/* Design QA round 2. */

/* Form cards: a grid item never grows past its card, so a file input or a
   long word wraps inside the field and the page does not scroll sideways. */
.rd .rd-card .auth-form > * {
    min-width: 0;
}

.rd .b7-drop {
    min-width: 0;
    max-width: 100%;
    margin: 0;
}

.rd .b7-drop > * {
    min-width: 0;
    max-width: 100%;
}

.rd main .b7-drop input[type="file"] {
    width: 100%;
    min-width: 0;
    max-width: 100%;
}

.rd .b7-drop > p {
    color: var(--text-faint);
    font-size: .78rem;
}

/* Image field with the script: the native file input stays the one input and
   the label target, but is clipped out of sight; a button opens it and a line
   names the chosen file. Without the script the native input stays visible. */
.rd .b7-drop.is-enhanced {
    position: relative;
}

.rd main .b7-drop.is-enhanced input[type="file"] {
    position: absolute;
    width: 1px;
    min-width: 0;
    max-width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    opacity: 0;
    pointer-events: none;
}

.rd .b7-drop__picker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    min-width: 0;
}

.rd .b7-drop__name {
    min-width: 0;
    color: var(--muted);
    font-size: .84rem;
}

/* The group legend of the card attributes sits inside the box, not on its
   frame line. */
.rd main fieldset.rd-attrs > legend {
    float: left;
    width: 100%;
    margin: 0 0 .25rem;
    padding: 0;
    font-size: 1.04rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

.rd main fieldset.rd-attrs > legend + * {
    clear: both;
}

/* Inset boxes: a quiet headline, tight text. */
.rd .rd-inset :is(h3, h4):where(:not(.listing *)) {
    margin: 0 0 .35rem;
    font-size: .95rem;
    font-weight: var(--font-weight-heading);
}

.rd .rd-inset p:where(:not(.listing *)) {
    margin: 0 0 .35rem;
    font-size: .89rem;
}

/* A37 (PK3): the text list indent is for plain lists only; a list of mini
   cards (.rd-minis) keeps the component's own zero padding and size, so its
   cards line up with the headline of the box. */
.rd .rd-inset ul:where(:not(.rd-minis)) {
    margin: 0;
    padding-left: 1.1rem;
    font-size: .89rem;
}

/* A37 (PK3): inside a box the mini cards take the box width and no more; a
   long title ends with an ellipsis inside its card instead of widening the
   list beyond the box. */
.rd .rd-inset > .rd-minis {
    grid-template-columns: minmax(0, 1fr);
}

.rd .rd-inset > :last-child {
    margin-bottom: 0;
}

/* The delete step: an accordion that still reads as a card. */
.rd .rd-acc--danger {
    border-color: color-mix(in srgb, var(--danger) 30%, var(--border));
    border-radius: var(--radius-lg);
    box-shadow: var(--box-light-shadow);
}

.rd .rd-acc--danger > summary {
    color: var(--danger);
}

.rd .rd-preview .profile-card-list {
    margin: 0;
    padding: 0;
}

/* The older listings page: its filter and create forms use the full width of
   their card or accordion. */
.rd .rd-card > .listing-filters,
.rd .rd-listing-create .auth-form {
    max-width: none;
    margin: 0;
}

.rd .rd-listing-create .auth-form {
    gap: var(--space-3);
}

.rd .listing-filters {
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

.rd .listing-filters .field {
    display: grid;
    gap: .35rem;
    align-content: start;
    min-width: 0;
}

.rd .listing-filters .rd-filter-actions {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

.rd .listing-filters .rd-filter-actions p {
    margin: 0;
}

/* An info icon after a card headline sits on the text line. */
.rd .rd-card__head :is(h2, h3) .b7-info {
    margin-left: .15rem;
    vertical-align: .3em;
}

/* A tip that is the sibling of the headline (not inside it) sits tight to the
   text and raised like the footnote mark of the headlines above. */
.rd .rd-card__head > :is(h2, h3) + .b7-info {
    align-self: start;
    margin-top: -.3rem;
    margin-right: auto;
    margin-left: -.6rem;
}

/* Profile card of the overview: the handle and the state on one line. */
.rd .rd-profile-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin: 0;
}

/* The checklist headline keeps the Done badge beside it. */
.rd .b7-start > summary > .rd-badge {
    margin-right: auto;
}

/* The foot of the overview: public rankings and, below the desktop width,
   the logout button as a small button on the same row. */
.rd .rd-end {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.rd .rd-end > p {
    max-width: none;
    margin: 0;
}

.rd main .b7-dash-logout button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.2rem;
    padding: 0 .8rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-size: .84rem;
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.rd main .b7-dash-logout button:hover {
    background: var(--surface-2);
}

/* The copy action inside the stored target URL box: the empty status line
   takes no room, and the category and industry chips of a frozen card sit
   below the text with the spacing of the other cards. */
.rd .rd-linkbox .copy-target-status:empty {
    display: none;
}

.rd .rd-card > .rd-locked-chips {
    margin-top: var(--space-3);
}

/* Boxes with something to operate. One rule for the whole redesign and for the
   public card page: a framed box that holds an operable element takes the
   shadow hover of the public card (the strong card shadow; the resting edge
   stays, nothing moves and no darker edge appears). Operable is the same list
   everywhere: a link with a target, a button that is not the info icon (N10:
   the info icon is a tooltip button, so a box whose only control is an info
   icon has no hover; the icon itself stays operable and focusable), a field
   other than a hidden one, a select, a text area or a summary, that is not
   hidden itself, not disabled, not inert and not inside a hidden or inert
   ancestor or the closed content of a details element. Hidden form data (a
   token field) therefore never lifts a box, and a pure information box has no
   hover. The
   hover itself sits in the single (hover: hover) block below, so a touch screen
   never keeps a lifted box. A box inside another framed box is a calm inner
   surface (the inset surface, no shadow, no lift of its own), so one pointer
   position never shows two strong shadows; the controls inside still fill on
   hover. A box that must never lift takes .rd-static. Keyboard focus inside a
   box gives the box the same shadow and never another edge (N6: focusing or
   clicking a control changes no box border; the mirror of
   .is-hover-lift:has(<operable list>:focus-visible)). A browser without :has() simply shows
   no lift. */
.rd :is(.rd-card, .rd-row, .rd-fav, .rd-acc, .rd-inset, .rd-empty, section.rd-stack:not(.rd-bare), .share-box) :is(.rd-row, .rd-card, .rd-acc, .rd-fav, .rd-linkbox, .rd-stat, .rd-empty) {
    background: var(--surface-2);
    box-shadow: none;
}

.rd .rd-preview :is(.rd-row, .rd-card) {
    background: var(--surface);
}

.rd :is(.rd-card, .rd-row, .rd-fav, .rd-acc, .rd-empty:not(.rd-empty--flat), section.rd-stack:not(.rd-bare), .share-box, .info-page .listing-group):not(.rd-static):not(:is(.rd-card, .rd-row, .rd-fav, .rd-acc, .rd-empty, section.rd-stack:not(.rd-bare), .share-box, .rd-inset:not(.rd-preview)) *):has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):focus-visible) {
    box-shadow: var(--shadow-card-strong);
}

/* U2 (UI block U, second phase). */

/* The overview profile card names the username in front of the handle. */
.rd .rd-profile-line__name {
    color: var(--foreground);
    font-weight: var(--font-weight-heading);
}

/* U4: the handle on the overview profile line is smaller than the username. */
.rd .rd-profile-line .rd-head__handle {
    font-size: .93rem;
}

/* U4: the two notes under "My ranking cards" read as one note group. */
.rd .rd-stack--notes {
    display: grid;
    gap: .35rem;
    margin: .84rem 0;
}

.rd .rd-stack--notes > .rd-note {
    margin: 0;
}

/* U4: the note under a single-category select keeps a little air from the field. */
.rd .field > .fsel + .rd-note {
    margin-top: .4rem;
}

/* Facet pills of a ranking card row and of a profile card (the public pill look
   of .rankshell-meta, a little lower), then the small type pill of a link row
   at the height of the status badge next to it. */
.rd .rd-row__pills {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    min-width: 0;
}

.rd :is(.rd-row__pills, .rd-row__meta) > .chip.rankshell-meta {
    min-height: 0;
    padding: .2rem .55rem;
    font-size: .735rem;
    line-height: 1.2;
}

/* A34 (PK3): the type pill of a link card in its own area at the right of the
   card, vertically centred to the upper content area (the whole card without
   an action row); a long title wraps in its own column
   at the left. Below 761px a long label wraps inside the narrow pill; from
   761px the pill keeps its whole label on one line (no cap, below). */
.rd .profile-card-list .rd-row__kind {
    grid-area: kind;
    align-self: center;
    justify-self: end;
    max-width: 6rem;
}

/* A34 (PK3, operator decision 2026-10-17): with shown actions a narrow card
   keeps its upper content area (logo, title column, type pill at the right,
   centred to that area) and puts Copy and Share into an action row of their
   own below it: side by side at the right, behind a divider line. Without a
   shown action there is no row. From 761px the actions take their column at
   the right again (in the 761px block). */
.rd .profile-card-list > .rd-row.rd-row--novalue:has(> .rd-row__linkacts:not([hidden])) {
    grid-template-columns: 3.4rem minmax(0, 1fr) auto;
    grid-template-areas:
        "logo main kind"
        "acts acts acts";
}

.rd .profile-card-list .rd-row__linkacts {
    grid-area: acts;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: .8rem;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

/* The cards of a profile (public page and owner preview) use the full width of
   their list: the line length limit of plain list items does not apply to a
   card, and the stats list of a card inside the preview inset keeps no indent. */
.rd .profile-card-list > .rd-row {
    max-width: none;
}

.rd .rd-inset .rd-row__stats {
    padding: 0;
}

/* The owner detail stats get the icons of the public card stats, no label. */
.rd .rd-row__stats--icons {
    color: var(--text-faint);
    font-size: .8rem;
}

.rd .rd-row__stats--icons li {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}

/* A stat tile with an info icon: the icon sits at its top right (the mirror of
   .pv-stat > .b7-info) and its bubble opens towards the left inside the tile
   width. */
.rd .rd-stat:has(> .b7-info) {
    container-type: inline-size;
}

.rd .rd-stat > .b7-info {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    margin: 0;
    vertical-align: baseline;
}

.rd .rd-stat > .b7-info .b7-info__bub {
    right: -.35rem;
    left: auto;
    max-width: min(19rem, 100cqw);
    transform: translateY(4px);
}

.rd .rd-stat > .b7-info:is(:hover, :focus-visible, [aria-expanded="true"]) .b7-info__bub {
    transform: none;
}

.rd .rd-stat:has(> .b7-info) > .rd-stat__label {
    padding-right: 1.6rem;
}

/* The Status box of a link: Activate or Deactivate beside the secondary
   Delete, left aligned; the warning sits underneath. */
.rd .rd-card__foot--split {
    justify-content: flex-start;
}

.rd .rd-card__foot--split > form {
    flex: 0 1 auto;
    margin: 0;
}

.rd .rd-card__foot--split .btn {
    width: auto;
}

/* Target value control. The plain text field is all there is without the
   script. With it (is-enhanced) the field sits in one bordered box between a
   minus and a plus, behind the currency, its figure right aligned; below come
   the slider over the full width, its range note and the quick additions. */
.rd .rd-target__box {
    display: flex;
    align-items: stretch;
    min-width: 0;
}

.rd .rd-target__box > input {
    flex: 1 1 auto;
    min-width: 0;
}

/* A compact box: wide enough for the longest valid figure (USD 999,999 is
   six digits) with its unit, never a hard width, and the same on every screen. */
.rd .rd-target.is-enhanced .rd-target__box {
    width: 100%;
    max-width: 16rem;
    min-height: 2.75rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    outline: 1px solid transparent;
}

.rd .rd-target.is-enhanced .rd-target__box:has(> input:focus-visible) {
    border-color: var(--focus-neutral);
    background-color: var(--surface-2);
}

.rd .rd-target.is-enhanced .rd-target__box > input {
    min-height: 2.65rem;
    padding: 0 .75rem 0 .5rem;
    border: 0;
    border-radius: 0;
    background-color: transparent;
    font-family: var(--font-family-num);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.rd .rd-target.is-enhanced .rd-target__box > input:focus-visible {
    border-color: transparent;
    background-color: transparent;
    outline: none;
}

.rd .rd-target__unit:not([hidden]) {
    display: flex;
    align-items: center;
    padding-left: .25rem;
    color: var(--text-faint);
    font-size: .89rem;
    font-weight: var(--font-weight-medium);
}

.rd .rd-target__step:not([hidden]) {
    flex: none;
    display: grid;
    align-self: stretch;
    place-items: center;
    width: 2.65rem;
    margin: 0;
    padding: 0;
    border: 0;
    background-color: var(--surface-2);
    color: var(--accent-text);
    font: inherit;
    font-size: 1.2rem;
    font-weight: var(--font-weight-heading);
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease);
}

/* Each button is a recognisable button: its own surface and a divider toward
   the value; the outer corners follow the radius inside the box edge. */
.rd .rd-target__step:first-child {
    border-right: 1px solid var(--border-control);
    border-radius: calc(var(--radius-md) - 1px) 0 0 calc(var(--radius-md) - 1px);
}

.rd .rd-target__step:last-child {
    border-left: 1px solid var(--border-control);
    border-radius: 0 calc(var(--radius-md) - 1px) calc(var(--radius-md) - 1px) 0;
}

/* The sign sits 2px higher than the centre of the button, which looks low in
   this font; the button box and its hit area do not move. */
.rd .rd-target__step > span {
    position: relative;
    top: -2px;
}

/* Pressed: a clearly darker surface than the resting one. The extra
   :not([hidden]) lifts it above the hover fill, so a pressed button under the
   pointer is darker than a hovered one. */
.rd .rd-target__step:not([hidden]):active:not(:disabled) {
    background-color: var(--border-quiet);
}

.rd .rd-target__step:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: -3px;
}

.rd .rd-target__step:disabled {
    color: var(--text-faint);
    cursor: not-allowed;
}

.rd .rd-target__slider:not([hidden]) {
    display: grid;
    gap: .25rem;
    margin-top: var(--space-3);
}

.rd .rd-target__range {
    width: 100%;
    margin: 0;
    accent-color: var(--accent);
}

.rd .rd-target__slider > .rd-note {
    margin: 0;
}

.rd .rd-target__quick:not([hidden]) {
    display: flex;
    flex-wrap: wrap;
    gap: .45rem;
    margin-top: var(--space-3);
}

.rd .rd-target__quick > .btn {
    margin: 0;
}

/* The amount payable beside the target field (shown by the script, text only). */
.rd .rd-target__payable {
    margin: var(--space-3) 0 0;
    font-variant-numeric: tabular-nums;
}

.rd .rd-target__payable + .rd-note {
    margin: .25rem 0 0;
}

/* More ways to share, in a card of the owner pages: the padding of an
   accordion body, the targets as small buttons in one row that wraps, and no
   dots between them. */
.rd .rd-card .share-box .share-more > .chips {
    gap: .45rem;
    margin: 0;
    padding: 0 1rem 1rem;
}

.rd .rd-card .share-box .share-more > .chips > a.copy-target:not([hidden]) {
    gap: .35rem;
    min-height: 2.2rem;
    padding: 0 .6rem;
    font-size: .84rem;
}

.rd .rd-card .share-box .share-more > .chips > .share-target-sep {
    display: none;
}

/* 2026-10-14: the share targets of the account panel as a dropdown in the
   look of the filter option panel (.b7-fpanel, .b7-fopt). The closed summary
   keeps the row of the accordion; the open list floats under it with the
   highlighted "Share on" title and a divider above the targets. */
.rd .rd-card .share-box .share-more--drop {
    position: relative;
}

.rd .rd-card .share-box .share-more--drop::details-content {
    overflow: visible;
    transition: none;
}

.rd .rd-card .share-box .share-more--drop > summary::after {
    content: none;
}

/* Its chevron and its layer are set with the accordion rules of the share
   box in front of this block (the block itself turns and layers nothing). */
.rd .rd-card .share-box .share-more--drop > .share-drop {
    position: absolute;
    top: calc(100% + .35rem);
    left: 0;
    width: min(18.5rem, 100%);
    padding: .4rem;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
}

.rd .rd-card .share-box .share-drop__title {
    margin: 0;
    padding: .45rem .6rem .55rem;
    border-bottom: 1px solid var(--border);
    color: var(--foreground);
    font-size: .87rem;
    font-weight: var(--font-weight-heading);
}

.rd .rd-card .share-box .share-drop__list {
    display: grid;
    gap: .1rem;
    margin: .3rem 0 0;
    padding: 0;
    list-style: none;
}

.rd .rd-card .share-box a.share-drop__item {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: 2.75rem;
    /* Order 2026-10-29, point 8: 1.6rem in (was .95rem). */
    padding: .48rem .6rem .48rem 1.6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--foreground);
    font-size: .87rem;
    text-decoration: none;
    transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.rd .rd-card .share-box a.share-drop__item:hover,
.rd .rd-card .share-box a.share-drop__item:focus-visible {
    border-color: var(--border);
    background-color: var(--surface-2);
    color: var(--accent-text);
}

/* UI corrections N (2026-10-09). Shadows that the old nested rule would take away
   again are raised by scope, not by order: the account preview (the profile
   head card and the profile card rows inside the preview frame) and the owner
   rows of "My cards" keep the resting card shadow. The surfaces themselves
   are white through the separate block in front of this one. A33 (PK3): the
   link list of the preview is a bare list without a shadow of its own; only
   its rows carry the card shadow (and its hover and focus lift), so no row
   sits on a second shadow. */
.rd .rd-inset.rd-preview .rd-card.rd-profile-head,
.rd .rd-inset.rd-preview .profile-card-list > .rd-row.rd-row--novalue {
    box-shadow: var(--shadow);
}

/* AC-04 (UI package, 2026-10-12): the owner rows of "My ranking cards" rest
   without a shadow and take the normal card shadow on hover (below), a
   calmer lift than the strong one. Claim rank rows are not owner rows. */
.rd .rd-stack.rd-stack--cards .rd-row.rd-row--owner {
    box-shadow: none;
}

/* N9: the order control of the link list: one small bordered button with a
   chevron up and directly below it one with a chevron down, in a column at
   the right edge of the row. The row has no value zone any more. */
.rd .rd-rows-form .rd-row {
    grid-template-columns: 3.4rem minmax(0, 1fr) auto;
    grid-template-areas:
        "logo main move"
        "actions actions actions";
}

.rd .rd-row__move {
    grid-area: move;
    display: grid;
    gap: .3rem;
    align-content: start;
    justify-items: center;
}

/* A38 (PK3): an order button reads as a button, in the look of the steppers of
   the target total: a bordered box on the light surface token, close to its
   partner. NK14 (operator list 2026-10-23): the box is 1.5rem (24px) from
   761px and 1.75rem on a phone (below). UI-09 (operator decision
   2026-10-21): frame and chevron share the neutral --move-control ink, never
   the accent; hover, pressed and disabled keep their fills and the global
   focus ring. The touch target grows from the border box by .625rem at the
   sides and the outer edge and by .15rem toward the partner, so the two
   targets of a pair meet in the .3rem gap without overlapping: 2.75rem wide
   and 2.275rem high each. */
.rd .rd-move__btn {
    position: relative;
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 1px solid var(--move-control);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--move-control);
    cursor: pointer;
}

.rd .rd-move__btn::before {
    content: "";
    position: absolute;
    inset: -.625rem;
}

.rd .rd-move__btn--up::before {
    bottom: -.15rem;
}

.rd .rd-move__btn--down::before {
    top: -.15rem;
}

/* Pressed: the darker surface of a pressed stepper (the dark theme takes the
   page background, outside this block); the extra :not([hidden]) lifts it
   above the hover fill, so a pressed button under the pointer is darker than
   a hovered one. Only a visual state: nothing is sent or stored for it.
   UI-09: frame and chevron turn to the darker neutral --muted together, so
   they keep at least 3 : 1 on the pressed fill. */
.rd .rd-move__btn:not([hidden]):active:not(:disabled) {
    border-color: var(--muted);
    background-color: var(--border-quiet);
    color: var(--muted);
}

.rd .rd-move__btn:disabled {
    cursor: not-allowed;
    opacity: .5;
}

.rd .rd-move__btn .ico {
    width: .875rem;
    height: .875rem;
}

/* V-4: the ranking card of the public profile and of the owner preview is the
   card of the public list. In the member layout the plain element rules of
   ".surface main" (links, paragraphs, buttons) and, inside the preview frame,
   the text rules of ".rd-inset" (left alone for the card above) would restyle
   it; the few that still reach the card are switched back to what the list
   shows. The heart rules of the list are scoped to the list page, so the
   public profile gets the same ones for the card. */
.rd .rd-preview .listing p {
    max-width: none;
}

.rd .rd-preview .listing a.rankshell-facet:not(:hover),
.rd .rd-preview .listing a.rankshell-meta:not(:hover) {
    color: var(--muted);
}

.rd .rd-preview .listing button.preview-fav {
    min-height: auto;
}

.rd .rd-preview .listing .details-toggle {
    border: 0;
    background-color: transparent;
}

/* From 761px: the wider layouts of the components above. UI-10 (operator
   decision 2026-10-21): a select field keeps the 2.75rem of the light
   buttons (.btn) here too; the former A45 reduction to 2.2rem is gone. */
@media (min-width: 761px) {
    .rd .rd-head__top {
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: start;
    }

    .rd .rd-head__actions {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: flex-start;
        justify-content: flex-end;
    }

    .rd .rd-head__actions .btn {
        width: auto;
    }

    .rd .rd-crumbs li:not(.rd-crumbs__parent) {
        display: inline-flex;
    }

    .rd .rd-crumbs__parent::before {
        content: none;
    }

    .rd .rd-crumbs li + li::before {
        content: "\203A";
        color: var(--text-faint);
    }

    .rd .rd-grid--2 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: stretch;
    }

    .rd .rd-row {
        grid-template-columns: 3.4rem minmax(0, 1fr) minmax(9rem, 13rem);
        grid-template-areas:
            "logo main value"
            "logo actions value";
        padding: var(--space-4) var(--space-5);
    }

    .rd .rd-row__value {
        flex-direction: column;
        align-items: flex-end;
        justify-content: flex-start;
        padding: 0 0 0 var(--space-4);
        border-top: 0;
        border-left: 1px solid var(--border);
        text-align: right;
    }

    .rd .rd-row__actions {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .rd .rd-row__actions .btn {
        width: auto;
    }

    .rd .rd-actions {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .rd .rd-actions .btn {
        width: auto;
    }

    .rd .rd-actions .btn--sm {
        min-height: 2.2rem;
    }

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

    .rd main .b7-tiles {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    .rd main .b7-tiles > li:last-child {
        grid-column: auto;
    }

    .rd .rd-activity > li {
        grid-template-columns: max-content minmax(0, 1fr);
        gap: var(--space-4);
        align-items: baseline;
    }

    .rd .rd-pager .btn {
        min-height: 2.2rem;
    }

    .rd .rd-card__foot .btn {
        width: auto;
    }

    .rd .rd-confirm form.auth-form button.btn {
        width: auto;
    }

    .rd .rd-row.rd-row--novalue {
        grid-template-columns: 3.4rem minmax(0, 1fr);
        grid-template-areas:
            "logo main"
            "logo actions";
    }

    .rd .rd-row.rd-row--owner {
        grid-template-areas:
            "logo main value"
            "logo facts value"
            "logo actions value";
    }

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

    .rd .rd-stats--odd > .rd-stat--last {
        grid-column: auto;
    }

    .rd .rd-rows-form .rd-row {
        grid-template-columns: 3.4rem minmax(0, 1fr) auto;
        grid-template-areas:
            "logo main move"
            "logo actions actions";
    }

    .rd .rd-row--owner .rd-compose--mini .rd-compose__legend {
        align-items: flex-end;
    }

    .rd .rd-head__action .btn {
        flex: 0 0 auto;
    }

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

    .rd .rd-table {
        display: table;
        border-collapse: separate;
        border-spacing: 0;
        overflow: hidden;
        border: 1px solid var(--box-light-border);
        border-radius: var(--radius-lg);
        background: var(--surface);
        box-shadow: var(--box-light-shadow);
    }

    .rd .rd-card .rd-table {
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }

    .rd .rd-table thead {
        position: static;
        display: table-header-group;
        width: auto;
        height: auto;
        overflow: visible;
        clip-path: none;
        white-space: normal;
    }

    .rd .rd-table tbody {
        display: table-row-group;
    }

    .rd .rd-table tr {
        display: table-row;
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: none;
        box-shadow: none;
    }

    .rd .rd-table :is(th, td) {
        display: table-cell;
        padding: .7rem .85rem;
        border-bottom: 1px solid var(--border);
        vertical-align: middle;
        overflow-wrap: normal;
    }

    /* The row heading keeps a readable minimum width and only it may break
       inside a word; every other cell and the heading row wrap at spaces, so
       a long value never pushes the table past its card. */
    .rd .rd-table tbody th[scope="row"] {
        min-width: 8rem;
    }

    .rd .rd-table thead :is(th, td) {
        color: var(--text-faint);
        font-size: .73rem;
        font-weight: var(--font-weight-heading);
        letter-spacing: .08em;
        text-transform: uppercase;
    }

    .rd .rd-table tbody tr:last-child :is(th, td) {
        border-bottom: 0;
    }

    .rd .rd-table tbody tr:hover :is(th, td) {
        background: var(--surface-2);
    }

    .rd .rd-table td[data-label]::before {
        content: none;
    }

    .rd .rd-table__actions,
    .rd .rd-table__actions:not(:has(form, a)) {
        display: table-cell;
    }

    /* A width hint for the column of the invoice and receipt pair: the table
       gives it room for both buttons side by side while it has room and takes
       it back (the pair wraps) before the table would overflow. */
    .rd .rd-table__actions:has(.rd-actions-pair) {
        width: 24rem;
    }

    .rd .rd-center .rd-card__foot,
    .rd .rd-center .rd-actions {
        justify-content: center;
    }

    .rd .rd-row .rd-row__value {
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: flex-end;
        justify-content: flex-start;
    }

    .rd .rd-row__value > * {
        max-width: 100%;
    }

    .rd .rd-profile-head {
        grid-template-columns: auto minmax(0, 1fr) auto;
    }

    .rd .rd-profile-head__aside {
        grid-column: auto;
        flex-direction: column;
        align-items: flex-end;
        padding-top: 0;
        border-top: 0;
    }

    .rd .rd-profile-head__aside .ranking-page {
        flex-direction: column;
        align-items: flex-end;
    }

    .rd .rd-profile-share {
        position: relative;
    }

    .rd .rd-profile-share.is-popover .share-box {
        top: calc(100% + .5rem);
        right: 0;
        left: auto;
        width: min(30rem, calc(100vw - 2rem));
        margin-top: 0;
    }

    .rd .profile-card-list > .rd-row.rd-row--novalue {
        grid-template-columns: 3.4rem minmax(0, 1fr) auto;
        grid-template-areas: "logo main kind";
    }

    .rd .profile-card-list .rd-row__kind {
        max-width: none;
    }

    /* A34: from 761px the actions are the column at the right of the card,
       behind a divider, after the type pill. */
    .rd .profile-card-list > .rd-row.rd-row--novalue:has(> .rd-row__linkacts:not([hidden])) {
        grid-template-columns: 3.4rem minmax(0, 1fr) auto auto;
        grid-template-areas: "logo main kind acts";
    }

    .rd .profile-card-list .rd-row__linkacts {
        align-self: center;
        padding-top: 0;
        padding-left: var(--space-3);
        border-top: 0;
        border-left: 1px solid var(--border);
    }

    /* UI package (2026-10-12): Claim rank from 761px. */
    .rd main .rd-claim-details > .rd-claim-details__row {
        grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
        gap: var(--space-3);
        align-items: baseline;
    }

    /* CR-08: a link card puts "Create a new card from this link" to the right
       of its title; on a narrow screen the button stays below, full width.
       U73.01 (operator list 2026-10-21): the button sits vertically centred
       in the row. */
    .rd main .rd-claim-list .rd-rows > li.rd-row.rd-row--novalue {
        grid-template-columns: 3.4rem minmax(0, 1fr) auto;
        grid-template-areas: "logo main actions";
    }

    .rd main .rd-claim-list .rd-rows > li.rd-row.rd-row--novalue > .rd-row__actions {
        align-self: center;
    }

    .rd main .rd-claim-list .rd-rows > li.rd-row > .rd-row__actions .btn {
        white-space: nowrap;
    }

    /* CR-10: an own card puts Review to the right of the title and
       description, in front of the value column, which keeps its place. */
    .rd main .rd-claim-list .rd-rows > li.rd-row:not(.rd-row--novalue) {
        grid-template-columns: 3.4rem minmax(0, 1fr) auto minmax(9rem, 13rem);
        grid-template-areas: "logo main actions value";
    }

    .rd main .rd-claim-list .rd-rows > li.rd-row:not(.rd-row--novalue) > .rd-row__actions {
        align-self: center;
    }


    /* U08: the share and the heart button of the profile head are 38px
       squares on the desktop width; their icons keep their size. */
    .rd .rd-profile-head__aside .rd-sharebtn:not([hidden]) {
        width: 2.375rem;
        height: 2.375rem;
    }
}

/* From 981px: the two column detail layout; below it everything is one column. */
@media (min-width: 981px) {
    .rd .rd-detail {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    }

    .rd .rd-table time {
        white-space: nowrap;
    }

    .rd .rd-detail:has(> .rd-pos-facts) {
        grid-template-rows: auto 1fr;
    }

    .rd .rd-detail > .rd-pos-main {
        grid-column: 1;
        grid-row: 1 / span 2;
    }

    .rd .rd-detail > .rd-pos-facts {
        grid-column: 2;
        grid-row: 1;
    }

    .rd .rd-detail > .rd-pos-source {
        grid-column: 2;
        grid-row: 2;
    }

    /* UI-11: the tiles and the Points link on the left, "How redeeming
       works" on the right, stretched to the height of that stack (taller
       with a longer text of its own). NK01 (operator list 2026-10-23): the
       rules box is about twice as wide as before and the tile column about
       half (1 : 3.4); the notice and the form below span both columns. */
    .rd .rd-detail.rd-redeem {
        grid-template-columns: minmax(0, 1fr) minmax(0, 3.4fr);
    }

    .rd .rd-detail.rd-redeem > .rd-redeem__facts {
        grid-column: 1;
        grid-row: 1;
    }

    .rd .rd-detail.rd-redeem > .rd-redeem__rules {
        grid-column: 2;
        grid-row: 1;
        align-self: stretch;
    }

    .rd .rd-detail.rd-redeem > .rd-redeem__action {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    /* U2: without the facts card (payments off) the redeem box rises to the top. */
    .rd .rd-detail:not(:has(> .rd-pos-facts)) > .rd-pos-source {
        grid-row: 1;
        align-self: start;
    }

    .rd .rd-toc-layout {
        grid-template-columns: 13rem minmax(0, 1fr);
        align-items: start;
    }

    /* Point 2: from 981px the box stays at the top of the content area while
       the page scrolls. Without JavaScript the header scrolls away, so the
       box keeps a small gap to the top; with the sticky header it sits below
       the header while the header shows and moves up once it hides. A box
       taller than the window scrolls inside itself, so every entry stays
       reachable on a low window. */
    .rd .rd-toc-side {
        position: sticky;
        top: var(--space-4);
        display: block;
        max-height: calc(100vh - 2 * var(--space-4));
        overflow-y: auto;
        overscroll-behavior: contain;
        transition: top var(--motion-slow) var(--motion-ease), max-height var(--motion-slow) var(--motion-ease);
    }

    .rd .rd-toc-side:is(.js *) {
        top: calc(var(--header-height) + var(--space-4));
        max-height: calc(100vh - var(--header-height) - 2 * var(--space-4));
    }

    .rd .rd-toc-side:is(.js:has(.site-header.is-hidden) *) {
        top: var(--space-4);
        max-height: calc(100vh - 2 * var(--space-4));
    }

}

/* Hover. Only on a device that hovers: the lift of a box with a control (the
   rule above, now with the pointer), the lift of a stat tile that is a link
   (a stat without a link has none) and the fill of an editable field. */
@media (hover: hover) {
    /* SH-14: a saved item lights its whole white card on hover (the border
       colour only, the width stays 1px); its inner link adds no frame. */
    .rd .rd-fav:hover {
        border-color: var(--accent-border);
    }

    .rd .rd-fav > a.rd-mini:hover {
        border-color: transparent;
        background: transparent;
    }

    /* The external link of a public profile link and its two actions. */
    .rd .profile-card-list .rd-row__title a:hover {
        color: var(--accent-text);
    }

    .rd .profile-card-list .rd-row__linkacts > .rd-linkact:hover {
        border-color: var(--accent-border);
        background: var(--accent-soft);
        color: var(--accent-text);
    }

    .rd main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input[type="file"], input:not([type]), select, textarea):hover:not(:disabled):not([readonly]):not([data-login-code-digit]),
    .rd .fsel > .rd-sel-btn:hover:not(:disabled) {
        background-color: var(--surface-2);
    }

    /* U44 (operator list 2026-10-21, replaces the rule that every box with a
       control lifts on hover): content boxes (cards, accordions, empty
       states, stacks, share boxes, stat tiles, the claim list box) have no
       hover shadow. The card group keeps the one reduced card hover: the
       link and card rows (public profile links, account links, the preview
       rows), the favourites, the card rows of the Claim rank lists and the
       owner rows of "Ranking Cards" (which rest without a shadow). */
    .rd :is(.rd-row, .rd-fav):not(.rd-static):not(:is(.rd-card, .rd-row, .rd-fav, .rd-acc, .rd-empty, section.rd-stack:not(.rd-bare), .share-box, .rd-inset:not(.rd-preview)) *):hover:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):not([hidden], [inert], :disabled, :is([hidden], [inert], details:not([open]) > :not(summary)) *, details:not([open]) > :not(summary))),
    .rd main .rd-claim-list .rd-rows > li.rd-row:hover:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):not([hidden], [inert], :disabled, :is([hidden], [inert], details:not([open]) > :not(summary)) *, details:not([open]) > :not(summary))),
    .rd .rd-stack.rd-stack--cards .rd-row.rd-row--owner:hover:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):not([hidden], [inert], :disabled, :is([hidden], [inert], details:not([open]) > :not(summary)) *, details:not([open]) > :not(summary))) {
        box-shadow: var(--box-card-shadow-hover);
    }

    /* A51: the bare create list has no hover shadow of its own. */
    .rd main .rd-claim-list--create > .rd-rows:hover:has(:is(a[href], button:not(.b7-info), input:not([type="hidden"]), select, textarea, summary):not([hidden], [inert], :disabled, :is([hidden], [inert], details:not([open]) > :not(summary)) *, details:not([open]) > :not(summary))) {
        box-shadow: none;
    }

    .rd .rd-target.is-enhanced .rd-target__box:hover {
        background-color: var(--surface-2);
    }

    .rd .rd-target.is-enhanced .rd-target__box > input:hover:not(:disabled):not([readonly]) {
        background-color: transparent;
    }

    .rd .rd-target__step:hover:not(:disabled) {
        background-color: var(--accent-soft);
    }

    .rd .rd-move__btn:hover:not(:disabled) {
        background-color: var(--accent-soft);
    }

    .rd .rd-sharebtn:hover {
        border-color: var(--border-control);
        background-color: var(--surface-2);
    }
}

/* Reduced motion: every transition and animation of this block is off. The
   states themselves (checked box, current tab, open accordion, toast) stay
   exactly as they are; they just arrive at once. */
@media (prefers-reduced-motion: reduce) {
    .rd .rd-shake,
    .login-pop .rd-shake,
    .rd .rd-fav-pop svg,
    .rd .rd-fav-pop::after,
    .rd .rd-handle-state__wait::after {
        animation: none;
    }

    .rd .rd-card,
    .rd .rd-stat,
    .rd .rd-row,
    .rd .rd-acc,
    .rd .rd-toc-side,
    .rd .rd-fav,
    .rd .rd-empty,
    .rd .fsel > .rd-sel-btn,
    .rd .rd-mini,
    .rd .rd-sharebtn:not([hidden]),
    .rd .rd-target__step:not([hidden]),
    .rd .rd-more::after,
    .rd .profile-tabs.has-ink.is-ink-ready .rd-tab-ink,
    .rd .cbx__box,
    .rd .cbx__box svg path,
    .rd .rd-pick label:not([hidden]),
    .rd .b7-switch__track,
    .rd .b7-switch__track::after,
    .rd .b7-info:hover .b7-info__bub,
    .rd .b7-info:focus-visible .b7-info__bub,
    .rd .b7-info[aria-expanded="true"] .b7-info__bub,
    .rd main .b7-tiles > li.rd-stat,
    .rd .rd-card .share-box a.share-drop__item,
    .b7-toast__close {
        transition: none;
    }

    /* The "Open ›" chevron of a tile keeps its place on hover (no jump). */
    .rd a:hover > .rd-more::after,
    .rd a.rd-more:hover::after {
        transform: none;
    }

    /* Its own rule: a browser without ::details-content (older Firefox,
       Firefox ESR) drops a whole selector list that names it, so these
       stay apart from the list above. */
    .rd .rd-acc::details-content,
    .rd .rd-acc[data-disclosure-ready]::details-content {
        transition: none;
    }
}

/* Forced colours: the system colours decide. Cards, toasts, segments and
   badges keep a transparent outline in their own rules that becomes visible
   here; the checked checkbox, the switch (track and thumb) and the tab ink are
   set to the highlight pair so the state never depends on an author colour,
   and the segments of a composition bar are cut apart by a canvas line. */
@media (forced-colors: active) {
    /* N5: a focused field has no outline, so its edge is the focus indicator and
       takes the system highlight colour; the older surfaces (login window,
       contact and filter fields, admin fields, share inputs) are listed as
       documented exceptions of this block. */
    .inp:focus-visible,
    .ranking-page .listing-filters select:focus-visible,
    .surface main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea):focus-visible,
    .ranking-page .share-box input:focus-visible,
    .profile-page .share-box input:focus-visible,
    .ranking-page .share-box .fsel > .rd-sel-btn:focus-visible {
        border-color: Highlight;
    }

    .surface main input[type="file"]:focus-visible::file-selector-button,
    .rd main input[type="file"]:focus-visible::file-selector-button {
        border-color: Highlight;
    }

    .rd main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input[type="file"], input:not([type]), select, textarea):focus-visible,
    .rd .fsel > .rd-sel-btn:focus-visible,
    .rd .rd-target.is-enhanced .rd-target__box:has(> input:focus-visible) {
        border-color: Highlight;
    }

    .rd .cbx > input:checked + .cbx__box {
        border-color: Highlight;
        background-color: Highlight;
        forced-color-adjust: none;
    }

    .rd .cbx__box svg {
        stroke: HighlightText;
    }

    /* A14: the B-7 checkbox of the admin forms and the header login window. */
    .surface--admin .cbx > input:checked + .cbx__box,
    .login-pop .cbx > input:checked + .cbx__box {
        border-color: Highlight;
        background-color: Highlight;
        forced-color-adjust: none;
    }

    .surface--admin .cbx__box svg,
    .login-pop .cbx__box svg {
        stroke: HighlightText;
    }

    .rd .rd-tab-ink {
        background: Highlight;
        forced-color-adjust: none;
    }

    .rd .rd-compose__seg,
    .rd .rd-compose__swatch {
        background: CanvasText;
        forced-color-adjust: none;
    }

    .rd .rd-compose__seg {
        outline: 1px solid Canvas;
        outline-offset: -1px;
    }

    .rd .b7-switch__track {
        border-color: ButtonText;
        forced-color-adjust: none;
    }

    .rd .b7-switch__track::after {
        background: ButtonText;
        forced-color-adjust: none;
    }

    .rd .b7-switch > input:checked + .b7-switch__track {
        border-color: Highlight;
        background: Highlight;
    }

    .rd .b7-switch > input:checked + .b7-switch__track::after {
        background: HighlightText;
    }

    .rd .rd-pick label:has(input:checked) {
        border-color: Highlight;
    }

    /* NK13: without the stripe the current account entry keeps its frame
       in the system highlight colour. */
    .rd .b7-side-link[aria-current="page"] {
        border-color: Highlight;
    }

    /* A45 (Q45.7): forced colours drop the background drawing of the static
       chevron pair of a native select; the pair keeps its place in the text
       colour of the system, also while the field has the focus. */
    .rd .fsel::after,
    .rd .fsel:has(> select:focus)::after,
    .ranking-page .share-box .fsel::after,
    .ranking-page .share-box .fsel:has(> select:focus)::after {
        background-image:
            linear-gradient(135deg, transparent 42%, CanvasText 42%, CanvasText 58%, transparent 58%),
            linear-gradient(45deg, transparent 42%, CanvasText 42%, CanvasText 58%, transparent 58%),
            linear-gradient(45deg, transparent 42%, CanvasText 42%, CanvasText 58%, transparent 58%),
            linear-gradient(135deg, transparent 42%, CanvasText 42%, CanvasText 58%, transparent 58%);
        forced-color-adjust: none;
    }
}

/* O1: the card image in the owner rows of "My ranking cards". It fills the
   existing logo tile; without an image (or when it cannot be loaded) the
   initial tile stays. The tile of a failed picture comes from public/js/app.js
   and is reduced to the letter, so the frame is not drawn twice. */
.rd .rd-row__logo.rd-row__logo--img {
    border-color: transparent;
    background: none;
}

.rd .rd-row__logo.rd-row__logo--img > img[hidden] {
    display: none;
}

.rd .rd-row__logo.rd-row__logo--img > .logo {
    width: 100%;
    height: 100%;
    border-radius: 0;
    color: var(--accent-text);
    font-size: 1.15rem;
}

/* O3: Save image and Remove image in one row. The generic neighbour margin of
   two buttons is dropped because the row already has its gap, and the form that
   only carries the Remove token and action stays out of the layout. */
.rd .rd-card__foot > button + button {
    margin-left: 0;
}

.rd form[hidden] {
    display: none;
}

/* SH-01 to SH-16 (operator decisions 2026-10-14), owner pages: the ranking
   contexts, the statistics, the one card URL field and the public profile
   link actions. */
/* SH-08: an owner ranking context in two lines, the position with the
   comparison group first (a little heavier), the context under it. */
.rd .rd-ctx.rd-ctx--two-line li {
    grid-template-columns: minmax(0, 1fr);
    gap: .1rem;
}

.rd .rd-ctx.rd-ctx--two-line .rd-ctx__rank {
    color: var(--foreground);
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-heading);
}

.rd .rd-ctx.rd-ctx--two-line .rd-ctx__name {
    color: var(--muted);
    font-size: .89rem;
}

/* SH-12: the one owner card URL field, its copy row and the referral option
   sit closer together (gap 1rem -> .5rem), and the card ends a little
   earlier (bottom padding 1.5rem -> 1rem). */
.rd .rd-card.rd-card--public-url {
    padding-bottom: var(--space-4);
}

.rd .rd-card--public-url .rd-public-url {
    display: grid;
    gap: var(--space-2);
    min-width: 0;
}

.rd .rd-card--public-url .rd-public-url > p {
    margin: 0;
}

/* SH-15: the owner statistics of Ranking value and My ranking cards. The
   groups get a little more room (1rem and .9rem -> 1.25rem), the glyphs sit
   1px lower and the info icons come closer to their text (.6rem -> .3rem,
   the flex gap alone). */
.rd .rd-row__stats.rd-row__stats--icons {
    column-gap: calc(var(--space-4) + var(--space-1));
}

.rd .rd-row.rd-row--owner .rd-row__facts {
    column-gap: calc(var(--space-4) + var(--space-1));
}

.rd .rd-row__stats.rd-row__stats--icons > li > .ico,
.rd .rd-row.rd-row--owner .rd-row__facts > li > .ico {
    position: relative;
    top: 1px;
}

.rd .rd-row__stats.rd-row__stats--icons > li > .b7-info,
.rd .rd-row.rd-row--owner .rd-row__facts > li > .b7-info {
    margin-left: 0;
}

/* Public profile links: the actions Copy and Share as two compact square
   icon buttons whose hit area still reaches 44px (layout with the A34 rules
   in front of the 761px block). */
.rd .profile-card-list .rd-row__linkacts[hidden],
.rd .profile-card-list .rd-row__linkacts > .rd-linkact[hidden] {
    display: none;
}

.rd .profile-card-list .rd-row__linkacts > .rd-linkact {
    width: 2rem;
    height: 2rem;
    border-color: var(--border-control);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--muted);
}

/* The hit area grows from the padding box (30px inside the 1px border) by
   7px on every side to 44px; the gap (.8rem) keeps the two areas of a pair
   apart. */
.rd .profile-card-list .rd-row__linkacts > .rd-linkact::after {
    content: "";
    position: absolute;
    inset: -7px;
}

.rd .profile-card-list .rd-row__title a:focus-visible {
    color: var(--accent-text);
}

/* B-7 system pages. Maintenance and the standalone error pages show their
   message in the B-7 empty state card (.empty from the foundation block), with
   an icon box, an eyebrow with the code, the headline, one sentence and the
   one way on. The single link of a page keeps its bare markup and is styled
   as a button through the wrapper only. No media rule and no motion. */
.system-page {
    max-width: 40rem;
    margin: var(--space-6) auto 0;
}

.system-page h1 {
    margin: 0;
    font-size: clamp(1.6rem, 4vw, 2.1rem);
    font-weight: var(--font-weight-heading);
    letter-spacing: -.03em;
    line-height: 1.15;
}

.system-page p:last-child {
    margin-bottom: 0;
}

.system-page a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 1.05rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.system-page a:hover {
    background: var(--surface-2);
}

.system-page a:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

.system-page .system-page__icon {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    margin: 0 auto var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--accent-text);
}

.system-page .system-page__icon svg {
    width: 1.5rem;
    height: 1.5rem;
}

.system-page .system-page__eyebrow {
    display: inline-flex;
    align-items: center;
    max-width: none;
    margin: 0 auto var(--space-3);
    padding: .3rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: .71rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: .14em;
    text-transform: uppercase;
}

.system-page .system-page__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-4);
}

.system-page .system-page__actions form {
    margin: 0;
}

.system-page .system-page__actions button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 1.05rem;
    border: 1px solid var(--border-control);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    font: inherit;
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.system-page .system-page__actions button:hover {
    background: var(--surface-2);
}

.system-page .system-page__actions button:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

/* Operator package A (2026-10-21). Package A of the operator list of
   2026-10-21 (docs/plans/2026-10-21-betreiberliste-u00-u83.md). Each rule
   names its U number; the engine measurements are in
   tests/js/operator-package-a.test.mjs. The section stays last, directly
   behind the system pages block: its overrides of the earlier blocks need
   the later position in the cascade, and the earlier blocks keep their own
   pinned contracts unchanged. */

/* U82 (operator list 2026-10-21): the facts line of the own card rows in the
   account uses the same text trigger as the ranking cards (RK-06), so the
   info icon is gone and the text opens the bubble. NK02 (operator list
   2026-10-23): the same for the stats line of the own card detail page. */
.rd-row__facts .b7-info.b7-info--text,
.rd-row__stats--icons .b7-info.b7-info--text {
    width: auto;
    height: auto;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: inherit;
    font: inherit;
    line-height: inherit;
    vertical-align: baseline;
    text-decoration: none;
}

.rd-row__facts .b7-info.b7-info--text:hover,
.rd-row__facts .b7-info.b7-info--text[aria-expanded="true"],
.rd-row__stats--icons .b7-info.b7-info--text:hover,
.rd-row__stats--icons .b7-info.b7-info--text[aria-expanded="true"] {
    background: transparent;
    color: var(--accent-text);
}

.rd-row__facts .b7-info--text .b7-info__label,
.rd-row__stats--icons .b7-info--text .b7-info__label {
    white-space: nowrap;
}

.rd-row__facts .b7-info.b7-info--text::before,
.rd-row__stats--icons .b7-info.b7-info--text::before {
    content: none;
}

/* U39: with the script the share button sits vertically centred on the
   title of the rankings head row (instead of the computed h1 line offset);
   the .2rem below the title is matched below the button, so the centre is
   that of the title, not of the title with its spacing. */
.ranking-page .ranking-head:has(> .rankings-share.is-popover) {
    align-items: center;
}

.ranking-page .ranking-head > .rankings-share.is-popover {
    margin-top: 0;
    margin-bottom: .2rem;
}

/* U41: only on the login page (not in the header login window) the "Keep me
   signed in · Privacy Notice" line is centred horizontally. */
.rd.surface--auth main .login-remember {
    text-align: center;
}

/* U42: the error box of the statistics window lines up with the title icon:
   the title row is indented by its own .5rem padding, the box by the same
   amount on both sides. */
.stats-pop .stats-pop-state--error {
    margin-right: .5rem;
    margin-left: .5rem;
}

/* U45: a fixed @profile-name field shows the not-allowed cursor like the
   other locked fields. */
input#handle-fixed[readonly] {
    cursor: not-allowed;
}

/* U08: the profile heart is a square icon button of the share button's look
   (.rd-sharebtn), right below it. Saved, the heart itself is red and filled;
   border and surface stay those of the unsaved button (the U83 rule of the
   card heart). The saved count chip keeps its muted heart (UI-06). */
.rd .rd-profile-fav {
    display: inline-flex;
    margin: 0;
}

.rd .rd-profile-fav__btn[aria-pressed="true"] .ico {
    color: var(--heart);
    fill: currentColor;
}

.rd .rd-profile-fav__btn[aria-busy="true"] {
    cursor: progress;
}

/* U08: in the owner preview both buttons are pictures without an action. */
.rd .rd-profile-head__aside--preview .rd-sharebtn {
    cursor: default;
}

/* U11: the two save notes of "Your profile" on the account overview, each
   under a hairline (the separator colour of the card), with a small heading. */
.rd .rd-saves {
    display: grid;
    align-content: start;
    gap: .35rem;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

.rd .rd-saves > h3,
.rd .rd-saves__head > h3 {
    margin: 0;
    font-size: .88rem;
}

/* A06 (order 2026-11-01): the tooltip of a save note stands beside its
   heading; the note below it is only the number. */
.rd .rd-saves__head {
    display: flex;
    align-items: center;
    gap: .35rem;
    min-width: 0;
}

/* A06: the note about the public profile is its own line under the name and
   the handle of the identity group. */
.rd .rd-profile-line > .rd-note {
    width: 100%;
    margin: 0;
}

.rd .rd-saves > p {
    margin: 0;
}

/* Order 2026-10-29, point 19: the identity, the profile saves and the card
   saves of "Your profile" are three groups of two lines. The groups keep the
   gap of the card, so a narrow card shows them one under the other in the
   former order and look. Where the card itself offers at least 26rem (its
   own width, not the viewport) they stand side by side: the name above the
   @handle, each heading above its sentence and tip, without the hairline of
   the stacked order; the missing fields and the note about the public
   profile take the full width below them. The long name and handle keep the
   U53 (K1) ellipsis of their own rules. */
.rd .rd-card:has(> .rd-profile-groups) {
    container: rd-profile / inline-size;
}

.rd .rd-profile-groups {
    display: grid;
    gap: var(--space-4);
    min-width: 0;
}

.rd .rd-profile-groups > * {
    min-width: 0;
}

@container rd-profile (min-width: 26rem) {
    .rd .rd-profile-groups {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .rd .rd-profile-groups > * {
        grid-column: 1 / -1;
    }

    .rd .rd-profile-groups > :is(.rd-profile-line, .rd-saves) {
        grid-row: 1;
        grid-column: auto;
    }

    .rd .rd-profile-groups > .rd-profile-line {
        flex-direction: column;
        align-items: flex-start;
        gap: .35rem;
    }

    /* A06 (order 2026-11-01): side by side the saves keep to the top of
       their row, and the three groups are parted by a quiet vertical line
       in the separator colour of the card instead of the hairline above. */
    .rd .rd-profile-groups > .rd-saves {
        align-self: start;
        padding-top: 0;
        padding-left: var(--space-4);
        border-top: 0;
        border-left: 1px solid var(--border);
    }
}

/* Point 19: beside "Get started" the profile card takes three fifths of the
   overview row from 1100px; the other two-column grids keep their halves. */
@media (min-width: 1100px) {
    .rd .rd-grid--2.rd-grid--overview {
        grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    }
}

/* Order 2026-10-29, point 14: the home activity boxes in a grid instead of
   the sideways row: one column, two columns once two boxes of the row's
   minimum width (15rem) and the gap fit into the container (30.75rem), four
   columns from 981px. Nothing scrolls, so nothing fades at the sides. The
   rules stand outside the public content pages and B-7 surfaces blocks
   (plain rules only); the 981px rule of the four columns carries one more
   class, so it overrides them. */
.home-activity-grid {
    container-type: inline-size;
    min-width: 0;
}

.home-activity .b4-feed {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: minmax(0, 1fr);
    margin: 0;
    padding: 0;
    list-style: none;
}

@container (min-width: 30.75rem) {
    .home-activity .b4-feed {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* U33/U61: on Claim rank and Increase ranking value the figures of the tight
   stat tiles sit at the bottom of each tile, so a tile with a longer label
   keeps its figure on the line of its neighbours. */
.rd .rd-stats--tight .rd-stat__value {
    margin-top: auto;
}

/* U58: the items of a running text list keep a little room between them, as
   the points of .rd-rules (.5rem). Only plain text lists of the content
   boxes; menus and lists with a class of their own (.rd-toc__list, the "More
   about Upbiddr" links, the home steps) keep their spacing. */
.rd main :is(.rd-card, .rd-inset, .listing-group:not(.about-more)) > :is(ul, ol):not([class]) > li + li {
    margin-top: .5rem;
}

/* U63.01: "Cancel payment" and "Continue payment" of an open checkout (Increase
   ranking value, Claim rank) stand side by side at their own width; on a foot
   too narrow for both in one row (measured: 152px + .5rem + 168px = 20.5rem)
   they stack, each over the full width. The foot is the size container, so
   the switch follows the room of the card, not the screen. */
.rd .rd-card__foot--pair {
    container-type: inline-size;
}

@container (max-width: 21rem) {
    .rd .rd-card__foot--pair > form {
        flex: 1 1 100%;
    }

    .rd .rd-card__foot--pair > form > .btn {
        width: 100%;
    }
}

/* U46: measured cause of the frame around a card picture in the "Redeem on"
   list of the Points page: the general picture frame of the member pages
   (.surface main img, a 1px border and the medium radius) also reached the
   picture inside the small logo tile, whose own frame and placeholder
   surface are already off while it shows a picture. The picture of a logo
   tile carries no frame and no surface of its own; the tile clips it to its
   small radius. */
.rd .rd-mini__logo > img.logo--img {
    border: 0;
    border-radius: 0;
    background: none;
}

/* U44 (operator list 2026-10-21): borders and shadows of the content boxes.
   The box borders, the separators on white, the chips, detail panels and
   free logos of the cards and the card borders all follow var(--border)
   (#e1e7f0 in the light theme, the token values at the top; no class
   changed for a colour). The standard shadow var(--shadow) is lighter and
   airier; the card hover var(--shadow-card-strong) is reduced to about the
   former standard and stays distinguishable from it; popovers keep
   var(--shadow-overlay).

   The three groups the operator can style on their own, each one rule over
   the existing classes (U44.22: no markup class was needed):
   - white content boxes: the rules with box-shadow: var(--shadow) (for
     example .rd-card, .home-card, .home-steps li, .listing-group);
   - grey content boxes: the rule below that hands the grey surface its own
     border tokens;
   - the card group with the reduced hover shadow: .is-hover-lift (ranking
     cards), .ranking-page a.card-neighbour, .ranking-page a.b4-feed-card and
     the .rd-row, .rd-fav, Claim rank card row and owner row lift rule.

   One box alone on a page (the login card, the error and notice pages, a
   single confirmation or guest box) has the stronger border #d6dde9. */
.surface--auth main,
.empty.system-page,
.rd main > .rd-card.rd-center,
.rd main > .rd-card.rd-confirm:not(.rd-card--danger) {
    border-color: var(--border-solo);
}

/* U44.32 to U44.34, E-12: inside a grey content surface a border keeps its
   recognisability against the grey: var(--border) becomes #d6dde9,
   var(--border-quiet) and var(--border-strong) become #c5cdd9 (dark theme:
   the same contrast steps against its grey). The surface itself keeps the
   normal box border; only what sits on it changes. The grey head of a live
   leaderboard box is the one place where a card origin label (Free,
   Sponsored) sits on grey; the labels on the white cards stay unchanged. */
.rd .rd-inset:not(.rd-preview, .rd-inset--points) > *,
.rd .rd-linkbox > *,
.rd .rd-mini:not(.rd-fav > .rd-mini) > *,
.rd main fieldset.rd-attrs > *,
.ranking-archive .archive-box-head > * {
    --border: var(--border-muted);
    --border-quiet: var(--border-quiet-muted);
    --border-strong: var(--border-strong-muted);
    --box-light-border: var(--border-muted);
    --box-muted-border: var(--border-muted);
    --box-card-border: var(--border-muted);
}

/* U53 (operator list 2026-10-21, K1): text breaks between whole words
   only; no rule of the stylesheet splits a word into letters (the former
   letter and word break fallbacks are gone). A single word that is longer
   than a whole line on a narrow screen is handled by the kind of text:
   - names, titles, handles, links, URLs, file names, chips and short values
     of the components below: that word is shortened with an ellipsis on its
     own line; every other word of the same text keeps wrapping normally and
     stays complete. The full value stays in the link target, the copy
     button or the detail page. The clip margin keeps focus rings visible.
   - running text of members and of the operator (card description, profile
     bio, the account card description, the promotion bar and the X prompt):
     nothing is cut; that one paragraph scrolls sideways within its box
     instead, so the page never gets wider (named in the plan as the one
     open decision of U53: keep this or shorten as well).
   - static copy, tables of the admin area (its main area scrolls) and
     figures need no fallback. */
.rankshell .listing-name,
.rd .rd-head h1,
.rd .rd-head__handle,
.rd .rd-row__title,
.rd .rd-row__text,
.rd .rd-source-title,
.rd .rd-report__link,
.rd .rd-profile-head__main :is(h1, h2),
.rd .rd-profile-head__handle,
.rd .rd-profile-head__main .profile-location .chip > .profile-location__value,
.rd .rd-profile-line__name,
.rd .rd-kv dd,
.rd .rd-activity__body,
.rd main .rd-claim-details dd,
.rd .rd-center .rd-return-facts dd,
.rd .rd-ctx.rd-ctx--two-line .rd-ctx__name,
.rd .rd-linkbox__url,
.rd .rd-linkbox__text > *,
.rd .b7-drop__name,
.rd .rd-table :is(th, td),
.ranking-page .share-info .share-info__line,
.rd .rd-card .share-info .share-info__line,
.b7-toast-text,
.rankshell .card-mid > p:not([class]) {
    min-width: 0;
    max-width: 100%;
    overflow-x: clip;
    overflow-clip-margin: calc(var(--focus-ring-width) + var(--focus-ring-offset));
    text-overflow: ellipsis;
}

.rd .rd-profile-head__main .profile-location .chip > .profile-location__value {
    white-space: normal;
}

/* U-03 (Bestandsaudit 2026-10, P2): a stored URL of the detail lists is one
   word; Firefox offers line breaks after its slashes, so the URL values keep
   to their one line and end in the ellipsis above. The full value stays in
   the link target or on the detail page. Every other value of the list
   wraps between whole words as before. */
.rd .rd-kv dd.rd-kv__url {
    white-space: nowrap;
}

/* The rows that hold such a name may shrink below its longest word, so the
   word is cut inside the row instead of widening the page. */
.rd .rd-head__meta,
.rd .rd-profile-head__titlerow,
.rd .rd-profile-line,
.rd .rd-profile-head__chips,
.rd .rd-profile-head__main .profile-location,
.rd .rd-profile-head__main .profile-location .chip {
    min-width: 0;
    max-width: 100%;
}

.rankshell .detail-panel > p:not([class]),
.profile-page .profile-bio,
.rd .rd-text,
.promotion-bar,
.promotion-bar-source,
.x-prompt .x-prompt__body {
    max-width: 100%;
    overflow-x: auto;
}

/* U48 to U50, U52 (operator list 2026-10-21): the identity line of a card
   ("Username · @profile-name") on a narrow screen. First the @profile-name
   moves to a line of its own, and the separator goes (public/js/app.js marks
   the wrapped line, which then gives the @profile-name the whole second
   line); only then are the username and the @profile-name cut with an
   ellipsis. Without the script the line wraps the same way and the
   separator simply stays. */
.rc-ident {
    flex-wrap: wrap;
    row-gap: .15rem;
}

.rc-ident-uname,
.rc-ident-handle {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rc-ident.is-wrapped > .rc-ident-sep {
    display: none;
}

.rc-ident.is-wrapped > .rc-ident-handle {
    flex-basis: 100%;
}

/* U49.04: on the card page the Free or Sponsored label stays on the top line
   beside the identity; the identity gives way and is cut. */
.ranking-page .card-detail .rankshell-identrow {
    flex-wrap: nowrap;
    align-items: flex-start;
}

.ranking-page .card-detail .rankshell-identrow .rc-ident {
    flex: 1 1 auto;
}

/* U48.04/U48.05: the picture column never takes the text column: the text
   column may shrink to nothing but never overlaps, and on a very narrow
   screen the picture gets smaller, down to 2.75rem.
   B-KARTE-01 (package B, 2026-10-21): these rules belong to the narrow
   two-column card only. Unbounded, they overrode the three-column grid of
   761px and 981px (picture, text, value zone), so the value zone fell into
   the narrow picture column under the picture and the desktop picture was
   capped at 3.4rem. From 761px the earlier grid and picture sizes apply
   again unchanged. */
@media (max-width: 760px) {
    .rankshell .card-main {
        grid-template-columns: clamp(2.75rem, 14vw, 3.4rem) minmax(0, 1fr);
    }

    .rankshell .card-left {
        min-width: 0;
    }

    .rankshell .card-left > .logo {
        width: 100%;
        max-width: 3.4rem;
        height: auto;
        aspect-ratio: 1;
    }
}

/* K-01 (R-01/A-04, operator approval 2026-10-28): the same narrow
   two-column card only, and only where the screen is at most 18 times the
   browser's default font size wide (an enlarged default font size; with 16px
   only up to 288px): the text column takes its own full line below picture
   and rank, so no statistic is cut by the card. The picture column, the
   value zone and every wider card grid stay as they are. */
@media (max-width: 760px) and (max-width: 18em) {
    .rankshell .card-mid {
        grid-column: 1 / -1;
    }
}

/* K-05 (R-01/A-04, operator approval 2026-10-28, "akzeptiere"): the hero's
   one column no longer grows to the width of its widest single word, so
   slogan, subtitle, subline and the two actions wrap between whole words
   inside the hero. The title keeps its former place: where it is wider than
   the column it starts at the column's start (safe), otherwise it stays
   centred. Only together with safe alignment, so a browser without it keeps
   the former hero entirely. It stands here because the public content block
   holds no at-rule. */
@supports (justify-self: safe center) {
    .home-hero {
        grid-template-columns: minmax(0, 1fr);
    }

    .home-hero h1 {
        justify-self: safe center;
    }
}

/* U48.09: a category, country or language chip never squeezes and wraps
   inside itself; it moves to the next line as a whole, and only a value
   longer than the line is cut. */
.rankshell .chips > :is(.rankshell-meta, .rankshell-facet) {
    display: block;
    flex: none;
    max-width: 100%;
    padding-top: .2rem;
    padding-bottom: .2rem;
    overflow: hidden;
    line-height: 1.35rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* U49.06/U50.05/U54: the copy box. Wide, the link box and the "Copy target
   URL" button stand side by side as before (the copy box adds no box of its
   own). Where the button would wrap below the link box (measured: 18rem of
   link box, .75rem gap and 175px of button, so below 29.75rem of the target
   row) the same button becomes the copy icon button at the right end inside
   the link box: its text stays its accessible name, only visually hidden; a
   copy turns its icon into the check for two seconds (b7CopyFeedback) and
   the status line announces it. The account copy box of "Ranking Cards >
   Details" is always in this form. */
.rankshell .target-link {
    container-type: inline-size;
}

.rankshell .copybox {
    display: contents;
}

@container (max-width: 29.75rem) {
    .rankshell .target-link > .copybox {
        position: relative;
        display: flex;
        flex: 1 1 100%;
        min-width: 0;
    }

    .rankshell .target-link > .copybox > .rankshell-linkbox {
        flex: 1 1 auto;
        padding-right: 2.65rem;
    }

    .rankshell .target-link > .copybox > .copy-target:not([hidden]) {
        position: absolute;
        top: 50%;
        right: .4rem;
        width: 1.75rem;
        min-height: 1.75rem;
        height: 1.75rem;
        padding: 0;
        gap: 0;
        border-radius: var(--radius-sm);
        font-size: 0;
        translate: 0 -50%;
    }

    .rankshell .target-link > .copybox > .copy-target:not([hidden])::after {
        content: "";
        position: absolute;
        inset: -.5rem;
    }

    .rankshell .target-link > .copybox > .copy-target:not([hidden]):active {
        padding-top: 0;
    }

    .rankshell .target-link > .copybox > .copy-target:not([hidden]):active > .ico {
        translate: none;
    }

    /* U48.06: the target visit of a list card, then on its own line over the
       full width. */
    .rankshell .target-link > .btn {
        flex: 1 1 100%;
    }
}

.rd .rd-linkbox--copy {
    position: relative;
    flex-wrap: nowrap;
    padding-right: 2.65rem;
}

.rd .rd-linkbox--copy > .rd-linkbox__url {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: .5rem;
    min-width: 0;
}

.rd .rd-linkbox--copy .rd-linkbox__urltext {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rd .rd-card .rd-linkbox--copy > .copy-target:not([hidden]) {
    position: absolute;
    top: 50%;
    right: .4rem;
    width: 1.75rem;
    min-height: 1.75rem;
    height: 1.75rem;
    padding: 0;
    gap: 0;
    border-radius: var(--radius-sm);
    font-size: 0;
    translate: 0 -50%;
}

/* NK06 (operator list 2026-10-23): the copy icon button inside a URL box is
   1.75rem (28px) visible, on the card pages and in the account; the link
   box keeps .4rem + 1.75rem + .5rem free on its right. An invisible
   extension keeps the hit area larger than the visible square (2.75rem);
   the card pages get the same inside their container query above. */
.rd .rd-card .rd-linkbox--copy > .copy-target:not([hidden])::after {
    content: "";
    position: absolute;
    inset: -.5rem;
}

.rd .rd-card .rd-linkbox--copy > .copy-target:not([hidden]):active {
    padding-top: 0;
}

.rd .rd-card .rd-linkbox--copy > .copy-target:not([hidden]):active > .ico {
    translate: none;
}

/* U48.06/U48.07, U50.08/U50.09: "Card & profile" (and the actions of the card
   page). Once the buttons no longer fit in one row (measured: 299px for
   Open card page, View profile and the heart on a phone; 267px on the card
   page), each takes the full width; the heart keeps its square and stays
   beside the button before it, which fills the rest of that line. The
   detail panel is the size container. */
.rankshell .detail-panel {
    container-type: inline-size;
}

@container (max-width: 18.75rem) {
    .rankshell .rankshell-actions:not(.rankshell-actions--detail) {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
    }

    .rankshell .rankshell-actions:not(.rankshell-actions--detail):has(> :is(.rankshell-fav-form, .rankshell-fav)) {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .rankshell .rankshell-actions:not(.rankshell-actions--detail):has(> :is(.rankshell-fav-form, .rankshell-fav)) > .btn:not(.rankshell-fav, :nth-last-child(2)) {
        grid-column: 1 / -1;
    }
}

@container (max-width: 16.75rem) {
    .rankshell .rankshell-actions--detail {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
    }

    .rankshell .rankshell-actions--detail:has(> :is(.rankshell-fav-form, .rankshell-fav)) {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .rankshell .rankshell-actions--detail:has(> :is(.rankshell-fav-form, .rankshell-fav)) > .btn:not(.rankshell-fav, :nth-last-child(2)) {
        grid-column: 1 / -1;
    }
}

/* U48.08 to U48.10, U52.02: the link cards of a profile (public Links tab and
   the owner preview) on a narrow list. Title and host break only between
   whole words (U53); the type chip no longer squeezes beside the title but
   moves as a whole to a line of its own under it (cut only when longer than
   the line), and Copy and Share keep their own row under the card. The list
   is the size container. */
.rd .profile-card-list {
    container-type: inline-size;
}

@container (max-width: 30rem) {
    .rd .profile-card-list > .rd-row.rd-row--novalue {
        grid-template-columns: 3.4rem minmax(0, 1fr);
        grid-template-areas:
            "logo main"
            "logo kind";
    }

    .rd .profile-card-list > .rd-row.rd-row--novalue:has(> .rd-row__linkacts:not([hidden])) {
        grid-template-columns: 3.4rem minmax(0, 1fr);
        grid-template-areas:
            "logo main"
            "logo kind"
            "acts acts";
    }

    .rd .profile-card-list .rd-row__kind {
        display: block;
        justify-self: start;
        max-width: 100%;
        padding-top: .2rem;
        padding-bottom: .2rem;
        overflow: hidden;
        line-height: 1.35rem;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* U51 (operator list 2026-10-21): the page buttons of the lists (Rankings,
   Leaderboards, a closed leaderboard). The group never breaks apart: it
   stays one line and wraps only as a whole below "Showing ...". On a narrow
   list (below 40rem) "Showing ..." and the group each take the full width,
   centred. On a very narrow list (below 27rem, a phone in portrait) the pages
   right beside the current one give way to a gap and Previous and Next show
   their arrow only (the words stay their accessible names), so the first,
   the current and the last page always fit on one line. The server window
   (first, current and its neighbours, last, gaps) is unchanged; every page
   stays a plain link. */
.ranking-page .ranking-pages {
    container-type: inline-size;
}

.ranking-page .ranking-pagination {
    flex-wrap: nowrap;
}

.ranking-page .ranking-page-gap--compact {
    display: none;
}

@container (max-width: 40rem) {
    .ranking-page .ranking-pages > .ranking-showing {
        flex: 1 1 100%;
        text-align: center;
    }

    .ranking-page .ranking-pages > .ranking-pagination {
        flex: 1 1 100%;
        justify-content: center;
    }
}

@container (max-width: 27rem) {
    .ranking-page .ranking-pagination {
        gap: .25rem;
    }

    .ranking-page .ranking-pagination > .ranking-page-near {
        display: none;
    }

    .ranking-page .ranking-pagination > .ranking-page-gap--compact {
        display: inline;
    }

    .ranking-page .ranking-page-gap {
        padding: 0;
    }

    /* NK10 (operator list 2026-10-23): no gap beside the hidden word, so
       the arrow sits horizontally centred in its button. */
    .ranking-page .ranking-pagination > :is(:first-child, :last-child) {
        min-width: 2.75rem;
        padding: 0;
        gap: 0;
        font-size: 0;
    }

    .ranking-page .ranking-pagination > :first-child::before {
        content: "\2039";
        content: "\2039" / "";
        font-size: 1.15rem;
    }

    .ranking-page .ranking-pagination > :last-child::before {
        content: "\203A";
        content: "\203A" / "";
        font-size: 1.15rem;
    }
}

/* U76 (operator list 2026-10-21): in the attribute box of the card forms the
   info icon after a field label (Category) stands raised at the top of the
   label like the icon after a leaderboard box title (UI-04), not below its
   text line. Measured: label text top 113.5px, icon top 116.9px before; the
   leaderboard icon sits 4.4px above its text top. */
.rd fieldset.rd-attrs .rd-field-head {
    align-items: flex-start;
}

.rd fieldset.rd-attrs .rd-field-head > .rd-field-head__aside {
    margin-top: -.2rem;
}

/* U38 (operator list 2026-10-21): the blue text links that were underlined
   at rest (the plain text links of the info pages: Contact with its email
   address and Privacy Notice, the FAQ menu, the Contract Withdrawal texts,
   the legal pages; and of every member and admin page) rest without the
   underline and take it on hover and on keyboard focus; their colour, the
   focus ring and the hover colour stay. Links with a class of their own
   (buttons, chips, arrow links, menus) keep their own look. The promotion
   bar link follows the same rule. The privacy link of the header login
   window takes the look of the login page (U38.08: accent, medium weight,
   underline on hover and focus only). */
:is(.info-page, .surface main) a:not([class]),
.promotion-bar a,
.login-pop .login-remember a {
    text-decoration: none;
}

:is(.info-page, .surface main) a:not([class]):is(:hover, :focus-visible),
.promotion-bar a:is(:hover, :focus-visible),
.login-pop .login-remember a:is(:hover, :focus-visible) {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: .22em;
}

.login-pop .login-remember a {
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

/* U72 (operator list 2026-10-21): vendor prefixes where a supported engine
   still needs one. Checked: -webkit-line-clamp with -webkit-box (present),
   -webkit-background-clip: text and -webkit-backdrop-filter (present),
   ::-webkit-details-marker and the hidden WebKit scrollbars (present);
   added: -webkit-user-select (Safari), -webkit-mask-image (Chromium before
   120 and older Safari, beside every mask-image), and the text size of
   iOS Safari, which would otherwise enlarge text in landscape on its own.
   Not prefixed, because the supported engines read them as they are or no
   prefix exists: appearance, inset, aspect-ratio, translate, color-mix,
   :has(), container queries (without them the wide layout stays) and the
   alternative text of generated content (a plain content value comes first
   as the fallback). */
html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* U62 (operator list 2026-10-21): only a real pointer hover tints a field. On
   a touch screen a tap leaves a sticky :hover behind, so the first code box
   of the login page kept the hover surface after the code moved on to the
   next box (measured with touch emulation); the hover now needs a device
   that can hover, like every other hover rule of the redesigned pages. The
   rule left the B-7 surfaces block for this media rule of its own.
   A18 (order 2026-11-01): the six login code boxes take no hover surface at
   all. The pointer stays over the first box after a click while the focus
   moves on with every digit, so a hover surface looked like a second active
   box; only the focused box keeps the darker surface (:focus-visible). */
@media (hover: hover) {
    .surface main :is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"], input[type="search"], input:not([type]), select, textarea):not([data-login-code-digit]):hover {
        background-color: var(--surface-2);
    }
}

/* U43 (operator list 2026-10-21): buttons.
   - The home hero button (.btn--hero) keeps its look and the B-7 hover, the
     gradient sliding to the other side.
   - Every other primary button (the .btn--primary class and the gradient
     submit buttons of the member, admin, login and filter forms) keeps its
     gradient in place; hover darkens it by 12 percent with a black overlay
     of .12 that fades in and out (the old slide jumped on some pages, U63.02),
     a press by .2. The overlay lies under the text, never takes a click and
     follows the radius; the focus ring, the disabled and the forced colour
     look stay those of before.
   - A press on a recognisable text button (a filled or framed button with a
     text) moves only its text 1px down: the text sits in its own label
     (span.btn__label, also in the buttons the script builds), and only that
     label moves, relative to its place. Box, padding, size, layout and an
     icon beside the text stay exactly where they are. Not changed: buttons
     that do not look like buttons ("Details +", ghost and menu links) and
     buttons with an icon only, which carry no label. An input submit has no
     label and keeps its text unchanged. The classless admin views keep their
     contract: their plain submit buttons carry a plain span as the label. */
.btn--hero:hover {
    background-position: 100% 50%;
}

:where(.btn--primary, .ranking-page .listing-filters button[type="submit"], .surface--auth .auth-form:has(> input:not([type="hidden"])) button, .surface--auth main > form:only-of-type button, .surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"], .surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]):not(.btn--hero, .rd .btn:not(.btn--primary), :disabled, [aria-disabled="true"]) {
    position: relative;
    isolation: isolate;
}

:is(.btn--primary, .ranking-page .listing-filters button[type="submit"], .surface--auth .auth-form:has(> input:not([type="hidden"])) button, .surface--auth main > form:only-of-type button, .surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"], .surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]):not(.btn--hero, .rd .btn:not(.btn--primary), :disabled, [aria-disabled="true"])::before {
    content: "";
    position: absolute;
    inset: -1px;
    z-index: -1;
    border-radius: inherit;
    background-color: rgba(0, 0, 0, .12);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--motion-base) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

:is(.btn--primary, .ranking-page .listing-filters button[type="submit"], .surface--auth .auth-form:has(> input:not([type="hidden"])) button, .surface--auth main > form:only-of-type button, .surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"], .surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]):not(.btn--hero, .rd .btn:not(.btn--primary), :disabled, [aria-disabled="true"]):hover::before {
    opacity: 1;
}

:is(.btn--primary, .ranking-page .listing-filters button[type="submit"], .surface--auth .auth-form:has(> input:not([type="hidden"])) button, .surface--auth main > form:only-of-type button, .surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"], .surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]):not(.btn--hero, .rd .btn:not(.btn--primary), :disabled, [aria-disabled="true"]):active::before {
    opacity: 1;
    background-color: rgba(0, 0, 0, .2);
}

:is(.btn, .copy-target, .ranking-page .listing-filters button[type="submit"], .surface--auth .auth-form:has(> input:not([type="hidden"])) button, .surface--auth main > form:only-of-type button, .surface main button, .rd main .b7-dash-logout button, .ranking-page .share-box button, .profile-page .share-box button):not(.btn--ghost, .rankshell-fav, .b7-info, .iconbtn, .rd-heart, .rd-move__btn, .rd-target__step, .b7-side-link, .b7-acct-link, .share-dialog__x, .details-toggle, .rd-sharebtn, .filter-nav, .rd-sel-btn, .b7-fsw-btn, .rankings-share-btn, .ranking-fav, :disabled, [aria-disabled="true"]):active .btn__label,
.surface--admin main button:not([class], :disabled, [aria-disabled="true"]):active > span:only-child {
    position: relative;
    top: 1px;
}

/* U43: a light text button without the .btn class darkens on press as .btn
   does (.btn:active). */
:is(.surface main button, .ranking-page .share-box button, .ranking-page .share-box .copy-target, .profile-page .share-box button, .rd main .b7-dash-logout button):not(.btn, .btn--ghost, .rankshell-fav, .b7-info, .iconbtn, .rd-heart, .rd-move__btn, .rd-target__step, .b7-side-link, .b7-acct-link, .share-dialog__x, .details-toggle, .rd-sharebtn, .filter-nav, .rd-sel-btn, .b7-fsw-btn, .rankings-share-btn, .ranking-fav, :disabled, [aria-disabled="true"]):active {
    background-color: color-mix(in srgb, var(--surface-2) 80%, var(--border-strong));
}

/* U55 (operator list 2026-10-21): a classic scrollbar of a long option list
   stays inside the rounded corners of the panel. The scrolling area begins
   and ends one corner radius inside the panel (a transparent top and bottom
   border of the radius, filled by the panel surface), so the track never
   reaches into a corner curve; the visible 1px edge is drawn as the outline
   on the border edge. Measured with visible classic scrollbars: before, the
   track ran into both right corners. */
div.b7-fpanel {
    padding: 0 calc(.4rem + 1px);
    border: 0 solid transparent;
    border-block-width: var(--radius-lg);
    outline: 1px solid var(--border-quiet);
    outline-offset: -1px;
}

@media (prefers-reduced-motion: reduce) {
    /* U43: the hover overlay of the primary buttons arrives at once. */
    :is(.btn--primary, .ranking-page .listing-filters button[type="submit"], .surface--auth .auth-form:has(> input:not([type="hidden"])) button, .surface--auth main > form:only-of-type button, .surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"], .surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]):not(.btn--hero, .rd .btn:not(.btn--primary), :disabled, [aria-disabled="true"])::before {
        transition: none;
    }
}

@media (forced-colors: active) {
    /* U43: no overlay in forced colours; the system draws the button. */
    :is(.btn--primary, .ranking-page .listing-filters button[type="submit"], .surface--auth .auth-form:has(> input:not([type="hidden"])) button, .surface--auth main > form:only-of-type button, .surface--member main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"], .surface--admin main form:has(:is(input[type="text"], input[type="email"], input[type="url"], input[type="number"], input[type="file"], select, textarea)) button[type="submit"]):not(.btn--hero, .rd .btn:not(.btn--primary), :disabled, [aria-disabled="true"])::before {
        display: none;
    }

    /* U55: forced colours would paint the transparent corner bands of the
       option panel; there it keeps one plain system border and its padding. */
    div.b7-fpanel {
        padding: .4rem;
        border: 1px solid CanvasText;
        outline: 0;
    }
}

/* Package B (operator list 2026-10-21, U27): the faint URL example of the
   link form is a placeholder only. It disappears while the field has the
   focus and returns on blur while the field is empty; it is never a value.
   The faint colour itself is the existing placeholder colour of the account
   surface. */
.rd main input[data-url-example-generic]:focus::placeholder {
    color: transparent;
}

/* Package B (U73.04): the heading of an optional field without a native label
   reads like the field labels of the form, and its "(optional)" marker is
   quiet: smaller and in the muted text colour. Required fields carry no
   marker. */
.rd .rd-field-heading {
    margin: 0;
    font-weight: 650;
}

.rd .field-optional {
    color: var(--muted);
    font-size: .84rem;
    font-weight: 400;
}

/* NK04 (operator list 2026-10-23): the image field of the add form. The
   title "Link Image" and its quiet "(optional)" marker share one line; the
   title keeps the same distance to the dropzone as the heading of the Link
   image box (the box gap, var(--space-4)). */
.rd .rd-field-image {
    display: grid;
    gap: var(--space-4);
}

.rd .rd-field-headrow {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .35rem;
}

/* C-1 (U07): the lists under the two boxes. Each group heads a grid of
   tiles, three per row from 981px, two from 761px, one below; a tile is
   the B-7 mini box of the platforms page (.b4-act) and its rows are the
   neighbour rows of the card page (.card-neighbour) in the size of the mini
   rows: place, a 28px image or initial, name and description on one line
   with an ellipsis (no break inside a word), the value. */
.stats-lists {
    display: grid;
    gap: var(--space-3);
    min-width: 0;
}

.stats-lists-heading {
    margin: var(--space-3) 0 0;
    font-size: 1.04rem;
}

.stats-lists-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}

/* C-1 (U13.01): the statistics box of the card page under the share box,
   on the content box surface of the value box, with the rows of the
   statistics panel. It holds links but no other control, so it keeps the
   resting look of the content boxes. */
.ranking-page .card-detail-stats {
    padding: var(--space-4) var(--space-4) var(--space-3);
    border: 1px solid var(--box-muted-border);
    border-radius: var(--radius-lg);
    background: var(--box-muted-bg);
    box-shadow: var(--box-muted-shadow);
}

.ranking-page .card-detail-stats-heading {
    margin: 0 0 .25rem;
    color: var(--text-faint);
    font-size: .76rem;
    font-weight: 400;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.ranking-page .card-detail-stats .stats-row {
    padding-inline: 0;
}

/* C-1 (U25.04/.05): the bottom row of the footer. The copyright line keeps
   the left side; the beta notice, the separator and the two small icon links
   to /sitemap and /llms.txt follow each other on the right, in the text
   colour of the row (currentColor), with the focus ring of every link and
   the tooltip of the footer icon links. */
.f-bottom {
    justify-content: flex-start;
    column-gap: .5rem;
}

.f-bottom > p:first-child {
    margin-right: auto;
    padding-right: var(--space-4);
}

.f-bottom > p.f-files {
    display: inline-flex;
    align-items: center;
    gap: .15rem;
}

.f-files__sep {
    margin-right: .35rem;
}

.f-files__link {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    margin-block: -.6rem;
    border-radius: var(--radius-sm);
    color: inherit;
}

.f-files__link:hover {
    color: var(--foreground);
}

.f-files__link svg {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* A closed bubble takes no room: hidden, not only transparent, so it never
   counts as footer content under the back to top button. */
.f-files__link .tip-bub {
    top: auto;
    right: auto;
    bottom: calc(100% + .45rem);
    left: 50%;
    visibility: hidden;
    transform: translateX(-50%) translateY(4px);
}

.f-files__link:hover .tip-bub,
.f-files__link:focus-visible .tip-bub {
    visibility: visible;
    opacity: 1;
    transform: translateX(-50%);
}

/* C-1 (U25.01): the sitemap page, the listing groups of the information
   pages side by side from 761px (pages) and up to three platforms per row
   from 981px; the links keep the plain text link look of those pages. */
.sitemap-groups,
.sitemap-platforms {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}

.sitemap-platform {
    min-width: 0;
}

.info-page .listing-group .sitemap-platform h3 {
    margin: 0 0 var(--space-2);
    font-size: 1rem;
}

.info-page .listing-group .sitemap-list li + li {
    margin-top: .3rem;
}

/* UI01 (operator order 2026-10-24): the short description under a page
   link, the same text /llms.txt shows, in the quiet small type of the
   page (the muted text token, no new style). */
.info-page .listing-group .sitemap-list__desc {
    display: block;
    margin-top: .1rem;
    color: var(--text-faint);
    font-size: .82rem;
    line-height: 1.45;
}

.info-page .listing-group .sitemap-list li:has(.sitemap-list__desc) + li {
    margin-top: .6rem;
}

/* C-1 (operator list 2026-10-21, U06): the two statistics boxes of the
   /statistics page. NK32 (operator list 2026-10-23): from 761px the two
   boxes stand side by side, Visitors with Profiles on the left as one box
   and Ranking cards on the right, both of the height of the taller one;
   each box draws its own frame and shadow once, so nothing shows through
   between the groups. The header window keeps its stacked panel (its own
   copy, without the boxes). */
@media (min-width: 761px) {
    .statistics-page .stats-panel {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-rows: auto 1fr;
        column-gap: var(--space-4);
        padding: 0;
        border: 0;
        border-radius: 0;
        background: none;
        box-shadow: none;
    }

    /* The one left box behind Visitors and Profiles, drawn once: a grid item
       of its own over both rows, so no shadow lies between the two groups
       and its bottom meets the bottom of the right box. */
    .statistics-page .stats-panel::before {
        content: "";
        grid-column: 1;
        grid-row: 1 / span 2;
        border: 1px solid var(--box-light-border);
        border-radius: var(--radius-lg);
        background: var(--surface);
        box-shadow: var(--box-light-shadow);
    }

    .statistics-page .stats-panel > .stats-group {
        position: relative;
        min-width: 0;
        padding: .5rem;
    }

    .statistics-page .stats-panel > [aria-labelledby="stats-group-visitors"] {
        grid-column: 1;
        grid-row: 1;
    }

    .statistics-page .stats-panel > [aria-labelledby="stats-group-profiles"] {
        grid-column: 1;
        grid-row: 2;
        align-self: start;
    }

    /* The right box: Ranking cards over both rows, as high as the left one. */
    .statistics-page .stats-panel > [aria-labelledby="stats-group-cards"] {
        grid-column: 2;
        grid-row: 1 / span 2;
        border: 1px solid var(--box-light-border);
        border-radius: var(--radius-lg);
        background: var(--surface);
        box-shadow: var(--box-light-shadow);
    }

    /* The group head at the top of a box has no divider above it. */
    .statistics-page .stats-panel > [aria-labelledby="stats-group-cards"] .stats-group-label,
    .statistics-page .stats-panel:not(:has(> [aria-labelledby="stats-group-visitors"])) > [aria-labelledby="stats-group-profiles"] .stats-group-label {
        margin-top: 0;
    }

    /* Without the visitor group the left box holds Profiles alone. */
    .statistics-page .stats-panel:not(:has(> [aria-labelledby="stats-group-visitors"])) > [aria-labelledby="stats-group-profiles"] {
        grid-row: 1;
    }

    /* Order 2026-10-29, point 10: on the public statistics page only, the
       Profiles head has this padding from 761px (point 9 keeps its top
       margin at 0, rule above the media rules). */
    .statistics-page--public .stats-panel > [aria-labelledby="stats-group-profiles"] .stats-group-label {
        padding: .44rem .6rem .3rem;
    }

    /* The sitemap page: the three page groups and two platforms per row. */
    .sitemap-groups {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

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

@media (min-width: 981px) {
    .sitemap-platforms {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.stats-list-tile {
    display: flex;
    flex-direction: column;
    gap: .45rem;
    min-width: 0;
    padding: var(--space-4);
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--box-muted-bg);
}

.stats-list-title {
    min-width: 0;
    margin: 0;
    font-size: .95rem;
    font-weight: var(--font-weight-heading);
    letter-spacing: -.02em;
}

/* NK33 (operator list 2026-10-23): the list tiles stand in one column;
   the period note ("Last 7 days", or "All time" for the two all-time lists)
   stands on the right of the list title, in one row while there is room. */
/* UI11.7/UI11.8 (operator order 2026-10-24): the period stands directly
   right of the list title, not at the right edge; a long title and its
   period wrap in order (the period moves to the next line, left). */
.stats-list-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: flex-start;
    gap: .25rem .75rem;
    min-width: 0;
}

.stats-list-period {
    display: flex;
    align-items: center;
    gap: .35rem;
    margin: 0;
    color: var(--text-faint);
    font-size: .78rem;
}

.stats-list-note {
    margin: 0;
    color: var(--text-faint);
    font-size: .86rem;
}

.stats-lists .card-neighbour-list {
    display: grid;
    gap: .4rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.stats-lists .card-neighbour {
    position: relative;
    display: grid;
    grid-template-columns: auto 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: .6rem;
    min-height: 2.75rem;
    padding: .5rem .6rem;
    border: 1px solid var(--box-card-border);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}

.stats-lists .card-neighbour-rank,
.stats-lists .card-neighbour-value {
    color: var(--text-faint);
    font-family: var(--font-family-num);
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.stats-lists .card-neighbour-value {
    color: var(--muted);
    font-size: .84rem;
}

.stats-lists .card-neighbour-logo {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: linear-gradient(145deg, var(--accent-soft), var(--teal-soft));
    color: var(--accent-deep);
    font-size: .78rem;
    font-weight: var(--font-weight-heading);
}

.stats-lists .card-neighbour-logo.card-neighbour-logo--img {
    border-color: transparent;
    background: none;
}

.stats-lists .card-neighbour-logo > img.logo--img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.stats-lists .card-neighbour-title {
    display: flex;
    align-items: baseline;
    gap: .35rem;
    min-width: 0;
    overflow: hidden;
    font-size: .9rem;
}

.stats-lists .card-neighbour-name {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    font-weight: var(--font-weight-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stats-lists .card-neighbour-sep {
    flex: none;
    color: var(--text-faint);
}

.stats-lists .card-neighbour-teaser {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    color: var(--text-faint);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* NK33: a hovered row takes the blue frame and fill of the mini boxes of
   the platforms page (.platforms-mini-card), no shadow. */
@media (hover: hover) {
    .stats-lists a.card-neighbour:hover {
        border-color: var(--accent-border);
        background-color: var(--accent-soft);
    }
}

@media (prefers-reduced-motion: reduce) {
    .stats-lists .card-neighbour {
        transition: none;
    }
}

/* C-4 (operator list 2026-10-21, U07.24–.41): the milestone timeline under
   the lists of the statistics page. One quiet panel in the surface of the
   list tiles with a thin line; every item is a small circle with a local
   icon on the line and a card next to it (title, date and label above, a
   short muted sentence below), every year a slightly larger circle on the
   line. Narrow screens: the line on the left, all cards on its right. From
   761px the line is centred and the cards alternate left and right. Goals
   are dashed and muted, today carries the accent. No motion of its own;
   all colours are theme tokens, so light and dark follow the theme. */
.timeline {
    display: grid;
    gap: var(--space-3);
    min-width: 0;
    margin-top: var(--space-5);
}

.timeline-heading {
    margin: var(--space-3) 0 0;
    font-size: 1.04rem;
}

.timeline-intro,
.timeline-pager {
    margin: 0;
    color: var(--muted);
    font-size: .9rem;
}

.timeline-pager {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem var(--space-3);
    align-items: baseline;
}

.timeline-pager a,
.timeline-body a {
    color: var(--accent-text);
    text-decoration: underline;
    text-underline-offset: .15em;
}

.timeline-line {
    position: relative;
    display: grid;
    gap: var(--space-4);
    min-width: 0;
    margin: 0;
    padding: var(--space-4) var(--space-4) var(--space-4) 0;
    list-style: none;
    border: 1px solid var(--border-quiet);
    border-radius: var(--radius-lg);
    background: var(--box-muted-bg);
}

.timeline-line::before {
    content: "";
    position: absolute;
    top: var(--space-5);
    bottom: var(--space-5);
    left: calc(var(--space-4) + 15px);
    width: 2px;
    border-radius: 2px;
    background: var(--border-quiet);
}

.timeline-item {
    position: relative;
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr);
    column-gap: var(--space-3);
    min-width: 0;
    padding-left: var(--space-4);
}

.timeline-dot {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: start;
    width: 32px;
    height: 32px;
    margin-top: var(--space-2);
    border: 1px solid var(--border-quiet);
    border-radius: 50%;
    background: var(--surface);
    color: var(--accent-text);
    box-shadow: 0 0 0 4px var(--box-muted-bg);
}

.timeline-card {
    min-width: 0;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.timeline-meta {
    display: flex;
    flex-wrap: wrap;
    gap: .15rem .6rem;
    margin: 0 0 .2rem;
    color: var(--text-faint);
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.timeline-label {
    color: var(--accent-text);
    font-weight: var(--font-weight-medium);
}

/* Titles (U53, K1): breaks between whole words only; an overlong word is
   shortened with an ellipsis. */
.timeline-title {
    margin: 0;
    overflow-x: clip;
    overflow-clip-margin: calc(var(--focus-ring-width) + var(--focus-ring-offset));
    font-size: .98rem;
    text-overflow: ellipsis;
}

/* Running text (U53, K1): breaks between whole words only; an overlong
   word scrolls sideways inside the card, nothing is cut. */
.timeline-body {
    max-width: 100%;
    margin: .25rem 0 0;
    overflow-x: auto;
    color: var(--muted);
    font-size: .9rem;
}

.timeline-year {
    position: relative;
    padding-left: var(--space-2);
}

.timeline-year-mark {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border: 2px solid var(--accent-border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--accent-text);
    font-size: .78rem;
    font-weight: var(--font-weight-heading);
    box-shadow: 0 0 0 4px var(--box-muted-bg);
}

/* NK34.07 (operator list 2026-10-23, Block B; correction K1): the dashed
   frames of the upcoming goals in the faint text token, so they keep at
   least 3:1 against the grey timeline ground in both themes (light
   4.69:1, dark 4.77:1; --border-control reached 2.87:1 in light). */
.timeline-item--goal .timeline-dot,
.timeline-item--goal .timeline-card {
    border-style: dashed;
    border-color: var(--text-faint);
    background: transparent;
}

.timeline-item--goal .timeline-dot {
    background: var(--box-muted-bg);
    color: var(--text-faint);
}

.timeline-item--goal .timeline-title,
.timeline-item--goal .timeline-label {
    color: var(--muted);
}

.timeline-item--today .timeline-dot,
.timeline-item--live .timeline-dot {
    border-color: var(--accent-border);
    background: var(--accent-soft);
}

.timeline-item--today .timeline-card {
    border-color: var(--accent-border);
}

.timeline-today {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .35rem var(--space-4);
    margin: var(--space-2) 0 0;
}

.timeline-today > div {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-3);
    min-width: 0;
}

/* NK34 (Block B, correction K2): the label takes the rest of the row, so a
   value moves below it only when it does not fit next to it. A value wider
   than the whole card (e.g. 9,223,372,036,854,775,807 on a narrow screen)
   stays complete on one line and scrolls sideways within its own box, as
   U53 (K1) does for text that must not be cut; the page never gets wider
   and no number is split. */
.timeline-today dt {
    flex: 1 1 0;
    min-width: 0;
    color: var(--muted);
    font-size: .86rem;
}

.timeline-today dd {
    max-width: 100%;
    margin: 0 0 0 auto;
    overflow-x: auto;
    font-weight: var(--font-weight-medium);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

@media (min-width: 761px) {
    .timeline-line {
        padding: var(--space-5) var(--space-4);
    }

    .timeline-line::before {
        left: calc(50% - 1px);
    }

    .timeline-item {
        grid-template-columns: minmax(0, 1fr) 32px minmax(0, 1fr);
        padding-left: 0;
    }

    .timeline-item .timeline-dot {
        grid-row: 1;
        grid-column: 2;
    }

    .timeline-item--left .timeline-card {
        grid-row: 1;
        grid-column: 1;
    }

    .timeline-item--right .timeline-card {
        grid-row: 1;
        grid-column: 3;
    }

    .timeline-year {
        display: flex;
        justify-content: center;
        padding-left: 0;
    }

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

@media (forced-colors: active) {
    .timeline-line::before {
        background: CanvasText;
    }

    .timeline-dot,
    .timeline-year-mark,
    .timeline-card {
        border-color: CanvasText;
        box-shadow: none;
    }

    .timeline-item--today .timeline-dot,
    .timeline-item--live .timeline-dot,
    .timeline-year-mark {
        border-color: Highlight;
    }
}

/* Paket E-1 (operator list 2026-10-21, approval 2026-10-23): the rules of the
   price notes (U32, U35), the "Claim #1" phrase of the rankings head (U60) and
   the merged "My increases" overview with its row menu (U65), in their own
   section at the end of the stylesheet. They follow the existing B-7 tokens
   and components; no new design direction. */

/* Paket E-1 (U32, U35): a price note in an inset holds one or two
   sentences; the last one keeps no bottom margin. */
.rd .rd-inset.price-note > p:last-child,
.rd .rd-inset.checkout-info__prices > p:last-child {
    margin-bottom: 0;
}

/* U60 (Paket E-1): "Claim #1 for $XX" beside the title; below 761px it
   took its own line under the title (since 2026-10-29, point 6, it is not
   shown there). UI05 (operator order 2026-10-24): an
   inviting call to claim rank 1, so it is larger and in the text colour,
   with the medium weight of the page; its tooltip was removed. It may wrap
   at its spaces instead of overflowing a narrow screen or a large zoom. */
.ranking-page .ranking-claim-top {
    margin: 0;
    min-width: 0;
    color: var(--foreground);
    font-size: 1.05rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.35;
}

@media (min-width: 761px) {
    .ranking-page .ranking-intro:has(> .ranking-claim-top) {
        grid-template-columns: auto minmax(0, 1fr);
        column-gap: .75rem;
        align-items: baseline;
    }
}

/* Order 2026-10-29, point 6: below 761px the phrase would stand on a line
   of its own under the title; there it is not shown. */
@media (max-width: 760px) {
    .ranking-page .ranking-claim-top {
        display: none;
    }
}

/* Paket E-1 (U65): the merged "My increases" overview. Every cell holds two
   lines: the main line and a smaller, quieter second line. A long card
   title ends with an ellipsis; its full text stays in the title attribute and
   in the accessible name. */
.rd .rd-table--pairs .rd-pair__main,
.rd .rd-table--pairs .rd-pair__sub {
    display: block;
    min-width: 0;
}

.rd .rd-table--pairs .rd-pair__sub {
    margin-top: .15rem;
    color: var(--text-faint);
    font-size: .8rem;
    font-weight: 400;
}

.rd .rd-table--pairs .rd-pair__sub--warn {
    color: var(--foreground);
}

.rd .rd-table--pairs .rd-pair__title {
    display: block;
    max-width: 100%;
    overflow: hidden;
    color: var(--foreground);
    font-weight: var(--font-weight-heading);
    text-decoration: none;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rd .rd-table--pairs a.rd-pair__title:hover {
    color: var(--accent-text);
}

/* U65.13/.14: the actions menu of a row, a native details disclosure. The
   trigger is the B-7 square icon button with three vertical dots; the panel
   repeats the surface, frame, radius and shadow of the B-7 menu panel and its
   entries are .menu-link items. The panel opens below the trigger: from the
   start of the stacked card on a narrow screen, towards the left of the last
   column in the table. */
.rd .row-menu {
    position: relative;
    display: inline-block;
}

.rd .row-menu > summary {
    display: inline-grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--foreground);
    cursor: pointer;
    list-style: none;
}

.rd .row-menu > summary::-webkit-details-marker {
    display: none;
}

/* UI16 (operator order 2026-10-24): on a hovered table row (--surface-2)
   the trigger stays visible: at rest it keeps the surface and its frame;
   hovered, focused or pressed it takes the soft accent surface with the
   accent frame (B-7 .mini:hover, .iconbtn:active), open it also tints the
   dots (B-7 .iconbtn[aria-expanded="true"]). The frame is always 1px, so
   no state changes its size. */
.rd .row-menu > summary:hover,
.rd .row-menu > summary:focus-visible,
.rd .row-menu > summary:active {
    background: var(--accent-soft);
    border-color: var(--accent-border);
    color: var(--foreground);
}

.rd .row-menu[open] > summary {
    background: var(--accent-soft);
    border-color: var(--accent-border);
    color: var(--accent-text);
}

.rd .row-menu > summary:focus-visible {
    outline: var(--focus-ring-width) solid var(--focus);
    outline-offset: var(--focus-ring-offset);
}

/* UI16: on a desktop with a fine pointer the trigger is compact, 2.25rem
   with the small radius and a 1rem icon; touch and narrow screens keep the
   2.75rem target. */
@media (min-width: 761px) and (hover: hover) and (pointer: fine) {
    .rd .row-menu > summary {
        width: 2.25rem;
        height: 2.25rem;
        border-radius: var(--radius-sm);
    }

    .rd .row-menu > summary .ico {
        width: 1rem;
        height: 1rem;
    }
}

/* Order 2026-10-29, point 12: in the "My ranking increases" table the action
   trigger is 2.25rem at every width and pointer (it was 2.75rem on touch and
   narrow screens); its radius, icon and states stay as above. Only the pairs
   table carries a row menu today; this rule stays inside it. */
.rd .rd-table--pairs .row-menu > summary {
    width: 2.25rem;
    height: 2.25rem;
}

.rd .row-menu__panel {
    position: absolute;
    top: calc(100% + .35rem);
    left: 0;
    z-index: 6;
    display: grid;
    width: min(16rem, calc(100vw - 2rem));
    padding: .4rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-overlay);
}

.rd .row-menu__panel form {
    display: block;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
}

.rd .row-menu__item {
    display: flex;
    width: 100%;
    background: none;
    font: inherit;
    font-size: .92rem;
    text-align: left;
    cursor: pointer;
}

.rd .row-menu__item:hover {
    background-color: var(--surface-2);
    border-color: var(--border);
}

/* UI14-A (operator order 2026-10-24): in the actions menu of My increases
   the two document actions (POST buttons) read as text links like View
   public card; the member pages' button rule (.surface main button) no
   longer frames them as light buttons. At rest no fill and a transparent
   1px frame (no size jump); hovered, focused or pressed the soft accent
   surface with the quiet frame (E-9); the text is never blue. Only the menu
   of this table; the POST forms, the CSRF token, target, rel and the
   Preparing label are unchanged. */
.rd .rd-table--pairs .row-menu__panel .row-menu__item {
    min-height: 2.75rem;
    padding: .6rem .7rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--foreground);
    font-size: .92rem;
    font-weight: 400;
}

.rd .rd-table--pairs .row-menu__panel .row-menu__item:is(:hover, :focus-visible, :active) {
    border-color: var(--border-quiet);
    background: var(--accent-soft);
    color: var(--foreground);
}

/* The cell and, from 761px, the table must not cut the open panel. */
.rd .rd-table--pairs td.rd-table__actions {
    overflow: visible;
}

.rd .rd-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem var(--space-3);
    margin-top: var(--space-3);
}

.rd .rd-pager__current {
    color: var(--text-faint);
    font-size: .85rem;
}

@media (min-width: 761px) {
    .rd .rd-table.rd-table--pairs {
        overflow: visible;
    }

    .rd .rd-table--pairs thead tr > :first-child {
        border-top-left-radius: var(--radius-lg);
    }

    .rd .rd-table--pairs thead tr > :last-child {
        border-top-right-radius: var(--radius-lg);
    }

    .rd .rd-table--pairs tbody tr:last-child > :first-child {
        border-bottom-left-radius: var(--radius-lg);
    }

    .rd .rd-table--pairs tbody tr:last-child > :last-child {
        border-bottom-right-radius: var(--radius-lg);
    }

    .rd .rd-table--pairs tbody th[scope="row"] {
        max-width: 18rem;
    }

    .rd .rd-table--pairs td.rd-table__actions {
        width: 3.5rem;
        text-align: right;
    }

    .rd .rd-table--pairs .row-menu__panel {
        right: 0;
        left: auto;
        text-align: left;
    }
}

/* ==========================================================================
   NK01–NK41, Block A (operator list 2026-10-23,
   docs/plans/2026-10-23-korrekturauftrag-nk01-nk41.md). The responsive rules
   of the block, grouped by media query so the block adds as few media rules
   as possible; each rule names its NK number. The rules without a media
   query stay next to the components they change. The section stays last:
   its overrides of the earlier blocks need the later position in the
   cascade.
   ========================================================================== */

/* NK-PHONE: below 761px. */
@media (max-width: 760px) {
    /* NK12: on the card page the picture column keeps the width of the list
       cards (the auto column of the detail card collapsed around the fluid
       picture, most visibly around the letter tile of a card without a
       picture). */
    .ranking-page .card-detail .card-main {
        grid-template-columns: clamp(2.75rem, 14vw, 3.4rem) minmax(0, 1fr);
    }

    /* NK14: on a phone the order buttons are 1.75rem, their touch target
       stays 2.75rem across (.5rem at the sides and the outer edge). */
    .rd .rd-move__btn {
        width: 1.75rem;
        height: 1.75rem;
    }

    .rd .rd-move__btn::before {
        inset: -.5rem;
    }

    .rd .rd-move__btn--up::before {
        bottom: -.15rem;
    }

    .rd .rd-move__btn--down::before {
        top: -.15rem;
    }

    .rd .rd-move__btn .ico {
        width: 1rem;
        height: 1rem;
    }

    /* UI19 (operator order 2026-10-24): the share image preview and the
       example image dialog on a phone, smaller by the operator's decision,
       even below the usual touch size. The close X keeps its one heading
       line square: the member pages' button rule (.surface main button)
       adds a 2.75rem minimum height, which made it narrow and tall. The two
       footer actions fit side by side; the closing one reads Close. The X
       prompt keeps its own controls. */
    .share-dialog:is([data-share-dialog], [data-share-example-dialog]) {
        padding: var(--space-4);
    }

    .share-dialog:is([data-share-dialog], [data-share-example-dialog]) .share-dialog__x {
        min-width: 0;
        min-height: 0;
    }

    .share-dialog:is([data-share-dialog], [data-share-example-dialog]) .share-dialog__foot {
        gap: .4rem;
    }

    .share-dialog:is([data-share-dialog], [data-share-example-dialog]) .share-dialog__foot .btn {
        min-height: 2.25rem;
        padding: 0 .75rem;
        font-size: .84rem;
    }

    .share-dialog:is([data-share-dialog], [data-share-example-dialog]) .share-dialog__close-wide {
        display: none;
    }

    .share-dialog:is([data-share-dialog], [data-share-example-dialog]) .share-dialog__close-narrow {
        display: inline;
    }

    /* UI21 (operator order 2026-10-24): My increases as stacked cards on a
       phone. Amount, Status and Date are blocks of a darker heading and two
       small grey lines (the status badge stays), with more room above each
       heading than inside a block; the actions sit on the right. The table
       from 761px, the neutral row under review (no data-label) and the card
       title are unchanged. */
    .rd .rd-table--pairs tbody tr {
        gap: 0;
    }

    /* Order 2026-10-29, point 12: --space-4 above each block (was
       --space-3). */
    .rd .rd-table--pairs td[data-label] {
        margin-top: var(--space-4);
    }

    .rd .rd-table--pairs td[data-label]::before {
        margin-bottom: .2rem;
        color: var(--foreground);
        font-weight: var(--font-weight-medium);
    }

    .rd .rd-table--pairs td[data-label] .rd-pair__main.rd-table__num,
    .rd .rd-table--pairs td[data-label] .rd-pair__sub {
        color: var(--text-faint);
        font-size: .8rem;
        font-weight: 400;
    }

    .rd .rd-table--pairs td[data-label] .rd-pair__sub {
        margin-top: .1rem;
    }

    .rd .rd-table--pairs td.rd-table__actions {
        justify-self: end;
        margin-top: var(--space-2);
    }

    .rd .rd-table--pairs .row-menu__panel {
        right: 0;
        left: auto;
    }
}

/* NK-PORTRAIT: a narrow portrait screen (the A20c/d layout of the rankings
   controls). */
@media (max-width: 760px) and (orientation: portrait) {
    /* NK30 (operator list 2026-10-23): without a countdown (no running
       period is chosen) the count stands centred under the full width
       switch; with the countdown it stays on the right of it (U59). */
    .ranking-page .ranking-meta:not(:has(> .ranking-reset)) {
        justify-content: center;
    }

    .ranking-page .ranking-meta:not(:has(> .ranking-reset)) > .ranking-results {
        margin-left: 0;
    }
}

/* NK-SMALL-ROW: below 768px where the switch and the count still share one
   row (landscape phones, and 761px to 767px). */
@media (max-width: 767px) and (orientation: landscape), (min-width: 761px) and (max-width: 767px) {
    /* NK30: the chips of the chosen filters and their reset take a line of
       their own below, centred; the switch and the metadata group wrap as
       everywhere (UI08). */
    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary {
        flex-basis: 100%;
        justify-content: center;
        margin-left: 0;
    }

    .ranking-page .ranking-controls:has(.range-switch) .ranking-summary .ranking-facets {
        justify-content: center;
    }
}

/* NK-WIDE: from 981px. */
@media (min-width: 981px) {
    /* NK20 (operator list 2026-10-23): more room between the about column
       and Explore, Help and Legal (the payment row keeps its alignment under
       Explore); the three link columns get a little narrower for it. The
       about column gives up a little width, the link columns take it. */
    .f-grid--pay {
        grid-template-columns: minmax(0, 1fr) minmax(0, 3.3fr) minmax(0, 1.7fr);
    }

    .f-grid--pay .footer-nav,
    .f-grid--pay .f-pay {
        margin-left: var(--space-5);
    }
}

/* NK-SCRIPT: while scripting is enabled. */
@media (scripting: enabled) {
    /* NK36: the theme button keeps its place from the first paint, so the
       header does not shift once public/js/app.js runs. Until then it is an
       invisible place only (no pointer, no focus, not in the accessibility
       tree); .js shows it once it switches the theme. */
    .site-header .theme-toggle {
        display: inline-grid;
        visibility: hidden;
    }

    /* A03 (order 2026-11-01): the share box of the rankings list starts in
       its closed popover state from the first paint, so it never flashes
       above the latest activity before public/js/app.js turns it into the
       popover (.is-popover). Until then the panel takes no room and the
       button keeps its place as an invisible box (no pointer, no focus, not
       in the accessibility tree). Without scripting the box stays an
       ordinary visible box. */
    .ranking-page .ranking-head:has(> .rankings-share:not(.is-popover)) {
        flex-wrap: nowrap;
        align-items: center;
    }

    .ranking-page .ranking-head > .rankings-share:not(.is-popover) {
        flex-basis: auto;
        margin-top: 0;
        margin-bottom: .2rem;
    }

    .ranking-page .rankings-share:not(.is-popover) .rankings-share-panel {
        display: none;
    }

    .ranking-page .rankings-share:not(.is-popover) .rankings-share-btn[hidden] {
        display: inline-grid;
        visibility: hidden;
        width: 2.75rem;
        height: 2.75rem;
    }
}
