/*
  Hook Motion Pack playground (G3, 2026-10-31). Mounted in <section class="play" id="play" data-play>; play.js renders everything.
  Outer frame = site palette (cream #FAF6EF, card #F1EDE7, line #E5DFD6, text #25222A / #4A4650 / #6B655F, ink #0E0C10 only for
  dark blocks and solid buttons, rose #D0538F only ≥24px or blocks, garnet #4A1530 for small links).
  Inside the 9:16 screen = the chosen video theme (ruby / paris / beanie JSON), set as --k-* variables by play.js.
  The 1080×1920 composition copies the pack file effects/17-kinetic-word-stack/compositions/kinetic-word-stack.html:
  same positions, sizes, fonts, timeline.
  Round 2: opening-line box (.pl-input-line), price row = /assets/offer/offer.js hooks (.rf-offer-* styled below),
  second button = free sample (.pl-btn2 → /kits/hook-motion-pack/#sample).
  Round 3: the opening-line box is its own grid cell (.pl-type) so phones put it right above the screen; timeline focus ring
  drawn above the second labels; Chinese hero word upright; step 04 shows the pack file's line numbers 63–64.
*/

/* Effect fonts: only named under .pl-kit (play.js adds it once the section has been on screen and GSAP is in). */
@font-face {
  font-family: "Play Kit Display";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("HelveticaNeue-Medium"), local("Helvetica Neue Medium"), url("/assets/play/vendor/inter-tight-500.woff2") format("woff2");
}
@font-face {
  font-family: "Play Kit Serif";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/play/vendor/fraunces-italic-vf.woff2") format("woff2");
}

.play {
  --pl-bg: #FAF6EF; --pl-card: #F1EDE7; --pl-white: #FFFFFF; --pl-line: #E5DFD6;
  --pl-text: #25222A; --pl-text2: #4A4650; --pl-small: #6B655F; --pl-ink: #0E0C10;
  --pl-rose: #D0538F; --pl-rose-press: #B8407A; --pl-garnet: #4A1530; --pl-pink: #F8D6E7; --pl-blush: #FCE8F1; --pl-champ: #C8A97E;
  --pl-serif: var(--rf-face-serif);
  /* Font plan A: two voices. Sans family set once in /assets/fonts/fonts.css (--rf-face-sans); --pl-mono is the old
     label name and now = the sans (caps + tracking); --pl-code (Space Mono) only for code / path / timeline scale + read-out. */
  --pl-sans: var(--rf-face-sans), "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --pl-mono: var(--pl-sans);
  --pl-code: var(--rf-face-code), ui-monospace, Menlo, monospace;
  --pl-ease: cubic-bezier(.19, 1, .22, 1);
  --pl-spring: cubic-bezier(.34, 1.36, .64, 1);
  --pl-gl: max(24px, env(safe-area-inset-left, 0px));
  --pl-gr: max(24px, env(safe-area-inset-right, 0px));
  display: block; position: relative; background: var(--pl-bg); color: var(--pl-text);
  font-family: var(--pl-sans); font-size: 16px; line-height: 1.55; -webkit-font-smoothing: antialiased;
}
/* Resets wrapped in :where() so they never outrank the component rules below. */
:where(.play) *, :where(.play) *::before, :where(.play) *::after { box-sizing: border-box; }
:where(.play) em, :where(.play) i { font-synthesis: none; }
:where(.play) h2, :where(.play) h3, :where(.play) p, :where(.play) pre { margin: 0; }
:where(.play) button { font: inherit; color: inherit; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
:where(.play) a { color: inherit; -webkit-tap-highlight-color: transparent; }
.play :focus-visible { outline: 2px solid var(--pl-rose); outline-offset: 3px; }
.pl-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

.pl-wrap { max-width: 1480px; margin: 0 auto; padding: 32px var(--pl-gr) 110px var(--pl-gl); }
.pl-rule { height: 1px; background: var(--pl-line); }
.pl-grid {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  grid-template-areas: "player head" "player type" "player ctrl" "player pack"; grid-template-rows: auto auto auto 1fr;
  column-gap: clamp(32px, 5vw, 88px); padding-top: 56px; align-items: start;
}
.pl-head { grid-area: head; }
.pl-type { grid-area: type; }
.pl-player { grid-area: player; }
.pl-ctrl { grid-area: ctrl; }
.pl-pack { grid-area: pack; }

/* ---------- Title block ---------- */
.pl-eyebrow { font: 500 11px/1.4 var(--pl-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--pl-small); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pl-eyebrow .pl-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pl-rose); flex: none; }
.pl-title { margin-top: 14px; font: 400 clamp(44px, 5.4vw, 80px)/1.04 var(--pl-serif); letter-spacing: -.02em; color: var(--pl-text); text-wrap: balance; }
.pl-title em { font-style: italic; color: var(--pl-rose); }
html[lang^="zh"] .pl-title { font-weight: 600; line-height: 1.12; letter-spacing: 0; }
html[lang^="zh"] .pl-title em { font-style: normal; }
.pl-nb { white-space: nowrap; }
/* Chinese headline punctuation set half-width where the font allows it (the homepage maps "，。" to PingFang). */
html[lang^="zh"] .pl-title { font-feature-settings: "halt" 1; }
.pl-demo { margin: 12px 0 0; text-align: center; font: 400 12px/1.5 var(--pl-sans, inherit); color: var(--pl-small); text-wrap: balance; }
.pl-en { margin-top: 8px; font: italic 400 clamp(20px, 2vw, 26px)/1.3 var(--pl-serif); color: var(--pl-text2); }
.pl-lede { margin-top: 18px; max-width: 34em; font-size: 17px; line-height: 1.7; color: var(--pl-text2); text-wrap: pretty; }

