/* Layout: full-bleed 3D canvas; goal top-left, recipe band along the bottom, prompts and dialogue above it. Night-plum veils,
   ivory text, mist-lilac accents; 霞鹜文楷 (LXGW WenKai, subset in ui/wenkai.woff2) for titles, 思源宋体 (Noto Serif SC) for text. */
@font-face { font-family: "Ma Shan Zheng"; src: url("ui/title_msz.woff2") format("woff2"); font-display: block; }   /* loading title only: 紫藤岛 / 遗忘亭与七味孟婆汤 */
@font-face { font-family: "Zhi Mang Xing"; src: url("ui/title_zmx.woff2") format("woff2"); font-display: block; }
@font-face { font-family: "LXGW WenKai"; src: url("ui/wenkai.woff2") format("woff2"); font-weight: 400; font-display: swap; }
:root {
  color-scheme: dark;
  --veil: rgba(30, 22, 30, 0.84);          /* panels and dialogue */
  --veil-soft: rgba(24, 18, 30, 0.5);      /* the recipe band: the island shows through */
  --paper: var(--veil);
  --paper-solid: #2a2233;
  --ink: #f3eee8;                          /* ivory */
  --ink-soft: rgba(243, 238, 232, 0.72);
  --wisteria: #c9bbdd;                     /* mist lilac: the accent */
  --wisteria-hi: #e4dcef;
  --wisteria-deep: #e4dcef;
  --gold: #c9bbdd;                         /* (was gold; the UI keeps no gold) */
  --done: #a9c48f;
  --line: rgba(201, 187, 221, 0.45);
  --line-soft: rgba(201, 187, 221, 0.22);
  --hot: #e0907a;
  --shade: 0 1px 10px rgba(20, 14, 26, 0.7);
  --font-display: "LXGW WenKai", "Kaiti SC", "STKaiti", "KaiTi", serif;
  --font-body: "Noto Serif SC", "Songti SC", "STSong", "SimSun", serif;
  --gap: 12px;
  --band: 84px;
}
[hidden] { display: none !important; }
html, body { height: 100%; }
body { background: #b9c8d4; color: var(--ink); font-family: var(--font-body); overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none; }
#stage { position: fixed; inset: 0; }
#stage canvas { display: block; width: 100%; height: 100%; outline: none; }
kbd { display: inline-flex; align-items: center; justify-content: center; min-width: 1.9em; height: 1.9em; padding: 0 .45em; box-sizing: border-box; border: 1.5px solid currentColor; border-radius: 6px; font: 600 .78em/1 var(--font-body); }

.panel { background: var(--veil); border: 1px solid var(--line); border-radius: 2px; box-shadow: 0 8px 28px rgba(20, 14, 26, 0.35); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); color: var(--ink); }

/* Goal, top-left: a wisteria raceme and one line */
#goalbar { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 40px); left: calc(env(safe-area-inset-left, 0px) + 48px); display: flex; align-items: center; gap: 12px; pointer-events: none; }
#goalbar { transition: opacity 1.2s ease; }
#goalbar.pending { opacity: 0; }   /* (CC 11/02) until she has talked to 岛主 (story.js revealGoal) */
#goalbar img { width: auto; height: 40px; filter: drop-shadow(0 1px 4px rgba(20, 14, 26, 0.6)); }
#goal { font: 400 21px/1.3 var(--font-display); letter-spacing: 0.1em; color: var(--ink); text-shadow: var(--shade); }

/* Recipe band along the bottom: photo once found, outline before */
#recipe { position: fixed; left: 0; right: 0; bottom: 0; height: calc(var(--band) + env(safe-area-inset-bottom, 0px)); padding: 0 max(48px, env(safe-area-inset-right, 0px)) env(safe-area-inset-bottom, 0px) max(48px, env(safe-area-inset-left, 0px)); box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; gap: 32px; background: var(--veil-soft); border-top: 1px solid var(--line); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); transition: opacity .4s; }
#recipe .head { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
#recipe h1 { margin: 0; font: 400 20px/1.1 var(--font-display); letter-spacing: 0.3em; color: var(--wisteria); }
#recipe .sub { font-size: 11px; letter-spacing: 0.2em; color: var(--ink-soft); }
#recipe ol { list-style: none; margin: 0; padding: 0 32px; display: flex; align-items: center; gap: 22px; border-left: 1px solid var(--line); border-right: 1px solid var(--line); }
#recipe li { display: flex; align-items: center; gap: 8px; color: var(--ink-soft); }
#recipe li .pic { position: relative; width: 50px; height: 50px; flex-shrink: 0; }
#recipe li img { position: absolute; inset: 0; width: 100%; height: 100%; transition: opacity .6s, transform .6s; }
#recipe li img.on { opacity: 0; transform: scale(0.85); filter: drop-shadow(0 2px 6px rgba(20, 14, 26, 0.5)); }
#recipe li img.off { opacity: 0.85; }
#recipe li .txt { display: flex; flex-direction: column; gap: 1px; }
#recipe li .name { font-size: 15px; letter-spacing: 0.08em; white-space: nowrap; }
#recipe li .trait { font-size: 11px; letter-spacing: 0.08em; color: var(--ink-soft); opacity: 0.85; white-space: nowrap; }
#recipe li.got { color: var(--ink); }
#recipe li.got img.on { opacity: 1; transform: none; }
#recipe li.got img.off { opacity: 0; }
#recipe li.got .name { font-weight: 500; }
/* just found (CC step 114: only a lilac flash, no growing ring): a soft glow behind the icon brightens twice and fades,
   the icon itself glows and lifts a little, the name glows */
#recipe li .pic::before { content: ""; position: absolute; inset: -16px; border-radius: 50%; opacity: 0; pointer-events: none; filter: blur(4px);
  background: radial-gradient(circle, rgba(232, 220, 250, 0.85) 0%, rgba(206, 188, 236, 0.45) 35%, rgba(170, 145, 215, 0) 70%); }
#recipe li.new .pic::before { animation: flash 3.2s ease-in-out both; }
#recipe li.new img.on { animation: lift 3.2s ease-out both, iconGlow 3.2s ease-in-out both; }
#recipe li.new .name { animation: nameGlow 3.2s ease-out both; }
@keyframes flash { 0% { opacity: 0; } 15% { opacity: 1; } 40% { opacity: 0.35; } 62% { opacity: 0.9; } 100% { opacity: 0; } }
@keyframes iconGlow { 0%, 100% { filter: none; } 15%, 62% { filter: drop-shadow(0 0 6px rgba(220, 204, 246, 0.95)); } 40% { filter: drop-shadow(0 0 2px rgba(220, 204, 246, 0.5)); } }
@keyframes lift { 0% { transform: scale(0.85); } 20% { transform: scale(1.14) translateY(-3px); } 100% { transform: none; } }
@keyframes nameGlow { 0%, 60% { color: var(--wisteria-hi); text-shadow: 0 0 12px rgba(201, 187, 221, 0.9); } 100% { text-shadow: none; } }
#recipe .stats { flex-shrink: 0; font-size: 13px; letter-spacing: 0.06em; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
#recipe .stats b { font-weight: 400; color: var(--ink); }
body.in-scene #recipe { opacity: 0; pointer-events: none; }
#recipe.pending { opacity: 0; pointer-events: none; transform: translateY(40%); }   /* (CC 11/03) until the goal is given (story.js revealGoal) */
#recipe { transition: opacity .9s ease, transform .9s ease; }
/* 水彩标本 (step 118, CC: lighter, finer, an eastern-watercolour indie UI): the band is a strip of translucent rice paper; each
   of the seven sits in a hairline ring like a pressed specimen: still to find, a faint pencil ghost of its picture; found, the
   watercolour in full with a small vermilion seal dot */
#recipe { background: linear-gradient(to top, rgba(247, 243, 236, 0.86), rgba(247, 243, 236, 0.68)); border-top: 0; box-shadow: 0 -0.5px 0 rgba(58, 47, 69, 0.14), 0 -12px 30px rgba(30, 20, 34, 0.08);
  backdrop-filter: blur(12px) saturate(1.05); -webkit-backdrop-filter: blur(12px) saturate(1.05); color: #3a2f45; }
#recipe h1 { color: #3a2f45; font-size: 19px; letter-spacing: 0.36em; }
#recipe .sub { color: rgba(58, 47, 69, 0.5); letter-spacing: 0.3em; font-size: 10.5px; }
#recipe ol { border-left: 0.5px solid rgba(58, 47, 69, 0.16); border-right: 0.5px solid rgba(58, 47, 69, 0.16); }
#recipe li { color: rgba(58, 47, 69, 0.5); }
#recipe li .pic { width: 46px; height: 46px; border-radius: 50%; background: radial-gradient(circle at 40% 35%, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.15) 70%);
  box-shadow: inset 0 0 0 0.75px rgba(58, 47, 69, 0.16); }
#recipe li img { inset: 5px; width: calc(100% - 10px); height: calc(100% - 10px); object-fit: contain; }
/* (CC 11/03: 轮廓 → 原版原料, 白色宣纸质感不变) still to find: the herb's outer outline in soft ink on the paper; found: it fades
   into the picture in its true colours (js/ui.js) */
