/* Discover — editorial front page (本周精选 / 创作比赛 / 最新上架).
 *
 * Every v3 token is referenced bare, with NO fallback literal. The pre-2026-08-16 sheet carried
 * fallbacks from a different palette (#1c2530 ink, #1c8a4e green) which silently rendered off-brand
 * wherever a token failed to resolve — a fallback that lies is worse than none.
 *
 * DELIBERATE DEPARTURE FROM "ONE ACCENT": each product line owns a hue, per the reference. It is
 * scoped hard — a chip border, a button outline and a card wash at ~6% alpha. No filled buttons, no
 * coloured type outside the chip, and emerald stays the page's only primary action colour (the
 * contest CTA). The four hues live in one block below so a fifth line cannot be invented ad hoc. */

/* NO width of its own. The shell already supplies the column (.rk-content 1360 centred inside
   .rk-main's padding), and imposing a second, narrower one put a 81px inset on this page only —
   so the header's account cluster sat on one right edge at 1534 while the search field, every card
   row and the contest banner sat on another at 1453. Two right edges on one page is what read as
   clutter; sharing the shell's edge lines all of them up at once. */
.disc-page {
  --disc-kind: var(--rk-emerald);
  --disc-wash: color-mix(in srgb, var(--disc-kind) 5%, var(--rk-surface));
  padding-block: 4px 80px;
}

.is-picture-book { --disc-kind: #2f8f6b; }
.is-animation { --disc-kind: #3f74a8; }
.is-comic { --disc-kind: #c1663a; }
.is-image { --disc-kind: #7a6bb0; }

/* ── page title (lives in the shared header's left slot) ──────────────────── */
.disc-title {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-inline-size: 0;
  max-width: 640px;
}

.disc-title h1 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 30px;
  line-height: 1.15;
  color: var(--rk-ink);
}

.disc-title p {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--rk-ink-soft);
}

/* ── category tabs ────────────────────────────────────────────────────────── */
/* Same height as the search field beside it. They were 50 and 44 — centred but different shapes,
   which is what made the row read as two unrelated objects rather than one control strip. */
/* No outline, no white trough. The selected tab's emerald pill already says which one is active, so
   a box around the whole row only adds another white-on-white container to a header that had four
   of them; without it the tabs read as navigation sitting on the paper rather than as one more
   control widget. Height still matches the search field beside it. */
/* The tabs used to share a row with a search field; with that gone they carry the row's own bottom
   margin. No outline and no white trough either — the selected tab's emerald pill already says which
   one is active, so a box around the row would just be another white-on-white container. */
.disc-tabs {
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  inline-size: fit-content;
  max-inline-size: 100%;
  margin-block-end: 32px;
}

.disc-tab {
  min-height: 44px;
  padding-inline: 20px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--rk-ink-soft);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease;
}

.disc-tab:hover { color: var(--rk-ink); }
.disc-tab.is-active { background: var(--rk-emerald-soft); color: var(--rk-emerald); }
.disc-tab:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

/* ── band scaffolding ─────────────────────────────────────────────────────── */
.disc-band { margin-block-end: 40px; }

.disc-band-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-block-end: 16px;
}

.disc-band-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 21px;
  line-height: 1.2;
  color: var(--rk-ink);
}

.disc-band-mark { display: inline-flex; color: var(--rk-emerald); }
.disc-band-mark svg { width: 17px; height: 17px; stroke-width: 1.7; }

.disc-pager { display: flex; gap: 8px; flex: none; }

.disc-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 34px;
  block-size: 34px;
  border: 1px solid var(--rk-line);
  border-radius: 999px;
  background: var(--rk-surface);
  color: var(--rk-ink);
  cursor: pointer;
  transition: border-color 160ms ease, opacity 160ms ease;
}

.disc-arrow svg { width: 16px; height: 16px; stroke-width: 2; }
.disc-arrow:hover:not(:disabled) { border-color: var(--rk-emerald); color: var(--rk-emerald); }
/* Disabled at the ends rather than wrapping: a silent jump back to the first three works reads as
   "the button did nothing". */
.disc-arrow:disabled { opacity: 0.35; cursor: default; }
.disc-arrow:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

/* ── type chip ────────────────────────────────────────────────────────────── */
.disc-chip {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 5px;
  min-block-size: 24px;
  padding-inline: 9px;
  border: 1px solid color-mix(in srgb, var(--disc-kind) 35%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--disc-kind) 9%, var(--rk-surface));
  color: var(--disc-kind);
  font-size: 11.5px;
  font-weight: 700;
}

.disc-chip svg { width: 13px; height: 13px; stroke-width: 1.9; }

/* Outline, never filled: the verb belongs to the work's product line, but the page's one primary
   action is the contest CTA and it must stay the only solid emerald button in view. */
.disc-cta {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 6px;
  min-block-size: 36px;
  padding-inline: 16px;
  border: 1px solid color-mix(in srgb, var(--disc-kind) 45%, transparent);
  border-radius: 999px;
  background: var(--rk-surface);
  color: var(--disc-kind);
  font-size: 13px;
  font-weight: 700;
}

.disc-cta svg { width: 15px; height: 15px; stroke-width: 2; }
.disc-cta.is-lead { min-block-size: 42px; padding-inline: 20px; font-size: 14px; }

.disc-week-lead:hover .disc-cta,
.disc-week-side:hover .disc-cta { background: color-mix(in srgb, var(--disc-kind) 10%, var(--rk-surface)); }

/* ── band 1: 本周精选 ─────────────────────────────────────────────────────── */
/* The band declares its own height. Without it the art column sets it: an <img> with block-size:100%
   inside an auto-height box falls back to its intrinsic ratio, and a 3:4 cover at 206px wide is
   275px tall — two of those stacked forced the whole band to 572px, nearly double the intended 300.
   A definite height here is also what makes block-size:100% on the art resolve at all. */
.disc-week {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 18px;
  align-items: stretch;
  block-size: 320px;
}

.disc-week-stack { display: grid; grid-template-rows: 1fr 1fr; gap: 18px; min-block-size: 0; }

.disc-week-lead,
.disc-week-side {
  position: relative;
  display: block;
  overflow: hidden;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--disc-wash);
  cursor: pointer;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

