/* ═══════════════════════════════════════════════════════════
   LITECOIN HORIZON — HUB, LIBRARY & SUPPORT
   index.php · comics.php · donate.php
   Direction: A PHOENIX RISING
   ═══════════════════════════════════════════════════════════

   ONE stylesheet, three pages, loaded after style.css via
   lh_head(['pageCss' => 'home']) on each of them. That is deliberate: the hub
   shows a taste of the library using the SAME .lib-card the library itself uses,
   so a change to the card lands on both or neither. Splitting this into
   home.css / comics.css / donate.css would let them drift apart within a week.
   The shared PHP half of that guarantee lives in partials/home_ui.php.

   Everything here is scoped to markup only those three pages emit, so it can
   restyle them without touching the shared token layer in style.css.

   THE METAPHOR, IN FIVE MECHANISMS
   Colour alone does not say "rising". These do, and they compound:

     1. The ground is ASH — warm charcoal with a violet cast, the thing a phoenix
        rises OUT of. Every band, including the two that are dark in both themes,
        sits on the --ink-* ash ramp. Nothing here is navy any more.
     2. --flame runs 0deg — deep ember at the base, gold at the crown. Anything
        painted with it reads as rising rather than merely as "orange". It fills
        the primary CTA and clips through the hero's accent word.
     3. --flame-soft washes UP from the bottom edge of the hero and the drop
        band, so the heat is under the content, not floating above it.
     4. The eyebrow rule is VERTICAL — a short flame rule growing up into the
        headline, not the horizontal rule the sibling site uses.
     5. Motion is upward. The hero rises into place on load; every card, tile and
        button lifts on hover and focus. Nothing slides sideways.

   RULES THIS FILE KEEPS
     • Zero importance overrides. First-party CSS in this codebase has none and
       that stays true. Where a dark-locked band has to beat `.theme-dark .band`,
       it does it with an equal-specificity selector placed later in source order
       — see the "DARK-LOCKED BANDS" note below.
     • Every colour, size, space and duration comes from a style.css token.
       Translucency is derived with color-mix() so a token change propagates.
     • Both themes are complete. Theme-responsive components declare their light
       values on the bare selector and their dark values under `.theme-dark`.
       Two bands (hero, drop) are deliberately dark in BOTH themes — they carry
       their own ash ground and their own foreground ramp, so nothing about them
       depends on which theme is active.
     • Contrast is checked, not assumed. Ratios are recorded beside the pairing.
       --ember-700 is decorative only (2.59:1) and never carries text on ash.

   PAGE RHYTHM
   The homepage is a HUB, not a scroll — hero, four doors, a taste, the drop, and
   it ends. The full library and the wallets each have their own route.

     index.php    .hero                 ash, always      01  THE RISING
                  .band.band-auction    ash, always      02  UNDER THE HAMMER *
                  .band.band-alt        white / ash-850  03  FOUR DOORS
                  .band                 cream / ash-900  04  LATEST
                  .band.band-drop       ash, always      05  THE DROP

     auction.php  .hero.is-compact      ash, always      01  THE LOT
                  .band.band-drop       ash, always      02  THE PIECE
                  .band.band-alt        white / ash-850  03  HOW TO BID *
                  .band                 cream / ash-900  04  BID HISTORY

     comics.php   .hero.is-compact      ash, always      01  THE LIBRARY
                  .band                 cream / ash-900  02  ALL ISSUES

     donate.php   .hero.is-compact      ash, always      01  SUPPORT
                  .band                 cream / ash-900  02  WALLETS

   * Conditional. The auction band renders only while an auction is live, so
     index.php is a four-section page the rest of the time and the numbers close
     up behind it — they come from ++$sectionNo, not from the markup. "How to
     bid" likewise disappears once the lot has closed.

   .band-library and .band-support are inert markers carried on the markup for
   readability; only .band, .band-alt, .band-drop and .band-auction paint
   anything.
   ═══════════════════════════════════════════════════════════ */


/* ─── Page shell ──────────────────────────────────────────── */

.home {
    /* One horizontal rhythm for every band, so the bands can paint full-bleed
       inside .app-window while their content stays on a single left edge. */
    --band-x: clamp(1.25rem, 5vw, 3.5rem);
    --band-y: clamp(2.75rem, 6vw, 5rem);

    display: block;
    width: 100%;
}

/* Anchored sections sit under nothing sticky today, but a little breathing room
   makes #comics / #videos / #donate land on the eyebrow rather than flush. */
.home > section {
    scroll-margin-top: var(--space-5);
}


/* ─── Upward motion ───────────────────────────────────────── */
/* Both the duration and the stagger are expressed in --dur-* tokens, which the
   prefers-reduced-motion block in style.css zeroes globally. At 0ms with
   fill-mode `both` the animation lands on its end state immediately, so a
   reduced-motion visitor gets the finished layout with no movement and no delay.

   This is a load-in, not a scroll reveal, and only the hero uses it. A scroll
   reveal would want `animation-timeline: view()`, but .app-window is
   `overflow: hidden`, which makes it a scroll container that never scrolls — the
   view timeline would resolve against a non-scrolling scrollport. The failure
   mode there is content stuck at opacity 0, which is not a risk worth taking for
   an effect that cannot be verified from here. The hero is above the fold, so a
   load-in is the honest place for it anyway. */

@keyframes rise-in {
    from { opacity: 0; transform: translateY(1.75rem); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes rule-rise {
    from { transform: scaleY(0); }
    to   { transform: scaleY(1); }
}

/* The eyebrow is always the hero's first child and always rises, so it does not
   need the class in the markup — lh_eyebrow() stays a single-argument helper. */
.hero .eyebrow,
.hero .rise {
    animation: rise-in var(--dur-base) var(--ease-out) both;
}

.hero .rise:nth-child(2) { animation-delay: calc(var(--dur-fast) * 0.6); }
.hero .rise:nth-child(3) { animation-delay: calc(var(--dur-fast) * 1.2); }
.hero .rise:nth-child(4) { animation-delay: calc(var(--dur-fast) * 1.8); }
.hero .rise:nth-child(5) { animation-delay: calc(var(--dur-fast) * 2.4); }


/* ─── Skip link ───────────────────────────────────────────── */
/* The first focusable element on the page. Hidden until focused; the global
   :focus-visible ring in style.css still draws around it. */

.skip-link {
    position: absolute;
    top: var(--space-4);
    left: var(--space-4);
    z-index: 100;
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-pill);
    background: var(--accent);
    color: var(--text-on-accent);
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    box-shadow: var(--shadow-3);
    transform: translateY(calc(-100% - var(--space-6)));
    transition: transform var(--dur-base) var(--ease-out);
}

.skip-link:focus {
    transform: translateY(0);
}


/* ─── Editorial primitives ────────────────────────────────── */
/* Every band supplies --band-fg / --band-fg-soft / --band-accent / --band-hot /
   --band-line / --rule-fill, so these components are written once and inherit
   their palette from whichever band they land in. */

/* THE VERTICAL RULE. A short flame growing up into the eyebrow and the headline
   above it — the motif that replaces the sibling site's horizontal rule. */
.hero-inner::before,
.band-head::before {
    content: '';
    display: block;
    width: 3px;
    height: clamp(2rem, 4vw, 3.25rem);
    margin-bottom: var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--rule-fill);
}

