/* PinkyDolly V2 · pd-v2-collection-listing (T6, SPEC §2)
 * Shares .tabs/.tab/.grid base with pd-v2-collection.css (the home quick-view
 * widget) on purpose — same design tokens, same badge system. The card
 * itself (T9) now lives in public/css/pd-v2-product-card.css, shared via
 * components/pd-v2-product-card.html — this file only keeps what's genuinely
 * specific to this page: the series hero (.chero), the sticky tool bar
 * (.bar/.count/.sort), this page's own grid column count, the empty state,
 * pagination and the footnote block (.cnote).
 */

/* ══ 系列头图 ══ */
/* margin-top:var(--navh) clears the fixed nav (SPEC §2's own prototype
   sets this) — missing it left .chero starting at y=0, rendering its
   first ~62px underneath the nav instead of below it. Found via this
   page's own prototype diff. */
/* aspect-ratio matches the real art (3200x1000, per Yimei's explicit sizing
   instruction) — the bare min-height clamp alone (no ratio) let the box stay
   viewport-height-driven regardless of the image's own proportions, so at
   any normal desktop width the frame came out far squatter than 3.2:1 and
   object-fit:cover zoomed in, cropping real content off the art.

   CORRECTION (found via Yimei's own mobile screenshot, 2026-10-12): the
   previous version of this comment claimed combining min-height with
   aspect-ratio was safe here because width is always 100%, "never derived
   from height" — that's wrong. min-height is vh-based (36vh), and on a
   typical tall phone viewport (e.g. 375x812) that floor (≈292px) EXCEEDS
   what aspect-ratio would derive from a 375px width (≈117px). When the
   floor wins, the browser doesn't just grow the height past the ratio's
   preference — with aspect-ratio also set, it back-solves a WIDER width to
   keep the ratio, which is exactly the width-blowout trap this project
   already has a named lesson for (brief layout-traps rule). Confirmed live:
   .chero rendered 935px wide inside a 375px viewport, clipped by
   overflow:hidden, showing only a cropped slice of the art — the opposite
   of what this rule was meant to fix.

   Real fix: never let both rules be active where the floor could exceed
   the ratio's implied height. min-height's clamp maxes out at 400px, so
   aspect-ratio only switches on at a width where 3200:1000 guarantees at
   least 400px of height regardless of the viewport's actual height
   (400 * 3.2 = 1280px) — fully independent of vh, not just "probably fine
   at common sizes." Below that, pure min-height (today's number, same as
   before this whole aspect-ratio change existed). */
.chero{position:relative;overflow:hidden;min-height:clamp(240px,36vh,400px);
  margin-top:var(--navh);display:grid;align-content:center;transition:background .5s var(--e)}
@media (min-width:1280px){.chero{aspect-ratio:3200/1000}}
/* contrast audit (pd-v2-verify.mjs --contrast) measured the dark .cap/.chero__p
   text below at 4.16:1 (pinky) / 3.76:1 (dolly) against the raw brand fills —
   both under the 4.5 AA floor, the exact #FE0373/#C527F3-behind-text failure
   brief rule #15 already calls out by name. Baked a 30% black mix into the
   fill itself (not a layered overlay — a flat colour is what a contrast
   checker, real or automated, actually reads off backgroundColor) and swapped
   the text from dark to the site's standard off-white; verified this clears
   6.7:1+ on both. --btn1/--btn2 themselves are untouched, so buttons and
   every other use of the raw brand colour elsewhere keep their original
   vibrancy — this darkened fill exists only here. */