.disc-week-lead:hover,
.disc-week-side:hover { border-color: color-mix(in srgb, var(--disc-kind) 35%, transparent); box-shadow: var(--rk-shadow-panel); }
.disc-week-lead:focus-visible,
.disc-week-side:focus-visible { outline: 2px solid var(--disc-kind); outline-offset: 2px; }

/* THE BLEND. The artwork fills the whole card and dissolves into the card colour under the copy,
   rather than meeting it at a hard vertical seam.
   Two independent guards keep this legible in all 25 languages, which is what a hard split used to
   buy: (1) the mask holds the art at zero opacity across the copy column, so text never sits on
   illustration; (2) the copy carries its own gradient of card colour, so a long German or Russian
   title that runs past the column still lands on a readable base instead of on sky. */
.disc-week-lead-art,
.disc-week-side-art,
.disc-pick-art {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--rk-paper-2);
  -webkit-mask-image: linear-gradient(to right, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
  mask-image: linear-gradient(to right, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
}

html[dir="rtl"] .disc-week-lead-art,
html[dir="rtl"] .disc-week-side-art,
html[dir="rtl"] .disc-pick-art {
  -webkit-mask-image: linear-gradient(to left, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
  mask-image: linear-gradient(to left, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
}

.disc-week-lead { min-block-size: 0; --disc-fade-from: 20%; --disc-fade-to: 58%; }
.disc-week-side { min-block-size: 0; --disc-fade-from: 26%; --disc-fade-to: 74%; }
.disc-pick { --disc-fade-from: 16%; --disc-fade-to: 64%; }

.disc-week-lead-copy,
.disc-week-side-copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  padding: 28px 24px;
  block-size: 100%;
  min-inline-size: 0;
  overflow: hidden;
  /* Opaque across the text, then dissolving — the second half of the blend, from the copy's side. */
  background: linear-gradient(to right, var(--disc-wash) 62%, transparent 100%);
}

html[dir="rtl"] .disc-week-lead-copy,
html[dir="rtl"] .disc-week-side-copy,
html[dir="rtl"] .disc-pick-copy {
  background: linear-gradient(to left, var(--disc-wash) 62%, transparent 100%);
}

.disc-week-lead-copy { inline-size: 52%; }
.disc-week-side-copy { inline-size: 62%; }

/* A side card gets (320 - 18) / 2 = 151px. Budget: 32 padding + 24 chip + 22 title + 34 two lines
   of copy + 36 button + 24 gaps = 172 at two title lines, so the title clamps to one on this card. */
.disc-week-side-copy { padding: 16px; gap: 7px; }

.disc-week-lead-copy h3 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 30px;
  line-height: 1.13;
  color: var(--rk-ink);
}

.disc-week-side-copy h3 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 18px;
  line-height: 1.2;
  color: var(--rk-ink);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.disc-week-lead-copy p,
.disc-week-side-copy p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--rk-ink-soft);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.disc-week-side-copy p { -webkit-line-clamp: 2; font-size: 12.5px; }

.disc-week-lead-art img,
.disc-week-side-art img,
.disc-pick-art img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Covers are portrait; a landscape crop from the centre cuts the character's face as often as not.
     35% keeps the upper-middle third, which is where picture-book covers put their subject. */
  object-position: 50% 34%;
  display: block;
}

.disc-art-blank { display: block; inline-size: 100%; block-size: 100%; background: var(--cloth, var(--rk-paper-2)); }

/* ── band 2: 编辑推荐 ─────────────────────────────────────────────────────── */
/* The strip always leaves the next card half-visible, which is the honest signal that the row
   continues. Fading its inline-end edge stops that half-card reading as a clipping bug. */
.disc-picks-wrap {
  position: relative;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 68px), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - 68px), transparent 100%);
}

html[dir="rtl"] .disc-picks-wrap {
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 68px), transparent 100%);
  mask-image: linear-gradient(to left, #000 calc(100% - 68px), transparent 100%);
}

/* A strip, not a grid: the row holds every work past the first three, and the arrow walks it. Scroll
   snapping keeps a card edge at the rail after each step instead of leaving a sliver showing. */
.disc-picks {
  display: grid;
  grid-auto-flow: column;
  /* Card width is a share of the VISIBLE strip, not a minimum. With `minmax(216px, 1fr)` the tracks
     collapsed to their 216px floor — `1fr` has nothing to distribute inside a scroller — so the row
     showed five-and-a-bit cards regardless of the declared column count. A percentage of the content
     box makes "four per view" true at any width, and one variable drives the breakpoints. */
  --disc-cols: 4;
  grid-auto-columns: calc((100% - (var(--disc-cols) - 1) * 16px) / var(--disc-cols));
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-block-end: 4px;
}

.disc-picks::-webkit-scrollbar { display: none; }

.disc-pick {
  position: relative;
  display: block;
  block-size: 176px;
  overflow: hidden;
  scroll-snap-align: start;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--disc-wash);
  cursor: pointer;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

.disc-pick:hover { border-color: color-mix(in srgb, var(--disc-kind) 35%, transparent); box-shadow: var(--rk-shadow-panel); }
.disc-pick:focus-visible { outline: 2px solid var(--disc-kind); outline-offset: 2px; }

.disc-pick-copy {
  position: relative;
  z-index: 1;
  inline-size: 66%;
  block-size: 100%;
  background: linear-gradient(to right, var(--disc-wash) 62%, transparent 100%);
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 10px 12px 14px;
  min-inline-size: 0;
  overflow: hidden;
}