/* Only the hero's rule animates — it is the one a visitor is actually looking at
   when the page loads. Growing from the bottom edge, so it rises. */
.hero-inner::before {
    transform-origin: bottom;
    animation: rule-rise var(--dur-slow) var(--ease-out) both;
}

.eyebrow {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
    color: var(--band-accent);
    font-size: var(--fs-xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}

.eyebrow-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.125rem;
    height: 2.125rem;
    border: 1px solid color-mix(in srgb, var(--band-accent) 55%, transparent);
    border-radius: var(--radius-pill);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: 0;
}

.display {
    margin: 0;
    color: var(--band-fg);
    font-size: var(--fs-2xl);
    font-family: var(--font-display);
    font-weight: 400;   /* Anton ships one weight */
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
    text-transform: uppercase;
    text-wrap: balance;
}

.display-xl {
    font-size: var(--fs-3xl);
}

.display .line {
    display: block;
}

/* The house signature: the last word of the headline drops out of the sans and
   into a gold serif italic. The `*` reset in style.css sets Inter on every
   element, so this needs a real selector to win — it has one (0,1,1).

   The solid colour here is the FALLBACK and is declared first on purpose. On a
   cream band it is also the final answer: --accent-deep #9a2d0c measures 6.80:1
   on --ink-50, whereas the gold crown of --flame would measure 1.4:1 there. The
   gradient fill below is therefore applied only on the ash-ground bands. */
.display em {
    font-family: Georgia, 'Times New Roman', Times, serif;
    font-style: italic;
    font-weight: var(--fw-normal);
    letter-spacing: 0;
    text-transform: none;
    color: var(--band-accent);
}

/* THE FLAME HEADLINE. Every stop of --flame from --ember-500 up clears 5:1 on
   ash (#e8481c 5.05:1 at the base, #ffd774 14.29:1 at the crown), so the word
   passes AA along its whole length rather than only in the middle. Guarded by
   @supports so a browser without background-clip keeps the solid colour above
   instead of rendering transparent text. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
    .hero .display em,
    .band.band-drop .display em,
    .theme-dark .band .display em {
        background: var(--flame);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        -webkit-text-fill-color: transparent;
    }
}

.lead {
    max-width: 62ch;
    margin-top: var(--space-5);
    color: var(--band-fg-soft);
    font-size: var(--fs-md);
    line-height: 1.7;
}

.kicker {
    display: block;
    color: var(--band-accent);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}

/* The pullquote rule is the vertical motif again, painted with the flame so it
   reads bottom-to-top like everything else. */
.pullquote {
    position: relative;
    max-width: 46ch;
    margin-top: var(--space-6);
    padding-left: var(--space-5);
    color: var(--band-fg);
    font-size: var(--fs-md);
    font-weight: var(--fw-medium);
    line-height: var(--lh-base);
}

.pullquote::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 3px;
    border-radius: var(--radius-pill);
    background: var(--rule-fill);
}

.empty-note {
    color: var(--band-fg-soft);
    font-size: var(--fs-md);
}


/* ─── Calls to action ─────────────────────────────────────── */
/* Ember and gold are a FILL carrying ash-dark text, or bright TEXT on the ash
   ground. Never white on gold — 1.77:1. */

.cta-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3) var(--space-6);
    margin-top: var(--space-7);
}

/* The primary CTA is the flame itself. --accent-ink on the gradient measures
   5.05:1 at the ember base and 10.96:1 at the gold crown, so the label holds AA
   across the whole button rather than only where it is brightest. */
.btn-flame {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 48px;
    padding: 0 var(--space-6);
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--flame);
    color: var(--text-on-accent);
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
    box-shadow: var(--shadow-2);
    transition: transform var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}

/* Lifts, never slides. */
.btn-flame:hover,
.btn-flame:focus-visible {
    transform: translateY(-2px);
    box-shadow: var(--shadow-3),
                0 0 0 1px color-mix(in srgb, var(--accent-bright) 70%, transparent);
}

.btn-flame:active {
    transform: translateY(0);
}

.btn-quiet {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 48px;
    color: var(--band-accent);
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 7px;
    text-decoration-color: color-mix(in srgb, var(--band-accent) 45%, transparent);
    transition: text-decoration-color var(--dur-base) var(--ease),
                color var(--dur-base) var(--ease);
}

.btn-quiet:hover {
    color: var(--band-hot);
    text-decoration-color: currentColor;
}


/* ─── 01 · Hero ───────────────────────────────────────────── */
/* Deliberately ash in both themes. It declares its own ground AND its own
   foreground ramp, so nothing here reads a theme-dependent token.

   Tall on purpose, with the content sitting low and the heat washing up from the
   bottom edge: the composition itself is "rising out of the ash". */

.hero {
    --band-fg:      var(--white);            /* 18.6:1 on --ink-900 */
    --band-fg-soft: var(--ink-200);          /* 12.1:1 */
    --band-accent:  var(--accent-bright);    /* 14.29:1 */
    --band-hot:     var(--ember-300);        /*  8.51:1 */
    --band-line:    color-mix(in srgb, var(--ember-400) 30%, transparent);
    --rule-fill:    var(--flame);

    position: relative;
    isolation: isolate;
    display: flex;
    align-items: flex-end;
    overflow: hidden;
    min-height: clamp(28rem, 68vh, 44rem);
    padding: clamp(3.5rem, 9vw, 7.5rem) var(--band-x) clamp(2.75rem, 6vw, 5rem);
    border-bottom: 1px solid var(--band-line);
    background: linear-gradient(180deg,
                var(--ink-950) 0%,
                var(--ink-900) 62%,
                var(--ink-850) 100%);
    color: var(--band-fg-soft);
}

