/*
 * RECORDS MASTER — printed vintage record sleeve. See docs/DESIGN.md.
 * Four colours only; shades come from opacity, grain and multiply overlays.
 * Layers: reset < base < components < layout < pages < fx.
 */
@layer reset, base, components, layout, pages, fx;

:root {
  --paper: #ffdf74;
  --ink: #0f2515;
  --stamp: #f03838;
  --ok: #17703a;
  --paper-white: #ffffff;

  /* Overlays, not new colours. */
  --paper-lift: color-mix(in srgb, var(--paper-white) 45%, var(--paper));
  --ink-soft: color-mix(in srgb, var(--ink) 65%, transparent);
  --ink-faint: color-mix(in srgb, var(--ink) 18%, transparent);

  --font-display: var(--font-anton), "Impact", "Haettenschweiler", sans-serif;
  --font-body: var(--font-archivo), system-ui, sans-serif;
  --font-mono: var(--font-plex-mono), ui-monospace, monospace;

  --rule: 2px solid var(--ink);
  --rule-thick: 3px solid var(--ink);
  --drop: 4px 4px 0 var(--ink);
  --drop-lg: 7px 7px 0 var(--ink);

  --ease-snap: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-pop: cubic-bezier(0.34, 1.7, 0.64, 1);

  --band-tilt: -3.4deg;
  --page: 1180px;
  --gutter: clamp(1rem, 3vw, 2rem);
  --main-top: clamp(1.8rem, 5vw, 3.2rem);

  /* Fine paper grain (global overlay) and a coarse mask for stamp wear. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.4 -0.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --wear: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2.6 2.3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23w)'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------------ reset */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  body, h1, h2, h3, p, figure, dl, dd, blockquote { margin: 0; }
  ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
  img, svg, canvas { display: block; max-width: 100%; }
  img { height: auto; }
  input, select, button, textarea { font: inherit; color: inherit; }
  table { border-collapse: collapse; }
}

/* ------------------------------------------------------------------- base */
@layer base {
  html { background: var(--paper); color-scheme: light; overflow-x: clip; }

  body {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow-x: clip;
    background: var(--paper);
    color: var(--ink);
    font: 400 1rem/1.5 var(--font-body);
    -webkit-font-smoothing: antialiased;
  }

  /* Global paper grain. */
  body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 100;
    pointer-events: none;
    background-image: var(--grain);
    background-size: 220px;
    mix-blend-mode: multiply;
    opacity: 0.06;
  }

  ::selection { background: var(--stamp); color: var(--paper); }

  a {
    color: inherit;
    text-decoration-line: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 0.18em;
    text-decoration-color: var(--stamp);
  }
  a:hover { background: var(--ink); color: var(--paper); text-decoration-color: var(--paper); }
  :focus-visible { outline: 3px solid var(--stamp); outline-offset: 2px; }

  h1, h2, h3 {
    font-family: var(--font-display);
    font-weight: 400;
    text-transform: uppercase;
    line-height: 0.92;
    letter-spacing: 0.01em;
    text-wrap: balance;
  }
  /* Offset print: ink bleed plus a slightly misregistered red pass. */
  h1 {
    font-size: clamp(2.6rem, 7.5vw, 5.6rem);
    margin-block: 0.25em 0.35em;
    text-shadow: 0.035em 0.03em 0 color-mix(in srgb, var(--stamp) 85%, transparent);
    filter: url(#ink-bleed-coarse);
  }
  h2 {
    font-size: clamp(1.6rem, 3.6vw, 2.4rem);
    margin-block: 1.6em 0.6em;
    filter: url(#ink-bleed);
  }
  h3 { font-size: 1.3rem; margin-block: 1em 0.4em; }
  h1 small, h2 small {
    display: inline-block;
    vertical-align: 0.5em;
    margin-left: 0.4em;
    padding: 0.25em 0.5em 0.2em;
    border: var(--rule);
    font: 600 max(0.8rem, 0.18em)/1 var(--font-mono);
    letter-spacing: 0.12em;
    text-shadow: none;
    rotate: -2deg;
  }

  p { max-width: 68ch; }
  p + p { margin-top: 0.75em; }
  strong { font-weight: 700; }
  em { font-style: normal; background: var(--stamp); color: var(--paper); padding: 0 0.15em; }
  code { font: 0.85em var(--font-mono); }
  hr { border: 0; border-top: var(--rule); margin: 2rem 0; }
  ul:not([class]), ol:not([class]) { padding-left: 1.2em; }

  /* Fact sheets: mono keys, ruled lines. */
  dl {
    display: grid;
    grid-template-columns: minmax(8rem, max-content) 1fr;
    border-top: var(--rule);
  }
  dt, dd { padding: 0.45rem 0.6rem 0.4rem 0; border-bottom: 1px dashed var(--ink-soft); }
  dt {
    font: 600 0.72rem/1.6 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  dd { margin: 0; font-variant-numeric: tabular-nums; }
  /* Phones: keys sit above their values so long values get the full width. */
  @media (max-width: 480px) {
    dl:not(.collector-stats) { grid-template-columns: 1fr; }
    dl:not(.collector-stats) dt { border-bottom: 0; padding-bottom: 0.1rem; }
    dl:not(.collector-stats) dd { padding-top: 0.1rem; }
  }

  /* Tables as dispatch slips (bordereaux). */
  table {
    width: 100%;
    border: var(--rule-thick);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    font-variant-numeric: tabular-nums;
  }
  caption {
    caption-side: top;
    text-align: left;
    padding-bottom: 0.5rem;
    font: 600 0.75rem/1 var(--font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
  }
  thead th {
    background: var(--ink);
    color: var(--paper);
    font: 600 0.7rem/1.2 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  th, td { text-align: left; vertical-align: top; padding: 0.5rem 0.7rem; }
  tbody tr + tr > * { border-top: 1px dashed var(--ink-soft); }
  tbody th { font: 600 0.8rem/1.4 var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em; }
  tbody tr:hover > * { background: color-mix(in srgb, var(--paper) 70%, transparent); }

  /* Forms: labels are small mono captions above ruled fields. */
  label {
    display: inline-flex;
    flex-direction: column;
    gap: 0.3rem;
    max-width: 100%;
    margin: 0.3rem 1rem 0.6rem 0;
    font: 600 0.72rem/1.2 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    vertical-align: bottom;
  }
  label:has(> input[type="checkbox"]) {
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    text-transform: none;
    letter-spacing: 0.02em;
    font: 500 0.95rem/1.3 var(--font-body);
  }
  input:not([type="checkbox"], [type="hidden"]), select, textarea {
    min-height: 2.5rem;
    padding: 0.45rem 0.6rem;
    border: var(--rule);
    border-radius: 0;
    background: var(--paper-lift);
    color: var(--ink);
    font: 500 1rem/1.2 var(--font-body);
    letter-spacing: 0;
    text-transform: none;
    box-shadow: inset 2px 2px 0 var(--ink-faint);
  }
  input[type="number"] { font-family: var(--font-mono); width: 9rem; }
  label:has(> textarea) { display: flex; margin-right: 0; }
  input:not([type="checkbox"], [type="hidden"]), select { max-width: 100%; }
  textarea { width: 100%; max-width: 100%; line-height: 1.45; resize: vertical; }
  select {
    appearance: none;
    padding-right: 2rem;
    background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%),
      linear-gradient(-45deg, transparent 50%, var(--ink) 50%);
    background-position: right 0.95rem center, right 0.6rem center;
    background-size: 0.35rem 0.35rem;
    background-repeat: no-repeat;
  }
  input:focus-visible, select:focus-visible, textarea:focus-visible {
    outline: none;
    border-color: var(--stamp);
    box-shadow: 3px 3px 0 var(--stamp);
  }
  input[type="checkbox"] {
    appearance: none;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0;
    flex: none;
    border: var(--rule);
    background: var(--paper-lift);
    display: grid;
    place-content: center;
    cursor: pointer;
  }
  input[type="checkbox"]:checked::before {
    content: "✕";
    color: var(--stamp);
    font: 400 1.1rem/1 var(--font-display);
  }

  fieldset {
    position: relative;
    margin: 1.8rem 0 1.2rem;
    padding: 1.5rem 1rem 0.8rem;
    border: 2px dashed var(--ink);
    min-width: 0;
  }
  legend {
    position: absolute;
    top: 0;
    left: 0.8rem;
    translate: 0 -55%;
    padding: 0.3rem 0.6rem 0.2rem;
    background: var(--ink);
    color: var(--paper);
    font: 400 1rem/1 var(--font-display);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    rotate: -2deg;
  }
}

/* ----------------------------------------------------------------- layout */
@layer layout {
  .site-main {
    flex: 1;
    width: 100%;
    max-width: var(--page);
    margin: 0 auto;
    padding: var(--main-top) var(--gutter) clamp(2.6rem, 6vw, 4rem);
  }

  .site-header {
    position: relative;
    z-index: 10;
    background: var(--ink);
    color: var(--paper);
    border-bottom: 4px solid var(--stamp);
  }
  .site-header-inner {
    position: relative;
    max-width: var(--page);
    margin: 0 auto;
    padding: 0 var(--gutter);
    min-height: 4.4rem;
    display: flex;
    align-items: center;
  }
  /* Black monogram printed on a red label spanning the full height of the ink band. The label is a
   * slanted parallelogram: both side edges lean the same way, like the band. */
  .site-logo {
    flex: none;
    align-self: stretch;
    display: flex;
    align-items: center;
    margin-right: clamp(1rem, 2.4vw, 2rem);
    line-height: 0;
    padding: 0.45rem 0.65rem 0.45rem 1.1rem;
    background: var(--stamp);
    clip-path: polygon(0 0, 86% 0, 100% 100%, 14% 100%);
  }
  .site-logo-mono {
    display: block;
    height: 56px;
    aspect-ratio: 157 / 90;
    background: #000;
    -webkit-mask: url("/assets/brand/rm-mono-33b92359.svg") center / contain no-repeat;
    mask: url("/assets/brand/rm-mono-33b92359.svg") center / contain no-repeat;
  }
  .site-logo:hover { background: var(--stamp); }

  .site-nav { flex: 1; min-width: 0; padding: 0.7rem 0; }
  .site-nav .nav-state { white-space: nowrap; }
  .site-nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem clamp(0.7rem, 1.4vw, 1.25rem);
  }
  .site-nav a {
    font: 400 clamp(0.92rem, 1.3vw, 1.08rem)/1 var(--font-display);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--paper);
    padding: 0.3rem 0.1rem;
    border-bottom: 3px solid transparent;
  }
  .site-nav a:hover { background: none; color: var(--stamp); border-bottom-color: var(--stamp); }
  .site-nav .nav-spacer { margin-left: auto; }
  .site-nav .nav-state {
    color: var(--ink);
    background: var(--paper);
    border-color: var(--paper);
    box-shadow: 3px 3px 0 var(--stamp);
  }
  .site-nav .nav-state b { font-weight: 700; }
  .site-nav button {
    --btn-bg: transparent;
    --btn-fg: var(--paper);
    --btn-shadow: var(--stamp);
    min-height: 0;
    border-color: var(--paper);
    font-size: 0.85rem;
    padding: 0.4rem 0.7rem 0.3rem;
  }

  /* Footer: the full ink logo and a few links, nothing else. */
  .site-footer {
    border-top: var(--rule-thick);
    padding: 2rem var(--gutter) 2.6rem;
  }
  .site-footer-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1.2rem 2rem;
    max-width: var(--page);
    margin: 0 auto;
  }
  .footer-logo { display: block; line-height: 0; }
  .footer-logo:hover { background: none; }
  .footer-logo img { width: 92px; height: auto; transition: rotate 160ms var(--ease-pop); }
  .footer-logo:hover img { rotate: -4deg; }
  .footer-nav { display: flex; flex-wrap: wrap; gap: 0.6rem 1.6rem; }
  .footer-nav a {
    font: 600 0.75rem/1.2 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    border-bottom: 2px solid transparent;
  }
  .footer-nav a:hover { background: none; color: var(--stamp); border-bottom-color: var(--stamp); }

  /* "Données fournies par Discogs": shown on /legal only (decision of 2026-10-13, docs/PIVOT.md). */
  .discogs-credit {
    font: 500 0.72rem/1.4 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  /* Burger: hidden on wide screens. */
  .nav-toggle { display: none; }

  /* Narrow screens: logo + burger in the band, the nav drops down as a full-width ink panel. */
  @media (max-width: 860px) {
    .site-header-inner { min-height: 3.6rem; }
    .site-logo-mono { height: 42px; }
    .nav-toggle {
      --btn-bg: transparent;
      --btn-shadow: transparent;
      display: grid;
      place-items: center;
      margin-left: auto;
      width: 2.9rem;
      height: 2.9rem;
      min-height: 0;
      padding: 0;
      border: 0;
      box-shadow: none;
    }
    .nav-toggle:hover { translate: none; box-shadow: none; }
    .nav-toggle span,
    .nav-toggle span::before,
    .nav-toggle span::after {
      display: block;
      width: 1.6rem;
      height: 3px;
      background: var(--paper);
      transition: rotate 160ms var(--ease-snap), translate 160ms var(--ease-snap), opacity 120ms linear;
    }
    .nav-toggle span { position: relative; }
    .nav-toggle span::before, .nav-toggle span::after { content: ""; position: absolute; left: 0; }
    .nav-toggle span::before { translate: 0 -8px; }
    .nav-toggle span::after { translate: 0 8px; }
    .nav-toggle[aria-expanded="true"] span { background: transparent; }
    .nav-toggle[aria-expanded="true"] span::before { translate: 0 0; rotate: 45deg; background: var(--stamp); }
    .nav-toggle[aria-expanded="true"] span::after { translate: 0 0; rotate: -45deg; background: var(--stamp); }

    .site-nav {
      display: none;
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      /* Hangs below the header's red bottom rule and repeats it. */
      margin-top: 4px;
      padding: 0.6rem var(--gutter) 1.2rem;
      background: var(--ink);
      border-bottom: 4px solid var(--stamp);
      box-shadow: 0 10px 0 var(--ink-faint);
    }
    .site-header[data-nav-open] .site-nav { display: block; }
    .site-nav ul { flex-direction: column; align-items: stretch; gap: 0; }
    .site-nav li { border-bottom: 1px dashed color-mix(in srgb, var(--paper) 30%, transparent); }
    .site-nav li:has(.nav-state) { border-bottom: 0; padding-top: 0.9rem; }
    .site-nav a { display: block; padding: 0.85rem 0.1rem 0.7rem; font-size: 1.3rem; border-bottom: 0; }
    .site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--stamp); }
    .site-nav .nav-spacer { margin-left: 0; }
    .site-nav .nav-state { white-space: normal; }
  }
}