.disc-pick-copy h3 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 15px;
  line-height: 1.25;
  color: var(--rk-ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.disc-byline {
  margin: 0;
  font-size: 12px;
  line-height: 1.35;
  color: var(--rk-ink-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.disc-pick-foot {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-block-start: auto;
  color: var(--rk-ink-muted);
}

.disc-stat { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; }
.disc-stat svg, .disc-likes svg { width: 14px; height: 14px; stroke-width: 1.6; }
.disc-pick-go { display: inline-flex; color: var(--disc-kind); }
.disc-pick-go svg { width: 15px; height: 15px; stroke-width: 2; }


/* Floats over the rail's inline-end edge, as in the reference. */
.disc-arrow.is-float {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: 6px;
  transform: translateY(-50%);
  box-shadow: var(--rk-shadow-panel);
  z-index: 2;
}

/* ── band 3: 创作比赛 ─────────────────────────────────────────────────────── */
.disc-contest {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px;
  margin-block-end: 40px;
  padding-block: 20px;
  /* Logical, not physical. The inline-end gutter is where the mascot lives and the mascot is pinned
     with inset-inline-end — in Arabic both must move to the left together. Written as a physical
     padding-right the gutter stayed put while the mascot moved, and the CTA landed on top of it.
     216 = the illustration's real rendered width (198) plus its 8px inset and a hair of air. */
  padding-inline: 24px 216px;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--rk-paper-2);
  overflow: hidden;
}

.disc-contest-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 48px;
  block-size: 48px;
  border-radius: 999px;
  background: var(--rk-emerald-soft);
  color: var(--rk-emerald);
  flex: none;
}

.disc-contest-mark svg { width: 24px; height: 24px; stroke-width: 1.7; }

.disc-contest-copy { display: flex; flex-direction: column; gap: 5px; min-inline-size: 0; }

.disc-contest-copy h2 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 21px;
  line-height: 1.2;
  color: var(--rk-ink);
}

.disc-contest-copy p { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--rk-ink-soft); }

/* The page's one solid action. */
.disc-contest-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-block-size: 48px;
  padding-inline: 26px;
  border-radius: 999px;
  background: var(--rk-emerald);
  color: var(--rk-surface);
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}

.disc-contest-cta:hover { background: var(--rk-emerald-hover); }
.disc-contest-cta svg { width: 16px; height: 16px; stroke-width: 2.2; }

.disc-contest-mascot {
  position: absolute;
  inset-block-end: -12px;
  inset-inline-end: 8px;
  block-size: 118px;
  pointer-events: none;
}

html[dir="rtl"] .disc-contest-mascot { transform: scaleX(-1); }


/* ── the picture-book catalogue tab ───────────────────────────────────────── */
.disc-orders { display: flex; gap: 8px; margin-block-end: 28px; }

.disc-order {
  min-height: 38px;
  padding: 0 16px;
  border: 1px solid var(--rk-line);
  border-radius: 999px;
  background: var(--rk-surface);
  color: var(--rk-ink-soft);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}

.disc-order.is-active { border-color: var(--rk-emerald); background: var(--rk-emerald-soft); color: var(--rk-emerald); }
.disc-order:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

/* align-items: start, NOT end. Cards differ in height because a community book has no meta line, and
   bottom-aligning the CARDS drops that book below its neighbours — the books stop sharing a shelf
   line, which is the one thing this layout has to get right. */
.disc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(216px, 1fr));
  gap: 44px 24px;
  align-items: start;
}

.disc-card { display: flex; flex-direction: column; align-items: center; gap: 14px; }

/* Perspective must live on the per-book slot, never on the grid: a container-level perspective makes
   books at the edges lean differently from books in the middle. --rk-book-scale is supplied by
   .shelf-stage on the home page; this page has no such ancestor, so the base value is declared here
   or every calc() collapses the book to 0x0. */
.disc-slot {
  position: relative;
  perspective: 900px;
  --rk-book-scale: 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 208px;
}

.disc-meta { display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; max-width: 200px; }
.disc-name { margin: 0; font-size: 15px; font-weight: 700; line-height: 1.3; color: var(--rk-ink); }
.disc-sub { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--rk-ink-muted); }
.disc-likes { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--rk-ink-muted); }

/* ── responsive ───────────────────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .disc-picks { --disc-cols: 3; }
  /* The mascot's reserved gutter is desktop-only; below this the CTA wraps to its own row instead. */
  .disc-contest { grid-template-columns: auto minmax(0, 1fr); padding-inline-end: 24px; }
  .disc-contest-cta { grid-column: 1 / -1; justify-content: center; }
  .disc-contest-mascot { display: none; }
}

/* One column below this, so the band can no longer hold a fixed height — it stacks and grows. */
@media (max-width: 900px) {
  .disc-week { grid-template-columns: minmax(0, 1fr); block-size: auto; }
  .disc-week-lead { min-block-size: 280px; }
  .disc-week-side { min-block-size: 150px; }
  .disc-picks { --disc-cols: 2; }
}

@media (max-width: 720px) {
  /* The shell's own padding narrows on phones; this page only trims its vertical rhythm. */
  .disc-page { padding-block: 4px 60px; }
  .disc-head h1 { font-size: 27px; }
  /* Phones give the toolbar two rows: tabs first (navigation), search under it at full width. */
  /* Tabs scroll sideways rather than wrapping into a three-row block that pushes the page down. */
  .disc-tabs { flex-wrap: nowrap; overflow-x: auto; inline-size: 100%; scrollbar-width: none; }
  .disc-tabs::-webkit-scrollbar { display: none; }
  .disc-tab { flex: none; }
  /* On a phone the blend turns vertical: there is no room for a text column beside the art, so the
     copy sits at the top of the card and the illustration dissolves upward into it. Same two guards
     as the desktop version — the art is at zero opacity behind the text, and the copy still carries
     its own wash. */
  .disc-week-lead { min-block-size: 268px; }
  .disc-week-side { min-block-size: 200px; }
  .disc-week-lead-copy, .disc-week-side-copy {
    inline-size: 100%;
    justify-content: flex-start;
    background: linear-gradient(to bottom, var(--disc-wash) 50%, transparent 100%);
  }
  html[dir="rtl"] .disc-week-lead-copy,
  html[dir="rtl"] .disc-week-side-copy {
    background: linear-gradient(to bottom, var(--disc-wash) 50%, transparent 100%);
  }
  .disc-week-lead-art, .disc-week-side-art,
  html[dir="rtl"] .disc-week-lead-art, html[dir="rtl"] .disc-week-side-art {
    -webkit-mask-image: linear-gradient(to bottom, transparent 16%, #000 58%);
    mask-image: linear-gradient(to bottom, transparent 16%, #000 58%);
  }
  .disc-week-side-copy h3 { -webkit-line-clamp: 2; }
  /* Narrower cards need a longer fade or the art is a sliver of noise at the edge. */
  .disc-pick { --disc-fade-from: 26%; --disc-fade-to: 78%; }
  /* Fractional on purpose: a whole card plus a third of the next one is the affordance that says
     "this row scrolls". At exactly 1 the next card is fully offscreen and the strip looks static. */
  .disc-picks { --disc-cols: 1.3; }
  .disc-arrow.is-float { inset-inline-end: 2px; }
  .disc-contest { grid-template-columns: minmax(0, 1fr); padding: 20px; text-align: start; }
  .disc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px 16px; }
  .disc-slot { height: 152px; --rk-book-scale: 0.72; }
  .disc-meta { max-width: 100%; }
}

/* ── the contest tab ──────────────────────────────────────────────────────── */
/* Same blend contract as the cards on the front page: the art fills the panel and dissolves under
   the copy, and the copy carries its own wash so a long title in any language still lands on a
   readable base. */
.disc-hero {
  position: relative;
  display: block;
  block-size: 320px;
  overflow: hidden;
  margin-block-end: 28px;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--disc-wash);
  --disc-fade-from: 26%;
  --disc-fade-to: 62%;
}