/* The ember bed. --flame-soft is a 0deg gradient, so it is hot along the bottom
   edge and gone by 70% of the way up — the glow rises out of the ash rather than
   hanging over it. */
.hero::before {
    content: '';
    position: absolute;
    inset: auto 0 0 0;
    z-index: -1;
    height: 65%;
    background: var(--flame-soft);
    pointer-events: none;
}

/* A single low bloom, off to one side, so the bed is not perfectly symmetrical. */
.hero::after {
    content: '';
    position: absolute;
    right: -10%;
    bottom: -22%;
    z-index: -1;
    width: min(38rem, 80%);
    aspect-ratio: 1;
    background: radial-gradient(circle,
                color-mix(in srgb, var(--ember-500) 26%, transparent) 0%,
                transparent 68%);
    pointer-events: none;
}

.hero-inner {
    position: relative;
    max-width: 46rem;
}

.hero .lead {
    max-width: 54ch;
}

.hero-stats {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4) var(--space-8);
    margin-top: clamp(2.5rem, 5vw, 4rem);
    padding-top: var(--space-5);
    border-top: 1px solid var(--band-line);
}

.hero-stat dt {
    color: var(--band-fg-soft);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}

.hero-stat dd {
    margin-top: var(--space-1);
    color: var(--accent-bright);
    font-size: var(--fs-xl);
    font-weight: var(--fw-black);
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
}

/* The date is prose, not a number — it should not shout at display size. */
.hero-stat dd.is-date {
    font-size: var(--fs-md);
    font-weight: var(--fw-bold);
    letter-spacing: 0;
}


/* ─── Bands ───────────────────────────────────────────────── */
/* Base = light theme (cream ground). The .theme-dark block below is the dark
   half (ash ground). Both are complete: no band inherits a colour that exists in
   only one theme.

   Light-theme text pairings, measured on --ink-50 #f7f2ea:
     --ink-900 body/headline   17.0:1
     --ink-500 muted           8.70:1     (warm ash, not the cool legacy --text-2)
     --accent-deep accent      6.80:1
     --ember-600 hot           4.65:1 */

.band {
    --band-bg:      var(--ink-50);
    --band-fg:      var(--ink-900);
    --band-fg-soft: var(--ink-500);
    --band-accent:  var(--accent-deep);
    --band-hot:     var(--ember-600);
    --band-line:    color-mix(in srgb, var(--ink-900) 16%, transparent);
    --band-card:    var(--white);
    --rule-fill:    linear-gradient(0deg, var(--accent-deep) 0%, var(--ember-500) 100%);

    padding: var(--band-y) var(--band-x);
    background: var(--band-bg);
    color: var(--band-fg);
}

/* Dark-theme pairings, measured on --ink-900 #141017:
     --white body/headline     18.6:1
     --ink-200 muted           12.1:1
     --accent-bright accent    14.29:1
     --ember-300 hot            8.51:1 */
.theme-dark .band {
    --band-bg:      var(--ink-900);
    --band-fg:      var(--white);
    --band-fg-soft: var(--ink-200);
    --band-accent:  var(--accent-bright);
    --band-hot:     var(--ember-300);
    --band-line:    color-mix(in srgb, var(--ember-400) 24%, transparent);
    --band-card:    var(--ink-850);
    --rule-fill:    var(--flame);
}

/* ── DARK-LOCKED AND ALTERNATING BANDS ──
   These selectors are (0,2,0), the same weight as `.theme-dark .band` above,
   and they sit AFTER it, so they win in the dark theme on source order alone.
   That is what lets the override work with no importance flag — do not move
   this block above the .theme-dark rule. */

/* 04 — alternates against its neighbours in both themes by riding the semantic
   surface tokens, which already flip with the theme. */
.band.band-alt {
    --band-bg:   var(--surface-1);
    --band-card: var(--surface-2);
}

/* 03 — the drop. Ash in both themes, self-contained like the hero, with the same
   ember bed rising from its bottom edge. */
.band.band-drop {
    --band-bg:      var(--ink-950);
    --band-fg:      var(--white);
    --band-fg-soft: var(--ink-300);          /* 8.90:1 on the ash ground */
    --band-accent:  var(--accent-bright);
    --band-hot:     var(--ember-300);
    --band-line:    color-mix(in srgb, var(--ember-400) 28%, transparent);
    --band-card:    var(--ink-900);
    --rule-fill:    var(--flame);

    position: relative;
    isolation: isolate;
    overflow: hidden;
    border-block: 1px solid color-mix(in srgb, var(--ember-400) 28%, transparent);
}

.band.band-drop::before {
    content: '';
    position: absolute;
    inset: auto 0 0 0;
    z-index: -1;
    height: 55%;
    background: var(--flame-soft);
    pointer-events: none;
}

.band-head {
    position: relative;
    max-width: 72ch;
    margin-bottom: clamp(2rem, 4.5vw, 3.5rem);
}


/* ─── 02 · The library ────────────────────────────────────── */

/* Featured issue — split layout, cover one side, copy the other. The cover is
   the LCP element, which is why index.php marks it eager + fetchpriority=high
   and everything below it lazy. */
.lib-featured {
    display: grid;
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center;
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
    padding-bottom: clamp(2.5rem, 5vw, 4rem);
    border-bottom: 1px solid var(--band-line);
}

.lib-featured-media {
    position: relative;
    display: block;
    overflow: hidden;
    aspect-ratio: 2 / 3;
    border: 1px solid var(--band-line);
    border-radius: var(--radius-lg);
    background: var(--ink-900);
    box-shadow: var(--shadow-4);
    transition: transform var(--dur-slow) var(--ease-out),
                border-color var(--dur-base) var(--ease);
}

.lib-featured:hover .lib-featured-media,
.lib-featured:focus-visible .lib-featured-media {
    transform: translateY(-6px);
    border-color: var(--band-hot);
}

.lib-featured-copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
}

.lib-featured-title {
    display: block;
    color: var(--band-fg);
    font-size: var(--fs-xl);
    font-weight: var(--fw-black);
    line-height: var(--lh-snug);
    letter-spacing: var(--tracking-display);
    text-wrap: balance;
}

.lib-featured-note {
    display: block;
    max-width: 44ch;
    color: var(--band-fg-soft);
    font-size: var(--fs-base);
    line-height: 1.7;
}

/* The rest of the run. 8 covers on a 4-wide desktop grid = two clean rows. */
.lib-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
    gap: clamp(1rem, 2.4vw, 1.75rem);
    margin: 0;
    padding: 0;
    list-style: none;
}

.lib-item {
    min-width: 0;
}

.lib-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
    height: 100%;
}