/* ------------------------------------------------------------- components */
@layer components {
  .row { display: flex; flex-wrap: wrap; gap: 1.5rem 2rem; align-items: flex-start; }
  .row > * { min-width: 0; }
  .split { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 2rem 3rem; align-items: start; }
  .split > section > h2:first-child { margin-top: 0; }
  @media (max-width: 860px) { .split { grid-template-columns: 1fr; } }

  .muted { opacity: 0.72; font-size: 0.9em; }
  .mono { font-family: var(--font-mono); letter-spacing: 0.04em; }
  .lede { font-size: 1.12rem; max-width: 60ch; }

  .error {
    color: var(--stamp);
    font: 600 0.85rem/1.4 var(--font-mono);
    letter-spacing: 0.04em;
  }
  .error::before { content: "✕ "; }
  .success {
    display: inline-block;
    margin-top: 0.6rem;
    padding: 0.35rem 0.7rem;
    border: var(--rule);
    background: var(--paper-lift);
    font: 600 0.85rem/1.4 var(--font-mono);
    rotate: -1deg;
    box-shadow: 3px 3px 0 var(--ink);
  }

  /* Small tilted metadata label. */
  .label {
    --tilt: -2deg;
    display: inline-block;
    padding: 0.28em 0.6em 0.22em;
    border: 1.5px solid currentColor;
    font: 600 0.72rem/1.2 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    white-space: nowrap;
    max-width: 100%;
    rotate: var(--tilt);
  }
  /* Long values (e-mail, balances) may break rather than push the page sideways. */
  @media (max-width: 480px) { .label { white-space: normal; overflow-wrap: anywhere; } }
  .label.r { --tilt: 2deg; }
  .label.ink { background: var(--ink); color: var(--paper); border-color: var(--ink); }
  .label.red { background: var(--stamp); color: var(--paper); border-color: var(--stamp); }

  /* Rubber stamp: worn red ink multiplied onto whatever is under it. */
  .stamp {
    --tilt: -8deg;
    display: inline-block;
    padding: 0.2em 0.45em 0.1em;
    border: 0.12em solid currentColor;
    outline: 0.05em solid currentColor;
    outline-offset: 0.12em;
    color: var(--stamp);
    font: 400 1.4rem/1 var(--font-display);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
    rotate: var(--tilt);
    mix-blend-mode: multiply;
    -webkit-mask-image: var(--wear);
    mask-image: var(--wear);
    -webkit-mask-size: 160px;
    mask-size: 160px;
    filter: url(#ink-bleed);
  }

  /* Rarity: palette-only escalation, from a thin outline to a solid double stamp. */
  .tier {
    display: inline-block;
    padding: 0.25em 0.5em 0.15em;
    font: 400 0.9rem/1 var(--font-display);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border: 1.5px solid var(--ink);
    background: var(--paper);
    rotate: -3deg;
    white-space: nowrap;
    filter: url(#ink-bleed);
  }
  .tier[data-tier="uncommon"] { border-width: 3px; }
  .tier[data-tier="rare"] { background: var(--ink); color: var(--paper); }
  .tier[data-tier="epic"] { border: 3px solid var(--stamp); color: var(--stamp); }
  .tier[data-tier="legendary"] {
    background: var(--stamp);
    color: var(--paper);
    border: 3px double var(--paper);
    outline: 2px solid var(--stamp);
  }

  /* Buttons: rectangle, condensed caps, hard shadow; pressing sinks the block. */
  :where(button, .btn) {
    --btn-bg: var(--paper);
    --btn-fg: var(--ink);
    --btn-shadow: var(--ink);
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    min-height: 2.5rem;
    padding: 0.55rem 1.1rem 0.42rem;
    border: 2px solid var(--ink);
    border-radius: 0;
    background: var(--btn-bg);
    color: var(--btn-fg);
    box-shadow: 3px 3px 0 var(--btn-shadow);
    font: 400 1.05rem/1 var(--font-display);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    user-select: none;
    transition: translate 90ms var(--ease-snap), box-shadow 90ms var(--ease-snap);
  }
  :where(button, .btn):hover {
    background: var(--btn-bg);
    color: var(--btn-fg);
    translate: -1px -1px;
    box-shadow: 4px 4px 0 var(--btn-shadow);
  }
  :where(button, .btn):active {
    translate: 3px 3px;
    box-shadow: 0 0 0 var(--btn-shadow);
    transition-duration: 30ms;
  }
  :where(button, .btn):disabled,
  :where(button, .btn)[aria-disabled="true"] {
    cursor: not-allowed;
    translate: none;
    box-shadow: none;
    opacity: 0.45;
    background-image: repeating-linear-gradient(-45deg, transparent 0 6px, var(--ink-faint) 6px 8px);
  }
  .btn-ink { --btn-bg: var(--ink); --btn-fg: var(--paper); --btn-shadow: var(--stamp); }
  .btn-stamp { --btn-bg: var(--stamp); --btn-fg: var(--paper); --btn-shadow: var(--ink); }
  .btn-big { font-size: 1.5rem; padding: 0.8rem 1.6rem 0.65rem; }

  /* ActionForm wrapper. */
  .action-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.4rem 0.8rem; margin: 0.4rem 0 0.8rem; }
  .action-form > p, .action-form > .row { flex-basis: 100%; }
  .action-form > [role="alert"], .action-form > [role="status"] { flex-basis: 100%; width: fit-content; max-width: 100%; }
  .action-form.is-shaking { animation: shake 320ms var(--ease-snap); }

  .filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0 0.2rem;
    margin: 0 0 1.6rem;
    padding: 0.9rem 1rem 0.5rem;
    border: var(--rule);
    border-left-width: 10px;
    background: var(--paper-lift);
  }
  .filters button { margin: 0.3rem 0 0.6rem; }

  /* Sleeve ticket: 3D sleeve on paper, hard shadow, slight tilt. */
  .ticket, .grid > li {
    --tilt: 0deg;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.55rem 0.55rem 0.7rem;
    border: var(--rule);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    rotate: var(--tilt);
    transition: rotate 160ms var(--ease-snap), translate 160ms var(--ease-snap), box-shadow 160ms var(--ease-snap);
  }
  .grid > li:nth-child(4n + 1) { --tilt: -1.2deg; }
  .grid > li:nth-child(4n + 2) { --tilt: 0.8deg; }
  .grid > li:nth-child(4n + 3) { --tilt: -0.4deg; }
  .grid > li:nth-child(4n) { --tilt: 1.4deg; }
  .grid > li:hover { rotate: 0deg; translate: -3px -3px; box-shadow: var(--drop-lg); z-index: 1; }

  .grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(150px, 42vw), 1fr));
    gap: 1.6rem 1.3rem;
    margin: 0 0 1rem;
  }
  .grid > li > a, .ticket > a { display: flex; flex-direction: column; gap: 0.45rem; text-decoration: none; }
  .grid > li > a:hover, .ticket > a:hover { background: none; color: inherit; }
  .thumb-missing {
    width: 100%;
    aspect-ratio: 3 / 4;
    background: var(--ink);
  }

  /* Dense-list sleeve: pseudo-3D animated cover with cardboard thickness,
     mouse follow tilt, and low-res pixelated texture. */
  .list-sleeve {
    --sleeve-rx: 0deg;
    --sleeve-ry: 0deg;
    --sleeve-mx: 0%;
    --sleeve-my: 0%;
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    perspective: 700px;
    background: transparent;
  }
  .list-sleeve-inner {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: color-mix(in srgb, var(--paper) 82%, var(--ink));
    border-radius: 1px;
    transform: rotateX(var(--sleeve-rx)) rotateY(var(--sleeve-ry));
    transform-style: preserve-3d;
    transition: transform 90ms ease-out, box-shadow 90ms ease-out;
    will-change: transform;
    /* Simulated cardboard edge / thickness: layered offset shadows that respond to tilt */
    box-shadow:
      calc(var(--sleeve-ry) * -0.15px) calc(var(--sleeve-rx) * 0.15px + 1px) 0 0 color-mix(in srgb, var(--paper) 40%, var(--ink)),
      calc(var(--sleeve-ry) * -0.3px) calc(var(--sleeve-rx) * 0.3px + 2px) 0 0 color-mix(in srgb, var(--paper) 15%, var(--ink)),
      calc(var(--sleeve-ry) * -0.5px + 1px) calc(var(--sleeve-rx) * 0.5px + 4px) 6px -1px var(--ink-faint);
  }
  .list-sleeve:hover .list-sleeve-inner {
    transition: transform 40ms linear, box-shadow 40ms linear;
  }
  /* Low-res downscale & upscale with pixelated filtering */
  .list-sleeve-pixel-viewport {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
  .list-sleeve-pixel-img,
  .list-sleeve img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    image-rendering: -moz-crisp-edges;
    image-rendering: crisp-edges;
    image-rendering: pixelated;
    filter: saturate(0.92) contrast(1.05);
  }
  /* Cardboard sheen / reflection shifting with mouse pointer */
  .list-sleeve-inner::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: radial-gradient(
      circle at calc(50% + var(--sleeve-mx) * 0.8) calc(50% + var(--sleeve-my) * 0.8),
      rgb(255 255 255 / 0.14) 0%,
      transparent 65%
    );
    mix-blend-mode: overlay;
    opacity: 0.9;
  }
  /* Cardboard spine / inner crease highlight */
  .list-sleeve-inner::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    box-shadow: inset 1px 0 0 rgb(255 255 255 / 0.18), inset -1px 0 0 rgb(0 0 0 / 0.25), inset 0 1px 0 rgb(255 255 255 / 0.12), inset 0 -1px 0 rgb(0 0 0 / 0.35);
  }
  .list-sleeve-missing {
    display: grid;
    place-items: end start;
  }
  .list-sleeve-missing .list-sleeve-inner {
    display: grid;
    place-items: end start;
    background: var(--ink);
  }
  .list-sleeve-missing span {
    position: relative;
    z-index: 2;
    margin: 0.45rem;
    padding: 0.15em 0.4em 0.1em;
    background: var(--paper);
    color: var(--ink);
    font: 600 0.6rem/1.2 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    rotate: -2deg;
  }
  @media (prefers-reduced-motion: reduce) {
    .list-sleeve-inner {
      transform: none !important;
      transition: none !important;
      box-shadow: 1px 2px 0 0 color-mix(in srgb, var(--paper) 20%, var(--ink)), 2px 4px 5px var(--ink-faint);
    }
    .list-sleeve-inner::before {
      display: none;
    }
  }

  /* 3D sleeve box: reserved for isolated showcase scenes such as the homepage marquee. */
  .pack3d {
    position: relative;
    width: 100%;
    /* Square sleeves (12" / 7"). */
    aspect-ratio: 1;
    image-rendering: pixelated;
  }
  .pack3d > canvas { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; }
  /* Until the viewer has drawn: an ink sleeve silhouette on a paper ground, never the 2D cover. */
  .pack3d-placeholder {
    position: absolute;
    inset: 14%;
    background: var(--ink);
    border: 2px solid var(--ink);
    box-shadow: inset 0 0.9rem 0 color-mix(in srgb, var(--paper) 22%, var(--ink)), 4px 4px 0 var(--ink-faint);
    opacity: 0.9;
    transition: opacity 160ms linear;
  }
  .pack3d[data-ready] .pack3d-placeholder { opacity: 0; }
  .pack3d[data-failed] .pack3d-placeholder::after {
    content: "3D indisponible";
    position: absolute;
    inset: auto 0 40%;
    color: var(--paper);
    font: 600 0.6rem/1.2 var(--font-mono);
    letter-spacing: 0.1em;
    text-align: center;
    text-transform: uppercase;
  }
  /* Tickets: the sleeve floats on a paper ground. */
  .ticket .pack3d, .grid .pack3d {
    background: var(--paper);
    border: 1.5px solid var(--ink);
  }
  .thumb-missing {
    display: grid;
    place-items: center;
    color: var(--paper);
    font: 600 0.7rem/1.2 var(--font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
  }
  .ticket-name {
    font: 400 1.18rem/1 var(--font-display);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-wrap: balance;
  }
  .ticket-meta {
    font: 500 0.72rem/1.45 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
  .ticket-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; }
  .ticket-sub { font: 500 0.78rem/1.35 var(--font-body); opacity: 0.8; }

  /* Tracklist, printed like the back of a sleeve: position, title, tags, length on ruled lines.
   * In a player's view (data-status), the copy's own tracks get the green band and tracks already on
   * air a ✓ and an "à l'antenne" tag; elsewhere the green band marks the tracks on air. */
  .tracklist {
    counter-reset: none;
    display: grid;
    border-top: var(--rule);
    font-variant-numeric: tabular-nums;
  }
  .tracklist > li {
    display: grid;
    grid-template-columns: 1.4rem 2.6rem minmax(0, 1fr) auto auto;
    align-items: baseline;
    gap: 0 0.6rem;
    padding: 0.32rem 0.2rem 0.26rem;
    border-bottom: 1px dashed var(--ink-soft);
  }
  .tracklist:not([data-status]) > li[data-opened="true"],
  .tracklist > li[data-new] {
    background: color-mix(in srgb, var(--ok) 22%, transparent);
    box-shadow: inset 4px 0 0 var(--ok);
  }
  .tracklist > li[data-new] .tracklist-title { font-weight: 700; }
  .tracklist-check { color: var(--ok); font: 400 1.3rem/1 var(--font-display); text-align: center; }
  .tracklist-onair {
    display: inline-block;
    padding: 0.14em 0.45em 0.1em;
    font: 600 0.6rem/1.2 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    background: var(--ok);
    color: var(--paper);
  }
  .tracklist-status { margin: 0.2rem 0 0.6rem; font: 600 0.9rem/1.4 var(--font-body); }
  .tracklist-status[data-onair]:not([data-onair="0"])::before { content: "✓ "; color: var(--ok); }

  /* Album page tracklist table: same distinction, plus an explicit label on collected tracks. */
  .album-tracks tbody tr[data-opened="true"] > * { background: color-mix(in srgb, var(--ok) 22%, transparent); }
  .album-tracks tbody tr[data-opened="true"] > :first-child { box-shadow: inset 4px 0 0 var(--ok); }
  .album-tracks tbody tr[data-opened="true"] th { font-weight: 700; }
  .album-tracks .album-tracks-check { width: 1.6rem; padding-right: 0; color: var(--ok); font: 400 1.3rem/1 var(--font-display); text-align: center; }
  .album-tracks .album-tracks-owned { margin-left: 0.6rem; font-size: 0.58rem; background: var(--ok); color: var(--paper); border-color: var(--ok); vertical-align: middle; }
  .tracklist-pos { font: 600 0.72rem/1.4 var(--font-mono); letter-spacing: 0.08em; }
  .tracklist-title { min-width: 0; overflow-wrap: anywhere; font: 500 0.95rem/1.35 var(--font-body); }
  .tracklist-title a { text-decoration-thickness: 1px; }
  .tracklist:not([data-status]) > li[data-opened="true"] .tracklist-title { font-weight: 700; }
  .tracklist-credit { font-weight: 400; opacity: 0.75; }
  .tracklist-tags { display: flex; flex-wrap: wrap; gap: 0.3rem; justify-content: flex-end; }
  .tracklist-tags .label { font-size: 0.6rem; }
  .tracklist-len { font: 500 0.75rem/1.4 var(--font-mono); text-align: right; min-width: 3.2rem; }
  /* Mute pressing: a small crossed-out speaker tag in ink outline (data hole, not a rarity). */
  .tracklist-mute {
    display: inline-block;
    padding: 0.12em 0.4em 0.08em;
    border: 1.5px dashed currentColor;
    font: 600 0.6rem/1.2 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    rotate: -2deg;
    white-space: nowrap;
  }
  @media (max-width: 480px) {
    .tracklist > li { grid-template-columns: 1.2rem 2.2rem minmax(0, 1fr) auto; }
    .tracklist-tags { grid-column: 3 / -1; justify-content: flex-start; }
    .tracklist-len { grid-row: 1; grid-column: 4; }
  }
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Editions of an album, each with its Discogs credit next to the format data. */
  .editions { display: grid; gap: 0.7rem; }
  .editions > li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem 0.8rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px dashed var(--ink-soft);
  }
  .ticket .tier, .grid .tier { align-self: flex-start; }
  .ticket form, .grid form { margin-top: auto; }
  .ticket .action-form, .grid .action-form { margin-bottom: 0; }

  /* Ink band crossing the page diagonally; its content is counter-rotated upright. */
  .band {
    position: relative;
    width: 130vw;
    margin-inline: calc(50% - 65vw);
    padding: clamp(2.4rem, 6vw, 4.2rem) 0;
    background: var(--ink);
    color: var(--paper);
    rotate: var(--band-tilt);
  }
  .band-inner {
    width: min(var(--page), 100vw);
    max-width: var(--page);
    margin: 0 auto;
    padding: 0 var(--gutter);
    rotate: calc(var(--band-tilt) * -1);
  }

  /* 3D viewer: the library sizes its canvas from this box and appends the tear tab to it. */
  .viewer {
    position: relative;
    isolation: isolate;
    width: 100%;
    height: min(78vh, 760px);
    background: var(--ink);
    image-rendering: pixelated;
  }
  .viewer canvas { width: 100%; height: 100%; }
  .viewer.is-tearing { cursor: grabbing; }
  figure:has(> .viewer) { margin: 0; }

  .tabs { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-bottom: 1.6rem; }
  .tabs a, .tabs strong {
    padding: 0.5rem 0.9rem 0.38rem;
    border: var(--rule);
    font: 400 1rem/1 var(--font-display);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
  }
  .tabs strong { background: var(--ink); color: var(--paper); rotate: -1.5deg; box-shadow: 3px 3px 0 var(--stamp); }

  .panel {
    padding: 1.2rem 1.2rem 1rem;
    border: var(--rule-thick);
    background: var(--paper-lift);
    box-shadow: var(--drop);
  }
  .panel > h2:first-child, .panel > h3:first-child { margin-top: 0; }

  /* Wide tables scroll inside their own box instead of pushing the page; the padding keeps the drop shadow. */
  .table-scroll {
    max-width: 100%;
    overflow-x: auto;
    padding: 0 7px 7px 0;
    margin-right: -7px;
    overscroll-behavior-x: contain;
  }
  .table-scroll > table { min-width: max-content; }

  .empty-note {
    display: inline-block;
    max-width: none;
    padding: 0.8rem 1rem;
    border: 2px dashed var(--ink);
    font: 600 0.85rem/1.4 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
}