.disc-hero-art {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--rk-paper-2);
  -webkit-mask-image: linear-gradient(to right, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
  mask-image: linear-gradient(to right, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
}

html[dir="rtl"] .disc-hero-art {
  -webkit-mask-image: linear-gradient(to left, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
  mask-image: linear-gradient(to left, transparent var(--disc-fade-from), #000 var(--disc-fade-to));
}

.disc-hero-art img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: 50% 34%;
  display: block;
}

.disc-hero-copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 12px;
  inline-size: 58%;
  block-size: 100%;
  padding: 30px 28px;
  overflow: hidden;
  background: linear-gradient(to right, var(--disc-wash) 62%, transparent 100%);
}

html[dir="rtl"] .disc-hero-copy { background: linear-gradient(to left, var(--disc-wash) 62%, transparent 100%); }

.disc-hero-status {
  display: inline-flex;
  align-items: center;
  min-block-size: 26px;
  padding-inline: 12px;
  border-radius: 999px;
  background: var(--rk-emerald);
  color: var(--rk-surface);
  font-size: 12px;
  font-weight: 800;
}

.disc-hero-copy h2 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 32px;
  line-height: 1.14;
  color: var(--rk-ink);
}

.disc-hero-copy > p { margin: 0; font-size: 14.5px; line-height: 1.5; color: var(--rk-ink-soft); }

.disc-hero-facts { display: flex; gap: 34px; margin: 2px 0 0; }
.disc-hero-facts > div { display: flex; flex-direction: column; gap: 2px; }

.disc-hero-facts dt {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 15px;
  font-weight: 700;
  color: var(--rk-ink);
  white-space: nowrap;
}

.disc-hero-facts dt svg { width: 17px; height: 17px; stroke-width: 1.7; color: var(--rk-ink-muted); flex: none; }
.disc-hero-facts dd { margin: 0; padding-inline-start: 24px; font-size: 12.5px; color: var(--rk-ink-muted); }

/* ── contest sub-tabs ─────────────────────────────────────────────────────── */
/* Underline, not pills: the category tabs above already own the pill shape, and two rows of pills
   on one screen read as two competing navigations. */
.disc-subtabs {
  display: flex;
  gap: 8px;
  margin-block-end: 22px;
  border-block-end: 1px solid var(--rk-line);
}

.disc-subtab {
  min-height: 44px;
  padding-inline: 18px;
  border: 0;
  border-block-end: 2px solid transparent;
  background: none;
  color: var(--rk-ink-soft);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  margin-block-end: -1px;
}

.disc-subtab:hover { color: var(--rk-ink); }
.disc-subtab.is-active { color: var(--rk-emerald); border-block-end-color: var(--rk-emerald); }
.disc-subtab:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

.disc-subpanel { margin-block-end: 36px; }

/* ── entries ─────────────────────────────────────────────────────────────── */
.disc-entries { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 16px; }

.disc-entry {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--rk-surface);
  cursor: pointer;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

.disc-entry:hover { border-color: color-mix(in srgb, var(--disc-kind) 35%, transparent); box-shadow: var(--rk-shadow-panel); }
.disc-entry:focus-visible { outline: 2px solid var(--disc-kind); outline-offset: 2px; }

.disc-entry-art { aspect-ratio: 4 / 3; overflow: hidden; background: var(--rk-paper-2); }
.disc-entry-art img { inline-size: 100%; block-size: 100%; object-fit: cover; object-position: 50% 34%; display: block; }
.disc-entry-copy { display: flex; flex-direction: column; gap: 4px; padding: 12px 14px 14px; }

.disc-entry-copy h3 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 15px;
  line-height: 1.25;
  color: var(--rk-ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── leaderboard ──────────────────────────────────────────────────────────── */
.disc-note { margin: 0 0 14px; font-size: 13px; color: var(--rk-ink-muted); }

.disc-board { list-style: none; display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; }

.disc-rank {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--rk-surface);
  cursor: pointer;
  transition: border-color 180ms ease;
}

.disc-rank:hover { border-color: var(--rk-card-hover-border); }
.disc-rank:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

.disc-rank-n {
  inline-size: 26px;
  font-family: var(--rk-font-display);
  font-size: 17px;
  color: var(--rk-ink-muted);
  text-align: center;
  flex: none;
}

/* No votes in: the slot keeps its width so the rows stay aligned, but shows a dot rather than a
   position nobody has earned. */
.disc-rank.is-unranked .disc-rank-n { color: var(--rk-line); }

.disc-rank-art { inline-size: 56px; block-size: 42px; border-radius: var(--rk-radius); overflow: hidden; background: var(--rk-paper-2); flex: none; }
.disc-rank-art img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
.disc-rank-copy { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; flex: 1; }
.disc-rank-copy strong { font-size: 14.5px; color: var(--rk-ink); }
.disc-rank-copy em { font-style: normal; font-size: 12.5px; color: var(--rk-ink-muted); }