.chero[data-c="all"]{background:linear-gradient(110deg,#B20251,#8A1BAA)}
.chero[data-c="pinky"]{background:#B20251}
.chero[data-c="dolly"]{background:#8A1BAA}
.chero[data-c="other"]{background:var(--surface)}
.chero__art{position:absolute;inset:0;z-index:1;width:100%;height:100%;
  object-fit:cover;object-position:center right;pointer-events:none}
/* data-c="all" shows both characters side by side across the full width —
   "center right" (tuned for the solo pinky/dolly art, keeping ONE character
   framed on the art-visible right side while text sits left) crops Pinky
   out entirely here. object-position:center keeps both in frame on desktop.

   2026-10-13(反馈: "I need a full picture to fill in the frame" — Yimei
   rejected the letterboxed version below 760px): switched to a dedicated
   mobile crop (pd-v2-col-hero-all-mobile.webp, 1800x1000, wired in via
   <picture><source> in the markup) instead of showing the whole 3.2:1
   desktop art shrunk down. Still object-fit:cover, not contain — the new
   crop is composed with empty background on the left and Dolly close to
   the right edge, so object-position shifts the crop window left (80%
   right-biased) instead of centering it, to avoid cutting into her wing. */
.chero[data-c="all"] .chero__art{object-position:center}
@media (max-width:760px){.chero[data-c="all"] .chero__art{object-position:80% center}}
.chero::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(96deg,rgba(0,0,0,.3) 0%,rgba(0,0,0,.12) 42%,transparent 72%)}
.chero[data-c="other"]::after{display:none}
.chero__in{position:relative;z-index:3;max-width:var(--maxw);margin:0 auto;width:100%;
  padding:clamp(24px,4vh,42px) var(--gut)}
.chero .cap{color:rgba(255,247,241,.8)}
/* Same dark-mode swap as .head .cap in pd-v2-header.css — see that comment.
   data-c="other" is the only .chero variant with a mode-aware background
   (var(--surface), the other three are fixed-color gradients/solids), so it's the
   only one that actually goes dark in dark mode and needs this. */
.chero[data-c="other"] .cap{color:var(--act2)}
html[data-mode="dark"] .chero[data-c="other"] .cap{color:var(--main1)}
.chero h1{color:#FFF7F1}
.chero[data-c="other"] h1{color:var(--tx)}
.chero__p{margin-top:12px;max-width:52ch;color:rgba(255,247,241,.9);font-size:15.5px}
.chero[data-c="other"] .chero__p{color:var(--tx-dim)}

/* ══ 工具条 ══ */
.bar{position:sticky;top:var(--navh);z-index:40;background:var(--bg);
  border-bottom:1px solid var(--line)}
.bar__in{max-width:var(--maxw);margin:0 auto;padding:12px var(--gut);
  display:flex;align-items:center;gap:14px;flex-wrap:wrap}
/* .tabs/.tab base styling already defined in pd-v2-collection.css; these
   are real <a> links here (SPEC §2: "上线版本的 tab 必须是真实链接"), not
   the prototype's buttons, so they need the same visual treatment a
   hover/focus pass the shared .tab rule doesn't cover for anchors. */
.tab:hover{color:var(--tx);border-color:var(--tx-faint);background:var(--raise)}
.tab:focus-visible{outline:2px solid var(--act);outline-offset:3px}
.bar__r{margin-left:auto;display:flex;align-items:center;gap:12px}
.count{font-size:14px;color:var(--tx-dim);white-space:nowrap}
.sort{padding:9px 13px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);color:var(--tx);font-size:14px;font-weight:600;cursor:pointer;
  text-align:center;text-align-last:center;
  transition:border-color .18s var(--e),background .18s var(--e)}
.sort:hover{border-color:var(--tx-faint);background:var(--raise)}

/* ══ 网格:这一页比首页快览区宽,列数切换的断点也不一样 ══ */
#pd-v2-collection-grid.grid{grid-template-columns:repeat(3,1fr)}
@media (max-width:1000px){#pd-v2-collection-grid.grid{grid-template-columns:repeat(2,1fr)}}

/* ══ 空状态 ══ */
.empty{padding:clamp(40px,8vh,90px) 0;text-align:center}
.empty h2{font-size:clamp(20px,3vw,30px);letter-spacing:.02em}
.empty p{margin-top:10px;color:var(--tx-dim)}
.empty a{margin-top:20px;display:inline-flex;align-items:center;min-height:48px;padding:0 24px;
  border-radius:var(--r);background:var(--act);color:#fff;font-size:15px;font-weight:700}

/* ══ 分页 ══ */
.pd-v2-collection-pagination{margin-top:clamp(28px,4vh,44px);display:flex;gap:8px;
  flex-wrap:wrap;justify-content:center}
.pd-v2-collection-pagination a,.pd-v2-collection-pagination span{min-width:36px;height:36px;
  display:inline-flex;align-items:center;justify-content:center;border-radius:var(--r);
  font-size:14px;font-weight:700;color:var(--tx-dim)}
.pd-v2-collection-pagination a:hover{background:var(--raise);color:var(--tx)}
.pd-v2-collection-pagination span[aria-current="page"]{background:var(--tx);color:var(--bg)}

/* ══ 系列脚注 ══ */
/* Was 1fr 1fr — Yimei's real footnote art (wide character + wordmark
   compositions, ~2:1) read cramped at 50% width with the text side mostly
   empty space. Widened the image column; text column only needs enough
   room for a short heading + ~52ch paragraph. */
.cnote{margin-top:clamp(36px,6vh,74px);border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);overflow:hidden;
  display:grid;grid-template-columns:3fr 2fr;align-items:stretch}
@media (max-width:860px){.cnote{grid-template-columns:1fr}}
.cnote__art{position:relative;min-height:clamp(240px,32vw,380px);background:var(--raise)}
.cnote__art img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* 2026-10-13(反馈: "I need a full picture to fill in the frame"): this used
   to default to object-fit:contain below 760px as a cautious placeholder-
   era guess — the real 1800x900 two-character + wordmark art is now in,
   and at this box's mobile ratio (~1.56:1, narrower than the art's 2:1)
   cover only crops width, not height, so the horizontally-centered
   wordmark stays fully intact; only the outer edges of each character's
   kneeling pose lose a little margin, not enough to cut either of them
   out of frame. Switched to cover like the rest of this component. */
@media (max-width:760px){.cnote[data-c="all"] .cnote__art img{object-fit:cover;object-position:center}}
/* The "all" art is the real 1800x900 two-character + wordmark photo (2:1).
   .cnote__art's bare min-height clamp (no ratio, sized off the grid column
   + viewport width) landed around 1.9:1 at common desktop widths — close
   enough to look fine most of the time, but the widest/narrowest viewports
   drifted further from 2:1 and object-fit:cover cropped the top of the
   wordmark or the sides of the characters. Pinned to the art's own ratio,
   scoped to data-c="all" only — up-close/from-above keep the bare clamp
   since their own art is a different ratio (~1.56:1).

   Gated to >=761px for the same reason .chero's aspect-ratio is gated in
   this file (see that rule's comment, found from the same mobile report):
   min-height's clamp maxes at 380px here, so aspect-ratio only switches on
   once a 2:1 box guarantees at least 380px of height regardless of actual
   width (380*2=760px) — below that the floor would win and aspect-ratio
   would back-solve a wider-than-viewport box, clipped by .cnote's own
   overflow:hidden into a cropped slice. Confirmed live on mobile: 480px-
   wide box inside a 375px viewport. object-fit:contain above was correct
   all along; it just never got a correctly-sized box to work inside. */
@media (min-width:761px){.cnote[data-c="all"] .cnote__art{aspect-ratio:1800/900}}
.cnote__art[data-empty="1"]::after{content:"[ image pending ]";position:absolute;inset:0;
  display:grid;place-items:center;color:var(--tx-faint);font-size:13px;letter-spacing:.1em}
.cnote__tx{padding:clamp(26px,3.4vw,48px);display:grid;align-content:center}
.cnote h3{font-size:clamp(21px,2.6vw,30px);font-weight:650;letter-spacing:.02em}
.cnote p{margin-top:13px;color:var(--tx-dim);max-width:52ch;font-size:15px;line-height:1.7}
/* .rev/.rev.in reveal-on-scroll is already global (pd-v2-footer.css +
   pd-v2-shared.js's IntersectionObserver, loaded sitewide since item 2) —
   not redefined here. */