/* ------------------------------------------------------------------ pages */
@layer pages {
  /* Home hero, after the DA frame. */
  /* Cancels .site-main's top padding: the logo hangs right under the nav band. */
  .hero { position: relative; margin-top: calc(var(--main-top) * -1); }
  .hero-logo {
    display: grid;
    width: min(360px, 74vw);
    margin: 0 auto;
  }
  .hero-logo > img { grid-area: 1 / 1; width: 100%; height: auto; }
  /* The band slides down along its own tilt while a wipe parallel to its bottom edge reveals it. */
  .hero-logo-band { animation: band-sweep 620ms cubic-bezier(0.22, 1, 0.36, 1) both; }
  .hero-logo-mark { animation: pop-in 460ms var(--ease-pop) 560ms both; }
  @keyframes band-sweep {
    0% {
      translate: 10% -70%;
      clip-path: polygon(0 0, 100% 0, 100% 0%, 0 -27%);
    }
    100% {
      translate: 0 0;
      clip-path: polygon(0 0, 100% 0, 100% 127%, 0 100%);
    }
  }
  /* Home ink bands (radios, sleeves): the conveyors follow the tilt, their heading stands upright. */
  .home-band { margin-block: clamp(3rem, 7vw, 4.6rem); }
  .home-band .band-inner { width: 100vw; max-width: none; padding: 0; rotate: 0deg; }
  .band-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem 1.2rem;
    max-width: var(--page);
    margin: 0 auto 0.4rem;
    padding: 0 var(--gutter) 0.6rem;
    text-align: left;
    rotate: calc(var(--band-tilt) * -1);
  }
  .band-head h2 { margin: 0; color: var(--paper); font-size: clamp(2rem, 5vw, 3.2rem); }
  .band-head h2::first-letter { color: var(--stamp); }
  .band-head p { flex: 1 1 16rem; margin: 0; font: 500 0.78rem/1.4 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.85; }
  .band-head .btn { --btn-shadow: var(--paper); align-self: center; }
  .sleeves-band .marquee-viewport { padding-top: 0.6rem; }
  /* Thumbnails follow the window pointer without stealing clicks from their links. */
  a .pack3d > canvas { pointer-events: none; }

  .pack-marquee {
    --marquee-pack-width: clamp(210px, 30vw, 390px);
    --marquee-gap: clamp(1.25rem, 3vw, 3rem);
  }
  .marquee-viewport { overflow: hidden; padding-block: 2rem; }
  .marquee-track {
    display: flex;
    width: max-content;
    animation: packs-conveyor var(--marquee-duration) linear infinite;
    will-change: transform;
  }
  .marquee-group {
    display: flex;
    flex: none;
    align-items: flex-end;
    gap: var(--marquee-gap);
    margin: 0;
    padding: 0 var(--marquee-gap) 0 0;
    list-style: none;
  }
  /* The conveyor follows the ink band; only the individual packs counter-rotate upright. */
  .marquee-item { flex: none; width: var(--marquee-pack-width); rotate: calc(var(--band-tilt) * -1); }
  .marquee-item a { display: block; text-decoration: none; color: var(--paper); }
  .marquee-item a:hover { background: none; color: var(--paper); }
  .marquee-item .pack3d { width: 100%; transform-origin: 50% 75%; }
  .marquee-item[data-open="true"] .pack3d { animation: pack-opening-kick 480ms var(--ease-pop) both; }
  .marquee-item .pack3d-placeholder { background: color-mix(in srgb, var(--paper) 14%, var(--ink)); }
  .pack-marquee[data-offscreen="true"] .marquee-track,
  .marquee-viewport:focus-within .marquee-track { animation-play-state: paused; }
  @keyframes packs-conveyor {
    to { transform: translate3d(-50%, 0, 0); }
  }
  @keyframes pack-opening-kick {
    0% { transform: translateY(0) rotate(0deg) scale(1); }
    24% { transform: translateY(3px) rotate(1deg) scale(0.97, 1.015); }
    58% { transform: translateY(-9px) rotate(-2deg) scale(1.04); }
    100% { transform: translateY(0) rotate(0deg) scale(1); }
  }
  @media (prefers-reduced-motion: reduce) {
    .marquee-track { animation: none; transform: none; will-change: auto; }
    .marquee-group[data-duplicate="true"] { display: none; }
    .marquee-viewport { overflow-x: auto; }
    .marquee-item[data-open="true"] .pack3d { animation: none; }
  }
  .hero-lede { margin: 2rem auto 0; text-align: center; font-size: clamp(1.1rem, 2.2vw, 1.3rem); max-width: 40ch; }

  /* Hero ways in: create an account / listen (visitor), finish the profile. */
  .hero-actions { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 1rem 1.2rem; margin-top: 1.8rem; }
  .hero-actions-note {
    flex-basis: 100%;
    margin: 0;
    max-width: none;
    text-align: center;
    font: 600 0.75rem/1.4 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }

  /* Collector strip: the card (stats as stamped boxes) and "Ta station" side by side. */
  .collector {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    align-items: stretch;
    gap: 1.4rem;
    max-width: 62rem;
    margin: 2.4rem auto 0;
    text-align: left;
  }
  .collector-card {
    padding: 0 1.2rem 1.1rem;
    border: var(--rule-thick);
    background: var(--paper-lift);
    box-shadow: var(--drop-lg);
    rotate: -0.6deg;
  }
  .collector-card p { max-width: none; }
  .collector-card h2 { margin: 0.6rem 0 0.8rem; font-size: clamp(1.8rem, 4.5vw, 2.6rem); overflow-wrap: anywhere; }
  .collector-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: 0.6rem;
    border: 0;
  }
  .collector-stats > div { display: grid; align-content: start; gap: 0.25rem; padding: 0.5rem 0.6rem 0.55rem; border: var(--rule); background: var(--paper); }
  .collector-stats dt, .collector-stats dd { padding: 0; border: 0; }
  .collector-stats dd { display: grid; gap: 0.25rem; font: 400 1.5rem/1 var(--font-display); letter-spacing: 0.03em; }
  .collector-stats small { font: 500 0.68rem/1.3 var(--font-mono); letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.8; }
  .collector-onair { background: var(--stamp) !important; border-color: var(--stamp) !important; color: var(--paper); rotate: 1deg; }
  .collector-trades dd a { color: var(--stamp); }
  .collector-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; margin: 1rem 0 0; }
  .collector-actions a:hover { background: var(--btn-bg); }
  .collector .station-card { align-content: start; border: var(--rule-thick); box-shadow: 6px 6px 0 var(--stamp); rotate: 0.8deg; }
  @media (max-width: 760px) {
    .collector { grid-template-columns: minmax(0, 1fr); }
  }
  @media (max-width: 560px) {
    .collector-card { padding: 0 0.9rem 1rem; }
    .collector-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }

  /* Home sections between the two ink bands. */
  .home-section { max-width: 62rem; margin: 0 auto clamp(2.6rem, 6vw, 3.6rem); }
  .home-section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem 1.2rem;
    padding-bottom: 0.5rem;
    margin-bottom: 1.4rem;
    border-bottom: var(--rule-thick);
  }
  .home-section-head h2 { margin: 0; }
  .home-section-head p { margin: 0; }

  /* "Comment ça marche": three numbered slips, the number as a red stamp. */
  .home-steps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
    gap: 1.4rem;
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: step;
  }
  .home-steps > li {
    position: relative;
    display: grid;
    align-content: start;
    gap: 0.5rem;
    padding: 1.6rem 1.1rem 1rem;
    border: var(--rule);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    counter-increment: step;
    rotate: var(--tilt, 0deg);
  }
  .home-steps > li:nth-child(1) { --tilt: -0.8deg; }
  .home-steps > li:nth-child(2) { --tilt: 0.6deg; }
  .home-steps > li:nth-child(3) { --tilt: -0.3deg; }
  .home-steps > li::before {
    content: counter(step);
    position: absolute;
    top: -1rem;
    left: 0.8rem;
    display: grid;
    place-items: center;
    width: 2.2rem;
    height: 2.2rem;
    background: var(--stamp);
    color: var(--paper);
    font: 400 1.4rem/1 var(--font-display);
    rotate: -6deg;
    box-shadow: 2px 2px 0 var(--ink);
  }
  .home-steps h3 { margin: 0; font-size: 1.5rem; }
  .home-steps p { margin: 0; max-width: none; }
  .home-steps a { margin-top: 0.3rem; font: 600 0.78rem/1.4 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; }

  /* Booster reveal. */
  .stock { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1.2rem; margin-bottom: 1rem; }
  .stock-count { font: 400 3.6rem/0.9 var(--font-display); color: var(--stamp); }
  .open-booster > .btn, .open-booster > button { font-size: 1.5rem; padding: 0.8rem 1.6rem 0.65rem; }

  /* Crates ready to open: a shelf of 3D sealed crates, the empty spots are still on their way. */
  .crate-shelf {
    flex-basis: 100%;
    display: grid;
    /* max_stock slots (10): 5 per row, then 3 / 2 on narrower screens. */
    grid-template-columns: repeat(5, minmax(0, 1fr));
    width: 100%;
    min-width: 0;
    max-width: 62rem;
    gap: 0.2rem 0.8rem;
    margin: 0 0 1.4rem;
    padding: 0;
    list-style: none;
  }
  .crate-shelf > li { position: relative; min-width: 0; aspect-ratio: 1.15; transition: opacity 180ms linear, translate 180ms var(--ease-snap); }
  .crate-shelf > li[data-picked] { opacity: 0; translate: 0 -12%; }
  .crate-shelf > li > .crate-slot {
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    translate: none;
    cursor: pointer;
  }
  .crate-shelf > li > .crate-slot[aria-disabled="true"] { cursor: progress; }
  .crate-shelf > li > .crate-slot:hover, .crate-shelf > li > .crate-slot:active { background: none; box-shadow: none; translate: none; }
  .crate3d { position: relative; width: 100%; height: 100%; image-rendering: pixelated; }
  .crate3d > canvas { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; }
  /* Until the viewer has drawn (or without WebGL): a kraft crate silhouette. */
  .crate3d-placeholder {
    position: absolute;
    inset: 18% 20%;
    background: #a87a4c;
    border: 2px solid var(--ink);
    box-shadow: inset 0 -38% 0 #8a6038, 4px 4px 0 var(--ink-faint);
    transition: opacity 160ms linear;
  }
  .crate3d[data-ready] .crate3d-placeholder { opacity: 0; }
  /* Right after signup: the first crate in close-up, above the shelf. */
  .welcome-crate {
    flex-basis: 100%;
    display: grid;
    justify-items: center;
    gap: 0.4rem;
    margin: 0 0 1.2rem;
    transition: opacity 180ms linear, translate 180ms var(--ease-snap);
  }
  .welcome-crate[data-picked] { opacity: 0; translate: 0 -8%; }
  .welcome-crate-title {
    margin: 0;
    text-align: center;
    font: 400 clamp(1.6rem, 4.5vw, 2.6rem)/1 var(--font-display);
    text-transform: uppercase;
    color: var(--stamp);
  }
  .welcome-crate-title > span {
    display: block;
    margin-top: 0.4rem;
    font: 600 0.8rem/1.3 var(--font-mono);
    letter-spacing: 0.08em;
    text-transform: none;
    color: var(--ink);
  }
  .welcome-crate > .crate-slot {
    width: min(26rem, 80vw);
    aspect-ratio: 1.15;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    translate: none;
    cursor: pointer;
  }
  .welcome-crate > .crate-slot:hover, .welcome-crate > .crate-slot:active { background: none; box-shadow: none; translate: none; }
  .welcome-crate > .crate-slot:focus-visible { outline: 3px solid var(--stamp); outline-offset: 4px; }
  @media (max-width: 860px) { .crate-shelf { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  @media (max-width: 480px) { .crate-shelf { gap: 0.1rem 0.5rem; } .crate-shelf .crate-empty-label { font-size: 0.55rem; letter-spacing: 0.04em; } .crate-shelf .crate-timer-label { font-size: 0.5rem; letter-spacing: 0.04em; } }
  @media (max-width: 359px) { .crate-shelf { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  /* An empty spot: the dashed outline of a crate (same footprint as the placeholder). */
  .crate-empty {
    display: grid;
    place-items: center;
    color: color-mix(in srgb, var(--ink) 55%, transparent);
  }
  .crate-empty-outline {
    position: absolute;
    inset: 18% 20%;
    border: 2px dashed color-mix(in srgb, var(--ink) 30%, transparent);
    background: color-mix(in srgb, var(--ink) 3%, transparent);
  }
  .crate-empty-label, .crate-timer-label {
    position: relative;
    font: 600 0.7rem/1 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }
  /* The next spot to fill: the outline in ink, a ring filling over the period, time left. */
  .crate-empty[data-next] { color: var(--ink); }
  .crate-empty[data-next] > .crate-empty-outline { border-color: color-mix(in srgb, var(--ink) 60%, transparent); }
  .crate-timer { position: relative; display: grid; place-items: center; width: min(58%, 7.5rem); aspect-ratio: 1; }
  .crate-timer-ring { position: absolute; inset: 0; width: 100%; height: 100%; rotate: -90deg; overflow: visible; }
  .crate-timer-ring circle { fill: none; stroke-width: 3.5; }
  .crate-timer-track { stroke: color-mix(in srgb, var(--ink) 14%, transparent); fill: var(--paper) !important; }
  .crate-timer-arc { stroke: var(--stamp); stroke-linecap: butt; transition: stroke-dashoffset 1s linear; }
  .crate-timer-text { position: relative; display: grid; justify-items: center; gap: 0.25em; }
  .crate-timer-label { font-size: 0.6rem; }
  .crate-timer-clock { font: 400 clamp(1.1rem, 2.4vw, 1.6rem)/1 var(--font-display); font-variant-numeric: tabular-nums; color: var(--stamp); }
  .crate-timer[data-due] .crate-timer-arc { animation: stamp-blink 900ms steps(2, jump-none) infinite; }
  @keyframes stamp-blink { 50% { opacity: 0.35; } }
  @media (prefers-reduced-motion: reduce) {
    .crate-timer-arc { transition: none; }
    .crate-timer[data-due] .crate-timer-arc { animation: none; }
  }
  .reveal-head h2 { margin-bottom: 0.2em; }
  .draws { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); margin-top: 1rem; }
  .draws > li .tier { position: absolute; top: 0.9rem; right: 0.9rem; font-size: 1.05rem; z-index: 1; rotate: -8deg; }
  .draws > li[data-tier="epic"], .draws > li[data-tier="legendary"] { box-shadow: 5px 5px 0 var(--stamp); }
  .history { display: flex; flex-wrap: wrap; gap: 0.7rem; }
  .history a { text-decoration: none; }
  .history a:hover { background: var(--ink); color: var(--paper); }


  /* Item page: a flat ink band edge to edge. The 3D canvas covers the whole band; the title and
   * the facts card are laid over it, so a turning pack (lid, shadow) never clips on a box edge. */
  .item-stage {
    --band-pad: clamp(1.2rem, 3vw, 2rem);
    position: relative;
    isolation: isolate;
    /* Hangs right under the nav band, like .hero: cancels .site-main's top padding. */
    margin-top: calc(var(--main-top) * -1);
    margin-inline: calc(50% - 50vw);
    padding: var(--band-pad) calc(50vw - 50%);
    background: var(--ink);
    color: var(--paper);
  }
  /* Content-width grid over the band: title top left, card centred on the right, and an empty
   * slot left of the card whose centre the pack is shifted onto (see item-actions.tsx). */
  .item-stage-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 380px);
    grid-template-rows: auto 1fr;
    column-gap: clamp(1.5rem, 3vw, 2.5rem);
    /* Band height; a taller card grows it (the canvas follows, the pack stays centred). */
    min-height: calc(clamp(560px, 84vh, 820px) - 2 * var(--band-pad));
  }
  .item-stage h1 {
    grid-area: 1 / 1;
    position: relative;
    z-index: 1;
    margin-block: 0 0.1em;
    text-shadow: 0.035em 0.03em 0 var(--stamp);
    /* The lid may pass under the title: drags still reach the canvas. */
    pointer-events: none;
  }
  .item-canvas { position: absolute; inset: 0; z-index: 0; }
  .item-canvas figure, .item-canvas .viewer { height: 100%; }
  .item-pack-slot { grid-area: 1 / 1 / -1 / 2; pointer-events: none; }
  .item-facts {
    grid-area: 1 / 2 / -1 / 3;
    align-self: center;
    position: relative;
    z-index: 1;
    color: var(--ink);
  }
  .item-facts .tier { font-size: 1.05rem; }
  /* The card's title is its first rule: no ruled line above the facts. */
  .item-facts dl { border-top: 0; }
  .item-share { margin: 0.9rem 0 0; }
  .tear-hint {
    font: 600 0.78rem/1.4 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.72;
  }
  .tear-hint > span { display: block; font-weight: 500; letter-spacing: 0.04em; text-transform: none; }
  .sell-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1.5rem; align-items: start; }
  /* Auctions (BidForm, SellCopy, item page): live clock, red under 1 h, blinking under 5 min. */
  .auction-summary { margin: 0.9rem 0 0.4rem; }
  .auction-summary strong { font-size: 1.25em; }
  .auction-clock { font-variant-numeric: tabular-nums; white-space: nowrap; }
  .auction-clock[data-urgent] { color: var(--stamp); font-weight: 700; }
  @media (prefers-reduced-motion: no-preference) {
    .auction-clock[data-urgent="5m"] { animation: auction-blink 1s steps(2, start) infinite; }
  }
  @keyframes auction-blink { to { opacity: 0.35; } }
  .item-auction .bid-form input[type="number"] { width: 9ch; }
  .item-bids { margin-top: 1.5rem; }
  .item-bids tr[data-me] { font-weight: 700; }
  .my-copies { list-style: none; padding: 0; display: grid; gap: 1.5rem; }
  .my-copies > li + li { border-top: 1px dashed currentColor; padding-top: 1.5rem; }
  @media (max-width: 860px) {
    /* Stacked: title, canvas in the flow (edge to edge, pack centred), then the card. */
    .item-stage-inner { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; min-height: 0; }
    .item-stage h1, .item-facts { grid-area: auto; }
    .item-pack-slot { display: none; }
    .item-canvas { position: relative; inset: auto; margin-inline: calc(50% - 50vw); }
    .item-facts { margin-top: 1.6rem; }
    .viewer, .item-canvas .viewer { height: min(70vh, 520px); }
  }
  @media (max-width: 640px) { .sell-actions { grid-template-columns: minmax(0, 1fr); } }

  /* Tear tab, appended and positioned (inline transform) by the pack viewer: a paper reticle. */
  button.tear-tab {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    width: 44px;
    height: 44px;
    min-height: 0;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    translate: none;
    cursor: grab;
    touch-action: none;
    user-select: none;
    will-change: transform;
  }
  button.tear-tab:hover, button.tear-tab:active { background: transparent; box-shadow: none; translate: none; }
  button.tear-tab[hidden] { display: none; }
  button.tear-tab.is-pulling { cursor: grabbing; }
  button.tear-tab.is-pulling:focus-visible { outline: none; }
  .tear-tab__reticle {
    position: relative;
    width: 22px;
    height: 22px;
    border: 2px solid var(--paper);
    border-radius: 50%;
    filter: drop-shadow(1px 1px 0 var(--ink));
    animation: reticle-pulse 1.6s ease-in-out infinite;
  }
  /* Four ticks around the ring, and a centre dot. */
  .tear-tab__reticle::before {
    content: "";
    position: absolute;
    inset: -9px;
    background:
      linear-gradient(var(--paper) 0 0) top / 2px 7px no-repeat,
      linear-gradient(var(--paper) 0 0) bottom / 2px 7px no-repeat,
      linear-gradient(var(--paper) 0 0) left / 7px 2px no-repeat,
      linear-gradient(var(--paper) 0 0) right / 7px 2px no-repeat;
  }
  .tear-tab__reticle::after {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    width: 4px;
    height: 4px;
    translate: -50% -50%;
    background: var(--paper);
  }
  .tear-tab.is-pulling .tear-tab__reticle { animation: none; scale: 0.88; }
  .tear-tab__label {
    position: absolute;
    left: 46px;
    top: 50%;
    translate: 0 -50%;
    padding: 0.3em 0.5em 0.25em;
    background: var(--ink);
    color: var(--paper);
    font: 600 0.62rem/1.35 var(--font-mono);
    letter-spacing: 0.12em;
    text-align: left;
    text-transform: uppercase;
    white-space: nowrap;
    pointer-events: none;
    transition: opacity 120ms linear;
  }
  .tear-tab.is-partial .tear-tab__label, .tear-tab.is-pulling .tear-tab__label { opacity: 0; }
  @keyframes reticle-pulse {
    0%, 100% { scale: 1; }
    50% { scale: 1.14; }
  }
  @media (prefers-reduced-motion: reduce) {
    .tear-tab__reticle { animation: none; }
  }

  /* Station: the albums on air on their shelf, then the crate of sealed copies (station styles at
   * the end of this file). */
  .room-section { margin-top: 2.6rem; }
  .room-section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.6rem 1.4rem;
    margin-bottom: 1.4rem;
    padding-bottom: 0.6rem;
    border-bottom: var(--rule);
  }
  .room-section-head h2 { margin: 0; }

  /* The crate: a clean grid of sealed copies, no tilt. */
  .room-crate > li { --tilt: 0deg; }

  /* Item page: opening, warning when some tracks are already in the library. */
  .item-open { margin-top: 1.4rem; }
  .open-warning {
    max-width: 72ch;
    margin-bottom: 0.8rem;
    padding: 0.7rem 0.9rem;
    border: 3px solid var(--stamp);
    background: var(--paper-lift);
    font: 500 0.92rem/1.45 var(--font-body);
    rotate: -0.4deg;
    box-shadow: 4px 4px 0 var(--ink);
  }
  .open-warning strong { color: var(--stamp); }
  .item-tracklist { margin-top: 0.6rem; }

  .trade-list { display: grid; gap: 1.4rem; }
  .trade-list > li { padding: 1rem 1.1rem; border: var(--rule-thick); background: var(--paper-lift); box-shadow: var(--drop); }
  .trade-list > li:nth-child(even) { rotate: 0.4deg; }
  .trade-head { max-width: none; display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.8rem; font: 600 0.78rem/1.5 var(--font-mono); letter-spacing: 0.05em; text-transform: uppercase; }
  .trade-head strong { font: 400 1.3rem/1 var(--font-display); letter-spacing: 0.03em; }
  .trade-sides { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 0.8rem 0; }
  .trade-sides > div { padding: 0.7rem; border: 1.5px dashed var(--ink); }
  @media (max-width: 640px) { .trade-sides { grid-template-columns: 1fr; } }

  .auth-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.6rem; }
  .auth-grid > section:nth-child(2) { rotate: 0.8deg; }
  .auth-grid > section:nth-child(3) { rotate: -0.6deg; }
  .auth-grid input:not([type="checkbox"]) { width: 100%; }
  .auth-grid label { display: flex; margin-right: 0; }

  .legal { max-width: 72ch; }
  .legal section { margin-top: 2.4rem; }
  .legal ul { padding-left: 1.2rem; }
  .legal li + li { margin-top: 0.5rem; }

  .big-404 {
    max-width: none;
    font: 400 clamp(6rem, 22vw, 14rem)/0.8 var(--font-display);
    color: var(--stamp);
    filter: url(#ink-bleed-coarse);
    text-shadow: 0.03em 0.03em 0 var(--ink);
  }
}

