/* SoarClient design system — tokens, base, shared components. Page layouts live in home.css / community.css. */

@property --brand-angle { syntax: '<angle>'; inherits: false; initial-value: 110deg; }
/* Brand mark colours; the homepage updates them from the client preview's accent. Registered so they animate. */
@property --mark-start { syntax: '<color>'; inherits: true; initial-value: #59c173; }
@property --mark-end { syntax: '<color>'; inherits: true; initial-value: #5d26c1; }

:root {
  color-scheme: light;
  --bg: #f4f7f2;
  --bg-tint: #ebf2e8;
  --surface: #ffffff;
  --surface-2: #f3f6f1;
  --surface-3: #e8eee6;
  --surface-glass: rgb(255 255 255 / .72);
  --ink: #0f1a14;
  --ink-2: #3c4a42;
  --ink-3: #66756c;
  --line: #e0e7df;
  --line-2: #cbd6ca;
  --accent: #2bc26a;
  --accent-hover: #3dd47c;
  --accent-ink: #052713;
  --accent-text: #11804a;
  --accent-soft: #e1f6e8;
  --accent-ring: rgb(43 194 106 / .3);
  --violet: #6a3fd2;
  --violet-text: #5b33c0;
  --violet-soft: #eee8fd;
  --gold: #e8a91b;
  --danger: #dc3d3d;
  --danger-text: #b3261e;
  --danger-soft: #fdecea;
  --warning-text: #8a5a00;
  --warning-soft: #fff4d6;
  --info-text: #1d5bb8;
  --info-soft: #e7f0ff;
  --brand-gradient: linear-gradient(var(--brand-angle), #3fc477, #6a3fd2);
  --supporter: #d62f78;
  --supporter-soft: #ffe8f2;
  --supporter-gradient: linear-gradient(var(--brand-angle), #ff4f9a, #9b4dff);
  --shadow-xs: 0 1px 2px rgb(15 26 20 / .06);
  --shadow-sm: 0 1px 3px rgb(15 26 20 / .07), 0 1px 2px rgb(15 26 20 / .04);
  --shadow-md: 0 10px 30px -12px rgb(15 26 20 / .18), 0 3px 8px -2px rgb(15 26 20 / .06);
  --shadow-lg: 0 30px 70px -28px rgb(15 26 20 / .32), 0 10px 24px -12px rgb(15 26 20 / .12);
  --header-bg: rgb(244 247 242 / .76);
  --header-height: 68px;
  --radius-xs: 6px;
  --radius-sm: 9px;
  --radius: 12px;
  --radius-lg: 18px;
  --radius-xl: 26px;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --font-sans: "Inter", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "PingFang SC", "HarmonyOS Sans SC", "MiSans", "Microsoft YaHei UI", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --font-display: "Inter Display", "Inter", "Segoe UI Variable Display", "Segoe UI", system-ui, -apple-system, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei UI", "Microsoft YaHei", sans-serif;
  --font-mono: "JetBrains Mono", "Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0b110e;
  --bg-tint: #0f1813;
  --surface: #121a16;
  --surface-2: #17211c;
  --surface-3: #1e2a24;
  --surface-glass: rgb(18 26 22 / .7);
  --ink: #ecf3ee;
  --ink-2: #b3c1b8;
  --ink-3: #84958a;
  --line: rgb(255 255 255 / .075);
  --line-2: rgb(255 255 255 / .14);
  --accent: #5fe08f;
  --accent-hover: #7fe9a6;
  --accent-ink: #03200e;
  --accent-text: #7de7a3;
  --accent-soft: rgb(95 224 143 / .11);
  --accent-ring: rgb(95 224 143 / .32);
  --violet: #9b7bff;
  --violet-text: #b9a3ff;
  --violet-soft: rgb(155 123 255 / .13);
  --danger: #ff6b5f;
  --danger-text: #ff9a90;
  --danger-soft: rgb(255 107 95 / .12);
  --warning-text: #ffd27a;
  --warning-soft: rgb(255 196 64 / .11);
  --info-text: #9cc3ff;
  --info-soft: rgb(110 160 255 / .12);
  --supporter: #ff7ab3;
  --supporter-soft: rgb(255 79 154 / .14);
  --shadow-xs: 0 1px 2px rgb(0 0 0 / .3);
  --shadow-sm: 0 1px 3px rgb(0 0 0 / .35);
  --shadow-md: 0 14px 34px -14px rgb(0 0 0 / .6), 0 3px 8px -3px rgb(0 0 0 / .4);
  --shadow-lg: 0 30px 80px -30px rgb(0 0 0 / .8), 0 10px 24px -12px rgb(0 0 0 / .5);
  --header-bg: rgb(11 17 14 / .72);
}

/* Site language (set on <html> by i18n.js before first paint): CJK glyphs come from a font made for that language.
   These fonts sit before system-ui, which would otherwise resolve to the operating system's own CJK UI font. */
:root:lang(zh-TW) {
  --font-sans: "Inter", "Segoe UI Variable Text", "Segoe UI", "PingFang TC", "Microsoft JhengHei UI", "Microsoft JhengHei", "Noto Sans TC", system-ui, -apple-system, sans-serif;
  --font-display: "Inter Display", "Inter", "Segoe UI Variable Display", "Segoe UI", "PingFang TC", "Microsoft JhengHei UI", "Microsoft JhengHei", "Noto Sans TC", system-ui, -apple-system, sans-serif;
}
:root:lang(ja) {
  --font-sans: "Inter", "Segoe UI Variable Text", "Segoe UI", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic UI", "Meiryo UI", "Meiryo", "Noto Sans JP", system-ui, -apple-system, sans-serif;
  --font-display: "Inter Display", "Inter", "Segoe UI Variable Display", "Segoe UI", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic UI", "Meiryo UI", "Meiryo", "Noto Sans JP", system-ui, -apple-system, sans-serif;
}
:root:lang(ja) body { word-break: auto-phrase; line-break: strict; }

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--header-height) + 24px); }
body {
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  background: var(--bg); color: var(--ink);
  font-family: var(--font-sans); font-size: 15px; line-height: 1.7; font-synthesis: none;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  transition: background-color .35s, color .35s;
}
main { flex: 1; }
h1, h2, h3, h4, p, figure, dl, dd, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
h1, h2, h3, h4 { font-family: var(--font-display); line-height: 1.2; letter-spacing: -.02em; font-weight: 750; }
a { color: inherit; text-decoration: none; }
img, svg, canvas { display: block; max-width: 100%; }
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
a, button, summary, label { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
[hidden] { display: none !important; }
::selection { background: var(--accent-soft); color: var(--ink); }
:focus-visible { outline: 3px solid var(--accent-ring); outline-offset: 3px; border-radius: 6px; }
:root[data-theme="dark"] :focus-visible { outline-color: var(--accent); }
svg.icon { width: 20px; height: 20px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
code, .mono { font-family: var(--font-mono); font-size: .92em; }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; top: 12px; left: 12px; z-index: 100; padding: 10px 18px; border-radius: var(--radius-sm); background: var(--ink); color: var(--bg); font-weight: 650; transform: translateY(-160%); transition: transform .2s; }
.skip-link:focus { transform: none; }
.container { width: min(1200px, 100% - 48px); margin-inline: auto; }
.muted { color: var(--ink-3); }
.eyebrow { display: inline-flex; align-items: center; gap: 8px; color: var(--accent-text); font-size: .8125rem; font-weight: 700; letter-spacing: .04em; }
.eyebrow::before { content: ""; width: 8px; height: 8px; background: var(--brand-gradient); box-shadow: 3px 3px 0 color-mix(in srgb, var(--accent) 35%, transparent); }
.gradient-text { background: var(--brand-gradient); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* ---------- Header ---------- */
.site-header { position: sticky; top: 0; z-index: 50; background: var(--header-bg); backdrop-filter: saturate(1.6) blur(18px); -webkit-backdrop-filter: saturate(1.6) blur(18px); border-bottom: 1px solid transparent; transition: border-color .3s, background-color .35s, box-shadow .3s; }
.site-header[data-scrolled="true"] { border-bottom-color: var(--line); box-shadow: 0 8px 30px -24px rgb(15 26 20 / .35); }
.header-inner { width: min(1280px, 100% - 48px); margin-inline: auto; min-height: var(--header-height); display: flex; align-items: center; gap: 28px; }
/* Main navigation as a "Pill Nav" (React Bits): hovering a link floods it from below and rolls its label up. The current
   page's pill stays filled; on the homepage, home.js fills the pill of the section in view. */
.site-nav { display: flex; align-items: center; gap: 2px; margin-inline: auto; padding: 5px; border-radius: 999px; background: var(--surface-glass); border: 1px solid var(--line); box-shadow: var(--shadow-sm); font-size: .9rem; font-weight: 650; }
.site-nav a { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 6px; height: 38px; padding: 0 15px; border-radius: 999px; overflow: hidden; color: var(--ink-2); white-space: nowrap; transition: background-color .3s, color .3s; }
.site-nav .nav-support { color: var(--supporter); }
.site-nav a:is([aria-current], .is-active) { background: var(--accent); color: var(--accent-ink); }
.pill-circle { position: absolute; left: 50%; bottom: 0; z-index: -1; width: 160%; aspect-ratio: 1; border-radius: 50%; background: var(--ink); translate: -50% 101%; transition: translate .5s var(--ease-out); }
.pill-label { display: grid; height: 1.5em; line-height: 1.5; overflow: hidden; }
.pill-label > span { transition: translate .5s var(--ease-out); }
.pill-label > span + span { color: var(--bg); }
.site-nav a:is([aria-current], .is-active) .pill-circle { background: var(--accent-ink); }
.site-nav a:is([aria-current], .is-active) .pill-label > span + span { color: var(--accent); }
@media (hover: hover) {
  .site-nav a:hover .pill-circle { translate: -50% 22%; }
  .site-nav a:hover .pill-label > span { translate: 0 -100%; }
}
.site-nav a:focus-visible .pill-circle { translate: -50% 22%; }
.site-nav a:focus-visible .pill-label > span { translate: 0 -100%; }
.site-nav .nav-support::before, .mobile-nav .nav-support::after { content: ""; width: 14px; height: 14px; flex-shrink: 0; background: url("/assets/icons/sponsor.svg") center / contain no-repeat; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) { .site-nav .nav-support:hover::before { animation: supporter-beat .7s var(--ease-out); } }
.header-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.site-nav + .header-actions { margin-left: 0; }

.icon-button { display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 11px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); box-shadow: var(--shadow-xs); transition: color .2s, background-color .2s, border-color .2s; }
.icon-button:hover { color: var(--ink); border-color: var(--line-2); }
.icon-button svg.icon { width: 19px; height: 19px; }

.theme-toggle { position: relative; overflow: hidden; }
.theme-toggle svg { position: absolute; transition: transform .5s var(--ease-out), opacity .3s; }
.theme-toggle .theme-icon-moon { transform: translateY(26px) rotate(-60deg); opacity: 0; }
:root[data-theme="dark"] .theme-toggle .theme-icon-sun { transform: translateY(-26px) rotate(60deg); opacity: 0; }
:root[data-theme="dark"] .theme-toggle .theme-icon-moon { transform: none; opacity: 1; }

/* Language switcher: globe with the current language's tag; built by i18n.js. */
.lang-switch { position: relative; display: inline-grid; }
.lang-toggle { position: relative; }
.lang-toggle svg.icon { transition: transform .7s var(--ease-out); }
.lang-toggle[aria-expanded="true"] { color: var(--ink); border-color: var(--line-2); }
.lang-toggle[aria-expanded="true"] svg.icon { transform: rotate(-24deg); }
.lang-toggle[data-loading] svg.icon { animation: spin 1.1s linear infinite; }
.lang-badge { position: absolute; right: -6px; bottom: -5px; display: grid; place-items: center; min-width: 17px; height: 17px; padding: 0 3px; border-radius: 6px; background: var(--accent); color: var(--accent-ink); box-shadow: 0 0 0 2px var(--bg); font-family: var(--font-sans); font-size: 10px; font-weight: 800; line-height: 1; letter-spacing: 0; pointer-events: none; animation: lang-badge-in .5s var(--ease-out); }
.lang-badge[data-long="true"] { font-size: 8.5px; letter-spacing: .02em; }
@keyframes lang-badge-in { from { transform: translateY(5px) rotateX(80deg) scale(.6); opacity: 0; } }
.lang-menu { position: absolute; z-index: 60; right: -6px; top: calc(100% + 10px); display: grid; gap: 2px; min-width: 200px; padding: 6px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); box-shadow: var(--shadow-lg); animation: select-in .2s var(--ease-out); transform-origin: top right; }
.lang-option { display: grid; grid-template-columns: 30px minmax(0, 1fr) 14px; align-items: center; gap: 11px; width: 100%; min-height: 44px; padding: 0 12px 0 7px; border: 0; border-radius: 10px; background: none; color: var(--ink-2); font-size: .9rem; font-weight: 600; text-align: left; transition: background-color .15s, color .15s; }
.lang-option:hover, .lang-option:focus-visible { background: var(--surface-2); color: var(--ink); }
.lang-option:focus-visible { outline-offset: -2px; }
/* Each language shows its flag: mainland China for 简体, Hong Kong for 繁體, the UK for English, Japan for 日本語.
   The SVGs are flag-icons 7.2.3 (4x3 set, MIT, © 2013 Panayiotis Lipiridis), inlined unchanged. */
.lang-flag { justify-self: center; width: 24px; height: 18px; border-radius: 3px; background: var(--surface-3) center / cover no-repeat; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 14%, transparent); }
.lang-option[data-lang="zh-CN"] .lang-flag { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' id='flag-icons-cn' viewBox='0 0 640 480'%3E%3Cdefs%3E%3Cpath id='cn-a' fill='%23ff0' d='M-.6.8 0-1 .6.8-1-.3h2z'/%3E%3C/defs%3E%3Cpath fill='%23ee1c25' d='M0 0h640v480H0z'/%3E%3Cuse xlink:href='%23cn-a' width='30' height='20' transform='matrix(71.9991 0 0 72 120 120)'/%3E%3Cuse xlink:href='%23cn-a' width='30' height='20' transform='matrix(-12.33562 -20.5871 20.58684 -12.33577 240.3 48)'/%3E%3Cuse xlink:href='%23cn-a' width='30' height='20' transform='matrix(-3.38573 -23.75998 23.75968 -3.38578 288 95.8)'/%3E%3Cuse xlink:href='%23cn-a' width='30' height='20' transform='matrix(6.5991 -23.0749 23.0746 6.59919 288 168)'/%3E%3Cuse xlink:href='%23cn-a' width='30' height='20' transform='matrix(14.9991 -18.73557 18.73533 14.99929 240 216)'/%3E%3C/svg%3E"); }
.lang-option[data-lang="zh-TW"] .lang-flag { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' id='flag-icons-hk' viewBox='0 0 640 480'%3E%3Cpath fill='%23EC1B2E' d='M0 0h640v480H0'/%3E%3Cpath id='hk-a' fill='%23fff' d='M346.3 103.1C267 98 230.6 201.9 305.6 240.3c-26-22.4-20.6-55.3-10.1-72.4l1.9 1.1c-13.8 23.5-11.2 52.7 11.1 71-12.7-12.3-9.5-39 12.1-48.9s23.6-39.3 16.4-49.1q-14.7-25.6 9.3-38.9M307.9 164l-4.7 7.4-1.8-8.6-8.6-2.3 7.8-4.3-.6-8.9 6.5 6.1 8.3-3.3-3.7 8.1 5.6 6.8z'/%3E%3Cuse xlink:href='%23hk-a' transform='rotate(72 312.5 243.5)'/%3E%3Cuse xlink:href='%23hk-a' transform='rotate(144 312.5 243.5)'/%3E%3Cuse xlink:href='%23hk-a' transform='rotate(216 312.5 243.5)'/%3E%3Cuse xlink:href='%23hk-a' transform='rotate(288 312.5 243.5)'/%3E%3C/svg%3E"); }
.lang-option[data-lang="en"] .lang-flag { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' id='flag-icons-gb' viewBox='0 0 640 480'%3E%3Cpath fill='%23012169' d='M0 0h640v480H0z'/%3E%3Cpath fill='%23FFF' d='m75 0 244 181L562 0h78v62L400 241l240 178v61h-80L320 301 81 480H0v-60l239-178L0 64V0z'/%3E%3Cpath fill='%23C8102E' d='m424 281 216 159v40L369 281zm-184 20 6 35L54 480H0zM640 0v3L391 191l2-44L590 0zM0 0l239 176h-60L0 42z'/%3E%3Cpath fill='%23FFF' d='M241 0v480h160V0zM0 160v160h640V160z'/%3E%3Cpath fill='%23C8102E' d='M0 193v96h640v-96zM273 0v480h96V0z'/%3E%3C/svg%3E"); }
.lang-option[data-lang="ja"] .lang-flag { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' id='flag-icons-jp' viewBox='0 0 640 480'%3E%3Cdefs%3E%3CclipPath id='jp-a'%3E%3Cpath fill-opacity='.7' d='M-88 32h640v480H-88z'/%3E%3C/clipPath%3E%3C/defs%3E%3Cg fill-rule='evenodd' stroke-width='1pt' clip-path='url(%23jp-a)' transform='translate(88 -32)'%3E%3Cpath fill='%23fff' d='M-128 32h720v480h-720z'/%3E%3Ccircle cx='523.1' cy='344.1' r='194.9' fill='%23bc002d' transform='translate(-168.4 8.6)scale(.76554)'/%3E%3C/g%3E%3C/svg%3E"); }
.lang-option[aria-checked="true"] { color: var(--ink); }
.lang-check { width: 14px; height: 14px; }
.lang-option[aria-checked="true"] .lang-check { background: var(--accent-text); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat; }
.lang-segment { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 3px; margin-top: 10px; padding: 4px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); }
.lang-segment-option { min-width: 0; min-height: 40px; padding: 0 4px; border: 0; border-radius: 9px; background: none; color: var(--ink-3); font-size: .84rem; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background-color .2s, color .2s, box-shadow .2s; }
.lang-segment-option:hover { color: var(--ink); }
.lang-segment-option[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--line); }
/* Switching language: a soft diagonal edge sweeps across, the old text blurring away as the new text takes its place.
   The two snapshots carry complementary masks, so they never show through each other. */
:root[data-lang-switching]::view-transition-old(root), :root[data-lang-switching]::view-transition-new(root) { animation: lang-sweep .6s var(--ease-out) both; }
:root[data-lang-switching]::view-transition-old(root) {
  animation: lang-sweep .6s var(--ease-out) both, lang-blur .6s var(--ease-out) both;
  -webkit-mask: linear-gradient(105deg, transparent 40%, #000 60%) 0 0 / 250% 100% no-repeat;
  mask: linear-gradient(105deg, transparent 40%, #000 60%) 0 0 / 250% 100% no-repeat;
}
:root[data-lang-switching]::view-transition-new(root) {
  -webkit-mask: linear-gradient(105deg, #000 40%, transparent 60%) 0 0 / 250% 100% no-repeat;
  mask: linear-gradient(105deg, #000 40%, transparent 60%) 0 0 / 250% 100% no-repeat;
}
@keyframes lang-sweep { from { -webkit-mask-position: 100% 0; mask-position: 100% 0; } to { -webkit-mask-position: 0 0; mask-position: 0 0; } }
@keyframes lang-blur { to { filter: blur(3px); } }

.account-chip { display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 14px 0 5px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); box-shadow: var(--shadow-xs); font-size: .875rem; font-weight: 650; color: var(--ink-2); transition: color .2s, border-color .2s; }
.account-chip:hover { color: var(--ink); border-color: var(--line-2); }
.account-chip[aria-current] { border-color: var(--accent); color: var(--ink); }
.account-chip-avatar { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--surface-3); color: var(--ink-3); overflow: hidden; flex-shrink: 0; }
.account-chip-avatar svg.icon { width: 17px; height: 17px; }
.account-chip-avatar:has(.author-avatar) { background: none; }
.account-chip-avatar .author-avatar { width: 30px; height: 30px; border-radius: 50%; }
/* A long player name ends in an ellipsis rather than pushing the header wider. */
.account-chip [data-account-label] { max-width: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Until /me answers with no player remembered, the chip's face and name shimmer in place ("Shiny Text"), and a face
   still on its way shimmers too. A name that /me brings scrambles into place ("Decrypted Text", shell.js). */
:root { --chip-shine: rgb(255 255 255 / .75); }
:root[data-theme="dark"] { --chip-shine: rgb(255 255 255 / .1); }
.js .account-chip:not([data-session]) :is(.account-chip-avatar, [data-account-label]), .account-chip[data-session="loading"] :is(.account-chip-avatar, [data-account-label]), .account-chip-avatar.is-loading { background: linear-gradient(100deg, transparent 30%, var(--chip-shine) 50%, transparent 70%) 0 0 / 300% 100% no-repeat, var(--surface-3); animation: chip-shine 1.3s linear infinite; }
.js .account-chip:not([data-session]) .account-chip-avatar > *, .account-chip[data-session="loading"] .account-chip-avatar > * { visibility: hidden; }
.js .account-chip:not([data-session]) [data-account-label], .account-chip[data-session="loading"] [data-account-label] { padding-inline: 1em; border-radius: 6px; color: transparent; }
@keyframes chip-shine { from { background-position: 100% 0, 0 0; } to { background-position: 0 0, 0 0; } }
/* Account menu (session.js): for a signed-in player the chip opens a profile card under it instead of going to
   /account/: a small player banner coloured from the face ("Profile Card": it leans toward the pointer), the account's
   pages as tiles, the theme and signing out. The parts rise in one after another. */
.account-chip .chip-caret { display: none; width: 14px; height: 14px; margin-left: -3px; color: var(--ink-3); transition: rotate .3s var(--ease-out); }
.account-chip[aria-haspopup] .chip-caret { display: block; }
.account-chip[aria-expanded="true"] { border-color: var(--accent); color: var(--ink); box-shadow: 0 0 0 4px var(--accent-ring); }
.account-chip[aria-expanded="true"] .chip-caret { rotate: 180deg; }
.account-menu { position: fixed; z-index: 60; top: var(--menu-top, 78px); right: var(--menu-right, 24px); width: 340px; max-height: calc(100dvh - var(--menu-top, 78px) - 12px); overflow: auto; overscroll-behavior: contain; padding: 8px; border: 1px solid var(--line); border-radius: 22px; background: var(--surface); box-shadow: var(--shadow-lg); color: var(--ink); transform-origin: top right; opacity: 0; scale: .96; translate: 0 -6px; transition: opacity .2s, scale .2s, translate .2s; }
.account-menu[hidden] { display: none; }
.account-menu.is-open { opacity: 1; scale: 1; translate: 0; animation: menu-in .32s var(--ease-out); }
@keyframes menu-in { from { opacity: 0; scale: .94; translate: 0 -6px; } }
.account-menu.is-open [style*="--i"] { animation: menu-item-in .38s var(--ease-out) both; animation-delay: calc(var(--i) * 28ms + 60ms); }
@keyframes menu-item-in { from { opacity: 0; translate: 0 6px; } }
.menu-card { --face-0: var(--accent); --face-1: #9b7bff; --face-2: #6a3fd2; position: relative; overflow: hidden; isolation: isolate; display: grid; gap: 14px; padding: 16px; border-radius: 16px; background: linear-gradient(135deg, color-mix(in srgb, var(--face-0) 45%, #fff), color-mix(in srgb, var(--face-1) 35%, #fff) 60%, color-mix(in srgb, var(--face-2) 45%, #fff)); color: #1b1020; transition: transform .5s var(--ease-out); }
:root[data-theme="dark"] .menu-card { background: linear-gradient(135deg, color-mix(in srgb, var(--face-0) 55%, #0b110e), color-mix(in srgb, var(--face-1) 45%, #0b110e) 60%, color-mix(in srgb, var(--face-2) 55%, #0b110e)); color: #fff; }
.menu-card.is-tilting { transition: none; }
.menu-card::before { content: ""; position: absolute; inset: 0; z-index: -1; background-image: radial-gradient(rgb(255 255 255 / .35) 1px, transparent 1.2px); background-size: 10px 10px; -webkit-mask: linear-gradient(120deg, transparent 30%, #000); mask: linear-gradient(120deg, transparent 30%, #000); }
.menu-sheen { position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0; background: radial-gradient(220px circle at var(--sx, 50%) var(--sy, 0%), rgb(255 255 255 / .45), transparent 60%); mix-blend-mode: soft-light; transition: opacity .3s; }
.menu-card.is-tilting .menu-sheen { opacity: 1; }
.menu-who { display: flex; align-items: center; gap: 12px; min-width: 0; }
.menu-face { display: grid; place-items: center; flex-shrink: 0; width: 54px; height: 54px; overflow: hidden; border-radius: 14px; background: rgb(255 255 255 / .35); box-shadow: 0 0 0 3px rgb(255 255 255 / .7), 0 8px 18px -8px rgb(0 0 0 / .45); }
.menu-face .author-avatar, .menu-face img, .menu-face .avatar-fallback { width: 54px; height: 54px; border-radius: 0; image-rendering: pixelated; }
.menu-face.is-loading { background: linear-gradient(100deg, transparent 30%, rgb(255 255 255 / .6) 50%, transparent 70%) 0 0 / 300% 100% no-repeat, rgb(255 255 255 / .3); animation: chip-shine 1.3s linear infinite; }
.menu-who > div { display: grid; min-width: 0; }
.menu-name { display: flex; align-items: center; min-width: 0; overflow: hidden; font-size: 1.12rem; letter-spacing: -.02em; white-space: nowrap; text-overflow: ellipsis; }
.menu-name .supporter-badge { flex-shrink: 0; margin-left: 6px; }
.menu-sub { overflow: hidden; font-size: .78rem; font-weight: 650; opacity: .78; white-space: nowrap; text-overflow: ellipsis; }
.menu-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; border-radius: 12px; background: rgb(255 255 255 / .5); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
:root[data-theme="dark"] .menu-stats { background: rgb(0 0 0 / .25); }
.menu-stats div { min-width: 0; padding: 9px 4px 8px; text-align: center; }
.menu-stats div + div { border-left: 1px solid rgb(0 0 0 / .08); }
.menu-stats dd { margin: 0; font-size: 1.15rem; font-weight: 800; line-height: 1.2; font-variant-numeric: tabular-nums; }
.menu-stats dt { overflow: hidden; font-size: .7rem; font-weight: 650; opacity: .72; white-space: nowrap; text-overflow: ellipsis; }
.menu-actions { display: flex; gap: 8px; }
.menu-actions .btn-primary { flex: 1; justify-content: center; }
.menu-copy { position: relative; flex-shrink: 0; width: 36px; padding: 0; justify-content: center; background: rgb(255 255 255 / .7); border-color: transparent; color: #1b1020; }
:root[data-theme="dark"] .menu-copy { background: rgb(255 255 255 / .16); color: #fff; }
.menu-copy .sc-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.menu-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding: 8px 0 4px; }
.menu-tile { position: relative; display: grid; justify-items: center; align-content: start; gap: 6px; padding: 12px 4px 10px; border-radius: 13px; color: var(--ink-2); font-size: .78rem; font-weight: 700; text-align: center; transition: background-color .2s, color .2s; }
.menu-tile:hover, .menu-tile:focus-visible { background: var(--surface-2); color: var(--ink); }
.menu-tile-icon { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px; background: var(--surface-2); color: var(--ink-2); transition: scale .35s var(--spring), background-color .2s, color .2s; }
.menu-tile-icon svg.icon { width: 18px; height: 18px; }
.menu-tile:hover .menu-tile-icon, .menu-tile:focus-visible .menu-tile-icon { scale: 1.1; background: var(--accent-soft); color: var(--accent-text); }
.menu-tile small { position: absolute; top: 6px; right: calc(50% - 30px); min-width: 18px; height: 18px; padding: 0 5px; border-radius: 99px; background: var(--ink); color: var(--bg); font-size: .66rem; font-weight: 750; line-height: 18px; text-align: center; font-variant-numeric: tabular-nums; }
.menu-tile small:empty { display: none; }
.menu-foot { display: flex; align-items: center; gap: 8px; padding: 8px 4px 2px; border-top: 1px solid var(--line); }
.menu-theme { display: inline-flex; padding: 3px; border-radius: 99px; background: var(--surface-2); }
.menu-theme button { display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 11px; border: 0; border-radius: 99px; background: none; color: var(--ink-3); font: inherit; font-size: .76rem; font-weight: 700; cursor: pointer; }
.menu-theme svg.icon { width: 15px; height: 15px; }
.menu-theme button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-xs); }
.menu-out { display: inline-flex; align-items: center; gap: 6px; height: 34px; margin-left: auto; padding: 0 12px; border: 0; border-radius: 99px; background: none; color: var(--ink-3); font: inherit; font-size: .8rem; font-weight: 700; cursor: pointer; }
.menu-out:hover, .menu-out:focus-visible { background: var(--danger-soft); color: var(--danger-text); }
.menu-out svg.icon { width: 16px; height: 16px; }
@media (max-width: 760px) { .account-menu { left: 12px; right: 12px; width: auto; } }

.menu-toggle { display: none; position: relative; width: 40px; height: 40px; border-radius: 11px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); padding: 0; }
.menu-toggle span { position: absolute; left: 11px; right: 11px; height: 2px; border-radius: 2px; background: currentColor; transition: transform .3s var(--ease-out); }
.menu-toggle span:first-child { top: 15px; }
.menu-toggle span:last-child { top: 22px; }
.menu-toggle[aria-expanded="true"] span:first-child { transform: translateY(3.5px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:last-child { transform: translateY(-3.5px) rotate(-45deg); }
.mobile-nav { border-top: 1px solid var(--line); padding: 10px 16px 18px; background: var(--surface); display: grid; gap: 2px; animation: menu-in .32s var(--ease-out); }
.mobile-nav a { display: flex; align-items: center; justify-content: space-between; padding: 13px 12px; border-radius: var(--radius-sm); font-weight: 600; color: var(--ink-2); }
.mobile-nav a:hover, .mobile-nav a[aria-current] { background: var(--surface-2); color: var(--ink); }
.mobile-nav .btn { margin-top: 10px; }
@keyframes menu-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* ---------- Brand lockup: text rises, hint appears, mark stays put ---------- */
.brand { display: inline-flex; align-items: center; gap: 11px; flex-shrink: 0; min-height: 44px; font-family: var(--font-display); font-size: 1.12rem; font-weight: 800; letter-spacing: .04em; white-space: nowrap; color: var(--ink); }
.brand-mark { position: relative; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 11px; background: linear-gradient(var(--brand-angle), var(--mark-start, #59c173), var(--mark-end, #5d26c1)); box-shadow: 0 6px 16px -6px color-mix(in srgb, var(--mark-end, #5d26c1) 65%, transparent), inset 0 1px 0 rgb(255 255 255 / .25); animation: brand-flow 9s linear infinite; transition: --mark-start .6s var(--ease-out), --mark-end .6s var(--ease-out); flex-shrink: 0; }
.brand-mark img { width: 25px; height: 25px; }
.brand-light { font-weight: 400; }
.brand-lockup { position: relative; display: inline-flex; align-items: center; min-height: 44px; }
.brand-name { transition: transform .28s cubic-bezier(.2, .8, .2, 1); }
.brand-home-hint { position: absolute; left: 0; right: 0; bottom: 2px; font-family: var(--font-sans); font-size: 8.5px; font-style: italic; font-weight: 700; line-height: 1.2; letter-spacing: .14em; color: var(--ink-3); white-space: nowrap; opacity: 0; transform: translateY(4px); transition: opacity .24s, transform .28s; pointer-events: none; }
.brand-home-link:focus-visible .brand-name { transform: translateY(-6px); }
.brand-home-link:focus-visible .brand-home-hint { opacity: 1; transform: none; }
@media (hover: hover) { .brand-home-link:hover .brand-name { transform: translateY(-6px); } .brand-home-link:hover .brand-home-hint { opacity: 1; transform: none; } }
@keyframes brand-flow { to { --brand-angle: 470deg; } }

/* ---------- Buttons ---------- */
.btn {
  --btn-bg: var(--surface); --btn-fg: var(--ink); --btn-border: var(--line-2);
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 44px; padding: 0 20px; border-radius: var(--radius); border: 1px solid var(--btn-border);
  background: var(--btn-bg); color: var(--btn-fg); font-weight: 650; font-size: .9375rem; line-height: 1.2; white-space: nowrap;
  box-shadow: var(--shadow-xs); user-select: none;
}
.btn svg.icon { width: 18px; height: 18px; }
.btn:hover:not(:disabled) { --btn-border: color-mix(in srgb, var(--ink) 22%, var(--line-2)); }
.btn-primary { --btn-bg: var(--accent); --btn-fg: var(--accent-ink); --btn-border: transparent; box-shadow: 0 8px 20px -10px color-mix(in srgb, var(--accent) 80%, transparent), inset 0 1px 0 rgb(255 255 255 / .28); }
.btn-primary:hover:not(:disabled) { --btn-bg: var(--accent-hover); --btn-border: transparent; }
.btn-dark { --btn-bg: var(--ink); --btn-fg: var(--bg); --btn-border: transparent; }
.btn-dark:hover:not(:disabled) { --btn-border: transparent; opacity: .92; }
.btn-ghost { --btn-bg: transparent; --btn-border: transparent; box-shadow: none; color: var(--ink-2); }
.btn-ghost:hover:not(:disabled) { --btn-bg: var(--surface-3); --btn-border: transparent; color: var(--ink); }
.btn-danger { --btn-bg: var(--danger-soft); --btn-fg: var(--danger-text); --btn-border: color-mix(in srgb, var(--danger) 25%, transparent); box-shadow: none; }
.btn-danger:hover:not(:disabled) { --btn-border: color-mix(in srgb, var(--danger) 45%, transparent); }
.btn-solid-danger { --btn-bg: var(--danger); --btn-fg: #fff; --btn-border: transparent; }
.btn-sm { min-height: 36px; padding: 0 14px; font-size: .84rem; border-radius: 10px; }
.btn-lg { min-height: 54px; padding: 0 28px; font-size: 1.02rem; border-radius: 14px; }
.btn-block { width: 100%; }
.btn-icon { width: 40px; min-height: 40px; padding: 0; }
.btn:disabled { cursor: not-allowed; opacity: .5; box-shadow: none; }
.btn-primary:disabled { opacity: .45; }
.btn-download:hover:not(:disabled) { --btn-bg: var(--accent); opacity: .9; }

.link, .link-button { color: var(--accent-text); font-weight: 600; text-underline-offset: 4px; text-decoration-thickness: 1.5px; }
.link:hover, .link-button:hover:not(:disabled) { text-decoration: underline; }
.link-button { padding: 0; border: 0; background: none; font-size: inherit; }
.link-button:disabled { opacity: .5; cursor: not-allowed; }
.link-button.is-danger { color: var(--danger-text); }
.link-muted { color: var(--ink-3); font-weight: 500; }
.link-muted:hover { color: var(--ink); }

/* Slanted highlight sweep, unified 0.9s, never a flat horizontal wipe. */
.hover-shine { --shine-duration: .9s; position: relative; isolation: isolate; overflow: hidden; }
.hover-shine::before { content: ""; position: absolute; inset: -60% 0; z-index: -1; pointer-events: none; background: linear-gradient(70deg, transparent calc(50% - 55px), rgb(255 255 255 / .9) calc(50% - 28px), rgb(255 255 255 / .9) calc(50% + 28px), transparent calc(50% + 55px)); opacity: var(--shine-opacity, .45); transform: translateX(-100%); }
.hover-shine:focus-visible:not(:disabled)::before { animation: hover-shine var(--shine-duration) ease-in-out both; }
@media (hover: hover) { .hover-shine:hover:not(:disabled)::before { animation: hover-shine var(--shine-duration) ease-in-out both; } }
@keyframes hover-shine { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
:root[data-theme="dark"] .hover-shine:not(.btn-primary) { --shine-opacity: .14; }

/* Gentle centered scale, never a vertical lift. */
:is(.btn, .icon-button, .account-chip, .chip, .community-link, .thanks-banner, .sponsor-promo, .client-home-discord-join) { scale: 1; transform-origin: center; transition: scale .2s ease-in-out, background-color .22s, color .2s, border-color .25s, opacity .2s ease-in-out, box-shadow .22s; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :is(.btn, .icon-button, .account-chip, .chip, .client-home-discord-join):hover:not(:disabled):not([aria-disabled="true"]) { scale: 1.02; }
}
@media (prefers-reduced-motion: no-preference) {
  :is(.btn, .icon-button, .chip):focus-visible:not(:disabled) { scale: 1.02; }
}

/* ---------- Fields ---------- */
.form { display: grid; gap: 18px; }
.field { display: grid; gap: 7px; min-width: 0; }
.field-label, .field > span:first-child { font-size: .84rem; font-weight: 650; color: var(--ink-2); }
.field-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.field-hint { font-size: .8rem; color: var(--ink-3); }
.input {
  width: 100%; min-height: 46px; padding: 11px 14px; border-radius: var(--radius); border: 1px solid var(--line-2);
  background: var(--surface); color: var(--ink); font-size: .95rem; line-height: 1.5; outline: none;
  box-shadow: inset 0 1px 2px rgb(15 26 20 / .04); transition: border-color .2s, box-shadow .2s, background-color .2s;
}
.input::placeholder { color: color-mix(in srgb, var(--ink-3) 75%, transparent); }
.input:hover:not(:disabled):not([readonly]) { border-color: color-mix(in srgb, var(--ink) 22%, var(--line-2)); }
.input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring); }
.input[readonly] { background: var(--surface-2); color: var(--ink-2); }
.input:disabled { opacity: .6; cursor: not-allowed; }
textarea.input { resize: vertical; min-height: 104px; }
/* Selects stay native, so forms and scripts read them as before. Where the browser lets a select be styled
   (appearance: base-select), its button and list take the look of the library dropdown; elsewhere they look as before. */
select.input:not(:disabled) { cursor: pointer; }
@supports (appearance: base-select) {
  select.input, select.input::picker(select) { appearance: base-select; }
  select.input { display: flex; align-items: center; gap: 10px; font-weight: 600; }
  select.input::picker-icon { content: ""; flex: none; width: 16px; height: 16px; margin-left: auto; background: var(--ink-3); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 7.5 5 5 5-5'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 7.5 5 5 5-5'/%3E%3C/svg%3E") center / contain no-repeat; transition: rotate .25s var(--ease-out), background-color .2s; }
  select.input:open { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring); }
  select.input:open::picker-icon { rotate: 180deg; background: var(--accent-text); }
  select.input::picker(select) { margin-block: 8px; padding: 6px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg); max-block-size: min(320px, 60dvh); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
  select.input:open::picker(select) { animation: select-in .2s var(--ease-out); }
  select.input option { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 0 12px; border-radius: 9px; font-size: .875rem; font-weight: 550; line-height: 1.4; color: var(--ink-2); cursor: pointer; transition: background-color .15s, color .15s; }
  select.input option + option { margin-top: 2px; }
  select.input option:is(:hover, :focus-visible) { background: var(--surface-2); color: var(--ink); outline: none; }
  select.input option:checked { background: color-mix(in srgb, var(--accent) 11%, var(--surface)); color: var(--accent-text); font-weight: 700; }
  select.input option::checkmark { order: 1; margin-left: auto; padding-left: 12px; content: "✓"; font-size: .8rem; }
  select.input option:disabled { opacity: .5; cursor: not-allowed; }
}
.input-code { font-family: var(--font-mono); letter-spacing: .12em; text-transform: uppercase; }
.input-json { font-family: var(--font-mono); font-size: .8rem; line-height: 1.6; white-space: pre; tab-size: 2; }
.input-group { position: relative; display: flex; align-items: center; }
.input-group .input { padding-right: 48px; }
.input-addon { position: absolute; right: 5px; display: grid; place-items: center; width: 38px; height: 36px; border: 0; border-radius: 9px; background: none; color: var(--ink-3); }
.input-addon:hover { color: var(--ink); background: var(--surface-3); }
.input-addon .eye-off { display: none; }
.input-addon[aria-pressed="true"] .eye-on { display: none; }
.input-addon[aria-pressed="true"] .eye-off { display: block; }
.counter { font-size: .75rem; color: var(--ink-3); font-variant-numeric: tabular-nums; opacity: 0; transition: opacity .2s; }
.field:focus-within .counter { opacity: 1; }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.form-actions .push { margin-left: auto; }

/* ---------- Notices & statuses ---------- */
.notice {
  --notice-fg: var(--accent-text); --notice-bg: var(--accent-soft);
  position: relative; display: block; padding: 11px 14px 11px 42px; border-radius: var(--radius); background: var(--notice-bg); color: var(--notice-fg);
  font-size: .875rem; font-weight: 550; line-height: 1.55; animation: notice-in .35s var(--ease-out);
}
.notice::before { content: ""; position: absolute; left: 14px; top: 12px; width: 18px; height: 18px; background: currentColor; -webkit-mask: var(--notice-icon) center / contain no-repeat; mask: var(--notice-icon) center / contain no-repeat; }
.notice, .notice[data-kind="success"] { --notice-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m8 12.5 2.7 2.6L16 9.6'/%3E%3C/svg%3E"); }
.notice[data-kind="error"] { --notice-fg: var(--danger-text); --notice-bg: var(--danger-soft); --notice-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5.5M12 16.5h.01'/%3E%3C/svg%3E"); }
.notice[data-kind="warning"] { --notice-fg: var(--warning-text); --notice-bg: var(--warning-soft); --notice-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.3 4.3 2.7 17.6a2 2 0 0 0 1.7 3h15.2a2 2 0 0 0 1.7-3L13.7 4.3a2 2 0 0 0-3.4 0Z'/%3E%3Cpath d='M12 9.5v4M12 17h.01'/%3E%3C/svg%3E"); }
.notice[data-kind="info"] { --notice-fg: var(--info-text); --notice-bg: var(--info-soft); --notice-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11v5.5M12 7.5h.01'/%3E%3C/svg%3E"); }
@keyframes notice-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.status-line { font-size: .84rem; color: var(--ink-3); }

.badge { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: 999px; font-size: .75rem; font-weight: 700; letter-spacing: .01em; background: var(--surface-3); color: var(--ink-2); white-space: nowrap; }
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .85; }
.badge[data-state="ok"], .badge[data-tone="ok"] { background: var(--accent-soft); color: var(--accent-text); }
.badge[data-state="warning"], .badge[data-tone="warning"] { background: var(--warning-soft); color: var(--warning-text); }
.badge[data-tone="danger"] { background: var(--danger-soft); color: var(--danger-text); }
.badge[data-tone="violet"] { background: var(--violet-soft); color: var(--violet-text); }
.badge[data-tone="gold"] { background: color-mix(in srgb, var(--gold) 16%, var(--surface)); color: var(--warning-text); }
.badge[data-tone="info"] { background: var(--info-soft); color: var(--info-text); }

.chip { position: relative; display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 15px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); font-size: .875rem; font-weight: 600; white-space: nowrap; box-shadow: var(--shadow-xs); }
.chip:hover { color: var(--ink); border-color: var(--line-2); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); box-shadow: 0 6px 16px -8px rgb(15 26 20 / .5); }
:root[data-theme="dark"] .chip[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }

.tag { display: inline-flex; align-items: center; height: 24px; padding: 0 9px; border-radius: 7px; background: var(--violet-soft); color: var(--violet-text); font-size: .75rem; font-weight: 700; white-space: nowrap; transition: filter .2s; }
a.tag:hover { filter: brightness(.96) saturate(1.2); }
.tag-list { display: flex; flex-wrap: wrap; gap: 6px; }
.tag-list:empty { display: none; }

/* ---------- Surfaces ---------- */
.card { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
.spotlight { --mx: 50%; --my: 50%; isolation: isolate; }
.spotlight::after { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity .35s; background: radial-gradient(420px circle at var(--mx) var(--my), color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%); }
@media (hover: hover) { .spotlight:hover::after { opacity: 1; } }

.divider { display: flex; align-items: center; gap: 14px; color: var(--ink-3); font-size: .8rem; }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.disclosure { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); overflow: hidden; }
.disclosure > summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 16px; font-weight: 650; cursor: pointer; transition: background-color .2s; }
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::after { content: ""; width: 9px; height: 9px; border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3); transform: rotate(45deg) translate(-2px, -2px); transition: transform .3s var(--ease-out); flex-shrink: 0; }
.disclosure[open] > summary::after { transform: rotate(225deg) translate(-2px, -2px); }
.disclosure > summary:hover { background: var(--surface-2); }
.disclosure-body { padding: 4px 16px 18px; }
.disclosure[open] .disclosure-body { animation: notice-in .3s var(--ease-out); }

/* ---------- Dialog ---------- */
.modal { width: min(460px, calc(100% - 32px)); max-height: calc(100dvh - 48px); padding: 0; border: 1px solid var(--line); border-radius: 22px; background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg); overflow: auto; }
.modal::backdrop { background: rgb(9 16 12 / .38); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); }
.modal[open] { animation: modal-in .32s var(--ease-out); }
.modal[open]::backdrop { animation: fade-in .3s ease-out; }
.modal-inner { display: grid; gap: 18px; padding: 26px; }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.modal-head h2 { font-size: 1.3rem; }
.modal-head p { margin-top: 6px; color: var(--ink-3); font-size: .9rem; }
.modal-close { display: grid; place-items: center; width: 34px; height: 34px; flex-shrink: 0; margin: -4px -6px 0 0; border: 0; border-radius: 10px; background: var(--surface-2); color: var(--ink-3); }
.modal-close:hover { color: var(--ink); background: var(--surface-3); }
@keyframes modal-in { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@media (max-width: 560px) {
  .modal { width: 100%; max-width: none; margin: auto 0 0; border-radius: 22px 22px 0 0; max-height: 92dvh; }
  .modal[open] { animation-name: sheet-in; }
  .modal-inner { padding: 22px 18px calc(22px + env(safe-area-inset-bottom)); }
}
@keyframes sheet-in { from { transform: translateY(40px); opacity: .4; } to { transform: none; opacity: 1; } }

/* ---------- Announcement content blocks ---------- */
/* Shared by the public body, the page popup and the admin preview (--ann-bg is the surface they sit on). */
.ann-flow { --ann-bg: var(--surface); }
.ann-flow:is([data-format="blocks"], [data-format="rich"]) { white-space: normal; }
.ann-flow:is([data-format="blocks"], [data-format="rich"]) > * + * { margin-top: 1em; }
.ann-paragraph, .ann-quote, .ann-list li { white-space: pre-wrap; overflow-wrap: anywhere; }
.ann-heading { display: flex; align-items: baseline; gap: .5em; font-weight: 800; letter-spacing: -.03em; line-height: 1.35; overflow-wrap: anywhere; }
h2.ann-heading { font-size: 1.42em; }
h3.ann-heading { font-size: 1.15em; }
h2.ann-heading::before { content: ""; flex: none; width: .38em; height: .38em; translate: 0 -.14em; background: var(--brand-gradient); }
.ann-flow:is([data-format="blocks"], [data-format="rich"]) > * + .ann-heading { margin-top: 1.75em; }
.ann-flow:is([data-format="blocks"], [data-format="rich"]) > .ann-heading + * { margin-top: .6em; }
.ann-list { display: grid; gap: .3em; padding-left: 1.55em; }
ul.ann-list { list-style: square outside; }
ol.ann-list { list-style: decimal outside; }
.ann-list li { padding-left: .25em; }
.ann-list li::marker { color: var(--accent-text); font-weight: 800; font-variant-numeric: tabular-nums; }
.ann-quote { position: relative; margin: 0; padding: .8em 1.1em .8em 1.3em; border-radius: 0 14px 14px 0; background: var(--surface-2); color: var(--ink-2); }
.ann-quote::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--brand-gradient); }
/* A pixel-dashed rule with a gem in the middle. */
.ann-divider { position: relative; height: 4px; border: 0; overflow: visible; background: repeating-linear-gradient(90deg, var(--line-2) 0 8px, transparent 8px 16px); }
.ann-divider::after { content: ""; position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; translate: -50% -50%; rotate: 45deg; background: var(--brand-gradient); box-shadow: 0 0 0 6px var(--ann-bg); }
.ann-flow:is([data-format="blocks"], [data-format="rich"]) > .ann-divider { margin-block: 1.9em; }
.ann-figure { width: var(--ann-figure-width, 100%); max-width: 100%; margin: 0 auto; }
.ann-figure[data-align="left"] { margin-left: 0; }
.ann-figure[data-align="right"] { margin-right: 0; }
.ann-flow:is([data-format="blocks"], [data-format="rich"]) > .ann-figure { margin-top: 1.5em; }
.ann-flow:is([data-format="blocks"], [data-format="rich"]) > .ann-figure + * { margin-top: 1.5em; }
.ann-figure-frame { position: relative; overflow: hidden; border-radius: 14px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.ann-figure img { display: block; width: 100%; height: auto; }
.ann-figure img[data-state="loading"] { min-height: 120px; background: linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--surface) 70%, transparent) 50%, transparent 70%) 0 0 / 300% 100% var(--surface-2); animation: ann-shimmer 1.4s linear infinite; }
.ann-figure img[data-state="ready"] { animation: ann-reveal .45s var(--ease-out); }
.ann-figure img[data-state="error"] { display: none; }
@keyframes ann-shimmer { to { background-position: -150% 0; } }
@keyframes ann-reveal { from { opacity: 0; } }
.ann-figure-fallback { display: none; }
.ann-figure img[data-state="error"] + .ann-figure-fallback { display: grid; place-content: center; gap: 4px; min-height: 140px; padding: 20px; text-align: center; font-size: .86rem; line-height: 1.5; color: var(--ink-3); background: repeating-linear-gradient(-45deg, transparent 0 10px, color-mix(in srgb, var(--line) 70%, transparent) 10px 20px); overflow-wrap: anywhere; }
.ann-figure-fallback strong { color: var(--ink-2); font-weight: 650; }
.ann-figure figcaption { margin-top: .6em; font-size: .86em; line-height: 1.6; color: var(--ink-3); text-align: center; overflow-wrap: anywhere; }
.ann-figure[data-align="left"] figcaption { text-align: left; }
.ann-figure[data-align="right"] figcaption { text-align: right; }
/* The whole picture is the button that opens the viewer; a magnifier tab shows on hover, and always on touch screens. */
.ann-figure-zoom { display: none; position: absolute; inset: 0; width: 100%; padding: 0; border: 0; border-radius: inherit; background: none; color: #fff; cursor: zoom-in; }
.ann-figure img[data-state="ready"] ~ .ann-figure-zoom { display: block; }
.ann-figure-zoom:focus-visible { outline-offset: -3px; }
.ann-figure-zoom svg.icon { position: absolute; top: 10px; right: 10px; box-sizing: content-box; width: 18px; height: 18px; padding: 8px; border-radius: 11px; background: rgb(9 16 12 / .58); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .16); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); stroke-width: 2.2; opacity: 0; scale: .8; transition: opacity .2s, scale .3s var(--ease-out); }
.ann-figure-zoom:is(:hover, :focus-visible) svg.icon { opacity: 1; scale: 1; }
@media (hover: none) { .ann-figure-zoom svg.icon { opacity: .9; scale: .86; } }
.ann-figure[data-viewing="true"] img { visibility: hidden; }

/* ---------- Announcement covers (the list and the homepage band) ---------- */
/* A pixel landscape, and the announcement's own picture fading in over it once it has loaded. */
.news-cover { position: relative; display: block; overflow: hidden; isolation: isolate; background: #82aff4; }
.news-cover::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px rgb(0 0 0 / .07); pointer-events: none; }
.news-cover-art, .news-cover-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease-out), opacity .6s var(--ease-out), filter .6s var(--ease-out); }
.news-cover-art { image-rendering: pixelated; }
.news-cover-photo { opacity: 0; filter: blur(10px); transform: scale(1.08); }
.news-cover-photo[data-state="ready"] { opacity: 1; filter: none; transform: none; }
:root[data-theme="dark"] .news-cover-art { filter: brightness(.82) saturate(.9); }
/* Halftone Reveal: the loaded picture shows through dots that grow from the top-left corner (announcement-cover.js). */
.news-cover-halftone { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.news-cover-photo.is-instant { transition: none; }
@media (hover: hover) { a:hover > .news-cover > :is(.news-cover-art, .news-cover-photo[data-state="ready"]) { transform: scale(1.06); } }
@media (prefers-reduced-motion: reduce) { .news-cover-art, .news-cover-photo { transition: opacity .3s; } }

/* ---------- Announcement picture viewer ---------- */
.ann-zoom { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: none; color: #f2f7f3; overflow: hidden; }
.ann-zoom::backdrop { background: none; }
:root:has(.ann-zoom[open]) { overflow: hidden; }
.ann-zoom-shade { position: absolute; inset: 0; background: radial-gradient(120% 90% at 50% 45%, rgb(14 26 19 / .9), rgb(4 8 6 / .96)); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.ann-zoom-shade::after { content: ""; position: absolute; inset: 0; background-image: linear-gradient(rgb(255 255 255 / .035) 1px, transparent 1px), linear-gradient(90deg, rgb(255 255 255 / .035) 1px, transparent 1px); background-size: 24px 24px; -webkit-mask-image: radial-gradient(70% 70% at 50% 50%, transparent 30%, #000); mask-image: radial-gradient(70% 70% at 50% 50%, transparent 30%, #000); }
.ann-zoom-stage { position: absolute; inset: 0; display: flex; padding: 68px clamp(16px, 8vw, 96px) 88px; overflow: hidden; overscroll-behavior: contain; touch-action: pinch-zoom; scrollbar-width: thin; scrollbar-color: rgb(255 255 255 / .3) transparent; }
.ann-zoom-image { display: block; margin: auto; max-width: 100%; max-height: 100%; border-radius: 8px; box-shadow: 0 0 0 1px rgb(255 255 255 / .08), 0 40px 90px -30px rgb(0 0 0 / .85); transform-origin: 0 0; cursor: zoom-out; user-select: none; -webkit-user-drag: none; }
.ann-zoom[data-zoomable="true"] .ann-zoom-image { cursor: zoom-in; }
.ann-zoom[data-zoom="actual"] .ann-zoom-stage { padding: 0; overflow: auto; touch-action: auto; }
.ann-zoom[data-zoom="actual"] .ann-zoom-image { max-width: none; max-height: none; border-radius: 0; box-shadow: none; cursor: zoom-out; }
.ann-zoom[data-zoom="actual"] :is(.ann-zoom-bar, .ann-zoom-prev, .ann-zoom-next) { opacity: 0; pointer-events: none; }
.ann-zoom-button { position: absolute; z-index: 1; display: grid; place-items: center; width: 46px; height: 46px; padding: 0; border: 0; border-radius: 14px; background: rgb(255 255 255 / .09); color: #fff; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .14); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); transition: background-color .2s, color .2s, opacity .2s; }
.ann-zoom-button:hover { background: var(--accent); color: var(--accent-ink); }
.ann-zoom-button svg.icon { stroke-width: 2.2; }
.ann-zoom-close { top: 14px; right: 14px; }
.ann-zoom-prev, .ann-zoom-next { top: 50%; margin-top: -23px; }
.ann-zoom-prev { left: 14px; }
.ann-zoom-next { right: 14px; }
.ann-zoom-bar { position: absolute; z-index: 1; left: 50%; bottom: 20px; translate: -50% 0; display: flex; align-items: center; gap: 14px; width: max-content; max-width: calc(100% - 32px); padding: 9px 16px; border-radius: 14px; background: rgb(255 255 255 / .08); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .12); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); font-size: .875rem; line-height: 1.55; pointer-events: none; transition: opacity .2s; }
.ann-zoom-caption { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.ann-zoom-count { flex: none; color: rgb(255 255 255 / .66); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.ann-zoom-caption:not([hidden]) + .ann-zoom-count { padding-left: 14px; border-left: 1px solid rgb(255 255 255 / .18); }
@media (max-width: 640px) {
  .ann-zoom-stage { padding: 64px 0 84px; }
  .ann-zoom-image { border-radius: 0; }
  .ann-zoom-prev, .ann-zoom-next { top: auto; bottom: 16px; margin-top: 0; width: 42px; height: 42px; }
  .ann-zoom-bar { bottom: calc(16px + env(safe-area-inset-bottom)); max-width: calc(100% - 128px); padding: 8px 12px; }
  .ann-zoom-prev, .ann-zoom-next { bottom: calc(16px + env(safe-area-inset-bottom)); }
}

/* ---------- Announcement rich text ---------- */
/* Text colours and highlights for the body only, each with its own light and dark value so that a coloured word on a
   highlight stays readable in both themes. Sizes are fixed pixel steps; a span without one inherits its block's. */
:root {
  --ann-red: #c42b1c; --ann-orange: #b45309; --ann-green: #15803d; --ann-blue: #1d4ed8; --ann-purple: #7e22ce;
  --ann-hl-yellow: #fff0a3; --ann-hl-green: #d2f4dc; --ann-hl-blue: #d9e6ff; --ann-hl-pink: #ffdcea;
  --ann-link: #1a6fd1;
}
:root[data-theme="dark"] {
  --ann-red: #ff8f85; --ann-orange: #fdb873; --ann-green: #72e3a0; --ann-blue: #93b5ff; --ann-purple: #d2abff;
  --ann-hl-yellow: rgb(250 204 21 / .27); --ann-hl-green: rgb(74 222 128 / .2); --ann-hl-blue: rgb(96 165 250 / .25); --ann-hl-pink: rgb(244 114 182 / .25);
  --ann-link: #8fc0ff;
}
.ann-text[data-size="14"] { font-size: 14px; }
.ann-text[data-size="16"] { font-size: 16px; }
.ann-text[data-size="18"] { font-size: 18px; }
.ann-text[data-size="24"] { font-size: 24px; letter-spacing: -.015em; }
.ann-text[data-size="32"] { font-size: 32px; letter-spacing: -.025em; line-height: 1.3; }
.ann-text[data-color="default"] { color: var(--ink); }
.ann-text[data-color="muted"] { color: var(--ink-3); }
.ann-text[data-color="accent"] { color: var(--accent-text); }
.ann-text[data-color="red"] { color: var(--ann-red); }
.ann-text[data-color="orange"] { color: var(--ann-orange); }
.ann-text[data-color="green"] { color: var(--ann-green); }
.ann-text[data-color="blue"] { color: var(--ann-blue); }
.ann-text[data-color="purple"] { color: var(--ann-purple); }
.ann-text[data-highlight] { padding: .04em .14em; border-radius: .22em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.ann-text[data-highlight="yellow"] { background: var(--ann-hl-yellow); }
.ann-text[data-highlight="green"] { background: var(--ann-hl-green); }
.ann-text[data-highlight="blue"] { background: var(--ann-hl-blue); }
.ann-text[data-highlight="pink"] { background: var(--ann-hl-pink); }
/* Chinese fonts have no italic face; the body lets the browser slant them, so italic text still looks italic. */
.ann-flow strong { font-weight: 760; }
.ann-flow em { font-synthesis: style; }
.ann-flow u { text-underline-offset: .2em; }
.ann-flow s { text-decoration-thickness: .08em; }
.ann-flow :not(pre) > code { padding: .08em .38em; border-radius: 6px; background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--line); font-family: var(--font-mono); font-size: .86em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
/* A link is always underlined, so it never depends on colour alone; one leaving the site also carries an arrow. */
.ann-flow { --ann-out: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E"); }
.ann-link { color: var(--ann-link); text-decoration: underline; text-decoration-thickness: .075em; text-underline-offset: .22em; text-decoration-color: color-mix(in srgb, currentColor 50%, transparent); overflow-wrap: anywhere; transition: text-decoration-color .2s; }
.ann-link:hover { text-decoration-color: currentColor; }
.ann-link[data-external]::after, .ann-button[data-external]::after { content: ""; display: inline-block; width: .7em; height: .7em; margin-left: .2em; vertical-align: .02em; background: currentColor; -webkit-mask: var(--ann-out) center / contain no-repeat; mask: var(--ann-out) center / contain no-repeat; }
.ann-paragraph[data-align="center"], .ann-button-row[data-align="center"] { text-align: center; justify-content: center; }
.ann-paragraph[data-align="right"], .ann-button-row[data-align="right"] { text-align: right; justify-content: flex-end; }
.ann-heading[data-align="center"] { justify-content: center; text-align: center; }
.ann-heading[data-align="right"] { justify-content: flex-end; text-align: right; }
.ann-heading-text { min-width: 0; }
.ann-flow[data-format="rich"] > :is(.ann-callout, .ann-table-wrap, .ann-code, .ann-details, .ann-button-row) { margin-top: 1.3em; }
.ann-flow[data-format="rich"] > :is(.ann-callout, .ann-table-wrap, .ann-code, .ann-details, .ann-button-row) + * { margin-top: 1.3em; }
.ann-flow[data-format="rich"] > :first-child { margin-top: 0; }
.ann-button-row { display: flex; flex-wrap: wrap; }
.ann-button { display: inline-flex; align-items: center; justify-content: center; max-width: 100%; min-height: 46px; padding: .5em 1.4em; border-radius: 13px; font-weight: 750; line-height: 1.45; text-align: center; text-decoration: none; white-space: normal; overflow-wrap: anywhere; transition: transform .25s var(--ease-out), box-shadow .25s, background-color .2s; }
.ann-button[data-variant="primary"] { background: var(--accent); color: var(--accent-ink); box-shadow: 0 10px 24px -12px color-mix(in srgb, var(--accent) 85%, transparent), inset 0 1px 0 rgb(255 255 255 / .28); }
.ann-button[data-variant="secondary"] { background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--line-2), var(--shadow-xs); }
a.ann-button:hover { transform: translateY(-2px); }
a.ann-button[data-variant="primary"]:hover { background: var(--accent-hover); }
a.ann-button[data-variant="secondary"]:hover { box-shadow: inset 0 0 0 1.5px var(--accent), var(--shadow-sm); }
a.ann-button:focus-visible, .ann-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
span.ann-button { opacity: .6; }
.ann-callout { --callout: var(--info-text); --callout-soft: var(--info-soft); display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .75em; align-items: start; padding: .9em 1.15em .9em .95em; border-radius: 14px; background: var(--callout-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--callout) 22%, transparent); }
.ann-callout[data-tone="success"] { --callout: var(--accent-text); --callout-soft: var(--accent-soft); }
.ann-callout[data-tone="warning"] { --callout: var(--warning-text); --callout-soft: var(--warning-soft); }
.ann-callout[data-tone="danger"] { --callout: var(--danger-text); --callout-soft: var(--danger-soft); }
.ann-callout > svg.icon { width: 1.3em; height: 1.3em; margin-top: .3em; color: var(--callout); stroke-width: 2.1; }
.ann-callout-content { display: grid; gap: .2em; min-width: 0; }
.ann-callout-title { font-weight: 760; color: var(--callout); overflow-wrap: anywhere; }
.ann-callout-text { white-space: pre-wrap; overflow-wrap: anywhere; }
/* Tables and code scroll sideways inside their own frame, so the page itself never does. */
.ann-table-wrap { max-width: 100%; overflow-x: auto; border-radius: 14px; background: var(--ann-bg); box-shadow: inset 0 0 0 1px var(--line); scrollbar-width: thin; }
.ann-table-wrap:focus-visible, .ann-code-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ann-table { width: 100%; border-collapse: collapse; font-size: .94em; line-height: 1.65; }
.ann-table th, .ann-table td { min-width: 7.5em; padding: .6em .95em; text-align: left; vertical-align: top; white-space: pre-wrap; overflow-wrap: anywhere; border-bottom: 1px solid var(--line); }
.ann-table :is(th, td) + :is(th, td) { border-left: 1px solid var(--line); }
.ann-table tr:last-child > td { border-bottom: 0; }
.ann-table thead th { background: var(--surface-2); font-weight: 760; }
.ann-table tbody tr:nth-child(even) > td { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }
.ann-code { overflow: hidden; border-radius: 14px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.ann-code-bar { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 5px 6px 5px 14px; border-bottom: 1px solid var(--line); font-size: .78rem; line-height: 1.4; }
.ann-code-lang { font-family: var(--font-mono); font-weight: 650; color: var(--ink-3); overflow-wrap: anywhere; }
.ann-code-lang:empty { display: none; }
.ann-code-status { margin-left: auto; font-weight: 650; color: var(--accent-text); }
.ann-code-copy { min-height: 30px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink-2); font: inherit; font-weight: 650; cursor: pointer; transition: color .2s, border-color .2s; }
.ann-code-copy:hover { border-color: var(--line-2); color: var(--ink); }
.ann-code-copy[data-state="failed"], .ann-code-status[data-state="failed"] { color: var(--danger-text); }
.ann-code-scroll { overflow-x: auto; scrollbar-width: thin; }
.ann-code pre { margin: 0; padding: 14px 16px; font-family: var(--font-mono); font-size: .85em; line-height: 1.7; white-space: pre; overflow-wrap: normal; tab-size: 4; color: var(--ink); }
.ann-details { border-radius: 14px; background: var(--ann-bg); box-shadow: inset 0 0 0 1px var(--line); }
.ann-details-summary { display: flex; align-items: center; gap: .65em; padding: .75em 1.05em; border-radius: 14px; font-weight: 720; cursor: pointer; list-style: none; overflow-wrap: anywhere; }
.ann-details-summary::-webkit-details-marker { display: none; }
.ann-details-summary::before { content: ""; flex: none; width: .48em; height: .48em; margin-left: .1em; border-right: 2px solid var(--accent-text); border-bottom: 2px solid var(--accent-text); rotate: -45deg; transition: rotate .2s var(--ease-out); }
.ann-details[open] > .ann-details-summary::before { rotate: 45deg; }
.ann-details-summary:hover { background: var(--surface-2); }
.ann-details-summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ann-details[open] > .ann-details-summary { border-radius: 14px 14px 0 0; }
.ann-details-body { padding: .35em 1.1em 1.1em; }
.ann-details-body > * + * { margin-top: 1em; }

/* ---------- Announcement popup ---------- */
/* One dialog for every page an announcement can target: the head and the close button stay put while the body scrolls. */
.ann-popup { width: min(660px, calc(100% - 32px)); overflow: hidden; }
.ann-popup::before { content: ""; position: absolute; inset: 0 0 auto; height: 4px; background: var(--brand-gradient); animation: brand-flow 9s linear infinite; }
.ann-popup-inner { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; max-height: calc(100dvh - 48px); }
.ann-popup-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 28px 26px 16px; }
.ann-popup-heading { display: grid; gap: 8px; min-width: 0; }
.ann-popup-kicker { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: .75rem; font-weight: 750; letter-spacing: .06em; color: var(--accent-text); }
.ann-popup-kicker > span:first-child { display: inline-flex; align-items: center; gap: 7px; }
.ann-popup-kicker > span:first-child::before { content: ""; width: 8px; height: 8px; rotate: 45deg; background: var(--brand-gradient); }
.ann-popup-category { padding: 2px 9px; border-radius: 99px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); color: var(--ink-2); letter-spacing: .02em; overflow-wrap: anywhere; }
.ann-popup-machine { padding: 2px 9px; border-radius: 99px; background: var(--violet-soft); color: var(--violet-text); letter-spacing: .02em; }
.ann-popup-title { font-size: clamp(1.3rem, 3.2vw, 1.65rem); font-weight: 800; letter-spacing: -.035em; line-height: 1.25; overflow-wrap: anywhere; }
.ann-popup-scroll { padding: 0 26px 22px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
.ann-popup-summary { position: relative; margin-bottom: 18px; padding: 2px 0 2px 16px; color: var(--ink-2); line-height: 1.75; white-space: pre-wrap; overflow-wrap: anywhere; }
.ann-popup-summary::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; border-radius: 3px; background: var(--brand-gradient); }
.ann-popup-body { font-size: .95rem; line-height: 1.85; white-space: pre-wrap; overflow-wrap: anywhere; }
.ann-popup-actions { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 26px 22px; border-top: 1px solid var(--line); background: var(--surface); }
@media (max-width: 560px) {
  .ann-popup { width: 100%; }
  .ann-popup-inner { max-height: 92dvh; }
  .ann-popup-head { padding: 24px 18px 12px; }
  .ann-popup-scroll { padding: 0 18px 18px; }
  .ann-popup-actions { padding: 12px 18px calc(14px + env(safe-area-inset-bottom)); }
  .ann-popup-actions .btn { flex: 1; }
}

/* ---------- Custom select (listbox) ---------- */
.select { display: grid; gap: 6px; min-width: 0; }
.select > span { font-size: .75rem; font-weight: 700; color: var(--ink-3); letter-spacing: .02em; }
.select-control { position: relative; }
.select-trigger { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 40px; padding: 0 12px 0 14px; border: 1px solid var(--line); border-radius: 11px; background: var(--surface); box-shadow: var(--shadow-xs); font-size: .875rem; font-weight: 600; color: var(--ink); text-align: left; }
.select-trigger:hover { border-color: var(--line-2); }
.select-trigger svg { width: 16px; height: 16px; fill: none; stroke: var(--ink-3); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .25s var(--ease-out); flex-shrink: 0; }
.select-control[data-open="true"] .select-trigger { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring); }
.select-control[data-open="true"] .select-trigger svg { transform: rotate(180deg); }
.select-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.select-menu { position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 8px); min-width: 180px; max-height: var(--menu-max-height, 268px); overflow-y: auto; overscroll-behavior: contain; padding: 6px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); box-shadow: var(--shadow-lg); animation: select-in .2s var(--ease-out); transform-origin: top center; scrollbar-width: thin; }
.select-control[data-placement="top"] .select-menu { top: auto; bottom: calc(100% + 8px); transform-origin: bottom center; }
.select-option { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 40px; padding: 0 12px; border-radius: 9px; font-size: .875rem; font-weight: 550; color: var(--ink-2); cursor: pointer; user-select: none; }
.select-option[data-active="true"] { background: var(--surface-2); color: var(--ink); }
.select-option[aria-selected="true"] { color: var(--accent-text); font-weight: 700; }
.select-check { opacity: 0; font-size: .8rem; }
.select-option[aria-selected="true"] .select-check { opacity: 1; }
@keyframes select-in { from { opacity: 0; transform: scale(.97) translateY(-4px); } to { opacity: 1; transform: none; } }
/* Glide Select: the menu pops from its corner and one highlight glides between the options. */
.select-control.is-glide .select-menu { animation: glide-pop .4s var(--spring); transform-origin: 16px 0; }
.select-control.is-glide[data-placement="top"] .select-menu { transform-origin: 16px 100%; }
@keyframes glide-pop { from { opacity: 0; transform: scale(.4); border-radius: 40px; } 50% { opacity: 1; } to { transform: none; } }
.glide-hl { position: absolute; left: 6px; right: 6px; top: 0; height: 40px; border-radius: 9px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); opacity: 0; transition: transform .34s cubic-bezier(.34, 1.36, .64, 1), height .2s; pointer-events: none; }
.is-glide .select-option { position: relative; z-index: 1; transition: color .2s, translate .25s var(--ease-out); }
.is-glide .select-option[data-active="true"] { background: none; translate: 3px 0; }

/* ---------- Loading ---------- */
/* Lattice Loader: the cells light up in waves; shell.js fills the grid and runs the stopwatch beside page-sized loaders. */
.lattice { display: grid; grid-template-columns: repeat(4, 7px); gap: 3px; flex-shrink: 0; }
.lattice i { width: 7px; height: 7px; border-radius: 2px; background: var(--accent); animation: lattice 1.3s ease-in-out infinite; animation-delay: calc(var(--d) * 95ms); }
.lattice-lg { grid-template-columns: repeat(4, 10px); gap: 4px; }
.lattice-lg i { width: 10px; height: 10px; border-radius: 3px; }
@keyframes lattice { 0%, 55%, 100% { opacity: .16; scale: .78; } 22% { opacity: 1; scale: 1; } }
.lattice-clock { min-width: 4.2em; padding: 3px 8px; border-radius: 7px; background: var(--surface-2); color: var(--ink-3); font-family: var(--font-mono); font-size: .76rem; font-variant-numeric: tabular-nums; text-align: right; }
.lattice-clock:empty { display: none; }
.skeleton { position: relative; overflow: hidden; background: var(--surface-3); border-radius: 8px; }
.skeleton::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--surface) 65%, transparent) 50%, transparent 80%); animation: skeleton 1.4s ease-in-out infinite; }
@keyframes skeleton { to { transform: translateX(100%); } }

.empty { display: grid; justify-items: center; gap: 10px; padding: 56px 20px; text-align: center; color: var(--ink-3); }
.empty strong { color: var(--ink); font-size: 1.05rem; }
.empty-art { width: 64px; height: 64px; margin-bottom: 6px; image-rendering: pixelated; }

/* ---------- Avatars ---------- */
/* Keep a single opaque layer under the rounded clip: stacked layers bleed through its anti-aliased edge as a dark fringe. */
.author-avatar, .player-avatar { position: relative; display: inline-grid; place-items: center; flex-shrink: 0; overflow: hidden; border-radius: 7px; color: #fff; font-weight: 800; line-height: 1; }
.author-avatar { width: 24px; height: 24px; font-size: .72rem; }
.player-avatar { width: 96px; height: 96px; border-radius: 22px; font-size: 2.4rem; box-shadow: var(--shadow-md); }
.avatar-fallback { position: absolute; inset: 0; background: url("/assets/preview/steve-head.svg") center / cover no-repeat; image-rendering: pixelated; }
.author-avatar img, .player-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; }

/* ---------- Supporter badge ---------- */
/* Drawn only from a server badge list; the icon is the fixed site asset and falls back to the emoji if it fails to load. */
.supporter-badge { position: relative; display: inline-grid; place-items: center; flex-shrink: 0; width: 1.15em; height: 1.15em; line-height: 1; vertical-align: -.2em; }
.supporter-badge img { width: 100%; height: 100%; filter: drop-shadow(0 1px 2px rgb(194 48 122 / .35)); }
.supporter-badge[data-fallback] { font-size: .92em; }
.supporter-badge::after { content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 8px); z-index: 5; padding: 5px 9px; border-radius: 8px; background: var(--ink); color: var(--surface); font-family: var(--font-sans); font-size: .72rem; font-weight: 700; letter-spacing: .02em; line-height: 1.3; white-space: nowrap; pointer-events: none; opacity: 0; translate: -50% 4px; transition: opacity .18s, translate .18s var(--ease-out); }
.supporter-badge:hover::after, a:focus-visible .supporter-badge::after { opacity: 1; translate: -50% 0; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) { a:hover .supporter-badge img, .supporter-badge:hover img { animation: supporter-beat .7s var(--ease-out); } }
@keyframes supporter-beat { 0% { scale: 1; } 28% { scale: 1.3; } 52% { scale: .92; } 74% { scale: 1.08; } 100% { scale: 1; } }
.badge[data-tone="supporter"] { background: var(--supporter-soft); color: var(--supporter); }