.lib-cover {
    position: relative;
    display: block;
    width: 100%;
    overflow: hidden;
    aspect-ratio: 2 / 3;
    margin-bottom: var(--space-2);
    border: 1px solid var(--band-line);
    border-radius: var(--radius-md);
    background: var(--ink-900);
    box-shadow: var(--shadow-2);
    transition: transform var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease);
}

.lib-card:hover .lib-cover,
.lib-card:focus-visible .lib-cover {
    transform: translateY(-5px);
    border-color: var(--band-hot);
    box-shadow: var(--shadow-3);
}

/* lh_picture() emits <picture><source><img> when derivatives exist and a bare
   <img> when they do not. Both shapes have to fill the frame. */
.lib-cover picture,
.lib-featured-media picture,
.drop-media picture {
    position: absolute;
    inset: 0;
    display: block;
}

.lib-cover img,
.lib-featured-media img,
.drop-media img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cover-fallback {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-3);
    color: var(--ink-200);
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    text-align: center;
}

.lib-title {
    display: block;
    color: var(--band-fg);
    font-size: var(--fs-base);
    font-weight: var(--fw-bold);
    line-height: var(--lh-snug);
    letter-spacing: var(--tracking-display);
}

.lib-creator {
    display: block;
    color: var(--band-fg-soft);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-medium);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}

/* Not a link of its own — the whole card is one anchor, so there is still
   exactly one read.php?comic= href per comic. This is the affordance. */
.lib-read {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 44px;
    margin-top: auto;
    padding: 0 var(--space-4);
    border: 1px solid color-mix(in srgb, var(--band-accent) 45%, transparent);
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--band-accent) 12%, transparent);
    color: var(--band-accent);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    white-space: nowrap;
    transition: background var(--dur-base) var(--ease),
                color var(--dur-base) var(--ease),
                border-color var(--dur-base) var(--ease);
}

/* Fills solid gold on hover: --accent under --accent-ink measures 10.96:1. */
.lib-card:hover .lib-read,
.lib-card:focus-visible .lib-read,
.lib-featured:hover .lib-read,
.lib-featured:focus-visible .lib-read {
    border-color: var(--accent);
    background: var(--accent);
    color: var(--text-on-accent);
}

.lib-featured .lib-read {
    min-height: 48px;
    margin-top: var(--space-2);
    padding: 0 var(--space-6);
    font-size: var(--fs-sm);
}


/* ─── 03 · The drop ───────────────────────────────────────── */

.drop-grid {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: clamp(1rem, 2.4vw, 1.75rem);
    margin: 0;
    padding: 0;
    list-style: none;
}

.drop-item {
    min-width: 0;
}

.drop-tile {
    position: relative;
    display: block;
    overflow: hidden;
    aspect-ratio: 4 / 3;
    border: 1px solid var(--band-line);
    border-radius: var(--radius-lg);
    background: var(--ink-900);
    box-shadow: var(--shadow-3);
    transition: transform var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease);
}

.drop-tile:hover,
.drop-tile:focus-visible {
    transform: translateY(-5px);
    border-color: var(--band-hot);
    box-shadow: var(--shadow-4);
}

.drop-media {
    position: absolute;
    inset: 0;
    display: block;
}

/* The scrim is ash, not black — box art should sit in the same warm ground as
   everything else on the page. */
.drop-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--space-1);
    padding: var(--space-5);
    background: linear-gradient(to top,
                color-mix(in srgb, var(--ink-950) 93%, transparent) 0%,
                color-mix(in srgb, var(--ink-950) 58%, transparent) 46%,
                transparent 82%);
}

.drop-name {
    display: block;
    color: var(--white);
    font-size: var(--fs-lg);
    font-weight: var(--fw-black);
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
}

.drop-blurb {
    display: block;
    color: var(--ink-200);
    font-size: var(--fs-sm);
    line-height: var(--lh-snug);
}

.drop-cta {
    display: block;
    margin-top: var(--space-2);
    color: var(--accent-bright);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}


/* ─── 04 · Transmissions ──────────────────────────────────── */
/* The three X embeds. shared.js stamps data-theme on each blockquote from the
   theme class before widgets.js reads it, so the embeds follow the site theme;
   the blockquote markup itself is left frozen for that initial scan. The cells
   only set the track and the vertical date rule. */

.tx-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: clamp(1.5rem, 3vw, 2.5rem);
    align-items: start;
}

.tx-cell {
    min-width: 0;
}

.tx-date {
    position: relative;
    display: block;
    margin-bottom: var(--space-4);
    padding-left: var(--space-4);
    color: var(--band-fg-soft);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}

/* The vertical motif once more, at label scale. */
.tx-date::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 3px;
    border-radius: var(--radius-pill);
    background: var(--rule-fill);
}

.tx-embed {
    width: 100%;
    overflow: hidden;
}


/* ─── 05 · Support ────────────────────────────────────────── */

.coin-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: clamp(1rem, 2.4vw, 1.75rem);
    margin: 0;
    padding: 0;
    list-style: none;
}

.coin-card {
    /* Brand coin colours are semantically fixed — they belong to other projects
       and are not ours to restyle, so they are identical in both themes. Only
       the card's own ground follows the band. */
    --coin: var(--ltc);
    --coin-ink: var(--white);

    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    overflow: hidden;
    min-width: 0;
    padding: var(--space-6);
    border: 1px solid var(--band-line);
    border-radius: var(--radius-lg);
    background: var(--band-card);
    box-shadow: var(--shadow-2);
    transition: transform var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease);
}

.coin-card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--coin) 55%, transparent);
    box-shadow: var(--shadow-3);
}

.coin-card::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 88% 6%,
                color-mix(in srgb, var(--coin) 20%, transparent) 0%,
                transparent 62%);
    pointer-events: none;
}

/* Re-measured against the new --accent-ink #0b0a10: ash-dark on the Bitcoin
   orange is 8.59:1 and on the Doge gold 8.27:1, while on the Litecoin blue it
   would be only 3.04:1 — so LTC keeps white (6.40:1) and the other two take the
   ash ink. White on orange would have been 2.26:1, which is what this replaces. */
.coin-card.is-btc {
    --coin: var(--btc);
    --coin-ink: var(--accent-ink);
}

.coin-card.is-doge {
    --coin: var(--doge);
    --coin-ink: var(--accent-ink);
}

.coin-head {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.coin-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-pill);
    background: var(--coin);
    color: var(--coin-ink);
    font-size: var(--fs-lg);
    font-weight: var(--fw-black);
    line-height: 1;
}