/* --------------------------------------------------------------------- fx */
@layer fx {
  /* Booster reveal: packs pop in sequence, then the rarity stamp slams. */
  .draws > li {
    animation: pop-in 460ms var(--ease-pop) backwards;
    animation-delay: calc(120ms + var(--i, 0) * 80ms);
  }
  .draws > li .tier {
    animation: stamp-slam 340ms var(--ease-snap) backwards;
    animation-delay: calc(440ms + var(--i, 0) * 80ms);
  }
  /* The crate button trembles while the server draws it. */
  .open-booster[aria-busy="true"] button { animation: shake 260ms linear infinite; }

  .reveal[data-best="epic"], .reveal[data-best="legendary"] {
    animation: shake 380ms var(--ease-snap) both;
    animation-delay: 900ms;
  }

  /* Global FX layer (slammed stamps). */
  .fx-layer {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: grid;
    place-items: center;
    pointer-events: none;
  }
  .fx-layer.is-anchored .fx-stamp { font-size: clamp(2.2rem, 6vw, 4.4rem); }
  .fx-stamp {
    font-size: clamp(3.5rem, 13vw, 8rem);
    border-width: 0.09em;
    animation: fx-slam 1500ms var(--ease-snap) both;
  }
  /* Crate opening: full-screen 3D scene above the dimmed page, DOM controls and labels on top.
   * The reveal list underneath stays in the DOM but hidden; showing it again restarts its pop-ins. */
  html[data-carton="open"] .reveal-section { display: none; }
  .carton-overlay {
    position: fixed;
    inset: 0;
    z-index: 95;
    overflow: hidden;
    outline: none;
    touch-action: none;
  }
  .carton-overlay[hidden] { display: none; }
  .carton-dim {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, var(--ink) 88%, black);
    opacity: 0;
    transition: opacity 260ms var(--ease-snap);
  }
  .carton-overlay.is-on .carton-dim { opacity: 0.86; }
  .carton-canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 200ms linear; }
  .carton-overlay.is-on .carton-canvas { opacity: 1; }

  .carton-hint {
    position: absolute;
    left: 50%;
    top: calc(env(safe-area-inset-top) + clamp(1rem, 7vh, 3.5rem));
    margin: 0;
    padding: 0.4em 0.75em 0.3em;
    background: var(--paper);
    color: var(--ink);
    border: var(--rule);
    box-shadow: 4px 4px 0 var(--stamp);
    font: 400 clamp(1.3rem, 4.5vw, 2rem)/1 var(--font-display);
    letter-spacing: 0.06em;
    text-align: center;
    text-transform: uppercase;
    translate: -50% 0;
    rotate: -2deg;
    pointer-events: none;
    opacity: 0;
    transition: opacity 160ms linear, scale 300ms var(--ease-pop);
    scale: 0.8;
  }
  .carton-overlay.is-on[data-phase="sealed"] .carton-hint { opacity: 1; scale: 1; }

  /* Pull handle: a focusable reticle laid on the tab, moved by the scene every frame. */
  button.carton-pull {
    position: absolute;
    left: -22px;
    top: -22px;
    width: 44px;
    height: 44px;
    min-height: 0;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    translate: none;
    cursor: grab;
    will-change: transform;
    /* The canvas below handles the drag; the button is for focus, keys and taps. */
    pointer-events: none;
  }
  button.carton-pull:not([data-placed]) { visibility: hidden; }
  button.carton-pull[hidden] { display: none; }
  button.carton-pull:hover, button.carton-pull:active { background: transparent; box-shadow: none; translate: none; }
  button.carton-pull:focus-visible { outline: 3px solid var(--stamp); outline-offset: 2px; }
  .carton-pull__reticle {
    position: absolute;
    inset: 11px;
    border: 2px solid var(--paper);
    border-radius: 50%;
    filter: drop-shadow(1px 1px 0 var(--ink));
    animation: reticle-pulse 1.6s ease-in-out infinite;
  }
  .carton-overlay[data-phase="tearing"] .carton-pull__reticle { animation: none; opacity: 0.5; }

  /* One label above each pack, following its anchor; the rarity stamp slams in once out. */
  .carton-labels { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; pointer-events: none; }
  .carton-label {
    position: absolute;
    left: 0;
    top: 0;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    width: 0;
    height: 0;
    will-change: transform;
    visibility: hidden;
  }
  .carton-label[data-visible] { visibility: visible; }
  .carton-label > a {
    flex: none;
    display: grid;
    justify-items: center;
    gap: 0.3rem;
    width: max-content;
    max-width: 10rem;
    color: var(--ink); /* the .tier stamp inherits it; its rare+ variants set their own */
    text-decoration: none;
    pointer-events: auto;
    opacity: 0;
  }
  .carton-overlay[data-phase="revealed"] .carton-label > a {
    animation: pop-in 420ms var(--ease-pop) both;
    animation-delay: calc(var(--i, 0) * 80ms);
  }
  .carton-label-name {
    padding: 0.2em 0.45em 0.15em;
    background: var(--ink);
    color: var(--paper);
    border: 1.5px solid var(--paper);
    font: 600 0.68rem/1.2 var(--font-mono);
    letter-spacing: 0.08em;
    text-align: center;
    text-transform: uppercase;
    box-shadow: 3px 3px 0 var(--stamp);
  }
  .carton-label .tier { font-size: 0.95rem; box-shadow: 3px 3px 0 var(--ink); }
  .carton-overlay[data-phase="revealed"] .carton-label .tier {
    animation: stamp-slam 340ms var(--ease-snap) both;
    animation-delay: calc(260ms + var(--i, 0) * 80ms);
  }
  .carton-label[data-hero] > a { max-width: 14rem; z-index: 1; }
  .carton-label[data-hero] .carton-label-name { font-size: 0.82rem; }
  .carton-label[data-hero] .tier { font-size: 1.5rem; }
  .carton-label > a:hover .carton-label-name,
  .carton-label > a:focus-visible .carton-label-name { background: var(--stamp); }
  .carton-label > a:focus-visible { outline: 3px solid var(--paper); outline-offset: 3px; }
  @media (max-width: 560px) {
    .carton-label > a { max-width: 6.5rem; gap: 0.2rem; }
    .carton-label-name { font-size: 0.56rem; letter-spacing: 0.04em; }
    .carton-label .tier { font-size: 0.7rem; }
    .carton-label[data-hero] > a { max-width: 9rem; }
    .carton-label[data-hero] .carton-label-name { font-size: 0.66rem; }
    .carton-label[data-hero] .tier { font-size: 1.05rem; }
  }

  .carton-actions {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.8rem;
    min-height: 90px;
    padding: 0.8rem max(1rem, env(safe-area-inset-right)) calc(0.8rem + env(safe-area-inset-bottom))
      max(1rem, env(safe-area-inset-left));
    pointer-events: none;
  }
  .carton-actions > button { pointer-events: auto; animation: drop-in 260ms var(--ease-snap) both; }
  .carton-actions > .btn-ink { border-color: var(--paper); }
  .carton-actions > .btn-stamp { font-size: 1.35rem; padding: 0.75rem 1.4rem 0.6rem; }
  .carton-actions > .carton-share { --btn-shadow: var(--stamp); }
  .carton-actions > .carton-share[data-state="shared"],
  .carton-actions > .carton-share[data-state="saved"] { --btn-bg: var(--ink); --btn-fg: var(--paper); border-color: var(--paper); }

  /* Presented sleeve: big label laid under it, the rarity stamp slamming in harder as tiers rise. */
  .carton-present {
    position: absolute;
    left: 0;
    top: 0;
    width: 0;
    height: 0;
    display: flex;
    justify-content: center;
    will-change: transform;
    pointer-events: none;
    visibility: hidden;
  }
  .carton-present[data-shown] { visibility: visible; }
  .carton-present__card {
    flex: none;
    display: grid;
    justify-items: center;
    gap: 0.35rem;
    width: max-content;
    max-width: min(34rem, 92vw);
    color: var(--ink); /* the .tier stamp inherits it; its rare+ variants set their own */
    text-align: center;
  }
  .carton-present[data-shown] .carton-present__card { animation: pop-in 380ms var(--ease-pop) both; }
  .carton-present__count {
    padding: 0.15em 0.5em 0.1em;
    background: var(--paper);
    color: var(--ink);
    border: 1.5px solid var(--ink);
    font: 600 0.62rem/1.2 var(--font-mono);
    letter-spacing: 0.14em;
  }
  .carton-present__title {
    display: grid;
    gap: 0.2em;
    padding: 0.3em 0.6em 0.2em;
    background: var(--paper);
    color: var(--ink);
    border: var(--rule);
    box-shadow: 4px 4px 0 var(--stamp);
    font: 400 clamp(1.3rem, 4.2vw, 2.3rem)/1.05 var(--font-display);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    overflow-wrap: anywhere;
    rotate: -1.5deg;
  }
  .carton-present__title > small {
    font: 600 0.62rem/1.2 var(--font-mono);
    letter-spacing: 0.14em;
    color: var(--stamp);
  }
  .carton-present__artist {
    padding: 0.2em 0.5em 0.15em;
    background: var(--ink);
    color: var(--paper);
    border: 1.5px solid var(--paper);
    font: 600 clamp(0.72rem, 2.2vw, 0.95rem)/1.2 var(--font-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    overflow-wrap: anywhere;
  }
  .carton-present .tier { font-size: clamp(1.1rem, 3.4vw, 1.6rem); box-shadow: 3px 3px 0 var(--ink); }
  .carton-present[data-shown] .tier { animation: stamp-slam 340ms var(--ease-snap) 180ms both; }
  .carton-present__card[data-tier="rare"] .tier { font-size: clamp(1.3rem, 4vw, 1.9rem); }
  .carton-present__card[data-tier="epic"] .tier,
  .carton-present__card[data-tier="legendary"] .tier { font-size: clamp(1.6rem, 5vw, 2.5rem); animation-duration: 460ms; }
  .carton-present__card[data-tier="legendary"] .carton-present__title { box-shadow: 4px 4px 0 var(--stamp), 0 0 0 3px var(--paper), 0 0 28px 6px color-mix(in srgb, #ffdf74 55%, transparent); }

  /* Sound toggle, top right (the radio is paused under the overlay). */
  button.carton-mute {
    position: absolute;
    top: calc(env(safe-area-inset-top) + 0.75rem);
    right: max(0.75rem, env(safe-area-inset-right));
    min-height: 0;
    width: 2.6rem;
    height: 2.6rem;
    padding: 0;
    font-size: 1.15rem;
    border-color: var(--paper);
    --btn-bg: var(--ink);
    --btn-fg: var(--paper);
    --btn-shadow: var(--stamp);
  }
  button.carton-mute:focus-visible { outline: 3px solid var(--paper); outline-offset: 2px; }
  .carton-overlay:not(.is-on) .carton-mute { visibility: hidden; }
  .carton-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  @keyframes pop-in {
    0% { opacity: 0; scale: 0.6; translate: 0 18px; }
    60% { opacity: 1; scale: 1.08; translate: 0 -4px; }
    100% { opacity: 1; scale: 1; translate: 0 0; }
  }
  @keyframes stamp-slam {
    0% { opacity: 0; scale: 1.4; rotate: -16deg; }
    60% { opacity: 1; scale: 0.94; rotate: -8deg; }
    100% { opacity: 1; scale: 1; rotate: -8deg; }
  }
  @keyframes fx-slam {
    0% { opacity: 0; scale: 2.2; rotate: -18deg; }
    18% { opacity: 1; scale: 0.92; rotate: -9deg; }
    26% { scale: 1.04; }
    34%, 78% { opacity: 1; scale: 1; rotate: -9deg; }
    100% { opacity: 0; scale: 1; rotate: -9deg; }
  }
  @keyframes shake {
    0%, 100% { translate: 0 0; }
    20% { translate: -6px 1px; }
    40% { translate: 5px -1px; }
    60% { translate: -3px 0; }
    80% { translate: 2px 0; }
  }
  @keyframes drop-in {
    0% { opacity: 0; translate: 0 -40px; rotate: -8deg; }
    100% { opacity: 1; translate: 0 0; rotate: 0deg; }
  }
  @keyframes fx-fade {
    0%, 85% { opacity: 1; }
    100% { opacity: 0; }
  }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 1ms !important;
      animation-iteration-count: 1 !important;
      animation-delay: 0ms !important;
      transition-duration: 1ms !important;
    }
    /* Feedback stays readable, without motion. */
    .fx-stamp { animation: fx-fade 1400ms linear both !important; }
  }
}

