/* ════════════════════════════════════════════════════════════════
   report.css — 績效報告（creator performance report, standalone handoff).

   Layers ON TOP of tokens.css + components.css (the Ztor design system;
   both untouched). Two families in here:

   1. PORTED VERBATIM from the co-create build's 版稅 tab
      (my-cocreate-proposal.html → components.css .roy-* / .mcp-panel /
      .rev-legend__dot blocks). Class names kept identical on purpose so
      the two builds can be diffed / merged later. Only change: the
      feed-tab underline fix is re-scoped from [data-tab-panel="royalty"]
      to .rpt (this page's report scope).

   2. NEW .rpt-* — the bento grid, tri-hero row, gender split strip,
      post-type table, and the top-level 影視/音樂/貼文 panel switch.

   Conventions (same as the mainline): every visual value is a token;
   bar widths are DATA (inline %, written by report.js — the
   .watch-item__bar-fill convention); chart colours are the --chart-*
   tokens with published fallbacks.
   ════════════════════════════════════════════════════════════════ */

/* ── ported · shared panel surface (co-create .mcp-panel recipe) ── */
.mcp-panel {
  background: var(--bg-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.mcp-panel__title {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-body);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
}

/* ── ported · chart legend dots (co-create .rev-legend) ── */
.rev-legend__dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.rev-legend__dot--1 { background: var(--chart-1, #4ade80); }
.rev-legend__dot--2 { background: var(--chart-2, #a78bfa); }
.rev-legend__dot--3 { background: var(--chart-3, #38bdf8); }
.rev-legend__dot--4 { background: var(--chart-4, #f472b6); }

/* ── ported · data-recency banner ── */
.roy-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-tertiary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.roy-meta__stamp {
  margin: 0;
  font-size: var(--fs-body-sm);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.roy-meta__note {
  flex: 1 1 260px;
  margin: 0;
  font-size: var(--fs-caption);
  color: var(--text-tertiary);
}
.roy-meta > .btn { margin-left: auto; }

/* ── ported · hero panel (one big number + period picker) ── */
.roy-hero__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.roy-hero__head .mcp-panel__title { margin-bottom: 0; }
/* side-by-side hero cards share one number baseline: heads without a period
   picker still reserve the picker row's height, so every hero value starts
   at the same y (single-column mobile drops the reservation) */
@media (min-width: 900px) {
  .rpt .roy-hero__head { min-height: 56px; }
}
/* CJK labels of different lengths skew .feed-tabs' equal-segment sliding
   underline → per-tab underline instead (same fix as the royalty tab).
   The underline is a border-bottom, NOT an inset box-shadow: at fractional
   device scales (Windows 150%) an inset shadow's box-vs-hole subpixel
   misalignment leaks hairline VERTICAL lines down the tab's edges; a
   bottom border has no side paint to leak. */
.rpt .feed-tabs::after { display: none; }
.rpt .feed-tab {
  flex: none;
  white-space: nowrap;
  padding-inline: var(--space-3);
  border-bottom: 2px solid transparent;
  transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 150ms cubic-bezier(0.4, 0, 0.2, 1),
              opacity 100ms ease-out;
}
.rpt .feed-tab--active { border-bottom-color: var(--yellow-500); }
.roy-hero__value {
  display: block;
  margin-top: var(--space-4);
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.roy-hero__cap {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--fs-caption);
  color: var(--text-tertiary);
}

/* ── ported · top-10 bar list (rank · name · bar · value) ── */
.roy-top__cap {
  margin: 0 0 var(--space-3);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
}
.roy-bars {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  counter-reset: roybar;
}
.roy-bars__row {
  display: grid;
  grid-template-columns: 20px minmax(88px, 0.55fr) 1fr auto;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-body-sm);
}
.roy-bars__row::before {
  counter-increment: roybar;
  content: counter(roybar);
  color: var(--text-tertiary);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.roy-bars__name {
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.roy-bars__track {
  height: 10px;
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  overflow: hidden;
}
.roy-bars__fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--chart-1, #4ade80);
}
.roy-bars--usage .roy-bars__fill { background: var(--chart-3, #38bdf8); }
/* demographic ranks (star sign / MBTI / zodiac) wear their own hue so the
   three side-by-side cards read as three datasets, one system */
.roy-bars--demo .roy-bars__fill { background: var(--chart-2, #a78bfa); }
.roy-bars__val {
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ── ported · rank list (idx · name · bar · share% · amount) ── */
.roy-rank-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-2);
}
.roy-rank-head .mcp-panel__title { margin-bottom: 0; }
.roy-rank {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.roy-rank__row {
  display: grid;
  grid-template-columns: 28px minmax(96px, 0.4fr) 1fr 56px 88px;
  grid-template-areas: "idx name bar pct amt";
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  font-size: var(--fs-body-sm);
}
.roy-rank__row + .roy-rank__row { border-top: 1px solid var(--border-subtle); }
.roy-rank__idx {
  grid-area: idx;
  color: var(--text-tertiary);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.roy-rank__name {
  grid-area: name;
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.roy-rank__bar {
  grid-area: bar;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  overflow: hidden;
}
.roy-rank__fill {
  display: block;
  height: 100%;
  border-radius: inherit;
}
.roy-rank__fill--geo { background: var(--chart-2, #a78bfa); }
.roy-rank__fill--dsp { background: var(--chart-4, #f472b6); }
.roy-rank__pct {
  grid-area: pct;
  color: var(--text-tertiary);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.roy-rank__amt {
  grid-area: amt;
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.roy-rank__row--others .roy-rank__name { color: var(--text-tertiary); font-weight: var(--fw-regular); }
.roy-rank__row--others .roy-rank__amt { color: var(--text-secondary); font-weight: var(--fw-regular); }

/* ════════════════════════════════════════════════════════════════
   NEW · .rpt-* — report page shell
   ════════════════════════════════════════════════════════════════ */

/* top-level panel switch (影視 / 音樂 / 貼文) — occasional frequency, so it
   earns a full entrance: fade + settle travel on the DS curve. Keyframe (not
   transition) is correct here: panels display-swap, every show is a fresh
   entrance, and a rapid re-click just restarts an instant swap. */
.rpt [data-report-panel] {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  animation: rpt-panel-in 450ms var(--ease-settle, cubic-bezier(0.22, 1, 0.36, 1));
}
.rpt [data-report-panel][hidden] { display: none; }
@keyframes rpt-panel-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
/* sub-view swap (依版稅 ↔ 依串流) — tens-of-times frequency: fast fade only,
   no travel. Data re-draws are reserved for each view's FIRST reveal. */
.rpt [data-subtab-panel] {
  animation: rpt-sub-in 240ms var(--ease-settle, cubic-bezier(0.22, 1, 0.36, 1));
}
@keyframes rpt-sub-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .rpt [data-report-panel],
  .rpt [data-subtab-panel] { animation: none; }
}

/* bento grid — 12-col, cards span via modifiers; single column on mobile */
.rpt-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-5);
}
.rpt-grid > * { grid-column: span 12; }
@media (min-width: 900px) {
  .rpt-col-4  { grid-column: span 4; }
  .rpt-col-5  { grid-column: span 5; }
  .rpt-col-6  { grid-column: span 6; }
  .rpt-col-7  { grid-column: span 7; }
  .rpt-col-8  { grid-column: span 8; }
  .rpt-col-12 { grid-column: span 12; }
}

/* ── chart motion — the DS fundbar recipe, generalized ─────────────────
   Bars grow width 0 → data-% exactly like .cocreation-card__bar-fill
   (transition: width 1s ease; IO-triggered once, ds.js 'fundbar' contract).
   Cascade rides a per-row --row index written by report.js at render (data,
   not theme — the .watch-item__bar-fill convention), delay capped the same
   way reveal.js caps long grids so 16-row lists resolve in one short wave.
   Numbers enter AFTER their bar leads (bar draws → value confirms), on the
   settle curve. Initial-hidden states gate on .js-reveal-ready (set by
   reveal.js only when GSAP is present and motion is allowed) — with JS or
   GSAP absent, or under prefers-reduced-motion, everything below is inert
   and the resting markup is the final state. */
.rpt .roy-bars__fill,
.rpt .roy-rank__fill {
  transition: width 1s ease;
  transition-delay: min(calc(var(--row, 0) * 45ms), 450ms);
}
.js-reveal-ready .rpt .roy-bars__val,
.js-reveal-ready .rpt .roy-rank__pct,
.js-reveal-ready .rpt .roy-rank__amt,
.js-reveal-ready .rpt .rpt-gender__pct,
.js-reveal-ready .rpt .rpt-gender__amt {
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 450ms var(--ease-settle, cubic-bezier(0.22, 1, 0.36, 1)),
              transform 450ms var(--ease-settle, cubic-bezier(0.22, 1, 0.36, 1));
  transition-delay: calc(min(calc(var(--row, 0) * 45ms), 450ms) + 180ms);
}
.js-reveal-ready .rpt .is-in .roy-bars__val,
.js-reveal-ready .rpt .is-in .roy-rank__pct,
.js-reveal-ready .rpt .is-in .roy-rank__amt,
.js-reveal-ready .rpt .is-in .rpt-gender__pct,
.js-reveal-ready .rpt .is-in .rpt-gender__amt {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .rpt .roy-bars__fill,
  .rpt .roy-rank__fill { transition: none; }
  .js-reveal-ready .rpt .roy-bars__val,
  .js-reveal-ready .rpt .roy-rank__pct,
  .js-reveal-ready .rpt .roy-rank__amt,
  .js-reveal-ready .rpt .rpt-gender__pct,
  .js-reveal-ready .rpt .rpt-gender__amt { opacity: 1; transform: none; transition: none; }
}

/* card head with sub-view tabs (依版稅 / 依串流 …) — roy-rank-head recipe,
   reusable on any card */
.rpt-cardhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-2);
}
.rpt-cardhead .mcp-panel__title { margin-bottom: 0; }
.rpt [data-subtab-panel][hidden] { display: none; }

/* gender split — pie (donut) + legend rows (one reference frame: every
   slice/row tracks share of the SAME total). The pie is a pure-CSS
   conic-gradient written by report.js — data, not theme (the
   .watch-item__bar-fill convention); slice hues are the --chart-* tokens. */
.rpt-gender__pie {
  width: 168px;
  aspect-ratio: 1;
  border-radius: 50%;
  margin: var(--space-5) auto;
  -webkit-mask: radial-gradient(closest-side, transparent 58%, #000 calc(58% + 1px));
          mask: radial-gradient(closest-side, transparent 58%, #000 calc(58% + 1px));
}
.rpt-gender__legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.rpt-gender__row {
  display: grid;
  grid-template-columns: auto 1fr 56px 96px;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  font-size: var(--fs-body-sm);
}
.rpt-gender__row + .rpt-gender__row { border-top: 1px solid var(--border-subtle); }
.rpt-gender__label { color: var(--text-primary); font-weight: var(--fw-medium); }
.rpt-gender__pct {
  color: var(--text-tertiary);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.rpt-gender__amt {
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* post-type table (貼文類型表現) */
.rpt-table-wrap { overflow-x: auto; }
.rpt-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-body-sm);
}
.rpt-table th {
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  color: var(--text-tertiary);
  text-align: right;
  white-space: nowrap;
  border-bottom: 1px solid var(--border-subtle);
}
.rpt-table th:first-child { text-align: left; padding-left: 0; }
.rpt-table td {
  padding: var(--space-3);
  color: var(--text-primary);
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  border-bottom: 1px solid var(--border-subtle);
}
.rpt-table td:first-child {
  text-align: left;
  padding-left: 0;
  font-weight: var(--fw-medium);
}
.rpt-table tr:last-child td { border-bottom: 0; }
.rpt-table__muted { color: var(--text-tertiary); }

/* ── content-detail popup (.rpt-content-modal) — ds-modal primitive with a
   wider panel: the placeholder must hold a full content surface. Scrim blur
   comes from the primitive (blur 8px); modal stays center-origin (DS). ── */
.rpt-content-modal .ds-modal__panel { max-width: 880px; }
.rpt-cm {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: var(--space-6);
  align-items: start;
}
@media (max-width: 640px) {
  .rpt-cm { grid-template-columns: 1fr; }
}
/* cover placeholder — aspect follows the content kind (poster law: films
   are STRICT 2:3; music covers square; posts 16:9) */
.rpt-cm__media {
  width: 100%;
  aspect-ratio: 2 / 3;
  border-radius: var(--radius-md);
  background:
    repeating-linear-gradient(-45deg,
      var(--white-alpha-8, rgba(255, 255, 255, 0.08)) 0 10px,
      transparent 10px 20px),
    var(--bg-tertiary);
  border: 1px dashed var(--border-subtle);
  display: grid;
  place-items: center;
}
.rpt-content-modal[data-cm-kind-key="music"] .rpt-cm__media { aspect-ratio: 1 / 1; }
.rpt-content-modal[data-cm-kind-key="posts"] .rpt-cm__media { aspect-ratio: 16 / 9; }
.rpt-cm__media-note {
  font-size: var(--fs-caption);
  color: var(--text-tertiary);
}
.rpt-cm__kind {
  display: inline-block;
  margin-bottom: var(--space-2);
  padding: 2px var(--space-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  font-size: var(--fs-caption);
  color: var(--text-secondary);
}
.rpt-cm__stats {
  margin-top: var(--space-5);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-3);
}
.rpt-cm__stat {
  padding: var(--space-3) var(--space-4);
  background: var(--bg-tertiary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.rpt-cm__stat-label {
  font-size: var(--fs-caption);
  color: var(--text-tertiary);
}
.rpt-cm__stat-value {
  font-size: var(--fs-body);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* content rows are pressable — quiet hover lift on the row, press feedback
   on the whole row (scale stays off: a full-width row would jiggle; DS
   feed-tab precedent dims instead) */
.rpt [data-rpt-content] .roy-bars__row {
  cursor: pointer;
  border-radius: var(--radius-sm);
  padding-inline: var(--space-2);
  margin-inline: calc(-1 * var(--space-2));
  transition: background-color 150ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .rpt [data-rpt-content] .roy-bars__row:hover {
    background: var(--white-alpha-8, rgba(255, 255, 255, 0.08));
  }
  .rpt [data-rpt-content] .roy-bars__row:hover .roy-bars__name {
    color: var(--text-primary);
  }
}
.rpt [data-rpt-content] .roy-bars__row:active { opacity: 0.6; transition: opacity 100ms ease-out; }

/* the verbatim 貼文報告 table block keeps its own section spacing when it
   lives inside the posts panel */
.rpt-postreport { margin-top: var(--space-4); }
.rpt-postreport .preport-bar { margin-top: var(--space-4); }

/* page-head info button (欄位說明) sits in the posts panel, not the page
   head — keep the component look when detached from .page-head */
.rpt-postreport__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.rpt-postreport__head .mcp-subhead { margin: 0; }
.mcp-subhead {
  font-size: var(--fs-h5);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
}