.coin-id {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.coin-name {
    color: var(--band-fg);
    font-size: var(--fs-md);
    font-weight: var(--fw-black);
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
    text-transform: uppercase;
}

.coin-ticker {
    color: var(--band-fg-soft);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}

.coin-desc {
    position: relative;
    color: var(--band-fg-soft);
    font-size: var(--fs-sm);
    line-height: var(--lh-base);
}

/* copyWallet() in shared.js swaps this button's text to "COPIED" and sets an
   inline green background, then restores both. aria-live="polite" on the button
   in the markup is what makes that swap audible — the site has no other live
   region, and a silent confirmation is no confirmation at all.

   Solid gold rather than the flame here: three gradient buttons in one row would
   fight the section headline, and the inline background JS sets on copy replaces
   a flat colour more gracefully than a gradient. */
.coin-copy {
    position: relative;
    width: 100%;
    min-height: 48px;
    margin-top: auto;
    padding: var(--space-3) var(--space-4);
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--accent);
    color: var(--text-on-accent);
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--dur-base) var(--ease),
                transform var(--dur-base) var(--ease-out);
}

.coin-copy:hover {
    background: var(--accent-bright);
    transform: translateY(-2px);
}

.coin-copy:active {
    transform: translateY(0);
}


/* ─── Entry points — the doors ────────────────────────────── */
/* The centre of the hub. Four parallel routes out of the homepage, each a real
   page rather than an in-page anchor. The vertical flame rule on each card sits
   at 45% and grows to full height on hover and focus — the rising motif turned
   into the affordance itself. */

.door-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: clamp(1rem, 2.4vw, 1.75rem);
    margin: 0;
    padding: 0;
    list-style: none;
}

.door-item {
    min-width: 0;
}

.door {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    overflow: hidden;
    height: 100%;
    min-height: 11rem;
    padding: var(--space-5) var(--space-5) var(--space-5) var(--space-6);
    border: 1px solid var(--band-line);
    border-radius: var(--radius-lg);
    background: var(--band-card);
    box-shadow: var(--shadow-2);
    transition: transform var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease);
}

.door::before {
    content: '';
    position: absolute;
    top: var(--space-5);
    bottom: var(--space-5);
    left: 0;
    width: 3px;
    border-radius: var(--radius-pill);
    background: var(--rule-fill);
    transform: scaleY(0.45);
    transform-origin: bottom;
    transition: transform var(--dur-base) var(--ease-out);
}

.door:hover,
.door:focus-visible {
    transform: translateY(-5px);
    border-color: var(--band-hot);
    box-shadow: var(--shadow-3);
}

.door:hover::before,
.door:focus-visible::before {
    transform: scaleY(1);
}

.door-name {
    display: block;
    color: var(--band-fg);
    font-size: var(--fs-lg);
    font-weight: var(--fw-black);
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
    text-transform: uppercase;
}

.door-desc {
    display: block;
    color: var(--band-fg-soft);
    font-size: var(--fs-sm);
    line-height: var(--lh-base);
}

.door-go {
    display: block;
    margin-top: auto;
    padding-top: var(--space-3);
    color: var(--band-accent);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}


/* ─── A taste, not the whole thing ────────────────────────── */
/* The homepage shows a few covers and the newest transmission side by side, each
   with a link onward. The components are the same .lib-card and .tx-cell the
   full pages use, so the hub and its destinations cannot drift apart. */

.latest-split {
    display: grid;
    grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
}

.latest-col {
    min-width: 0;
}

.latest-col .kicker {
    margin-bottom: var(--space-4);
}

/* Three-up regardless of the page-level .lib-grid breakpoints — this selector is
   (0,2,0) and beats the (0,1,0) rules in the media queries below. */
.latest-col .lib-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.latest-foot {
    margin-top: var(--space-5);
}


/* ─── Compact page head ───────────────────────────────────── */
/* comics.php and donate.php reuse the hero verbatim — same ash ground, same
   ember bed, same flame accent word — at a height that suits a page that has
   real content directly beneath it rather than a fold to fill. */

.hero.is-compact {
    min-height: 0;
    padding-top: clamp(2.5rem, 6vw, 4.5rem);
    padding-bottom: clamp(2rem, 4.5vw, 3.25rem);
}


/* ─── Responsive ──────────────────────────────────────────── */

@media (max-width: 760px) {
    .hero {
        min-height: clamp(24rem, 62vh, 34rem);
    }

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

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

    .lib-featured-media {
        max-width: 17rem;
    }

    .hero-stats {
        gap: var(--space-4) var(--space-6);
    }
}

@media (max-width: 560px) {
    /* Deterministic two-up rather than auto-fill, which collapses to a single
       very wide column once .app-window is down to phone width. */
    .lib-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .tx-grid,
    .drop-grid,
    .coin-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .cta-row {
        gap: var(--space-4);
    }

    .btn-flame,
    .btn-quiet {
        width: 100%;
    }

    .btn-quiet {
        justify-content: center;
    }
}

@media (min-width: 1000px) {
    /* Eight remaining covers land as two full rows of four. */
    .lib-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .lib-featured {
        grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    }
}

/* ─── Creator portrait (creator.php) ─────────────────────────
   Sits above the eyebrow on the hero. Circular, ember-ringed, and sized in rem
   so it scales with the type rather than against it. width/height are on the
   element itself so the box is reserved before the image decodes — the last
   commit before this redesign was a layout-shift fix and it is not being undone
   by a portrait. */
.creator-portrait {
    display: block;
    width: clamp(88px, 11vw, 132px);
    height: clamp(88px, 11vw, 132px);
    border-radius: var(--radius-pill);
    object-fit: cover;
    margin-bottom: var(--space-5);
    border: 2px solid var(--accent);
    box-shadow: var(--shadow-3);
}
.theme-dark .creator-portrait { border-color: var(--ember-400); }

/* The vertical flame rule on .hero-inner would otherwise start above the
   portrait and read as unrelated to the headline. */
.hero.has-portrait .hero-inner::before { display: none; }

.creator-stats { margin-top: var(--space-6); }

/* ─── Origin pullquote (creator.php) ─────────────────────────
   The flame rule is on the LEFT edge and runs bottom-to-top, so the quote reads
   as rising out of the paragraph above it — the same direction as every other
   accent on the site. */
.creator-pull {
    position: relative;
    margin: var(--space-6) 0 0;
    padding: var(--space-2) 0 var(--space-2) var(--space-5);
    max-width: 44ch;
    font-family: var(--font-serif);
    font-style: italic;
    font-size: var(--fs-lg);
    line-height: var(--lh-snug);
    color: var(--text-1);
}
.creator-pull::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    border-radius: var(--radius-pill);
    background: var(--flame);
}
.theme-dark .creator-pull { color: var(--white); }