/* ---------- Player: 9:16 screen + timeline ---------- */
.pl-player { background: var(--pl-card); border-radius: 28px; padding: 28px 28px 22px; }
.pl-screen {
  position: relative; width: min(320px, 78vw); aspect-ratio: 9 / 16; margin: 0 auto; border-radius: 18px; overflow: hidden;
  background: var(--k-paper, #FFF9FC); isolation: isolate; contain: layout paint;
  box-shadow: 0 0 0 1px rgba(14, 12, 16, .08), 0 28px 50px -28px rgba(14, 12, 16, .45);
}
.pl-comp { position: absolute; left: 0; top: 0; width: 1080px; height: 1920px; transform-origin: 0 0; transform: scale(var(--pl-s, .2962963)); pointer-events: none; }
.pl-paper { position: absolute; inset: 0; background-color: var(--k-paper); background-image: linear-gradient(var(--k-grid) 1px, transparent 1px), linear-gradient(90deg, var(--k-grid) 1px, transparent 1px); background-size: 24px 24px; }
.pl-plus { position: absolute; inset: 0; background-image: linear-gradient(var(--k-muted), var(--k-muted)), linear-gradient(var(--k-muted), var(--k-muted)); background-size: 2px 22px, 22px 2px; background-position: 83px 73px, 73px 83px; background-repeat: no-repeat; opacity: .45; }
/* Cards and words: numbers copied from the pack file (#kws-a/b, #kws1–4, .k-disp, .k-sq, .k-serif). */
.pl-card { position: absolute; left: 125px; width: 830px; height: 537px; border-radius: 15px; overflow: hidden; background: var(--k-panel); }
.pl-card img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity .45s var(--pl-ease); }
.pl-card img.is-in { opacity: 1; }
.pl-card[data-k="a"] img { object-position: left center; } /* the demo cover's caption sits at its left edge: crop the right side instead */
/* Blurred 12×7 previews of the two demo covers, inline (no request): the static frame never shows an empty card while the
   800×450 images are on their way (≈1.1–1.3 s on a throttled phone). Removed once the real image has faded in. */