@media (max-width: 1180px) {
  .disc-entries { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .disc-hero { block-size: auto; }
  .disc-hero-copy { inline-size: 100%; padding: 24px; background: linear-gradient(to bottom, var(--disc-wash) 62%, transparent 100%); }
  html[dir="rtl"] .disc-hero-copy { background: linear-gradient(to bottom, var(--disc-wash) 62%, transparent 100%); }
  .disc-hero-art,
  html[dir="rtl"] .disc-hero-art {
    -webkit-mask-image: linear-gradient(to bottom, transparent 22%, #000 64%);
    mask-image: linear-gradient(to bottom, transparent 22%, #000 64%);
  }
  .disc-hero-copy h2 { font-size: 26px; }
}

@media (max-width: 720px) {
  .disc-hero-facts { flex-direction: column; gap: 12px; }
  .disc-entries { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .disc-subtabs { overflow-x: auto; scrollbar-width: none; }
  .disc-subtabs::-webkit-scrollbar { display: none; }
  .disc-subtab { flex: none; }
  .disc-rank-art { display: none; }
}

/* ── leaderboard: podium + table ───────────────────────────────────────────── */
/* SECOND DELIBERATE DEPARTURE FROM "ONE ACCENT", same discipline as the product hues above: gold,
   silver and bronze are what a podium means, and no token in the v3 palette carries that meaning
   (--rk-warn is a warning colour and would be a semantic lie here). All three live in this one block
   so a fourth medal shade cannot be invented elsewhere, and they are used ONLY on the three badges
   and the winner's frame — never on type, never on a button. */
.disc-podium {
  --medal-1: #d6a12f;
  --medal-2: #9aa7ad;
  --medal-3: #c08a55;
}
.disc-board-head { margin-block-end: 22px; }

.disc-board-head h3 {
  margin: 0 0 4px;
  font-family: var(--rk-font-display);
  font-size: 22px;
  line-height: 1.2;
  color: var(--rk-ink);
}

.disc-board-head .disc-note { margin: 0; }

/* Three columns with the winner in the middle and taller than its neighbours. Bottom-aligned so the
   difference in book height reads as a podium rather than as three cards that failed to line up. */
.disc-podium {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* stretch, not end: a seat whose book has no byline is one line shorter, and bottom-aligning made
     the three card frames start at three different heights — read as a layout fault, not a podium.
     The frames now match and the ranking is carried by the book inside, which is what the design
     uses too. */
  align-items: stretch;
  gap: 18px;
  max-inline-size: 940px;
  margin: 0 auto 30px;
}

.disc-seat {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  padding: 34px 16px 18px;
  border: 1px solid transparent;
  border-radius: var(--rk-radius-lg);
  background: var(--rk-surface);
  cursor: pointer;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

/* Only the winner's seat is framed. Boxing all three would flatten the ranking the podium exists to
   show, and a second amber panel would compete with the emerald CTA above it. */
.disc-seat.is-p1 {
  border-color: color-mix(in srgb, var(--medal-1) 40%, transparent);
  background: color-mix(in srgb, var(--medal-1) 6%, var(--rk-surface));
  padding-block-start: 42px;
}

.disc-seat:hover { border-color: color-mix(in srgb, var(--disc-kind) 35%, transparent); box-shadow: var(--rk-shadow-panel); }
.disc-seat.is-p1:hover { border-color: color-mix(in srgb, var(--medal-1) 65%, transparent); }
.disc-seat:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

/* The laurels sit behind the runner-up seats, at the weight of a watermark — in the reference they
   read as texture, not as a second graphic competing with the covers. */
.disc-seat.is-p2::before,
.disc-seat.is-p3::before {
  content: '';
  position: absolute;
  inset-block-end: 18px;
  inline-size: 62px;
  block-size: 96px;
  opacity: 0.32;
  background: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 96' fill='none' stroke='%23a8c2ae' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M42 92C22 78 12 56 16 30'/%3E%3Cpath d='M18 40c-8-4-12-10-12-16 7 0 13 4 15 10zM22 56c-9-3-13-9-14-15 7-1 14 3 16 9zM29 71c-9-2-14-7-15-13 7-2 14 2 17 8zM21 26c-6-6-8-13-6-19 6 2 11 8 11 15z'/%3E%3C/svg%3E");
  pointer-events: none;
}

.disc-seat.is-p2::before { inset-inline-start: 6px; }
.disc-seat.is-p3::before { inset-inline-end: 6px; transform: scaleX(-1); }

.disc-seat-badge {
  position: absolute;
  inset-block-start: -2px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  color: var(--rk-surface);
  font-family: var(--rk-font-display);
  font-size: 17px;
  line-height: 1;
}

.disc-seat-badge b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 32px;
  block-size: 32px;
  border-radius: 999px;
  font-weight: 800;
}

.disc-seat-badge svg { width: 22px; height: 15px; margin-block-end: -2px; color: var(--medal-1); }

.disc-seat-badge.is-p1 b { background: var(--medal-1); }
.disc-seat-badge.is-p2 b { background: var(--medal-2); }
.disc-seat-badge.is-p3 b { background: var(--medal-3); }

/* The book object is a 3D construction: without `perspective` and a definite height it collapses to
   0×0, which is exactly what the seats did on first render. Same contract as .disc-slot above. */
.disc-seat-book {
  position: relative;
  perspective: 900px;
  --rk-book-scale: 1;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  block-size: 168px;
  margin-block-end: 8px;
}

.disc-seat.is-p1 .disc-seat-book { block-size: 206px; }

/* No vote in yet, so the podium flattens: same book size, same seat height, no medals, no frame.
   The raised centre seat is itself a claim of first place — it says winner as plainly as the crown
   does — so it cannot stay while the whole field is tied on nothing. Everything comes back the
   moment one like lands; this is a state, not a second design. */
.disc-seat.is-unranked .disc-seat-book,
.disc-seat.is-unranked.is-p1 .disc-seat-book { block-size: 168px; }
.disc-seat.is-unranked.is-p1 { padding-block-start: 34px; }
.disc-seat.is-unranked.is-p1 h4 { font-size: 15.5px; }

.disc-seat h4 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 15.5px;
  line-height: 1.3;
  color: var(--rk-ink);
  text-align: center;
}

.disc-seat.is-p1 h4 { font-size: 17px; }
.disc-seat p { margin: 0; font-size: 12.5px; color: var(--rk-ink-muted); }
.disc-seat .disc-stat { margin-block-start: 2px; font-size: 13.5px; font-weight: 700; color: var(--rk-emerald); }
.disc-seat .disc-stat svg { color: var(--rk-emerald); }

/* No vote in yet: the seats stay, the medals do not, and the winner's frame goes with them — an
   amber-framed centre seat is a claim of first place even without a number on it. */
.disc-seat.is-unranked.is-p1 { border-color: var(--rk-line); background: var(--rk-surface); }

/* ── ranks 4+ ─────────────────────────────────────────────────────────────── */
.disc-table {
  inline-size: 100%;
  border-collapse: collapse;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  overflow: hidden;
  background: var(--rk-surface);
}

.disc-table th {
  padding: 14px 20px;
  border-block-end: 1px solid var(--rk-line);
  background: var(--rk-paper-2);
  color: var(--rk-ink-muted);
  font-size: 13.5px;
  font-weight: 700;
  text-align: start;
}

/* Sized against the podium above it, not against a dense admin grid: a 34×26 thumbnail beside
   14px type read as a footnote under three full-size book objects. The cover is now a book-shaped
   portrait at 44×58 and the row breathes to match. */
.disc-table td {
  padding: 12px 20px;
  border-block-end: 1px solid var(--rk-line);
  font-size: 15.5px;
  color: var(--rk-ink);
  vertical-align: middle;
}

.disc-table tbody tr:last-child td { border-block-end: 0; }
.disc-table tbody tr { cursor: pointer; transition: background 140ms ease; }
.disc-table tbody tr:hover { background: var(--disc-wash); }
.disc-table tbody tr:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: -2px; }

.disc-td-rank { inline-size: 84px; font-family: var(--rk-font-display); font-size: 17px; color: var(--rk-ink-soft); }
.disc-td-work { display: flex; align-items: center; gap: 16px; font-weight: 600; }

.disc-td-art {
  inline-size: 44px;
  block-size: 58px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--rk-paper-2);
  flex: none;
}

.disc-td-art img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
.disc-td-author { inline-size: 30%; color: var(--rk-ink-muted); font-size: 14px; }
/* .disc-table th outranks .disc-td-heat on specificity, so the heading stayed start-aligned while
   its numbers sat on the right edge. Both halves of the column are named here. */
.disc-td-heat,
.disc-table th.disc-td-heat { inline-size: 140px; text-align: end; }
.disc-td-heat .disc-stat { color: var(--rk-emerald); font-weight: 700; font-size: 15px; }
.disc-td-heat .disc-stat svg { color: var(--rk-emerald); }

@media (max-width: 900px) {
  .disc-podium { gap: 10px; }
  .disc-seat { padding-inline: 8px; }
  .disc-seat.is-p2::before, .disc-seat.is-p3::before { display: none; }
  .disc-td-author { display: none; }
}

@media (max-width: 720px) {
  /* A three-across podium at 390px leaves 110px per book. Stacked, the winner still leads. */
  .disc-podium { grid-template-columns: minmax(0, 1fr); align-items: stretch; }
  .disc-seat, .disc-seat.is-p1 { padding-block-start: 34px; }

  /* The desktop column widths are fixed pixels: 84 for the rank + 140 for the likes + padding ate
     all but ~64px of a 348px table, so a Chinese title wrapped onto five lines and the row grew to
     227px. Everything that is not the title gives width back here. */
  .disc-table th,
  .disc-table td { padding-inline: 12px; }
  .disc-td-rank { inline-size: 34px; font-size: 15px; }
  .disc-td-heat,
  .disc-table th.disc-td-heat { inline-size: 66px; }
  .disc-td-work { gap: 10px; font-size: 14px; }
  .disc-td-art { inline-size: 34px; block-size: 45px; }
}

/* ── 奖励与规则 ───────────────────────────────────────────────────────────── */
/* Two columns: the rules people read, and a rail for the dates they check. The reference put a
   second copy of the contest card in that rail; here the hero is already directly above every
   sub-tab, so the rail carries only what the hero does not. */
.disc-rules-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  align-items: start;
  gap: 20px;
}

