  /* ─── Landing photons — rising warm-amber motes matching the game-over
     field. Three size tiers + per-photon brightness cap + occasional
     cool (cyan / pink) tints for palette variety. CSS-only animation
     means the layer costs nothing on CPU beyond the compositor. */
  #landing-photons {
    position: absolute; inset: 0; pointer-events: none;
    z-index: 0; overflow: hidden;
  }
  /* Space-warp photon — origin pinned at viewport centre, animation
     translates outward along a per-photon vector (--tx, --ty set in JS),
     scaling up + fading as it approaches the camera. Reads as a starship
     POV traveling through space rather than a rising-mote field. */
  .landing-photon {
    /* Origin defaults to viewport centre but the JS in src/landing-scene.js
       updates --photon-cx / --photon-cy on the parent #landing-photons layer
       to the title image's centre on load + resize, so the warp emanates
       from behind the polygonal title rather than dead-centre on screen. */
    position: absolute;
    left: var(--photon-cx, 50%);
    top: var(--photon-cy, 50%);
    border-radius: 50%;
    background: radial-gradient(circle,
      rgba(255, 240, 200, calc(0.9 * var(--lp-bright, 0.8))) 0%,
      rgba(255, 200, 120, calc(0.5 * var(--lp-bright, 0.8))) 45%,
      rgba(255, 180, 90, 0) 75%);
    box-shadow: 0 0 6px rgba(255, 210, 140, 0.4);
    opacity: 0;
    will-change: transform, opacity;
    animation: landing-photon-warp linear infinite;
  }
  .landing-photon[data-tint="cyan"] {
    background: radial-gradient(circle,
      rgba(200, 240, 255, calc(0.9 * var(--lp-bright, 0.8))) 0%,
      rgba(120, 200, 240, calc(0.5 * var(--lp-bright, 0.8))) 45%,
      rgba(90, 160, 220, 0) 75%);
    box-shadow: 0 0 6px rgba(140, 210, 245, 0.4);
  }
  .landing-photon[data-tint="pink"] {
    background: radial-gradient(circle,
      rgba(255, 220, 240, calc(0.9 * var(--lp-bright, 0.8))) 0%,
      rgba(255, 160, 200, calc(0.5 * var(--lp-bright, 0.8))) 45%,
      rgba(220, 110, 170, 0) 75%);
    box-shadow: 0 0 6px rgba(255, 170, 200, 0.4);
  }
  @keyframes landing-photon-warp {
    0%   { transform: translate(-50%, -50%) translate(0, 0) scale(0.05); opacity: 0; }
    8%   { opacity: 1; }
    70%  { opacity: 1; }
    100% {
      transform: translate(-50%, -50%)
                 translate(var(--tx, 0), var(--ty, 0))
                 scale(2.4);
      opacity: 0;
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .landing-photon { animation: none; opacity: 0; }
  }
  /* Subtle animated torch flicker over the image */
  #overlay-bg::after {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(ellipse 60% 40% at 50% 85%, rgba(255,160,80,0.18), transparent 70%);
    mix-blend-mode: screen;
    animation: torchFlicker 2.8s ease-in-out infinite;
  }
  @keyframes torchFlicker {
    0%, 100% { opacity: 0.8; }
    50%      { opacity: 1.0; }
    23%      { opacity: 0.65; }
    72%      { opacity: 0.9; }
  }
  /* Layout: portrait stacks one column under the title; landscape splits
     into two columns (title left, content stack right). Both branches use
     the same flex children — the body.landscape class flips the grid mode
     so the same DOM works for both. */
  #overlay-content {
    display: flex; flex-direction: column; align-items: center;
    padding: 32px 24px;
    max-width: 560px; text-align: center;
    gap: 18px;
  }
  /* Portrait — title pinned (with breathing room) at top, relic + play
     group anchored at the bottom (2x further from the device edge so
     PLAY isn't crowded by the home indicator). min-height fills the
     overlay; margin-top:auto on the bottom group eats the slack. */
  body.portrait #overlay-content {
    min-height: 100%;
    width: 100%;
    justify-content: flex-start;
    /* Bottom inset 80 → 104 (+30%) so RELIC + PLAY ride higher above the
       device bottom edge. The env() addition handles iOS home indicators;
       on Android the per-flavor override below pins the padding to a
       constant so the buttons don't visibly hop when the system nav bar
       transient-shows (it auto-hides in 3s anyway). */
    padding-bottom: calc(104px + env(safe-area-inset-bottom, 0px));
  }
  /* Android: ignore the dynamic bottom inset so RELIC + PLAY hold
     position when the system nav bar transient-shows. The bar is
     temporary (3s auto-hide via flavors/android/shim.js); letting the
     padding chase the inset made the buttons visibly hop up + down on
     every swipe-from-bottom-edge. The bottom-fade gradient
     (.flavor-android body::after) keeps the bar's icons readable
     without needing the layout to react to its appearance. */
  html.flavor-android body.portrait #overlay-content {
    padding-bottom: 104px;
  }
  body.portrait .landing-title-col {
    /* +115px on top of the existing 32px overlay-content padding-top
       so the title icon sits ~147px from the top of the safe area —
       trimmed 10% from the previous 128px to lift the title slightly. */
    margin-top: 115px;
  }
  body.portrait .landing-content-col {
    margin-top: auto;
    /* Tighten relic→PLAY from 14 → 10 (~30% closer) so the bottom
       cluster reads as one tight unit. */
    gap: 10px;
  }
  body.landscape #overlay-content {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: clamp(18px, 4vw, 48px);
    align-items: center;
    max-width: min(1240px, 92vw);
    text-align: left;
  }
  /* On very short landscape viewports (eg phone landscape ~390px tall) the
     vertically-centered content collides with the top-right utility cluster.
     Top-align + reserved top padding gives the utility row a guaranteed lane,
     and we cap the right column's max-width so it doesn't run under the
     cluster horizontally either. */
  @media (orientation: landscape) and (max-height: 540px) {
    body.landscape #overlay-content {
      align-items: start;
      padding-top: 64px;
      padding-bottom: 14px;
    }
    .landing-title-img { width: clamp(220px, 30vw, 360px); }
    .landing-content-col { gap: 8px; max-width: 100%; }
    .landing-panel { padding: 9px 14px; font-size: 12px; }
    #overlay p { font-size: 12.5px; line-height: 1.45; }
    .req-hint { font-size: 10.5px !important; }
    #overlay #start-btn { padding: 11px 42px; font-size: 16px; letter-spacing: 3px; }
    /* Compact the cluster on short landscape to free horizontal room. */
    #landing-top-right-utils { gap: 6px; }
    #landing-top-right-utils .rankings-label,
    #landing-top-right-utils .settings-label { display: none; }
  }
  .landing-title-col {
    display: flex; align-items: center; justify-content: center;
    width: 100%;
    /* Extra space below the title only — bumps the title→relic gap to
       18px (parent flex gap) + 54px (this margin) = 72px (doubled from
       the previous 36px state) without affecting the relic→PLAY gap
       which lives inside .landing-content-col at its own 14px. */
    margin-bottom: 54px;
  }
  body.landscape .landing-title-col { justify-content: flex-end; padding-right: 8px; }
  .landing-content-col {
    display: flex; flex-direction: column; align-items: stretch;
    gap: 14px;
    width: 100%;
    max-width: 480px;
  }
  body.portrait .landing-content-col { align-items: center; }

  /* Title — cropped polygonal-frame asset. Lighten blend so the dark
     surrounding pixels of the JPG composite onto the dark Three.js scene
     without a visible square. clamp() keeps the title sized for both
     phones and ultra-wide desktops without ever exceeding its native
     pixel width (960px → no upscale on 4K). */
  /* Wrapper sizes to the img exactly so the shimmer ::after pseudo can
     fill the same rect and clip to the title shape via mask-image. */
  .landing-title-wrap {
    position: relative;
    display: inline-block;
    line-height: 0;
  }
  .landing-title-img {
    /* Desktop sizing — ~20% smaller than the original mockup-matched scale
       so the title doesn't crowd the right-column panels on landscape. The
       portrait override below uses its own clamp band. */
    width: clamp(220px, 30vw, 448px);
    height: auto;
    display: block;
    /* Title PNG ships with chroma-keyed transparency so the polygonal frame
       sits cleanly on the Three.js scene with no blend-mode tricks needed.
       Cyan drop-shadow gives the glow halo the mockup shows. */
    filter: drop-shadow(0 0 28px rgba(126, 226, 255, 0.50))
            drop-shadow(0 6px 20px rgba(0, 0, 0, 0.45));
    pointer-events: none;
    user-select: none; -webkit-user-drag: none;
  }
  body.portrait .landing-title-img { width: clamp(288px, 84vw, 504px); }
  /* Shimmer sweep — diagonal highlight gradient travels across the title
     every cycle. mask-image clips the gradient to the polygonal frame's
     alpha so the highlight only lights up the title pixels (no rectangular
     glow leaking out). mix-blend-mode:overlay lifts existing colors instead
     of recoloring. */
  .landing-title-wrap::after {
    content: '';
    position: absolute; inset: 0;
    pointer-events: none;
    background: linear-gradient(110deg,
      rgba(255, 255, 255, 0)   38%,
      rgba(220, 240, 255, 0.55) 48%,
      rgba(255, 255, 255, 0.85) 50%,
      rgba(220, 240, 255, 0.55) 52%,
      rgba(255, 255, 255, 0)   62%);
    background-size: 220% 100%;
    background-repeat: no-repeat;
    background-position: 200% 50%;
    -webkit-mask-image: url('../assets/landing/title.webp?v=20260504a');
            mask-image: url('../assets/landing/title.webp?v=20260504a');
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    mix-blend-mode: overlay;
    opacity: 0;
    animation: title-shimmer 3.64s ease-in-out infinite;
  }
  @keyframes title-shimmer {
    0%   { background-position: 200% 50%; opacity: 0; }
    8%   { opacity: 1; }
    55%  { background-position: -100% 50%; opacity: 1; }
    65%  { opacity: 0; }
    100% { background-position: -100% 50%; opacity: 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .landing-title-wrap::after { animation: none; opacity: 0; }
  }
  /* Sr-only — keeps the localized H1 text in the accessibility tree without
     displaying the unstyled text under the image. */
  .landing-title-fallback {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
  }

  #overlay p  { color: var(--text); font-size: 14.5px; text-align: center; line-height: 1.65; margin: 0; text-shadow: 0 1px 2px rgba(0,0,0,0.45); }
  /* Per-orientation font sizes — mobile reads tight at -1pt, desktop has
     room to breathe at +3pt vs the 14.5px baseline. */
  body.portrait  #overlay p { font-size: 13.5px; }
  body.landscape #overlay p { font-size: 17.5px; text-align: center; }

  /* Description panel: hidden by default; only revealed on landscape
     non-touch surfaces (i.e. desktop). Mobile portrait, mobile
     landscape, tablets, and the Android Capacitor flavor all have the
     body.touch:not(.tablet) class set by src/input.js, so the negation below keeps
     them quiet. */
  .landing-panel.landing-intro { display: none; }
  body.landscape:not(.touch) .landing-panel.landing-intro { display: block; }

  /* Sci-fi framed landing panel — uses desc-frame.webp as a 9-slice
     border-image (no `fill`, so the center slice is dropped). The panel
     itself has no fill — only a single backdrop-filter:blur softens the
     dungeon scene that reads through the frame's transparent interior.
     The frame webp is luminance-alpha-keyed so the cyan/violet edges
     stay opaque while the interior scan-lines fade into the blur. */
  .landing-panel {
    width: 100%;
    background: transparent;
    border-style: solid;
    border-color: transparent;
    /* Border width controls the visible thickness of the frame artwork.
       28px scales reasonably across the panel's typical ~280–520px width. */
    border-width: 28px 32px;
    border-image-source: url('../assets/landing/desc-frame.webp?v=20260503b');
    /* Slice values empirically tuned to the trimmed asset (1200×579):
       top/bottom 30% covers the bracket + chevron details; left/right 22%
       covers the corner L-bars and side notches. No `fill` — center is
       transparent so our backdrop-blur shines through. */
    border-image-slice: 30% 22%;
    border-image-repeat: stretch;
    border-image-width: 1;
    border-image-outset: 0;
    border-radius: 0;
    padding: 4px 8px;
    color: var(--text);
    box-sizing: border-box;
    filter: drop-shadow(0 0 14px rgba(92, 212, 255, 0.25));
    transition: filter 0.22s ease, transform 0.18s ease, background 0.22s ease;
  }
  .landing-panel:hover {
    filter:
      drop-shadow(0 0 24px rgba(126, 226, 255, 0.65))
      drop-shadow(0 0 8px rgba(196, 124, 255, 0.35))
      brightness(1.18) saturate(1.10);
    transform: translateY(-1px);
  }
  @media (prefers-reduced-motion: reduce) {
    .landing-panel { transition: none; }
    .landing-panel:hover { transform: none; }
  }

  /* Inner controls layout — no longer a card itself, just lays out icons + text. */
  #requirements, #touch-requirements {
    display: inline-flex; align-items: center; gap: 14px;
    color: var(--text);
    background: none; border: none; padding: 0; margin: 0;
    box-shadow: none;
    width: 100%; justify-content: center;
  }
  #touch-requirements { display: none; }
  #requirements .req-icons {
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--amber); flex-shrink: 0;
  }
  #requirements .req-plus { opacity: 0.55; font-weight: 600; }
  #requirements .req-text {
    text-align: left; font-size: 13.5px; line-height: 1.45;
  }
  #requirements .req-text strong { font-weight: 700; }
  #requirements .req-hint {
    display: block; color: var(--text-dim);
    font-size: 11.5px; margin-top: 3px; letter-spacing: 0.2px;
  }
  /* Relic bar — the whole pill is a clickable button that opens the shop.
     Cyan palette so it reads distinct from rankings (violet) and PLAY (warm).
     Double-id beats the blanket `#overlay button` gradient. */
  /* Utility row holding the relic / rankings / achievements pills above PLAY.
     Flex-row that wraps on narrow phones so all three pills stay grouped as a
     unit. The row owns the bottom margin; individual pills don't add their
     own margin-bottom (would double-stack). */
  #landing-utility-row {
    --relic-w: clamp(220px, 24vw, 320px);
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 10px;
    margin: 0 0 22px;
    max-width: 100%;
  }
  /* Pulse glow halo on the relic chip — same breathing rhythm as the
     PLAY button but offset duration (3.7s vs 3.2s) so the two pulses
     don't lock into sync. The halo is a blurred copy of relic-button.webp
     sized to match the bar inside; isolation:isolate + z-index:-1 puts
     it behind the bar but above the row's transparent bg. */
  #landing-utility-row::before {
    content: '';
    position: absolute;
    left: 50%; top: 50%;
    width: var(--relic-w);
    aspect-ratio: 855 / 331;
    transform: translate(-50%, -50%);
    background: url('../assets/landing/relic-button.webp?v=20260504b') center / 100% 100% no-repeat;
    filter: blur(14px) brightness(1.25) saturate(1.15);
    opacity: 0.55;
    pointer-events: none;
    z-index: -1;
    animation: halo-pulse 3.7s ease-in-out infinite;
  }
  @media (prefers-reduced-motion: reduce) {
    #landing-utility-row::before { animation: none; }
  }
  @media (max-width: 480px) {
    #landing-utility-row { gap: 8px; margin-bottom: 18px; }
  }

  .landing-hud-pill {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 13px; font-weight: 700;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
  }
  .landing-energy-pill {
    background: rgba(100, 220, 100, 0.15);
    border: 1px solid rgba(100, 220, 100, 0.4);
    color: #88ff88;
  }
  .landing-stars-pill {
    background: rgba(255, 204, 51, 0.15);
    border: 1px solid rgba(255, 204, 51, 0.4);
    color: #ffcc33;
  }

  /* Daily Bin entry pill — clickable (overrides .landing-hud-pill's
     pointer-events:none, which is only for the read-only energy/stars chips).
     Gold treasure palette to match the daily-bin modal + HUD button. The
     ready/full badge anchors to the top-right corner like the HUD button. */
  .landing-daily-bin-pill {
    position: relative;
    pointer-events: auto;
    cursor: pointer;
    background: rgba(255, 216, 64, 0.15);
    border: 1px solid rgba(255, 216, 64, 0.4);
    color: #ffd840;
    font-weight: 800; letter-spacing: 0.4px;
    transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.14s ease;
  }
  .landing-daily-bin-pill:hover,
  .landing-daily-bin-pill:focus-visible {
    background: rgba(255, 216, 64, 0.28);
    box-shadow: 0 0 10px rgba(255, 216, 64, 0.35);
    transform: translateY(-1px);
    outline: none;
  }
  .landing-daily-bin-pill:active { transform: translateY(0); }
  .landing-daily-bin-icon { font-size: 15px; line-height: 1; }
  .landing-daily-bin-badge {
    position: absolute;
    top: -7px; right: -7px;
    min-width: 18px; height: 18px;
    padding: 0 5px;
    background: #ff4f4f;
    color: #fff;
    font-size: 11px; font-weight: 700; line-height: 18px;
    text-align: center;
    border-radius: 9px;
    box-shadow: 0 0 6px rgba(255, 79, 79, 0.6);
    pointer-events: none;
  }
  .landing-daily-bin-badge.is-ready {
    background: #ffd840;
    color: #1a1f2a;
    box-shadow: 0 0 8px rgba(255, 216, 64, 0.7);
    animation: daily-bin-landing-pulse 1.4s ease-in-out infinite;
  }
  .landing-daily-bin-badge.is-full {
    background: #ff7a3a;
    color: #fff;
    box-shadow: 0 0 8px rgba(255, 122, 58, 0.7);
  }
  @keyframes daily-bin-landing-pulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.15); }
  }
  @media (prefers-reduced-motion: reduce) {
    .landing-daily-bin-badge.is-ready { animation: none; }
  }

  /* Relic pill — uses the crystal-banner image as its background. The image
     has a built-in diamond gem on the left ~22% of the canvas, so the inner
     RELIC_GEM_HTML SVG is hidden and content shifts right via padding-left
     (≈25% reserves enough room for the diamond + a small gap). */
  #overlay #relic-bar {
    display: inline-flex; align-items: center; justify-content: space-between;
    gap: 8px;
    margin: 0;
    border: none;
    border-radius: 0;
    background: url('../assets/landing/relic-button.webp?v=20260504b') center / 100% 100% no-repeat,
                transparent;
    /* relic-button.webp now carries its own dark translucent fill in
       the interior (alpha = a * (0.5 + 0.5*intensity)) so the gradient
       label + white count have built-in contrast — no CSS overlay
       needed. Gem + gold cap stay fully opaque. */
    box-shadow: none;
    color: inherit; font-family: inherit; font-weight: 400;
    font-size: 13px; letter-spacing: 0.5px;
    cursor: pointer;
    width: clamp(220px, 24vw, 320px);
    aspect-ratio: 855 / 331;
    /* Mobile-tested padding: wider left for the gem, smaller right for
       the gold corner cap. Desktop has its own override (below). */
    padding: 0 44px 0 68px;
    /* No drop-shadow filter — some mobile browsers rasterize
       drop-shadow against the rectangular bbox, producing a phantom
       rectangle around the chevron-pill silhouette. Interaction
       feedback is carried by transform + brightness only. */
    transition: transform 0.16s cubic-bezier(0.2, 0.8, 0.2, 1),
                filter 0.18s;
  }
  body.landscape:not(.touch) #overlay #relic-bar {
    /* Desktop only: bar grows wider (clamp up to 320px) so the gem
       silhouette ends ~80px from the left edge — heavier left padding
       (100px) keeps the label clear of the diamond. Right padding
       bumped 44 → 68 (matching mobile's left value) so the count
       doesn't ride right up against the gold corner cap on the
       wider bar. */
    padding: 0 68px 0 100px;
  }
  #overlay #relic-bar:hover,
  #overlay #relic-bar:focus-visible {
    transform: translateY(-1px) scale(1.02);
    filter: brightness(1.10) saturate(1.06);
    outline: none;
  }
  #overlay #relic-bar:active {
    transform: translateY(1px) scale(0.97);
    filter: brightness(0.92);
    transition: transform 0.06s ease, filter 0.06s ease;
  }
  /* Click-burst: reuse the PLAY button's keyframe (same scale + brightness
     curve, NO box-shadow flare). The shared card-burst keyframe paints a
     rectangular gold box-shadow as its glow flare, but the relic chevron
     pill silhouette comes from the PNG alpha — the rectangle would show
     up as a phantom box behind the chip. Match the PLAY button's "pop"
     exactly: scale up briefly then shrink to zero, the burst sparks plus
     the audio cue carry the click feedback. */
  #overlay #relic-bar.card-picked {
    animation: start-btn-burst 380ms cubic-bezier(0.5, 0, 0.2, 1) forwards;
    box-shadow: none !important;
  }
  /* Inline RELIC_GEM_HTML SVG hidden across all surfaces — the bg
     image's built-in diamond on the left already reads as the chip's
     icon, so a second cyan gem next to the label was redundant. */
  #overlay #relic-bar .relic-label .relic-gem { display: none; }
  #relic-bar .relic-label {
    /* Warm gradient mirrors the stage-select PLAY button (yellow → pink →
       lilac) so the RELICS label reads as a "currency CTA" rather than a
       cyan info chip. background-clip:text turns the fill transparent,
       so we use filter:drop-shadow for the dark drop (text-shadow doesn't
       paint correctly on background-clipped text in every browser). */
    background: linear-gradient(135deg, #ffd36e, #ff9ec4 55%, #b89bff);
    -webkit-background-clip: text;
            background-clip: text;
    -webkit-text-fill-color: transparent;
            color: transparent;
    font-weight: 800; letter-spacing: 0.7px;
    /* Sized to PLAY-button -2pt — PLAY is clamp(18, 2vw, 24), relic
       label/count both shadow it at 2pt smaller for visual hierarchy. */
    font-size: clamp(16px, 1.78vw, 22px);
    display: inline-flex; align-items: center;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.85))
            drop-shadow(0 0 6px rgba(0, 0, 0, 0.55));
    flex-shrink: 0;
  }
  /* Brilliant-cut cyan diamond — oversized inline glyph. Sized at 1.8em so
     the gem visibly dominates the surrounding text (the currency symbol
     should feel like a precious gem, not a character next to a number).
     vertical-align keeps the baseline roughly centred. Markup lives in
     RELIC_GEM_HTML (src/meta-icons.js). */
  .relic-gem {
    display: inline-block;
    width: 1.55em; height: 1.55em;
    vertical-align: -0.42em;
    line-height: 0;
    filter: drop-shadow(0 0 4px rgba(92, 212, 255, 0.55));
  }
  .relic-gem svg { width: 100%; height: 100%; display: block; }
  /* BUY cost badges live in tight rows on the relic shop cards — keep the
     gem sized down there so the number stays on a single line. The
     game-over / victory earnings line and the landing relic pill both use
     the default 1.55em so the icon reads identically across the three
     screens (title, game-over, victory). */
  .relic-card-cost .relic-gem { width: 1.2em; height: 1.2em; vertical-align: -0.3em; }

  /* Trophy icon — inline SVG replacement for 🏆 on the rankings pill.
     Sized to match the relic gem so the pair look like a matched set.
     Violet drop-shadow picks up the rankings palette instead of cyan. */
  .trophy-icon {
    display: inline-block;
    width: 1.55em; height: 1.55em;
    vertical-align: -0.42em;
    line-height: 0;
    filter: drop-shadow(0 0 4px rgba(209, 174, 255, 0.55));
  }
  .trophy-icon svg { width: 100%; height: 100%; display: block; }
  #relic-bar .relic-count {
    color: #f4fdff; font-weight: 800;
    font-size: clamp(16px, 1.78vw, 22px);
    text-align: right;
    /* Layered drop so the white digits punch out against any dungeon
       colour bleeding through the alpha-keyed bg. */
    text-shadow:
      0 1px 2px rgba(0, 0, 0, 0.85),
      0 0 6px rgba(0, 0, 0, 0.55);
    /* Count column right-aligns against the chevron tip; flex-shrink:0 keeps
       large numbers (999,999) from being clipped by the label's flex grow. */
    min-width: 0;
    flex: 0 0 auto;
    overflow: hidden;
    white-space: nowrap;
  }

  /* Rankings pill — shared format used on the landing screen and at the end
     of a run. Whole pill is a single clickable button; the chevron is a
     visual affordance, not a separate control. Warm-violet palette so it
     reads distinct from relics (cyan) and PLAY (warm-amber). ID-selector
     specificity (#overlay, #gameover) beats the blanket button gradient
     defined above (`#overlay button { background: linear-gradient(...) }`). */
  #overlay .rankings-pill,
  #gameover .rankings-pill {
    display: inline-flex; align-items: center; gap: 12px;
    padding: 10px 18px;
    border-radius: var(--radius-pill);
    background: rgba(36, 22, 48, 0.44);
    border: 1px solid rgba(209, 174, 255, 0.3);
    color: inherit; font-family: inherit; font-weight: 400;
    font-size: 13px; letter-spacing: 0.5px;
    box-shadow: none;
    cursor: pointer;
    transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1),
                box-shadow 0.22s, border-color 0.22s, background 0.22s;
  }
  #overlay .rankings-pill:hover,
  #gameover .rankings-pill:hover,
  #overlay .rankings-pill:focus-visible,
  #gameover .rankings-pill:focus-visible {
    transform: translateY(-1px);
    border-color: rgba(209, 174, 255, 0.55);
    background: rgba(48, 30, 64, 0.56);
    box-shadow: 0 6px 20px rgba(155, 123, 255, 0.32);
    outline: none;
  }
  .rankings-pill .rankings-label {
    color: #d1aeff; font-weight: 800; letter-spacing: 0.8px;
  }

  /* Landing placement — pill sits between the relic bar and PLAY button. */
  #rankings-bar {
    margin: 0;
  }

  /* Top-right cluster placement (since 2026-05-03). Strips the lilac
     backdrop-blur fancy and matches the more modest settings-pill look
     so the three top-right actions (Achievements, Rankings, Settings)
     read as a coherent cluster. */
  /* Rankings pill (top-right utility variant) — sized to match the
     achievements badge (10px 16px padding, 13px text) so the three pills
     in the cluster read as a uniform set. */
  #landing-top-right-utils #rankings-bar.top-right-pill {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 10px 16px;
    background: rgba(20, 26, 44, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius-pill);
    color: var(--text, #e6ebf6);
    font: inherit;
    font-size: 13px; letter-spacing: 0.5px;
    font-weight: 700;
    box-shadow: none;
  }
  #landing-top-right-utils #rankings-bar.top-right-pill:hover {
    background: rgba(34, 44, 72, 0.85);
    border-color: rgba(255, 255, 255, 0.18);
    transform: translateY(-1px);
  }
  #landing-top-right-utils #rankings-bar.top-right-pill .rankings-pill-icon {
    font-size: 18px; line-height: 1;
  }
  #landing-top-right-utils #rankings-bar.top-right-pill .rankings-label {
    color: var(--text); font-weight: 700; letter-spacing: 0.6px;
  }
  /* Mobile (touch OR narrow window): rankings collapses to icon-only
     so the trophy reads instantly without long localized labels
     stretching the cluster. Desktop keeps the full RANKINGS label. */
  @media (pointer: coarse), (max-width: 540px) {
    #landing-top-right-utils #rankings-bar.top-right-pill .rankings-label { display: none; }
    #landing-top-right-utils #rankings-bar.top-right-pill { padding: 10px 12px; }
  }