.pl-card::before { content: ""; position: absolute; inset: -60px; background: center / cover no-repeat; filter: blur(36px); }
.pl-card.is-done::before { content: none; }
.pl-card[data-k="a"]::before { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAHCAIAAACz0DtzAAABDElEQVR42mNw9s0wdwgrSEk/sGV1X31dTHRyVmq4u4t9QkyCl4dXRGhkUkw8g5NnnLlDaHtl6cLm3Ixw36yUhPyUWGc7TwV5xRB/l+DAwNTETAYnrxgXr9iGwuz+8hQHexcHJ8eWzMgDk+rjfJ2ntpUlxMSnxCUzBAZHefmFu3oFe3gH6pnYS4hJ5Aa7zilP8nW26K3JiA8P9nN3YQgPioh3DopzCox1Cg40da1NCKtJCHS2slCQV7Y317M01rU21GFwtXepj81tSy4tD8ssCAwNdrbWVFHztDbn5RVSkJYyNTTQU1dmUJIRdbI2igsNDAlLEBeXFhOVUVFQbk8NlpMQ11PXdLN1tTQyBADn4E37w6DJ6AAAAABJRU5ErkJggg=="); }
.pl-card[data-k="b"]::before { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAHCAIAAACz0DtzAAAA20lEQVR42j2O3QvBYBTG98+6UmqlpJgii3KBUqjlwsdcUMpHuMC/sOXi3YdW2xTq1Whb87GXY8Zzczrn/Hqeh/J/egZ6BCIvcnvcfeJ7ngcrBW8YX4IQgs94p+4m/LiTHg65qbk3bNum/h6wOI5zOB37Tb7H5MqxLB1JtPgBHKlvluu6uq4bhiHJcpEpsJks120no8k4ncIYhxDgmqYBp6hqs1RhU8ysNtoUlo183bpeQgiywOYDKcp8ueCK3Lw6aef41XpjWVYIQXfgroFM00QSEkRR2AoIIWjyBonA1WUOR3kMAAAAAElFTkSuQmCC"); }
.pl-card[data-k="a"] { top: 531px; } .pl-card[data-k="b"] { top: 1132px; }
.pl-w { position: absolute; color: var(--k-text); white-space: nowrap; font-synthesis-style: none; }
/* The kit faces are only named under .pl-kit: naming them earlier would download Fraunces / Inter Tight before the section
   is on screen. Until then the static frame uses the pack's own fallbacks (Kit Display = local Helvetica Neue Medium, so on
   Apple devices words 1–3 already look final; Kit Serif → Georgia), Chinese in PingFang / YaHei. */
.pl-disp { font-family: "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; font-weight: 500; letter-spacing: -.06em; line-height: 1; }
.pl-sq { display: inline-block; transform: scaleX(var(--sq, .92)); transform-origin: 0 0; }
.pl-w[data-k="w1"] { left: 125px; top: 222px; font-size: 120px; }
.pl-w[data-k="w2"] { left: 150px; top: 316px; font-size: 120px; }
.pl-w[data-k="w3"] { left: 505px; top: 382px; font-size: 52px; letter-spacing: -.04em; }
.pl-w[data-k="hero"] { line-height: normal; left: 0; right: 0; top: 640px; text-align: center; font-size: 150px; color: #FFFFFF; text-shadow: 0 6px 22px rgba(0, 0, 0, .35); z-index: 5; }
.pl-kit .pl-disp { font-family: "Play Kit Display", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif; }
.pl-kit .pl-serif { font-family: "Play Kit Serif", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Georgia, serif; }
.pl-serif { font-family: Georgia, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", serif; font-style: italic; font-weight: 900; letter-spacing: -.03em; }
.pl-hs { display: inline-block; transform: scaleX(var(--sq, 1)); transform-origin: 50% 50%; }
/* Chinese words: system sans, no fake italic, theme cjkTracking .02em (kit rule: never 宋体 in video). */
.pl-w.is-cjk { letter-spacing: .02em; font-weight: 600; }
/* Site rule: no italic on Chinese. The hero box is italic for the Latin serif; a Chinese hero (讲究) is set upright. */
.pl-serif.is-cjk { font-style: normal; }
/* Before GSAP is ready (or if it fails): show the last frame, so the screen is never empty. */
.play:not(.pl-live) .pl-card { transform: translateY(-18px); }
.play:not(.pl-live) .pl-w[data-k="hero"] { transform: rotate(-3deg); }

/* Timeline */
.pl-tl { margin-top: 22px; }
.pl-step { display: flex; align-items: baseline; gap: 10px; font: 600 11px/1.4 var(--pl-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--pl-small); }
.pl-step b { font-weight: 700; color: var(--pl-garnet); }
.pl-step span { color: var(--pl-text2); }
html[lang^="zh"] .pl-step span { font: 600 13px/1.4 var(--pl-sans); letter-spacing: .04em; }
html[lang^="zh"] .pl-pack-no, html[lang^="zh"] .pl-price .rf-offer-note, html[lang^="zh"] .pl-countdown { letter-spacing: 0; font-family: var(--pl-sans); font-size: 13px; }
.pl-tl-row { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.pl-playbtn { flex: none; width: 44px; height: 44px; border-radius: 50%; background: var(--pl-ink); color: var(--pl-bg); display: grid; place-items: center; transition: background .4s var(--pl-ease), transform .38s var(--pl-spring); }
.pl-playbtn:hover { background: var(--pl-garnet); }
.pl-playbtn:active { transform: scale(.88); transition-duration: .09s; }
.pl-playbtn svg { width: 14px; height: 14px; }
.pl-playbtn .i-pause { display: none; }
.pl-playbtn[data-state="playing"] .i-play { display: none; }
.pl-playbtn[data-state="playing"] .i-pause { display: block; }
.pl-track { position: relative; flex: 1; min-width: 0; height: 44px; touch-action: none; cursor: ew-resize; border-radius: 10px; outline-offset: 2px; user-select: none; -webkit-user-select: none; }
/* Focus ring (round 3, P-c): the 44px row's content only spans y 1–34 (knob, rail, keys, ticks) and the 0s / 0.5 / … labels
   start right under it at y 44, so the usual 3px-offset outline cut through the labels. The ring is drawn instead around
   y −4…38: 3px clear of the knob and the ticks, 6px clear of the labels. A border (not a shadow) so forced-colours keeps it. */
.play .pl-track:focus-visible { outline: none; }
.pl-track::after { content: ""; position: absolute; left: -4px; right: -4px; top: -4px; bottom: 6px; border: 2px solid var(--pl-rose); border-radius: 12px; pointer-events: none; opacity: 0; }
.pl-track:focus-visible::after { opacity: 1; }
.pl-rail { position: absolute; left: 8px; right: 8px; top: 13px; height: 6px; border-radius: 3px; background: var(--pl-white); box-shadow: inset 0 0 0 1px var(--pl-line); }
.pl-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 100%; border-radius: 3px; background: var(--pl-rose); transform-origin: 0 50%; transform: scaleX(var(--p, 0)); }
.pl-ticks { position: absolute; left: 8px; right: 8px; top: 25px; height: 8px; pointer-events: none;
  background-image: repeating-linear-gradient(90deg, rgba(14, 12, 16, .32) 0 1px, transparent 1px calc(100% / 4)), repeating-linear-gradient(90deg, rgba(14, 12, 16, .16) 0 1px, transparent 1px calc(100% / 12));
  background-size: 100% 8px, 100% 4px; background-repeat: no-repeat; border-right: 1px solid rgba(14, 12, 16, .32); }
.pl-key { position: absolute; top: 16px; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; left: calc(8px + (100% - 16px) * var(--at)); background: var(--pl-blush); box-shadow: inset 0 0 0 1.5px var(--pl-garnet); transform: rotate(45deg); border-radius: 1.5px; pointer-events: none; transition: background .25s var(--pl-ease), box-shadow .25s var(--pl-ease); }
.pl-key.is-past { background: var(--pl-rose); box-shadow: inset 0 0 0 1.5px var(--pl-rose); }
.pl-playhead { position: absolute; top: 4px; left: calc(8px + (100% - 16px) * var(--p, 0)); width: 2px; height: 30px; margin-left: -1px; background: var(--pl-ink); border-radius: 1px; pointer-events: none; }
.pl-playhead::before { content: ""; position: absolute; left: 50%; top: -3px; width: 14px; height: 14px; margin-left: -7px; border-radius: 50%; background: var(--pl-ink); box-shadow: 0 0 0 2px var(--pl-white); transition: transform .38s var(--pl-spring); }
.pl-track.is-drag .pl-playhead::before { transform: scale(1.18); }
.pl-scale { display: flex; justify-content: space-between; margin: 0 0 0 56px; padding: 0 2px; font: 400 10px/1 var(--pl-code); color: var(--pl-small); }
.pl-readout { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 14px; font: 400 12px/1.4 var(--pl-code); color: var(--pl-text2); font-variant-numeric: tabular-nums; flex-wrap: wrap; }
.pl-readout b { font-weight: 700; color: var(--pl-text); }
.pl-keyname { color: var(--pl-garnet); }
.pl-hint { margin-top: 6px; font-size: 13px; line-height: 1.5; color: var(--pl-small); }

/* ---------- Controls ---------- */
/* Desktop: .pl-type (01 + the opening-line box) and .pl-ctrl (chips, 4 slot boxes, 03, 04) stack in the right column and
   read as one block, exactly as in round 2 (36px under the lede, 12px from the box to the chips). */
.pl-type { margin-top: 36px; }
.pl-type > .pl-step { margin-bottom: 12px; }
.pl-ctrl { margin-top: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; }
.pl-group > .pl-step { margin-bottom: 12px; }
/* "Or pick one" label: only shown on phones, where the chips sit under the screen instead of under the box. */
.pl-pick { display: none; }
/* Round 2: one "opening line" box first; the 4 slot boxes below are for fine-tuning the split. */
.pl-line { display: block; }
.pl-input.pl-input-line { height: 58px; padding: 0 18px; border-radius: 16px; font: 500 18px/1 var(--pl-sans); }
.pl-split { margin: 14px 0 10px; }
.pl-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.pl-field { position: relative; display: block; }
.pl-flabel { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); font: 600 11px/1 var(--pl-mono); letter-spacing: .04em; color: var(--pl-small); pointer-events: none; }
.pl-input { width: 100%; height: 50px; padding: 0 14px 0 58px; border-radius: 14px; border: 1px solid var(--pl-line); background: var(--pl-white); color: var(--pl-text);
  font: 500 16px/1 var(--pl-sans); outline: none; transition: border-color .3s var(--pl-ease), box-shadow .3s var(--pl-ease); -webkit-appearance: none; appearance: none; }
.pl-input::placeholder { color: var(--pl-small); opacity: 1; }
.pl-input:hover { border-color: rgba(14, 12, 16, .22); }
.pl-input:focus { border-color: var(--pl-rose); box-shadow: 0 0 0 3px var(--pl-pink); }
.pl-presets { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.pl-chip { display: inline-flex; align-items: center; min-height: 40px; padding: 8px 16px; border-radius: 999px; background: var(--pl-card); color: var(--pl-text); font: 500 14px/1.3 var(--pl-sans); text-align: left; transition: background .5s var(--pl-ease), color .5s var(--pl-ease), transform .38s var(--pl-spring); }
.pl-chip:hover { background: var(--pl-line); }
.pl-chip:active { transform: scale(.94); transition-duration: .09s; }
.pl-chip[aria-pressed="true"] { background: var(--pl-ink); color: var(--pl-bg); }
.pl-swatches { display: flex; flex-wrap: wrap; gap: 10px; }
.pl-swatch { display: inline-flex; align-items: center; gap: 10px; min-height: 48px; padding: 6px 16px 6px 8px; border-radius: 999px; background: var(--pl-white); box-shadow: inset 0 0 0 1px var(--pl-line); font: 500 14px/1 var(--pl-sans); color: var(--pl-text); transition: box-shadow .4s var(--pl-ease), transform .38s var(--pl-spring); }
.pl-swatch:hover { box-shadow: inset 0 0 0 1px rgba(14, 12, 16, .25); }
.pl-swatch:active { transform: scale(.94); transition-duration: .09s; }
.pl-swatch[aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--pl-ink); }
.pl-dots { display: inline-flex; }
.pl-dots i { width: 22px; height: 22px; border-radius: 50%; box-shadow: 0 0 0 2px var(--pl-white), inset 0 0 0 1px rgba(14, 12, 16, .12); }
.pl-dots i + i { margin-left: -7px; }
.pl-note { margin-top: 10px; font-size: 13px; line-height: 1.5; color: var(--pl-small); }
/* Round 4 (H8): Chinese lines break only at spaces and after punctuation (keep-all), never inside a word ("第 17 / 号",
   "说 / 明", "顺 / 着"); the no-break spaces in play.js keep "第 17 号" whole. pretty = no lone word on the last line. */
.pl-note, .pl-hint { text-wrap: pretty; }
html[lang^="zh"] .play :is(.pl-lede, .pl-note, .pl-hint, .pl-demo) { word-break: keep-all; overflow-wrap: break-word; }
.pl-code { position: relative; margin: 0; padding: 16px 18px 16px 12px; border-radius: 16px; background: var(--pl-ink); color: #F1EDE7; font: 400 13px/1.65 var(--pl-code); white-space: pre-wrap; overflow-wrap: anywhere; }
.pl-code code { display: block; font: inherit; }
/* Line 64 wraps between "key: value," pairs only: each pair is one unit (it wraps inside only if a single pair is wider
   than the box), and keep-all keeps a Chinese string such as "就要" whole. */
.pl-kv { display: inline-block; max-width: 100%; vertical-align: top; word-break: keep-all; }
/* Lines 63–64 of the pack file, with the editor's line numbers (generated content: never selected or copied). */
.pl-ln { display: block; position: relative; padding-left: 3.2em; }
.pl-ln::before { content: attr(data-n); position: absolute; left: 0; width: 2.2em; text-align: right; color: var(--pl-line); opacity: .55; }
/* The comment's long rule runs off the edge, like in an editor; inline-size containment keeps it from widening the column. */
.pl-ln .c { display: block; white-space: nowrap; overflow: hidden; contain: inline-size; }
.pl-code .c { color: var(--pl-champ); }
.pl-path { font: 400 12px/1.5 var(--pl-code); color: var(--pl-text2); overflow-wrap: anywhere; }
.pl-code .k { color: var(--pl-champ); }
.pl-code .s { color: var(--pl-pink); }
.pl-code .p { color: var(--pl-line); }
.pl-copyrow { display: flex; align-items: center; gap: 14px; margin-top: 12px; flex-wrap: wrap; }
.pl-copy { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 18px; border-radius: 999px; box-shadow: inset 0 0 0 1.5px var(--pl-ink); color: var(--pl-text); font: 600 14px/1 var(--pl-sans); transition: background .4s var(--pl-ease), color .4s var(--pl-ease), transform .38s var(--pl-spring); }
.pl-copy:hover { background: var(--pl-ink); color: var(--pl-bg); }
.pl-copy:active { transform: scale(.94); transition-duration: .09s; }
.pl-copy svg { width: 15px; height: 15px; flex: none; }
.pl-toast { display: inline-flex; align-items: center; gap: 8px; font: 600 12px/1 var(--pl-mono); color: var(--pl-garnet); opacity: 0; transform: translateY(6px); transition: opacity .3s var(--pl-ease), transform .5s var(--pl-spring); }
.pl-toast::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--pl-rose); }
.pl-toast.is-on { opacity: 1; transform: none; }

/* ---------- Pack info ---------- */
.pl-pack { margin-top: 36px; padding: 26px 28px 24px; border-radius: 24px; background: var(--pl-white); box-shadow: inset 0 0 0 1px var(--pl-line); }
.pl-pack-top { display: flex; justify-content: space-between; align-items: baseline; gap: 6px 16px; flex-wrap: wrap; }
.pl-pack-name { font: 600 15px/1.4 var(--pl-sans); color: var(--pl-text); }
.pl-pack-no { font: 400 11px/1.4 var(--pl-mono); letter-spacing: .02em; font-variant-numeric: tabular-nums; color: var(--pl-small); }
/* Price row = hooks for /assets/offer/offer.js (X1). offer.css is all :where(), so these rules win.
   soon:   $29 + "launch price · first 7 days after opening"
   launch: $29 + struck-through $39, countdown line below
   list:   $39
   If offer.js never answers, the empty row collapses (no empty box). */
.pl-price { margin-top: 10px; }
.pl-price:has(> [data-offer="price"]:empty) { display: none; }
.pl-price > [data-offer="price"] { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px; }
.pl-price .rf-offer-now { font: 400 56px/1 var(--pl-serif); letter-spacing: -.02em; color: var(--pl-rose); }
.pl-price .rf-offer-was { margin: 0; font: 400 26px/1 var(--pl-serif); color: var(--pl-small); text-decoration-thickness: 1.5px; }
.pl-price .rf-offer-note { margin: 0; font: 400 13px/1.4 var(--pl-mono); color: var(--pl-text2); }
.pl-countdown { margin-top: 10px; font: 600 12px/1.4 var(--pl-mono); letter-spacing: .04em; font-variant-numeric: tabular-nums; color: var(--pl-garnet); }
html[lang^="zh"] .pl-countdown { font-weight: 600; }
.pl-cny { margin-top: 8px; font-size: 13px; line-height: 1.6; color: var(--pl-text2); }
.pl-ctas { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-top: 20px; }
.pl-btn { display: inline-flex; align-items: center; gap: 12px; min-height: 50px; padding: 0 10px 0 22px; border-radius: 999px; background: var(--pl-ink); color: var(--pl-bg) !important; text-decoration: none; font: 600 15px/1 var(--pl-sans); transition: background .4s var(--pl-ease), transform .38s var(--pl-spring); }
.pl-btn:hover { background: var(--pl-garnet); }
.pl-btn:active { transform: scale(.95); transition-duration: .09s; }
.pl-btn .pl-arrow { width: 32px; height: 32px; border-radius: 50%; background: var(--pl-rose); color: var(--pl-white); display: grid; place-items: center; transition: transform .5s var(--pl-ease); }
.pl-btn:hover .pl-arrow { transform: translateX(3px); }
.pl-btn .pl-arrow svg { width: 12px; height: 12px; }
/* Second button: the free sample (X3). Outline pill, same height as the main button. */
.pl-btn2 { display: inline-flex; align-items: center; justify-content: center; min-height: 50px; padding: 0 22px; border-radius: 999px; box-shadow: inset 0 0 0 1.5px var(--pl-ink); color: var(--pl-text) !important; text-decoration: none; font: 600 15px/1 var(--pl-sans); transition: background .4s var(--pl-ease), color .4s var(--pl-ease), transform .38s var(--pl-spring); }
.pl-btn2:hover { background: var(--pl-ink); color: var(--pl-bg) !important; }
.pl-btn2:active { transform: scale(.95); transition-duration: .09s; }
.pl-sample-note { margin-top: 12px; }

/* Theme swap: 300ms cross-fade of the screen only (class set by play.js just for this transition). */
html.pl-vt .pl-screen { view-transition-name: pl-screen; }
html.pl-vt::view-transition-group(pl-screen), html.pl-vt::view-transition-old(pl-screen), html.pl-vt::view-transition-new(pl-screen) { animation-duration: .3s; animation-timing-function: cubic-bezier(.19, 1, .22, 1); }
html.pl-vt::view-transition-group(root), html.pl-vt::view-transition-old(root), html.pl-vt::view-transition-new(root) { animation-duration: .3s; }

/* ---------- Layout breakpoints ---------- */
@media (min-width: 861px) and (min-height: 860px) {
  .pl-player { position: sticky; top: calc(84px + env(safe-area-inset-top, 0px)); }
}
@media (max-width: 1100px) {
  .pl-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); }
}
@media (max-width: 860px) {
  /* One column: 01 box → screen → 02 timeline → chips + 4 slot boxes → 03 → 04 → pack. The box sits directly above the
     screen, so while typing (box scrolled to the top by play.js, keyboard over the bottom) the words stay in view (P-a). */
  .pl-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "type" "player" "ctrl" "pack"; grid-template-rows: none; padding-top: 40px; }
  .pl-type { margin-top: 28px; }
  .pl-player { margin-top: 16px; }
  .pl-ctrl { margin-top: 28px; }
  .pl-group-1 > .pl-presets { margin-top: 0; }
  .pl-pick { display: block; flex: 0 0 100%; margin-bottom: 4px; font: 600 11px/1.4 var(--pl-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--pl-text2); }
  html[lang^="zh"] .pl-pick { font: 600 13px/1.4 var(--pl-sans); letter-spacing: .04em; text-transform: none; }
  .pl-wrap { padding-bottom: 80px; }
}
@media (max-width: 520px) {
  .play { --pl-gl: max(16px, env(safe-area-inset-left, 0px)); --pl-gr: max(16px, env(safe-area-inset-right, 0px)); }
  .pl-player { padding: 20px 16px 18px; border-radius: 24px; }
  .pl-key { width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; }
  .pl-pack { padding: 22px 20px 20px; }
  .pl-price .rf-offer-now { font-size: 48px; }
  .pl-btn { width: 100%; justify-content: space-between; }
  .pl-btn2 { width: 100%; }
  /* Phones: sized so each Chinese phrase ("打一句你的开头，" / "看它变成钩子动效。") fits on one line. */
  html[lang^="zh"] .pl-title { font-size: min(9.4vw, 44px); }
}
@media (max-width: 360px) {
  .pl-fields { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .play *, .play *::before, .play *::after { transition-duration: 0s !important; animation-duration: 0s !important; }
  .pl-toast { transform: none; }
}