.disc-rules-main { display: flex; flex-direction: column; gap: 20px; min-inline-size: 0; }
.disc-rules-side { display: flex; flex-direction: column; gap: 20px; position: sticky; inset-block-start: 16px; }

.disc-panel {
  padding: 22px 24px;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--rk-surface);
}

.disc-panel > h3,
.disc-panel > h4 {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 19px;
  line-height: 1.2;
  color: var(--rk-ink);
}

.disc-panel > h4 { font-size: 16px; }
.disc-panel > h3 svg,
.disc-panel > h4 svg { width: 19px; height: 19px; stroke-width: 1.8; color: var(--rk-emerald); flex: none; }
.disc-panel-sub { margin: 6px 0 18px; font-size: 13.5px; line-height: 1.5; color: var(--rk-ink-muted); }

/* ── prize cards ──────────────────────────────────────────────────────────── */
/* Reuses the leaderboard's three medal colours rather than declaring a second gold — first place is
   first place on both panels, and two golds a scroll apart read as two different awards. */
.disc-prizes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  --medal-1: #d6a12f;
  --medal-2: #9aa7ad;
  --medal-3: #c08a55;
}

.disc-prize {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--medal);
  border-radius: var(--rk-radius);
  background: color-mix(in srgb, var(--medal) 6%, var(--rk-surface));
}

.disc-prize.is-first { --medal: var(--medal-1); }
.disc-prize.is-second { --medal: var(--medal-2); }
.disc-prize.is-third { --medal: var(--medal-3); }

.disc-prize-cup {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 44px;
  block-size: 44px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--medal) 16%, var(--rk-surface));
  color: var(--medal);
  flex: none;
}

.disc-prize-cup svg { width: 24px; height: 24px; stroke-width: 1.7; }