#recipe li img.off { display: block; opacity: 0.55; filter: none; transition: opacity .6s; }
#recipe li img.on { opacity: 0; transform: scale(0.9); filter: none; }
#recipe li.got img.off { opacity: 0; }
#recipe li.got img.on { opacity: 1; transform: none; filter: drop-shadow(0 1px 2px rgba(58, 47, 69, 0.18)); }
#recipe li .name { color: rgba(58, 47, 69, 0.55); }
#recipe li .trait { color: rgba(58, 47, 69, 0.42); opacity: 1; }
#recipe li.got .name { color: #3a2f45; font-weight: 500; }
/* step 120 (CC): no seal dot; a find glows lilac once more, as before, tuned to show on the pale band */
#recipe li .pic::before { inset: -18px; background: radial-gradient(circle, rgba(196, 172, 238, 0.95) 0%, rgba(168, 138, 220, 0.55) 38%, rgba(150, 120, 210, 0) 70%); }
#recipe li.new img.on { animation: lift 3.2s ease-out both, iconGlowLilac 3.2s ease-in-out both; }
#recipe li.new .name { animation: nameLilac 3.2s ease-out both; }
@keyframes iconGlowLilac { 0%, 100% { filter: drop-shadow(0 1px 2px rgba(58, 47, 69, 0.18)); } 15%, 62% { filter: drop-shadow(0 0 7px rgba(160, 128, 220, 0.95)); } 40% { filter: drop-shadow(0 0 3px rgba(160, 128, 220, 0.5)); } }
@keyframes nameLilac { 0%, 60% { color: #7a5aa8; text-shadow: 0 0 10px rgba(170, 140, 225, 0.75); } 100% { text-shadow: none; } }
#recipe .stats { color: rgba(58, 47, 69, 0.5); }
#recipe .stats b { color: #3a2f45; }


/* Bottom stack: prompt, dialogue, cooking (above the recipe band; down to the edge during scenes) */
#bottom { position: fixed; left: 0; right: 0; bottom: calc(env(safe-area-inset-bottom, 0px) + var(--band) + 24px); display: flex; flex-direction: column; align-items: center; gap: 10px; pointer-events: none; padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px)); transition: bottom .4s; }
body.in-scene #bottom { bottom: calc(env(safe-area-inset-bottom, 0px) + 48px); }
#line { position: relative; box-sizing: border-box; width: min(880px, 100%); margin-top: 22px; padding: 38px 44px 22px; display: flex; flex-direction: column; gap: 12px; transition: opacity .3s; }
#line .who { position: absolute; left: 32px; top: -20px; height: 40px; display: flex; align-items: center; gap: 8px; padding: 0 20px 0 10px; border-radius: 20px; border: 1px solid var(--line); background: rgba(30, 22, 30, 0.94); font: 400 19px var(--font-display); letter-spacing: 0.3em; color: var(--wisteria-hi); }
#line .who::before { content: ""; width: 24px; height: 24px; background: url("ui/raceme.png") center / contain no-repeat; }
#line .who.face { padding-left: 62px; }
/* 水彩点缀 (CC 10/30, 丙): a lavender-to-peach watercolour line along the top, a faint wash pooling top left, a stroke of lavender under the name */
#line::before { content: ""; position: absolute; left: 150px; right: 0; top: -1px; height: 3px; pointer-events: none; filter: url(#wRag) blur(0.6px);
  background: linear-gradient(90deg, rgba(184, 164, 216, 0), rgba(184, 164, 216, 0.85) 15%, rgba(211, 200, 232, 0.6) 60%, rgba(246, 189, 188, 0.5) 85%, rgba(246, 189, 188, 0)); }
#line::after { content: ""; position: absolute; left: 0; top: 0; width: 340px; height: 120px; pointer-events: none; filter: blur(14px); background: radial-gradient(closest-side, rgba(150, 120, 200, 0.3), rgba(150, 120, 200, 0)); }
#line .who, #line .say, #line .cont { position: relative; z-index: 1; }
#line .who { position: absolute; isolation: isolate; background: none; border-color: transparent; color: #f3eee8; }
#line .who::after { content: ""; position: absolute; inset: 0 -6px 0 20px; z-index: -1; border-radius: 3px; filter: url(#wRag2); background: rgba(110, 88, 150, 0.92); }   /* a portrait in a ring (ui/face, CC 10/30) sits over the tag's left end */
#line .who.face::before { display: none; }
#line .who.face img { position: absolute; left: -6px; top: 50%; width: 60px; height: 60px; margin-top: -30px; border-radius: 50%; border: 2px solid #efe6d8; box-shadow: 0 2px 10px rgba(20, 14, 26, 0.45); background: #faf6f0; }
#line .say { margin: 0; font-size: 22px; line-height: 1.65; letter-spacing: 0.1em; }
#line .cont { align-self: flex-end; display: flex; align-items: center; gap: 8px; font-size: 12px; letter-spacing: 0.1em; color: var(--ink-soft); }
#line .cont kbd { font-size: 11px; }
#line.wait { pointer-events: auto; cursor: pointer; }
#prompt { pointer-events: auto; cursor: pointer; display: inline-flex; align-items: center; gap: 12px; font: 400 18px var(--font-body); letter-spacing: 0.14em; color: var(--ink); background: none; border: 0; padding: 6px 10px; text-shadow: 0 1px 8px rgba(20, 14, 26, 0.85); }
#prompt kbd { font-size: 14px; height: 32px; padding: 0 10px; border: 2px solid var(--ink); border-radius: 7px; box-shadow: 0 1px 6px rgba(20, 14, 26, 0.45); text-shadow: none; }
#prompt:focus-visible, .btn:focus-visible { outline: 2px solid var(--wisteria); outline-offset: 2px; }

/* Hints in the middle: a line low down (toast), a place name large in the centre */
#toast { order: 3; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 10px; font-size: 19px; letter-spacing: 0.14em; color: var(--ink); text-shadow: 0 1px 8px rgba(20, 14, 26, 0.85); opacity: 1; transition: opacity .5s; animation: rise .45s ease-out; }
#toast.out { opacity: 0; }
#toast kbd { font-size: 15px; height: 34px; min-width: 34px; border: 2px solid var(--ink); border-radius: 7px; box-shadow: 0 1px 6px rgba(20, 14, 26, 0.45); text-shadow: none; }
#toast kbd.wide { min-width: 52px; }
#toast span { margin: 0 14px 0 4px; font-weight: 300; }
#toast span:last-child { margin-right: 0; }
#toast b { font: 400 21px var(--font-display); letter-spacing: 0.16em; }
#place { position: fixed; left: 0; right: 0; top: 22%; text-align: center; pointer-events: none; font: 400 46px/1.2 var(--font-display); letter-spacing: 0.5em; padding-left: 0.5em; color: var(--ink); text-shadow: 0 2px 18px rgba(20, 14, 26, 0.75); opacity: 1; transition: opacity 1.2s; animation: rise 1.4s ease-out; }
#place::before, #place::after { content: ""; display: inline-block; vertical-align: middle; width: 56px; height: 1px; margin: 0 22px; background: rgba(243, 238, 232, 0.6); }
#place.out { opacity: 0; }
#place.cue { font-size: 40px; }
#place.cue::before, #place.cue::after { display: none; }
#place small { display: block; margin-top: 16px; font: 300 20px/1.4 var(--font-display); letter-spacing: 0.3em; color: var(--ink); }
/* (CC 11/01) back to the first plain fade, in 霞鹜文楷: the name between its two dashes, the verse under it */
#place.named::before, #place.named::after { display: none; }
#place b { display: block; font-weight: 400; }
#place b s { display: inline-block; vertical-align: middle; width: 56px; height: 1px; margin: 0 22px 0.12em; background: rgba(243, 238, 232, 0.6); }
@media (max-width: 520px) { #place b s { width: 24px; margin: 0 10px 0.12em; } }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }
@media (max-width: 520px) { #place { font-size: 32px; letter-spacing: 0.3em; } #place.cue { font-size: 28px; } #place small { font-size: 15px; letter-spacing: 0.15em; } #place::before, #place::after { width: 24px; margin: 0 10px; } #toast { font-size: 16px; } }
@media (prefers-reduced-motion: reduce) { #toast, #place, #recipe li.new img.on { animation: none; } #recipe li.new .pic::before { animation-duration: 0.01s; } }

/* Settings: the button top right, the panel down the right side (Esc) */
#gear { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 36px); right: calc(env(safe-area-inset-right, 0px) + 44px); width: 44px; height: 44px; border-radius: 22px; border: 1px solid var(--line); background: var(--veil-soft); color: var(--ink); display: grid; place-items: center; padding: 0; cursor: pointer; transition: opacity .3s; }
#gear:hover { border-color: var(--wisteria); }
#gear:focus-visible { outline: 2px solid var(--wisteria); outline-offset: 2px; }
body.set-open #gear, body.in-scene #gear { opacity: 0; pointer-events: none; }
/* 拍照 (CC 10/31): always there, under the settings button */
#snap { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 92px); right: calc(env(safe-area-inset-right, 0px) + 44px); width: 44px; height: 44px; border-radius: 22px; border: 1px solid var(--line); background: var(--veil-soft); color: var(--ink); display: grid; place-items: center; padding: 0; cursor: pointer; transition: opacity .3s; }
#snap:hover { border-color: var(--wisteria); }
#snap:focus-visible { outline: 2px solid var(--wisteria); outline-offset: 2px; }
body.set-open #snap, body.in-scene #snap, body.mg-open #snap { opacity: 0; pointer-events: none; }
#settings { position: fixed; top: 0; right: 0; bottom: 0; z-index: 15; width: min(400px, 100%); box-sizing: border-box; overflow-y: auto; padding: calc(env(safe-area-inset-top, 0px) + 44px) max(40px, env(safe-area-inset-right, 0px)) 28px 40px;
  background: rgba(30, 22, 30, 0.86); border-left: 1px solid var(--line); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); display: flex; flex-direction: column; gap: 26px; animation: slideIn .35s ease-out; }
@keyframes slideIn { from { transform: translateX(24px); opacity: 0; } }
#settings .shead { display: flex; align-items: baseline; justify-content: space-between; }
#settings h2 { margin: 0; display: flex; align-items: center; gap: 10px; font: 400 26px var(--font-display); letter-spacing: 0.4em; }
#settings h2 img { height: 30px; }
#settings .shead span { font-size: 12px; letter-spacing: 0.1em; color: var(--ink-soft); }
#settings section { display: flex; flex-direction: column; gap: 12px; }
#settings h3 { margin: 0; display: flex; align-items: center; gap: 14px; font: 400 17px var(--font-display); letter-spacing: 0.3em; color: var(--wisteria); }
#settings h3::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); }
#settings .times { display: flex; flex-wrap: wrap; gap: 0 18px; }
#settings .times button { min-height: 36px; padding: 0; border: 0; background: none; font: 400 17px var(--font-body); letter-spacing: 0.12em; color: var(--ink-soft); cursor: pointer; }
#settings .times button:hover { color: var(--ink); }
#settings .snote { margin: 2px 0 0; font: 400 12px var(--font-body); letter-spacing: 0.08em; color: var(--ink-soft); opacity: 0.8; }
#settings .times button.on { color: var(--wisteria); text-decoration: underline; text-underline-offset: 7px; text-decoration-thickness: 1px; }
#settings .row { display: flex; align-items: center; justify-content: space-between; min-height: 32px; font-size: 15px; letter-spacing: 0.1em; }
#settings input[type=checkbox] { width: 18px; height: 18px; accent-color: var(--wisteria); }
#settings .slide { display: grid; grid-template-columns: 64px 1fr; align-items: center; gap: 16px; font-size: 15px; letter-spacing: 0.1em; }
#settings input[type=range] { width: 100%; accent-color: var(--wisteria); }
#setTracks { display: flex; flex-direction: column; }
#setTracks button { display: grid; grid-template-columns: 22px auto 1fr; align-items: baseline; gap: 4px 10px; min-height: 42px; padding: 0; border: 0; background: none; text-align: left; color: var(--ink); cursor: pointer; }
#setTracks .mk { align-self: center; width: 16px; height: 22px; }
#setTracks [aria-checked=true] .mk { background: url("ui/raceme.png") center / contain no-repeat; }
#setTracks .nm { font: 400 17px var(--font-body); letter-spacing: 0.14em; }
#setTracks [aria-checked=true] .nm { color: var(--wisteria); }
#setTracks .sb { font-size: 12px; letter-spacing: 0.06em; color: var(--ink-soft); }
#setTracks button:hover .nm { color: var(--wisteria-hi); }
#settings details summary { list-style: none; cursor: pointer; }
#settings details summary::-webkit-details-marker { display: none; }
#settings summary h3::before { content: "展开 ›"; order: 2; font: 400 12px var(--font-body); letter-spacing: 0.1em; color: var(--ink-soft); }
#settings details[open] summary h3::before { content: "收起"; }
#settings .keys { display: grid; grid-template-columns: auto 1fr; gap: 10px 18px; align-items: center; margin: 14px 0 0; font-size: 15px; letter-spacing: 0.1em; }
#settings .keys dt { display: flex; gap: 5px; font-size: 17px; }
#settings .keys dd { margin: 0; }
/* 小像 (CC 10/30): the painted portraits, tucked away in the panel */
#settings .album { display: grid; gap: 18px; margin: 14px 0 0; }
#settings .album figure { margin: 0; }
#settings .album img { display: block; width: 100%; height: auto; border-radius: 2px; border: 1px solid var(--line); }
#settings .album figcaption { margin-top: 8px; font: 400 13px var(--font-display); letter-spacing: 0.2em; color: var(--ink-soft); text-align: center; }
#settings .sfoot { margin-top: auto; align-self: center; display: flex; align-items: center; gap: 10px; min-height: 44px; border: 0; background: none; color: var(--ink); font: 400 15px var(--font-body); letter-spacing: 0.12em; cursor: pointer; }
#settings .sfoot kbd { font-size: 13px; }
#settings button:focus-visible { outline: 2px solid var(--wisteria); outline-offset: 2px; }

/* Touch joystick (above the recipe band) */
#joy { position: fixed; left: calc(env(safe-area-inset-left, 0px) + 22px); bottom: calc(env(safe-area-inset-bottom, 0px) + var(--band) + 22px); width: 116px; height: 116px; border-radius: 50%; background: rgba(30, 22, 30, 0.3); border: 1px solid var(--line); }
#joy i { position: absolute; left: 50%; top: 50%; width: 48px; height: 48px; margin: -24px 0 0 -24px; border-radius: 50%; background: rgba(243, 238, 232, 0.85); box-shadow: 0 2px 8px rgba(20, 14, 26, .35); }
#sprint, #stroll { position: fixed; right: calc(env(safe-area-inset-right, 0px) + 22px); width: 64px; height: 64px; border-radius: 50%; border: 1px solid var(--line); background: var(--veil); color: var(--ink); font: 400 15px var(--font-display); letter-spacing: 0.1em; box-shadow: 0 4px 14px rgba(20, 14, 26, .3); }
#sprint { bottom: calc(env(safe-area-inset-bottom, 0px) + var(--band) + 36px); }
#stroll { bottom: calc(env(safe-area-inset-bottom, 0px) + var(--band) + 110px); }
#sprint.on, #stroll.on { background: var(--wisteria); color: #2a2233; }

/* Loading: the painted island turning on its sea, the title under it (loader.js) */
#intro { position: fixed; inset: 0; z-index: 30; background: radial-gradient(ellipse 70% 55% at 50% 40%, #fbf8f3 0%, #f4efe8 60%, #ece4ee 100%); transition: opacity 1.4s ease, filter 1.4s ease, transform 1.4s ease; }
#intro::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background: radial-gradient(ellipse 30% 22% at 22% 18%, rgba(222, 208, 240, 0.5), rgba(222, 208, 240, 0) 70%); }
#intro.leaving { opacity: 0; filter: blur(8px) saturate(1.3); transform: scale(1.05); pointer-events: none; }
#ldCanvas { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; cursor: grab; }
#ldCanvas:active { cursor: grabbing; }
.ldText { position: absolute; left: 0; right: 0; bottom: max(7vh, 40px); display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; color: #3a2f45; text-align: center; padding: 0 16px; }
/* the title in a brush hand of its own (not the game's UI face), with a faint gold and lilac light behind it, breathing */
.ldText { --font-title: "Ma Shan Zheng", "Xingkai SC", "STXingkai", var(--font-display); }
.ldText h1 { position: relative; margin: 0; font: 400 112px/1.1 var(--font-title); letter-spacing: 0.3em; padding-left: 0.3em; color: #3a2f45;
  text-shadow: 0 0 10px rgba(255, 246, 228, 0.9), 0 0 26px rgba(236, 206, 148, 0.55), 0 0 54px rgba(204, 178, 238, 0.6); }
.ldText h1::before { content: ""; position: absolute; left: 50%; top: 50%; width: 170%; height: 230%; z-index: -1; pointer-events: none;
  transform: translate(-50%, -50%); border-radius: 50%; animation: halo 6s ease-in-out infinite;
  background: radial-gradient(ellipse 50% 50% at 42% 50%, rgba(240, 210, 150, 0.55), rgba(240, 210, 150, 0) 70%),
              radial-gradient(ellipse 45% 50% at 60% 52%, rgba(206, 182, 240, 0.6), rgba(206, 182, 240, 0) 72%); }
@keyframes halo { 50% { opacity: .55; transform: translate(-50%, -50%) scale(1.08); } }
.ldText .ldSub { margin: 0; font: 400 22px/1.3 var(--font-title); letter-spacing: 0.35em; padding-left: 0.35em; color: #6d5d82;
  text-shadow: 0 0 12px rgba(236, 206, 148, 0.5), 0 0 24px rgba(204, 178, 238, 0.45); }
.ldIntro { margin: 6px 0 10px; font-size: 14px; letter-spacing: 0.12em; color: rgba(58, 47, 69, 0.75); }
.ldBar { position: relative; width: 300px; height: 96px; margin: -6px 0 -10px; }   /* the raceme is drawn here by loader-scene.js */
.ldBar i { display: none; }
#loadmsg { min-height: 1.4em; font-size: 13px; letter-spacing: 0.16em; color: #6d5d82; }
#intro #go { pointer-events: auto; margin-top: 8px; opacity: 0; transform: translateY(6px); transition: opacity .8s, transform .8s; background: transparent; color: #3a2f45; border: 1px solid #a58bcf; padding: 10px 34px 10px 40px; }
#intro #go:hover { background: rgba(201, 187, 221, 0.25); }
#intro.ready #go { opacity: 1; transform: none; }
/* (CC 11/05) phones and tablets: the title page with one line in place of the loading text and the button */
.ldTiming { position: absolute; left: 12px; bottom: 10px; margin: 0; font: 11px/1.45 ui-monospace, Menlo, monospace; color: rgba(58, 47, 69, 0.6); pointer-events: none; white-space: pre; text-align: left; }
.nophone .ldTiming { display: none; }
.ldPhone { display: none; margin: 4px 0 0; font-size: 15px; line-height: 1.6; color: #5b4d6b; max-width: 26em; text-wrap: balance; }
.nophone .ldPhone { display: block; }
.nophone #loadmsg, .nophone #go { display: none; }
@media (max-width: 520px) { .ldText h1 { font-size: 66px; } .ldText .ldSub { font-size: 17px; } .ldBar { width: 240px; height: 78px; } }
@media (prefers-reduced-motion: reduce) { .ldText h1::before { animation: none; } }

/* Cards */
.overlay { position: fixed; inset: 0; display: grid; place-items: center; background: rgba(20, 14, 26, 0.35); padding: 16px; }
.card { width: min(420px, 100%); padding: 30px 32px 26px; text-align: left; }
.card h2 { margin: 0 0 4px; font: 400 30px/1.2 var(--font-display); letter-spacing: 0.12em; color: var(--ink); text-wrap: balance; }
.card .en { margin: 0 0 16px; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--wisteria); }
.card p { margin: 0 0 12px; font-size: 15px; line-height: 1.75; letter-spacing: 0.04em; color: var(--ink); }
.card dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; margin: 6px 0 20px; font-size: 14px; }
.card dt { color: var(--ink-soft); }
.card dd { margin: 0; font-variant-numeric: tabular-nums; }
/* step 129: the end card over the island seen from above (dimmed only a little), two ways on */
#done { background: rgba(20, 14, 26, 0.12); }
#done .row { display: flex; flex-wrap: wrap; gap: 12px; justify-content: flex-end; }
.btn { font: 400 17px var(--font-display); letter-spacing: 0.3em; color: #2a2233; background: var(--wisteria); border: 0; border-radius: 2px; padding: 10px 26px 10px 30px; cursor: pointer; }
.btn:hover { background: var(--wisteria-hi); }
.btn:disabled { opacity: .55; cursor: progress; }
.btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.btn.small { font-size: 14px; letter-spacing: 0.14em; padding: 5px 14px; }

/* 接住好运 and the other mini-games */
@font-face { font-family: "MG Brush"; src: url("ui/mg/brush.woff2") format("woff2"); font-display: block; }   /* 马善政, cut to the mini-games' own words (titles, cards, +3) */
:is(#mg, #photo) { z-index: 20; }
.mgbox { position: relative; width: min(440px, 100%); }
.mgpaper { padding: 14px 16px; display: grid; gap: 10px; }
.mghead { display: flex; align-items: baseline; gap: 12px; }
.mgtitles { flex: 1; display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.mghead h2 { margin: 0; font: 400 24px/1.1 var(--font-display); letter-spacing: 0.12em; color: var(--ink); }
.mghead .mgsub { font-size: 12px; letter-spacing: 0.1em; color: var(--wisteria); }
.mghead .x { border: 0; background: none; font: 400 22px/1 var(--font-body); color: var(--ink-soft); cursor: pointer; padding: 0 4px; }
.mghead .x:focus-visible { outline: 2px solid var(--wisteria); border-radius: 4px; }
.mgbars { display: grid; grid-template-columns: 1fr auto; gap: 6px 12px; align-items: center; font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.mgbars .bar { height: 4px; border-radius: 99px; background: rgba(201, 187, 221, 0.2); overflow: hidden; }
.mgbars .bar i { display: block; height: 100%; width: 0; background: var(--wisteria); border-radius: inherit; transition: width .15s; }
.mgbars .bar.time i { background: rgba(243, 238, 232, 0.75); transition: none; }
.mgbars .bar.time.hot i { background: var(--hot); }
.mgbars b { color: var(--ink); font-weight: 500; }
.mgwrap { position: relative; width: min(100%, calc(min(60vh, 520px) * 0.75)); aspect-ratio: 3 / 4; max-width: 100%; margin: 0 auto; border-radius: 2px; overflow: hidden; border: 1px solid var(--line); touch-action: none; }
.mgwrap canvas { display: block; width: 100%; height: 100%; cursor: ew-resize; transition: filter 1.4s ease, opacity 1.4s ease; }
.mgcard { position: absolute; inset: 0; display: grid; place-content: center; gap: 12px; padding: 18px; text-align: center; background: rgba(30, 22, 30, 0.88); }
.mgcard h3 { margin: 0; font: 400 26px/1.2 var(--font-display); letter-spacing: 0.12em; color: var(--ink); }
.mgcard p { margin: 0; font-size: 14px; line-height: 1.7; color: var(--ink); }
.mgcard .legend { display: grid; grid-template-columns: auto auto; justify-content: center; gap: 6px 14px; font-size: 13.5px; text-align: left; align-items: center; }
.mgcard .legend span:nth-child(even) { font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.mgcard .dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-right: 6px; vertical-align: -1px; }
.mgcard .legend img { width: 22px; height: 22px; object-fit: contain; margin-right: 6px; vertical-align: -6px; }
.mgcard .row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.mgcard .note { color: var(--ink-soft); font-size: 13px; }
.mgcard h3.feel { font-size: 22px; line-height: 1.4; max-width: 18em; justify-self: center; }
.mgcard .gain { font: 400 16px/1.4 var(--font-display); letter-spacing: 0.15em; }
.mgcard .stats { display: grid; grid-template-columns: auto auto; justify-content: center; gap: 2px 14px; margin: 0; font-size: 13.5px; font-variant-numeric: tabular-nums; }
.mgcard .stats dt { color: var(--ink-soft); text-align: right; }
.mgcard .stats dd { margin: 0; text-align: left; }
.mgfoot { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; }
.mghint { font-size: 12px; letter-spacing: 0.06em; color: var(--ink-soft); text-align: center; }
.mgroll, .mgrace, .mgseal { display: none; }
:is(#mg, #photo).strip { background: none; align-items: end; pointer-events: none; padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 12px); }
:is(#mg, #photo).strip .mgbox { pointer-events: auto; width: min(420px, 100%); }
:is(#mg, #photo).strip .mgpaper { padding: 8px 12px; gap: 6px; }

/* 画卷 (step 116, the mini-game art plan; 116c, CC: plainer, more refined): every game but the 站桩 strip is a hanging scroll —
   a band of quiet silk mounting round rice paper, a gold hairline between them, two bamboo rollers; the title in brush script,
   progress a row of wisteria florets opening on a hairline, the time a line of small text, a thin round close button like the
   game's own; cards are paper, the win stamped with a seal */
:is(#mg, #photo) { --mg-ink: #3a2f45; --mg-ink-soft: rgba(58, 47, 69, 0.56); --mg-paper: #f7f3ec; --mg-silk: #e6e0e5; --mg-gilt: rgba(178, 146, 92, 0.45); --mg-lilac: #9a78e0; }
:is(#mg, #photo):not(.strip) {
  background: none; backdrop-filter: saturate(0.5) blur(3px); -webkit-backdrop-filter: saturate(0.5) blur(3px); }
/* step 118 (CC): not a flat dark veil: the game behind loses its colour and focus, and darkens only softly towards the edges */
:is(#mg, #photo):not(.strip)::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 75% 70% at 50% 48%, rgba(30, 22, 36, 0) 35%, rgba(30, 22, 36, 0.34) 100%); }
:is(#mg, #photo):not(.strip) .mgbox { width: min(460px, 100%); padding: 12px 0; }
:is(#mg, #photo):not(.strip) .mgroll { display: block; position: absolute; left: -30px; right: -30px; height: 26px; background: url("ui/mg/scroll_roller.webp") center / 100% 100% no-repeat; z-index: 2; pointer-events: none;
  filter: drop-shadow(0 3px 4px rgba(40, 28, 40, 0.28)); }
:is(#mg, #photo):not(.strip) .mgroll.top { top: 0; } :is(#mg, #photo):not(.strip) .mgroll.bottom { bottom: 0; }
:is(#mg, #photo) .mgpaper { position: relative; color: var(--mg-ink); border: 0; border-radius: 0; backdrop-filter: none; -webkit-backdrop-filter: none; padding: 30px 30px 22px; gap: 14px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.45 0 0 0 0 0.38 0 0 0 0 0.3 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E"),
    var(--mg-paper);
  box-shadow: inset 0 0 0 7px var(--mg-silk), inset 0 0 0 7.5px var(--mg-gilt), 0 22px 60px rgba(30, 20, 34, 0.26), 0 2px 8px rgba(30, 20, 34, 0.1); }
/* 展开 / 收起: the paper unrolls from the middle with the rollers riding its edges, then the picture and words come up through it;
   closing runs it backwards (core.js adds .mgclose and hides the overlay once it has rolled up) */
:is(#mg, #photo):not([hidden]):not(.strip) { animation: mgDim 0.6s ease both; }
:is(#mg, #photo):not([hidden]):not(.strip) .mgbox { animation: mgPop 0.9s linear 0.05s both; }
:is(#mg, #photo):not([hidden]):not(.strip) .mgpaper { animation: mgUnroll 0.9s linear 0.05s both; }
:is(#mg, #photo):not([hidden]):not(.strip) .mgroll.top { animation: mgRollTop 0.9s linear 0.05s both, mgSwish 0.9s linear 0.05s both; }
:is(#mg, #photo):not([hidden]):not(.strip) .mgroll.bottom { animation: mgRollBottom 0.9s linear 0.05s both, mgSwish 0.9s linear 0.05s both; }
:is(#mg, #photo):not([hidden]):not(.strip) .mgpaper > * { animation: mgInkIn 0.5s ease 0.38s both; }
:is(#mg, #photo).mgclose:not(.strip) { animation: mgDim 0.45s ease 0.55s reverse both; }
:is(#mg, #photo).mgclose:not(.strip) .mgpaper > * { animation: mgInkOut 0.2s ease both; }
:is(#mg, #photo).mgclose:not(.strip) .mgpaper { animation: mgRollUp 0.65s linear 0.1s both; }
:is(#mg, #photo).mgclose:not(.strip) .mgroll.top { animation: mgRollTopUp 0.65s linear 0.1s both, mgSwishUp 0.65s linear 0.1s both, mgFade 0.25s ease 0.78s both; }
:is(#mg, #photo).mgclose:not(.strip) .mgroll.bottom { animation: mgRollBottomUp 0.65s linear 0.1s both, mgSwishUp 0.65s linear 0.1s both, mgFade 0.25s ease 0.78s both; }
@keyframes mgDim { from { backdrop-filter: saturate(1) blur(0); -webkit-backdrop-filter: saturate(1) blur(0); } to { backdrop-filter: saturate(0.5) blur(3px); -webkit-backdrop-filter: saturate(0.5) blur(3px); } }
:is(#mg, #photo):not([hidden]):not(.strip)::before { animation: mgFadeIn 0.6s ease both; }
:is(#mg, #photo).mgclose:not(.strip)::before { animation: mgFade 0.45s ease 0.5s both; }
@keyframes mgFadeIn { from { opacity: 0; } }
/* step 119b (CC): inertia you can feel, a flick (唰) rather than a glide. Opening: a tiny pinch, then the rollers whip apart,
   fly past the ends, bounce back and settle, blurred while they move fast. Closing: a held pull outwards, a snap shut, a knock that
   bounces them apart, then rest. Each segment carries its own easing (the animations themselves run linear) */
@keyframes mgPop { 0% { transform: scale(0.97); animation-timing-function: cubic-bezier(.15, .65, .3, 1); } 36% { transform: scale(1.012); animation-timing-function: ease-in-out; } 60% { transform: scale(0.997); animation-timing-function: ease-in-out; } 100% { transform: none; } }
@keyframes mgUnroll { 0%, 8% { clip-path: inset(50% 0 50% 0); animation-timing-function: cubic-bezier(.15, .65, .3, 1); } 36% { clip-path: inset(0 0 0 0); animation-timing-function: ease-in-out; }
  56% { clip-path: inset(6px 0 6px 0); animation-timing-function: ease-in-out; } 74%, 100% { clip-path: inset(0 0 0 0); } }
@keyframes mgRollTop { 0% { top: calc(50% - 25px); animation-timing-function: ease-in; } 8% { top: calc(50% - 23px); animation-timing-function: cubic-bezier(.15, .65, .3, 1); }
  36% { top: -12px; animation-timing-function: ease-in-out; } 56% { top: 5px; animation-timing-function: ease-in-out; } 74% { top: -3px; animation-timing-function: ease-in-out; } 100% { top: 0; } }
@keyframes mgRollBottom { 0% { bottom: calc(50% - 25px); animation-timing-function: ease-in; } 8% { bottom: calc(50% - 23px); animation-timing-function: cubic-bezier(.15, .65, .3, 1); }
  36% { bottom: -12px; animation-timing-function: ease-in-out; } 56% { bottom: 5px; animation-timing-function: ease-in-out; } 74% { bottom: -3px; animation-timing-function: ease-in-out; } 100% { bottom: 0; } }
@keyframes mgSwish { 0%, 8% { filter: none; } 18% { filter: blur(2.2px); } 34%, 100% { filter: none; } }
@keyframes mgRollUp { 0%, 30% { clip-path: inset(0 0 0 0); animation-timing-function: cubic-bezier(.8, 0, 1, .6); } 62% { clip-path: inset(50% 0 50% 0); animation-timing-function: ease-out; }
  76% { clip-path: inset(calc(50% - 9px) 0 calc(50% - 9px) 0); animation-timing-function: ease-in; } 88%, 100% { clip-path: inset(50% 0 50% 0); } }
@keyframes mgRollTopUp { 0% { top: 0; animation-timing-function: cubic-bezier(.25, .1, .3, 1); } 30% { top: -10px; animation-timing-function: cubic-bezier(.8, 0, 1, .6); }
  62% { top: calc(50% - 25px); animation-timing-function: ease-out; } 76% { top: calc(50% - 34px); animation-timing-function: ease-in; } 88% { top: calc(50% - 25px); animation-timing-function: ease-out; }
  94% { top: calc(50% - 15px); animation-timing-function: ease-in; } 100% { top: calc(50% - 25px); } }
@keyframes mgRollBottomUp { 0% { bottom: 0; animation-timing-function: cubic-bezier(.25, .1, .3, 1); } 30% { bottom: -10px; animation-timing-function: cubic-bezier(.8, 0, 1, .6); }
  62% { bottom: calc(50% - 25px); animation-timing-function: ease-out; } 76% { bottom: calc(50% - 34px); animation-timing-function: ease-in; } 88% { bottom: calc(50% - 25px); animation-timing-function: ease-out; }
  94% { bottom: calc(50% - 15px); animation-timing-function: ease-in; } 100% { bottom: calc(50% - 25px); } }
@keyframes mgSwishUp { 0%, 36% { filter: none; } 52% { filter: blur(2.2px); } 62%, 100% { filter: none; } }
@keyframes mgInkIn { from { opacity: 0; filter: blur(3px); } to { opacity: 1; filter: none; } }
@keyframes mgInkOut { to { opacity: 0; filter: blur(2px); } }
@keyframes mgFade { to { opacity: 0; } }
:is(#mg, #photo) .mghead { align-items: center; }
:is(#mg, #photo) .mgtitles { flex-direction: column; align-items: flex-start; gap: 4px; }
:is(#mg, #photo) .mghead h2 { font: 400 30px/1.05 "MG Brush", var(--font-display); letter-spacing: 0.12em; color: var(--mg-ink); }
:is(#mg, #photo) .mghead .mgsub { font: 400 11px var(--font-display); letter-spacing: 0.42em; color: var(--mg-ink-soft); }
:is(#mg, #photo) .mghead .x { width: 32px; height: 32px; display: grid; place-items: center; padding: 0; border-radius: 50%; color: var(--mg-ink-soft);
  border: 1px solid rgba(58, 47, 69, 0.22); background: rgba(255, 255, 255, 0.18); transition: border-color .25s, color .25s, background .25s; }
:is(#mg, #photo) .mghead .x:hover { border-color: var(--mg-lilac); color: var(--mg-ink); background: rgba(201, 187, 221, 0.18); }
:is(#mg, #photo) .mghead .x:focus-visible { outline: 1px solid var(--mg-lilac); outline-offset: 2px; }
/* progress: florets opening one by one along a gilt hairline (core.js adds them); time: small text beside the count */
:is(#mg, #photo) .mgbars { grid-template-columns: 1fr auto; color: var(--mg-ink-soft); font: 400 12.5px var(--font-display); letter-spacing: 0.14em; }
:is(#mg, #photo) .mgbars .bar { display: none; }
:is(#mg, #photo) .mgbars { grid-template-rows: auto auto; row-gap: 1px; }
:is(#mg, #photo) .mgbars > span:not(.mgtime) { grid-row: 1; grid-column: 2; text-align: right; }
:is(#mg, #photo) .mgbars .mgtime { grid-row: 2; grid-column: 2; text-align: right; font-size: 11.5px; }
:is(#mg, #photo) .mgbars b { color: var(--mg-ink); font-weight: 400; font-variant-numeric: tabular-nums; }
:is(#mg, #photo) .mgrace { display: block; position: relative; height: 30px; grid-row: 1 / span 2; grid-column: 1; align-self: center; }
.mgrace::before { content: ""; position: absolute; left: 0; right: 4px; top: 50%; height: 1px; background: linear-gradient(90deg, var(--mg-gilt), rgba(178, 146, 92, 0.12)); }
.mgrace .stem { display: none; }
.mgrace .fl { position: absolute; top: 3px; width: 24px; height: 24px; object-fit: contain; transform: scale(0.2) rotate(-30deg); opacity: 0; transition: transform .5s cubic-bezier(.3, 1.6, .5, 1), opacity .4s; }
.mgrace .fl.on { transform: scale(1) rotate(0); opacity: 1; }
:is(#mg, #photo) .mgwrap { border: 0; border-radius: 1px; box-shadow: 0 0 0 0.5px rgba(58, 47, 69, 0.16); }
:is(#mg, #photo) .mgwrap.washed canvas { filter: saturate(0.25) brightness(1.18) blur(0.6px); opacity: 0.75; }
:is(#mg, #photo) .mgcard { background: rgba(248, 245, 239, 0.9); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); color: var(--mg-ink); gap: 14px; }
:is(#mg, #photo) .mgcard h3 { font: 400 34px/1.15 "MG Brush", var(--font-display); letter-spacing: 0.1em; color: var(--mg-ink); }
:is(#mg, #photo) .mgcard p { color: var(--mg-ink); font-family: var(--font-display); font-size: 15px; }
:is(#mg, #photo) .mgcard .note, :is(#mg, #photo) .mgcard .legend span:nth-child(even) { color: var(--mg-ink-soft); }
:is(#mg, #photo) .mgcard .stats { font-family: var(--font-display); font-size: 14px; gap: 4px 14px; }   /* one face with the card (CC 10/30) */
:is(#mg, #photo) .mgcard .stats dt { color: var(--mg-ink-soft); }
/* the main button: translucent jade-white paper; on hover a drop of pale ink spreads under the word */
:is(#mg, #photo) .mgcard .btn { position: relative; isolation: isolate; overflow: hidden; font: 400 19px "MG Brush", var(--font-display); letter-spacing: 0.32em; color: var(--mg-ink); padding: 9px 28px 9px 34px; border-radius: 999px;
  border: 0.75px solid rgba(58, 47, 69, 0.2); background: linear-gradient(180deg, rgba(255, 255, 255, 0.62), rgba(240, 244, 238, 0.4));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), 0 3px 14px rgba(58, 47, 69, 0.08); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); transition: border-color .4s, box-shadow .4s; }
:is(#mg, #photo) .mgcard .btn::before { content: ""; position: absolute; left: 50%; top: 55%; width: 120%; aspect-ratio: 1; z-index: -1; border-radius: 50%; transform: translate(-50%, -50%) scale(0.05); opacity: 0;
  background: radial-gradient(circle, rgba(74, 58, 98, 0.2) 0%, rgba(110, 88, 150, 0.1) 40%, rgba(110, 88, 150, 0) 68%); filter: blur(2px); transition: transform .9s cubic-bezier(.2, .7, .2, 1), opacity .6s; }
:is(#mg, #photo) .mgcard .btn:hover { border-color: rgba(58, 47, 69, 0.32); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), 0 4px 18px rgba(58, 47, 69, 0.12); background: linear-gradient(180deg, rgba(255, 255, 255, 0.62), rgba(240, 244, 238, 0.4)); }
:is(#mg, #photo) .mgcard .btn:hover::before { transform: translate(-50%, -50%) scale(1); opacity: 1; }
:is(#mg, #photo) .mgcard .btn.ghost { font-size: 15px; letter-spacing: 0.24em; color: var(--mg-ink-soft); border-color: transparent; background: none; box-shadow: none; backdrop-filter: none; }
:is(#mg, #photo) .mgcard .btn.ghost:hover { border-color: transparent; color: var(--mg-ink); }
:is(#mg, #photo) .mgfoot .btn.ghost { font-size: 12px; letter-spacing: 0.16em; padding: 5px 14px; color: var(--mg-ink-soft); background: rgba(255, 255, 255, 0.35); border: 0.5px solid rgba(58, 47, 69, 0.22); box-shadow: none; }
:is(#mg, #photo) .mgfoot .btn.ghost:hover { color: var(--mg-ink); border-color: rgba(58, 47, 69, 0.4); }
:is(#mg, #photo) .mgcard .btn:focus-visible { outline: 0.5px solid rgba(132, 108, 160, 0.45); outline-offset: 4px; }
:is(#mg, #photo) .mgseal { display: block; position: absolute; right: 22px; top: 18px; width: 60px; height: 60px; object-fit: contain; mix-blend-mode: multiply;
  animation: mgStamp 0.5s cubic-bezier(.5, 0, .7, 1.4) 0.15s both; }
@keyframes mgStamp { from { transform: scale(2.4) rotate(-14deg); opacity: 0; } 70% { opacity: 1; } to { transform: scale(1) rotate(-7deg); opacity: 0.9; } }
:is(#mg, #photo) .mghint { color: var(--mg-ink-soft); font-family: var(--font-display); letter-spacing: 0.12em; }
/* 站桩 (step 120, CC: the same design for every game; 121, after CC's reference): a small hanging scroll in the lower right,
   the same rollers, unroll and roll-up; the scene stays clear and in colour so 小白 and her are both in view */
:is(#mg, #photo).strip .mgbox { width: min(400px, calc(100% - 64px)); padding: 12px 0; margin-left: auto; margin-right: max(40px, 5vw); }
:is(#mg, #photo).strip .mgroll { display: block; position: absolute; left: -26px; right: -26px; height: 22px; background: url("ui/mg/scroll_roller.webp") center / 100% 100% no-repeat; z-index: 2; pointer-events: none;
  filter: drop-shadow(0 3px 4px rgba(40, 28, 40, 0.28)); }
:is(#mg, #photo).strip .mgroll.top { top: 0; } :is(#mg, #photo).strip .mgroll.bottom { bottom: 0; }
:is(#mg, #photo).strip .mgpaper { padding: 22px 24px 16px; gap: 8px; }
:is(#mg, #photo).strip .mghead h2 { font-size: 24px; } :is(#mg, #photo).strip .mghead .mgsub { font-size: 10px; letter-spacing: 0.32em; }
:is(#mg, #photo).strip .mghead .x { width: 26px; height: 26px; }
:is(#mg, #photo).strip .mgbars { font-size: 11.5px; }
:is(#mg, #photo).strip .mgwrap { box-shadow: none; }
:is(#mg, #photo)[data-game="spot"] .mgwrap { box-shadow: none; }   /* step 128 (CC): 井中倒影 painted straight onto the scroll, no field frame */
:is(#mg, #photo)[data-game=soup] .mgcard h3.feel { font-size: 27px; letter-spacing: 0.04em; white-space: nowrap; max-width: none; }   /* (CC 10/31) 七味入汤's endings: two lines, each kept whole */
:is(#mg, #photo).strip .mgcard h3 { font-size: 24px; } :is(#mg, #photo).strip .mgcard p { font-size: 13px; } :is(#mg, #photo).strip .mgcard { gap: 8px; padding: 10px; }
:is(#mg, #photo).strip .mgcard .btn { font-size: 16px; padding: 7px 26px 7px 32px; }
:is(#mg, #photo).strip .mgseal { width: 44px; height: 44px; right: 12px; top: 8px; }
:is(#mg, #photo).strip .mgfoot { display: none; }
/* 站桩 (CC 10/30): the strip as wide as the other games' scrolls, in the middle, low over the recipe band; no dimming, so the
   two of them standing are seen while you breathe */
:is(#mg, #photo).strip[data-game="stance"] { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 92px); }
:is(#mg, #photo).strip[data-game="stance"] .mgbox { width: min(500px, calc(100% - 64px)); margin-left: auto; margin-right: auto; }
:is(#mg, #photo).strip:not([hidden]) .mgbox { animation: mgPop 0.9s linear 0.05s both; }
:is(#mg, #photo).strip:not([hidden]) .mgpaper { animation: mgUnroll 0.9s linear 0.05s both; }
:is(#mg, #photo).strip:not([hidden]) .mgroll.top { animation: mgRollTop 0.9s linear 0.05s both, mgSwish 0.9s linear 0.05s both; }
:is(#mg, #photo).strip:not([hidden]) .mgroll.bottom { animation: mgRollBottom 0.9s linear 0.05s both, mgSwish 0.9s linear 0.05s both; }
:is(#mg, #photo).strip:not([hidden]) .mgpaper > * { animation: mgInkIn 0.5s ease 0.38s both; }
:is(#mg, #photo).strip.mgclose .mgpaper > * { animation: mgInkOut 0.2s ease both; }
:is(#mg, #photo).strip.mgclose .mgpaper { animation: mgRollUp 0.65s linear 0.1s both; }
:is(#mg, #photo).strip.mgclose .mgroll.top { animation: mgRollTopUp 0.65s linear 0.1s both, mgSwishUp 0.65s linear 0.1s both, mgFade 0.25s ease 0.78s both; }
:is(#mg, #photo).strip.mgclose .mgroll.bottom { animation: mgRollBottomUp 0.65s linear 0.1s both, mgSwishUp 0.65s linear 0.1s both, mgFade 0.25s ease 0.78s both; }
/* step 121 (CC's reference: an indie game's painted scroll, not a web dialog). The paper has soft deckled sides and a few
   dried-pigment blooms instead of a ruled silk band; wisteria from the top roller hangs over both upper corners; the buttons are
   washes of colour with a rough, dried edge. (Placeholders from the art we have, until the painted paper, roller, corners and
   tassels come in.) */
:is(#mg, #photo) .mgbox { filter: drop-shadow(0 18px 34px rgba(30, 20, 34, 0.22)) drop-shadow(0 2px 4px rgba(30, 20, 34, 0.08)); }
:is(#mg, #photo) .mgpaper { box-shadow: none; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 520' preserveAspectRatio='none'%3E%3Cfilter id='f' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.09' numOctaves='2' seed='7'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='4'/%3E%3C/filter%3E%3Crect x='5' y='5' width='390' height='510' fill='white' filter='url(%23f)'/%3E%3C/svg%3E") center / 100% 100% no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 520' preserveAspectRatio='none'%3E%3Cfilter id='f' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.09' numOctaves='2' seed='7'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='4'/%3E%3C/filter%3E%3Crect x='5' y='5' width='390' height='510' fill='white' filter='url(%23f)'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  background:
    radial-gradient(ellipse 38% 26% at 12% 90%, rgba(206, 186, 150, 0.16), rgba(206, 186, 150, 0) 70%),
    radial-gradient(ellipse 34% 22% at 90% 10%, rgba(186, 168, 214, 0.16), rgba(186, 168, 214, 0) 70%),
    radial-gradient(ellipse 60% 40% at 50% 45%, rgba(255, 253, 248, 0.5), rgba(255, 253, 248, 0) 80%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.45 0 0 0 0 0.38 0 0 0 0 0.3 0 0 0 0.07 0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E"),
    linear-gradient(180deg, #f8f4ec, #f3eee4); }
:is(#mg, #photo) .mgbox::before, :is(#mg, #photo) .mgbox::after { content: ""; position: absolute; top: 6px; width: 80px; height: 110px; z-index: 3; pointer-events: none;
  background: url("ui/mg/wisteria_raceme.webp") 0 0 / 32px auto no-repeat, url("ui/mg/wisteria_raceme.webp") 28px 4px / 24px auto no-repeat, url("ui/mg/wisteria_raceme.webp") 50px 6px / 17px auto no-repeat;
  filter: drop-shadow(0 3px 3px rgba(60, 40, 80, 0.18)); transform-origin: 50% 0; }
:is(#mg, #photo) .mgbox::before { left: -42px; }
:is(#mg, #photo) .mgbox::after { right: -42px; transform: scaleX(-1); }
:is(#mg, #photo).strip .mgbox::before, :is(#mg, #photo).strip .mgbox::after { scale: 0.7; }
:is(#mg, #photo):not([hidden]) .mgbox::before, :is(#mg, #photo):not([hidden]) .mgbox::after { animation: mgSway 5.5s ease-in-out 1s infinite alternate, mgFadeIn 0.4s ease 0.5s both; }
@keyframes mgSway { from { rotate: -1.6deg; } to { rotate: 1.6deg; } }
:is(#mg, #photo).mgclose .mgbox::before, :is(#mg, #photo).mgclose .mgbox::after { opacity: 0; transition: opacity .2s; }
:is(#mg, #photo) .mgcard .btn { border: 0; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; padding: 11px 34px 11px 40px;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cfilter id='f' x='-5%25' y='-10%25' width='110%25' height='120%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.07' numOctaves='2' seed='3'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='5'/%3E%3C/filter%3E%3Crect x='4' y='4' width='192' height='52' rx='26' fill='white' filter='url(%23f)'/%3E%3C/svg%3E") center / 100% 100% no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cfilter id='f' x='-5%25' y='-10%25' width='110%25' height='120%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.07' numOctaves='2' seed='3'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='5'/%3E%3C/filter%3E%3Crect x='4' y='4' width='192' height='52' rx='26' fill='white' filter='url(%23f)'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  background: radial-gradient(ellipse 70% 90% at 50% 50%, rgba(214, 198, 238, 0.55), rgba(178, 150, 222, 0.62) 78%, rgba(150, 120, 205, 0.75) 100%); }
:is(#mg, #photo) .mgcard .btn:hover { border: 0; box-shadow: none; background: radial-gradient(ellipse 70% 90% at 50% 50%, rgba(220, 205, 242, 0.65), rgba(168, 138, 216, 0.7) 78%, rgba(140, 108, 198, 0.82) 100%); }
:is(#mg, #photo) .mgcard .btn.ghost, :is(#mg, #photo) .mgfoot .btn.ghost { border: 0; color: var(--mg-ink-soft); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cfilter id='f' x='-5%25' y='-10%25' width='110%25' height='120%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.07' numOctaves='2' seed='3'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='5'/%3E%3C/filter%3E%3Crect x='4' y='4' width='192' height='52' rx='26' fill='white' filter='url(%23f)'/%3E%3C/svg%3E") center / 100% 100% no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cfilter id='f' x='-5%25' y='-10%25' width='110%25' height='120%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.07' numOctaves='2' seed='3'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='5'/%3E%3C/filter%3E%3Crect x='4' y='4' width='192' height='52' rx='26' fill='white' filter='url(%23f)'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  background: radial-gradient(ellipse 75% 95% at 50% 50%, rgba(255, 252, 245, 0.9), rgba(236, 228, 214, 0.9) 80%, rgba(196, 178, 218, 0.7) 100%); }
:is(#mg, #photo) .mgfoot .btn.ghost { padding: 6px 18px; }
:is(#mg, #photo) .mghead .x { border: 0; color: var(--mg-ink); background: radial-gradient(circle, rgba(255, 252, 245, 0.95) 48%, rgba(178, 150, 222, 0.55) 100%); box-shadow: 0 0 0 0.75px rgba(120, 94, 170, 0.35), 0 1px 4px rgba(58, 47, 69, 0.14); }
:is(#mg, #photo) .mghead .x:hover { background: radial-gradient(circle, rgba(246, 240, 252, 0.95) 50%, rgba(178, 150, 222, 0.75) 100%); }
/* step 122: CC's paintings in place of the stand-ins — the deckled rice paper, the celadon roller with its vine and lotus-bud
   ends, lilac tassels from the top roller, wisteria sprays over the upper corners and one rising at the lower right, and
   painted buttons (a lilac wash, an ivory one, a paper disc for close). The rollers are taller now, so the box makes room */
:is(#mg, #photo) .mgpaper { -webkit-mask: none; mask: none; background: url("ui/mg/paper.webp") center / 100% 100% no-repeat; padding-left: 40px; padding-right: 40px; }
:is(#mg, #photo):not(.strip) .mgbox, :is(#mg, #photo).strip .mgbox { padding: 25px 0; }
:is(#mg, #photo):not(.strip) .mgroll, :is(#mg, #photo).strip .mgroll { left: -38px; right: -38px; height: 50px; background: url("ui/mg/roller.webp") center / 100% 100% no-repeat; filter: drop-shadow(0 4px 4px rgba(40, 28, 40, 0.22)); }
:is(#mg, #photo) .mgroll.top::before, :is(#mg, #photo) .mgroll.top::after { content: ""; position: absolute; top: 36px; width: 22px; height: 74px; background: url("ui/mg/tassel.webp") center top / contain no-repeat;
  transform-origin: 50% 0; animation: mgTassel 3.6s ease-in-out infinite alternate; }
:is(#mg, #photo) .mgroll.top::before { left: 10px; } :is(#mg, #photo) .mgroll.top::after { right: 10px; animation-delay: -1.4s; }
@keyframes mgTassel { from { rotate: -3deg; } to { rotate: 3deg; } }
/* step 125: CC — no wisteria sprays at the sides, and the step 121 wash buttons back (they read better than the painted ones) */
:is(#mg, #photo) .mgbox::before, :is(#mg, #photo) .mgbox::after { content: none; }
:is(#mg, #photo):not(.strip) .mghead { padding: 0 34px 0 22px; }
:is(#mg, #photo):not(.strip) .mgfoot { padding-right: 30px; }
@media (prefers-reduced-motion: reduce) { :is(#mg, #photo), :is(#mg, #photo) .mgpaper, :is(#mg, #photo) .mgpaper > *, :is(#mg, #photo) .mgroll, :is(#mg, #photo) .mgseal, :is(#mg, #photo) .mgbox, :is(#mg, #photo) .mgbox::before, :is(#mg, #photo) .mgbox::after, :is(#mg, #photo) .mgroll.top::before, :is(#mg, #photo) .mgroll.top::after { animation: none !important; } }

/* Cooking panel */
#cook { pointer-events: auto; padding: 14px 18px; display: grid; gap: 10px; width: min(600px, 100%); }
#cook .cook-title { font: 400 20px var(--font-display); letter-spacing: 0.14em; color: var(--ink); text-align: center; }
#cook .chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
#cook .chip { font: 400 14px var(--font-body); letter-spacing: 0.06em; color: var(--ink); background: rgba(243, 238, 232, 0.06); border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; }
#cook .chip:hover { border-color: var(--wisteria); }
#cook .chip img { width: 26px; height: 26px; margin: -4px 0 -4px -6px; }
#cook .chip:disabled { opacity: .35; cursor: default; }
#cook .chip:focus-visible { outline: 2px solid var(--wisteria); }
#cook .stir { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 12px; font-size: 13px; font-variant-numeric: tabular-nums; }
#cook .stir .bar { height: 4px; border-radius: 99px; background: rgba(201, 187, 221, 0.2); overflow: hidden; }
#cook .stir .bar i { display: block; height: 100%; width: 0; background: var(--wisteria); }
#stirBtn { touch-action: none; user-select: none; -webkit-user-select: none; }

body.in-scene #joy, body.in-scene #sprint, body.in-scene #stroll { visibility: hidden; }
#grassDbg { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 96px); right: calc(env(safe-area-inset-right, 0px) + var(--gap)); width: 168px; padding: 6px 8px; font: 11px/1.5 ui-monospace, Menlo, monospace; color: var(--ink); background: var(--veil); border: 1px solid var(--line); border-radius: 2px; white-space: pre; font-variant-numeric: tabular-nums; }

@media (max-width: 1180px) { #recipe li .trait { display: none; } #recipe { gap: 22px; } #recipe ol { gap: 14px; padding: 0 22px; } }
@media (max-width: 900px) { #recipe .head, #recipe .stats { display: none; } #recipe ol { border: 0; padding: 0; } #recipe li .txt { display: none; } }
@media (max-width: 520px) {
  :root { --band: 64px; }
  #recipe { padding-left: 8px; padding-right: 8px; }
  #recipe ol { gap: 4px; }
  #recipe li .pic { width: 42px; height: 42px; }
  #goalbar { top: calc(env(safe-area-inset-top, 0px) + 16px); left: calc(env(safe-area-inset-left, 0px) + 16px); }
  #goal { font-size: 17px; }
  #line { padding: 32px 22px 16px; } #line .say { font-size: 18px; }
}
@media (prefers-reduced-motion: reduce) { #line { transition: none; } }

/* 原料标记 (guide.js marks, step 115b): a thin ivory ring with the ingredient's outline, pinned over it on the screen */
.gmarks { position: fixed; inset: 0; z-index: 4; pointer-events: none; overflow: hidden; }
.gmark { position: absolute; left: 0; top: 0; width: 54px; height: 54px; border-radius: 50%; display: none;
  border: 1.5px solid rgba(250, 246, 238, 0.92); background: radial-gradient(circle, rgba(201, 182, 236, 0.28) 0%, rgba(201, 182, 236, 0.12) 62%, rgba(201, 182, 236, 0) 100%);
  box-shadow: 0 0 10px rgba(217, 198, 244, 0.55), inset 0 0 8px rgba(217, 198, 244, 0.35); will-change: transform, opacity; }
.gmark img { position: absolute; left: 50%; top: 50%; width: 36px; height: 36px; transform: translate(-50%, -50%);
  filter: brightness(0) invert(1) drop-shadow(0 0 3px rgba(190, 166, 232, 0.9)); opacity: 0.95; animation: gmarkBreathe 2.6s ease-in-out infinite; }
.gmark b { position: absolute; left: 50%; bottom: calc(100% + 5px); transform: translateX(-50%); white-space: nowrap; font-weight: 500; font-size: 14px; letter-spacing: 0.18em; padding-left: 0.18em;
  color: #faf6ee; text-shadow: 0 0 4px rgba(70, 48, 104, 0.85), 0 0 10px rgba(190, 166, 232, 0.8); }
.gpoint { position: absolute; left: 0; top: 0; width: 40px; height: 40px; display: none; will-change: transform, opacity; }
.gpoint img { position: absolute; left: 50%; top: 50%; width: 26px; height: 26px; transform: translate(-50%, -50%);
  filter: brightness(0) invert(1) drop-shadow(0 0 3px rgba(190, 166, 232, 0.9)); opacity: 0.95; animation: gmarkBreathe 2.6s ease-in-out infinite; }
.gpoint b { position: absolute; left: 50%; bottom: calc(100% + 2px); transform: translateX(-50%); white-space: nowrap; font-weight: 500; font-size: 13px; letter-spacing: 0.18em; padding-left: 0.18em;
  color: #faf6ee; text-shadow: 0 0 4px rgba(70, 48, 104, 0.85), 0 0 10px rgba(190, 166, 232, 0.8); }
.gpoint s { position: absolute; left: 50%; top: 50%; width: 0; height: 0; border-style: solid; border-width: 6px 0 6px 10px; border-color: transparent transparent transparent #faf6ee;
  filter: drop-shadow(0 0 3px rgba(190, 166, 232, 0.95)); }
@keyframes gmarkBreathe { 0%, 100% { opacity: 0.8; } 50% { opacity: 1; } }

/* 拍照 (CC 10/31): the flash, the photo card, the album */
#flash { position: fixed; inset: 0; z-index: 40; background: #fff; opacity: 0; pointer-events: none; }
#flash.go { animation: flash 0.85s ease-out; }
@keyframes flash { 0% { opacity: 0.95; } 100% { opacity: 0; } }
body.shooting #bottom, body.shooting #gear, body.shooting #snap, body.shooting #joy, body.shooting #sprint, body.shooting #stroll, body.shooting #toast, body.shooting #place { visibility: hidden; }
#photo { z-index: 30; }
#prompt svg.cam { flex: none; margin-right: -4px; }
#settings .photos { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 12px 0 0; }
#settings .photos .shot { padding: 0; border: 1px solid var(--line); border-radius: 2px; background: none; cursor: pointer; }
#settings .photos img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }

/* 留影 (CC 10/31): the photo card is a scroll like the mini-games' (the #mg rules above dress it too) */
#photo#photo .mgbox { width: min(700px, calc(100% - 60px)); }
#photo img { display: block; max-width: 100%; max-height: 56vh; width: auto; height: auto; margin: 0 auto; border-radius: 2px; box-shadow: 0 0 0 1px rgba(178, 146, 92, 0.35), 0 4px 14px rgba(58, 47, 69, 0.18); }
#photo#photo .mgcard { position: static; inset: auto; background: none; backdrop-filter: none; -webkit-backdrop-filter: none; padding: 0; gap: 6px; }
#photo#photo .mgcard .row { gap: 4px 6px; }
#photo#photo .mgcard .btn { font-size: 17px; padding: 9px 24px 9px 30px; }
#photo#photo .mgcard .note { margin: 0; font: 400 13px var(--font-display); letter-spacing: 0.08em; color: var(--mg-ink-soft); word-break: break-all; }
#photo#photo .mgcard .note:empty { display: none; }
@media (max-width: 520px) { #photo#photo .mgcard .btn { font-size: 15px; padding: 7px 16px 7px 20px; } }

/* 开场镜头 (CC 11/02): the HUD stays hidden during the opening shot and fades in as control comes back */
body.opening #goalbar, body.opening #recipe, body.opening #gear, body.opening #snap, body.opening #joy, body.opening #sprint, body.opening #stroll, body.opening #bottom { opacity: 0 !important; pointer-events: none !important; }
body.hud-in #goalbar, body.hud-in #recipe, body.hud-in #gear, body.hud-in #snap, body.hud-in #joy, body.hud-in #sprint, body.hud-in #stroll, body.hud-in #bottom { transition: opacity 1.4s ease !important; }

/* ==== English (CC 11/04, lang.js): Manrope throughout (CC: a modern, quiet sans, not an old-style serif), light for the big
   titles and place names, semibold for headings and names; the wide spacing the Chinese faces carry would pull English words apart, so it goes, with the padding that balanced it ==== */
html[lang="en"] { --font-display: "Manrope", system-ui, sans-serif; --font-body: "Manrope", system-ui, sans-serif; --font-name: "Manrope", system-ui, sans-serif; --font-mark: "Instrument Serif", Georgia, serif; }
html[lang="en"] body, html[lang="en"] body * { letter-spacing: normal !important; }
html[lang="en"] .ldText { --font-title: var(--font-name); }
html[lang="en"] .ldText h1 { font: italic 400 clamp(60px, 9.5vw, 112px)/1.05 var(--font-mark); padding-left: 0.07em; letter-spacing: 0.07em !important; }   /* CC 11/04: the word mark in Instrument Serif Italic, open (CC: 太挤, 再松一点) */
html[lang="en"] .ldText .ldSub { font: 500 20px/1.4 var(--font-title); padding-left: 0; text-wrap: balance; }
html[lang="en"] .ldIntro { max-width: 34em; text-wrap: balance; }
html[lang="en"] #place { font: 300 44px/1.15 var(--font-name); padding: 0 16px; letter-spacing: 0.02em !important; }
html[lang="en"] #place b { font: italic 400 56px/1.1 var(--font-mark); letter-spacing: 0 !important; }   /* the place names too (not the other cues) */
@media (max-width: 520px) { html[lang="en"] #place b { font-size: 40px; } }
html[lang="en"] #place small { font: 400 18px/1.45 var(--font-name); text-wrap: balance; }
html[lang="en"] #recipe h1, html[lang="en"] #settings h2, html[lang="en"] .card h2 { font-family: var(--font-name); font-weight: 600; }
html[lang="en"] #settings h3, html[lang="en"] #line .who { font-family: var(--font-name); font-weight: 600; font-size: 17px; }
html[lang="en"] .btn { padding-left: 26px; }
html[lang="en"] :is(#mg, #photo) :is(.mghead h2, .mgcard h3, .mgcard .btn) { font-family: var(--font-name); font-weight: 600; }
html[lang="en"] :is(#mg, #photo) .mgcard .btn { padding-left: 28px; }
html[lang="en"] #settings summary h3::before { content: "More ›"; }
html[lang="en"] #settings details[open] summary h3::before { content: "Less"; }
/* (CC 11/04) a light case hierarchy: the title in Title Case, subtitles and running text as written, and a few short labels in
   ALL CAPS: Manrope 500, tracked 0.12–0.2em by size (the eyebrow over the title, the start button, the minigames' sub-line and
   prize label, the ending's English line and its stat names). The Chinese pages are untouched */
html[lang="en"] .ldText h1::after { content: "An island to remember"; position: absolute; left: 0; right: 0; bottom: 100%; margin-bottom: 6px;
  font: 500 13px/1.2 var(--font-body); letter-spacing: 0.22em !important; text-indent: 0.22em; text-transform: uppercase; color: #6e5890; }   /* the eyebrow (::before is the title's glow) */
html[lang="en"] #intro #go { font: 500 14px/1.2 var(--font-body); letter-spacing: 0.16em !important; text-transform: uppercase; }
html[lang="en"] :is(#mg, #photo) .mghead .mgsub { font: 500 12px/1.3 var(--font-body); letter-spacing: 0.18em !important; text-transform: uppercase; }
html[lang="en"] .mgcard .gain { font: 500 14px/1.4 var(--font-body); letter-spacing: 0.14em !important; text-transform: uppercase; }
html[lang="en"] .card .en { font: 500 13px/1.3 var(--font-body); letter-spacing: 0.2em !important; }
html[lang="en"] .card dt { font: 500 12px/1.6 var(--font-body); letter-spacing: 0.14em !important; text-transform: uppercase; }
/* the title page's language switch: quiet, top right */
#ldLang { position: absolute; z-index: 2; top: max(16px, env(safe-area-inset-top, 0px)); right: max(16px, env(safe-area-inset-right, 0px)); min-width: 44px; min-height: 36px;
  padding: 4px 12px; border: 1px solid rgba(165, 139, 207, 0.6); border-radius: 999px; background: rgba(251, 248, 243, 0.5);
  font: 500 14px "Manrope", "Noto Serif SC", system-ui, sans-serif; color: #5b4a6e; cursor: pointer; }
#ldLang:hover { background: rgba(201, 187, 221, 0.3); }
#intro.leaving #ldLang { opacity: 0; }
/* 小游戏美术 A · 接住好运 as the sample (CC 11/06): the scroll opened to nearly the height of the screen, the game painted
   straight onto its paper (no field frame), the cards ink on the paper rather than a white panel, the keys as small tags */
#mg:is([data-game="catch"], [data-game="chime"]):not(.strip) .mgbox { width: min(calc(100vw - 120px), calc((100vh - 300px) * 0.75 + 60px)); }
#mg[data-game="chime"]:not(.strip) .mgbox { width: min(calc(100vw - 120px), calc((100vh - 340px) * 0.75 + 60px)); }   /* its foot has a second row (the sound switch) */
#mg[data-game="spot"]:not(.strip) .mgbox { width: min(calc(100vw - 120px), calc((100vh - 340px) * 0.643 + 60px)); }   /* 井中倒影: a taller page (360 × 560), the hint button below */
#mg[data-game="spot"] .mgwrap { width: 100% !important; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="stance"], [data-game="soup"]) .mgwrap { width: 100%; box-shadow: none;   /* the field's edges melt into the paper */
  -webkit-mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent), linear-gradient(180deg, transparent, #000 5%, #000 100%); -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent), linear-gradient(180deg, transparent, #000 5%, #000 100%); mask-composite: intersect; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="stance"], [data-game="soup"]) .mgcard { background: radial-gradient(ellipse 62% 56% at 50% 48%, rgba(249, 244, 235, 0.86), rgba(249, 244, 235, 0.6) 60%, rgba(249, 244, 235, 0) 100%); backdrop-filter: none; -webkit-backdrop-filter: none; }
#mg .mghint kbd { display: inline-block; min-width: 1.7em; margin: 0 2px; padding: 1px 6px 0; font: 500 11px/1.6 var(--font-body); letter-spacing: 0; text-align: center; color: var(--mg-ink);
  border: 0.5px solid rgba(58, 47, 69, 0.3); border-bottom-width: 1.5px; border-radius: 5px; background: rgba(255, 255, 255, 0.4); }
#mg .mghint:has(kbd) { letter-spacing: 0.06em; min-width: 0; } #mg .mghint :is(kbd, span) { white-space: nowrap; } #mg .mghint span { margin: 0 4px; } #mg .mghint span.soft { margin-left: 12px; opacity: 0.75; }
#mg:is([data-game="spot"], [data-game="soup"]) .mgcard { background: radial-gradient(ellipse 80% 70% at 50% 50%, rgba(249, 244, 235, 0.93), rgba(249, 244, 235, 0.8) 60%, rgba(249, 244, 235, 0) 100%); }   /* the busy well under the words: a thicker wash */
#mg[data-game="spot"] .mgcard h3.feel { max-width: none; white-space: nowrap; font-size: 26px; }
#mg[data-game="stance"] .mgcard { background: radial-gradient(ellipse 85% 90% at 50% 50%, rgba(249, 244, 235, 0.96), rgba(249, 244, 235, 0.9) 60%, rgba(249, 244, 235, 0.4) 100%); }   /* 站桩: a short page, the card covers the whole field */
#mg[data-game="soup"]:not(.strip) .mgbox { width: min(calc(100vw - 120px), calc((100vh - 290px) * 0.75 + 180px)); }   /* 七味入汤 (CC 11/07): a wider scroll than the pot's page, room either side for the words */
#mg[data-game="soup"] .mgwrap { width: calc(100% - 120px); overflow: visible; -webkit-mask: none; mask: none; }
#mg[data-game="soup"] .mgwrap canvas { -webkit-mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent), linear-gradient(180deg, transparent, #000 5%, #000 100%); -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent), linear-gradient(180deg, transparent, #000 5%, #000 100%); mask-composite: intersect; }
#mg[data-game="soup"] .mgcard { inset: 0 -60px; }   /* the cards span the whole scroll */
html[lang="en"] #mg[data-game="soup"] .mgcard h3.feel { white-space: normal; text-wrap: balance; font-size: 25px; }   /* 七味入汤: the hint wraps to two rows; the pot and herbs nearly the height of the screen */
/* English (CC 11/07): the words run longer and cover more of the field, so the wash under them is thicker; the long 井中倒影 win line wraps */
html[lang="en"] #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]) .mgcard { background: radial-gradient(ellipse 85% 75% at 50% 50%, rgba(249, 244, 235, 0.95), rgba(249, 244, 235, 0.86) 60%, rgba(249, 244, 235, 0) 100%); }
html[lang="en"] #mg[data-game="spot"] .mgcard h3.feel { white-space: normal; }
/* English title page (CC 11/07): no intro line; the title block sits lower, a breath between the subtitle and the wisteria */
html[lang="en"] .ldIntro { display: none; }
html[lang="en"] .ldText .ldSub { margin-bottom: 18px; }
#mg[data-game="soup"] .mgcard, html[lang="en"] #mg[data-game="soup"] .mgcard { background: radial-gradient(ellipse 50% 60% at 50% 50%, rgba(249, 244, 235, 0.96), rgba(249, 244, 235, 0.92) 72%, rgba(249, 244, 235, 0) 100%); }   /* the wider card: a wash that fades out before its edges */
/* (CC 11/07) the tall scrolls much wider than their pictures: the picture sized by the screen's height, the scroll by its width,
   the cards and the words spread across the whole scroll. --ch: the picture's height, --ar: its width / height */
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) { --room: 300px; --ar: 0.75; --ch: max(260px, calc(100vh - var(--room))); --cw: calc(var(--ch) * var(--ar)); }
#mg:is([data-game="chime"], [data-game="soup"]):not(.strip) { --room: 330px; }
#mg[data-game="spot"]:not(.strip) { --room: 340px; --ar: 0.643; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgbox { width: min(calc(100vw - 80px), max(640px, calc(var(--cw) + 280px))); }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgwrap { width: 100% !important; aspect-ratio: auto !important; overflow: visible; box-shadow: none; -webkit-mask: none; mask: none; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgwrap canvas { width: min(var(--cw), 100%); height: auto; aspect-ratio: 3 / 4; margin: 0 auto; }
#mg[data-game="spot"]:not(.strip) .mgwrap canvas { aspect-ratio: 360 / 560; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="soup"]):not(.strip) .mgwrap canvas { -webkit-mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent), linear-gradient(180deg, transparent, #000 5%, #000 100%); -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent), linear-gradient(180deg, transparent, #000 5%, #000 100%); mask-composite: intersect; }
#mg[data-game="soup"]:not(.strip) .mgcard { inset: 0; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgcard { background: radial-gradient(ellipse 50% 55% at 50% 50%, rgba(249, 244, 235, 0.95), rgba(249, 244, 235, 0.88) 66%, rgba(249, 244, 235, 0) 100%); }   /* the card as wide as the scroll: a wash that fades before its edges */
/* a short window (CC's, about 460px high): the scroll can be scrolled rather than cut off, and its frame is tighter */
#mg:not(.strip) { overflow-y: auto; align-items: safe center; }
@media (max-height: 640px) {
  #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) { --room: 230px; --ch: max(320px, calc(100vh - var(--room)));   /* below 320 the cards no longer fit: the page scrolls instead */ }
  #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgpaper { padding-top: 22px; padding-bottom: 14px; gap: 8px; }
}
/* (CC 11/07: 汤锅和原料都很小) the scroll as tall as the window and the picture filling whatever height its frame leaves,
   rather than a fixed allowance for the frame guessed in advance */
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) { --boxh: min(1000px, max(520px, calc(100vh - 40px))); --ch: calc(var(--boxh) - 230px); }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgbox { height: var(--boxh); display: flex; flex-direction: column; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgpaper { flex: 1; min-height: 0; grid-template-rows: auto auto minmax(0, 1fr) auto; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgwrap { height: 100%; min-height: 0; display: flex; justify-content: center; }
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgwrap canvas { height: 100%; width: auto; max-width: 100%; margin: 0; }
/* a short window: less frame, more picture */
@media (max-height: 760px) {
  #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) { --boxh: max(440px, calc(100vh - 16px)); }
  #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgbox { padding: 8px 0; }
  #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgpaper { padding: 36px 30px 40px; gap: 6px; }
  #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mghead h2 { font-size: 21px; }
  #mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgbars { margin-top: -22px; padding-left: 50%; padding-right: 64px; }   /* the counts beside the title, not under it */
}
/* (CC 11/07: 井中倒影的提示按钮按不到) the scroll fits inside the window, frame and rollers included */
#mg:is([data-game="catch"], [data-game="chime"], [data-game="spot"], [data-game="soup"]):not(.strip) .mgbox { box-sizing: border-box; max-height: calc(100vh - 32px); }
