:root{
  --bg:#0C1512; --fg:#ECE6D8; --dim:#9AA59C; --gold:#C9A66B; --gold-soft:#E2C783; --line:#2A3A33;
  --display:'Bodoni Moda','Noto Serif TC',serif; --tc:'Noto Serif TC',serif; --ui:'Instrument Sans',system-ui,sans-serif;
  color-scheme:dark;
}
*{box-sizing:border-box}
html,body{background:var(--bg)}
body{margin:0;color:var(--fg);font-family:var(--ui);font-size:14px;min-height:100vh;
  padding-block:20px 48px;padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
body::before{content:"";position:fixed;inset:0;background:url(assets/paper-grain.jpg) center/cover;opacity:.07;mix-blend-mode:screen;pointer-events:none;z-index:0}
.wrap{position:relative;z-index:1;max-width:1180px;margin:0 auto}
.top{display:flex;justify-content:space-between;align-items:center;font-size:12px;letter-spacing:.3em;text-transform:uppercase;gap:12px}
.top .no{color:var(--gold)}
.mode{display:flex;gap:0}
.mode button{padding:7px 14px;font-size:11px;letter-spacing:.2em}
.mode button[aria-pressed=true]{background:var(--gold);color:var(--bg)}
.mode button+button{border-left:0}

.stage{display:grid;grid-template-columns:230px 1fr;gap:8px;align-items:start;margin-top:14px}
.who{padding-top:18px;text-align:center}
.arch{width:200px;aspect-ratio:4/5;margin:0 auto;border-radius:100px 100px 6px 6px;overflow:hidden;border:1px solid var(--gold);padding:5px;background:#0f1d18}
.arch img{display:block;width:100%;height:100%;object-fit:cover;border-radius:96px 96px 3px 3px;transition:opacity .5s}
.who h1{margin:16px 0 0;font-family:var(--tc);font-weight:300;font-size:clamp(34px,4.4vw,52px);letter-spacing:.12em;padding-left:.12em;line-height:1.05}
.who .meta{margin:6px 0 0;font-family:var(--display);font-style:italic;font-size:16px;color:var(--fg)}
.who .blurb{margin:10px auto 0;font-family:var(--tc);font-weight:300;font-size:13px;line-height:1.7;color:var(--dim);max-width:16em}
.who .fict{margin:12px 0 0;font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--dim)}
#svg{display:block;width:100%;height:auto;overflow:visible}

.cap{text-align:center;min-height:96px;margin-top:6px;display:flex;flex-direction:column;gap:6px;align-items:center}
.cap .en{font-family:var(--display);font-style:italic;font-size:clamp(18px,2.6vw,26px);margin:0}
.cap .zh{font-family:var(--tc);font-weight:300;font-size:clamp(14px,1.8vw,17px);letter-spacing:.06em;color:var(--dim);margin:0;max-width:36em;text-wrap:balance;line-height:1.7}
.ctl{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-top:14px}
button{font:inherit;font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold);background:transparent;border:1px solid var(--gold);padding:11px 20px;cursor:pointer}
button:hover:not(:disabled){background:var(--gold);color:var(--bg)}
button:disabled{opacity:.35;cursor:default}
button:focus-visible,summary:focus-visible{outline:2px solid var(--gold-soft);outline-offset:3px}
.cast{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin-top:22px}
.cast button{width:48px;height:48px;padding:0;border-radius:50%;overflow:hidden;border:1px solid var(--line);opacity:.85}
.cast button img{width:100%;height:100%;object-fit:cover;object-position:top}
.cast button[aria-current=true]{border-color:var(--gold);opacity:1}
details{margin-top:28px;border-top:1px solid var(--line);padding-top:14px;max-width:800px;margin-inline:auto}
summary{cursor:pointer;font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim)}
.engine{margin:14px 0 0;font-family:var(--tc);font-size:13px;line-height:1.7}
.engine b{color:var(--gold-soft);font-weight:400}
pre{margin:12px 0 0;font:12px/1.7 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--fg);white-space:pre-wrap;word-break:break-all}
.note{margin:12px 0 0;font-family:var(--tc);font-size:12px;color:var(--dim);letter-spacing:.04em;line-height:1.7}
.you{margin:12px 0 0;font-family:var(--tc);font-size:12px;color:var(--dim);line-height:1.8}
.foot{margin-top:28px;text-align:center;font-family:var(--display);font-style:italic;font-size:15px;color:var(--dim)}