.disc-prize-cup b {
  position: absolute;
  inset-block-end: 4px;
  inset-inline-end: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 17px;
  block-size: 17px;
  border-radius: 999px;
  background: var(--medal);
  color: var(--rk-surface);
  font-size: 10.5px;
  font-weight: 800;
}

.disc-prize-copy { display: flex; flex-direction: column; gap: 3px; min-inline-size: 0; }
.disc-prize-copy h4 { margin: 0; font-size: 13px; font-weight: 700; color: var(--medal); }

.disc-prize-copy > strong {
  font-family: var(--rk-font-display);
  font-size: 20px;
  line-height: 1.15;
  color: var(--rk-ink);
}

.disc-prize-copy ul { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.disc-prize-copy li { display: flex; align-items: flex-start; gap: 6px; font-size: 12.5px; line-height: 1.4; color: var(--rk-ink-soft); }
.disc-prize-copy li svg { width: 13px; height: 13px; stroke-width: 2.4; color: var(--rk-emerald); flex: none; margin-block-start: 2px; }

/* ── how it works ─────────────────────────────────────────────────────────── */
.disc-steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin: 0;
  padding: 0;
  counter-reset: step;
}

.disc-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  padding: 16px 14px 14px;
  border-radius: var(--rk-radius);
  background: var(--rk-paper-2);
}

.disc-step-n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 22px;
  block-size: 22px;
  border-radius: 999px;
  background: var(--rk-emerald);
  color: var(--rk-surface);
  font-size: 12px;
  font-weight: 800;
}

.disc-step-mark { display: inline-flex; color: var(--rk-emerald); margin-block-start: 2px; }
.disc-step-mark svg { width: 20px; height: 20px; stroke-width: 1.7; }
.disc-step h4 { margin: 4px 0 0; font-size: 14.5px; font-weight: 700; color: var(--rk-ink); }
.disc-step p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--rk-ink-soft); }

/* ── rules accordion ──────────────────────────────────────────────────────── */
.disc-rulelist { display: flex; flex-direction: column; gap: 8px; }

.disc-rule {
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius);
  background: var(--rk-surface);
  overflow: hidden;
}

.disc-rule[open] { background: var(--disc-wash); }

.disc-rule summary {
  display: flex;
  align-items: center;
  gap: 10px;
  min-block-size: 52px;
  padding-inline: 16px;
  cursor: pointer;
  font-size: 15px;
  font-weight: 700;
  color: var(--rk-ink);
  list-style: none;
}

.disc-rule summary::-webkit-details-marker { display: none; }
.disc-rule summary:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: -2px; }
.disc-rule-mark { display: inline-flex; color: var(--rk-emerald); flex: none; }
.disc-rule-mark svg { width: 18px; height: 18px; stroke-width: 1.8; }
.disc-rule-chev { display: inline-flex; margin-inline-start: auto; color: var(--rk-ink-muted); transition: transform 180ms ease; }
.disc-rule-chev svg { width: 18px; height: 18px; stroke-width: 2; }
.disc-rule[open] .disc-rule-chev { transform: rotate(180deg); }
.disc-rule > p { margin: 0; padding: 0 16px 16px 44px; font-size: 14px; line-height: 1.65; color: var(--rk-ink-soft); }

/* ── timeline ─────────────────────────────────────────────────────────────── */
.disc-timeline { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 18px; }

.disc-timeline li {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-inline-start: 22px;
}

/* The connector is drawn on the list item so it stops at the last dot rather than running past it. */
.disc-timeline li:not(:last-child)::before {
  content: '';
  position: absolute;
  inset-inline-start: 5px;
  inset-block: 16px -18px;
  inline-size: 1px;
  background: var(--rk-line);
}

.disc-time-dot {
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 6px;
  inline-size: 11px;
  block-size: 11px;
  border-radius: 999px;
  background: var(--rk-emerald);
}

.disc-timeline strong { font-size: 14px; color: var(--rk-ink); }
.disc-timeline em { font-style: normal; font-size: 12px; font-weight: 500; color: var(--rk-ink-muted); margin-inline-start: 6px; }
.disc-timeline span:last-child { font-size: 13px; color: var(--rk-ink-muted); }

/* ── help ─────────────────────────────────────────────────────────────────── */
.disc-panel.is-help { background: var(--rk-emerald-soft); border-color: transparent; }
.disc-panel.is-help p { margin: 8px 0 12px; font-size: 13.5px; line-height: 1.5; color: var(--rk-ink-soft); }

.disc-textlink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: var(--rk-emerald);
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
}

.disc-textlink svg { width: 15px; height: 15px; stroke-width: 2; }
.disc-textlink:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

@media (max-width: 1180px) {
  .disc-rules-page { grid-template-columns: minmax(0, 1fr); }
  .disc-rules-side { position: static; }
  .disc-rules-side .disc-panel { flex: 1 1 280px; }
  .disc-rules-side { flex-direction: row; flex-wrap: wrap; }
}

@media (max-width: 900px) {
  .disc-prizes { grid-template-columns: minmax(0, 1fr); }
  .disc-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .disc-panel { padding: 18px 16px; }
  .disc-steps { grid-template-columns: minmax(0, 1fr); }
  .disc-rules-side { flex-direction: column; }
  .disc-rule > p { padding-inline-start: 16px; }
}

/* ── 绘本 tab: toolbar ────────────────────────────────────────────────────── */
.disc-books-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-block-end: 26px;
}

/* Search is back on THIS tab only, and it filters for real. The front page lost it because nobody
   can search for a book they have never heard of; the catalogue answers the opposite question. */
.disc-search {
  position: relative;
  display: flex;
  align-items: center;
  inline-size: min(320px, 100%);
  flex: 0 1 320px;
}

.disc-search-mark {
  position: absolute;
  inset-inline-start: 14px;
  display: inline-flex;
  color: var(--rk-ink-muted);
  pointer-events: none;
}

.disc-search-mark svg { width: 17px; height: 17px; stroke-width: 1.9; }