/* ------------------------------------------------- station (pages, reopened) */
/* The player's station (docs/PIVOT.md, « la station du joueur »): a radio sign for /u/[username],
 * the "Ta station" stub of the collector card, "Sur les ondes" on the home page, the keep / on air
 * choice of the item page, the album progress tags of the crate reveal. */
@layer pages {

  /* Station page header: the sign (ink, edge to edge, like the item band) and the set. */
  .station-head {
    position: relative;
    isolation: isolate;
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: 1.6rem clamp(1.5rem, 4vw, 3rem);
    align-items: center;
    margin-top: calc(var(--main-top) * -1);
    margin-inline: calc(50% - 50vw);
    padding-block: clamp(1.6rem, 4vw, 2.8rem) clamp(1.8rem, 4vw, 3rem);
    /* Edge-to-edge band, content aligned on the page column. */
    padding-inline: max(var(--gutter), calc(50vw - var(--page) / 2 + var(--gutter)));
    background: var(--ink);
    color: var(--paper);
    border-bottom: 4px solid var(--stamp);
  }
  .station-head[data-private] { grid-template-columns: 1fr; }
  .station-sign { min-width: 0; }
  .station-kicker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.8rem;
    margin: 0;
    font: 600 0.78rem/1.3 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  .station-head h1 {
    margin-block: 0.18em 0.2em;
    font-size: clamp(2.6rem, 8vw, 6.2rem);
    color: var(--paper);
    text-shadow: 0.04em 0.035em 0 var(--stamp);
    overflow-wrap: anywhere;
  }
  .station-bio { margin: 0 0 0.6rem; max-width: 52ch; opacity: 0.9; }
  .station-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem 1rem;
    margin: 0;
    font: 500 0.78rem/1.4 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
  .station-meta strong {
    display: inline-block;
    padding: 0.2em 0.5em 0.12em;
    background: var(--paper);
    color: var(--ink);
    font: 400 clamp(1.3rem, 3vw, 1.8rem)/1 var(--font-display);
    letter-spacing: 0.03em;
    rotate: -2deg;
    box-shadow: 3px 3px 0 var(--stamp);
  }
  .station-private-note { margin: 0.8rem 0 0; font: 500 0.8rem/1.4 var(--font-mono); opacity: 0.85; }
  .station-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem 1rem; margin: 1.3rem 0 0; }
  .station-actions .btn:not(.btn-ink) { --btn-shadow: var(--stamp); }
  .station-actions .btn-ink { border-color: var(--paper); }
  .station-play { font-size: clamp(1.3rem, 3vw, 1.7rem); }
  .station-actions .radio-play-error { color: var(--paper); }
  .station-off { margin: 1rem 0 0 0.4rem; font-size: 2.4rem; color: var(--stamp); mix-blend-mode: normal; }

  /* Station3D slot. Until the PSX scene is wired: its static fallback, an "ON AIR" sign above the
   * latest sleeves laid flat on a shelf. */
  .station3d {
    position: relative;
    min-width: 0;
    height: clamp(280px, 32vw, 360px);
    border: 2px solid color-mix(in srgb, var(--paper) 35%, transparent);
    background:
      repeating-linear-gradient(-45deg, transparent 0 9px, color-mix(in srgb, var(--paper) 5%, transparent) 9px 10px);
    overflow: hidden;
  }
  /* The scene's canvas fills the stage; the fallback sits under it and goes once it has drawn. */
  .station3d-stage { position: absolute; inset: 0; z-index: 1; image-rendering: pixelated; }
  .station3d-fallback {
    position: absolute;
    inset: 0;
    display: grid;
    align-content: center;
    justify-items: center;
    gap: 1.1rem;
    padding: 1.2rem 1rem 1.4rem;
  }
  .station3d[data-ready] .station3d-fallback { visibility: hidden; }
  .station-onair {
    padding: 0.35rem;
    border: 3px solid var(--paper);
    rotate: -2.5deg;
    opacity: 0.45;
  }
  .station-onair > span {
    display: block;
    padding: 0.2em 0.55em 0.12em;
    border: 2px solid var(--paper);
    font: 400 clamp(1.8rem, 4.5vw, 3rem)/1 var(--font-display);
    letter-spacing: 0.14em;
    text-transform: uppercase;
  }
  .station3d[data-on-air] .station-onair {
    opacity: 1;
    border-color: var(--stamp);
    box-shadow: 0 0 22px 4px color-mix(in srgb, var(--stamp) 45%, transparent);
  }
  .station3d[data-on-air] .station-onair > span {
    background: var(--stamp);
    color: var(--paper);
    border-color: var(--paper);
    filter: url(#ink-bleed);
  }
  .station-shelf {
    display: flex;
    justify-content: center;
    width: 100%;
    padding: 0 0 0.7rem;
    border-bottom: 6px solid color-mix(in srgb, var(--paper) 70%, var(--ink));
  }
  .station-shelf > li { flex: 0 1 7.5rem; min-width: 0; margin-inline: -0.9rem; }
  .station-shelf > li:nth-child(odd) { rotate: -4deg; }
  .station-shelf > li:nth-child(even) { rotate: 3deg; translate: 0 -0.3rem; }
  .station-shelf > li:first-child { z-index: 2; }
  .station-shelf a { display: block; text-decoration: none; }
  .station-shelf a:hover { background: none; translate: 0 -4px; }
  .station-shelf img, .station-shelf-blank {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    border: 2px solid var(--paper);
    box-shadow: 4px 4px 0 var(--stamp);
    image-rendering: pixelated;
  }
  .station-shelf-blank {
    display: grid;
    place-items: center;
    padding: 0.4rem;
    background: var(--paper);
    color: var(--ink);
    font: 400 0.9rem/1 var(--font-display);
    text-align: center;
    text-transform: uppercase;
    overflow: hidden;
  }
  .station-shelf-empty {
    padding: 0.6rem 1rem;
    border: 2px dashed color-mix(in srgb, var(--paper) 50%, transparent);
    font: 600 0.75rem/1.2 var(--font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    opacity: 0.7;
  }
  /* Station band (StationStage), like the item band: the booth covers the whole band, edge to edge
   * and at least half the viewport high; the sign sits over its left, the booth is framed in the
   * free slot right of it. */
  .station-stage {
    /* A wider column than the page: the sign leans left, the booth's slot reaches further right. */
    --stage-col: min(1640px, 100vw);
    display: block;
    min-height: max(50vh, 460px);
    padding-block: clamp(2rem, 6vh, 4rem);
    padding-inline: max(var(--gutter), calc(50vw - var(--stage-col) / 2 + 2.5rem));
    /* No red rule: the yellow desk runs on into the page's paper. */
    border-bottom: 0;
  }
  .station-stage-inner {
    position: relative;
    z-index: 2;
    display: grid;
    grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
    column-gap: clamp(2rem, 5vw, 5rem);
    align-items: center;
    min-height: calc(max(50vh, 460px) - 2 * clamp(2rem, 6vh, 4rem));
    pointer-events: none;
  }
  .station-stage .station-sign { pointer-events: auto; }
  .station-stage-slot { align-self: stretch; }
  .station-stage .station-stage-canvas {
    position: absolute;
    inset: 0;
    z-index: 1;
    height: auto;
    border: 0;
    background: none;
  }
  /* Readable sign over the scene's dark wall. */
  .station-stage .station-kicker, .station-stage .station-meta > span, .station-stage .station-bio,
  .station-stage .station-private-note {
    text-shadow: 0 0 18px var(--ink), 0 0 6px var(--ink);
  }
  .station-stage .station-head h1, .station-stage h1 {
    font-size: clamp(2.6rem, 6.4vw, 6.2rem);
    text-shadow: 0.04em 0.035em 0 var(--stamp), 0 0 24px var(--ink);
  }
  .station-stage .station3d-fallback { left: auto; width: 55%; }
  @media (max-width: 860px) {
    .station-stage { min-height: 0; padding-bottom: 0; }
    .station-stage-inner { grid-template-columns: minmax(0, 1fr); min-height: 0; }
    .station-stage-slot { display: none; }
    .station-stage .station-stage-canvas {
      position: relative;
      inset: auto;
      height: max(50vh, 340px);
      margin-top: 1.4rem;
      margin-inline: calc(-1 * max(var(--gutter), calc(50vw - var(--stage-col) / 2 + 2.5rem)));
    }
    .station-stage .station3d-fallback { width: auto; left: 0; }
  }
  .room-section-note { margin: -0.6rem 0 1rem; }

  /* Empty station: what it is for, and the next step. */
  .station-empty {
    display: grid;
    justify-items: start;
    gap: 0.7rem;
    max-width: 44rem;
    margin-top: 2rem;
    padding: 1.1rem 1.2rem 1.2rem;
    border: 3px solid var(--stamp);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    rotate: -0.5deg;
  }
  .station-empty p { margin: 0; }
  .station-empty-title {
    font: 400 clamp(1.6rem, 4vw, 2.3rem)/1 var(--font-display);
    text-transform: uppercase;
    color: var(--stamp);
  }
  .station-empty-cta { margin-top: 0.3rem !important; }

  @media (max-width: 860px) {
    .station-head { grid-template-columns: minmax(0, 1fr); }
    .station3d-fallback { padding: 0.9rem 0.6rem 1rem; }
  }
  @media (max-width: 480px) {
    .station-shelf > li { flex-basis: 5.4rem; margin-inline: -0.6rem; }
    .station-play { width: 100%; }
  }

  /* "Ta station": a stub torn off the collector card. */
  .station-card {
    display: grid;
    gap: 0.45rem;
    padding: 0.9rem 1.2rem 1.1rem;
    border-top: 3px dashed var(--ink);
    background: var(--ink);
    color: var(--paper);
  }
  .station-card p { margin: 0; max-width: none; }
  .station-card-title { font: 400 clamp(1.7rem, 5vw, 2.4rem)/1 var(--font-display); text-transform: uppercase; overflow-wrap: anywhere; }
  .station-card-title a { color: var(--paper); text-decoration-color: var(--stamp); }
  .station-card-title a:hover { background: var(--paper); color: var(--ink); }
  .station-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 0.9rem;
    font: 500 0.74rem/1.4 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
  .station-card-meta strong { color: var(--paper); font-weight: 700; }
  .station-card[data-on-air] .station-card-meta strong { color: var(--stamp); background: var(--paper); padding: 0 0.3em; }
  .station-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 0.9rem; margin-top: 0.3rem !important; }
  .station-card-actions .btn-ink { border-color: var(--paper); }
  .station-card-actions .btn-ink:hover { background: var(--ink); }
  .station-card-actions .btn-stamp { --btn-shadow: var(--paper); }
  .station-card-hint { flex-basis: 100%; font: 500 0.78rem/1.4 var(--font-mono); opacity: 0.85; }
  .station-card .radio-play-error { color: var(--paper); }
  @media (max-width: 560px) { .station-card { padding: 0.8rem 0.9rem 1rem; } }

  /* "Sur les ondes" (components/StationMarquee): an ink band like the sleeves one; the conveyor
   * follows its tilt while the paper station tickets and the heading stand upright. */
  .on-air-band { padding-block: clamp(2rem, 5vw, 3.2rem); }
  .on-air-empty {
    display: block;
    width: fit-content;
    max-width: calc(100% - 2 * var(--gutter));
    margin: 1rem auto 0;
    border-color: var(--paper);
    color: var(--paper);
    text-align: center;
    rotate: calc(var(--band-tilt) * -1);
  }

  .on-air-marquee { --on-air-ticket: clamp(13.5rem, 19vw, 15.5rem); --on-air-gap: clamp(1rem, 2.4vw, 1.8rem); }
  .on-air-viewport { overflow: hidden; padding: 1.4rem 0 1.6rem; }
  .on-air-track { display: flex; width: max-content; }
  .on-air-marquee[data-animated] .on-air-track {
    animation: packs-conveyor var(--on-air-duration) linear infinite;
    will-change: transform;
  }
  .on-air-marquee:not([data-animated]) .on-air-track { margin-inline: auto; }
  .on-air-marquee[data-paused="true"] .on-air-track,
  .on-air-viewport:hover .on-air-track,
  .on-air-viewport:focus-within .on-air-track { animation-play-state: paused; }
  .on-air-group {
    display: flex;
    flex: none;
    align-items: flex-start;
    gap: var(--on-air-gap);
    margin: 0;
    padding: 0 var(--on-air-gap) 0 0;
    list-style: none;
  }
  .on-air-marquee:not([data-animated]) .on-air-group { padding-left: var(--on-air-gap); }
  /* A paper ticket stuck on the band, upright, slightly askew. */
  .on-air-ticket {
    display: grid;
    gap: 0.5rem;
    flex: none;
    width: var(--on-air-ticket);
    padding: 0.7rem 0.75rem 0.75rem;
    border: var(--rule);
    background: var(--paper-lift);
    color: var(--ink);
    box-shadow: 4px 4px 0 var(--stamp);
    text-align: left;
    rotate: calc(var(--band-tilt) * -1 + var(--tilt, 0deg));
  }
  .on-air-ticket:nth-child(3n + 1) { --tilt: -1deg; }
  .on-air-ticket:nth-child(3n + 2) { --tilt: 0.8deg; }
  .on-air-ticket:nth-child(3n) { --tilt: -0.3deg; }
  .on-air-ticket p, .radio-card p { margin: 0; max-width: none; }
  .on-air-ticket .on-air-name a { font-size: 1.25rem; }
  .on-air-ticket .genre-stamps { min-height: 1.5rem; }
  @media (prefers-reduced-motion: reduce) {
    .on-air-marquee[data-animated] .on-air-track { animation: none; will-change: auto; }
    .on-air-group[data-duplicate="true"] { display: none; }
    .on-air-viewport { overflow-x: auto; }
  }

  /* Genre profile of a station: small ink tags, the share in red; the selected genre in red. */
  .genre-stamps { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0; padding: 0; list-style: none; }
  .genre-stamps > li {
    padding: 0.22em 0.5em 0.12em;
    background: var(--ink);
    color: var(--paper);
    font: 400 0.82rem/1 var(--font-display);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
    rotate: -1.5deg;
    filter: url(#ink-bleed);
  }
  .genre-stamps > li:nth-child(2n) { rotate: 1.2deg; }
  .genre-stamps b { color: var(--stamp); font-weight: 400; }
  .genre-stamps > li[data-selected] { background: var(--stamp); }
  .genre-stamps > li[data-selected] b { color: var(--paper); }

  /* /radios (components/StationBrowser): toolbar, genre tabs, a grid of tilted station cards. */
  .radios-head .lede { margin: 0; }
  .radios-toolbar { row-gap: 0.5rem; }
  .radios-toolbar select { max-width: 100%; }
  .radios-genres { flex-basis: 100%; }
  .radios-genres small { margin-left: 0.25em; font: 600 0.68rem/1 var(--font-mono); opacity: 0.75; }
  .radios-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
    gap: 1.6rem 1.3rem;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .radio-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    min-width: 0;
    padding: 0.85rem 0.9rem 0.9rem;
    border: var(--rule);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    rotate: var(--tilt, 0deg);
    transition: rotate 160ms var(--ease-snap), translate 160ms var(--ease-snap), box-shadow 160ms var(--ease-snap);
  }
  .radio-card:nth-child(4n + 1) { --tilt: -0.8deg; }
  .radio-card:nth-child(4n + 2) { --tilt: 0.6deg; }
  .radio-card:nth-child(4n + 3) { --tilt: -0.3deg; }
  .radio-card:nth-child(4n) { --tilt: 0.9deg; }
  .radio-card:hover { rotate: 0deg; translate: -3px -3px; box-shadow: var(--drop-lg); z-index: 1; }
  .radio-card[data-me] { border-width: 3px; box-shadow: 4px 4px 0 var(--stamp); }
  .radio-card-me { position: absolute; top: -0.9rem; right: 0.6rem; z-index: 1; font-size: 1.05rem; background: var(--paper-lift); }
  .radio-card-styles { font: 500 0.7rem/1.4 var(--font-mono); letter-spacing: 0.04em; opacity: 0.8; overflow-wrap: anywhere; }
  .radio-card-date { flex-basis: 100%; font: 500 0.68rem/1.3 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.75; }
  .radio-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: auto !important; }
  @media (max-width: 560px) {
    .radios-toolbar > label { flex: 1 1 100%; }
    .radios-toolbar input[type="search"], .radios-toolbar select { width: 100%; }
    .radio-card { rotate: 0deg; }
  }
  @media (prefers-reduced-motion: reduce) {
    .radio-card { transition: none; }
  }

  .on-air-name { display: grid; gap: 0.15rem; }
  .on-air-name a {
    font: 400 1.45rem/1 var(--font-display);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-decoration: none;
    overflow-wrap: anywhere;
  }
  .on-air-user { font: 600 0.72rem/1.2 var(--font-mono); letter-spacing: 0.08em; opacity: 0.75; }
  .on-air-covers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.45rem; }
  .on-air-covers > li { position: relative; aspect-ratio: 1; }
  .on-air-covers img, .on-air-blank {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border: 1.5px solid var(--ink);
    image-rendering: pixelated;
  }
  .on-air-blank { background: var(--ink); }
  .on-air-covers > li:first-child img { box-shadow: 3px 3px 0 var(--stamp); }
  .on-air-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
  .on-air-count {
    padding: 0.2em 0.5em 0.12em;
    border: 1.5px solid var(--ink);
    font: 600 0.72rem/1.2 var(--font-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    rotate: -2deg;
  }
  .on-air-play { min-height: 2.2rem; padding: 0.45rem 0.9rem 0.35rem; }
  .on-air-ticket .radio-play-error, .radio-card .radio-play-error { flex-basis: 100%; margin: 0; }

  /* Item page: keep sealed, or put on air — two columns side by side. */
  .choice {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.2rem 1.4rem;
    max-width: 62rem;
  }
  .choice-col {
    display: grid;
    align-content: start;
    gap: 0.7rem;
    min-width: 0;
    padding: 1rem 1.1rem 1.1rem;
    border: var(--rule-thick);
    background: var(--paper-lift);
    box-shadow: var(--drop);
  }
  .choice-col[data-side="sealed"] { rotate: -0.5deg; }
  .choice-col[data-side="onair"] { rotate: 0.4deg; border-color: var(--stamp); box-shadow: 5px 5px 0 var(--stamp); }
  .choice-col p { margin: 0; }
  .choice-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.4rem 0.8rem; }
  .choice-name { font: 400 clamp(1.6rem, 3.4vw, 2.2rem)/1 var(--font-display); text-transform: uppercase; }
  .choice-col[data-side="onair"] .choice-name { color: var(--stamp); }
  .choice-facts { grid-template-columns: 5.6rem 1fr; }
  .choice-facts dd { font-size: 0.95rem; }
  .choice-facts dd:first-of-type { font: 400 1.6rem/1 var(--font-display); }
  .choice-facts i { font-style: normal; font-weight: 700; }
  .choice-steps { white-space: nowrap; font-family: var(--font-mono); }
  .choice-steps b { color: var(--stamp); }
  .choice-note { font: 500 0.78rem/1.45 var(--font-mono); opacity: 0.8; }
  .choice-cta { margin-top: 0.2rem !important; }
  .choice .open-warning { margin: 0; rotate: none; box-shadow: 3px 3px 0 var(--ink); }
  .choice .tear-hint { margin-top: -0.3rem; }
  @media (max-width: 480px) { .choice-facts { grid-template-columns: 1fr; } }
  @media (max-width: 720px) {
    .choice { grid-template-columns: minmax(0, 1fr); }
    .choice-col[data-side="sealed"], .choice-col[data-side="onair"] { rotate: none; }
    .choice-cta .btn-big { width: 100%; }
  }
}