/* ─── Figurine showcase (index.php, the drop band) ───────────
   The band used to be three category tiles — a picture of a category standing in
   for the best art on the site. This is the actual pieces, one per community, so
   the homepage shows range rather than a label.

   auto-fit rather than a fixed column count: six figures on a wide screen, and it
   reflows to two on a phone without a breakpoint per size. */
.fig-showcase {
    list-style: none;
    margin: var(--space-6) 0 0;
    padding: 0;
    display: grid;
    /* Fixed counts, not auto-fit. There are six figures — one per community —
       and auto-fit at this container width resolved to five columns, orphaning
       the sixth on a row of its own. Every count here divides six evenly. */
    grid-template-columns: repeat(6, 1fr);
    gap: var(--space-4);
}
@media (max-width: 1180px) { .fig-showcase { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px)  { .fig-showcase { grid-template-columns: repeat(2, 1fr); } }

.fig-show {
    display: flex;
    flex-direction: column;
    height: 100%;
    text-decoration: none;
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: border-color var(--dur-base) var(--ease),
                transform var(--dur-base) var(--ease-out);
}
/* Upward on hover, like everything else on this site. */
.fig-show:hover { border-color: var(--accent); transform: translateY(-4px); }
.theme-dark .fig-show { background: var(--surface-2); }

.fig-show-media { display: block; position: relative; background: var(--surface-sunken); }
.fig-show-media img { display: block; width: 100%; height: auto; }
/* Ember banked along the base of the art, growing on approach. */
.fig-show-media::after {
    content: "";
    position: absolute; inset: auto 0 0 0; height: 3px;
    background: var(--flame);
    transform: scaleX(0); transform-origin: left;
    transition: transform var(--dur-base) var(--ease-out);
}
.fig-show:hover .fig-show-media::after,
.fig-show:focus-visible .fig-show-media::after { transform: scaleX(1); }

.fig-show-body { display: block; padding: var(--space-3) var(--space-4) var(--space-4); }
.fig-show-community {
    display: block;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-black);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--accent-deep);
    margin-bottom: 2px;
}
.theme-dark .fig-show-community { color: var(--accent-bright); }
.fig-show-name {
    display: block;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: var(--fs-lg);
    line-height: var(--lh-tight);
    letter-spacing: 0.01em;
    text-transform: uppercase;
    color: var(--text-1);
}
.fig-show-sub {
    display: block;
    font-size: var(--fs-xs);
    color: var(--text-3);
    margin-top: 2px;
}
.fig-show-more { margin-top: var(--space-5); }

/* ─── Legal pages (privacy.php, terms.php) ───────────────────
   Long-form prose, so the measure is capped at ~68ch — the rest of the site is
   short copy in wide bands and that line length is unreadable for paragraphs. */
.legal-prose { max-width: 68ch; }
.legal-prose h3 {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: var(--fs-md);
    letter-spacing: 0.01em;
    text-transform: uppercase;
    color: var(--text-1);
    margin: var(--space-6) 0 var(--space-2);
}
.legal-prose h3:first-child { margin-top: 0; }
.legal-prose p {
    color: var(--text-2);
    font-size: var(--fs-base);
    line-height: var(--lh-base);
    margin-bottom: var(--space-4);
}
.legal-prose strong { color: var(--text-1); font-weight: var(--fw-bold); }
.legal-prose a { color: var(--accent-deep); text-decoration: underline; }
.theme-dark .legal-prose a { color: var(--accent-bright); }
.legal-prose code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.92em;
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text-1);
}
.theme-dark .legal-prose code { background: var(--surface-sunken); }

.legal-updated {
    margin-top: var(--space-4);
    font-size: var(--fs-xs);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-3);
}
.legal-note {
    border-left: 3px solid var(--accent);
    padding-left: var(--space-4);
    color: var(--text-3);
    font-size: var(--fs-sm);
}

/* ─── Footer legal nav ───────────────────────────────────────
   Sits between the copyright line and the socials. These links used to be
   hardcoded href="#" in four separate callers. */
.footer-legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    font-size: var(--fs-xs);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    font-weight: var(--fw-bold);
}
.footer-legal a { color: var(--text-3); text-decoration: none; }
.footer-legal a:hover { color: var(--accent-deep); }
.theme-dark .footer-legal a:hover { color: var(--accent-bright); }

/* ─── Letting the phoenix through (index.php only) ───────────
   The bird is fixed behind the page at z-index -1, above .app-window's own
   background. That is not enough on its own: every band paints its own OPAQUE
   ground on top of it, so the bird was correctly rendered, correctly positioned,
   and completely invisible below the hero.

   The fix is to make the bands translucent rather than to move the bird in front
   of them. Putting it in front would mean blending it over live text, and the
   contrast budget for that is far tighter than for a background.

   Scoped to .home-with-phoenix so it can only affect the homepage — the other
   pages share this stylesheet and their bands stay solid. 88% keeps each band
   reading as its own surface; the bird shows as a shape moving beneath glass. */
.home-with-phoenix .band {
    background: color-mix(in srgb, var(--band-bg) 72%, transparent);
}
/* The hero already layers its own gradient and glows, so it gets a lighter
   touch — its top stop is the page ground and needs to stay readable. */
.home-with-phoenix .hero {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--ink-950) 82%, transparent) 0%,
        color-mix(in srgb, var(--ink-950) 62%, transparent) 55%,
        color-mix(in srgb, var(--ink-950) 78%, transparent) 100%);
}


/* ═══ The auction ══════════════════════════════════════════════════════
   Used by the homepage band (index.php) and by auction.php.

   Like .band-drop, this band is ash in BOTH themes and carries its own
   foreground ramp, so nothing here depends on which theme is active. That is
   deliberate: an auction is the drop's sibling and should read as the same
   kind of moment, and a lot photographed on black does not belong on cream.

   Contrast on the ash ground, checked not assumed:
     --accent-bright  #ffd774  14.29:1   the bid figure, the largest number
     --ink-300        #b9aab5   8.90:1   labels and muted copy
     --ember-300      #ff8c3a   8.51:1   the live dot and the leading tag
   --ember-700 stays decorative and never carries text, as everywhere else.
   ═══════════════════════════════════════════════════════════════════ */