.disc-search input {
  inline-size: 100%;
  min-block-size: 44px;
  padding-inline: 42px 38px;
  border: 1px solid var(--rk-line);
  border-radius: 999px;
  background: var(--rk-surface);
  color: var(--rk-ink);
  font: inherit;
  font-size: 14px;
}

.disc-search input::placeholder { color: var(--rk-ink-muted); }
.disc-search input:focus { outline: none; border-color: var(--rk-emerald); box-shadow: 0 0 0 3px var(--rk-focus-ring); }
/* The engine's own clear button sits where ours does and looks nothing like the rest of the page. */
.disc-search input::-webkit-search-cancel-button { display: none; }

.disc-search-clear {
  position: absolute;
  inset-inline-end: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 22px;
  block-size: 22px;
  border: 0;
  border-radius: 999px;
  background: var(--rk-paper-2);
  color: var(--rk-ink-soft);
  cursor: pointer;
}

.disc-search-clear svg { width: 12px; height: 12px; stroke-width: 2.4; }
.disc-search-clear:hover { background: var(--rk-line); }
.disc-search-clear:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

.disc-results { margin: 0 0 16px; font-size: 13.5px; color: var(--rk-ink-muted); }

.disc-noresults {
  padding: 56px 24px;
  border: 1px dashed var(--rk-line);
  border-radius: var(--rk-radius-lg);
  text-align: center;
}

.disc-noresults h3 { margin: 0 0 6px; font-family: var(--rk-font-display); font-size: 19px; color: var(--rk-ink); }
.disc-noresults p { margin: 0; font-size: 14px; color: var(--rk-ink-muted); }

/* ── 绘本 tab: hero row ───────────────────────────────────────────────────── */
/* One wide lead and two companions, all the same height and all with their copy ON the artwork.
   This is the one place the page overlays type on an illustration; the scrim underneath holds any
   line length, which is the thing the side-by-side layout elsewhere exists to guarantee. */
.disc-shelf-hero {
  display: grid;
  grid-template-columns: 1.75fr 1fr 1fr;
  gap: 16px;
  block-size: 232px;
  margin-block-end: 40px;
}

.disc-lead,
.disc-side {
  position: relative;
  display: block;
  overflow: hidden;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius-lg);
  background: var(--rk-paper-2);
  cursor: pointer;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

.disc-lead:hover,
.disc-side:hover { border-color: var(--rk-card-hover-border); box-shadow: var(--rk-shadow-panel); }
.disc-lead:focus-visible,
.disc-side:focus-visible { outline: 2px solid var(--rk-emerald); outline-offset: 2px; }

.disc-shelf-art { position: absolute; inset: 0; }
.disc-shelf-art img { inline-size: 100%; block-size: 100%; object-fit: cover; object-position: 50% 40%; display: block; }

.disc-shelf-copy {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 46px 18px 16px;
  /* Opaque at the type, gone before the middle of the card — a flat overlay would grey the whole
     illustration, which is the thing people came to look at. */
  background: linear-gradient(to top, rgba(24, 22, 18, 0.82) 0%, rgba(24, 22, 18, 0.55) 42%, transparent 100%);
  color: #fff;
}

.disc-shelf-copy h3 {
  margin: 0;
  font-family: var(--rk-font-display);
  font-size: 17px;
  line-height: 1.2;
  color: #fff;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.disc-lead .disc-shelf-copy { padding: 64px 24px 22px; }
.disc-lead .disc-shelf-copy h3 { font-size: 27px; }
.disc-shelf-sub { margin: 0; font-size: 14px; line-height: 1.35; color: rgba(255, 255, 255, 0.88); }
.disc-shelf-meta { margin: 2px 0 0; font-size: 12.5px; color: rgba(255, 255, 255, 0.72); }

/* The only button on the artwork keeps the page's primary colour rather than borrowing the type
   scale's outline treatment — on a photographic background an outline button disappears. */
.disc-lead .disc-cta.is-lead {
  margin-block-start: 10px;
  border-color: transparent;
  background: var(--rk-emerald);
  color: var(--rk-surface);
}

.disc-lead:hover .disc-cta.is-lead { background: var(--rk-emerald-hover); }

@media (max-width: 1100px) {
  .disc-shelf-hero { grid-template-columns: 1fr 1fr; block-size: auto; }
  .disc-lead { grid-column: 1 / -1; block-size: 232px; }
  .disc-side { block-size: 180px; }
}

@media (max-width: 720px) {
  .disc-books-bar { gap: 12px; }
  .disc-search { flex: 1 1 100%; inline-size: 100%; }
  .disc-shelf-hero { grid-template-columns: minmax(0, 1fr); }
  .disc-lead { block-size: 200px; }
  .disc-lead .disc-shelf-copy { padding: 48px 16px 16px; }
  .disc-lead .disc-shelf-copy h3 { font-size: 21px; }
  .disc-side { block-size: 150px; }
}

/* ── non-book product lines ───────────────────────────────────────────────── */
/* An animation, a comic strip or an image is not a physical book, so it does not get the spine and
   the shelf. It gets a flat frame in its own hue with its own verb badge — the same card grid, a
   different object inside it. Nothing renders here until the feed carries a kind other than
   picture-book; the styles exist so that day needs no second pass. */
.disc-frame {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--rk-line);
  border-radius: var(--rk-radius);
  background: var(--rk-paper-2);
  cursor: pointer;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

.disc-frame img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
.disc-card:hover .disc-frame { border-color: color-mix(in srgb, var(--disc-kind) 40%, transparent); box-shadow: var(--rk-shadow-panel); }
.disc-frame:focus-visible { outline: 2px solid var(--disc-kind); outline-offset: 2px; }

/* Bottom-start, not centred: a badge over the middle of the frame covers the subject. */
.disc-frame-badge {
  position: absolute;
  inset-block-end: 10px;
  inset-inline-start: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 32px;
  block-size: 32px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--disc-kind) 88%, transparent);
  color: var(--rk-surface);
}

.disc-frame-badge svg { width: 17px; height: 17px; stroke-width: 2; }

/* A comic is read page by page, so it keeps a portrait frame. */
.disc-card.is-comic .disc-frame { aspect-ratio: 3 / 4; }
.disc-card.is-image .disc-frame { aspect-ratio: 1 / 1; }