@layer pages {
  /* Station wave 3 (docs/PIVOT.md « Vague 3 »): listeners, "Découvert par", complete albums. */

  /* Listeners this week: a red counter next to the "on air" one, tilted the other way. */
  .station-meta .station-listeners {
    display: inline-block;
    padding: 0.2em 0.5em 0.12em;
    background: var(--stamp);
    color: var(--paper);
    font: 400 clamp(1.05rem, 2.4vw, 1.4rem)/1 var(--font-display);
    letter-spacing: 0.04em;
    rotate: 1.5deg;
    box-shadow: 3px 3px 0 var(--paper);
    filter: url(#ink-bleed);
  }
  .station-meta .station-listeners[data-n="0"] { background: transparent; border: 2px solid var(--paper); box-shadow: none; }
  .station-nudge {
    display: inline-block;
    margin: 0.8rem 0 0;
    padding: 0.35rem 0.6rem 0.3rem;
    border: 2px dashed var(--stamp);
    background: color-mix(in srgb, var(--ink) 80%, transparent);
    color: var(--paper);
    font: 600 0.78rem/1.35 var(--font-mono);
    letter-spacing: 0.04em;
    rotate: -1deg;
  }
  .copy-link { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; max-width: 100%; }
  .copy-link[data-state="copied"] button { --btn-bg: var(--stamp); --btn-fg: var(--paper); }
  .copy-link-field {
    min-width: 0;
    width: min(22rem, 100%);
    padding: 0.35rem 0.5rem;
    border: 2px solid var(--paper);
    background: var(--paper);
    color: var(--ink);
    font: 500 0.78rem/1.2 var(--font-mono);
  }

  /* Station shelf (StationShelf): the albums on air on a wooden shelf set into the page, Cover Flow
   * style (PSX scene). A native horizontal scroller lies over the scene, one snap point per album:
   * trackpads, fingers and wheels keep their own momentum. Without the scene: the same scroller
   * shows the covers. The album in the middle is described below on a cartel. */
  /* The shelf runs from edge to edge of the screen: the albums beyond it are off screen. */
  .shelf { position: relative; margin: 0 calc(50% - 50vw) 1rem; }
  .room-shelf { margin-top: 3.4rem; }
  .shelf-stage {
    position: relative;
    height: clamp(15rem, 30vw, 27rem);
    background: #1a0e06;
    /* Set into the page: ink edges top and bottom, a paper highlight under it. */
    border-block: 3px solid var(--ink);
    box-shadow: 0 4px 0 var(--paper-lift);
    image-rendering: pixelated;
  }
  /* "À l'antenne", astride the top of the shelf. */
  .shelf-tag {
    position: absolute;
    top: 0;
    left: max(var(--gutter), calc(50vw - var(--page) / 2 + var(--gutter)));
    z-index: 2;
    margin: 0;
    padding: 0.35rem 0.7rem 0.25rem;
    translate: 0 -55%;
    rotate: -2deg;
    background: var(--ink);
    color: var(--paper);
    box-shadow: 3px 3px 0 var(--stamp);
    font: 400 clamp(1.1rem, 2.2vw, 1.5rem)/1 var(--font-display);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    pointer-events: none;
  }
  .shelf-tag small { margin-left: 0.4rem; font: 600 0.64rem/1 var(--font-mono); letter-spacing: 0.1em; opacity: 0.8; }
  .shelf-scroller {
    position: absolute;
    inset: 0;
    z-index: 1;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    cursor: grab;
    -webkit-tap-highlight-color: transparent;
    container: shelf / size;
  }
  .shelf-scroller::-webkit-scrollbar { display: none; }
  .shelf-scroller[data-dragging] { scroll-snap-type: none; cursor: grabbing; user-select: none; }
  .shelf-scroller:focus-visible { outline: 3px solid var(--stamp); outline-offset: 3px; }
  .shelf-albums {
    --shelf-step: clamp(4.5rem, 13cqw, 8.5rem);
    display: flex;
    align-items: center;
    width: max-content;
    height: 100%;
    margin: 0;
    list-style: none;
  }
  /* Spacers before the first album and after the last: both can reach the middle. */
  .shelf-albums::before, .shelf-albums::after { content: ""; flex: 0 0 calc(50cqw - var(--shelf-step) / 2); }
  .shelf-albums > li { flex: 0 0 var(--shelf-step); width: var(--shelf-step); scroll-snap-align: center; }
  .shelf-cover { display: block; aspect-ratio: 1; margin: 0 6%; border: 1.5px solid var(--ink); background: var(--ink); transition: scale 0.2s var(--ease-snap); }
  .shelf-cover img { display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
  .shelf-cover > span { display: grid; place-items: end start; height: 100%; padding: 0.3rem; color: var(--paper); font: 600 0.55rem/1.2 var(--font-mono); text-transform: uppercase; }
  .shelf-albums > li:not([data-current]) .shelf-cover { scale: 0.78; opacity: 0.7; }
  /* The scene draws the albums: the scroller only keeps the gestures. */
  .shelf[data-ready] .shelf-cover { visibility: hidden; }

  /* The cartel: what is on air from the album in the middle. */
  .shelf-card {
    position: relative;
    max-width: 38rem;
    margin: 1.6rem auto 0;
    padding: 0.9rem 1rem 1rem;
    border: var(--rule);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    container: shelf-card / inline-size;
  }
  .shelf-card p { max-width: none; }
  .shelf-card-head { display: grid; gap: 0.25rem; margin: 0 0 0.7rem; text-align: center; }
  .shelf-card-head > p { margin: 0; }
  .shelf-card-head h3 { margin: 0; font: 400 clamp(1.35rem, 3vw, 1.9rem)/1 var(--font-display); text-transform: uppercase; overflow-wrap: anywhere; }
  .shelf-card-head h3 a { text-decoration: none; }
  .shelf-card-count { font: 500 0.66rem/1 var(--font-mono); letter-spacing: 0.12em; opacity: 0.7; }
  .shelf-card-meta {
    display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0.3rem 0.6rem;
    font: 500 0.74rem/1.2 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase;
  }
  .shelf-card-complete { --tilt: -6deg; font-size: 1rem; mix-blend-mode: normal; }
  .shelf-card-play { margin-top: 0.4rem !important; }
  .shelf-card-play .btn-stamp { min-height: 2.3rem; padding: 0.45rem 0.9rem 0.35rem; }
  .shelf-card .tracklist-check { display: none; }
  .shelf-card .tracklist > li[data-opened="true"] { background: none; box-shadow: none; }
  .shelf-card .tracklist > li[data-opened="true"] .tracklist-title { font-weight: 500; }
  /* The cartel: position | title | length, the tags under the title. */
  @container shelf-card (min-width: 0) {
    .shelf-card .tracklist > li { grid-template-columns: 2.2rem minmax(0, 1fr) auto; }
    .shelf-card .tracklist-pos { grid-area: 1 / 1; }
    .shelf-card .tracklist-title { grid-area: 1 / 2; }
    .shelf-card .tracklist-len { grid-area: 1 / 3; min-width: 0; }
    .shelf-card .tracklist-tags { grid-area: 2 / 2 / 3 / 4; justify-content: flex-start; }
    .shelf-card .tracklist-tags:empty { display: none; }
  }
  @media (max-width: 640px) {
    .shelf-albums { --shelf-step: 22cqw; }
    .shelf-stage { height: 16rem; }
  }
  @media (prefers-reduced-motion: reduce) {
    .shelf-cover { transition: none; }
  }

  /* Tracklist: the "1er" stamp of a discovery. */
  .tracklist-first {
    display: inline-block;
    padding: 0.1em 0.35em 0.04em;
    border: 1.5px solid var(--stamp);
    color: var(--stamp);
    font: 400 0.72rem/1.1 var(--font-display);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    rotate: -6deg;
    filter: url(#ink-bleed);
  }

  /* Static wall of the station (no WebGL): a small "Complet" on the complete sleeves. */
  .station-shelf > li { position: relative; }
  .station-shelf-complete {
    --tilt: -12deg;
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 3;
    translate: -50% -50%;
    font-size: 0.95rem;
    color: var(--stamp);
    background: color-mix(in srgb, var(--paper) 70%, transparent);
    mix-blend-mode: normal;
    pointer-events: none;
  }

  /* Home: listeners on the station stub and on the "Sur les ondes" tickets (and /radios cards). */
  .station-card-meta .station-card-listeners { color: var(--paper); font-weight: 700; }
  .station-card-meta .station-card-listeners:not([data-n="0"]) { background: var(--stamp); padding: 0 0.3em; }
  .on-air-counts { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; }
  .on-air-listeners {
    padding: 0.2em 0.5em 0.12em;
    background: var(--ink);
    color: var(--paper);
    font: 600 0.68rem/1.2 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    rotate: 1.5deg;
  }
  .on-air-listeners:not([data-n="0"]) { background: var(--stamp); }

  /* Track page: "Découvert par", a rubber stamp at the head of the facts. */
  .discovered-by {
    --tilt: -4deg;
    display: inline-grid;
    justify-items: start;
    gap: 0.15rem;
    max-width: 100%;
    margin: 0.2rem 0 1rem;
    padding: 0.45rem 0.7rem 0.4rem;
    border: 3px double var(--stamp);
    outline: 1.5px solid var(--stamp);
    outline-offset: 2px;
    color: var(--stamp);
    rotate: var(--tilt);
    filter: url(#ink-bleed);
  }
  .discovered-by-kicker { font: 600 0.66rem/1.2 var(--font-mono); letter-spacing: 0.14em; text-transform: uppercase; }
  .discovered-by-who {
    font: 400 clamp(1.4rem, 3vw, 2rem)/1 var(--font-display);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    overflow-wrap: anywhere;
  }
  .discovered-by-who a { color: inherit; text-decoration-thickness: 2px; }
  .discovered-by-at { font: 600 0.72rem/1.2 var(--font-mono); letter-spacing: 0.08em; }
  .discovered-by[data-me] { background: var(--stamp); color: var(--paper); outline-color: var(--stamp); border-color: var(--paper); }
  .discovered-by[data-none] { --tilt: 2deg; border: 2px dashed var(--ink); outline: 0; color: var(--ink); opacity: 0.8; filter: none; }

  /* Item page: "Tu l'as découvert". */
  .discovered-tag {
    display: inline-block;
    padding: 0.18em 0.5em 0.12em;
    border: 2px solid var(--stamp);
    color: var(--stamp);
    font: 400 1.05rem/1 var(--font-display);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    rotate: -2deg;
  }

  /* Item page, right after "Mettre à l'antenne": one tilted paper label (title, station, album
   * progress, links); red rubber stamps inked over its corners when a track was discovered or the
   * album completed. */
  .onair-result {
    position: relative;
    display: grid;
    justify-items: start;
    gap: 0.35rem;
    width: fit-content;
    max-width: min(40rem, 100%);
    margin: 1.6rem 0 0.4rem;
    padding: 0.9rem 1.3rem 1rem 1.1rem;
    border: var(--rule-thick);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    rotate: -1.2deg;
    animation: pop-in 380ms var(--ease-pop) backwards;
  }
  .onair-result[data-discovered] { padding-right: clamp(7rem, 22vw, 11rem); }
  .onair-result[data-complete] { padding-bottom: 2.6rem; }
  .onair-result p { margin: 0; max-width: none; }
  .onair-result-title {
    font: 400 clamp(1.9rem, 4.6vw, 2.7rem)/0.95 var(--font-display);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-shadow: 0.04em 0.035em 0 var(--stamp);
  }
  .onair-result-sub { font: 500 0.98rem/1.35 var(--font-body); }
  .onair-result-sub b { color: var(--stamp); font-variant-numeric: tabular-nums; }
  .onair-result i { font-style: normal; font-weight: 700; }
  .onair-result-note { max-width: 36ch !important; font: 500 0.92rem/1.4 var(--font-body); }
  .onair-result-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin-top: 0.4rem !important; }
  .onair-result-actions .btn-stamp { min-height: 2.3rem; padding: 0.45rem 0.9rem 0.35rem; }
  .onair-result-link {
    font: 600 0.74rem/1.2 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration-color: var(--stamp);
    text-decoration-thickness: 2px;
  }
  /* The rubber stamp: worn red ink (the .stamp texture), double border, no fill, astride a corner. */
  .onair-stamp {
    --tilt: -14deg;
    position: absolute;
    z-index: 2;
    padding: 0.18em 0.4em 0.08em;
    border: 0.1em double var(--stamp);
    outline: 0.04em solid var(--stamp);
    outline-offset: 0.1em;
    color: var(--stamp);
    font: 400 clamp(1.7rem, 4.4vw, 2.6rem)/1 var(--font-display);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    opacity: 0.92;
    rotate: var(--tilt);
    mix-blend-mode: multiply;
    -webkit-mask-image: var(--wear);
    mask-image: var(--wear);
    -webkit-mask-size: 240px;
    mask-size: 240px;
    filter: url(#ink-bleed);
    pointer-events: none;
    animation: onair-stamp 520ms var(--ease-snap) backwards;
    animation-delay: 350ms;
  }
  .onair-stamp[data-kind="discovered"] { top: -0.55em; right: -0.7em; }
  .onair-stamp[data-kind="complete"] {
    --tilt: 7deg;
    bottom: -0.6em;
    right: 0.6em;
    font-size: clamp(1.3rem, 3.4vw, 1.9rem);
    animation-delay: 900ms;
  }
  @keyframes onair-stamp {
    0% { opacity: 0; scale: 1.4; rotate: calc(var(--tilt) - 10deg); }
    55% { opacity: 0.9; scale: 0.94; rotate: var(--tilt); }
    75% { scale: 1.03; }
    100% { opacity: 0.92; scale: 1; rotate: var(--tilt); }
  }
  @media (prefers-reduced-motion: reduce) {
    .onair-result, .onair-stamp { animation: none; }
  }
  @media (max-width: 480px) {
    .onair-result { width: auto; rotate: -0.6deg; }
    .onair-result[data-discovered] { padding-top: 2.4rem; padding-right: 1.1rem; }
    .onair-stamp[data-kind="discovered"] { top: -0.45em; right: 0.3em; }
    .onair-result[data-complete] { padding-bottom: 3.4rem; }
    .onair-stamp[data-kind="complete"] { bottom: -0.3em; }
  }
  @media (max-width: 480px) {
    .station-meta .station-listeners { font-size: 1rem; }
    .copy-link, .copy-link button { width: 100%; }
  }
}

@layer fx {
  /* Longer slammed words ("Album complet !") fit a phone screen. */
  .fx-stamp[data-long] { font-size: clamp(2.4rem, 9vw, 6rem); }
}

/* ------------------------------------------------------ collection list (pages) */
/* "Ma collection" (/collection) and the station crate (/u/[username]): components/AlbumCopyList.
 * One ruled paper slip per album (flat cover, title, rarity, progress), the obtained tracks below it
 * as ruled lines, each copy with its compact controls, then the folded missing tracks. */
@layer pages {
  .acl-page-head { display: grid; gap: 0.9rem; margin-bottom: 1.8rem; }
  .acl-page-head h1 { margin: 0; }
  .acl-totals {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    border: var(--rule-thick);
    background: var(--paper-lift);
    box-shadow: var(--drop);
    width: fit-content;
    max-width: 100%;
  }
  .acl-totals > div { display: grid; gap: 0.2rem; padding: 0.55rem 1rem 0.6rem; border-right: 1px dashed var(--ink-soft); }
  .acl-totals > div:last-child { border-right: 0; }
  .acl-totals dt, .acl-totals dd { padding: 0; border: 0; }
  .acl-totals dd { font: 400 1.6rem/1 var(--font-display); letter-spacing: 0.02em; }
  .acl-totals > div:nth-child(2) dd { color: var(--stamp); }
  .acl-page-links { font: 600 0.78rem/1.4 var(--font-mono); letter-spacing: 0.1em; text-transform: uppercase; }

  /* Toolbar: search, the four filters as tilted tabs, sort. */
  .acl-toolbar { align-items: flex-end; gap: 0.2rem 1rem; }
  .acl-toolbar input[type="search"] { width: min(18rem, 100%); }
  .acl-filter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.3rem 0 0.6rem;
    padding: 0;
    border: 0;
  }
  .acl-filter label {
    position: relative;
    margin: 0;
    padding: 0.5rem 0.75rem 0.4rem;
    border: var(--rule);
    background: var(--paper);
    font: 400 0.95rem/1 var(--font-display);
    letter-spacing: 0.06em;
    cursor: pointer;
  }
  .acl-filter input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
  .acl-filter label[data-active] { background: var(--ink); color: var(--paper); rotate: -1.5deg; box-shadow: 3px 3px 0 var(--stamp); }
  .acl-filter label:has(input:focus-visible) { outline: 3px solid var(--stamp); outline-offset: 2px; }

  /* The list. */
  .acl { display: grid; gap: 1.6rem; }
  .acl-album {
    border: var(--rule-thick);
    background: var(--paper-lift);
    box-shadow: var(--drop);
  }
  .acl-head {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.4rem 1rem;
    padding: 0.7rem 0.9rem;
    border-bottom: var(--rule);
  }
  .acl-cover {
    display: block;
    width: clamp(64px, 12vw, 88px);
    aspect-ratio: 1;
    border: 2px solid var(--ink);
    background: var(--ink);
    box-shadow: 3px 3px 0 var(--ink-faint);
    rotate: -1.5deg;
  }
  .acl-cover:hover { background: var(--ink); }
  .acl-cover img { width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; filter: saturate(0.92) contrast(1.05); }
  .acl-cover-blank {
    display: grid;
    place-items: end start;
    height: 100%;
    padding: 0.3rem;
    color: var(--paper);
    font: 600 0.55rem/1.2 var(--font-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  .acl-head-text { display: grid; gap: 0.25rem; min-width: 0; }
  .acl-head-text p { margin: 0; max-width: none; }
  .acl-title { margin: 0; font-size: clamp(1.25rem, 2.6vw, 1.7rem); filter: none; overflow-wrap: anywhere; }
  .acl-title a { text-decoration: none; }
  .acl-sub { font: 500 0.88rem/1.3 var(--font-body); opacity: 0.85; }
  .acl-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.7rem; }
  .acl-meta .tier { font-size: 0.8rem; }
  .acl-progress { font: 600 0.72rem/1.2 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; }
  .acl-progress b { color: var(--stamp); font-size: 0.9rem; }
  .acl-complete { --tilt: -6deg; font-size: 0.95rem; mix-blend-mode: normal; }
  .acl-head-play { margin: 0; }

  /* Obtained lines. */
  .acl-rows { display: grid; }
  .acl-row { padding: 0.45rem 0.9rem 0.5rem; border-bottom: 1px dashed var(--ink-soft); }
  .acl-row:last-child { border-bottom: 0; }
  .acl-row[data-on-air] { box-shadow: inset 4px 0 0 var(--ok); background: color-mix(in srgb, var(--ok) 10%, transparent); }
  .acl-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.7rem; min-height: 2.1rem; }
  .acl-pos { flex: 0 0 2.2rem; font: 600 0.72rem/1.4 var(--font-mono); letter-spacing: 0.08em; }
  .acl-row-title { flex: 1 1 12rem; min-width: 0; overflow-wrap: anywhere; font: 600 0.98rem/1.3 var(--font-body); }
  .acl-row-title a { text-decoration-thickness: 1px; }
  .acl-onair {
    color: var(--ok);
    font: 600 0.68rem/1.2 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
  }

  /* Copies of a line: facts on the left, controls on the right. */
  .acl-copies { display: grid; gap: 0.35rem; margin: 0.35rem 0 0 2.9rem; }
  .acl-copy {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.35rem 1rem;
    padding: 0.35rem 0 0.2rem;
    border-top: 1px dotted var(--ink-faint);
  }
  .acl-copy:first-child { border-top: 0; }
  .acl-copy-facts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.6rem;
    margin: 0;
    padding-top: 0.35rem;
    max-width: none;
    font: 500 0.75rem/1.3 var(--font-mono);
    letter-spacing: 0.05em;
    text-transform: uppercase;
  }
  .acl-copy-facts .label { font-size: 0.6rem; }
  .acl-serial { font-weight: 600; text-decoration-thickness: 1px; }
  .acl-value { opacity: 0.85; }

  .acl-controls { display: grid; justify-items: end; gap: 0.35rem; min-width: 0; max-width: 100%; }
  .acl-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.4rem; }
  /* Compact buttons: same print, smaller block. */
  :where(button, .btn).acl-btn {
    min-height: 2.1rem;
    padding: 0.4rem 0.7rem 0.3rem;
    font-size: 0.88rem;
    box-shadow: 2px 2px 0 var(--btn-shadow);
  }
  :where(button, .btn).acl-btn:hover { box-shadow: 3px 3px 0 var(--btn-shadow); }
  .acl-btn-link:hover { background: var(--btn-bg); color: var(--btn-fg); }
  .acl-note { margin: 0; font: 500 0.72rem/1.35 var(--font-mono); letter-spacing: 0.04em; opacity: 0.8; text-align: right; }
  .acl .radio-play-error { flex-basis: 100%; text-align: right; }

  /* Inline confirm / price panel, pinned under the controls like a slip. */
  .acl-panel {
    display: grid;
    gap: 0.45rem;
    width: min(26rem, 100%);
    margin: 0.1rem 0 0.2rem;
    padding: 0.7rem 0.8rem 0.6rem;
    border: 2px dashed var(--ink);
    background: var(--paper);
    rotate: -0.4deg;
    animation: pop-in 220ms var(--ease-pop) backwards;
  }
  .acl-panel p { margin: 0; max-width: none; font: 500 0.88rem/1.4 var(--font-body); }
  .acl-panel label { margin: 0; }
  .acl-panel input[type="number"] { width: 8rem; }
  .acl-panel-hint { font: 500 0.7rem/1.35 var(--font-mono) !important; letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.8; }
  .acl-panel-warn { padding: 0.4rem 0.55rem; border: 2px solid var(--stamp); }
  .acl-panel-warn strong { color: var(--stamp); }
  .acl-panel-buttons { display: flex; flex-wrap: wrap; gap: 0.4rem; }

  /* Missing tracks, folded: a dashed tab, then the tracklist. */
  .acl-missing { border-top: var(--rule); }
  .acl-missing > summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.9rem;
    font: 600 0.72rem/1.2 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    cursor: pointer;
    list-style: none;
  }
  .acl-missing > summary::-webkit-details-marker { display: none; }
  .acl-missing > summary::before { content: "+"; display: inline-grid; place-items: center; width: 1.2rem; height: 1.2rem; border: 1.5px solid var(--ink); font: 400 1rem/1 var(--font-display); }
  .acl-missing[open] > summary::before { content: "−"; background: var(--ink); color: var(--paper); }
  .acl-missing > summary:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
  .acl-missing .tracklist { margin: 0 0.9rem 0.7rem; }
  /* Keep the check column (the tracklist grid counts it): missing tracks have no check anyway. */
  .acl-missing .tracklist-check { visibility: hidden; }

  /* Station: the crate list sits in its section; the "Gérer ma collection" link under it. */
  .room-manage { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; margin-top: 1.6rem; max-width: none; }

  @media (max-width: 640px) {
    .acl-head { grid-template-columns: auto minmax(0, 1fr); padding: 0.6rem 0.7rem; }
    .acl-head-play { grid-column: 1 / -1; }
    .acl-row { padding-inline: 0.7rem; }
    .acl-copies { margin-left: 0; }
    .acl-copy { flex-direction: column; align-items: stretch; }
    .acl-controls { justify-items: start; }
    .acl-actions { justify-content: flex-start; }
    .acl-note { text-align: left; }
    .acl-totals > div { padding: 0.45rem 0.7rem 0.5rem; }
    .acl-totals dd { font-size: 1.3rem; }
  }
  @media (max-width: 400px) {
    .acl-actions > * { flex: 1 1 calc(50% - 0.4rem); }
    .acl-actions .radio-play-error { flex-basis: 100%; }
    .acl-filter label { padding: 0.45rem 0.55rem 0.35rem; font-size: 0.85rem; }
  }
  @media (prefers-reduced-motion: reduce) {
    .acl-panel { animation: none; }
  }
}