.band.band-auction {
    --band-bg:      var(--ink-950);
    --band-fg:      var(--white);
    --band-fg-soft: var(--ink-300);
    --band-accent:  var(--accent-bright);
    --band-hot:     var(--ember-300);
    --band-line:    color-mix(in srgb, var(--ember-400) 28%, transparent);
    --band-card:    var(--ink-900);
    --rule-fill:    var(--flame);

    position: relative;
    isolation: isolate;
    overflow: hidden;
    border-block: 1px solid color-mix(in srgb, var(--ember-400) 34%, transparent);
}

/* The same rising ember bed as the drop, but seated at the top edge. The drop
   closes the page and rises out of it; the auction opens under the hero and
   should feel lit from where the hero left off. */
.band.band-auction::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    z-index: -1;
    height: 60%;
    background: linear-gradient(180deg,
        rgba(232, 72, 28, 0.20) 0%,
        rgba(255, 215, 116, 0) 100%);
    pointer-events: none;
}

/* ─── The bid board ───────────────────────────────────────────
   The one component shared by the homepage band and the lot page. It is a card
   rather than loose text because the number on it is the single thing a visitor
   came to read, and it has to survive being dropped into two different columns
   without re-tuning. */
.auc-board {
    background: var(--band-card, var(--surface-2));
    border: 1px solid var(--band-line, var(--border-1));
    border-radius: var(--radius-lg);
    padding: clamp(1.1rem, 2.6vw, 1.6rem);
    display: grid;
    gap: 0.75rem;
    align-content: start;
}

.auc-status {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--band-hot, var(--accent-deep));
}

.auc-dot {
    width: 8px; height: 8px;
    border-radius: 999px;
    background: currentColor;
    box-shadow: 0 0 0 0 currentColor;
    animation: auc-pulse 2s ease-out infinite;
}

.auc-board.is-closed .auc-status { color: var(--band-fg-soft, var(--text-2)); }
.auc-board.is-closed .auc-dot    { animation: none; opacity: 0.6; }

@keyframes auc-pulse {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 55%, transparent); }
    70%  { box-shadow: 0 0 0 9px color-mix(in srgb, currentColor 0%, transparent); }
    100% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 0%, transparent); }
}

/* The dot is the only moving thing on the page. Honour the OS setting: a
   pulsing ring beside a countdown is exactly the kind of motion people turn
   off, and the word "Auction live" already carries the meaning. */
@media (prefers-reduced-motion: reduce) {
    .auc-dot { animation: none; }
}

.auc-figure {
    margin: 0;
    display: grid;
    gap: 0.2rem;
}

.auc-figure-label,
.auc-clock-label {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--band-fg-soft, var(--text-2));
}

.auc-figure-amount {
    font-family: var(--font-display);
    font-weight: 400;
    line-height: 0.95;
    /* Clamped so the number stays the biggest thing in the card at every width
       without pushing the card wider than its column on a phone. */
    font-size: clamp(2.6rem, 7vw, 4.2rem);
    color: var(--band-accent, var(--accent-deep));
    letter-spacing: 0.01em;
}

.auc-ccy {
    font-size: 0.38em;
    letter-spacing: 0.1em;
    vertical-align: 0.55em;
    color: var(--band-fg-soft, var(--text-2));
}

.auc-figure-holder {
    font-size: 0.92rem;
    color: var(--band-fg-soft, var(--text-2));
}

.auc-figure-holder a {
    color: var(--band-fg, var(--text-1));
    font-weight: 700;
    text-underline-offset: 3px;
}

.auc-clock {
    margin: 0;
    display: grid;
    gap: 0.2rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--band-line, var(--border-1));
}

.auc-clock-value {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--band-fg, var(--text-1));
}

/* Set by shared.js once the countdown is under an hour. Nothing depends on it
   for meaning — it is emphasis on information already in the text. */
.auc-clock-value.is-urgent { color: var(--band-hot, var(--accent-deep)); }

.auc-next {
    margin: 0;
    font-size: 0.88rem;
    color: var(--band-fg-soft, var(--text-2));
}

.auc-next strong { color: var(--band-fg, var(--text-1)); }

/* ─── Homepage teaser ─────────────────────────────────────────
   Image and board side by side, stacking under 780px. The image is
   aria-hidden and tabindex=-1: it is the same destination as the "See the lot"
   button directly beside it, so exposing it as a second link would make a
   keyboard user tab twice through one idea. */
.auc-teaser {
    display: grid;
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    gap: clamp(1.25rem, 3.5vw, 2.5rem);
    align-items: center;
}

.auc-teaser-media {
    display: block;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--band-line, var(--border-1));
    background: var(--ink-900);
}

.auc-teaser-media img { display: block; width: 100%; height: auto; }

.auc-teaser-body {
    display: grid;
    gap: 1.25rem;
}

@media (max-width: 780px) {
    .auc-teaser { grid-template-columns: minmax(0, 1fr); }
    .auc-teaser-media { max-width: 260px; }
}

/* ─── The lot page ────────────────────────────────────────────*/

/* The board sits inside the compact hero on auction.php, where it must not
   stretch to the full 72ch measure of the hero copy above it. */
.auc-hero .auc-board { max-width: 26rem; }

/* Board and bid button, side by side once there is room for both.
   Stacked, the button landed at 962px on a 1440x900 laptop — below the fold,
   which is what the link was moved up here to avoid. The board is only 26rem
   wide, so the space beside it was already there. Below 900px they stack, and
   the button follows the number rather than preceding it. */
.auc-hero-act {
    display: grid;
    gap: clamp(1.25rem, 2.5vw, 2rem);
    margin-top: clamp(1.5rem, 3vw, 2.25rem);
    align-items: center;
}

/* .cta-row carries margin-top: var(--space-7) globally, which inside this grid
   would offset the button within its own cell and defeat align-items: center.
   The wrapper owns the spacing here. */
.auc-hero-act .cta-row { margin-top: 0; }

/* Short laptops. At 1366x768 — still one of the most common desktop sizes — the
   bid button's bottom edge landed at 779px against a 768px fold, missing by 11.
   Keyed on viewport HEIGHT, not width, because that is the actual constraint:
   a wide-but-short window has the same problem and a tall narrow one does not.
   Only the hero's own padding gives way; nothing inside the board moves. */
@media (min-width: 900px) and (max-height: 820px) {
    .hero.is-compact.auc-hero {
        padding-top: clamp(1.75rem, 4vh, 2.75rem);
        padding-bottom: clamp(1.5rem, 3vh, 2.5rem);
    }
    /* The last 20px, which is what 1280x720 was short by. */
    .auc-hero .auc-hero-act { margin-top: 1rem; }
}