/* feathers: closed bundle <-> open fan, driven by --k */
.fan{--k:.05}
.fan.open{--k:1}
.f{transform-origin:0 0;transform:rotate(calc(var(--a) * 1deg * var(--k))) scale(calc(.45 + .55 * var(--k)))}
.fan.open .f{transition:transform 1.25s cubic-bezier(.2,1.55,.35,1) var(--d)}
.fan:not(.open) .f{transition:transform .75s cubic-bezier(.6,0,.9,.55) var(--dc)}
.halo{opacity:0;transition:opacity .6s}
.fan.verdict .f.res .halo{opacity:.55}
.fan.match .f.res .halo{animation:pulse .5s ease-in-out infinite alternate}
.fan.match .f.res{animation:shiver .11s ease-in-out var(--sd) infinite alternate}
.fan.swoon .f.res{--amp:3.4}
.fan.match .f.m:not(.res){animation:sway 1.6s ease-in-out var(--sd) infinite alternate}
.fan.verdict:not(.match) .f.m:not(.res){filter:saturate(.55) brightness(.8)}
.fan .f.bridge .halo{opacity:.7;fill:#E2C783}
@keyframes shiver{from{transform:rotate(calc(var(--a) * 1deg - var(--amp) * 1deg)) scale(1.012)}to{transform:rotate(calc(var(--a) * 1deg + var(--amp) * 1deg)) scale(1)}}
@keyframes sway{from{transform:rotate(calc(var(--a) * 1deg - .7deg))}to{transform:rotate(calc(var(--a) * 1deg + .7deg))}}
@keyframes pulse{from{opacity:.3}to{opacity:.8}}

/* head: expressions crossfade; hidden while the tail is closed */
.head-img{opacity:0;transition:opacity .35s}
.head-img.on{opacity:1}

/* labels */
.lab{opacity:0;transition:opacity .5s}
.fan.open ~ #labs .lab{opacity:1;transition-delay:1s}
.fan:not(.open) ~ #labs .lab{transition-delay:0s}
.lab text{fill:var(--fg)}
.lab .en{font-family:var(--ui);font-size:15px;letter-spacing:3.4px;fill-opacity:.62}
.lab .zh{font-family:var(--tc);font-size:15px;letter-spacing:2px;fill-opacity:.5}
.lab .nm{font-family:var(--display);font-style:italic;font-size:21px;fill:var(--gold-soft);opacity:0;transition:opacity .6s}
.fan.verdict ~ #labs .lab.res .en{fill-opacity:1;font-weight:500}
.fan.verdict ~ #labs .lab.res .zh{fill-opacity:.85}
.fan.verdict ~ #labs .lab.res .nm,.fan ~ #labs .lab.bridge .nm{opacity:1}
.fan.verdict ~ #labs .lab:not(.res):not(.bridge){opacity:.35}

@media (max-width:900px){
  .stage{grid-template-columns:1fr}
  .who{padding-top:6px;display:grid;grid-template-columns:104px 1fr;gap:4px 16px;text-align:left;align-items:center}
  .arch{width:104px;grid-row:1/4;border-radius:52px 52px 4px 4px;margin:0}
  .arch img{border-radius:48px 48px 2px 2px}
  .who h1{margin:0;font-size:34px}
  .who .blurb{margin:0;max-width:none}
  .who .fict{grid-column:1/-1;text-align:center;margin:8px 0 0}
}
@media (max-width:700px){
  /* narrow screens: only the feathers that lit up get a category name, so ten labels never crowd the fan */
  .lab .en,.lab .zh{display:none}
  .fan.verdict ~ #labs .lab.res .en{display:block;font-size:25px;letter-spacing:2px}
  html[data-lang=zh] .fan.verdict ~ #labs .lab.res .en{display:none}
  html[data-lang=zh] .fan.verdict ~ #labs .lab.res .zh{display:block;font-size:27px}
  html[data-lang=zh] .lab .nm{transform:translateY(10px)}
  .lab .nm{font-size:30px}
  .fan.verdict ~ #labs .lab.fav .nm{font-size:36px}
  button{min-height:44px;min-width:44px}
}
/* top bar: wraps instead of pushing Friend/Lover off a phone screen */
.top{flex-wrap:wrap;row-gap:10px}
.top .right{flex-wrap:wrap;justify-content:flex-end}
@media (max-width:620px){
  .top .right{width:100%;justify-content:space-between;gap:8px}
  .mode button,.mode.lang button,.snd{padding:9px 12px}
}
.setup{margin:12px 0 0;max-width:46em;font-family:var(--tc);font-size:13px;line-height:1.7;color:var(--dim)}
html[data-lang=en] .setup{font-family:var(--ui)}
.you{text-align:center;max-width:46em;margin-inline:auto}
@media (prefers-reduced-motion:reduce){
  .fan .f,.fan .halo,.head-img{animation:none!important;transition-duration:.01s!important;transition-delay:0s!important}
}
.top span:first-child{white-space:nowrap}
@media (max-width:520px){.top .no{display:none}}
.fan.verdict:not(.open) ~ #labs .lab{opacity:0;transition-delay:0s}
/* the fan is decoration only; its glow overflows the viewBox and must never eat clicks */
#svg{pointer-events:none}
.top{position:relative;z-index:2}

/* head body language: every expression moves a little, pivoting at the base of the neck */
#head{transform-origin:720px 920px;transform-box:view-box}
#head.mood-eager{animation:breathe 3.2s ease-in-out infinite}
#head.mood-stifled{animation:tremble .13s ease-in-out infinite alternate}
#head.mood-ecstatic{animation:bob .9s ease-in-out infinite}
#head.mood-sideeye{animation:turnaway 1.1s cubic-bezier(.3,0,.2,1) forwards}
#head.mood-unimpressed{animation:turnaway .8s cubic-bezier(.3,0,.2,1) forwards}
#head.mood-yawning{animation:stretch 1.4s ease-in-out forwards}
#head.mood-startled{animation:jolt .55s cubic-bezier(.2,1.8,.4,1) forwards}
#head.mood-flustered{animation:wobble .7s ease-in-out infinite alternate}
@keyframes breathe{50%{transform:scale(1.012)}}
@keyframes tremble{from{transform:rotate(-.7deg)}to{transform:rotate(.7deg)}}
@keyframes bob{50%{transform:translateY(-8px) rotate(1.2deg)}}
@keyframes turnaway{from{transform:rotate(0)}to{transform:rotate(-5deg) translateX(-6px)}}
@keyframes stretch{40%{transform:scale(1.03,1.07)}70%{transform:scale(1.03,1.07)}100%{transform:scale(1)}}
@keyframes jolt{from{transform:translateY(0) scale(1)}35%{transform:translateY(-26px) scale(1.06)}to{transform:translateY(0) scale(1)}}
@keyframes wobble{from{transform:rotate(-2.2deg)}to{transform:rotate(2.2deg) translateY(-3px)}}
@media (prefers-reduced-motion:reduce){#head{animation:none!important}}

/* the peacock's favourite feather: gold, with golden hearts (lover) or sparkles (friend) floating up */
.fan.verdict .f.fav .halo{fill:#E2C783;opacity:.85}
.fan.verdict ~ #labs .lab.fav .nm{fill:#F6DE9A;font-size:25px}
#gold .gp{fill:#FFE29A;filter:drop-shadow(0 0 5px rgba(242,213,138,.9));opacity:0;transform:scale(.4);
  animation:rise 2.8s ease-out var(--dl) infinite}
@keyframes rise{0%{opacity:0;transform:translate(0,0) scale(calc(var(--sc) * .4))}18%{opacity:1}
  100%{opacity:0;transform:translate(var(--dx),-150px) scale(var(--sc))}}
.cap .fav{margin:2px 0 0;font-family:var(--tc);font-weight:300;font-size:13px;letter-spacing:.08em;color:var(--gold-soft)}
.cap .fav:empty{display:none}
@media (prefers-reduced-motion:reduce){#gold .gp{animation:none;opacity:.8;transform:scale(var(--sc))}}

.kiss{opacity:0;transform-box:fill-box;transform-origin:center;animation:stamp .7s cubic-bezier(.2,1.6,.4,1) .7s forwards;filter:drop-shadow(0 0 6px rgba(196,84,94,.55))}
@keyframes stamp{0%{opacity:0;transform:scale(2.6) rotate(8deg)}55%{opacity:.98;transform:scale(.92)}100%{opacity:.9;transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.kiss{animation:none;opacity:.9}}

.top .right{display:flex;gap:14px;align-items:center}
.mode.lang button{letter-spacing:.12em;padding:7px 11px}
html[data-lang=en] .lab .zh{display:none}
html[data-lang=en] .cap .zh{font-family:var(--display);font-style:italic;font-size:clamp(15px,1.9vw,18px);letter-spacing:.01em;color:var(--dim);max-width:34em}
html[data-lang=en] .who h1{font-family:var(--display);font-weight:400;letter-spacing:.04em}
html[data-lang=en] .who .blurb,html[data-lang=en] .note,html[data-lang=en] .engine,html[data-lang=en] .you,html[data-lang=en] .cap .fav{font-family:var(--ui);letter-spacing:.01em}
.snd{padding:7px 12px;font-size:11px;letter-spacing:.16em}
.snd[aria-pressed=true]{background:var(--gold);color:var(--bg)}
@media (max-width:520px){.snd{padding:7px 8px;letter-spacing:.06em}}
/* language is a quiet outlined switch; Friend/Lover is the filled one, so the two never read as the same control */
.mode.lang button{border-color:var(--line);color:var(--dim)}
.mode.lang button[aria-pressed=true]{background:transparent;color:var(--gold-soft);border-color:var(--gold)}
.mode.lang button:hover:not(:disabled){background:transparent;color:var(--gold-soft)}
.castHint{margin:20px 0 0;text-align:center;font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--dim)}
.castHint + .cast{margin-top:10px}
.cap .hits{margin:4px 0 0;max-width:42em;font-family:var(--ui);font-size:12px;letter-spacing:.02em;color:var(--dim);line-height:1.7}
.cap .hits:empty{display:none}
html:not([data-lang=en]) .cap .hits{font-family:var(--tc)}
/* must come after the desktop rule above (same specificity): on phones the favourite feather is the biggest word */
@media (max-width:700px){.fan.verdict ~ #labs .lab.fav .nm{font-size:36px}}

.who .tasteLine{margin:8px auto 0;font-family:var(--tc);font-weight:300;font-size:12px;line-height:1.65;color:var(--dim);max-width:17em;opacity:.9}
html[data-lang=en] .who .tasteLine{font-family:var(--ui);letter-spacing:.01em}
@media (max-width:900px){.who .tasteLine{grid-column:1/-1;max-width:none;margin:6px 0 0;text-align:left}}

.cap .theirs{margin:6px 0 0;font-family:var(--tc);font-size:12px;line-height:1.6;color:var(--dim);opacity:.8}
html[data-lang=en] .cap .theirs{font-family:var(--ui)}
.engine .legend{display:block;margin-top:4px;opacity:.75}

/* details for the setup rules */
.how{margin:6px 0 0;margin-inline:0;border-top:0;padding-top:0;max-width:46em;font-size:13px;color:var(--dim)}
.how summary{cursor:pointer;display:inline-block;padding:4px 0}
.how p{margin:4px 0 0;line-height:1.65}
.bridgeRow{display:flex;justify-content:center;align-items:center;margin-top:12px;min-height:46px}
.bridgeRow button[hidden]{display:none}
/* small screens: the three buttons sit in one fixed bar at the bottom; the page leaves room for it */
@media (max-width:600px){
  body{padding-bottom:76px}
  .ctl{position:fixed;left:0;right:0;bottom:0;z-index:20;margin:0;padding:10px 12px calc(10px + env(safe-area-inset-bottom));flex-wrap:nowrap;gap:8px;background:var(--bg);border-top:1px solid var(--line)}
  .ctl button{flex:1 1 auto;padding-inline:6px;font-size:13px;white-space:nowrap}
}
@media (max-width:600px){ .cap .theirs{font-size:11px} }
.via{margin:6px 0 0;max-width:46em;font-size:12px;letter-spacing:.02em;color:var(--gold)}
.castHint{margin:14px 0 0}
.castHint + .cast{margin-top:8px;margin-bottom:6px}
@media (min-width:601px){ #stageSvg svg{max-height:max(300px,calc(100vh - 380px));margin:0 auto;display:block} }
@media (min-width:601px) and (max-height:820px){ .arch{width:132px;height:165px;margin-inline:auto} .who .blurb,.who .tasteLine,.who .fict{display:none} #name{font-size:30px} }
@media (max-width:600px){ .wrap{display:flex;flex-direction:column} .wrap>*{order:0} .wrap>.castHint,.wrap>.cast{order:1} .wrap>.you,.wrap>details,.wrap>.foot{order:2} .castHint{margin-top:22px} }