/* ------------------------------------------------- station deals (pages) */
/* A visitor on another player's station (/u/[username], "Ses disques"): components/CopyDealActions
 * on each copy (buy a listing, offer ₲, "Ajouter à l'échange") and components/StationDeals, the trade
 * cart: an ink slip stuck to the bottom of the screen while the list is in view (above the radio
 * dock), folded to one line; unfolded, "Je demande" / "Je donne" side by side, then send. */
@layer pages {
  .deal-login { margin-top: -0.4rem; }

  /* "Ajouter à l'échange": a checkbox dressed as a compact button; checked, it turns ink. */
  .deal-add {
    --btn-bg: var(--paper);
    --btn-fg: var(--ink);
    --btn-shadow: var(--ink);
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    margin: 0;
    min-height: 2.1rem;
    padding: 0.4rem 0.7rem 0.3rem;
    border: 2px solid var(--ink);
    background: var(--btn-bg);
    color: var(--btn-fg);
    box-shadow: 2px 2px 0 var(--btn-shadow);
    font: 400 0.88rem/1 var(--font-display);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    user-select: none;
  }
  .deal-add input { width: 1rem; height: 1rem; margin: 0; accent-color: var(--stamp); }
  .deal-add[data-checked] { --btn-bg: var(--ink); --btn-fg: var(--paper); --btn-shadow: var(--stamp); rotate: -1deg; }
  .deal-add:has(input:focus-visible) { outline: 3px solid var(--stamp); outline-offset: 2px; }
  .deal-add[data-disabled] { cursor: not-allowed; opacity: 0.45; box-shadow: none; }

  /* The cart. */
  .deal-cart {
    position: sticky;
    /* --radio-clear / --radio-inset: dodge the radio dock (RadioDock.tsx). */
    bottom: calc(var(--radio-clear, 0px) + 0.5rem);
    z-index: 70; /* over the list, under the radio dock (80) and the FX layer (90) */
    margin-top: 1.4rem;
    margin-right: var(--radio-inset, 0px);
    border: var(--rule-thick);
    background: var(--ink);
    color: var(--paper);
    box-shadow: 5px 5px 0 var(--stamp);
  }
  .deal-cart-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 1rem;
    padding: 0.5rem 0.8rem;
  }
  .deal-cart-title { margin: 0; font-size: 1.15rem; color: var(--paper); filter: none; outline: none; }
  .deal-cart-count {
    margin: 0;
    flex: 1 1 auto;
    font: 600 0.72rem/1.3 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }
  .deal-cart-bar p { max-width: none; }
  .deal-cart-toggle { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 0 auto; }
  .deal-cart .btn-ink { border-color: var(--paper); }
  .deal-cart-sent {
    margin: 0;
    padding: 0.45rem 0.8rem 0.55rem;
    border-top: 1px dashed var(--paper);
    font: 600 0.8rem/1.4 var(--font-mono);
    max-width: none;
  }
  .deal-cart a { text-decoration-color: var(--stamp); }

  .deal-cart-body {
    display: grid;
    border-top: 2px solid var(--paper);
    background: var(--paper);
    color: var(--ink);
  }
  /* The two sides scroll; the send row stays in view under them. */
  .deal-cart-sides {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.8rem;
    max-height: min(52vh, 30rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0.7rem 0.8rem 0.8rem;
  }
  .deal-side {
    display: grid;
    align-content: start;
    gap: 0.5rem;
    min-width: 0;
    margin: 0;
    padding: 0.7rem 0.7rem 0.7rem;
    border: 2px dashed var(--ink);
  }
  .deal-side legend {
    padding: 0.15rem 0.5rem 0.05rem;
    background: var(--stamp);
    color: var(--paper);
    font: 400 1rem/1 var(--font-display);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    rotate: -1.5deg;
  }
  .deal-empty { margin: 0; font: 500 0.8rem/1.4 var(--font-mono); opacity: 0.8; }
  .deal-items { display: grid; gap: 0.2rem; }
  .deal-items > li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.2rem 0;
    border-bottom: 1px dotted var(--ink-faint);
    font: 500 0.82rem/1.35 var(--font-body);
    overflow-wrap: anywhere;
  }
  .deal-items label { display: flex; align-items: baseline; gap: 0.4rem; margin: 0; font: inherit; cursor: pointer; }
  .deal-items input { flex: none; accent-color: var(--stamp); }
  .deal-value { font: 500 0.72rem/1 var(--font-mono); opacity: 0.8; white-space: nowrap; }
  :where(button).deal-remove {
    flex: none;
    min-height: 1.8rem;
    min-width: 1.8rem;
    padding: 0;
    font-size: 1.1rem;
    box-shadow: 2px 2px 0 var(--ink);
  }
  .deal-mine { display: grid; gap: 0.55rem; }
  .deal-mine-head { margin: 0; font: 600 0.78rem/1.3 var(--font-mono); letter-spacing: 0.04em; text-transform: uppercase; }
  .deal-mine-head span { opacity: 0.75; font-weight: 500; }
  .deal-coins { display: grid; gap: 0.2rem; margin: 0.2rem 0 0; }
  .deal-coins input { width: 9rem; }
  .deal-cart-foot { display: grid; gap: 0.45rem; padding: 0.55rem 0.8rem 0.65rem; border-top: var(--rule); }
  .deal-cart-foot .acl-note, .deal-cart-foot .error { text-align: left; }
  .deal-cart-link { align-self: center; font: 600 0.78rem/1.4 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; }

  @media (max-width: 640px) {
    .deal-cart { bottom: var(--radio-clear, 0px); margin-inline: calc(-1 * var(--gutter) + 0.25rem); box-shadow: 0 -4px 0 var(--stamp); }
    .deal-cart-sides { grid-template-columns: 1fr; max-height: 48vh; }
  }
  @media (max-width: 400px) {
    .deal-cart-bar { padding: 0.45rem 0.6rem; }
    .deal-cart-title { font-size: 1rem; flex-basis: 100%; }
    .deal-cart-sides, .deal-cart-foot { padding-inline: 0.55rem; }
    .deal-coins input { width: 100%; }
  }
}

/* ------------------------------------------------------------- flash (Rails) */
/* A page shows its flash next to its form or action, like ActionForm; otherwise it heads the page. */
@layer pages {
  .site-main > :is(.error, .success):first-child { margin: 0 0 1.2rem; }
  .hero > :is(.error, .success) { display: table; margin: 1.6rem auto 0; }
}