@media (min-width: 900px) {
    .auc-hero-act {
        grid-template-columns: minmax(0, 26rem) minmax(0, 1fr);
    }
    /* Two buttons in a column narrower than the copy measure: let them stack
       rather than squeeze onto one line and wrap mid-label. */
    .auc-hero-act .cta-row {
        flex-direction: column;
        align-items: flex-start;
    }
}

.auc-lot {
    display: grid;
    grid-template-columns: minmax(0, 460px) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: start;
}

.auc-lot-media {
    margin: 0;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--band-line, var(--border-1));
    background: var(--ink-900);
}

.auc-lot-media img { display: block; width: 100%; height: auto; }

/* The "painted Lester not included" line. It is a caption and not a footnote
   because it corrects what the photograph appears to promise, and a reader who
   only looks at the picture is exactly the reader who needs it. */
.auc-lot-caption {
    padding: 0.8rem 1rem;
    font-size: 0.85rem;
    line-height: 1.45;
    color: var(--band-fg-soft, var(--text-2));
    border-top: 1px solid var(--band-line, var(--border-1));
}

.auc-lot-facts {
    margin: 0;
    display: grid;
    gap: 0;
}

.auc-fact {
    display: grid;
    grid-template-columns: minmax(7rem, 30%) minmax(0, 1fr);
    gap: 1rem;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--band-line, var(--border-1));
}

.auc-fact:first-child { border-top: 1px solid var(--band-line, var(--border-1)); }

.auc-fact dt {
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--band-fg-soft, var(--text-2));
    align-self: center;
}

.auc-fact dd {
    margin: 0;
    color: var(--band-fg, var(--text-1));
    align-self: center;
}

@media (max-width: 800px) {
    .auc-lot { grid-template-columns: minmax(0, 1fr); }
}

/* ─── How to bid ──────────────────────────────────────────────*/
.auc-steps {
    list-style: none;
    margin: 0 0 clamp(1.5rem, 3vw, 2rem);
    padding: 0;
    display: grid;
    gap: 1rem;
    counter-reset: none;
}

.auc-steps li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

.auc-step-n {
    display: grid;
    place-items: center;
    width: 2.1rem; height: 2.1rem;
    border-radius: 999px;
    border: 1px solid var(--band-line, var(--border-1));
    font-family: var(--font-display);
    font-size: 1.05rem;
    color: var(--band-accent, var(--accent-deep));
    background: var(--band-card, var(--surface-2));
}

.auc-step-b { line-height: 1.55; color: var(--band-fg-soft, var(--text-2)); }
.auc-step-b strong { color: var(--band-fg, var(--text-1)); }

.auc-thread-link { margin: 0; }

/* ─── Bid history ─────────────────────────────────────────────*/
.auc-history {
    list-style: none;
    margin: 0 0 1.5rem;
    padding: 0;
    display: grid;
    gap: 0;
}

.auc-bid {
    display: grid;
    grid-template-columns: minmax(6rem, auto) minmax(0, 1fr) auto auto;
    gap: 0.75rem 1rem;
    align-items: baseline;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--band-line, var(--border-1));
}

.auc-bid:first-child { border-top: 1px solid var(--band-line, var(--border-1)); }

.auc-bid-amount {
    font-family: var(--font-display);
    font-size: 1.5rem;
    line-height: 1;
    color: var(--band-fg, var(--text-1));
}

.auc-bid.is-top .auc-bid-amount { color: var(--band-accent, var(--accent-deep)); }

.auc-bid-who { font-weight: 700; text-underline-offset: 3px; }

.auc-bid-when {
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
    color: var(--band-fg-soft, var(--text-2));
}

.auc-bid-tag {
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
    color: var(--accent-ink);
    background: var(--accent);
}

@media (max-width: 640px) {
    .auc-bid {
        grid-template-columns: minmax(0, 1fr) auto;
        row-gap: 0.35rem;
    }
    .auc-bid-amount { grid-column: 1 / -1; }
}

.auc-source {
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--band-fg-soft, var(--text-2));
    max-width: 62ch;
    margin: 0 0 clamp(1.5rem, 3vw, 2rem);
}

/* ─── Upcoming (announced, not yet open) ──────────────────────
   The dot goes gold rather than ember: "announced" is a calmer state than
   "live", and the two must not read identically at a glance. */
.auc-board.is-upcoming .auc-status { color: var(--band-accent, var(--accent-deep)); }

/* "TBA" where a bid figure would be. It is display type, not a number, so it
   sets a little smaller than the amount and does not use tabular figures. */
.auc-figure-tba {
    font-family: var(--font-display);
    font-weight: 400;
    line-height: 0.95;
    font-size: clamp(2.1rem, 5.4vw, 3.2rem);
    letter-spacing: 0.02em;
    color: var(--band-accent, var(--accent-deep));
}

/* With no photograph there is no image column to sit beside. */
.auc-teaser.is-bare { grid-template-columns: minmax(0, 1fr); }

/* The tease band lists its facts full width rather than beside a photo. */
.auc-facts-wide {
    max-width: 62ch;
}

/* ─── Past lots ───────────────────────────────────────────────*/
.auc-archive {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: clamp(1rem, 2.5vw, 1.5rem);
}

.auc-past {
    display: grid;
    grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
    gap: clamp(1rem, 3vw, 2rem);
    align-items: center;
    padding: clamp(1rem, 2.5vw, 1.4rem);
    border: 1px solid var(--band-line, var(--border-1));
    border-radius: var(--radius-lg);
    background: var(--band-card, var(--surface-2));
}

.auc-past-media {
    display: block;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--ink-900);
}

.auc-past-media img { display: block; width: 100%; height: auto; }

.auc-past-body { display: grid; gap: 0.35rem; }

.auc-past-name {
    font-family: var(--font-display);
    font-size: clamp(1.3rem, 3vw, 1.9rem);
    line-height: 1;
    text-transform: uppercase;
    color: var(--band-fg, var(--text-1));
}

.auc-past-sub {
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--band-fg-soft, var(--text-2));
}

.auc-past-sold { font-size: 0.95rem; color: var(--band-fg-soft, var(--text-2)); }
.auc-past-sold strong { color: var(--band-accent, var(--accent-deep)); }

.auc-past-link {
    margin-top: 0.3rem;
    font-size: 0.85rem;
    font-weight: 700;
    text-underline-offset: 3px;
}

@media (max-width: 620px) {
    .auc-past { grid-template-columns: minmax(0, 1fr); }
    .auc-past-media { max-width: 190px; }
}