/* ---------- Xianyu tickets ---------- */
/* What a Xianyu buyer gets is a code sent in the chat, so each item is a ticket: what it is on the left, the price and
   the way out on a torn-off yellow stub. The sponsor page and 赞助权益 on the account page both draw them. */
.market-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 380px), 1fr)); gap: 18px; }
.market-item { filter: drop-shadow(0 1px 1px rgb(15 26 20 / .08)) drop-shadow(0 12px 18px rgb(15 26 20 / .09)); transition: filter .25s var(--ease-out); }
.market-item:has(.market-buy:not([aria-disabled="true"]):is(:hover, :focus-visible)) { filter: drop-shadow(0 1px 1px rgb(15 26 20 / .08)) drop-shadow(0 16px 24px rgb(200 150 0 / .26)); }
.market-ticket { --stub: 150px; --notch: radial-gradient(circle 10px at calc(100% - var(--stub)) 0, #0000 97%, #000) top / 100% 51% no-repeat, radial-gradient(circle 10px at calc(100% - var(--stub)) 100%, #0000 97%, #000) bottom / 100% 51% no-repeat;
  display: grid; grid-template-columns: minmax(0, 1fr) var(--stub); height: 100%; min-height: 150px; border-radius: 18px; overflow: hidden; background: var(--surface); -webkit-mask: var(--notch); mask: var(--notch); }
.market-body { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; padding: 18px 20px; }
.market-kind { display: inline-flex; align-items: center; gap: 6px; color: var(--supporter); font-size: .8rem; font-weight: 750; }
.market-item[data-product^="CAPE"] .market-kind { color: var(--violet-text); }
.market-kind svg.icon { width: 15px; height: 15px; stroke-width: 2.2; }
.market-name { font-family: var(--font-display); font-size: 1.08rem; font-weight: 800; line-height: 1.35; letter-spacing: -.01em; overflow-wrap: anywhere; }
.market-term { padding: 2px 9px; border-radius: 999px; background: var(--surface-3); color: var(--ink-2); font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.market-notes { display: grid; gap: 4px; margin-top: 4px; }
.market-notes li { position: relative; padding-left: 14px; color: var(--ink-3); font-size: .84rem; line-height: 1.6; }
.market-notes li::before { content: ""; position: absolute; left: 1px; top: .66em; width: 5px; height: 5px; background: currentColor; opacity: .55; }
.market-notes li[data-tone="warning"] { color: var(--warning-text); font-weight: 650; }
.market-stub { position: relative; display: grid; place-content: center; justify-items: center; gap: 12px; padding: 18px 14px; border-left: 2px dashed rgb(70 50 0 / .28); background: #ffe14d; color: #2b2100;
  background-image: radial-gradient(circle at 100% 0, rgb(255 255 255 / .55), transparent 55%), repeating-linear-gradient(135deg, rgb(255 255 255 / .16) 0 6px, transparent 6px 12px); }
.market-price { font-family: var(--font-display); font-size: 1.85rem; font-weight: 800; letter-spacing: -.035em; line-height: 1; font-variant-numeric: tabular-nums; }
.market-buy { --btn-bg: #1d1a10; --btn-fg: #ffe14d; --btn-border: transparent; white-space: nowrap; }
.market-buy:hover:not(:disabled):not([aria-disabled="true"]) { --btn-bg: #000; --btn-border: transparent; }
/* A barred account's cape item: the stub stays, the way out is a dashed outline that goes nowhere. */
.market-buy[aria-disabled="true"] { --btn-bg: transparent; --btn-fg: #5c4a00; --btn-border: rgb(70 50 0 / .4); border-style: dashed; box-shadow: none; cursor: not-allowed; }
:root[data-theme="dark"] .market-item { filter: drop-shadow(0 12px 20px rgb(0 0 0 / .45)); }
:root[data-theme="dark"] .market-ticket { background: var(--surface-2); }
:root[data-theme="dark"] .market-stub { background-color: #f2cf2e; }
@media (max-width: 560px) {
  .market-ticket { --stub: 118px; }
  .market-body { padding: 16px; }
  .market-stub { padding: 16px 10px; }
  .market-price { font-size: 1.5rem; }
}
/* ---------- Code field (兑换与订单 on the account page, and the sponsor page) ---------- */
/* One field takes a 权益兑换码 or an afdian 领取码. A redemption code opens a ticket to confirm: two notches cut at the
   perforation, a stub with the product glyph, and a stamp once it is redeemed. */
@keyframes pop-in { 0% { opacity: 0; transform: scale(.96); } 60% { opacity: 1; transform: scale(1.01); } 100% { transform: none; } }
.code-entry { display: grid; min-width: 0; }
.redeem-form { display: grid; gap: 8px; }
.redeem-entry { display: flex; flex-wrap: wrap; gap: 8px; }
.redeem-input { flex: 1 1 180px; min-width: 0; font-family: var(--font-mono); letter-spacing: .04em; }
.redeem-form .notice, .redeem-confirm .notice { margin: 0; }
.redeem-confirm { display: grid; gap: 14px; animation: pop-in .5s var(--ease-out); }
.redeem-ticket-wrap { filter: drop-shadow(0 16px 22px rgb(155 77 255 / .26)); }
.redeem-ticket-wrap:has([data-product^="CAPE"]) { filter: drop-shadow(0 16px 22px rgb(63 196 119 / .24)); }
.redeem-ticket { --ticket: linear-gradient(var(--brand-angle), #ff4f9a, #9b4dff); --notch: radial-gradient(circle 11px at 78px 0, #0000 97%, #000) top / 100% 51% no-repeat, radial-gradient(circle 11px at 78px 100%, #0000 97%, #000) bottom / 100% 51% no-repeat; position: relative; isolation: isolate; display: grid; grid-template-columns: 78px minmax(0, 1fr); min-height: 116px; border-radius: 18px; overflow: hidden; color: #fff; background: var(--ticket); -webkit-mask: var(--notch); mask: var(--notch); animation: brand-flow 12s linear infinite; }
.redeem-ticket[data-product^="CAPE"] { --ticket: linear-gradient(var(--brand-angle), #2fb86a, #6a3fd2); }
.redeem-ticket::before { content: ""; position: absolute; inset: 0; z-index: -1; background-image: linear-gradient(rgb(255 255 255 / .09) 1px, transparent 1px), linear-gradient(90deg, rgb(255 255 255 / .09) 1px, transparent 1px); background-size: 12px 12px; -webkit-mask-image: linear-gradient(105deg, #000 20%, transparent 75%); mask-image: linear-gradient(105deg, #000 20%, transparent 75%); }
.redeem-ticket::after { content: ""; position: absolute; z-index: -1; right: -60px; top: -80px; width: 220px; height: 220px; border-radius: 50%; background: radial-gradient(circle, rgb(255 255 255 / .28), transparent 65%); }
.redeem-ticket-stub { display: grid; place-items: center; border-right: 2px dashed rgb(255 255 255 / .5); }
.redeem-ticket-stub svg.icon { width: 30px; height: 30px; stroke-width: 2; filter: drop-shadow(0 4px 6px rgb(0 0 0 / .18)); }
.redeem-ticket-body { display: grid; align-content: center; gap: 2px; min-width: 0; padding: 16px 22px; }
.redeem-ticket-kind { font-size: .82rem; font-weight: 700; opacity: .88; }
.redeem-ticket-term { font-family: var(--font-display); font-size: 2.1rem; font-weight: 800; line-height: 1.08; letter-spacing: -.035em; font-variant-numeric: tabular-nums; }
.redeem-ticket-meta { display: flex; flex-wrap: wrap; gap: 2px 14px; margin-top: 2px; font-size: .78rem; opacity: .86; }
.redeem-ticket-meta code { color: inherit; font-size: .74rem; overflow-wrap: anywhere; }
.redeem-stamp { position: absolute; right: 22px; top: 50%; padding: 5px 12px; border: 3px solid rgb(255 255 255 / .95); border-radius: 10px; color: #fff; font-size: 1.05rem; font-weight: 900; letter-spacing: .24em; text-indent: .24em; opacity: 0; translate: 0 -50%; rotate: -12deg; scale: 1.9; pointer-events: none; box-shadow: inset 0 0 0 2px rgb(255 255 255 / .25); }
.code-entry[data-step="done"] .redeem-stamp { animation: stamp-in .55s cubic-bezier(.2, 1.5, .45, 1) .15s forwards; }
.code-entry[data-step="done"] .redeem-ticket-wrap { animation: ticket-thud .5s ease-out .2s; }
@keyframes stamp-in { to { opacity: 1; scale: 1; } }
/* Tear Ticket: a redemption that went through tears the stub off along the perforation; it drops away. */
.redeem-ticket-wrap { position: relative; }
.redeem-ticket.is-torn .redeem-ticket-stub { visibility: hidden; }
.redeem-ticket-torn { position: absolute; left: 0; top: 0; bottom: 0; display: grid; place-items: center; padding-right: 6px; border-radius: 18px 0 0 18px; background: linear-gradient(160deg, #ff4f9a, #c35cf0); color: #fff; pointer-events: none; }
.redeem-ticket-torn[data-product^="CAPE"] { background: linear-gradient(160deg, #2fb86a, #4f8fd8); }
.redeem-ticket-torn svg.icon { width: 30px; height: 30px; stroke-width: 2; }
@keyframes ticket-thud { 0%, 100% { translate: 0 0; } 35% { translate: 0 3px; } }
.redeem-effect { display: grid; gap: 4px; font-size: .9rem; line-height: 1.7; color: var(--ink-2); }
.redeem-effect span:first-child { color: var(--ink); font-weight: 650; }
.code-entry[data-step="done"] .redeem-effect span:first-child { color: var(--accent-text); }
.redeem-target { display: grid; gap: 8px; padding: 12px 14px; border-radius: 16px; background: var(--surface-2); }
.redeem-target-label { font-size: .74rem; font-weight: 700; color: var(--ink-3); }
.redeem-target-who { display: flex; align-items: center; gap: 12px; min-width: 0; }
.redeem-avatar .player-avatar { width: 42px; height: 42px; border-radius: 12px; }
.redeem-target-text { display: grid; gap: 1px; min-width: 0; }
.redeem-target-text strong { font-size: .95rem; }
.redeem-target-text code { font-size: .74rem; color: var(--ink-3); overflow-wrap: anywhere; }
.redeem-target-missing { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.redeem-target-missing p { flex: 1 1 220px; font-size: .86rem; font-weight: 600; color: var(--warning-text); }
.redeem-slots { display: grid; gap: 8px; min-width: 0; margin: 0; padding: 0; border: 0; }
.redeem-slots legend { margin-bottom: 8px; padding: 0; font-size: .74rem; font-weight: 700; color: var(--ink-3); }
.redeem-slot-options { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.redeem-slot { display: grid; align-content: start; gap: 2px; min-width: 0; padding: 10px 12px; border: 1.5px solid var(--line); border-radius: 14px; background: var(--surface); color: var(--ink); text-align: left; transition: border-color .2s, background-color .2s, box-shadow .2s; }
.redeem-slot strong { font-size: .9rem; }
.redeem-slot span { font-size: .76rem; color: var(--ink-3); }
.redeem-slot:hover:not(:disabled) { border-color: var(--line-2); }
.redeem-slot[aria-pressed="true"] { border-color: var(--violet); background: var(--violet-soft); box-shadow: 0 0 0 3px color-mix(in srgb, var(--violet) 16%, transparent); }
.redeem-slot[aria-pressed="true"] strong { color: var(--violet-text); }
.redeem-slot:disabled { opacity: .45; cursor: not-allowed; }
.redeem-note { font-size: .8rem; color: var(--ink-3); }
.redeem-confirm .form-actions { margin: 0; }
@media (max-width: 560px) {
  .redeem-ticket { --notch: radial-gradient(circle 10px at 62px 0, #0000 97%, #000) top / 100% 51% no-repeat, radial-gradient(circle 10px at 62px 100%, #0000 97%, #000) bottom / 100% 51% no-repeat; grid-template-columns: 62px minmax(0, 1fr); }
  .redeem-ticket-body { padding: 14px 16px; }
  .redeem-ticket-term { font-size: 1.7rem; }
  .redeem-stamp { right: 12px; top: 14px; translate: 0; font-size: .86rem; }
  .redeem-slot-options { grid-template-columns: 1fr; }
}
/* ---------- Page effects ---------- */
/* Vanilla takes on React Bits components shared by every page. shell.js runs them (and lends them to pages as SoarFx);
   without it, or with reduced motion, the plain page stays. */
/* Blur Text: a page title drifts in out of a blur. */
@keyframes blur-in { from { opacity: 0; filter: blur(12px); transform: translateY(-.45em); } 55% { opacity: .6; filter: blur(4px); transform: translateY(.06em); } to { opacity: 1; filter: none; transform: none; } }
.blur-title > span { display: inline-block; animation: blur-in .85s var(--ease-out) both; animation-delay: calc(var(--i) * 70ms); }
/* Click Spark: square sparks burst from every click, drawn on one canvas over the page. */
.spark-layer { position: fixed; inset: 0; z-index: 80; width: 100vw; height: 100vh; pointer-events: none; }
/* Swipe Toast: short notices rise from the foot of the screen; the fuse burns down, a hover pauses it, a swipe dismisses. */
.toast-shelf { position: fixed; left: 50%; bottom: max(18px, env(safe-area-inset-bottom)); z-index: 90; width: max-content; max-width: calc(100% - 32px); translate: -50% 0; pointer-events: none; }
.fx-toast { position: relative; display: flex; align-items: center; gap: 10px; padding: 12px 18px 15px 14px; border-radius: 14px; background: var(--ink); color: var(--bg); box-shadow: 0 18px 34px -16px rgb(0 0 0 / .6); font-size: .9rem; font-weight: 650; line-height: 1.5; cursor: grab; touch-action: none; user-select: none; pointer-events: auto; animation: toast-in .5s var(--spring); }
.fx-toast:active { cursor: grabbing; }
.fx-toast svg.icon { width: 18px; height: 18px; color: var(--accent); stroke-width: 2.4; }
.fx-toast[data-tone="error"] svg.icon { color: var(--danger); }
.fx-toast[data-tone="error"] .toast-fuse { background: linear-gradient(90deg, color-mix(in srgb, var(--bg) 25%, transparent), var(--danger)); }
.toast-fuse { position: absolute; left: 14px; bottom: 6px; width: calc(100% - 28px); height: 2px; border-radius: 2px; background: linear-gradient(90deg, color-mix(in srgb, var(--bg) 25%, transparent), #ffb648); }
.toast-fuse::after, .fuse-line::after { content: ""; position: absolute; right: -4px; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: #ffe39a; box-shadow: 0 0 8px 3px #ff9d2e; animation: fuse-flicker .18s steps(2) infinite; }
@keyframes toast-in { from { opacity: 0; transform: translateY(40px) scale(.9); } }
@keyframes fuse-flicker { 50% { scale: .6; opacity: .7; } }
/* Counter: each digit rolls up to its place; --roll-h is the line height it rolls on. */
.roll { white-space: nowrap; }
.roll-digit { display: inline-block; height: var(--roll-h, 1.3em); line-height: var(--roll-h, 1.3em); overflow: hidden; vertical-align: top; }
.roll-strip { display: flex; flex-direction: column; }
.roll-strip > span { height: var(--roll-h, 1.3em); }
/* Line Sidebar: items near the pointer lean aside and a line follows it (account and admin navigation). */
.line-nav { position: relative; }
.line-cursor { position: absolute; left: -6px; top: 0; width: 3px; height: 28px; border-radius: 3px; background: var(--accent); box-shadow: 0 0 12px var(--accent); opacity: 0; transition: transform .16s var(--ease-out), opacity .2s; pointer-events: none; }
/* Hold Button: a red tide fills the button while it is held; letting go drains it. */
.fx-hold { position: relative; overflow: hidden; isolation: isolate; user-select: none; -webkit-user-select: none; touch-action: none; }
.hold-label { display: inline-flex; align-items: center; gap: 8px; }
.hold-fill { position: absolute; inset: 0; z-index: 1; overflow: hidden; border-radius: inherit; pointer-events: none; }
.hold-fill > i { position: absolute; inset: -8px 0 0; overflow: hidden; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 8'%3E%3Cpath d='M0 4q10-6 20 0t20 0v4H0Z' fill='%23e5484d'/%3E%3C/svg%3E") 0 0 / 40px 8px repeat-x, linear-gradient(transparent 7px, #e5484d 7px); transform: translateY(100%); animation: wave-run .8s linear infinite; }
.hold-fill b { position: absolute; inset: 8px 0 0; display: flex; align-items: center; justify-content: center; gap: 8px; color: #fff; font-weight: inherit; transform: translateY(calc(-100% - 8px)); }
@keyframes wave-run { to { background-position: 40px 0, 0 0; } }
.fx-hold.is-holding { box-shadow: 0 0 0 4px color-mix(in srgb, #e5484d 25%, transparent); }
.fx-hold.is-done { --btn-bg: #e5484d; --btn-fg: #fff; --btn-border: transparent; }
.fx-hold.is-done .hold-fill { display: none; }
/* Code Slots: the code is typed into one invisible field over a row of boxes. */
.slots { position: relative; display: flex; align-items: center; gap: clamp(5px, 1.6vw, 8px); }
.slots .slots-input { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; padding: 0; border: 0; opacity: 0; font-size: 16px; cursor: text; }
.slot { position: relative; display: grid; place-items: center; width: clamp(34px, 10vw, 44px); height: 54px; border: 1.5px solid var(--line-2); border-radius: 12px; background: var(--surface); font: 800 1.35rem/1 var(--font-mono); transition: border-color .2s, box-shadow .2s; }
.slot.is-caret { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring); }
.slot.is-caret:empty::after { content: ""; width: 2px; height: 22px; border-radius: 1px; background: var(--accent); animation: caret 1s steps(1) infinite; }
.slot-dash { color: var(--ink-3); font-weight: 800; }
.slots.is-done .slot { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-text); animation: slot-wave .5s var(--ease-out) both; animation-delay: calc(var(--i) * 45ms); }
.slots-input[aria-invalid="true"] ~ .slot { border-color: var(--danger); }
@keyframes slot-wave { 40% { transform: translateY(-5px); } }
@keyframes caret { 50% { opacity: 0; } }
/* Warm Tooltip: one bubble for every [data-tip]; it pops up after a pause, then glides between neighbours while warm. */
.warm-tip { --arrow: 50%; position: fixed; left: 0; top: 0; z-index: 95; padding: 7px 12px; border-radius: 10px; background: linear-gradient(135deg, #fff3e2, #ffe1ec); color: #4a2412; font-size: .78rem; font-weight: 700; line-height: 1.35; white-space: nowrap; pointer-events: none; box-shadow: 0 10px 26px -10px rgb(255 120 70 / .6), inset 0 0 0 1px rgb(255 160 110 / .45); transform-origin: var(--arrow) 100%; opacity: 0; transition: opacity .16s; }
.warm-tip::after { content: ""; position: absolute; left: calc(var(--arrow) - 6px); bottom: -5px; width: 12px; height: 12px; border-radius: 3px; background: #ffe6e6; box-shadow: inset -1px -1px 0 rgb(255 160 110 / .45); transform: rotate(45deg); }
.warm-tip.is-below { transform-origin: var(--arrow) 0; }
.warm-tip.is-below::after { top: -5px; bottom: auto; background: #fff0e4; box-shadow: inset 1px 1px 0 rgb(255 160 110 / .45); }
.warm-tip.is-on { opacity: 1; }
.warm-tip.is-gliding { transition: opacity .16s, left .32s var(--spring), top .32s var(--spring); }
:root[data-theme="dark"] .warm-tip { background: linear-gradient(135deg, #3a2312, #3d1828); color: #ffe2cc; box-shadow: 0 10px 26px -10px rgb(255 120 70 / .45), inset 0 0 0 1px rgb(255 150 100 / .3); }
:root[data-theme="dark"] .warm-tip::after { background: #3c1b22; box-shadow: inset -1px -1px 0 rgb(255 150 100 / .3); }
:root[data-theme="dark"] .warm-tip.is-below::after { background: #3a2116; box-shadow: inset 1px 1px 0 rgb(255 150 100 / .3); }
:root.warm-tips .supporter-badge::after { content: none; }
/* Spring Check: the copy icon springs into a tick and a ring flashes out. */
.spring-copy { overflow: visible; }
.sc-icon { position: relative; width: 16px; height: 16px; flex-shrink: 0; }
.sc-icon svg.icon { position: absolute; inset: 0; width: 16px; height: 16px; stroke-width: 2.2; transition: opacity .2s, scale .2s; }
.sc-check { opacity: 0; scale: .4; stroke-dasharray: 20; stroke-dashoffset: 20; }
.spring-copy.is-done { --btn-bg: var(--accent); --btn-fg: var(--accent-ink); --btn-border: transparent; }
.spring-copy.is-done .sc-copy { opacity: 0; scale: .4; }
.spring-copy.is-done .sc-check { opacity: 1; scale: 1; stroke-dashoffset: 0; animation: sc-spring .6s var(--spring); transition: opacity .2s, stroke-dashoffset .35s .08s var(--ease-out); }
.spring-copy.is-failed { --btn-border: color-mix(in srgb, var(--warning-text) 55%, transparent); }
.spring-copy::after { content: ""; position: absolute; inset: -2px; border-radius: inherit; opacity: 0; pointer-events: none; }
.spring-copy.is-done::after { animation: sc-ring .6s var(--ease-out); }
@keyframes sc-spring { 0% { scale: .3; rotate: -25deg; } 55% { scale: 1.35; rotate: 8deg; } 80% { scale: .92; rotate: -2deg; } 100% { scale: 1; rotate: 0deg; } }
@keyframes sc-ring { 0% { opacity: .6; box-shadow: 0 0 0 0 var(--accent); } 100% { opacity: 0; box-shadow: 0 0 0 12px var(--accent); } }
/* Glare Hover: a narrow slanted band sweeps across the card once when the pointer arrives. */
.glare { position: absolute; inset: 0; z-index: 3; overflow: hidden; border-radius: inherit; pointer-events: none; }
.glare::before { content: ""; position: absolute; top: -30%; bottom: -30%; left: -35%; width: 120px; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 26%, transparent) 35%, rgb(255 255 255 / .85) 50%, color-mix(in srgb, var(--accent) 26%, transparent) 65%, transparent); transform: skewX(-24deg); }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) { :hover > .glare::before { left: 120%; transition: left .8s cubic-bezier(.45, 0, .25, 1); } }
:root[data-theme="dark"] .glare::before { background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 18%, transparent) 35%, rgb(255 255 255 / .2) 50%, color-mix(in srgb, var(--accent) 18%, transparent) 65%, transparent); }
/* Magnet: shell.js sets --pull while the pointer is within reach. */
.magnetic { translate: var(--pull, 0px 0px); transition: translate .65s var(--spring), scale .2s ease-in-out, background-color .22s, color .2s, border-color .25s, opacity .2s ease-in-out, box-shadow .22s; }
.magnetic.is-pulled { transition: translate .22s var(--ease-out), scale .2s ease-in-out, background-color .22s, color .2s, border-color .25s, opacity .2s ease-in-out, box-shadow .22s; }
/* Character counters turn orange near the limit and red at it; with motion the digits roll (shell.js). */
.counter[data-tone="warn"] { color: var(--warning-text); }
.counter[data-tone="full"] { color: var(--danger-text); }
.counter .roll-digit { --roll-h: 1.3em; }
.counter .roll-strip { transition: transform .5s var(--spring); }
/* Reflective Card: the sponsor code as a metal card that tilts toward the pointer and mirrors a blurred sky. */
.reflect-card { --rx: 0deg; --ry: 0deg; --px: 50%; --py: 50%; position: relative; isolation: isolate; display: grid; align-content: space-between; gap: 14px; width: min(100%, 360px); min-height: 200px; padding: 20px 22px; border-radius: 20px; overflow: hidden; color: #fff; background: linear-gradient(125deg, #ff5fa2, #b04dff 55%, #6d4dff); box-shadow: 0 24px 46px -22px rgb(160 40 140 / .75), inset 0 1px 0 rgb(255 255 255 / .35); transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry)); transition: transform .5s var(--ease-out); }
.reflect-card.is-tilting { transition: transform .08s linear; }
.reflect-card > * { position: relative; z-index: 3; }
.reflect-card > :is(.rc-brush, .rc-mirror, .rc-sheen) { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.reflect-card > .rc-brush { background: repeating-linear-gradient(90deg, rgb(255 255 255 / .05) 0 1px, transparent 1px 3px); mix-blend-mode: overlay; }
/* The reflection slides by background-position, not transform: an animated transform gave the blurred layer a
   compositor layer of its own, which Chrome could leave half-drawn and unclipped by the rounded corners after the
   pointer left. */
.reflect-card > .rc-mirror { inset: -12%; background: url("/assets/background.png") calc(50% + (var(--px) - 50%) * .9) calc(50% + (var(--py) - 50%) * .9) / 150% auto no-repeat; filter: blur(7px) saturate(.35) brightness(1.25); opacity: .32; mix-blend-mode: screen; transition: background-position .5s var(--ease-out); }
.reflect-card.is-tilting > .rc-mirror { transition: none; }
.reflect-card > .rc-sheen { z-index: 2; background: radial-gradient(260px circle at var(--px) var(--py), rgb(255 255 255 / .45), transparent 55%), linear-gradient(115deg, transparent 30%, rgb(255 255 255 / .18) 45%, transparent 60%); mix-blend-mode: soft-light; }
.rc-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: .74rem; font-weight: 800; letter-spacing: .14em; opacity: .92; }
.rc-top img { width: 26px; height: 26px; filter: drop-shadow(0 2px 4px rgb(0 0 0 / .25)); }
.rc-chip { width: 38px; height: 28px; flex-shrink: 0; border-radius: 7px; background: linear-gradient(135deg, #fff2c4, #d8a843 60%, #fff0b8); box-shadow: inset 0 0 0 1px rgb(120 80 0 / .35); }
.reflect-card .rc-code { color: #fff; font-family: var(--font-mono); font-size: clamp(1.25rem, 4.6vw, 1.6rem); font-weight: 800; letter-spacing: .1em; text-shadow: 0 2px 10px rgb(60 0 60 / .35); }
.rc-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: .78rem; font-weight: 650; }
.rc-foot > span { opacity: .9; }
.rc-foot :is(.plan-code-label, .supporter-code-label) { color: inherit; font-size: inherit; font-weight: inherit; }
.rc-foot .btn { --btn-bg: rgb(255 255 255 / .22); --btn-fg: #fff; --btn-border: rgb(255 255 255 / .35); }
.rc-foot .spring-copy.is-done { --btn-bg: #fff; --btn-fg: #8a2bd6; --btn-border: transparent; }
/* Pixel Card: on hover, pink and violet pixels light up from the middle of a Xianyu ticket and shimmer. */
.market-ticket.pixel-card { position: relative; isolation: isolate; }
.market-ticket.pixel-card > .market-body { position: relative; z-index: 1; }
.pc-canvas { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }

/* ---------- Footer ---------- */
.site-footer { margin-top: 96px; border-top: 1px solid var(--line); background: var(--surface-2); overflow: hidden; }
.footer-grid { display: grid; grid-template-columns: 1.3fr 2fr; gap: 48px; padding-block: 52px 36px; }
.footer-brand p { margin-top: 14px; color: var(--ink-3); font-size: .9rem; max-width: 280px; }
.footer-links { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.footer-links p { font-size: .78rem; font-weight: 700; letter-spacing: .06em; color: var(--ink-3); margin-bottom: 12px; }
.footer-links a { display: block; width: fit-content; padding: 4px 0; color: var(--ink-2); font-size: .9rem; transition: color .2s; }
.footer-links a:hover { color: var(--accent-text); }
.footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 24px; padding-block: 20px 28px; border-top: 1px solid var(--line); color: var(--ink-3); font-size: .8rem; }
.footer-bottom a { color: var(--ink-2); transition: color .2s; }
.footer-bottom a:hover { color: var(--accent-text); }
/* An outlined SOARCLIENT whose letters fill with the brand gradient around the pointer ("Stroke Text"). */
.wordmark { --wx: 50%; --wy: 50%; position: relative; margin: 10px 0 -.17em; color: transparent; font: 900 clamp(3.4rem, 15.4vw, 15.5rem)/.9 var(--font-display); letter-spacing: -.06em; text-align: center; white-space: nowrap; -webkit-text-stroke: 1.5px var(--line-2); user-select: none; }
.wordmark::after { content: attr(data-text); position: absolute; inset: 0; background: var(--brand-gradient); -webkit-background-clip: text; background-clip: text; -webkit-text-stroke: 0; -webkit-mask-image: radial-gradient(circle 240px at var(--wx) var(--wy), #000 10%, transparent 72%); mask-image: radial-gradient(circle 240px at var(--wx) var(--wy), #000 10%, transparent 72%); opacity: 0; transition: opacity .45s; }
.wordmark.is-lit::after { opacity: 1; }

/* ---------- Motion helpers ---------- */
:root.js [data-reveal] { opacity: 0; transform: translateY(22px); transition: opacity .8s var(--ease-out), transform .8s var(--ease-out); transition-delay: var(--reveal-delay, 0s); }
:root.js [data-reveal].is-revealed { opacity: 1; transform: none; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* ---------- Responsive ---------- */
@media (max-width: 1200px) {
  .header-inner { gap: 18px; }
  .site-nav a { padding-inline: 11px; }
  .header-cta { display: none; }
}
@media (max-width: 960px) {
  .site-nav { display: none; }
  .menu-toggle { display: inline-block; }
  .header-actions, .site-nav + .header-actions { margin-left: auto; }
  .header-cta { display: none; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
}
/* The admin link makes the navigation one item longer: the links tighten first, and only English, the longest, drops the download button. */
@media (max-width: 1320px) { .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .site-nav a { padding-inline: 9px; } }
:root:lang(en) .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .site-nav a { padding-inline: 9px; }
@media (max-width: 1280px) { :root:lang(en) .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .header-cta { display: none; } }
@media (max-width: 1040px) {
  .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .site-nav { display: none; }
  .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .menu-toggle { display: inline-block; }
  .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .header-actions { margin-left: auto; }
}
/* English and Japanese labels are longer than Chinese ones, so their header folds into the menu sooner. */
@media (max-width: 1310px) { :root:lang(en) .header-cta { display: none; } }
@media (max-width: 1440px) { :root:lang(ja) .header-cta { display: none; } }
:root:lang(ja) .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .header-cta { display: none; }
@media (max-width: 1100px) {
  :root:lang(en) .site-nav { display: none; }
  :root:lang(en) .menu-toggle { display: inline-block; }
  :root:lang(en) .header-actions { margin-left: auto; }
}
@media (max-width: 1140px) {
  :root:lang(en) .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .site-nav { display: none; }
  :root:lang(en) .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .menu-toggle { display: inline-block; }
  :root:lang(en) .site-header:has(.site-nav [data-admin-nav]:not([hidden])) .header-actions { margin-left: auto; }
}
@media (max-width: 1200px) {
  :root:lang(ja) .site-nav { display: none; }
  :root:lang(ja) .menu-toggle { display: inline-block; }
  :root:lang(ja) .header-actions { margin-left: auto; }
}
@media (max-width: 560px) {
  body { font-size: 14.5px; }
  .container, .header-inner { width: calc(100% - 32px); }
  .header-inner { gap: 10px; }
  .brand { gap: 9px; font-size: 1rem; }
  .brand-mark { width: 32px; height: 32px; border-radius: 10px; }
  .brand-mark img { width: 22px; height: 22px; }
  .brand-home-hint { font-size: 7px; letter-spacing: .08em; }
  .account-chip { padding: 0; width: 40px; justify-content: center; }
  .account-chip [data-account-label], .account-chip[aria-haspopup] .chip-caret { display: none; }
  .header-actions { gap: 8px; }
  .header-actions > .lang-switch { display: none; }
  .footer-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .site-footer { margin-top: 64px; }
}
@media (max-width: 360px) {
  .brand-name { font-size: .92rem; }
  .theme-toggle { display: none; }
  .lang-segment { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
/* 减少动效 in the account preferences (theme.js sets data-motion before first paint): the same stillness as the system
   setting, for players who want it on this site only. */
:root[data-motion="reduce"] { scroll-behavior: auto; }
:root[data-motion="reduce"] *, :root[data-motion="reduce"] *::before, :root[data-motion="reduce"] *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
@media (prefers-reduced-motion: reduce) {
  .brand-home-link:hover .brand-name, .brand-home-link:focus-visible .brand-name { transform: none; }
  :root.js [data-reveal] { opacity: 1; transform: none; }
  .lattice i { animation: none; opacity: .55; }
  .hold-fill { display: none; }
}

/* ---------- Site search (session.js): one box for players and configs, from every header ---------- */
.header-search svg.icon { width: 19px; height: 19px; }
.header-search[aria-expanded="true"] { border-color: var(--accent); color: var(--ink); box-shadow: 0 0 0 4px var(--accent-ring); }
.site-search { position: fixed; inset: 0; z-index: 70; }
.site-search[hidden] { display: none; }
.site-search-scrim { position: absolute; inset: 0; background: rgb(8 14 11 / .28); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); opacity: 0; transition: opacity .2s; }
.site-search.is-open .site-search-scrim { opacity: 1; }
.site-search-box { position: absolute; left: 50%; top: var(--search-top, 80px); display: grid; width: min(640px, 100% - 24px); max-height: calc(100dvh - var(--search-top, 80px) - 16px); overflow: hidden; translate: -50% -8px; border: 1px solid var(--line); border-radius: 22px; background: var(--surface); box-shadow: var(--shadow-lg); opacity: 0; transition: opacity .2s, translate .3s var(--ease-out); }
.site-search.is-open .site-search-box { opacity: 1; translate: -50% 0; }
.site-search-field { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.site-search-field svg.icon { width: 20px; height: 20px; color: var(--ink-3); }
.site-search-field input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; color: var(--ink); font: inherit; font-size: 1.05rem; font-weight: 600; }
.site-search-field input::-webkit-search-cancel-button { display: none; }
.site-search-field kbd { padding: 2px 7px; border: 1px solid var(--line-2); border-radius: 7px; color: var(--ink-3); font-family: var(--font-mono); font-size: .72rem; }
.site-search-results { display: grid; gap: 4px; overflow: auto; overscroll-behavior: contain; padding: 8px; }
.search-group { display: grid; gap: 2px; padding: 4px 0; }
.search-group + .search-group { border-top: 1px solid var(--line); padding-top: 8px; }
.search-group-head { display: flex; align-items: center; justify-content: space-between; padding: 4px 10px; color: var(--ink-3); font-size: .76rem; font-weight: 800; letter-spacing: .04em; }
.search-list { display: grid; gap: 2px; }
.search-row { display: flex; align-items: center; gap: 12px; min-width: 0; padding: 8px 10px; border-radius: 13px; color: var(--ink); transition: background-color .15s; }
.search-row:hover, .search-row:focus-visible { background: var(--surface-2); outline: none; }
.search-row:focus-visible { box-shadow: inset 0 0 0 2px var(--accent-ring); }
.search-row .player-avatar { width: 36px; height: 36px; border-radius: 10px; font-size: .9rem; }
.search-row-icon { display: grid; place-items: center; flex-shrink: 0; width: 36px; height: 36px; border-radius: 10px; background: var(--violet-soft); color: var(--violet-text); }
.search-row-icon svg.icon { width: 18px; height: 18px; }
.search-row-text { display: grid; min-width: 0; }
.search-row-text strong { display: flex; align-items: center; overflow: hidden; font-size: .92rem; white-space: nowrap; text-overflow: ellipsis; }
.search-row-text strong .supporter-badge { flex-shrink: 0; margin-left: 5px; }
.search-row-text small { overflow: hidden; color: var(--ink-3); font-size: .76rem; white-space: nowrap; text-overflow: ellipsis; }
.search-more { color: var(--accent-text); font-size: .78rem; font-weight: 700; letter-spacing: 0; }
.search-more:hover, .search-more:focus-visible { text-decoration: underline; outline: none; }
.search-shortcuts { display: flex; flex-wrap: wrap; gap: 8px 18px; padding: 10px; border-top: 1px solid var(--line); }
.search-shortcuts:first-child { border-top: 0; }
.search-note { padding: 18px 10px; color: var(--ink-3); font-size: .88rem; text-align: center; }
@media (max-width: 760px) { .site-search-box { width: calc(100% - 24px); } .site-search-field kbd { display: none; } }
