/* ==========================================================================================
   screens/lobby.css — mode cards (独立/同盟/无限火力), difficulty cards, create button, join panel.
   ========================================================================================== */

.lobby-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: .3rem;
  width: 100%;
  max-width: 19.2rem;
  margin: 0 auto;
  padding: .36rem .6rem .4rem;
  align-content: start;
}
.lobby-left, .lobby-right { display: flex; flex-direction: column; min-width: 0; }
.lobby-mode { grid-column: 1 / -1; min-width: 0; }
.lobby-left { grid-column: 1; grid-row: 3; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: .12rem .4rem; }
.lobby-left > .section-label:first-child { grid-column: 1; grid-row: 1; }
.lobby-left > .matchmaking-panel { grid-column: 1; grid-row: 2; margin-bottom: 0; }
.lobby-left > .lobby-join-label { grid-column: 2; grid-row: 1; }
.lobby-left > .join-panel { grid-column: 2; grid-row: 2; }
.lobby-left > .tips { grid-column: 1 / -1; }
.lobby-right { grid-column: 1; grid-row: 2; }
.lobby-right .diff-list { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .18rem; }
.lobby-right .diff-card { padding: .18rem .2rem .16rem .28rem; gap: .1rem .14rem; }
.lobby-right .diff-card__head { flex-wrap: wrap; gap: .06rem .08rem; }
.lobby-right .diff-card__meta { flex-basis: 100%; margin-left: .36rem; }
.lobby-right .diff-card__name { font-size: calc(.24 * var(--t)); }
.lobby-right .diff-card__effects { gap: .03rem .14rem; }
.lobby-right .diff-card__check .icon { width: .35rem; height: .35rem; padding: .06rem; }
.lobby-right .create-box { align-items: center; margin-top: .22rem; }
.lobby-right .create-box > .tt-anchor { width: min(7rem, 100%); }
.lobby-right .create-box .btn--xl { height: .72rem; font-size: calc(.28 * var(--t)); }

/* ---- mode cards ------------------------------------------------------------------------------------ */
.lobby-mode .mode-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .24rem; margin-bottom: 0; }

.mode-beta {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: .025rem .09rem;
  border: 1px solid rgba(255, 198, 0, .6);
  background: rgba(255, 198, 0, .12);
  color: var(--gold);
  font-size: calc(.13 * var(--t));
  font-weight: 800;
  letter-spacing: .06em;
  line-height: 1.35;
}
.mode-card__name-row { display: flex; align-items: center; flex-wrap: wrap; gap: .13rem; }

.firepower-brief {
  --bk-c: var(--gold-2);
  --bk-l: .16rem;
  margin-top: .2rem;
  padding: .19rem .26rem;
  border: 1px solid rgba(255, 198, 0, .3);
  background: linear-gradient(110deg, rgba(255, 198, 0, .065), rgba(14, 20, 17, .9));
}
.firepower-brief__head { display: flex; align-items: center; flex-wrap: wrap; gap: .1rem .14rem; margin-bottom: .13rem; }
.firepower-brief__title { color: var(--gold); font-size: calc(.2 * var(--t)); font-weight: 800; }
.firepower-brief__hint { color: var(--text-lo); font-size: calc(.15 * var(--t)); margin-left: auto; }

.firepower-variants { display: flex; flex-wrap: wrap; gap: .12rem; margin-bottom: .14rem; }
.firepower-variant {
  flex: 1; min-width: 2.4rem; padding: .1rem .16rem; border: 1px solid rgba(255, 198, 0, .2);
  border-radius: 6px; background: rgba(14, 20, 17, .8); cursor: pointer; text-align: left;
  transition: border-color .12s ease, background .12s ease;
}
.firepower-variant:hover { border-color: rgba(255, 198, 0, .5); }
.firepower-variant.is-selected { border-color: var(--gold); background: linear-gradient(110deg, rgba(255, 198, 0, .1), rgba(14, 20, 17, .9)); }
.firepower-variant__name { display: block; font-weight: 700; font-size: calc(.17 * var(--t)); color: var(--gold); }
.firepower-variant__en { margin-left: .08rem; font-size: calc(.11 * var(--t)); font-weight: 400; color: var(--text-lo); text-transform: uppercase; letter-spacing: .04em; }
.firepower-variant__desc { display: block; margin-top: .04rem; font-size: calc(.13 * var(--t)); color: var(--text-lo); line-height: 1.5; }

.firepower-features { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .2rem; }
.firepower-feature { min-width: 0; }
.firepower-feature strong { color: var(--text-hi); font-size: calc(.17 * var(--t)); font-weight: 700; }
.firepower-feature p { margin: .04rem 0 0; color: var(--text-lo); font-size: calc(.15 * var(--t)); line-height: 1.65; }

/* ---- Legacy room selector styles, retained for older room components ------------------------------ */
.rm-sel-label { display: flex; align-items: baseline; gap: .14rem; margin-bottom: .12rem; }
.rm-sel { display: grid; grid-template-columns: 1fr 1fr; gap: .24rem; margin-bottom: .34rem; }
.rm-sel__opt {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start; gap: .1rem;
  min-height: 2.5rem;
  padding: .28rem .32rem .24rem;
  text-align: left;
  background: linear-gradient(180deg, rgba(28, 34, 31, .92), rgba(13, 16, 15, .94));
  border: 1px solid var(--line);
  color: var(--text-lo);
  transition: border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-med), background-color var(--t-fast);
}
.rm-sel__opt .icon { width: .34rem; height: .34rem; color: var(--line-3); transition: color var(--t-fast), filter var(--t-fast); }
.rm-sel__opt:hover:not(:disabled) { color: var(--text-hi); border-color: var(--line-3); }
.rm-sel__opt:hover:not(:disabled) .icon { color: var(--text-hi); }
.rm-sel__opt:disabled { cursor: default; }
.rm-sel__opt.is-active { color: var(--text-hi); border-color: var(--mint-400); box-shadow: 0 0 .16rem rgba(23, 249, 183, .22) inset; }
.rm-sel__opt.is-active .icon { color: var(--mint-400); filter: drop-shadow(0 0 5px var(--mint-glow)); }
.rm-sel__opt--random.is-active { border-color: var(--gold); box-shadow: 0 0 .16rem rgba(255, 198, 0, .2) inset; }
.rm-sel__opt--random.is-active .icon { color: var(--gold); filter: drop-shadow(0 0 5px rgba(255, 198, 0, .45)); }
.rm-sel__name { font-size: calc(.24 * var(--t)); font-weight: 800; letter-spacing: .1em; }
.rm-sel__desc { font-size: calc(.15 * var(--t)); color: var(--text-dim); letter-spacing: .06em; }

.rm-note { margin: .1rem 0 .06rem; font-size: calc(.17 * var(--t)); line-height: 1.5; color: var(--text-lo); }

/* the 无限火力 tag of a room card in the multiplayer modal (server room.view.random) */
.mm-room-rm { padding: .02rem .08rem; border: 1px solid var(--mint-400); border: 1px solid color-mix(in srgb, var(--mint-400) 55%, transparent); background: var(--mint-400); background: color-mix(in srgb, var(--mint-400) 12%, transparent); color: var(--mint-400); font-size: calc(.14 * var(--t)); font-weight: 700; letter-spacing: .1em; border-radius: 2px; }

.mode-card {
  --bk-c: transparent;
  --bk-l: .2rem;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .22rem;
  min-height: 2.72rem;
  padding: .26rem .3rem .24rem 1.34rem;
  overflow: hidden;
   screens/lobby.css — the hub (official entry backdrop, the emblem in its radar and the title, 成就统计 / 密钥加入 /
   作战提示 at the left, the light S.W.E.E.P.报告 / 干员调配 plates at the right, the 独立模拟 / 同盟模拟 entries at the
   bottom right), and the two full-screen dialogs (the project's Modal): 选择模拟协议 (official picture, difficulty cards
   with the 已选定 stamp, 开始独立模拟 — or the room's 确认 / read-only view) and 选择同盟方式 (radar, 创建同盟 and 加入同盟
   cards). Text follows 文字大小 (calc(k * var(--t))).
   ========================================================================================== */

/* ---- hub backdrop ------------------------------------------------------------------------------------- */
/* the entries' width follows 文字大小 (2.3rem at 小; §37.18 review: at a fixed 2.3rem the names had to stop at 小's size) */
.lobby-hub { --hub-entry-w: calc(2.3 * var(--t)); --hub-gap: .14rem; background: #050807; }
/* Korean breaks between words, not between the syllables of one (§37.18 review: 「독립 시뮬레이|션」 at 小); a word too
   long for its box still breaks rather than running out of it. The hub's own stage only: 选择模拟协议's button keeps its
   two lines (「독립 시뮬레이션 시작」 took three at 特大 in a 1024×600 window by words) */
.lobby-hub:lang(ko) .hub-stage { word-break: keep-all; overflow-wrap: break-word; }
/* Japanese never starts a line with a small kana, ー or a closing mark (§37.18 review: the tips' 「オペレ|ーター」 at 中 / 特大
   in a 1024×600 window; line-break: normal allows a break before them), as in the room */
.lobby-hub:lang(ja) .hub-stage { line-break: strict; }
/* a last line of one character: the hub's tips, the protocol dialog's paragraphs and its big button's label wrap `pretty`
   (§37.18 review of the text-fit fixes: 「比較的所要時間が短いシミュレーショ|ン」 on a phone at 特大, 「単独演算を開|始」,
   Korean 「독립 시뮬레이션 시|작」 on desktops). Scoped as in the room (room.css): WebKit's `pretty` adds lines to short
   labels, and the lobby's other dialogs were not measured with it. The dialog's button only (`.proto-foot`): the room's
   big button shares the label's class and wraps plainly — in Safari `pretty` broke its Japanese 「シミュレーション|開始」
   inside the word, 「シミュレー|ション開始」, at 小 on the phones (review of 6f34f380), as `balance` had. `pretty`:
   Chrome 117+, Safari 26+; Firefox wraps as before */
.tips__text, .proto-brief p, .proto-hint, .proto-foot .proto-start__label { text-wrap: pretty; }
/* 选择同盟方式's note breaks Japanese between phrases in Chrome 119+ (BudouX; review of 6f34f380: 「…教えてもらう|か、招待リンク…」
   at 特大 on the phones, now 「…教えて|もらうか、招待リンクを|直接開いてください」); Safari and Firefox ignore it and wrap as
   before */
.ally-recent:lang(ja) { word-break: auto-phrase; }
/* the top bar's ping pill grows with its text at 大 / 特大, as in the room (§37.18 review: its fixed .32rem cut it) */
.lobby-hub > .topbar .ping { height: auto; min-height: .32rem; padding-top: 1px; padding-bottom: 1px; }
.hub-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(55% 60% at 50% 48%, rgba(96, 170, 186, .14), transparent 72%),
    linear-gradient(180deg, #08100f, #040606 82%);
}
/* the official layers are drawn on black: `screen` keeps only their light. Their place, size and opacity below are
   eyeballed from the event video [ASSUMED: no official layout data] */
.hub-bg__glow, .hub-bg__ship { position: absolute; left: 50%; height: auto; transform: translate(-50%, -50%); mix-blend-mode: screen; }
.hub-bg__glow { top: 46%; width: 9.6rem; opacity: .2; }
.hub-bg__ship { top: 54%; width: 13.4rem; opacity: .4; animation: hub-ship 18s ease-in-out infinite alternate; }
@keyframes hub-ship { to { transform: translate(-50%, calc(-50% - .1rem)); } }
.hub-bg__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, .028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .028) 1px, transparent 1px);
  background-size: .6rem .6rem;
  -webkit-mask-image: radial-gradient(70% 70% at 50% 50%, #000 30%, transparent 85%);
  mask-image: radial-gradient(70% 70% at 50% 50%, #000 30%, transparent 85%);
}
.lobby-hub .topbar { background: linear-gradient(180deg, rgba(4, 8, 8, .85), transparent); border-bottom: 0; }

/* ---- 大厅背景与音乐 (PR #643 split 8, ui/lobbyMedia.js): the player's own picture / video over the official layers,
   darkened by its 暗度 (--own-dim) so the title and the entries stay readable; the dialog reuses the settings rows ---- */
.hub-bg__own { position: absolute; inset: 0; background: #050807; animation: hub-own-in 400ms ease-out backwards; }
.hub-bg__own img, .hub-bg__own video, .hub-bg__own canvas { display: block; width: 100%; height: 100%; object-fit: cover; }
.hub-bg__own::after { content: ''; position: absolute; inset: 0; background: rgba(5, 8, 7, var(--own-dim, .35)); }
@keyframes hub-own-in { from { opacity: 0; } }
.lmedia .modal__body { display: flex; flex-direction: column; gap: .16rem; }
.lmedia__part { display: flex; flex-direction: column; gap: .1rem; padding: .14rem .16rem; border: 1px solid var(--line); background: rgba(0, 0, 0, .25); }
.lmedia__head { display: flex; align-items: baseline; gap: .1rem; font-size: calc(.18 * var(--t)); color: var(--text-hi); }
.lmedia__now { display: flex; align-items: center; gap: .08rem; min-width: 0; font-size: calc(.16 * var(--t)); color: var(--text-md); }
.lmedia__now .icon { flex: none; width: .2rem; height: .2rem; color: var(--mint-500); }
.lmedia__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lmedia__size { flex: none; font-size: calc(.14 * var(--t)); color: var(--text-lo); }
.lmedia__btns { display: flex; flex-wrap: wrap; align-items: center; gap: .1rem; }
.lmedia__btns .set-toggle { grid-column: auto; }
.lmedia__dim { padding: 0 .16rem; }
.lmedia__note { display: flex; gap: .06rem; margin: 0; font-size: calc(.15 * var(--t)); line-height: 1.6; color: var(--text-lo); }
.lmedia__note .icon { flex: none; width: .18rem; height: .18rem; margin-top: .04rem; }

/* 大厅场景 (ui/hubScene.js): four generated scenes over the official backdrop; colour tokens per scene ---------- */
[data-hub-theme="night"] {
  --sky-0: #03080a; --sky-1: #08141a; --sky-2: #12262a; --sky-3: #050909;
  --haze: rgba(92, 168, 156, .17); --cloud: rgba(140, 196, 186, .055);
  --ridge-far: #122022; --ridge-mid: #0b1516; --ridge-near: #060b0b;
  --rim: rgba(110, 226, 196, .34); --fog: rgba(54, 104, 98, .3); --beam: rgba(150, 240, 215, .1);
  --beacon: #59f4ca; --window: rgba(89, 244, 202, .7); --grid: rgba(89, 244, 202, .32);
  --mote: rgba(170, 245, 225, .7);
}
/* the official backdrop's swatch: its dark field and glow */
[data-hub-theme="official"] {
  --sky-0: #08100f; --sky-1: #0c1a1b; --sky-2: #1b3134; --sky-3: #040606;
  --ridge-far: transparent; --ridge-mid: transparent; --ridge-near: transparent; --beacon: rgba(150, 220, 230, .7);
}
[data-hub-theme="frost"] {
  --sky-0: #070c12; --sky-1: #142029; --sky-2: #34444f; --sky-3: #090d11;
  --haze: rgba(205, 226, 240, .2); --cloud: rgba(220, 236, 246, .08);
  --ridge-far: #3a4852; --ridge-mid: #212c34; --ridge-near: #0f1418;
  --rim: rgba(240, 248, 255, .62); --fog: rgba(180, 200, 214, .24); --beam: rgba(225, 240, 255, .12);
  --beacon: #9fd8ff; --window: rgba(170, 220, 255, .7); --grid: rgba(170, 215, 240, .26);
  --mote: rgba(240, 248, 255, .85);
}
[data-hub-theme="ember"] {
  --sky-0: #080605; --sky-1: #120d0b; --sky-2: #251913; --sky-3: #070505;
  --haze: rgba(196, 104, 52, .15); --cloud: rgba(130, 96, 76, .08);
  --ridge-far: #211814; --ridge-mid: #150f0c; --ridge-near: #090606;
  --rim: rgba(255, 150, 80, .28); --fog: rgba(84, 52, 38, .32); --beam: transparent;
  --beacon: #ffae48; --window: rgba(255, 168, 80, .75); --grid: rgba(255, 170, 90, .22);
  --mote: rgba(255, 150, 70, .85);
}
[data-hub-theme="calm"] {
  --sky-0: #040606; --sky-1: #070b0b; --sky-2: #0c1211; --sky-3: #040505;
  --haze: rgba(80, 120, 110, .07); --cloud: transparent;
  --ridge-far: #0e1514; --ridge-mid: #090e0e; --ridge-near: #050808;
  --rim: rgba(89, 244, 202, .14); --fog: rgba(30, 50, 46, .25); --beam: transparent;
  --beacon: #4ed8af; --window: rgba(78, 216, 175, .45); --grid: rgba(89, 244, 202, .22);
  --mote: transparent;
}

.hub-scene { position: absolute; inset: 0; pointer-events: none; overflow: hidden; background: var(--sky-3); }
.hub-bg__sky { position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--sky-0) 0%, var(--sky-1) 36%, var(--sky-2) 63%, var(--sky-3) 100%); }
.hub-bg__stars { position: absolute; left: 0; top: 0; width: 1px; height: 1px; border-radius: 50%;
  animation: hub-twinkle 7s ease-in-out infinite alternate; }
.hub-bg__haze { position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 20% at 50% 64%, var(--haze), transparent 72%),
    radial-gradient(ellipse 130% 36% at 50% 72%, var(--haze), transparent 70%); }
.hub-bg__clouds { position: absolute; left: 0; top: 6%; width: 200%; height: 50%;
  background:
    radial-gradient(30% 10% at 15% 42%, var(--cloud), transparent 70%),
    radial-gradient(22% 7% at 38% 20%, var(--cloud), transparent 70%),
    radial-gradient(36% 11% at 66% 58%, var(--cloud), transparent 70%),
    radial-gradient(20% 6% at 88% 28%, var(--cloud), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x; animation: hub-drift 180s linear infinite; }
.hub-bg__land { position: absolute; left: 0; bottom: 0; width: 100%; height: 64%; overflow: visible; }
.hub-bg__ridge--far { fill: var(--ridge-far); }
.hub-bg__ridge--mid, .hub-bg__fort { fill: var(--ridge-mid); }
.hub-bg__ridge--near { fill: var(--ridge-near); }
.hub-bg__rim { fill: none; stroke: var(--rim); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.hub-fog-0 { stop-color: var(--fog); stop-opacity: 0; }
.hub-fog-1 { stop-color: var(--fog); stop-opacity: 1; }
.hub-beam-0 { stop-color: var(--beam); }
.hub-beam-1 { stop-color: var(--beam); stop-opacity: 0; }
.hub-bg__beam { transform-origin: 791px 300px; animation: hub-beam 16s ease-in-out infinite alternate; }
.hub-bg__windows rect { fill: var(--window); animation: hub-window 9s steps(1) infinite; animation-delay: var(--dl); }
.hub-bg__beacons g { fill: var(--beacon); animation: hub-beacon 2.8s ease-in-out infinite; animation-delay: var(--dl); }
.hub-bg__beacon-glow { opacity: .22; }
.hub-bg__motes { position: absolute; inset: 0; }
.hub-bg__mote { position: absolute; border-radius: 50%; background: var(--mote); box-shadow: 0 0 6px var(--mote); opacity: 0;
  animation: hub-mote var(--d) linear infinite; animation-delay: var(--dl); }
[data-hub-theme="frost"] .hub-bg__mote { animation-name: hub-snow; }
@keyframes hub-twinkle { from { opacity: .5; } to { opacity: 1; } }
@keyframes hub-drift { to { transform: translateX(-50%); } }
@keyframes hub-beam { from { transform: rotate(-18deg); } to { transform: rotate(24deg); } }
@keyframes hub-window { 0%, 70% { opacity: .9; } 72%, 78% { opacity: .2; } 80%, 100% { opacity: .9; } }
@keyframes hub-beacon { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
@keyframes hub-mote { 0% { transform: translate3d(0, 0, 0); opacity: 0; } 15% { opacity: .8; } 85% { opacity: .45; } 100% { transform: translate3d(2vw, -18vh, 0); opacity: 0; } }
@keyframes hub-snow { 0% { transform: translate3d(0, -12vh, 0); opacity: 0; } 15% { opacity: .9; } 85% { opacity: .7; } 100% { transform: translate3d(-3vw, 14vh, 0); opacity: 0; } }
.bgset__swatch { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; overflow: hidden;
  background: linear-gradient(180deg, var(--sky-0), var(--sky-1) 40%, var(--sky-2) 66%, var(--sky-3)); }
.bgset__swatch svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.bgset__swatch .sw-far { fill: var(--ridge-far); }
.bgset__swatch .sw-mid { fill: var(--ridge-mid); }
.bgset__swatch .sw-near { fill: var(--ridge-near); }
.bgset__swatch .sw-beacon { fill: var(--beacon); }
@media (prefers-reduced-motion: reduce) {
  .hub-scene * { animation: none; }
  .hub-scene .hub-bg__mote { opacity: .3; }
}
/* the scene buttons of 大厅背景与音乐 */
.bgset__themes { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .1rem; }
.bgset__theme {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .05rem;
  min-width: 0;
  padding: .06rem;
  font: inherit;
  text-align: left;
  color: var(--text-hi);
  cursor: pointer;
  background: rgba(223, 230, 226, .04);
  border: 1px solid rgba(223, 230, 226, .14);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.bgset__theme:hover { border-color: var(--mint-a35); }
.bgset__theme.is-selected { border-color: var(--mint-400); box-shadow: inset 0 0 0 1px var(--mint-400), 0 0 .14rem var(--mint-a20); }
.bgset__name { font-size: calc(.15 * var(--t)); font-weight: 800; white-space: nowrap; }
.bgset__en { font: 700 calc(.09 * var(--t)) / 1 ui-monospace, Consolas, monospace; letter-spacing: .14em; color: var(--text-dim); white-space: nowrap; }
@media (max-width: 720px) { .bgset__themes { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* ---- hub layout: the centre spans the first row; both columns lie above it -------------------------- */
.hub-stage {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 4rem) minmax(0, 1fr) minmax(0, calc(var(--hub-entry-w) * 2 + var(--hub-gap)));
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas: "side center right" "side entries entries";
  gap: .2rem .4rem;
  width: 100%;
  padding: .1rem .36rem .36rem;
}

.hub-center {
  grid-row: 1;
  grid-column: 1 / -1;
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .1rem;
  min-width: 0;
  text-align: center;
  pointer-events: none;
  animation: card-in var(--t-slow) var(--ease-out) backwards;
}
.mode-card:nth-child(2) { animation-delay: 60ms; }
.mode-card:nth-child(3) { animation-delay: 120ms; }
.mode-card__bg {
.hub-center__mark { position: relative; display: grid; place-items: center; min-height: 1.4rem; margin-bottom: .1rem; }
.hub-center__logo { position: relative; width: 1.3rem; height: auto; filter: drop-shadow(0 0 .12rem rgba(210, 255, 240, .25)); }
.hub-center__mark .emblem { position: relative; margin-bottom: 0; }
.hub-center__en { position: relative; font-family: var(--font-display); font-size: calc(.17 * var(--t)); letter-spacing: .32em; color: rgba(223, 230, 226, .72); text-shadow: 0 1px .08rem rgba(0, 0, 0, .85); }
.hub-center__en b { color: var(--mint-400); font-weight: 700; }
.hub-center__title {
  position: relative;
  margin: 0;
  /* follows 文字大小 while it fits on one line beside the side columns (larger, it ran under the left column's tips —
     §37.18 review): the centre is the stage's width (100vw less its .72rem padding) and the title's box 8.8rem less (below);
     7 CJK characters with their spacing are 7.4–8em, so it stops at that box / 8.2 (never below .56rem at 小); the latin
     title below */
  font-size: min(calc(.56 * var(--t)), calc((100vw - 9.52rem) / 8.2));
  font-weight: 900;
  letter-spacing: .14em;
  line-height: 1.15;
  color: var(--text-hi);
  text-shadow: 0 .04rem .3rem rgba(0, 0, 0, .8);
  overflow-wrap: anywhere;
}
.hub-center__title em { font-style: normal; color: var(--mint-400); }
.hub-center__title--latin { font-family: var(--font-display); letter-spacing: .04em; text-transform: uppercase; }
/* the title is centred over the whole stage: it keeps clear of the side columns (4rem and its gap each side), and the
   latin one — 「STRONGHOLD PROTOCOL: ALLIANCE」, 20em of the display font — is .46 × --t while it fits on one line
   inside that, (100vw − 9.52rem) / 20.2 (§37.18 review: at .56rem it reached under the left column's tips in English, at
   大 / 特大 in 800–1280 px windows; pinned at .46rem it no longer followed 文字大小). [ASSUMED] the .46 */
.hub-center__title { max-width: calc(100% - 8.8rem); }
.hub-center__title--latin { font-size: min(calc(.46 * var(--t)), calc((100vw - 9.52rem) / 20.2)); }
/* the radar rings around the emblem (original drawing) */
.hub-radar { position: absolute; left: 50%; top: 50%; width: 4.6rem; height: 4.6rem; transform: translate(-50%, -50%); }
.hub-radar svg { width: 100%; height: 100%; overflow: visible; fill: none; stroke: rgba(89, 244, 202, .15); stroke-width: 1; }
.hub-radar .hub-radar__ticks { stroke-width: 5; stroke-dasharray: 1.4 9.8; }
.hub-radar__sweep {
  position: absolute;
  inset: 5.4%;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 292deg, rgba(89, 244, 202, .15) 360deg);
  -webkit-mask-image: radial-gradient(circle, transparent 0 17%, #000 18%);
  mask-image: radial-gradient(circle, transparent 0 17%, #000 18%);
  animation: hub-sweep 9s linear infinite;
}
@keyframes hub-sweep { to { transform: rotate(1turn); } }

/* ---- left column: 成就统计, 密钥加入, 作战提示 ------------------------------------------------------------ */
.hub-side { grid-area: side; position: relative; z-index: 1; display: flex; flex-direction: column; gap: .14rem; min-width: 0; padding-top: .3rem; }
/* 成就统计 (#643's top-left card, from the event video): a dusk scene with the emblem and the trophy medal, the label strip
   with the LV under it */
.hub-ach {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  padding: 0;
  font: inherit;
  text-align: left;
  color: #eef3f1;
  cursor: pointer;
  background: #0c1110;
  border: 1px solid rgba(220, 230, 226, .16);
  box-shadow: 0 .04rem .16rem rgba(0, 0, 0, .45);
  transition: border-color var(--t-fast), filter var(--t-fast);
}
.hub-ach:hover, .hub-ach:focus-visible { border-color: rgba(78, 216, 175, .35); filter: brightness(1.08); outline: none; }
.hub-ach:focus-visible { box-shadow: 0 0 0 2px var(--mint-400); }
.hub-ach__scene { position: relative; height: 1rem; overflow: hidden; display: grid; place-items: center; }
.hub-ach__land { position: absolute; inset: 0; width: 100%; height: 100%; }
.hub-ach__scene::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .18) 0 1px, transparent 1px 3px), linear-gradient(90deg, rgba(8, 10, 10, .55), transparent 40%);
}
.hub-ach__mark { position: relative; z-index: 1; display: grid; place-items: center; }
.hub-ach__mark .emblem { margin: 0; gap: .06rem; animation: none; }
.hub-ach__mark .emblem__svg { width: .52rem; height: .56rem; filter: drop-shadow(0 0 .04rem rgba(0, 0, 0, .6)); }
.hub-ach__mark .emblem__svg circle { fill: #15110c; animation: none; }
.hub-ach__mark .emblem__svg circle.is-accent { fill: #2cf0b8; }
.hub-ach__mark .emblem__bracket { width: .07rem; height: .66rem; border-width: 1px; border-color: rgba(20, 16, 10, .55); }
.hub-ach__rank {
  position: absolute;
  left: .1rem;
  top: .1rem;
  z-index: 2;
  width: .6rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .01rem;
  padding: .04rem 0 .03rem;
  background: rgba(14, 18, 17, .55);
  border: 1px solid rgba(240, 244, 243, .4);
}
.mode-card__icon {
  position: absolute;
  top: .32rem;
  left: .28rem;
  width: .88rem;
  height: .88rem;
  display: grid;
  place-items: center;
  background: #0c0f0e;
  border: 1px solid var(--line-2);
  color: var(--text-md);
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
  transition: background var(--t-med), color var(--t-med);
}
.mode-card__icon .icon { width: .44rem; height: .44rem; }
.mode-card__text { position: relative; display: flex; flex-direction: column; gap: .1rem; }
.mode-card__name { font-size: calc(.38 * var(--t)); font-weight: 900; letter-spacing: .08em; line-height: 1.15; }
.mode-card__desc { font-size: calc(.17 * var(--t)); color: var(--text-lo); line-height: 1.65; max-width: 3.6rem; }
.mode-card__points { display: flex; flex-direction: column; gap: .05rem; margin-top: .06rem; font-size: calc(.15 * var(--t)); color: var(--text-md); }
.mode-card__points span::before {
  content: '';
  display: inline-block;
  width: .06rem;
  height: .06rem;
  margin: 0 .1rem .02rem 0;
  background: var(--mint-700);
  transform: rotate(45deg);
  vertical-align: middle;
}
.mode-card__check {
  position: absolute;
  bottom: .25rem;
  left: .28rem;
.hub-ach__medal { width: .44rem; height: .44rem; object-fit: contain; }
.hub-ach__rank > .icon { width: .3rem; height: .3rem; color: #eef3f1; }
.hub-ach__rank small { display: inline-flex; align-items: center; gap: .02rem; font-size: min(calc(.13 * var(--t)), .15rem); color: #e6ebe9; }
.hub-ach__rank small .icon { width: .12rem; height: .12rem; }
.hub-ach__label {
  position: relative;
  display: flex;
  align-items: center;
  gap: .08rem;
  flex-wrap: wrap;
  min-height: .46rem;
  padding: .02rem .16rem;
  font-size: calc(.21 * var(--t));
  font-weight: 700;
  background: linear-gradient(90deg, rgba(20, 26, 25, .96), rgba(14, 18, 17, .96));
  border-top: 1px solid rgba(220, 230, 226, .14);
}
.hub-ach__label::before, .hub-ach__label::after { content: ''; position: absolute; top: .06rem; bottom: .06rem; width: .06rem; border: 1px solid rgba(220, 230, 226, .3); }
.hub-ach__label::before { left: .04rem; border-right: 0; }
.hub-ach__label::after { right: .04rem; border-left: 0; }
.hub-ach__badge { flex: none; width: .24rem; height: .24rem; fill: #e8eeec; }
.hub-ach__lv { margin-left: auto; font-size: calc(.15 * var(--t)); font-weight: 600; color: var(--mint-400); }
.hub-tile {
  display: flex;
  align-items: center;
  gap: .14rem;
  width: 100%;
  min-height: .74rem;
  padding: .1rem .16rem;
  text-align: left;
  color: var(--text-hi);
  background: rgba(8, 14, 13, .8);
  border: 1px solid rgba(223, 230, 226, .2);
  border-left: 3px solid var(--mint-500);
  transition: background var(--t-fast), border-color var(--t-fast);
}
.hub-tile:hover, .hub-tile:focus-visible { background: rgba(24, 40, 36, .9); border-color: var(--mint-a35); }
.hub-tile__icon { flex: none; display: grid; place-items: center; width: .44rem; height: .44rem; border: 1px solid var(--mint-a35); color: var(--mint-400); }
.hub-tile__icon .icon { width: .24rem; height: .24rem; }
.hub-tile__text { display: flex; flex-direction: column; gap: .02rem; min-width: 0; }
.hub-tile__label { font-size: calc(.2 * var(--t)); font-weight: 800; }
.hub-tile__en { font-family: ui-monospace, Consolas, monospace; font-size: calc(.1 * var(--t)); font-weight: 600; letter-spacing: .18em; color: var(--text-dim); }
.hub-side .tips { margin-top: .04rem; background: rgba(8, 14, 13, .72); }

/* ---- right column: light plates with bracket marks (S.W.E.E.P.报告, 干员调配 = loadout.js's LoadoutButton) --------- */
.hub-right { grid-area: right; position: relative; z-index: 1; align-self: start; display: flex; flex-direction: column; gap: .12rem; min-width: 0; padding-top: .3rem; }
.lobby-hub .hub-plate {
  --pl-ink: #222b28;
  --bk-c: var(--mint-400);
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: .14rem;
  width: 100%;
  height: auto;
  min-height: .7rem;
  min-width: 0;
  padding: .04rem .22rem .04rem .2rem;
  font: inherit;
  font-size: calc(.2 * var(--t));
  letter-spacing: .04em;
  color: #111816;
  text-align: left;
  cursor: pointer;
  background:
    linear-gradient(var(--pl-ink), var(--pl-ink)) left .07rem center / 2px 54% no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) left .07rem top 23% / .06rem 2px no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) left .07rem bottom 23% / .06rem 2px no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) right .07rem center / 2px 54% no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) right .07rem top 23% / .06rem 2px no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) right .07rem bottom 23% / .06rem 2px no-repeat,
    linear-gradient(180deg, #e8edea, #c6cfcb);
  border: 1px solid rgba(255, 255, 255, .5);
  box-shadow: 0 .05rem .18rem rgba(0, 0, 0, .5), inset 0 -2px 0 rgba(0, 0, 0, .14);
}
.mode-card.is-selected::before { transform: scaleX(1); }
.mode-card.is-selected .mode-card__icon { background: var(--mint-500); border-color: var(--mint-400); color: var(--text-on-mint); }
.mode-card.is-selected .mode-card__check { opacity: 1; transform: none; }
.mode-card--firepower .mode-card__bg { background: radial-gradient(85% 65% at 100% 0%, rgba(255, 198, 0, .11), transparent 70%), repeating-linear-gradient(-45deg, rgba(255, 255, 255, .018) 0 2px, transparent 2px 12px); }
.mode-card--firepower .mode-card__icon { color: var(--gold-2); }
.mode-card--firepower::before { background: linear-gradient(90deg, var(--gold), transparent); }
.mode-card--firepower.is-selected { --bk-c: var(--gold); border-color: var(--gold-2); box-shadow: 0 0 0 1px rgba(255, 198, 0, .2), 0 0 .3rem rgba(255, 198, 0, .1), inset 0 0 .6rem rgba(255, 198, 0, .04); }
.mode-card--firepower.is-selected .mode-card__icon, .mode-card--firepower.is-selected .mode-card__check { background: var(--gold); color: #181405; border-color: var(--gold-2); }

/* Full-width protocol choices stay readable when the root scale reaches its mobile floor. */
@media (max-width: 900px) {
  .lobby-mode .mode-card { padding-left: 1.1rem; }
  .lobby-mode .mode-card__icon { left: .22rem; width: .66rem; height: .66rem; }
  .lobby-mode .mode-card__name { font-size: calc(.34 * var(--t)); }
  .lobby-mode .mode-card__desc { font-size: calc(.18 * var(--t)); }
  .lobby-mode .mode-card__points { font-size: calc(.16 * var(--t)); }
  .firepower-features { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .16rem .26rem; }
  .lobby-right .diff-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lobby-right .diff-card__head { flex-wrap: nowrap; }
  .lobby-right .diff-card__meta { flex-basis: auto; margin-left: auto; }
  .lobby-left { display: flex; }
  .lobby-left > .matchmaking-panel { margin-bottom: .22rem; }
}
@media (max-height: 460px) and (min-width: 641px) {
  .lobby-mode .mode-card { min-height: 0; padding: .24rem .22rem .22rem 1.05rem; }
  .lobby-mode .mode-card__name { font-size: calc(.34 * var(--t)); }
  .lobby-mode .mode-card__check { bottom: .18rem; left: .22rem; font-size: calc(.12 * var(--t)); padding: .03rem .06rem; }
  .firepower-brief { padding: .16rem .2rem; }
  .firepower-features { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .lobby-right .diff-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .lobby-right .diff-card__head { flex-wrap: wrap; }
  .lobby-right .diff-card__meta { flex-basis: 100%; margin-left: .36rem; }
}
@media (max-width: 640px) {
  .lobby-screen .lobby-body { grid-template-columns: minmax(0, 1fr); gap: .3rem; padding: .26rem .3rem .4rem; }
  .lobby-mode { grid-column: 1; }
  .lobby-right { grid-column: 1; grid-row: 2; }
  .lobby-left { grid-column: 1; grid-row: 3; }
  .lobby-mode .mode-cards { grid-template-columns: minmax(0, 1fr); gap: .15rem; }
  .lobby-mode .mode-card { min-height: 0; padding: .25rem .26rem .24rem 1.18rem; }
  .lobby-mode .mode-card__icon { top: .3rem; }
  .lobby-mode .mode-card__name { font-size: max(calc(.34 * var(--t)), 18px); }
  .lobby-mode .mode-card__desc { font-size: max(calc(.18 * var(--t)), 11px); max-width: none; }
  .lobby-mode .mode-card__points { display: flex; font-size: max(calc(.15 * var(--t)), 10px); }
  .lobby-mode .mode-card__check { bottom: .2rem; left: .22rem; }
  .lobby-mode .mode-card__text { padding-top: .03rem; }
  .firepower-brief__hint { margin-left: 0; width: 100%; font-size: max(calc(.15 * var(--t)), 10px); }
  .firepower-feature strong { font-size: max(calc(.17 * var(--t)), 11px); }
  .firepower-feature p { font-size: max(calc(.15 * var(--t)), 10px); }
  .mode-beta { font-size: max(calc(.13 * var(--t)), 9px); }
  .lobby-right .diff-card__head { flex-wrap: wrap; }
  .lobby-right .diff-card__meta { flex-basis: 100%; margin-left: .36rem; }
  .lobby-right .diff-card__name { font-size: max(calc(.22 * var(--t)), 12px); }
  .lobby-right .diff-card__desc { font-size: max(calc(.16 * var(--t)), 10px); line-height: 1.5; }
  .lobby-right .diff-card__effects { display: flex; font-size: max(calc(.14 * var(--t)), 9px); }
  .lobby-right .diff-card__check { display: none; }
  .lobby-right .diff-card__meta { font-size: max(calc(.14 * var(--t)), 9px); }
  .lobby-right .diff-card__meta .num { font-size: max(calc(.17 * var(--t)), 10px); }
  .lobby-right .create-box { width: 100%; }
  .lobby-right .create-box .btn--xl { font-size: max(calc(.28 * var(--t)), 16px); height: max(.72rem, 40px); }
  .matchmaking-panel { flex-wrap: wrap; }
  .join-row { flex-wrap: wrap; }
  .join-row .field { flex-basis: 100%; }
}
@keyframes card-in { from { opacity: 0; transform: translateY(.14rem); } }
.lobby-hub .hub-plate:not(:disabled):hover { border-color: #fff; box-shadow: 0 .05rem .22rem rgba(0, 0, 0, .55), 0 0 .16rem rgba(78, 216, 175, .3); filter: brightness(1.05); }
.lobby-hub .hub-plate:focus-visible { outline: 2px solid var(--mint-400); outline-offset: 2px; }
.hub-plate__glyph, .lobby-hub .hub-plate .lo-entry__icon, .lobby-hub .hub-plate > .btn__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: .46rem;
  height: .46rem;
  padding: .07rem;
  box-sizing: border-box;
  color: var(--mint-400);
  background: #182120;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .08);
}
.hub-plate__glyph svg { width: 100%; height: 100%; }
/* (a label too long for its plate wraps beside its glyph and the plate grows, rather than an ellipsis — §37.18 review:
   Japanese S.W.E.E.P.レポート beside its tag at 特大 in 800–1280 px windows. It takes the row's free width, at least its
   longest word, so only the tag drops under it when even that does not fit) */
.hub-plate__label, .lobby-hub .hub-plate .btn__label { flex: 1 1 0; min-width: min-content; font-weight: 900; letter-spacing: .04em; line-height: 1.15; white-space: normal; color: #111816; }
.hub-plate__tag { margin-left: auto; padding: .03rem .07rem; font-size: calc(.11 * var(--t)); font-weight: 700; letter-spacing: .12em; color: rgba(17, 24, 22, .6); border: 1px solid rgba(17, 24, 22, .28); white-space: nowrap; }
.lobby-hub .hub-plate .lo-entry__n { margin-left: auto; }
/* 成就统计 as a plate: only on short screens, where the left column with its card gives way (see the media block) */
.lobby-hub .hub-plate--ach { display: none; }
.hub-plate--ach .hub-plate__glyph svg { fill: currentColor; }

/* ---- entries (独立模拟 / 同盟模拟), bottom right ----------------------------------------------------------- */
/* (the card, the line above it, the tips' head and the 成就统计 card's label grow or wrap rather than cut their text at
   大 / 特大 in a small window — §37.18 review; the trophy count under the medal stops at .15rem, 大's size [ASSUMED]) */
/* (the two cards share a height: the taller one's, their text at the bottom) */
.hub-entries { grid-area: entries; position: relative; z-index: 1; display: flex; align-items: stretch; justify-content: flex-end; gap: var(--hub-gap); min-width: 0; }
.hub-entry-wrap { display: flex; flex-direction: column; gap: .05rem; min-width: 0; animation: card-in var(--t-slow) var(--ease-out) backwards; }
.hub-entry-wrap:nth-child(2) { animation-delay: 60ms; }
.hub-entry__group { display: flex; align-items: center; gap: .06rem; min-height: .22rem; padding-left: .04rem; font-size: calc(.13 * var(--t)); color: rgba(223, 230, 226, .7); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hub-entry__group .icon { flex: none; width: .16rem; height: .16rem; color: var(--mint-400); }
.hub-entry__long { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hub-entry__short { display: none; }
/* Narrow desktop windows keep the full descriptions (phones have their own short labels below).
   [ASSUMED] A shared two-line minimum keeps both cards level when only one description wraps. */
@media (max-width: 900px) and (min-height: 521px) {
  .hub-entry__group { min-height: 3em; white-space: normal; overflow: visible; text-overflow: clip; }
  .hub-entry__long { white-space: normal; overflow: visible; text-overflow: clip; }
}
.hub-entry {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  flex: 1 0 auto;
  width: var(--hub-entry-w);
  max-width: 100%;
  min-height: calc(1.34 * var(--t));
  padding: .14rem .16rem;
  /* the icon's height kept above the text (below) */
  padding-top: calc(.12rem + .42 * var(--t) + .04rem);
  overflow: hidden;
  text-align: left;
  color: var(--text-hi);
  background: linear-gradient(160deg, rgba(30, 46, 42, .94), rgba(9, 15, 14, .96));
  border: 1px solid rgba(223, 230, 226, .26);
  box-shadow: 0 .06rem .24rem rgba(0, 0, 0, .5);
  transition: transform var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
.hub-entry:hover, .hub-entry:focus-visible { transform: translateY(-.04rem); border-color: var(--mint-400); box-shadow: 0 .08rem .3rem rgba(0, 0, 0, .55), 0 0 .2rem var(--mint-a20); }
.hub-entry:active { transform: translateY(1px); }
.hub-entry__icon { position: absolute; right: .14rem; top: .12rem; color: var(--mint-a35); }
.hub-entry__icon .icon { width: calc(.42 * var(--t)); height: calc(.42 * var(--t)); }
/* the card, its icon and its text follow 文字大小 together (2.3 × 1.34 --t, the icon .42 --t), as at 小; the text stays
   below the icon — the card's top padding is the icon's .12rem offset, its height and a gap — so a long name or the
   decorative line grows the card rather than running under it (§37.18 review: 「ALLIANCE SIMULATION」 ran under the
   people icon in English, Korean names under it at 大 / 特大; a padding beside it instead wrapped the line in every
   language, Chinese 「ALLIANCE / SIMULATION」 at 小, which never reached the icon). A short card keeps its min-height */
.hub-entry__en { font-family: ui-monospace, Consolas, monospace; font-size: calc(.11 * var(--t)); font-weight: 700; letter-spacing: .22em; color: var(--mint-400); }
/* the name wraps between words (§37.18 review: on one line English 「Solo Simulation」 / 「Team Simulation」 ran 25–40 px
   past the 2.3rem card at 小 in every window and 84–100 px at 特大, the card cutting it); 「Simulation」 alone is ~6.2em,
   and the card (2.3 × --t) keeps ~1.98 × --t inside for the .3 × --t name */
.hub-entry__name { margin-top: .04rem; font-size: calc(.3 * var(--t)); font-weight: 900; letter-spacing: .06em; line-height: 1.1; }
.hub-entry__corner { position: absolute; right: 0; bottom: 0; width: .3rem; height: .3rem; background: linear-gradient(135deg, transparent 50%, var(--mint-500) 50%); opacity: .8; }
/* 同盟模拟, the main way to play: bright */
.hub-entry--coop { background: linear-gradient(160deg, var(--mint-500), #1f8f72); color: #04140f; border-color: var(--mint-400); }
.hub-entry--coop .hub-entry__en { color: rgba(4, 20, 15, .75); }
.hub-entry--coop .hub-entry__icon { color: rgba(4, 20, 15, .25); }
.hub-entry--coop .hub-entry__corner { background: linear-gradient(135deg, transparent 50%, #e8fff7 50%); }
@keyframes card-in { from { opacity: 0; transform: translateY(.14rem); } }

/* ---- tips -------------------------------------------------------------------------------------------- */
.tips {
  --bk-c: var(--line-3);
  margin-top: .3rem;
  padding: .16rem .22rem .2rem;
  background: rgba(8, 10, 9, .55);
  border: 1px solid var(--line);
}
.tips__head { display: flex; flex-wrap: wrap; align-items: center; gap: .1rem; font-size: calc(.16 * var(--t)); font-weight: 700; color: var(--text-md); }
.tips__head > .icon { width: .2rem; height: .2rem; color: var(--mint-500); }
/* the count and its arrows move to a line of their own, together, when the head is too narrow for them (§37.18 review) */
.tips__pager { display: inline-flex; align-items: center; gap: .1rem; margin-left: auto; }
.tips__idx { font-size: calc(.16 * var(--t)); color: var(--text-md); }
.tips__nav {
  display: grid;
  place-items: center;
  width: .3rem;
  height: .3rem;
  padding: 0;
  border: 1px solid var(--line-2);
  background: transparent;
  color: var(--text-lo);
  transition: color var(--t-fast), border-color var(--t-fast);
}
.tips__nav:hover { color: var(--mint-400); border-color: var(--mint-700); }
.tips__nav .icon { width: .18rem; height: .18rem; }
.tips__text { margin-top: .1rem; font-size: calc(.17 * var(--t)); color: var(--text-lo); line-height: 1.6; animation: tip-in var(--t-slow) var(--ease-out); }
@keyframes tip-in { from { opacity: 0; transform: translateX(.1rem); } }

/* ---- the two full-screen dialogs (Modal .proto / .ally) --------------------------------------------- */
.modal.proto-veil { padding: 0; background: #0b0c0c; -webkit-backdrop-filter: none; backdrop-filter: none; }
.modal__box.proto, .modal__box.ally {
  position: fixed;
  inset: 0;
  width: auto;
  max-height: none;
  padding: var(--sa-t, 0px) var(--sa-r, 0px) var(--sa-b, 0px) var(--sa-l, 0px);
  color: #eef0ef;
  background: #0b0c0c;
  border: 0;
  box-shadow: none;
  overscroll-behavior: contain;
  animation: proto-in 200ms var(--ease-out) backwards;
}
.modal__box.proto::after, .modal__box.proto > .modal__stripe, .modal__box.ally::after, .modal__box.ally > .modal__stripe { display: none; }
.modal__box.proto > .modal__body, .modal__box.ally > .modal__body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 0; overflow: hidden; color: inherit; }
.proto__body, .ally__body { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
@keyframes proto-in { from { opacity: 0; } }
.proto__bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: background 400ms;
  background:
    radial-gradient(46% 60% at 30% 52%, rgba(255, 255, 255, .05), transparent 70%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .022) 0 1px, transparent 1px 4px),
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    radial-gradient(120% 90% at 50% 40%, #151616, #070808);
  background:
    radial-gradient(46% 60% at 30% 52%, color-mix(in srgb, var(--d-color, #4ed8af) 16%, transparent), transparent 70%),
    radial-gradient(40% 50% at 100% 50%, color-mix(in srgb, var(--d-color, #4ed8af) 10%, transparent), transparent 70%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .022) 0 1px, transparent 1px 4px),
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    radial-gradient(120% 90% at 50% 40%, #151616, #070808);
}
.proto-top, .proto-body { position: relative; }
.proto-top { flex: none; display: flex; align-items: flex-start; justify-content: space-between; gap: .2rem; padding: .18rem .34rem 0 .22rem; z-index: 2; }
.proto-back {
  display: inline-flex;
  align-items: center;
  height: max(.62rem, 32px, calc(36px * var(--sp-ui, 1)));
  padding: 0;
  font: inherit;
  color: #f2f4f3;
  background: linear-gradient(180deg, #2b2c2d, #1b1c1d);
  border: 1px solid rgba(255, 255, 255, .1);
  box-shadow: 0 .04rem .14rem rgba(0, 0, 0, .5);
}
.proto-back > .icon { width: max(.4rem, 22px); height: max(.4rem, 22px); margin: 0 .3rem 0 .14rem; }
.proto-back__home {
  display: grid;
  place-items: center;
  align-self: stretch;
  width: max(2rem, 32px, calc(96px * var(--sp-ui, 1)));
  border-left: 2px solid #0d0e0e;
  background: radial-gradient(circle, rgba(255, 255, 255, .22) 1px, transparent 1.6px) 0 0 / .14rem .14rem, linear-gradient(90deg, #2f3132, #3d3f40 50%, #2f3132);
}
.proto-back__home .icon { width: max(.32rem, 18px); height: max(.32rem, 18px); }
.proto-back:hover, .proto-back:focus-visible { border-color: rgba(255, 255, 255, .35); }
.proto-title { display: flex; flex-direction: column; align-items: flex-end; gap: .02rem; min-width: 0; padding-top: .06rem; text-align: right; }
.proto-title .modal__title { margin: 0; font-size: calc(.36 * var(--t)); font-weight: 900; letter-spacing: .06em; color: #eef0ef; }
.proto-title__mode { display: inline-flex; align-items: center; gap: .08rem; font-size: calc(.16 * var(--t)); font-weight: 700; color: var(--d-color, var(--mint-400)); }
.proto-title__mode .icon { width: 1.1em; height: 1.1em; }
.proto-title__mode i { font-style: normal; font-family: var(--font-display); font-size: calc(.13 * var(--t)); letter-spacing: .16em; color: #8b8f8e; }

/* the cards' column 5.6rem, at least 300 px (§37.18 review: in a window whose 1rem is under 54 px — 960×540, 1100×530,
   800×600 — the px floors of the glyph and the 文字大小 made 5.6rem too narrow for English 「Standard Simulation」 /
   「Ultimate Simulation」 on one line, and the unselected cards' names ended in an ellipsis), never past 46vw. [ASSUMED] the
   floor */
.proto-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) min(max(5.6rem, 32px, calc(300px * var(--sp-ui, 1))), 46vw); gap: .3rem; padding: 0 .34rem .26rem .22rem; }
.proto-stage { position: relative; min-width: 0; min-height: 0; display: grid; place-items: center; }

/* the official picture of the selected difficulty, with its brief at the bottom left */
/* the picture fills the column (as #643's drawn scene did: from a little above the cards down to the brief) */
.proto__pic { position: absolute; inset: -.5rem -1.8rem .9rem -.3rem; display: grid; place-items: center; min-height: 0; animation: proto-pic var(--t-slow) var(--ease-out); }
.proto__art {
  width: 100%;
  height: 100%;
  max-width: 9.4rem; /* the art is 427 × 332: up to about 2.2× before it turns soft */
  max-height: 7.3rem;
  object-fit: contain;
  filter: drop-shadow(0 0 .2rem var(--d-color));
  filter: drop-shadow(0 0 .2rem color-mix(in srgb, var(--d-color) 45%, transparent));
}
.proto__glyph { width: 2.2rem; height: 2.2rem; color: var(--d-color); opacity: .8; filter: drop-shadow(0 0 .2rem var(--d-color)); }
@keyframes proto-pic { from { opacity: 0; transform: translateX(-.14rem); } }

/* the scene (ui/protocolScene.js, PR #643 + video 5:00–5:16): the official ship on a survey grid between two squares of
   defenders, the cable with a light running down it; it reaches under the cards like the event's. A new difficulty
   remounts it: dark first, then up in the new colour. */
.proto-side { position: relative; z-index: 1; }

.ps { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; color: var(--d-color); animation: ps-in 640ms ease-out backwards; }
@keyframes ps-in { 0% { opacity: 0; filter: brightness(.15); } 35% { opacity: .35; filter: brightness(.3); } 100% { opacity: 1; filter: none; } }
.ps-grid line { stroke: currentColor; stroke-opacity: .12; stroke-width: 1; }
.ps-pad polygon { fill: currentColor; fill-opacity: .1; stroke: currentColor; stroke-opacity: .55; stroke-width: 1.2; }
.ps-pad__edge { fill: none; stroke: currentColor; stroke-opacity: .7; stroke-width: 2; stroke-dasharray: 26 8; }
.ps-hull { filter: drop-shadow(0 0 6px var(--d-color)); }
.ps-ship image { filter: drop-shadow(0 0 10px var(--d-color)); filter: drop-shadow(0 0 10px color-mix(in srgb, var(--d-color) 55%, transparent)); }
.ps-face { stroke: currentColor; stroke-width: 1.3; stroke-linejoin: round; fill: currentColor; }
.ps-face--top { fill-opacity: .42; }
.ps-face--front { fill-opacity: .26; }
.ps-face--side { fill-opacity: .16; }
.ps-seam { stroke: #fff; stroke-opacity: .35; stroke-width: 1; }
.ps-beacon { fill: #fff; animation: ps-blink 1.6s steps(2) infinite; }
@keyframes ps-blink { 50% { opacity: .2; } }
.ps-cable { fill: none; stroke: currentColor; stroke-width: 5; stroke-opacity: .7; stroke-linecap: round; }
.ps-cable__pulse { fill: none; stroke: #fff6d8; stroke-width: 6; stroke-linecap: round; stroke-dasharray: 90 1200; stroke-dashoffset: 90;
  filter: drop-shadow(0 0 6px var(--d-color)); animation: ps-pulse 2.6s cubic-bezier(.5, 0, .7, 1) 400ms infinite; }
@keyframes ps-pulse { from { stroke-dashoffset: 90; opacity: 1; } 85% { opacity: 1; } to { stroke-dashoffset: -1000; opacity: 0; } }
.ps-fig { animation: ps-fig 360ms var(--ease-out) backwards; animation-delay: calc(240ms + var(--i) * 18ms); }
@keyframes ps-fig { from { opacity: 0; transform: translateY(-6px); } }
.ps-fig__body, .ps-fig__head { fill: currentColor; fill-opacity: .88; stroke: rgba(0, 0, 0, .45); stroke-width: .8; }
.ps-fig__head { fill-opacity: 1; }
.ps-fig__shadow { fill: #000; opacity: .35; }
.ps-spike polygon { fill: currentColor; fill-opacity: .75; }
.ps-spike__x { stroke: currentColor; stroke-width: 2; stroke-opacity: .8; }
.ps-spike { animation: ps-fig 420ms var(--ease-out) backwards; animation-delay: calc(var(--i) * 60ms + 120ms); }
.ps-call rect { fill: rgba(0, 0, 0, .55); stroke: currentColor; stroke-width: 1.5; }
.ps-call line { stroke: currentColor; stroke-width: 1.5; stroke-opacity: .8; }
.ps-call rect.ps-call__icon { fill: currentColor; fill-opacity: .25; }
.ps-call__man { fill: currentColor; }
.ps-call { animation: ps-fig 420ms var(--ease-out) 420ms backwards; }
.ps-scan { stroke: currentColor; stroke-opacity: .2; stroke-width: 2; animation: ps-scan 7s linear infinite; }
@keyframes ps-scan { from { transform: translateY(40px); } to { transform: translateY(620px); } }
.proto-brief {
  position: absolute;
  left: .1rem;
  bottom: .1rem;
  max-width: min(6rem, 92%);
  padding: .12rem .2rem .14rem;
  background: linear-gradient(90deg, rgba(0, 0, 0, .7), rgba(0, 0, 0, .2));
  border-left: 3px solid var(--d-color);
}
.proto-brief__code { margin-right: .1rem; padding: 0 .08rem; font-size: calc(.14 * var(--t)); color: #111; background: var(--d-color); }
.proto-brief__name { font-size: calc(.26 * var(--t)); color: var(--d-color); }
.proto-brief p { margin: .04rem 0 0; font-size: calc(.16 * var(--t)); line-height: 1.5; color: #b7bcba; }

/* the difficulty cards: the chosen one slides out with a glow and the 已选定 stamp; centred while they fit (auto margins, so
   a list taller than the column still scrolls from its top). The gaps and pads a little tighter than #643's (.14rem, .1rem
   and .1 / .11rem) so the full cards fit at 小 in a 16:9 window (they were 2–26 px too tall at 1280x720 – 1920x1080:
   §37.18's leftover). [ASSUMED] the spacing */
.proto-side { min-height: 0; display: flex; flex-direction: column; gap: .14rem; }
.proto-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: .1rem;
  padding: .07rem .06rem .07rem .5rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .25) transparent;
}
.proto-list > :first-child { margin-top: auto; }
.proto-list > :last-child { margin-bottom: auto; }
.pcard {
  position: relative;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: .04rem;
  padding: .08rem .26rem .09rem;
  overflow: hidden;
  font: inherit;
  text-align: left;
  color: #e9eceb;
  background: linear-gradient(180deg, #252627, #1a1b1c);
  border: 2px solid #55585a;
  border-radius: .2rem;
  box-shadow: 0 .05rem .16rem rgba(0, 0, 0, .5);
  transition: transform 220ms var(--ease-out), border-color 220ms;
}
.pcard:hover:not(.is-on), .pcard:focus-visible:not(.is-on) { border-color: #7b7f81; }
/* the room's read-only view (another doctor's: the host chooses): shown, not chosen */
.pcard:disabled { cursor: default; }
.pcard:disabled:hover:not(.is-on) { border-color: #55585a; }
.pcard.is-on { transform: translateX(-.44rem); border-color: #8f9496; }
.pcard__glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 260ms;
  background: radial-gradient(70% 140% at 100% 50%, rgba(255, 255, 255, .12), transparent 72%);
  background: radial-gradient(70% 140% at 100% 50%, color-mix(in srgb, var(--d-color) 70%, transparent), transparent 72%);
}
.pcard.is-on .pcard__glow { opacity: 1; }
.pcard__head, .pcard__desc, .pcard__effects, .pcard__meta { position: relative; }
.pcard.is-on .pcard__head, .pcard.is-on .pcard__desc, .pcard.is-on .pcard__effects, .pcard.is-on .pcard__meta { padding-right: max(1.3rem, 32px, calc(70px * var(--sp-ui, 1))); }
.pcard__head { display: flex; align-items: center; gap: .08rem; }
.pcard__glyph { width: max(.3rem, 18px); height: max(.3rem, 18px); color: var(--d-color); }
.pcard__name { font-size: min(calc(.28 * var(--t)), .36rem); font-weight: 900; letter-spacing: .04em; color: var(--d-color); text-shadow: 0 0 .1rem rgba(0, 0, 0, .6); white-space: nowrap; }
.pcard__desc { padding-bottom: .05rem; font-size: calc(.16 * var(--t)); color: #9a9f9d; border-bottom: 1px solid rgba(255, 255, 255, .18); }
.pcard__effects { display: flex; flex-direction: column; padding-top: .04rem; font-size: calc(.17 * var(--t)); line-height: 1.4; }
.pcard__effects span::before { content: '·'; margin-right: .06rem; }
.pcard__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .04rem .14rem; margin-top: .04rem; font-size: calc(.13 * var(--t)); color: #7f8583; }
.pcard__meta b { color: #cfd3d1; }
.pcard__stage { display: inline-flex; align-items: center; gap: .04rem; }
.pcard__stage .icon { width: 1.1em; height: 1.1em; }
.pcard__stamp {
  position: absolute;
  right: .2rem;
  top: 50%;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .04rem;
  width: max(1.3rem, 32px, calc(70px * var(--sp-ui, 1)));
  height: max(1.1rem, 32px, calc(60px * var(--sp-ui, 1)));
  transform: translateY(-50%) rotate(-6deg);
}
.pcard.is-on .pcard__stamp { display: flex; animation: proto-stamp 260ms var(--ease-out) backwards; }
@keyframes proto-stamp { from { opacity: 0; transform: translateY(-50%) rotate(-6deg) scale(1.4); } }
.pcard__ring { position: absolute; inset: -.1rem -.14rem; width: calc(100% + .28rem); height: calc(100% + .2rem); }
.pcard__ring path { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; opacity: .9; }
.pcard__tick { display: grid; place-items: center; width: max(.46rem, 26px); height: max(.46rem, 26px); color: #2a1712; background: #f5f5f5; border-radius: .06rem; box-shadow: 0 .02rem .08rem rgba(0, 0, 0, .5); }
.pcard__tick .icon { width: 78%; height: 78%; color: var(--d-color); filter: brightness(.7); }
.pcard__ok { font-size: calc(.18 * var(--t)); font-weight: 800; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .6); white-space: nowrap; }

/* the foot: the test-room box, the hint, 开始独立模拟 / 创建同盟 */
.proto-foot { flex: none; display: flex; flex-direction: column; gap: .08rem; padding-left: .5rem; }
.create-box__test {
  display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: .04rem .1rem;
  color: #e8b84a; font-size: calc(.16 * var(--t));
}
.create-box__test input { width: .2rem; height: .2rem; margin: 0; flex: none; accent-color: #e8b84a; }
.create-box__test em { flex-basis: 100%; font-style: normal; }
@media (max-width: 720px) {
  .create-box__test { font-size: 16px; }
  .create-box__test input { width: 32px; height: 32px; }
  .create-box__test em { font-size: 14px; }
}
.create-box .btn--xl { height: .92rem; font-size: calc(.32 * var(--t)); letter-spacing: .3em; }
.create-box__hint { display: flex; align-items: center; justify-content: center; min-height: .3rem; font-size: calc(.14 * var(--t)); color: var(--text-lo); }

.btn-create-alliance {
  position: relative;
  overflow: hidden;
}
.btn-create-alliance::after {
  content: '';
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 1.4rem;
  background: repeating-linear-gradient(-45deg, rgba(0, 0, 0, .14) 0 8px, transparent 8px 16px);
  pointer-events: none;
}

/* ---- online indicator pill -------------------------------------------------------------------------- */
.online-pill {
  display: inline-flex;
  align-items: center;
  gap: .06rem;
  padding: .04rem .14rem .04rem .12rem;
  background: rgba(14, 28, 24, .85);
  border: 1px solid rgba(78, 216, 175, .35);
  border-radius: .04rem;
  font-size: calc(.15 * var(--t));
  color: var(--mint-400);
}
.online-pill__dot {
  width: .08rem;
  height: .08rem;
  border-radius: 50%;
  background: var(--mint-400);
  box-shadow: 0 0 .08rem var(--mint-400);
}
.online-pill .num {
  font-weight: 700;
  color: var(--text-hi);
}
.online-pill__label {
  font-size: calc(.13 * var(--t));
  color: var(--mint-400);
}

/* ---- 02 多人匹配 MULTIPLAYER MATCHMAKING panel ---------------------------------------------------- */
.matchmaking-panel {
  --bk-c: var(--mint-400);
  --bk-l: .22rem;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .2rem;
  padding: .24rem .28rem;
  margin-bottom: .34rem;
  background: linear-gradient(180deg, rgba(20, 26, 23, .92), rgba(12, 16, 15, .95));
  border: 1px solid rgba(78, 216, 175, .3);
  box-shadow: 0 0 .3rem rgba(23, 249, 183, .04);
}
.matchmaking-panel__content {
  display: flex;
  flex-direction: column;
  gap: .06rem;
  min-width: 0;
}
.matchmaking-panel__title {
  font-size: calc(.28 * var(--t));
  font-weight: 900;
  letter-spacing: .06em;
  color: var(--text-hi);
}
.matchmaking-panel__desc {
  font-size: calc(.15 * var(--t));
  color: var(--text-lo);
  line-height: 1.55;
  max-width: 4.8rem;
}
.matchmaking-panel__action {
  display: flex;
  align-items: center;
  gap: .16rem;
  flex-shrink: 0;
}
.matchmaking-online-chip {
  display: flex;
  align-items: center;
  gap: .08rem;
  padding: .06rem .14rem;
  background: rgba(14, 28, 24, .85);
  border: 1px solid rgba(78, 216, 175, .3);
  border-radius: .04rem;
  color: var(--mint-400);
  font-size: calc(.16 * var(--t));
}
.matchmaking-online-chip .icon {
  width: .18rem;
  height: .18rem;
  color: var(--mint-400);
}
.matchmaking-online-chip .num {
  font-weight: 700;
  color: var(--text-hi);
  font-size: calc(.18 * var(--t));
}
.btn-matchmaking-open {
  height: .64rem;
  padding: 0 .26rem;
  font-size: calc(.2 * var(--t));
  font-weight: 900;
  letter-spacing: .08em;
  background: var(--mint-500);
  color: #0c1210;
  border: 1px solid var(--mint-400);
  box-shadow: 0 0 .2rem rgba(23, 249, 183, .25);
}
.btn-matchmaking-open:hover {
  background: var(--mint-400);
  box-shadow: 0 0 .3rem rgba(23, 249, 183, .45);
}

/* ---- Matchmaking Modal (图2 HUD风格房间大厅) ------------------------------------------------------- */
.mm-modal__box {
  --bk-c: var(--mint-400);
  --bk-l: .25rem;
  width: min(8.8rem, 95vw);
  max-height: 90vh;
  background: linear-gradient(180deg, #131917, #0c100e);
  border: 1px solid rgba(78, 216, 175, .35);
  box-shadow: 0 .3rem 1.2rem rgba(0, 0, 0, .8), 0 0 .5rem rgba(23, 249, 183, .12);
}
.mm-modal .modal__stripe {
  height: .07rem;
  background: repeating-linear-gradient(-45deg, var(--mint-400) 0 8px, transparent 8px 16px);
  opacity: .8;
}
.mm-modal__head {
  padding: .24rem .32rem .1rem;
}
.mm-modal__title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.mm-modal__title {
  font-size: calc(.34 * var(--t));
  font-weight: 900;
  letter-spacing: .06em;
  color: var(--text-hi);
}
.mm-modal__close {
  display: grid;
  place-items: center;
  width: .36rem;
  height: .36rem;
  background: transparent;
  border: 1px solid var(--line-2);
  color: var(--text-md);
  cursor: pointer;
  transition: border-color var(--t-fast), color var(--t-fast);
}
.mm-modal__close:hover {
  border-color: var(--mint-400);
  color: var(--mint-400);
}
.mm-modal__body {
  padding: .14rem .32rem .24rem;
  display: flex;
  flex-direction: column;
  gap: .18rem;
}
.mm-stats-bar {
  display: flex;
  align-items: center;
  padding: .16rem .28rem;
  background: rgba(18, 29, 25, .85);
  border: 1px solid rgba(78, 216, 175, .2);
  gap: .4rem;
}
.mm-stats-col {
  display: flex;
  flex-direction: column;
  gap: .02rem;
}
.mm-stats-num {
  font-size: calc(.38 * var(--t));
  font-weight: 900;
  line-height: 1;
  color: #fff;
}
.mm-stats-num--mint {
  color: var(--mint-400);
  text-shadow: 0 0 .15rem rgba(23, 249, 183, .35);
}
.mm-stats-label {
  font-size: calc(.14 * var(--t));
  color: var(--text-lo);
  letter-spacing: .04em;
}
.mm-refresh-btn {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: .08rem;
  padding: .08rem .16rem;
  background: rgba(0, 0, 0, .3);
  border: 1px solid var(--line-2);
  color: var(--text-md);
  font-size: calc(.16 * var(--t));
  cursor: pointer;
  transition: border-color var(--t-fast), color var(--t-fast);
}
.mm-refresh-btn:hover {
  border-color: var(--mint-400);
  color: var(--text-hi);
}
.mm-refresh-btn .icon {
  width: .18rem;
  height: .18rem;
}
.is-spinning {
  animation: spin 1s linear infinite;
}
@keyframes spin {
  100% { transform: rotate(360deg); }
}
.mm-room-list {
  display: flex;
  flex-direction: column;
  gap: .12rem;
  min-height: 2.2rem;
  max-height: 4.8rem;
  overflow-y: auto;
}
.mm-room-card {
  display: flex;
  align-items: center;
  gap: .2rem;
  padding: .14rem .2rem;
  background: rgba(18, 23, 21, .9);
  border: 1px solid var(--line-2);
  transition: border-color var(--t-fast);
}
.mm-room-card:hover {
  border-color: rgba(78, 216, 175, .3);
}
.mm-room-code {
  width: 1.1rem;
  height: .64rem;
  display: grid;
  place-items: center;
  background: rgba(10, 13, 12, .9);
  border: 1px solid var(--line);
  font-size: calc(.28 * var(--t));
  font-weight: 900;
  letter-spacing: .12em;
  color: var(--text-md);
}
.mm-room-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: .06rem;
  min-width: 0;
}
.mm-room-name {
  font-size: calc(.22 * var(--t));
  font-weight: 700;
  color: var(--text-hi);
}
.mm-room-meta {
  display: flex;
  align-items: center;
  gap: .18rem;
  font-size: calc(.14 * var(--t));
  color: var(--text-md);
}
.mm-room-diff {
  display: flex;
  align-items: center;
  gap: .05rem;
  color: var(--d-color);
  font-weight: 700;
}
.mm-room-diff .diff-glyph {
  width: .18rem;
  height: .18rem;
  color: var(--d-color);
}
.mm-room-players {
  display: flex;
  align-items: center;
  gap: .05rem;
  color: var(--text-md);
}
.mm-room-players .icon {
  width: .16rem;
  height: .16rem;
}
.mm-room-status {
  padding: .02rem .08rem;
  font-size: calc(.12 * var(--t));
  border: 1px solid var(--line);
}
.mm-room-status.is-in-match {
  background: rgba(50, 50, 50, .4);
  color: var(--text-dim);
  border-color: var(--line);
}
.mm-room-status.is-waiting {
  background: rgba(23, 249, 183, .12);
  color: var(--mint-400);
  border-color: rgba(78, 216, 175, .3);
}
.mm-room-actions {
  display: flex;
  align-items: center;
  gap: .1rem;
}
.mm-btn-join {
  min-width: 1.05rem;
  height: .56rem;
}
.mm-btn-join.is-disabled-match {
  opacity: .5;
  cursor: not-allowed;
  background: repeating-linear-gradient(45deg, rgba(23, 249, 183, .06) 0 6px, transparent 6px 12px) !important;
  border-color: var(--line) !important;
  color: var(--text-dim) !important;
}
.mm-btn-spectate {
  min-width: 1.05rem;
  height: .56rem;
  background: rgba(14, 18, 16, .9);
  border: 1px solid var(--line-2);
}
.mm-room-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .12rem;
  padding: .6rem 0;
  color: var(--text-dim);
  font-size: calc(.16 * var(--t));
}
.mm-room-empty .icon {
  width: .36rem;
  height: .36rem;
  color: var(--text-dim);
}
.mm-modal__foot {
  display: flex;
  align-items: center;
  gap: .14rem;
  padding-top: .12rem;
  border-top: 1px solid var(--line);
}
.mm-foot-text {
  font-size: calc(.13 * var(--t));
  color: var(--text-dim);
  letter-spacing: .02em;
}


.matchmaking-count { display: inline-flex; gap: .035rem; color: var(--mint); font-size: max(calc(.12 * var(--t)), 11px); white-space: nowrap; align-items: baseline; }
.mode-card .matchmaking-count { margin-top: .08rem; }
.diff-card__head { flex-wrap: wrap; }

/* Keep the deployed matchmaking controls beside the room browser. */
.matchmaking-panel__action { flex-wrap: wrap; justify-content: flex-end; gap: .1rem; }
.btn-quick-match { height: .64rem; white-space: nowrap; }

/* ---- lobby hub (2026-10-13, owner's request): generated backdrop (ui/hubBackdrop.js), the game's emblem, left
   column, right column (缺人同盟 · S.W.E.E.P.报告 · 干员调配), four entries ---- */
/* backdrop colour tokens: 夜巡 is the default; the swatches of the 大厅背景 dialog carry their own data-hub-theme */
.lobby-hub, [data-hub-theme="night"], [data-hub-theme="custom"] {
  --sky-0: #03080a; --sky-1: #08141a; --sky-2: #12262a; --sky-3: #050909;
  --haze: rgba(92, 168, 156, .17); --cloud: rgba(140, 196, 186, .055);
  --ridge-far: #122022; --ridge-mid: #0b1516; --ridge-near: #060b0b;
  --rim: rgba(110, 226, 196, .34); --fog: rgba(54, 104, 98, .3); --beam: rgba(150, 240, 215, .1);
  --beacon: #59f4ca; --window: rgba(89, 244, 202, .7); --grid: rgba(89, 244, 202, .32);
  --mote: rgba(170, 245, 225, .7); --radar: rgba(89, 244, 202, .15);
}
[data-hub-theme="frost"] {
  --sky-0: #070c12; --sky-1: #142029; --sky-2: #34444f; --sky-3: #090d11;
  --haze: rgba(205, 226, 240, .2); --cloud: rgba(220, 236, 246, .08);
  --ridge-far: #3a4852; --ridge-mid: #212c34; --ridge-near: #0f1418;
  --rim: rgba(240, 248, 255, .62); --fog: rgba(180, 200, 214, .24); --beam: rgba(225, 240, 255, .12);
  --beacon: #9fd8ff; --window: rgba(170, 220, 255, .7); --grid: rgba(170, 215, 240, .26);
  --mote: rgba(240, 248, 255, .85); --radar: rgba(180, 220, 245, .16);
}
[data-hub-theme="ember"] {
  --sky-0: #080605; --sky-1: #120d0b; --sky-2: #251913; --sky-3: #070505;
  --haze: rgba(196, 104, 52, .15); --cloud: rgba(130, 96, 76, .08);
  --ridge-far: #211814; --ridge-mid: #150f0c; --ridge-near: #090606;
  --rim: rgba(255, 150, 80, .28); --fog: rgba(84, 52, 38, .32); --beam: transparent;
  --beacon: #ffae48; --window: rgba(255, 168, 80, .75); --grid: rgba(255, 170, 90, .22);
  --mote: rgba(255, 150, 70, .85); --radar: rgba(255, 180, 110, .14);
}
[data-hub-theme="calm"] {
  --sky-0: #040606; --sky-1: #070b0b; --sky-2: #0c1211; --sky-3: #040505;
  --haze: rgba(80, 120, 110, .07); --cloud: transparent;
  --ridge-far: #0e1514; --ridge-mid: #090e0e; --ridge-near: #050808;
  --rim: rgba(89, 244, 202, .14); --fog: rgba(30, 50, 46, .25); --beam: transparent;
  --beacon: #4ed8af; --window: rgba(78, 216, 175, .45); --grid: rgba(89, 244, 202, .22);
  --mote: transparent; --radar: rgba(89, 244, 202, .11);
}
[data-hub-theme="custom"] { --radar: rgba(235, 245, 240, .14); }

.lobby-hub { --hub-entry-w: 2.1rem; --hub-gap: .14rem; display: flex; flex-direction: column; overflow: hidden; background: #050909; }
.hub-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; background: var(--sky-3); }
.hub-bg__sky { position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--sky-0) 0%, var(--sky-1) 36%, var(--sky-2) 63%, var(--sky-3) 100%); }
.hub-bg__stars { position: absolute; left: 0; top: 0; width: 1px; height: 1px; border-radius: 50%;
  animation: hub-twinkle 7s ease-in-out infinite alternate; }
.hub-bg__haze { position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 20% at 50% 64%, var(--haze), transparent 72%),
    radial-gradient(ellipse 130% 36% at 50% 72%, var(--haze), transparent 70%); }
.hub-bg__clouds { position: absolute; left: 0; top: 6%; width: 200%; height: 50%;
  background:
    radial-gradient(30% 10% at 15% 42%, var(--cloud), transparent 70%),
    radial-gradient(22% 7% at 38% 20%, var(--cloud), transparent 70%),
    radial-gradient(36% 11% at 66% 58%, var(--cloud), transparent 70%),
    radial-gradient(20% 6% at 88% 28%, var(--cloud), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x; animation: hub-drift 180s linear infinite; }
.hub-bg__land { position: absolute; left: 0; bottom: 0; width: 100%; height: 64%; overflow: visible; }
.hub-bg__ridge--far { fill: var(--ridge-far); }
.hub-bg__ridge--mid, .hub-bg__fort { fill: var(--ridge-mid); }
.hub-bg__ridge--near { fill: var(--ridge-near); }
.hub-bg__rim { fill: none; stroke: var(--rim); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.hub-fog-0 { stop-color: var(--fog); stop-opacity: 0; }
.hub-fog-1 { stop-color: var(--fog); stop-opacity: 1; }
.hub-beam-0 { stop-color: var(--beam); }
.hub-beam-1 { stop-color: var(--beam); stop-opacity: 0; }
.hub-bg__beam { transform-origin: 791px 300px; animation: hub-beam 16s ease-in-out infinite alternate; }
.hub-bg__windows rect { fill: var(--window); animation: hub-window 9s steps(1) infinite; animation-delay: var(--dl); }
.hub-bg__beacons g { fill: var(--beacon); animation: hub-beacon 2.8s ease-in-out infinite; animation-delay: var(--dl); }
.hub-bg__beacon-glow { opacity: .22; }
.hub-bg__motes { position: absolute; inset: 0; }
.hub-bg__mote { position: absolute; border-radius: 50%; background: var(--mote); box-shadow: 0 0 6px var(--mote); opacity: 0;
  animation: hub-mote var(--d) linear infinite; animation-delay: var(--dl); }
[data-hub-theme="frost"] .hub-bg__mote { animation-name: hub-snow; }
.hub-bg__grid { position: absolute; left: -20%; right: -20%; bottom: -6%; height: 30%; opacity: .24;
  background:
    repeating-linear-gradient(90deg, var(--grid) 0 1px, transparent 1px 64px),
    repeating-linear-gradient(0deg, var(--grid) 0 1px, transparent 1px 64px);
  transform: perspective(420px) rotateX(62deg); transform-origin: 50% 100%;
  mask-image: linear-gradient(0deg, #000 5%, transparent 85%); -webkit-mask-image: linear-gradient(0deg, #000 5%, transparent 85%); }
.hub-bg__dots { position: absolute; inset: 0; opacity: .12;
  background-image: radial-gradient(rgba(223, 230, 226, .6) 1px, transparent 1.2px); background-size: 22px 22px;
  mask-image: linear-gradient(180deg, #000, transparent 50%); -webkit-mask-image: linear-gradient(180deg, #000, transparent 50%); }
.hub-bg__scan { position: absolute; inset: 0;
  background:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .018) 0 1px, transparent 1px 3px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .06 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.hub-bg__vignette { position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, .42), transparent 16%),
    radial-gradient(130% 95% at 50% 42%, transparent 50%, rgba(0, 0, 0, .72)); }
.hub-bg__photo { position: absolute; inset: -24px; background-position: center; background-size: cover; background-repeat: no-repeat; }
.hub-bg__shade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(3, 7, 7, .92), rgba(3, 7, 7, .78) 50%, rgba(3, 7, 7, .96)); }
.hub-bg[data-motion="off"] *, .lobby-hub .hub-bg[data-motion="off"] { animation: none !important; }
.hub-bg[data-motion="off"] .hub-bg__mote { opacity: .3; }

@keyframes hub-twinkle { from { opacity: .5; } to { opacity: 1; } }
@keyframes hub-drift { to { transform: translateX(-50%); } }
@keyframes hub-beam { from { transform: rotate(-18deg); } to { transform: rotate(24deg); } }
@keyframes hub-window { 0%, 70% { opacity: .9; } 72%, 78% { opacity: .2; } 80%, 100% { opacity: .9; } }
@keyframes hub-beacon { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
@keyframes hub-mote { 0% { transform: translate3d(0, 0, 0); opacity: 0; } 15% { opacity: .8; } 85% { opacity: .45; } 100% { transform: translate3d(2vw, -18vh, 0); opacity: 0; } }
@keyframes hub-snow { 0% { transform: translate3d(0, -12vh, 0); opacity: 0; } 15% { opacity: .9; } 85% { opacity: .7; } 100% { transform: translate3d(-3vw, 14vh, 0); opacity: 0; } }
@keyframes hub-sweep { to { transform: rotate(1turn); } }
@keyframes hub-pulse { 0% { box-shadow: 0 0 0 0 rgba(89, 244, 202, .55); } 100% { box-shadow: 0 0 0 .1rem rgba(89, 244, 202, 0); } }

.lobby-hub > .topbar, .hub-stage { position: relative; z-index: 1; }
/* the top bar's own dialogs (设置, 玩法说明, the account menu) open inside it: it must stack above the stage */
.lobby-hub > .topbar { z-index: 2; }
.hub-topbar { background: linear-gradient(180deg, rgba(4, 8, 8, .85), transparent); border-bottom: 0; }
.hub-online { display: inline-flex; align-items: center; gap: .08rem; padding: .04rem .14rem; margin-right: .1rem;
  border: 1px solid var(--mint-a35); background: rgba(8, 14, 12, .6); color: var(--text-hi); font-size: calc(.14 * var(--t)); white-space: nowrap; }
.hub-online .num { color: var(--mint-400); font-weight: 800; }

/* the centre spans the whole first row so the emblem sits in the middle of the screen; both columns lie above it */
.hub-stage { flex: 1 1 auto; min-height: 0; display: grid; padding: .1rem .36rem .36rem;
  grid-template-columns: minmax(2.6rem, 3.2rem) 1fr calc(var(--hub-entry-w) * 2 + var(--hub-gap));
  grid-template-rows: minmax(0, 1fr) auto; gap: .2rem .4rem; }
.hub-center { grid-column: 1 / -1; grid-row: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; pointer-events: none; }
.hub-center__mark { position: relative; display: grid; place-items: center; margin-bottom: .14rem; }
.hub-center__mark .emblem { margin: 0; z-index: 1; }
.hub-center__en { position: relative; font: 700 .2rem/1 ui-monospace, Consolas, monospace; letter-spacing: .32em; color: rgba(223, 230, 226, .72);
  text-shadow: 0 1px .08rem rgba(0, 0, 0, .85); }
/* a bright custom picture: keep the emblem readable */
[data-hub-theme="custom"] .hub-center__mark .emblem { filter: drop-shadow(0 0 .1rem rgba(0, 0, 0, .7)); }
.hub-center__en b { color: var(--mint-400); }
.hub-center__title { position: relative; margin: .1rem 0 0; font-size: calc(.46 * var(--t)); font-weight: 900; letter-spacing: .14em; color: var(--text-hi);
  text-shadow: 0 .04rem .3rem rgba(0, 0, 0, .8); }
.hub-radar { position: absolute; left: 50%; top: 50%; width: 5.2rem; height: 5.2rem; transform: translate(-50%, -50%); }
.hub-radar svg { width: 100%; height: 100%; overflow: visible; fill: none; stroke: var(--radar); stroke-width: 1; }
.hub-radar .hub-radar__ticks { stroke-width: 5; stroke-dasharray: 1.4 9.8; }
.hub-radar__sweep { position: absolute; inset: 5.4%; border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 292deg, var(--radar) 360deg);
  mask-image: radial-gradient(circle, transparent 0 17%, #000 18%); -webkit-mask-image: radial-gradient(circle, transparent 0 17%, #000 18%);
  animation: hub-sweep 9s linear infinite; }

/* left column — top: the bottom-left corner belongs to the lobby chat (ui/communityChat.js) */
.hub-side { grid-column: 1; grid-row: 1 / -1; position: relative; z-index: 1; display: flex; flex-direction: column; justify-content: flex-start;
  gap: .14rem; min-width: 0; padding-top: .3rem; }
.hub-tile { display: flex !important; align-items: center; gap: .14rem; width: 100%; min-height: .74rem; padding: .1rem .16rem;
  background: rgba(8, 14, 13, .8); border: 1px solid rgba(223, 230, 226, .2); border-left: 3px solid var(--mint-500);
  color: var(--text-hi); text-align: left; cursor: pointer; transition: background var(--t-fast), border-color var(--t-fast); }
.hub-tile:hover { background: rgba(24, 40, 36, .9); border-color: var(--mint-a35); }
.hub-tile__icon { display: grid; place-items: center; width: .44rem; height: .44rem; flex: none; border: 1px solid var(--mint-a35); color: var(--mint-400); font-size: calc(.22 * var(--t)); }
.hub-tile__text { display: flex; flex-direction: column; gap: .02rem; min-width: 0; }
.hub-tile__label { font-size: calc(.2 * var(--t)); font-weight: 800; }
.hub-tile__en { font: 600 .1rem/1 ui-monospace, Consolas, monospace; letter-spacing: .18em; color: var(--text-dim); }
.hub-side .tips { margin-top: .04rem; background: rgba(8, 14, 13, .72); }

/* right column: 缺人同盟 card, then the S.W.E.E.P.报告 and 干员调配 plates, above the entries */
.hub-right { grid-column: 3; grid-row: 1; position: relative; z-index: 1; display: flex; flex-direction: column; gap: .16rem; min-width: 0; min-height: 0; padding-top: .06rem; }
.hub-recruit { flex: none; background: linear-gradient(180deg, rgba(9, 17, 16, .88), rgba(6, 11, 10, .9)); border: 1px solid rgba(223, 230, 226, .14);
  border-top: 2px solid var(--mint-500); box-shadow: 0 .06rem .24rem rgba(0, 0, 0, .45); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.hub-recruit__head { display: flex; align-items: center; gap: .08rem; height: .42rem; padding: 0 .08rem 0 .14rem; border-bottom: 1px solid rgba(223, 230, 226, .08); }
.hub-recruit__pulse { width: .08rem; height: .08rem; flex: none; border-radius: 50%; background: var(--text-dim); }
.hub-recruit__pulse.is-live { background: var(--mint-400); animation: hub-pulse 1.8s ease-out infinite; }
.hub-recruit__title { font-size: calc(.17 * var(--t)); font-weight: 800; color: var(--text-hi); letter-spacing: .06em; white-space: nowrap; }
.hub-recruit__en { font: 700 .1rem/1 ui-monospace, Consolas, monospace; letter-spacing: .2em; color: var(--mint-400); opacity: .7; }
.hub-recruit__n { min-width: .24rem; padding: .02rem .06rem; text-align: center; font-size: calc(.13 * var(--t)); font-weight: 800; color: #04140f; background: var(--mint-500); }
.hub-recruit__all { margin-left: auto; display: inline-flex; align-items: center; gap: .02rem; padding: .04rem .06rem; font-size: calc(.13 * var(--t));
  color: rgba(223, 230, 226, .72); background: none; border: 0; cursor: pointer; white-space: nowrap; }
.hub-recruit__all:hover { color: var(--mint-400); }
.hub-recruit__list { --row-h: .56rem; height: calc(var(--row-h) * 3 + .08rem + .16rem); padding: .08rem; display: flex; flex-direction: column; gap: .04rem; }
.hub-recruit__row { position: relative; display: flex; align-items: center; gap: .1rem; height: var(--row-h); flex: none; padding: 0 .08rem 0 .14rem;
  background: rgba(223, 230, 226, .035); border: 1px solid rgba(223, 230, 226, .06); transition: background var(--t-fast), border-color var(--t-fast); }
.hub-recruit__row::before { content: ''; position: absolute; left: 0; top: .08rem; bottom: .08rem; width: 3px; background: var(--d-color); }
.hub-recruit__row:hover { background: rgba(78, 216, 175, .07); border-color: var(--mint-a20); }
.hub-recruit__info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .04rem; }
.hub-recruit__name { font-size: calc(.15 * var(--t)); font-weight: 700; color: var(--text-hi); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hub-recruit__meta { display: flex; align-items: center; gap: .06rem; font-size: calc(.12 * var(--t)); color: var(--d-color); white-space: nowrap; overflow: hidden; }
.hub-recruit__meta .diff-glyph { width: .14rem; height: .14rem; flex: none; }
.hub-recruit__fp { color: var(--gold); }
.hub-recruit__seats { display: flex; flex-direction: column; align-items: flex-end; gap: .05rem; flex: none; }
.hub-recruit__pips { display: flex; gap: 2px; }
.hub-recruit__pips i { width: .07rem; height: .12rem; background: rgba(223, 230, 226, .16); }
.hub-recruit__pips i.is-on { background: var(--mint-400); }
.hub-recruit__need { font-size: calc(.12 * var(--t)); color: var(--amber); white-space: nowrap; }
.hub-recruit__need b { margin: 0 .02rem; font-size: calc(.14 * var(--t)); }
.hub-recruit__join { flex: none; height: .36rem; padding: 0 .16rem; font-size: calc(.14 * var(--t)); font-weight: 800; color: #04140f; background: var(--mint-500);
  border: 0; cursor: pointer; clip-path: polygon(0 0, 100% 0, 100% 68%, 84% 100%, 0 100%); transition: background var(--t-fast); }
.hub-recruit__join:hover:not(:disabled) { background: var(--mint-400); }
.hub-recruit__join:disabled { opacity: .45; cursor: default; }
.hub-recruit__empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .1rem;
  color: rgba(223, 230, 226, .5); font-size: calc(.14 * var(--t)); border: 1px dashed rgba(223, 230, 226, .1); }
.hub-recruit__create { display: inline-flex; align-items: center; gap: .02rem; padding: .05rem .14rem; font-size: calc(.13 * var(--t)); font-weight: 700;
  color: var(--mint-400); background: transparent; border: 1px solid var(--mint-a35); cursor: pointer; }
.hub-recruit__create:hover { background: rgba(78, 216, 175, .1); }

/* light plates with bracket marks (S.W.E.E.P.报告 opens screens/sweep.js, 干员调配 is loadout.js's LoadoutButton) */
.hub-right__plates { display: flex; flex-direction: column; gap: .12rem; }
.hub-plate { --pl-ink: #222b28; position: relative; display: flex !important; align-items: center; justify-content: flex-start !important; gap: .14rem;
  width: 100%; height: .7rem !important; min-width: 0; padding: 0 .22rem 0 .2rem !important; color: #111816 !important; text-align: left;
  background:
    linear-gradient(var(--pl-ink), var(--pl-ink)) left .07rem center / 2px 54% no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) left .07rem top 23% / .06rem 2px no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) left .07rem bottom 23% / .06rem 2px no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) right .07rem center / 2px 54% no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) right .07rem top 23% / .06rem 2px no-repeat,
    linear-gradient(var(--pl-ink), var(--pl-ink)) right .07rem bottom 23% / .06rem 2px no-repeat,
    linear-gradient(180deg, #e8edea, #c6cfcb) !important;
  border: 1px solid rgba(255, 255, 255, .5) !important; box-shadow: 0 .05rem .18rem rgba(0, 0, 0, .5), inset 0 -2px 0 rgba(0, 0, 0, .14); }
.hub-plate__glyph, .hub-plate .lo-entry__icon, .hub-plate > .btn__icon { width: .46rem !important; height: .46rem !important; flex: none; display: grid; place-items: center;
  padding: .07rem; background: #182120; color: var(--mint-400); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .08); box-sizing: border-box; }
.hub-plate__glyph svg { width: 100%; height: 100%; }
.hub-plate__label, .hub-plate .btn__label { font-size: calc(.2 * var(--t)); font-weight: 900; letter-spacing: .04em; color: #111816; white-space: nowrap; }
.hub-plate__tag { margin-left: auto; padding: .03rem .07rem; font-size: calc(.11 * var(--t)); font-weight: 700; letter-spacing: .12em; color: rgba(17, 24, 22, .6);
  border: 1px solid rgba(17, 24, 22, .28); white-space: nowrap; }
.hub-plate--sweep { font: inherit; cursor: pointer; }
.hub-plate--sweep:hover, .hub-plate--loadout:not(:disabled):hover { filter: brightness(1.05); }
.hub-plate--sweep:focus-visible { outline: 2px solid var(--mint-400); outline-offset: 2px; }

.hub-entries { grid-column: 2 / -1; grid-row: 2; display: flex; flex-direction: column; align-items: flex-end; gap: .12rem; }
.hub-searching, .hub-maint { width: min(100%, 8.6rem); }
.hub-maint { padding: .08rem .16rem; border: 1px solid var(--amber); color: var(--amber); background: rgba(40, 24, 6, .7); font-size: calc(.15 * var(--t)); }
.hub-entries__row { display: flex; align-items: flex-end; gap: var(--hub-gap); }
.hub-entry-wrap { display: flex; flex-direction: column; gap: .05rem; }
.hub-entry__group { display: flex; align-items: center; gap: .06rem; height: .2rem; padding-left: .04rem; font-size: calc(.13 * var(--t)); color: rgba(223, 230, 226, .7); }
.hub-entry {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start;
  width: var(--hub-entry-w); height: 1.34rem; padding: .14rem .16rem; overflow: hidden; cursor: pointer; text-align: left; color: var(--text-hi);
  background: linear-gradient(160deg, rgba(30, 46, 42, .94), rgba(9, 15, 14, .96)); border: 1px solid rgba(223, 230, 226, .26);
  box-shadow: 0 .06rem .24rem rgba(0, 0, 0, .5); transition: transform var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast); }
.hub-entry:hover:not(:disabled) { transform: translateY(-.04rem); border-color: var(--mint-400); box-shadow: 0 .08rem .3rem rgba(0, 0, 0, .55), 0 0 .2rem var(--mint-a20); }
.hub-entry:disabled { opacity: .5; cursor: default; }
.hub-entry__icon { position: absolute; right: .14rem; top: .12rem; font-size: calc(.42 * var(--t)); color: var(--mint-a35); }
.hub-entry__en { font: 700 .11rem/1 ui-monospace, Consolas, monospace; letter-spacing: .22em; color: var(--mint-400); }
.hub-entry__name { display: flex; align-items: center; gap: .08rem; margin-top: .04rem; font-size: calc(.3 * var(--t)); font-weight: 900; letter-spacing: .06em; white-space: nowrap; }
.hub-entry__name .mode-beta { font-size: calc(.12 * var(--t)); }
.hub-entry__count { position: absolute; left: .16rem; top: .12rem; }
.hub-entry__corner { position: absolute; right: 0; bottom: 0; width: .3rem; height: .3rem;
  background: linear-gradient(135deg, transparent 50%, var(--mint-500) 50%); opacity: .8; }
.hub-entry--gold .hub-entry__en { color: var(--gold); }
.hub-entry--gold .hub-entry__icon { color: rgba(255, 198, 0, .3); }
.hub-entry--gold .hub-entry__corner { background: linear-gradient(135deg, transparent 50%, var(--gold) 50%); }
.hub-entry--gold:hover:not(:disabled) { border-color: var(--gold); }
.hub-entry--bright { background: linear-gradient(160deg, var(--mint-500), #1f8f72); color: #04140f; border-color: var(--mint-400); }
.hub-entry--bright .hub-entry__en { color: rgba(4, 20, 15, .75); }
.hub-entry--bright .hub-entry__icon { color: rgba(4, 20, 15, .25); }
.hub-entry--bright .hub-entry__corner { background: linear-gradient(135deg, transparent 50%, #e8fff7 50%); }

.hub-dialog-open .community-chat { visibility: hidden; }
.hub-dialog__box { width: min(6.4rem, calc(100vw - 32px)); max-height: calc(100vh - 32px); display: flex; flex-direction: column; }
.hub-dialog__box--wide { width: min(10.4rem, calc(100vw - 32px)); }
.hub-dialog__head { padding: .2rem .26rem .1rem; }
.hub-dialog__title-row { display: flex; align-items: center; justify-content: space-between; gap: .2rem; }
.hub-dialog__body { padding: .06rem .26rem .24rem; overflow: auto; display: flex; flex-direction: column; gap: .14rem; }
.hub-sheet__desc { margin: 0; color: rgba(223, 230, 226, .8); font-size: calc(.16 * var(--t)); }
.hub-sheet__diffs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .12rem; }
.hub-sheet__foot { display: flex; align-items: center; justify-content: space-between; gap: .2rem; flex-wrap: wrap; }
.hub-sheet__actions { display: flex; align-items: center; gap: .14rem; margin-left: auto; }
.hub-join__buttons { display: flex; gap: .12rem; }

/* 大厅背景 dialog */
.bgset { display: flex; flex-direction: column; gap: .16rem; }
.bgset__themes { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .1rem; }
.bgset__theme { display: flex; flex-direction: column; align-items: flex-start; gap: .05rem; min-width: 0; padding: .06rem; color: var(--text-hi);
  background: rgba(223, 230, 226, .04); border: 1px solid rgba(223, 230, 226, .14); cursor: pointer; text-align: left;
  transition: border-color var(--t-fast), box-shadow var(--t-fast); }
.bgset__theme:hover { border-color: var(--mint-a35); }
.bgset__theme.is-selected { border-color: var(--mint-400); box-shadow: inset 0 0 0 1px var(--mint-400), 0 0 .14rem var(--mint-a20); }
.bgset__swatch { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; overflow: hidden;
  background: linear-gradient(180deg, var(--sky-0), var(--sky-1) 40%, var(--sky-2) 66%, var(--sky-3)); }
.bgset__swatch svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.bgset__swatch .sw-far { fill: var(--ridge-far); }
.bgset__swatch .sw-mid { fill: var(--ridge-mid); }
.bgset__swatch .sw-near { fill: var(--ridge-near); }
.bgset__swatch .sw-beacon { fill: var(--beacon); }
.bgset__swatch--custom { display: grid; place-items: center; background: #0b1110 center / cover no-repeat; outline: 1px dashed rgba(223, 230, 226, .2); outline-offset: -1px; }
.bgset__plus { font-size: calc(.34 * var(--t)); line-height: 1; color: rgba(223, 230, 226, .5); }
.bgset__name { font-size: calc(.15 * var(--t)); font-weight: 800; white-space: nowrap; }
.bgset__en { font: 700 .09rem/1 ui-monospace, Consolas, monospace; letter-spacing: .14em; color: var(--text-dim); white-space: nowrap; }
.bgset__custom { display: flex; flex-direction: column; gap: .1rem; padding: .12rem; border: 1px solid rgba(223, 230, 226, .1); background: rgba(223, 230, 226, .03); }
.bgset__row { display: flex; gap: .1rem; }
.bgset__slider { display: grid; grid-template-columns: .5rem 1fr .56rem; align-items: center; gap: .12rem; font-size: calc(.14 * var(--t)); color: rgba(223, 230, 226, .8); }
.bgset__slider input { width: 100%; accent-color: var(--mint-500); }
.bgset__slider b { text-align: right; color: var(--mint-400); }
.bgset__check { display: flex; align-items: center; gap: .08rem; font-size: calc(.14 * var(--t)); color: rgba(223, 230, 226, .85); cursor: pointer; }
.bgset__check input { width: .16rem; height: .16rem; accent-color: var(--mint-500); }
.bgset__note { margin: 0; font-size: calc(.12 * var(--t)); color: var(--text-dim); }

@media (prefers-reduced-motion: reduce) {
  .hub-bg *, .hub-radar__sweep, .hub-recruit__pulse.is-live { animation: none !important; }
  .hub-bg__mote { opacity: .3; }
}
/* phones in landscape: a shorter card (two rooms) and slimmer plates */
@media (max-height: 560px) and (min-aspect-ratio: 4/3) {
  .hub-right { gap: .1rem; }
  .hub-recruit__head { height: max(.36rem, 26px); }
  .hub-recruit__list { --row-h: max(.5rem, 32px); height: calc(var(--row-h) * 2 + .04rem + .12rem); padding: .06rem; }
  .hub-recruit__row:nth-child(n + 3) { display: none; }
  .hub-right__plates { gap: .08rem; }
  .hub-plate { height: max(.5rem, 32px) !important; gap: .1rem; }
  .hub-plate__glyph, .hub-plate .lo-entry__icon, .hub-plate > .btn__icon { width: max(.36rem, 22px) !important; height: max(.36rem, 22px) !important; padding: .04rem; }
  .hub-plate__label, .hub-plate .btn__label { font-size: calc(.16 * var(--t)); }
  .hub-plate__tag { font-size: calc(.1 * var(--t)); }
}
@media (max-aspect-ratio: 4/3) {
  .hub-stage { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; align-content: start; overflow-y: auto; }
  .hub-center, .hub-side, .hub-right, .hub-entries { grid-column: 1; grid-row: auto; }
  .hub-center { order: 0; padding: .3rem 0; } .hub-entries { order: 1; } .hub-right { order: 2; } .hub-side { order: 3; padding-top: 0; }
  .hub-right { justify-self: end; width: min(100%, calc(var(--hub-entry-w) * 2 + var(--hub-gap))); }
  .hub-side { justify-self: start; width: min(100%, 3.2rem); }
  .hub-entries { align-items: stretch; }
  .hub-entries__row { flex-wrap: wrap; }
}
@media (max-width: 560px) { .bgset__themes { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
:is(.sp-touch, .sp-coarse) .lobby-hub { --hub-entry-w: max(1.7rem, 112px); }
:is(.sp-touch, .sp-coarse) .hub-center__title { font-size: calc(.4 * var(--t)); }
:is(.sp-touch, .sp-coarse) .hub-entry { height: max(1.08rem, 72px); }
:is(.sp-touch, .sp-coarse) .hub-entry__name { font-size: calc(.24 * var(--t)); }
:is(.sp-touch, .sp-coarse) .hub-side .tips { display: none; }
:is(.sp-touch, .sp-coarse) .hub-recruit__title { font-size: calc(.17 * var(--t)); }
:is(.sp-touch, .sp-coarse) .hub-recruit__name { font-size: calc(.15 * var(--t)); }
:is(.sp-touch, .sp-coarse) .hub-recruit__meta, :is(.sp-touch, .sp-coarse) .hub-recruit__need, :is(.sp-touch, .sp-coarse) .hub-recruit__all { font-size: calc(.12 * var(--t)); }
:is(.sp-touch, .sp-coarse) .hub-recruit__join { height: max(.36rem, 26px); font-size: calc(.14 * var(--t)); }
:is(.sp-touch, .sp-coarse) .hub-recruit__empty { font-size: calc(.14 * var(--t)); }
:is(.sp-touch, .sp-coarse) .hub-recruit__create { font-size: calc(.13 * var(--t)); padding: 4px 10px; }
:is(.sp-touch, .sp-coarse) .hub-recruit__n { font-size: calc(.13 * var(--t)); }

/* ==========================================================================================
   S.W.E.E.P.报告 (2026-10-13, the owner's request; js/screens/sweep.js): a full-screen report over the lobby, laid out
   after the event's screen — a misty light-grey field, the top bar (back · ⓘ at the left, three tabs at the right), a
   detail column at the left and sections of dark tiles at the right; the enemy codex covers it when opened.
   ========================================================================================== */
.sw-open .community-chat { visibility: hidden; }
.sw {
  --sw-ink: #161b1a; --sw-tile: #262c2b; --sw-tile-2: #1a1f1e; --sw-panel: rgba(20, 25, 24, .8);
  position: fixed; inset: 0; z-index: 54; /* below 干员调配 (55), which a member opens over it */
  display: flex; flex-direction: column;
  padding: var(--sa-t, 0px) var(--sa-r, 0px) var(--sa-b, 0px) var(--sa-l, 0px);
  color: #f1f4f3; background: #9aa3a2; overscroll-behavior: contain;
  animation: sw-in 200ms var(--ease-out) backwards;
}
@keyframes sw-in { from { opacity: 0; } }
.sw__bg { position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  background:
    radial-gradient(90% 70% at 72% 8%, rgba(255, 255, 255, .62), transparent 62%),
    radial-gradient(70% 80% at -6% 108%, rgba(8, 11, 11, .92), rgba(8, 11, 11, .4) 55%, transparent 75%),
    linear-gradient(90deg, rgba(10, 13, 13, .62), rgba(10, 13, 13, .4) 36%, transparent 50%),
    linear-gradient(180deg, #c9d0cf, #9aa4a3 48%, #6d7877); }
/* a slow drift of mist and a few survey lines (drawn here, no picture) */
.sw__mist { position: absolute; inset: -20%; background:
    radial-gradient(30% 22% at 30% 40%, rgba(255, 255, 255, .18), transparent 70%),
    radial-gradient(26% 20% at 70% 70%, rgba(255, 255, 255, .12), transparent 70%);
  animation: sw-mist 38s ease-in-out infinite alternate; }
@keyframes sw-mist { to { transform: translate3d(4%, -3%, 0); } }
.sw__lines { position: absolute; inset: 0; opacity: .5; background:
    linear-gradient(rgba(255, 255, 255, .07) 1px, transparent 1px) 0 0 / 1.2rem 1.2rem,
    linear-gradient(90deg, rgba(255, 255, 255, .07) 1px, transparent 1px) 0 0 / 1.2rem 1.2rem;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 20%, #000 70%, transparent);
          mask-image: linear-gradient(180deg, transparent, #000 20%, #000 70%, transparent); }
.sw > :where(:not(.sw__bg, .sw-codex)) { position: relative; }

/* ---- top bar ---- */
.sw-top { flex: none; display: flex; align-items: center; justify-content: space-between; gap: .3rem; height: max(1rem, 50px); padding: 0 .34rem 0 .26rem; }
.sw-top__left { display: flex; align-items: center; gap: .12rem; }
.sw-back { display: inline-flex; align-items: center; gap: .14rem; height: max(.66rem, 36px); padding: 0 .3rem 0 .12rem; font: inherit; color: #eef2f1; cursor: pointer;
  background:
    radial-gradient(circle, rgba(255, 255, 255, .16) 1px, transparent 1.5px) 0 0 / .16rem .16rem,
    linear-gradient(180deg, #2a302f, #171b1a);
  border: 1px solid rgba(255, 255, 255, .14); box-shadow: 0 .04rem .14rem rgba(0, 0, 0, .35); }
.sw-back:hover { border-color: rgba(255, 255, 255, .4); }
.sw-back .icon { width: max(.34rem, 20px); height: max(.34rem, 20px); }
.sw-back__mark { padding-left: .16rem; border-left: 1px solid rgba(255, 255, 255, .22); font-family: var(--font-display); font-size: calc(.16 * var(--t)); letter-spacing: .2em; color: #c9d2cf; }
.sw-info { display: grid; place-items: center; width: max(.66rem, 36px); height: max(.66rem, 36px); padding: 0; color: #eef2f1; cursor: pointer;
  background: linear-gradient(180deg, #3a4140, #232827); border: 1px solid rgba(255, 255, 255, .14); }
.sw-info:hover { color: var(--mint-400); border-color: var(--mint-500); }
.sw-info .icon { width: 52%; height: 52%; }
.sw-tabs { display: flex; padding: 3px; background: rgba(214, 222, 221, .55); border: 1px solid rgba(22, 27, 26, .5); border-radius: 4px; box-shadow: 0 .04rem .16rem rgba(0, 0, 0, .25); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); min-width: 0; }
.sw-tab { display: inline-flex; align-items: center; justify-content: center; gap: .1rem; min-width: max(2.3rem, 92px); height: max(.66rem, 36px); padding: 0 .22rem;
  font: inherit; font-size: calc(.24 * var(--t)); font-weight: 800; color: var(--sw-ink); background: none; border: 0; border-radius: 3px; cursor: pointer; white-space: nowrap; }
.sw-tab:hover:not(.is-on) { background: rgba(255, 255, 255, .35); }
.sw-tab.is-on { color: #fff; background: linear-gradient(180deg, #2c3231, #151918); box-shadow: 0 .03rem .1rem rgba(0, 0, 0, .4); }
.sw-tab__icon { display: grid; place-items: center; }
.sw-tab__icon .icon { width: max(.28rem, 16px); height: max(.28rem, 16px); }

/* ---- body ---- */
.sw-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 4.3fr) minmax(0, 5.7fr); gap: .5rem; padding: .1rem .34rem .26rem .3rem; }
.sw-left { min-height: 0; display: flex; flex-direction: column; }
.sw-right { min-height: 0; overflow-y: auto; padding: .2rem .12rem .1rem 0; scrollbar-width: thin; scrollbar-color: rgba(22, 27, 26, .55) transparent; }
.sw-loading { margin: 1rem 0; text-align: center; color: var(--sw-ink); font-weight: 700; }

/* the left column */
.sw-detail { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: .14rem; animation: sw-in 160ms var(--ease-out) backwards; }
.sw-hero { flex: none; display: flex; flex-direction: column; align-items: center; gap: .08rem; }
.sw-hero__box { position: relative; display: grid; place-items: center; width: min(3.3rem, 80%); height: max(2.1rem, 96px); background: rgba(30, 36, 35, .78);
  box-shadow: 0 .06rem .2rem rgba(0, 0, 0, .3); }
.sw-hero__box.is-art { width: max(2.1rem, 96px); }
.sw-hero__c { position: absolute; width: .26rem; height: .26rem; border: 2px solid rgba(240, 244, 243, .75); }
.sw-hero__c--tl { left: -5px; top: -5px; border-right: 0; border-bottom: 0; }
.sw-hero__c--br { right: -5px; bottom: -5px; border-left: 0; border-top: 0; }
.sw-hero__img { display: grid; place-items: center; width: max(1.5rem, 70px); height: max(1.5rem, 70px); border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .1), rgba(255, 255, 255, .02) 66%, transparent 70%); box-shadow: 0 0 0 1px rgba(255, 255, 255, .08); }
.sw-hero__img img { width: 82%; height: 82%; object-fit: contain; filter: drop-shadow(0 0 .08rem rgba(255, 255, 255, .25)); }
.sw-hero__box.is-art .sw-hero__img { width: 88%; height: 88%; border-radius: 0; background: none; box-shadow: none; }
.sw-hero__box.is-art .sw-hero__img img { width: 100%; height: 100%; object-fit: cover; filter: none; }
.sw-hero__txt { font-size: calc(.6 * var(--t)); font-weight: 900; color: rgba(255, 255, 255, .7); }
.sw-hero__box > .sw-hero__img > .icon, .sw-hero__img > svg { width: 50%; height: 50%; color: rgba(255, 255, 255, .7); }
.sw-hero__name { margin: .04rem 0 0; font-size: calc(.34 * var(--t)); font-weight: 900; letter-spacing: .06em; text-shadow: 0 1px .08rem rgba(0, 0, 0, .55); }
.sw-hero__sub { font-size: calc(.16 * var(--t)); color: #c4ccca; }
.sw-facts { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: .1rem; }
.sw-pill { display: inline-flex; align-items: baseline; gap: .1rem; padding: .04rem .2rem; font-size: calc(.19 * var(--t)); color: #dfe5e3;
  background: rgba(24, 29, 28, .86); border-radius: 999px; box-shadow: 0 .03rem .08rem rgba(0, 0, 0, .3); }
.sw-pill b { font-size: calc(.26 * var(--t)); color: var(--mint-400); }
.sw-pill--ghost { background: rgba(24, 29, 28, .55); }
.sw-pill--ghost b { font-size: calc(.2 * var(--t)); color: #eef2f1; }
.sw-kind { margin-left: auto; font-size: calc(.15 * var(--t)); letter-spacing: .1em; color: rgba(240, 244, 243, .7); }
.sw-text { flex: 1 1 auto; min-height: max(.8rem, 40px); overflow-y: auto; padding-right: .1rem; font-size: calc(.2 * var(--t)); line-height: 1.55; color: #f4f7f6;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .55); scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .3) transparent; }
.sw-text p { margin: 0; }
.sw-text .rt span, .sw-cd__desc span, .sw-cd__abil .rt span { font-size: inherit; }
.sw-text__h { margin: 0 0 .04rem; font-size: calc(.21 * var(--t)); color: var(--mint-300, #8ff0d2); }
.sw-text__bonds { display: flex; flex-wrap: wrap; align-items: center; gap: .08rem; margin-top: .12rem !important; font-size: calc(.16 * var(--t)); color: #c7cfcd; }
.sw-chip { display: inline-flex; align-items: center; gap: .05rem; padding: .02rem .1rem .02rem .05rem; font-size: calc(.16 * var(--t)); color: #eef2f1;
  background: rgba(24, 29, 28, .8); border: 1px solid rgba(255, 255, 255, .12); text-shadow: none; }
.sw-chip img { width: max(.22rem, 14px); height: max(.22rem, 14px); object-fit: contain; }
.sw-box { flex: none; display: flex; flex-direction: column; gap: .1rem; padding: .1rem .14rem .14rem; background: var(--sw-panel); border-top: 1px solid rgba(255, 255, 255, .1);
  box-shadow: 0 .05rem .2rem rgba(0, 0, 0, .3); }
.sw-box__head { display: flex; align-items: center; justify-content: space-between; gap: .12rem; min-height: max(.4rem, 26px); }
.sw-box__k { display: inline-flex; align-items: center; gap: .08rem; font-size: calc(.2 * var(--t)); font-weight: 800; }
.sw-box__k .icon { width: max(.22rem, 14px); height: max(.22rem, 14px); color: #c7cfcd; }
.sw-box__k small { margin-left: .04rem; font-size: calc(.15 * var(--t)); color: var(--text-lo); }
.sw-box__note { min-width: 0; font-size: calc(.15 * var(--t)); color: #aab4b1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-box__swap { margin-right: .06rem; color: #dfe5e3; }
.sw-look { display: inline-flex; align-items: center; gap: .06rem; height: max(.4rem, 26px); padding: 0 .18rem; font: inherit; font-size: calc(.18 * var(--t)); font-weight: 700;
  color: #eef2f1; background: rgba(0, 0, 0, .5); border: 1px solid rgba(255, 255, 255, .22); border-radius: 999px; cursor: pointer; }
.sw-look:hover { border-color: var(--mint-500); color: var(--mint-300, #8ff0d2); }
.sw-look .icon { width: max(.2rem, 12px); height: max(.2rem, 12px); }
.sw-ops { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .1rem; }
.sw-op { --tc: var(--tier-1); position: relative; aspect-ratio: 1; padding: 0; overflow: hidden; cursor: pointer;
  background: linear-gradient(180deg, #d7dcda, #a9b1ae); border: 1px solid rgba(255, 255, 255, .5); }
.sw-op--t2 { --tc: var(--tier-2); } .sw-op--t3 { --tc: var(--tier-3); } .sw-op--t4 { --tc: var(--tier-4); }
.sw-op--t5 { --tc: var(--tier-5); } .sw-op--t6 { --tc: var(--tier-6); }
.sw-op:hover { border-color: var(--mint-400); }
.sw-op img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sw-op__txt { display: grid; place-items: center; height: 100%; font-weight: 900; color: rgba(17, 22, 20, .5); }
.sw-op__tier { position: absolute; left: 2px; bottom: 2px; min-width: max(.26rem, 16px); padding: 0 .03rem; font-family: var(--font-num); font-size: calc(.15 * var(--t)); font-weight: 900;
  line-height: max(.24rem, 15px); text-align: center; color: var(--tc); background: rgba(10, 12, 12, .85); border: 1px solid var(--tc); }
.sw-op__sub { position: absolute; right: 0; top: 0; padding: 0 .04rem; font-size: calc(.12 * var(--t)); font-weight: 800; color: #1a1a1a; background: var(--amber, #f2b544); }
.sw-op.is-standin img { filter: saturate(.55); }

/* enemy thumbnails */
.sw-ethumbs { display: flex; flex-wrap: wrap; align-items: center; gap: .08rem; }
.sw-ethumbs--grid { max-height: max(1.9rem, 96px); overflow-y: auto; scrollbar-width: thin; }
.sw-ethumbs__sep { padding: 0 .04rem 0 .08rem; font-size: calc(.14 * var(--t)); color: #aab4b1; border-left: 1px solid rgba(255, 255, 255, .18); }
.sw-eth { position: relative; display: block; flex: none; padding: 0; overflow: hidden; background: #3a3f3e; border: 1px solid rgba(255, 255, 255, .28); }
button.sw-eth { cursor: pointer; }
button.sw-eth:hover { border-color: #fff; }
.sw-eth--sm { width: max(.74rem, 40px); height: max(.74rem, 40px); }
.sw-eth--md { width: 100%; aspect-ratio: 1; }
.sw-eth img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sw-eth > .icon { width: 60%; height: 60%; margin: 20%; color: rgba(255, 255, 255, .4); }
.sw-eth__no { position: absolute; left: 0; top: 0; padding: 0 .05rem; font-family: var(--font-num); font-size: calc(.13 * var(--t)); line-height: 1.25; color: #fff; background: rgba(0, 0, 0, .78); }
.sw-eth.is-elite { border-color: rgba(242, 181, 68, .7); }
.sw-eth.is-boss { border-color: rgba(255, 120, 90, .8); }
.sw-eth.is-on { border-color: #fff; box-shadow: 0 0 0 2px #fff, 0 0 .14rem rgba(255, 255, 255, .6); }

/* the right column: sections of tiles */
.sw-sec { position: relative; margin: .26rem 0 .3rem; padding-bottom: .2rem;
  background: linear-gradient(rgba(24, 29, 28, .74), rgba(24, 29, 28, .74)) top / 100% max(.62rem, 34px) no-repeat, rgba(225, 232, 231, .16);
  box-shadow: 0 .04rem .16rem rgba(0, 0, 0, .14); }
.sw-sec__head { position: relative; display: grid; place-items: center; height: max(.62rem, 34px); }
.sw-sec__glyph { position: absolute; left: 50%; top: 0; transform: translate(-50%, -62%); display: grid; place-items: center; width: max(.38rem, 22px); height: max(.38rem, 22px);
  color: var(--sw-ink); background: linear-gradient(180deg, #f2f5f4, #c5cdcb); box-shadow: 0 .02rem .08rem rgba(0, 0, 0, .35); }
.sw-sec__glyph .icon { width: 64%; height: 64%; }
.sw-sec__name { display: inline-flex; align-items: center; gap: .14rem; font-size: calc(.25 * var(--t)); font-weight: 800; letter-spacing: .1em; color: #f1f4f3; }
.sw-sec__name i { font-style: normal; font-weight: 300; font-size: 1.3em; color: rgba(241, 244, 243, .6); }
.sw-sec__name small { font-size: .6em; font-weight: 600; letter-spacing: 0; color: rgba(241, 244, 243, .5); }
.sw-sec__grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .16rem; padding: .2rem .18rem 0; }
.sw-tile { position: relative; aspect-ratio: 1; padding: 0; overflow: visible; font: inherit; color: #eef2f1; cursor: pointer;
  background: linear-gradient(160deg, var(--sw-tile), var(--sw-tile-2)); border: 1px solid rgba(255, 255, 255, .07); border-radius: 3px;
  box-shadow: 0 .04rem .12rem rgba(0, 0, 0, .35), inset 0 1px 0 rgba(255, 255, 255, .06); transition: transform var(--t-fast), box-shadow var(--t-fast); }
.sw-tile:hover { transform: translateY(-2px); box-shadow: 0 .08rem .18rem rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .08); }
.sw-tile.is-on { outline: 2px solid #f5f8f7; outline-offset: .05rem; box-shadow: 0 0 .2rem rgba(255, 255, 255, .55), inset 0 1px 0 rgba(255, 255, 255, .08); }
.sw-tile__in { position: absolute; inset: 0; display: grid; place-items: center; overflow: hidden; border-radius: inherit; }
.sw-tile__cap { position: absolute; left: 0; right: 0; bottom: 0; padding: .02rem .06rem .04rem; font-size: calc(.13 * var(--t)); line-height: 1.2; text-align: center;
  color: rgba(238, 242, 241, .78); background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .5)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-tile__hp { position: absolute; right: 3px; top: 3px; padding: 0 .05rem; font-size: calc(.13 * var(--t)); font-weight: 800; line-height: 1.35; color: var(--mint-400); background: rgba(0, 0, 0, .6); }
/* 盟约: a dark glyph on a lit disc */
.sw-disc { display: grid; place-items: center; width: 64%; aspect-ratio: 1; margin-bottom: 10%; border-radius: 50%;
  background: radial-gradient(circle, #f6faf9 0 42%, #d3dddb 64%, #9fb1ae 100%); box-shadow: 0 0 .16rem rgba(220, 240, 236, .45), inset 0 0 .06rem rgba(0, 0, 0, .25); }
.sw-disc img { width: 70%; height: 70%; object-fit: contain; filter: brightness(0); opacity: .82; }
.sw-disc__txt { font-size: calc(.3 * var(--t)); font-weight: 900; color: var(--sw-ink); }
/* 策略: the portrait (its own ring is part of the icon) */
.sw-face { display: grid; place-items: center; width: 92%; aspect-ratio: 1; margin-bottom: 4%; overflow: hidden; }
.sw-face img { width: 100%; height: 100%; object-fit: cover; }
.sw-face__txt { font-size: calc(.3 * var(--t)); font-weight: 900; }
/* 领袖: the art; 特训: a white glyph */
.sw-art { display: block; width: 84%; aspect-ratio: 1; margin-bottom: 8%; overflow: hidden; box-shadow: 0 0 0 1px rgba(255, 255, 255, .14); }
.sw-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sw-glyph { display: grid; place-items: center; width: 72%; aspect-ratio: 1; margin-bottom: 8%; }
.sw-glyph img { width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 0 .08rem rgba(255, 255, 255, .55)); }
.sw-glyph .icon { width: 70%; height: 70%; }
.sw-allcodex { display: flex; align-items: center; gap: .16rem; width: 100%; margin: 0 0 .1rem; padding: .14rem .22rem; font: inherit; text-align: left; color: #eef2f1; cursor: pointer;
  background: linear-gradient(90deg, rgba(24, 29, 28, .86), rgba(24, 29, 28, .62)); border: 1px solid rgba(255, 255, 255, .12); }
.sw-allcodex:hover { border-color: var(--mint-500); }
.sw-allcodex > .icon { width: max(.36rem, 20px); height: max(.36rem, 20px); color: #c7cfcd; flex: none; }
.sw-allcodex > .icon:last-child { margin-left: auto; width: max(.26rem, 16px); }
.sw-allcodex span { display: flex; flex-direction: column; }
.sw-allcodex b { font-size: calc(.22 * var(--t)); }
.sw-allcodex small { font-size: calc(.15 * var(--t)); color: #aab4b1; }

/* ---- the enemy codex ---- */
.sw-codex { position: absolute; inset: 0; z-index: 5; display: flex; flex-direction: column;
  padding: var(--sa-t, 0px) var(--sa-r, 0px) var(--sa-b, 0px) var(--sa-l, 0px);
  background: rgba(14, 17, 17, .88); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); animation: sw-in 160ms var(--ease-out) backwards; }
.sw-codex__top { flex: none; display: flex; align-items: center; gap: .14rem; height: max(1rem, 50px); padding: 0 .34rem 0 .26rem; }
.sw-codex__top .sw-back { padding-right: .12rem; }
.sw-codex__title { font-size: calc(.26 * var(--t)); font-weight: 900; letter-spacing: .1em; }
.sw-scope { display: inline-flex; align-items: center; gap: .06rem; height: max(.42rem, 26px); padding: 0 .12rem 0 .16rem; font: inherit; font-size: calc(.16 * var(--t));
  color: #eef2f1; background: rgba(78, 216, 175, .14); border: 1px solid var(--mint-700); border-radius: 999px; cursor: pointer; white-space: nowrap; }
.sw-scope .icon { width: max(.16rem, 10px); height: max(.16rem, 10px); }
.sw-search { display: inline-flex; align-items: center; gap: .06rem; margin-left: auto; height: max(.46rem, 28px); padding: 0 .12rem; background: rgba(0, 0, 0, .4); border: 1px solid rgba(255, 255, 255, .16); }
.sw-search .icon { width: max(.2rem, 12px); height: max(.2rem, 12px); color: #aab4b1; }
.sw-search input { width: max(1.9rem, 110px); font: inherit; font-size: calc(.17 * var(--t)); color: #eef2f1; background: none; border: 0; outline: none; }
.sw-codex__body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr); gap: .3rem; padding: 0 .34rem .26rem .3rem; }
.sw-codex__list { min-height: 0; overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(max(1.3rem, 64px), 1fr)); align-content: start; gap: .14rem;
  /* rows keep their square: the thumbnails (overflow: hidden, so no minimum height) were otherwise shrunk to fit the box */
  grid-auto-rows: max-content;
  padding: .06rem .16rem .06rem .06rem; border-right: 2px solid rgba(255, 255, 255, .5); scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .25) transparent; }
.sw-codex__list .sw-eth__no { font-size: calc(.16 * var(--t)); }
.sw-codex__empty { grid-column: 1 / -1; margin: .6rem 0; text-align: center; color: var(--text-lo); }
.sw-codex__side { min-height: 0; display: flex; flex-direction: column; gap: .12rem; }
.sw-ranks { flex: none; display: flex; align-items: stretch; height: max(.6rem, 34px); background: #0c0f0f; border: 1px solid rgba(255, 255, 255, .1); }
.sw-ranks__n { display: grid; place-items: center; min-width: max(.8rem, 42px); font-size: calc(.2 * var(--t)); font-weight: 800; color: #4cc3ee; border-right: 1px solid rgba(255, 255, 255, .1); }
.sw-ranks button { flex: 1 1 0; font: inherit; font-size: calc(.2 * var(--t)); font-weight: 700; color: #8d9794; background: none; border: 0; cursor: pointer; }
.sw-ranks button:hover:not(:disabled):not(.is-on) { color: #eef2f1; }
.sw-ranks button.is-on { color: #fff; background: #1d6f8f; }
.sw-ranks button:disabled { opacity: .35; cursor: default; }
.sw-cd { min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: .12rem; padding-right: .08rem; animation: sw-in 140ms var(--ease-out) backwards;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .25) transparent; }
.sw-cd__head { position: relative; display: flex; flex-direction: column; gap: .02rem; min-height: max(1.1rem, 60px); }
.sw-cd__cat, .sw-cd__way { font-size: calc(.19 * var(--t)); color: #8f9a97; }
.sw-cd__name { display: flex; align-items: center; gap: .12rem; margin: 0; padding-right: 1.4rem; font-size: calc(.36 * var(--t)); font-weight: 900; line-height: 1.2; }
.sw-cd__no { padding: .02rem .12rem; font-family: var(--font-num); font-size: calc(.2 * var(--t)); font-weight: 700; color: #fff; background: #000; border: 1px solid rgba(255, 255, 255, .18); }
.sw-cd__lp { position: absolute; right: .06rem; top: .5rem; z-index: 1; display: inline-flex; align-items: center; gap: .04rem; color: #ff5b5b; }
.sw-cd__lp .icon { width: max(.3rem, 18px); height: max(.3rem, 18px); color: #f1f4f3; }
.sw-cd__lp b { font-size: calc(.3 * var(--t)); }
.sw-cd__mark { position: absolute; right: .3rem; top: -.04rem; width: max(1.3rem, 64px); height: max(1.3rem, 64px); opacity: .14; pointer-events: none; }
.sw-cd__mark img { width: 100%; height: 100%; object-fit: contain; }
.sw-cd__main { display: grid; grid-template-columns: max(1.6rem, 80px) minmax(0, 1fr); gap: .16rem; align-items: start; }
.sw-cd__art { display: flex; flex-direction: column; gap: .08rem; }
.sw-cd__img { display: block; aspect-ratio: 1; overflow: hidden; background: #3a3f3e; border: 1px solid rgba(255, 255, 255, .2); }
.sw-cd__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sw-cd__img > .icon { width: 60%; height: 60%; margin: 20%; color: rgba(255, 255, 255, .4); }
.sw-cd__mass { display: flex; align-items: center; gap: .06rem; padding: .03rem .1rem; font-size: calc(.16 * var(--t)); color: #c7cfcd; background: rgba(0, 0, 0, .55); }
.sw-cd__mass .icon { width: max(.18rem, 11px); height: max(.18rem, 11px); }
.sw-cd__mass b { margin-left: auto; font-size: calc(.26 * var(--t)); color: #eef2f1; }
.sw-cd__stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .08rem .1rem; }
.sw-stat { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: .08rem; min-height: max(.46rem, 28px); padding: 0 .12rem;
  background: rgba(255, 255, 255, .06); border-radius: 2px; }
.sw-stat__k { display: inline-flex; align-items: center; gap: .06rem; min-width: 0; font-size: calc(.17 * var(--t)); color: #b9c2bf; white-space: nowrap; overflow: hidden; }
.sw-stat__k .icon { flex: none; width: max(.18rem, 11px); height: max(.18rem, 11px); color: #eef2f1; }
.sw-stat__v { font-size: calc(.13 * var(--t)); color: #7f8a87; }
.sw-stat__g { min-width: max(.36rem, 20px); text-align: right; font-family: var(--font-display); font-size: calc(.28 * var(--t)); font-weight: 800; color: #eef2f1; }
.sw-stat__g.g-S { color: #ffcf5a; } .sw-stat__g.g-Ap, .sw-stat__g.g-A { color: #ff9a5c; }
.sw-stat__g.g-C, .sw-stat__g.g-D { color: #b9c2bf; } .sw-stat__g.g-E, .sw-stat__g.g-none { color: #6f7a77; }
.sw-cd__desc { margin: 0; font-size: calc(.19 * var(--t)); font-style: italic; line-height: 1.55; color: #aeb7b4; }
.sw-cd__types { display: flex; flex-wrap: wrap; gap: .08rem; margin: 0; }
.sw-cd__h { margin: .04rem 0 0; padding: .06rem .14rem; font-size: calc(.2 * var(--t)); font-weight: 800; background: rgba(255, 255, 255, .08); }
.sw-cd__abil { margin: 0; padding: 0 .1rem 0 .3rem; display: flex; flex-direction: column; gap: .05rem; font-size: calc(.18 * var(--t)); line-height: 1.5; color: #e4e9e7; }

/* phones in landscape: a lower bar, slimmer columns */
@media (max-height: 520px) {
  .sw-top, .sw-codex__top { height: 44px; }
  .sw-body { gap: .3rem; padding-bottom: .16rem; }
  /* too short for a fixed column: the whole detail scrolls */
  .sw-left { overflow-y: auto; scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .3) transparent; }
  .sw-detail { flex: none; }
  .sw-text { flex: none; overflow: visible; min-height: 0; }
  .sw-hero__box { height: 64px; } .sw-hero__box.is-art { width: 64px; }
  .sw-hero__img { width: 50px; height: 50px; }
  .sw-hero__name { font-size: 15px; }
  .sw-sec__grid { gap: 8px; padding: 10px 10px 0; }
  .sw-tile__cap { display: none; }
  .sw-ops { grid-template-columns: repeat(auto-fill, minmax(38px, 1fr)); }
  .sw-cd__name { font-size: 16px; }
}
/* tall / narrow windows: the detail above the tiles */
@media (max-aspect-ratio: 1/1) {
  .sw-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); gap: .2rem; }
  .sw-left { max-height: 48vh; }
  .sw-tabs .sw-tab { min-width: 0; }
  .sw-codex__body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, .8fr) minmax(0, 1.2fr); }
  .sw-codex__list { border-right: 0; border-bottom: 2px solid rgba(255, 255, 255, .5); }
}
@media (max-width: 640px) {
  .sw-back__mark { display: none; }
  .sw-tab { padding: 0 .12rem; font-size: 12px; }
  .sw-tab__icon { display: none; }
  .sw-sec__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (prefers-reduced-motion: reduce) {
  .sw, .sw-detail, .sw-codex, .sw-cd { animation: none; }
  .sw__mist { animation: none; }
  .sw-tile { transition: none; }
}

/* ==========================================================================================
   选择模拟协议 (2026-10-13, the owner's request; lobby.js ProtocolSelect, ui/protocolScene.js): the start screen of
   独立模拟 / 同盟模拟 / 无限火力, laid out after the event's — the picture in the difficulty's colour at the left, the
   difficulty cards down the right (the chosen one slides out with a glow and the 已选定 stamp), 开始模拟 below them.
   ========================================================================================== */
.proto {
  position: fixed; inset: 0; z-index: 54; display: flex; flex-direction: column;
  padding: var(--sa-t, 0px) var(--sa-r, 0px) var(--sa-b, 0px) var(--sa-l, 0px);
  color: #eef0ef; background: #0b0c0c; overscroll-behavior: contain; animation: sw-in 200ms var(--ease-out) backwards;
}
.proto__bg { position: absolute; inset: 0; pointer-events: none; transition: background 400ms; background: radial-gradient(46% 60% at 30% 52%, var(--d-color), transparent 70%),
    radial-gradient(40% 50% at 100% 50%, var(--d-color), transparent 70%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .022) 0 1px, transparent 1px 4px),
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    radial-gradient(120% 90% at 50% 40%, #151616, #070808); background:
    radial-gradient(46% 60% at 30% 52%, color-mix(in srgb, var(--d-color) 16%, transparent), transparent 70%),
    radial-gradient(40% 50% at 100% 50%, color-mix(in srgb, var(--d-color) 10%, transparent), transparent 70%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .022) 0 1px, transparent 1px 4px),
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    radial-gradient(120% 90% at 50% 40%, #151616, #070808); }
.proto > :where(:not(.proto__bg)) { position: relative; }

.proto-top { flex: none; display: flex; align-items: flex-start; justify-content: space-between; padding: .18rem .34rem 0 .22rem; z-index: 2; }
.proto-back { display: inline-flex; align-items: center; height: max(.62rem, 36px); padding: 0; font: inherit; color: #f2f4f3; cursor: pointer;
  background: linear-gradient(180deg, #2b2c2d, #1b1c1d); border: 1px solid rgba(255, 255, 255, .1); box-shadow: 0 .04rem .14rem rgba(0, 0, 0, .5); }
.proto-back > .icon { width: max(.4rem, 22px); height: max(.4rem, 22px); margin: 0 .3rem 0 .14rem; }
.proto-back__home { display: grid; place-items: center; align-self: stretch; width: max(2rem, 96px); border-left: 2px solid #0d0e0e;
  background: radial-gradient(circle, rgba(255, 255, 255, .22) 1px, transparent 1.6px) 0 0 / .14rem .14rem, linear-gradient(90deg, #2f3132, #3d3f40 50%, #2f3132); }
.proto-back__home .icon { width: max(.32rem, 18px); height: max(.32rem, 18px); }
.proto-back:hover { border-color: rgba(255, 255, 255, .35); }
.proto-title { display: flex; flex-direction: column; align-items: flex-end; gap: .02rem; padding-top: .06rem; }
.proto-title h2 { margin: 0; font-size: calc(.36 * var(--t)); font-weight: 900; letter-spacing: .06em; }
.proto-title__mode { display: inline-flex; align-items: baseline; gap: .1rem; font-size: calc(.16 * var(--t)); color: var(--d-color); font-weight: 700; }
.proto-title__mode i { font-style: normal; font-family: var(--font-display); font-size: .8em; letter-spacing: .16em; color: #8b8f8e; }

.proto-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) min(5.6rem, 46vw); gap: .3rem; padding: 0 .34rem .26rem .22rem; }
.proto-stage { position: relative; min-width: 0; min-height: 0; }

/* the picture */
.ps { position: absolute; inset: -.4rem 0 .9rem; width: 100%; height: calc(100% - .5rem); color: var(--d-color); transition: color 400ms; }
.ps-grid line { stroke: currentColor; stroke-opacity: .13; stroke-width: 1; }
.ps-pad polygon { fill: currentColor; fill-opacity: .1; stroke: currentColor; stroke-opacity: .55; stroke-width: 1.2; }
.ps-pad__edge { fill: none; stroke: currentColor; stroke-opacity: .7; stroke-width: 2; stroke-dasharray: 26 8; }
.ps-hull { filter: drop-shadow(0 0 6px var(--d-color)); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--d-color) 70%, transparent)); }
.ps-face { stroke: currentColor; stroke-width: 1.3; stroke-linejoin: round; fill: currentColor; }
.ps-face--top { fill-opacity: .42; } .ps-face--front { fill-opacity: .26; } .ps-face--side { fill-opacity: .16; }
.ps-seam { stroke: #fff; stroke-opacity: .35; stroke-width: 1; }
.ps-beacon { fill: #fff; animation: ps-blink 1.6s steps(2) infinite; }
@keyframes ps-blink { 50% { opacity: .2; } }
.ps-cable { fill: none; stroke: currentColor; stroke-width: 4; stroke-opacity: .75; }
.ps-fig { animation: ps-fig 360ms var(--ease-out) backwards; animation-delay: calc(var(--i) * 18ms); }
@keyframes ps-fig { from { opacity: 0; transform: translateY(-6px); } }
.ps-fig__body, .ps-fig__head { fill: currentColor; fill-opacity: .88; stroke: rgba(0, 0, 0, .45); stroke-width: .8; }
.ps-fig__head { fill-opacity: 1; }
.ps-fig__shadow { fill: #000; opacity: .35; }
.ps-spike polygon { fill: currentColor; fill-opacity: .75; filter: drop-shadow(0 0 4px var(--d-color)); }
.ps-spike__x { stroke: currentColor; stroke-width: 2; stroke-opacity: .8; }
.ps-spike { animation: ps-fig 420ms var(--ease-out) backwards; animation-delay: calc(var(--i) * 60ms + 120ms); }
.ps-call rect { fill: rgba(0, 0, 0, .55); stroke: currentColor; stroke-width: 1.5; }
.ps-call line { stroke: currentColor; stroke-width: 1.5; stroke-opacity: .8; }
.ps-call__icon { fill: currentColor !important; fill-opacity: .25; }
.ps-call__man { fill: currentColor; }
.ps-call text { fill: currentColor; font: 700 11px var(--font-num, monospace); letter-spacing: 2px; }
.ps-scan { stroke: currentColor; stroke-opacity: .22; stroke-width: 2; animation: ps-scan 7s linear infinite; }
@keyframes ps-scan { from { transform: translateY(40px); } to { transform: translateY(620px); } }

.proto-brief { position: absolute; left: .1rem; bottom: .1rem; max-width: min(6rem, 92%); padding: .12rem .2rem .14rem; background: linear-gradient(90deg, rgba(0, 0, 0, .7), rgba(0, 0, 0, .2));
  border-left: 3px solid var(--d-color); }
.proto-brief__code { margin-right: .1rem; padding: 0 .08rem; font-size: calc(.14 * var(--t)); color: #111; background: var(--d-color); }
.proto-brief__name { font-size: calc(.24 * var(--t)); color: var(--d-color); }
.proto-brief p { margin: .04rem 0 0; font-size: calc(.16 * var(--t)); line-height: 1.5; color: #b7bcba; }
.proto-fp { position: absolute; left: .1rem; top: .2rem; width: min(6.2rem, 96%); max-height: calc(100% - 1.6rem); overflow-y: auto; scrollbar-width: thin; }
.proto-fp .firepower-brief { margin: 0; background: rgba(8, 9, 9, .82); }

/* the difficulty cards */
.proto-side { min-height: 0; display: flex; flex-direction: column; gap: .14rem; }
.proto-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; gap: .2rem; padding: .1rem .06rem .1rem .5rem;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .25) transparent; }
.pcard { position: relative; flex: none; display: flex; flex-direction: column; gap: .04rem; padding: .16rem .26rem .16rem; overflow: hidden; font: inherit; text-align: left;
  color: #e9eceb; cursor: pointer; background: linear-gradient(180deg, #252627, #1a1b1c); border: 2px solid #55585a; border-radius: .2rem;
  box-shadow: 0 .05rem .16rem rgba(0, 0, 0, .5); transition: transform 220ms var(--ease-out), border-color 220ms; }
.pcard:hover:not(.is-on) { border-color: #7b7f81; }
.pcard.is-on { transform: translateX(-.44rem); border-color: #8f9496; }
.pcard__glow { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 260ms; background: radial-gradient(70% 140% at 100% 50%, var(--d-color), transparent 72%); background: radial-gradient(70% 140% at 100% 50%, color-mix(in srgb, var(--d-color) 70%, transparent), transparent 72%); }
.pcard.is-on .pcard__glow { opacity: 1; }
.pcard > :not(.pcard__glow, .pcard__stamp) { position: relative; }
.pcard.is-on > :not(.pcard__glow, .pcard__stamp) { padding-right: max(1.3rem, 70px); }
.pcard__head { display: flex; align-items: center; gap: .08rem; }
.pcard__glyph { width: max(.3rem, 18px); height: max(.3rem, 18px); color: var(--d-color); }
.pcard__head .mm-count, .pcard__head [class*='matchmaking'] { margin-left: auto; }
.pcard__desc { padding-bottom: .06rem; font-size: calc(.17 * var(--t)); color: #9a9f9d; border-bottom: 1px solid rgba(255, 255, 255, .18); }
.pcard__effects { display: flex; flex-direction: column; padding-top: .04rem; font-size: calc(.19 * var(--t)); line-height: 1.45; }
.pcard__effects span::before { content: '·'; margin-right: .06rem; }
.pcard__meta { display: flex; flex-wrap: wrap; gap: .04rem .14rem; margin-top: .04rem; font-size: calc(.13 * var(--t)); color: #7f8583; }
.pcard__meta b { color: #cfd3d1; }
.pcard__stamp { position: absolute; right: .2rem; top: 50%; display: none; width: max(1.3rem, 70px); height: max(1.1rem, 60px); transform: translateY(-50%) rotate(-6deg);
  flex-direction: column; align-items: center; justify-content: center; gap: .04rem; }
.pcard.is-on .pcard__stamp { display: flex; animation: proto-stamp 260ms var(--ease-out) backwards; }
@keyframes proto-stamp { from { opacity: 0; transform: translateY(-50%) rotate(-6deg) scale(1.4); } }
.pcard__ring { position: absolute; inset: -.1rem -.14rem; width: calc(100% + .28rem); height: calc(100% + .2rem); }
.pcard__ring path { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; opacity: .9; }
.pcard__tick { display: grid; place-items: center; width: max(.46rem, 26px); height: max(.46rem, 26px); color: #2a1712; background: #f5f5f5; border-radius: .06rem; box-shadow: 0 .02rem .08rem rgba(0, 0, 0, .5); }
.pcard__tick .icon { width: 78%; height: 78%; color: var(--d-color); filter: brightness(.7); }
.pcard__ok { font-size: calc(.18 * var(--t)); font-weight: 800; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .6); }

/* the foot: options, hint, 开始模拟 */
.proto-foot { flex: none; display: flex; flex-direction: column; gap: .08rem; padding-left: .5rem; }
.proto-opts { display: flex; align-items: center; justify-content: space-between; gap: .14rem; }
.proto-private { display: inline-flex; align-items: center; gap: .08rem; font-size: calc(.17 * var(--t)); color: #c9cecc; cursor: pointer; }
.proto-private input { width: max(.22rem, 15px); height: max(.22rem, 15px); accent-color: var(--mint-500); }
.proto-hint { margin: 0; font-size: calc(.14 * var(--t)); color: #858b89; }
  font: inherit; color: #0d2a23; cursor: pointer; text-align: left;
  background: linear-gradient(180deg, #4fe0bf, #34c8a6); border: 3px solid #121313; box-shadow: 0 0 0 1px rgba(79, 224, 191, .5), 0 .06rem .2rem rgba(0, 0, 0, .55);
  transition: filter var(--t-fast); }
.proto-start:hover:not(:disabled) { filter: brightness(1.07); }
.proto-hint { display: flex; align-items: center; gap: .08rem; min-height: .24rem; margin: 0; font-size: calc(.14 * var(--t)); color: #858b89; }
.proto-hint .icon { flex: none; width: 1.1em; height: 1.1em; }
.proto-hint--ro { min-height: max(.64rem, 32px, calc(38px * var(--sp-ui, 1))); font-size: calc(.18 * var(--t)); color: #b9bfbd; }
.proto-start {
  position: relative;
  display: flex;
  align-items: center;
  gap: .26rem;
  width: 100%;
  min-height: max(1.04rem, 32px, calc(54px * var(--sp-ui, 1)));
  padding: .03rem 0 .03rem .26rem;
  overflow: hidden;
  font: inherit;
  color: #0d2a23;
  text-align: left;
  background: linear-gradient(180deg, #4fe0bf, #34c8a6);
  border: 3px solid #121313;
  box-shadow: 0 0 0 1px rgba(79, 224, 191, .5), 0 .06rem .2rem rgba(0, 0, 0, .55);
  transition: filter var(--t-fast);
}
.proto-start:hover:not(:disabled), .proto-start:focus-visible { filter: brightness(1.07); }
.proto-start:focus-visible { outline: 2px solid #eef0ef; outline-offset: 2px; }
.proto-start:disabled { filter: grayscale(.8) brightness(.6); cursor: default; }
.proto-start__mark { flex: none; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.proto-start__rook { display: inline-flex; align-items: center; gap: 2px; font-size: calc(.36 * var(--t)); font-weight: 300; line-height: 1; }
.proto-start__rook i { font-style: normal; }
.proto-start__rook .icon { width: max(.34rem, 19px); height: max(.34rem, 19px); }
.proto-start__mark small { font-family: var(--font-display); font-size: calc(.08 * var(--t)); font-weight: 800; letter-spacing: .06em; line-height: 1.1; text-align: center; }
.proto-start__label { display: inline-flex; align-items: center; gap: .1rem; font-size: calc(.44 * var(--t)); font-weight: 900; letter-spacing: .08em; white-space: nowrap; }
.proto-start__deco { position: absolute; right: 0; top: 0; bottom: 0; width: 26%; clip-path: polygon(18% 0, 100% 0, 100% 100%, 0 100%);
  background: repeating-linear-gradient(135deg, rgba(0, 0, 0, .28) 0 5px, transparent 5px 11px), linear-gradient(90deg, rgba(13, 42, 35, .2), rgba(13, 42, 35, .6)); }

@media (max-height: 520px) {
  .proto-top { padding-top: 8px; }
  .proto-body { grid-template-columns: minmax(0, 1fr) min(5.6rem, 48vw); gap: 10px; }
  .proto-list { gap: 8px; padding-left: 22px; }
  .pcard { padding: 8px 12px; }
  .pcard.is-on { transform: translateX(-16px); }
  .pcard__meta { display: none; }
  .proto-foot { padding-left: 22px; }
  .proto-brief p { display: none; }
  /* phones: the side column is ~220px — the 已选定 stamp padding squeezed 标准模拟 to one character a line, the chips and
     创建无限火力 wrapped, and the 4-column 无限火力 rules were a few characters wide */
  .pcard.is-on > :not(.pcard__glow, .pcard__stamp) { padding-right: 0; }
  .pcard.is-on > .pcard__desc, .pcard.is-on > .pcard__effects { padding-right: 58px; }
  .pcard.is-on .pcard__stamp { right: 8px; width: 54px; height: 48px; }
  .pcard__name { white-space: nowrap; }
  .pcard__head { flex-wrap: wrap; }
  .proto-opts { flex-wrap: wrap; gap: 4px 8px; }
  .proto-opts > *, .proto-mode-chip { white-space: nowrap; }
  .proto-start { height: 46px; gap: 10px; padding-left: 10px; }
  .proto-start__label { font-size: 18px; letter-spacing: .02em; white-space: nowrap; }
  .proto-fp .firepower-features { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-aspect-ratio: 1/1) {
  .proto-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, .8fr) minmax(0, 1.2fr); }
  .proto-fp { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .proto, .ps-fig, .ps-spike, .pcard.is-on .pcard__stamp { animation: none; }
  .ps-scan, .ps-beacon { animation: none; }
}

/* ==========================================================================================
   房间与搜寻流程 (2026-10-13, the owner's request; js/ui/matchFlow.js, lobby.js AllianceSelect, room.js): 搜寻中 /
   搜寻成功 panels, 选择同盟方式, the room's tall seat cards and its bottom pill.
   ========================================================================================== */
/* ---- shared: brand, 搜寻中, 搜寻成功 ---- */
.mf-brand { display: inline-flex; align-items: center; gap: .1rem; font-family: var(--font-display); font-size: calc(.2 * var(--t)); letter-spacing: .12em; color: #8d9391; }
.mf-brand__rook { display: inline-flex; align-items: center; gap: 1px; font-weight: 300; }
.mf-brand__rook i { font-style: normal; }
.mf-brand__rook .icon { width: 1.05em; height: 1.05em; }
.mf-search { display: flex; flex-direction: column; align-items: center; gap: .14rem; padding: .5rem .3rem .3rem; text-align: center; color: #eef0ef; }
.mf-search__title { display: flex; align-items: baseline; gap: .1rem; margin: .06rem 0 0; font-size: calc(.5 * var(--t)); font-weight: 900; letter-spacing: .08em;
  text-shadow: 0 0 .24rem rgba(255, 255, 255, .35); }
.mf-search__dots { display: inline-block; width: 1.2em; text-align: left; }
.mf-search__title small { font-size: .42em; font-weight: 700; letter-spacing: 0; color: #c9cecc; text-shadow: none; }
.mf-search__tags { display: flex; flex-wrap: wrap; justify-content: center; gap: .1rem; }
.mf-tag { --tag: #8d9391; display: inline-flex; align-items: center; gap: .06rem; padding: .04rem .16rem; font-size: calc(.18 * var(--t)); font-weight: 700; color: #eef0ef; background: var(--tag); background: color-mix(in srgb, var(--tag) 26%, #1b1d1d); border-radius: 999px; box-shadow: inset 0 0 0 1px var(--tag); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tag) 45%, transparent); }
.mf-tag .icon { width: max(.2rem, 13px); height: max(.2rem, 13px); color: var(--tag); }
.mf-search__scene { position: relative; width: min(100%, 4.6rem); padding: .16rem .3rem; }
.mf-cross { position: absolute; width: .16rem; height: .16rem; }
.mf-cross::before, .mf-cross::after { content: ''; position: absolute; background: rgba(78, 216, 175, .55); }
.mf-cross::before { left: 50%; top: 0; bottom: 0; width: 1px; } .mf-cross::after { top: 50%; left: 0; right: 0; height: 1px; }
.mf-cross--tl { left: .1rem; top: 0; } .mf-cross--tr { right: .1rem; top: 0; } .mf-cross--bl { left: .1rem; bottom: 0; } .mf-cross--br { right: .1rem; bottom: 0; }
.mf-scout { display: block; width: 100%; height: auto; overflow: visible; }
.mf-scout__wave { fill: none; stroke: rgba(78, 216, 175, .35); stroke-width: 6; filter: blur(2px); animation: mf-wave 3s ease-in-out infinite alternate; }
@keyframes mf-wave { to { transform: translateX(-12px); } }
.mf-scout__sky { fill: #48e2b6; opacity: .9; animation: mf-sky 4s linear infinite; }
@keyframes mf-sky { from { transform: translateX(0); } to { transform: translateX(-120px); } }
.mf-scout__bot rect { fill: #5df0c6; }
.mf-scout__bot { animation: mf-hop .5s steps(2) infinite; }
@keyframes mf-hop { 50% { transform: translateY(-3px); } }
.mf-scout__eye { fill: #0b2620 !important; animation: mf-blink 3s steps(1) infinite; }
@keyframes mf-blink { 0%, 92% { opacity: 1; } 94%, 100% { opacity: 0; } }
.mf-scout__leg--a { animation: mf-leg .3s steps(2) infinite; } .mf-scout__leg--b { animation: mf-leg .3s steps(2) infinite reverse; }
@keyframes mf-leg { 50% { transform: translateY(-3px); } }
.mf-scout__ground { stroke: rgba(93, 240, 198, .5); stroke-width: 2; stroke-dasharray: 6 4; }
.mf-scout text { fill: #5df0c6; font: 700 8px var(--font-num, monospace); letter-spacing: 2px; opacity: .8; }
.mf-search__tip { min-height: 2.8em; margin: 0; max-width: 5rem; font-size: calc(.2 * var(--t)); line-height: 1.45; color: #e6e9e8; animation: sw-in 300ms var(--ease-out) backwards; }
.mf-search__note { margin: 0; font-size: calc(.15 * var(--t)); color: #8d9391; }
.mf-stop { display: inline-flex; align-items: center; gap: .12rem; margin-top: auto; align-self: flex-end; height: max(.62rem, 36px); padding: 0 .3rem 0 .14rem;
  font: inherit; font-size: calc(.24 * var(--t)); font-weight: 800; color: #ffd9d9; cursor: pointer;
  background: linear-gradient(90deg, rgba(120, 24, 34, .85), rgba(70, 14, 20, .85)); border: 1px solid rgba(255, 120, 130, .55); }
.mf-stop:hover:not(:disabled) { filter: brightness(1.15); }
.mf-stop__x { display: grid; place-items: center; width: max(.34rem, 20px); height: max(.34rem, 20px); border: 2px solid currentColor; border-radius: 3px; }
.mf-stop__x .icon { width: 80%; height: 80%; }
.mf-found { display: flex; flex-direction: column; align-items: center; gap: .08rem; padding: .3rem .3rem .4rem; color: #eafff8; text-align: center;
  background: radial-gradient(80% 50% at 50% 30%, rgba(90, 255, 205, .3), transparent 70%), linear-gradient(180deg, #2bb892, #155f4d 55%, #0d3b31);
  animation: mf-found-in 260ms var(--ease-out) backwards; }
@keyframes mf-found-in { from { opacity: 0; transform: translateX(.4rem); } }
.mf-found .mf-brand { color: #c9fff0; }
.mf-found__lines { width: 100%; max-height: 52%; flex: 1 1 auto; }
.mf-found__lines path { fill: none; stroke: #8dffd9; stroke-width: 2; stroke-opacity: .55; stroke-dasharray: 420; stroke-dashoffset: 420;
  animation: mf-line 900ms var(--ease-out) forwards; animation-delay: calc(var(--k) * 40ms); }
@keyframes mf-line { to { stroke-dashoffset: 0; } }
.mf-found__node { fill: #b7ffe8; stroke: #0d3b31; stroke-width: 2; }
.mf-found__face svg { width: max(1.1rem, 60px); height: max(1.1rem, 60px); }
.mf-found__face rect:first-child { fill: #5df0c6; }
.mf-found__eye { fill: #0d3b31; }
.mf-found__wink, .mf-found__smile { fill: none; stroke: #0d3b31; stroke-width: 4; stroke-linecap: round; }
.mf-found__title { font-size: calc(.46 * var(--t)); font-weight: 900; letter-spacing: .08em; color: #b7ffe8; text-shadow: 0 0 .2rem rgba(0, 0, 0, .3); }
.mf-found__sub { font-size: calc(.18 * var(--t)); color: #d5fff2; }

/* 搜寻队友 while searching: the panel in place of the cards */
.proto-side--search { justify-content: stretch; background: linear-gradient(90deg, transparent, rgba(0, 0, 0, .55) 30%); }
.proto-side--search .mf-search { flex: 1 1 auto; }
.proto-mode-chip { display: inline-flex; align-items: center; gap: .06rem; padding: .04rem .16rem; font-size: calc(.17 * var(--t)); font-weight: 700; color: #e9eceb;
  background: #2a2c2d; border-radius: 999px; }
.proto-mode-chip .icon { width: max(.2rem, 13px); height: max(.2rem, 13px); }

/* ---- 选择同盟方式 ---- */
.ally__bg { background:
.proto-start__label { position: relative; display: inline-flex; align-items: center; gap: .1rem; min-width: 0; font-size: calc(.4 * var(--t)); font-weight: 900; letter-spacing: .08em; white-space: nowrap; }
/* 选择模拟协议's own button (.proto-foot; the room's GoButton shares the rules above and makes its own choice in
   css/screens/room.css — §37.18 review: these rules once reached it too): the label wraps onto a second line (the button
   grows: min-height above) rather than being cut, and stops at .46rem — 大's size — on a screen taller than 520 px, the
   mark's rook at .4rem (§37.18's leftover: English 开始独立模拟 was cut at every desktop size, even at 小 at 1440x900;
   the short-screen block has its own caps). [ASSUMED] the label's caps */
.proto-foot .proto-start__label { flex: 1 1 auto; padding-right: 8%; font-size: min(calc(.4 * var(--t)), .46rem); white-space: normal; line-height: 1.1; }
.proto-foot .proto-start__rook { font-size: min(calc(.36 * var(--t)), .4rem); }
.proto-start__deco {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 26%;
  clip-path: polygon(18% 0, 100% 0, 100% 100%, 0 100%);
  background: repeating-linear-gradient(135deg, rgba(0, 0, 0, .28) 0 5px, transparent 5px 11px), linear-gradient(90deg, rgba(13, 42, 35, .2), rgba(13, 42, 35, .6));
}

/* ---- 选择同盟方式: the radar, the 创建同盟 / 加入同盟 cards -------------------------------------------------- */
.ally__bg {
  background:
    radial-gradient(40% 55% at 30% 52%, rgba(46, 210, 160, .12), transparent 70%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .022) 0 1px, transparent 1px 4px),
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    radial-gradient(120% 90% at 50% 40%, #141616, #070808); }
.ally__mode { color: var(--mint-400); }
.ally-stage { position: relative; min-height: 0; }
    radial-gradient(120% 90% at 50% 40%, #141616, #070808);
}
.ally__mode { color: var(--mint-400); }
.ally-body { grid-template-columns: minmax(0, 1fr) min(7.4rem, 46vw); }
.ally-stage { position: relative; min-width: 0; min-height: 0; }
.mf-radar { position: absolute; inset: 0 0 .8rem; width: 100%; height: calc(100% - .8rem); }
.mf-radar__grid line { stroke: rgba(78, 216, 175, .08); stroke-width: 1; }
.mf-radar__land path { fill: rgba(150, 170, 165, .1); stroke: rgba(150, 170, 165, .2); stroke-width: 1; }
.mf-radar__ring { fill: none; stroke: rgba(78, 216, 175, .25); stroke-width: 1.5; }
.mf-radar__ring--far { fill: rgba(30, 140, 110, .1); }
.mf-radar__ring--core { stroke: rgba(78, 216, 175, .75); stroke-width: 3; filter: drop-shadow(0 0 6px rgba(78, 216, 175, .6)); }
.mf-radar__sweep { transform-origin: 270px 250px; animation: mf-sweep 4.5s linear infinite; }
.mf-radar__sweep path { fill: rgba(60, 230, 180, .22); }
.mf-radar__sweep line { stroke: #5df0c6; stroke-width: 3; filter: drop-shadow(0 0 6px #5df0c6); }
@keyframes mf-sweep { to { transform: rotate(360deg); } }
.mf-radar__blip { fill: #ffc53d; filter: drop-shadow(0 0 8px #ffc53d); animation: mf-blip 2.2s ease-in-out infinite; }
.mf-radar__blip--b { fill: #5df0c6; filter: drop-shadow(0 0 6px #5df0c6); animation-delay: 1.1s; }
@keyframes mf-blip { 50% { opacity: .2; } }
.mf-radar__cross { stroke: #5df0c6; stroke-width: 3; }
.mf-radar__read rect { fill: rgba(0, 0, 0, .5); stroke: rgba(78, 216, 175, .45); }
.mf-radar__read text { fill: #9fe9d3; font: 700 14px var(--font-num, monospace); }
.mf-radar__frame { fill: none; stroke: rgba(78, 216, 175, .35); stroke-width: 2; }
.ally-guide { position: absolute; left: .1rem; bottom: .1rem; display: inline-flex; align-items: center; gap: .14rem; height: max(.64rem, 38px); padding: 0 .3rem 0 .1rem;
  font: inherit; font-size: calc(.22 * var(--t)); font-weight: 800; color: #1a1d1c; cursor: pointer; background: linear-gradient(180deg, #e9edeb, #c3cac7);
  border: 1px solid rgba(255, 255, 255, .6); box-shadow: 0 .04rem .14rem rgba(0, 0, 0, .5); }
.ally-guide:hover { filter: brightness(1.06); }
.ally-guide__icon { display: grid; place-items: center; width: max(.46rem, 28px); height: max(.4rem, 24px); color: #e9edeb; background: #2a2f2d; }
.ally-guide__icon .icon { width: 64%; height: 64%; }
.ally-body { grid-template-columns: minmax(0, 1fr) min(7.4rem, 42vw); }
.ally-side { min-height: 0; display: flex; flex-direction: column; justify-content: center; gap: .16rem; padding: .1rem 0 .1rem .3rem; overflow-y: auto; scrollbar-width: thin; }
.ally-card__art { flex: 1 1 auto; display: grid; place-items: center; }
.ally-card { position: relative; flex: none; display: flex; flex-direction: column; width: 100%; padding: 0; overflow: hidden; font: inherit; color: #eef0ef; text-align: left;
  background: radial-gradient(70% 90% at 50% 40%, #161a19, #090a0a); border: 1px solid rgba(255, 255, 255, .14); border-radius: .08rem;
  box-shadow: 0 .06rem .2rem rgba(0, 0, 0, .5); }
button.ally-card { cursor: pointer; }
button.ally-card:hover:not(:disabled) { border-color: rgba(93, 240, 198, .6); }
button.ally-card:disabled { filter: grayscale(.7) brightness(.7); cursor: default; }
.ally-card__art { display: block; padding: .1rem .2rem 0; }
.mf-art { display: block; width: 100%; height: auto; }
.ally-guide {
  position: absolute;
  left: .1rem;
  bottom: .1rem;
  display: inline-flex;
  align-items: center;
  gap: .14rem;
  height: max(.64rem, 32px, calc(38px * var(--sp-ui, 1)));
  padding: 0 .3rem 0 .1rem;
  font: inherit;
  font-size: calc(.22 * var(--t));
  font-weight: 800;
  color: #1a1d1c;
  background: linear-gradient(180deg, #e9edeb, #c3cac7);
  border: 1px solid rgba(255, 255, 255, .6);
  box-shadow: 0 .04rem .14rem rgba(0, 0, 0, .5);
}
.ally-guide:hover, .ally-guide:focus-visible { filter: brightness(1.06); }
.ally-guide__icon { display: grid; place-items: center; width: max(.46rem, 28px); height: max(.4rem, 24px); color: #e9edeb; background: #2a2f2d; }
.ally-guide__icon .icon { width: 64%; height: 64%; }
/* centred safely: the auto margins give way when the column is taller than its space (justify-content: center would
   push it past both ends), so a short screen's scroll (below) starts at 创建同盟 */
.ally-side { min-height: 0; display: flex; flex-direction: column; gap: .2rem; padding: .1rem 0 .1rem .3rem; }
.ally-side > :first-child { margin-top: auto; }
.ally-side > :last-child { margin-bottom: auto; }
.ally-card {
  position: relative;
  flex: none;
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 0;
  overflow: hidden;
  font: inherit;
  color: #eef0ef;
  text-align: left;
  background: radial-gradient(70% 90% at 50% 40%, #161a19, #090a0a);
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: .08rem;
  box-shadow: 0 .06rem .2rem rgba(0, 0, 0, .5);
}
button.ally-card:hover, button.ally-card:focus-visible { border-color: rgba(93, 240, 198, .6); }
.ally-card__art { display: block; padding: .1rem .2rem 0; }
.mf-art { display: block; width: 100%; height: auto; max-height: 1.3rem; }
.mf-art text { font: 700 8px var(--font-display, monospace); letter-spacing: 2px; fill: currentColor; opacity: .7; }
.mf-art--create { color: #5df0c6; }
.mf-art--create .mf-art__wire { fill: none; stroke: rgba(93, 240, 198, .45); stroke-width: 2; }
.mf-art--create .mf-art__oct { fill: #2fd6a6; filter: drop-shadow(0 0 10px rgba(93, 240, 198, .6)); }
.mf-art--create .mf-art__plus { stroke: #08221b; stroke-width: 7; stroke-linecap: square; }
.mf-art--create .mf-art__brk { fill: none; stroke: #5df0c6; stroke-width: 4; }
.mf-art--create .mf-art__dot { fill: #5df0c6; }
.mf-art--join { color: #ff9a3c; }
.mf-art--join .mf-art__wire { fill: none; stroke: rgba(255, 154, 60, .6); stroke-width: 2; }
.mf-art--join .mf-art__tri { fill: #ff9a3c; }
.mf-art--join .mf-art__target { fill: rgba(255, 154, 60, .15); stroke: #ff9a3c; stroke-width: 2; }
.mf-art--join .mf-art__x { stroke: #ff9a3c; stroke-width: 3; }
.mf-blk path { stroke: rgba(0, 0, 0, .5); stroke-width: 1; }
.mf-blk__top { fill: #3a3d3d; } .mf-blk__l { fill: #2a2c2c; } .mf-blk__r { fill: #1f2121; }
.mf-blk.is-lit .mf-blk__top { fill: #f0a35a; } .mf-blk.is-lit .mf-blk__l { fill: #c96b23; } .mf-blk.is-lit .mf-blk__r { fill: #a5541a; }
.mf-blk.is-lit { animation: mf-blk 2.4s ease-in-out infinite; animation-delay: calc(var(--k) * 120ms); }
@keyframes mf-blk { 50% { transform: translateY(-3px); } }
.ally-card__bar { position: relative; display: flex; align-items: center; gap: .14rem; height: max(.74rem, 42px); padding: 0 .2rem; font-size: calc(.3 * var(--t)); font-weight: 900;
  letter-spacing: .06em; color: #08221b; background: linear-gradient(180deg, #4fe8c0, #2fcf9f); border: 0; font-family: inherit; text-align: left; }
.ally-card__bar { white-space: nowrap; }
.ally-card__bar small { margin-left: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: calc(.14 * var(--t)); font-weight: 700; letter-spacing: 0; color: rgba(8, 34, 27, .75); }
.ally-pill { white-space: nowrap; }
@media (max-width: 700px) { .ally-card__bar small { display: none; } .ally-card__art { padding-top: 4px; } }
.ally-card__bar--join { width: 100%; color: #2a1404; background: linear-gradient(180deg, #ffb24f, #f08a26); cursor: pointer; }
.ally-card__bar--join:disabled { filter: grayscale(.6) brightness(.75); cursor: default; }
.ally-card__bar--join:hover:not(:disabled) { filter: brightness(1.06); }
.ally-card__icon { display: grid; place-items: center; width: max(.36rem, 22px); height: max(.36rem, 22px); color: currentColor; background: rgba(0, 0, 0, .14); border: 2px solid currentColor; border-radius: 4px; }
.ally-card__icon .icon { width: 74%; height: 74%; }
.ally-links { display: flex; justify-content: flex-end; gap: .1rem; margin: -.04rem 0; }
.ally-pill { display: inline-flex; align-items: center; gap: .08rem; height: max(.5rem, 30px); padding: 0 .2rem; font: inherit; font-size: calc(.2 * var(--t)); font-weight: 700;
  color: #eef0ef; background: linear-gradient(180deg, #2c2f2f, #1b1d1d); border: 1px solid rgba(255, 255, 255, .2); border-radius: 999px; cursor: pointer; }
.ally-pill:hover { border-color: rgba(255, 255, 255, .45); }
.ally-pill .icon { width: max(.2rem, 13px); height: max(.2rem, 13px); }
.ally-pill b { min-width: max(.24rem, 16px); padding: 0 4px; font-size: .8em; text-align: center; color: #2a1404; background: #ff9a3c; border-radius: 999px; }
.ally-pill__mark { width: max(.22rem, 14px); height: max(.22rem, 14px); background: conic-gradient(#ff9a3c 0 25%, transparent 0 50%, #ff9a3c 0 75%, transparent 0); }
.ally-key { display: flex; align-items: center; gap: .1rem; margin: .06rem .2rem .1rem; padding: 0 .06rem 0 .12rem; height: max(.56rem, 34px); background: #262929;
  border: 1px solid rgba(255, 255, 255, .2); border-radius: .06rem; }
.ally-key > .icon { flex: none; width: max(.24rem, 15px); height: max(.24rem, 15px); color: #c9cecc; }
.ally-key input { flex: 1 1 auto; min-width: 0; height: 100%; font: inherit; font-size: calc(.22 * var(--t)); font-weight: 700; letter-spacing: .08em; text-align: center;
  color: #f2f4f3; background: none; border: 0; outline: none; text-transform: uppercase; }
.ally-key input::placeholder { color: #8d9391; font-weight: 500; letter-spacing: .04em; text-transform: none; }
.ally-key__spec { display: inline-flex; align-items: center; gap: .04rem; height: 80%; padding: 0 .12rem; font: inherit; font-size: calc(.15 * var(--t)); color: #eef0ef;
  background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .2); border-radius: 4px; cursor: pointer; }
.ally-key__spec .icon { width: 1.1em; height: 1.1em; }
.ally-recent { display: flex; flex-wrap: wrap; justify-content: center; gap: .06rem; margin: -.04rem .2rem .1rem; }

/* ---- the room (room.js) ---- */
.rs { background: #0a0b0b; color: #eef0ef; }
.rs__bg { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(60% 50% at 30% 40%, var(--mint-500), transparent 70%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .02) 0 1px, transparent 1px 4px),
    linear-gradient(rgba(255, 255, 255, .025) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    linear-gradient(90deg, rgba(255, 255, 255, .025) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    radial-gradient(120% 90% at 50% 30%, #161818, #070808); background:
    radial-gradient(60% 50% at 30% 40%, color-mix(in srgb, var(--mint-500) 7%, transparent), transparent 70%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .02) 0 1px, transparent 1px 4px),
    linear-gradient(rgba(255, 255, 255, .025) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    linear-gradient(90deg, rgba(255, 255, 255, .025) 1px, transparent 1px) 0 0 / 1.1rem 1.1rem,
    radial-gradient(120% 90% at 50% 30%, #161818, #070808); }
.rs > :where(:not(.rs__bg, .mf-search, .mf-found, .rs-proto, .modal)) { position: relative; }
.rs-top { flex: none; display: flex; align-items: flex-start; justify-content: space-between; gap: .2rem; padding: .16rem .3rem 0 .22rem; z-index: 3; }
.rs-top__left { display: flex; align-items: center; gap: .16rem; min-width: 0; }
.rs-exit { display: grid; place-items: center; width: max(.6rem, 36px); height: max(.6rem, 36px); padding: 0; color: #1b1e1d; cursor: pointer;
  background: linear-gradient(180deg, #e3e7e5, #b7bfbc); border: 0; border-radius: .06rem; box-shadow: 0 .03rem .1rem rgba(0, 0, 0, .5); }
.rs-exit:hover { filter: brightness(1.08); }
.rs-exit .icon { width: 60%; height: 60%; }
.rs-clock { display: flex; flex-direction: column; gap: .02rem; min-width: 0; }
.rs-clock > b { display: inline-flex; align-items: center; gap: .1rem; font-size: calc(.2 * var(--t)); font-weight: 700; white-space: nowrap; }
.rs-clock__sep { width: 1px; height: .9em; background: rgba(255, 255, 255, .3); }
.rs-clock > span { font-size: calc(.16 * var(--t)); color: #9aa19e; }
.rs-ping { margin: 0 2px; } .rs-ping--low { color: #8fef5a; } .rs-ping--mid { color: #ffc53d; } .rs-ping--high, .rs-ping--off { color: #ff6b6b; }
.rs-tools { display: flex; gap: .08rem; margin-left: .1rem; }
.rs-key { display: flex; align-items: center; gap: .14rem; height: max(.56rem, 34px); padding: 0 .06rem 0 .2rem; background: rgba(28, 30, 30, .9); border: 1px solid rgba(255, 255, 255, .1); border-radius: .06rem; }
.rs-key__k { font-size: calc(.17 * var(--t)); color: #b7bdbb; padding-right: .14rem; border-right: 1px solid rgba(255, 255, 255, .25); }
.rs-key__code { font-size: calc(.28 * var(--t)); letter-spacing: .06em; color: #f2f4f3; }
.rs-key__copy { height: 78%; padding: 0 .26rem; font: inherit; font-size: calc(.2 * var(--t)); font-weight: 800; color: #1b1e1d; background: linear-gradient(180deg, #e9edeb, #c3cac7);
  border: 0; border-radius: .05rem; cursor: pointer; }
.rs-key__copy:hover { filter: brightness(1.06); }
.rs-key__copy, .rs-key__code { white-space: nowrap; }
.rs-key__link { display: grid; place-items: center; width: max(.44rem, 28px); height: 78%; padding: 0; color: #c9cecc; background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .15); border-radius: .05rem; cursor: pointer; }
.rs-key__link .icon { width: 60%; height: 60%; }
/* 邀请好友 (ui/friends.js panel; the owner, 2026-10-14: the tools' icon alone was not found) */
.rs-key__friends { display: inline-flex; align-items: center; gap: .06rem; height: 78%; padding: 0 .2rem; font: inherit; font-size: calc(.2 * var(--t));
  font-weight: 800; white-space: nowrap; color: #1d1405; background: linear-gradient(180deg, #ffd27a, #f0a93a); border: 0; border-radius: .05rem; cursor: pointer; }
.rs-key__friends:hover { filter: brightness(1.06); }
.rs-key__friends .icon { width: max(.24rem, 14px); height: max(.24rem, 14px); }
.rs-key--solo { gap: .1rem; padding-right: .2rem; font-size: calc(.16 * var(--t)); color: #b7bdbb; }

.rs-seats { flex: 1 1 auto; min-height: 0; display: flex; align-items: stretch; justify-content: center; gap: max(.3rem, 2.2vw); padding: .3rem .4rem .1rem;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
.rs--big .rs-seats { justify-content: flex-start; gap: .16rem; }
.rseat { --w: min(18vw, 3.4rem, calc((100vw - 1.6rem) / var(--n, 4) - .3rem)); position: relative; flex: none; width: var(--w); display: flex; flex-direction: column;
  animation: sw-in 260ms var(--ease-out) backwards; animation-delay: calc(var(--i) * 60ms); }
.rs--big .rseat { --w: max(1.7rem, 120px); }
.rs--solo .rseat { --w: min(2.7rem, 34vw); }
.rseat__clip { position: absolute; left: 50%; top: -.14rem; width: .16rem; height: .2rem; transform: translateX(-50%); background: #3a3e3d; border: 2px solid #1a1c1c; z-index: 2; }
.rseat.is-ready .rseat__clip { background: #4fe8c0; }
.rseat__strip { position: relative; display: flex; align-items: center; justify-content: space-between; height: max(.26rem, 16px); padding: 0 .08rem; background: #2b2e2e; }
.rseat__strip i { width: .5rem; height: 4px; background: repeating-linear-gradient(90deg, rgba(255, 255, 255, .45) 0 3px, transparent 3px 5px); }
.rseat__strip span { font-size: calc(.12 * var(--t)); color: #8d9391; }
.rseat.is-ready .rseat__strip { background: #4fe8c0; }
.rseat.is-ready .rseat__strip i { background: repeating-linear-gradient(90deg, rgba(8, 34, 27, .6) 0 3px, transparent 3px 5px); }
.rseat.is-ready .rseat__strip span { color: #08221b; }
.rseat__art { position: relative; flex: 1 1 auto; min-height: 0; display: grid; place-items: center; overflow: hidden; background: linear-gradient(180deg, #1f2222, #141616);
  border: 2px solid #2b2e2e; border-top: 0; }
.rseat.is-ready .rseat__art { border-color: #4fe8c0; box-shadow: 0 0 .2rem rgba(79, 232, 192, .35); }
.rseat__art img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; }
.rseat.is-ready .rseat__art::after { content: ''; position: absolute; inset: 50% 0 0; background: linear-gradient(180deg, transparent, rgba(47, 207, 159, .85)); pointer-events: none; }
.rseat__glyph { font-size: calc(.9 * var(--t)); font-weight: 900; color: rgba(255, 255, 255, .25); }
.rseat__glyph .icon { width: max(1rem, 50px); height: max(1rem, 50px); }
.rseat__host { position: absolute; top: .14rem; left: 50%; transform: translateX(-50%); z-index: 1; padding: .02rem .18rem; font-size: calc(.18 * var(--t)); font-weight: 800;
  color: #08221b; background: #4fe8c0; border-radius: .04rem; white-space: nowrap; }
.rseat__lost { position: absolute; left: 0; right: 0; top: 40%; z-index: 1; display: flex; align-items: center; justify-content: center; gap: .1rem; padding: .14rem 0;
  font-size: calc(.24 * var(--t)); font-weight: 800; color: #ff7a8a; background: rgba(80, 10, 18, .85); }
.rseat__lost .icon { width: 1.2em; height: 1.2em; }
.rseat.is-offline .rseat__art img { filter: grayscale(.8) brightness(.6); }
.rseat__state { position: absolute; left: 0; right: 0; bottom: .14rem; z-index: 1; display: flex; align-items: center; justify-content: center; gap: .1rem;
  font-size: calc(.26 * var(--t)); font-weight: 900; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .6); }
.rseat:not(.is-ready) .rseat__state { color: #c9cecc; font-size: calc(.2 * var(--t)); }
.rseat__box { display: grid; place-items: center; width: max(.34rem, 20px); height: max(.34rem, 20px); border: 2px solid currentColor; border-radius: 4px; background: rgba(0, 0, 0, .25); }
.rseat__box .icon { width: 80%; height: 80%; }
.rseat__kick { position: absolute; right: -.08rem; top: -.12rem; z-index: 3; display: inline-flex; align-items: center; height: max(.4rem, 24px); padding: 0 .1rem; color: #ff8a96;
  background: #3b1218; border: 1px solid rgba(255, 120, 130, .6); border-radius: 999px; cursor: pointer; }
.rseat__kick .icon { width: max(.2rem, 12px); height: max(.2rem, 12px); }
.rseat__kick .icon + .icon { width: max(.14rem, 9px); margin-left: -2px; }
.rseat__kick:hover:not(:disabled) { filter: brightness(1.3); }
.rseat__plate { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto; column-gap: .1rem; align-items: center;
  min-height: max(.76rem, 46px); margin-top: .08rem; padding: .06rem .1rem; background: linear-gradient(90deg, #232626, #161818); border: 1px solid rgba(255, 255, 255, .1); }
.rseat.is-ready .rseat__plate { border-color: rgba(79, 232, 192, .55); }
.rseat.is-me .rseat__plate { background: linear-gradient(90deg, #26302d, #161a19); }
.rseat__plate .avatar { grid-row: 1 / 3; }
.rseat__who { display: flex; align-items: center; gap: .06rem; min-width: 0; font-size: calc(.18 * var(--t)); }
.rseat__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rseat__doc { font-size: calc(.11 * var(--t)); letter-spacing: .1em; color: #7f8583; }
.rseat__me { position: absolute; left: -.1rem; top: -.1rem; display: grid; place-items: center; width: max(.26rem, 16px); height: max(.26rem, 16px); color: #08221b;
  background: #4fe8c0; border-radius: 3px; }
.rseat__me .icon { width: 80%; height: 80%; }
.rseat__plate--empty { border-style: dashed; border-color: rgba(255, 255, 255, .12); background: none; }
.rseat--empty .rseat__art { background: linear-gradient(135deg, transparent 47%, rgba(255, 255, 255, .06) 50%, transparent 53%), #141616; }
.rseat__invite { display: flex; flex-direction: column; align-items: center; gap: .1rem; padding: .2rem .1rem; font: inherit; color: #eef0ef; background: none; border: 0; cursor: pointer; }
.rseat__plus { position: relative; width: max(.9rem, 46px); height: max(.9rem, 46px); }
.rseat__plus::before, .rseat__plus::after { content: ''; position: absolute; background: #f2f4f3; box-shadow: 0 0 .1rem rgba(255, 255, 255, .5); }
.rseat__plus::before { left: 50%; top: 0; bottom: 0; width: 7px; transform: translateX(-50%); } .rseat__plus::after { top: 50%; left: 0; right: 0; height: 7px; transform: translateY(-50%); }
.rseat__invite b { font-size: calc(.26 * var(--t)); }
.rseat__invite small { font-size: calc(.15 * var(--t)); color: #8d9391; text-align: center; }
.rseat__invite:hover .rseat__plus::before, .rseat__invite:hover .rseat__plus::after { background: #5df0c6; }
.rseat__wait { display: flex; flex-direction: column; align-items: center; gap: .1rem; color: #b7bdbb; }
.rseat__wait svg { width: max(.7rem, 36px); height: auto; fill: none; stroke: currentColor; stroke-width: 3; }
.rseat__wait small { padding: .02rem .08rem; font-family: var(--font-display); font-size: calc(.1 * var(--t)); letter-spacing: .1em; background: rgba(255, 255, 255, .08); }
.rseat--empty.is-searching .rseat__wait { animation: mf-blip 1.6s ease-in-out infinite; }
.rseat__noinfo { position: absolute; right: .12rem; bottom: .3rem; font-family: var(--font-display); font-size: calc(.12 * var(--t)); letter-spacing: .1em; color: rgba(255, 255, 255, .15); }
.rs-brief { align-self: center; max-width: min(5rem, 46vw); }
/* 名片干员: one's own card opens the picker */
.rseat__art.is-pickable { cursor: pointer; }
.rseat__pick { position: absolute; right: .08rem; top: .5rem; z-index: 2; display: inline-flex; align-items: center; gap: .04rem; height: max(.36rem, 22px); padding: 0 .1rem;
  font: inherit; font-size: calc(.14 * var(--t)); font-weight: 700; color: #eef0ef; background: rgba(0, 0, 0, .55); border: 1px solid rgba(255, 255, 255, .3); border-radius: 999px;
  cursor: pointer; opacity: .75; transition: opacity var(--t-fast); }
.rseat__pick .icon { width: 1.1em; height: 1.1em; }
.rseat__art:hover .rseat__pick, .rseat__pick:focus-visible { opacity: 1; border-color: #5df0c6; }
@media (max-width: 900px) { .rseat__pick span { display: none; } }
.cardpick .modal__body, .cardpick { --cp-size: max(.86rem, 52px); }
.cardpick__bar { display: flex; flex-wrap: wrap; align-items: center; gap: .1rem; margin-bottom: .12rem; }
.cardpick__search { flex: 1 1 2.4rem; display: flex; align-items: center; gap: .06rem; height: max(.5rem, 30px); padding: 0 .1rem; background: rgba(0, 0, 0, .4); border: 1px solid var(--line-2); }
.cardpick__search .icon { width: 1.1em; height: 1.1em; color: var(--text-lo); }
.cardpick__search input { flex: 1 1 auto; min-width: 0; font: inherit; color: var(--text-hi); background: none; border: 0; outline: none; }
.cardpick__stars { display: inline-flex; border: 1px solid var(--line-2); }
.cardpick__stars button { height: max(.48rem, 28px); padding: 0 .14rem; font: inherit; font-size: calc(.16 * var(--t)); color: var(--text-md); background: none; border: 0; cursor: pointer; }
.cardpick__stars button.is-on { color: #08221b; background: var(--mint-500); }
.cardpick__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--cp-size), 1fr)); gap: .08rem; max-height: min(52vh, 5.4rem); overflow-y: auto; padding: 2px; scrollbar-width: thin; }
.cardpick__op { position: relative; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 3px; font: inherit; color: var(--text-md);
  background: rgba(255, 255, 255, .03); border: 1px solid var(--line); cursor: pointer; }
.cardpick__op:hover { border-color: var(--line-3); color: var(--text-hi); }
.cardpick__op.is-on { border-color: var(--mint-400); box-shadow: 0 0 0 1px var(--mint-400); color: var(--text-hi); }
.cardpick__img { display: grid; place-items: center; width: 100%; aspect-ratio: 1; overflow: hidden; background: linear-gradient(180deg, #d7dcda, #a9b1ae); }
.cardpick__img img { width: 100%; height: 100%; object-fit: cover; }
.cardpick__op--auto .cardpick__img { background: #1d2120; color: var(--mint-400); }
.cardpick__op--auto .cardpick__img .icon { width: 45%; height: 45%; }
.cardpick__name { width: 100%; font-size: calc(.13 * var(--t)); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cardpick__star { position: absolute; right: 3px; top: 3px; padding: 0 3px; font-size: calc(.11 * var(--t)); font-weight: 800; color: #111; background: #e8e8e8; }
.cardpick__star.r6 { background: #ffcf5a; } .cardpick__star.r5 { background: #f2e06b; }
.cardpick__note { display: flex; align-items: center; gap: .06rem; margin: .12rem 0 0; font-size: calc(.15 * var(--t)); color: var(--text-lo); }
.cardpick__note .icon { flex: none; width: 1.1em; height: 1.1em; }

.rs-foot { flex: none; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: end; gap: .2rem; padding: .1rem .3rem .2rem .22rem; z-index: 2; }
.rs-foot__left { min-width: 0; }
.rs-top__right { display: flex; align-items: center; gap: .14rem; }
.rs-loadout.hub-plate { width: auto !important; height: max(.56rem, 34px) !important; min-width: 0; padding: 0 .2rem 0 .14rem !important; }
.rs-loadout.hub-plate .lo-entry__icon, .rs-loadout.hub-plate > .btn__icon { width: max(.36rem, 22px) !important; height: max(.36rem, 22px) !important; padding: .04rem; }
.rs-loadout.hub-plate .btn__label { font-size: calc(.18 * var(--t)); }
.rs-ready { display: inline-flex; align-items: center; gap: 2px; margin-right: .14rem; font-size: calc(.16 * var(--t)); color: #9aa19e; vertical-align: middle; }
.rs-ready .icon { width: max(.2rem, 13px); height: max(.2rem, 13px); color: #4b504e; }
.rs-ready .icon.is-on { color: #4fe8c0; }
.rs-ready b { margin-left: .06rem; color: #eef0ef; }
.rs-foot__center { display: flex; flex-direction: column; align-items: center; gap: .08rem; }
.rs-hint { margin: 0; font-size: calc(.18 * var(--t)); color: #d6dad8; text-align: center; }
.rs-hint .icon { width: 1.1em; height: 1.1em; margin-right: 4px; vertical-align: -2px; }
.rs-pill { position: relative; display: inline-flex; align-items: center; gap: .14rem; height: max(.68rem, 40px); padding: 0 .08rem 0 .24rem;
  background: rgba(14, 15, 15, .92); border: 1px solid rgba(255, 255, 255, .14); border-radius: 999px; box-shadow: 0 .04rem .16rem rgba(0, 0, 0, .5); }
.rs-pill__mode { display: inline-flex; align-items: center; gap: .08rem; font-size: calc(.2 * var(--t)); font-weight: 700; color: #e9eceb; white-space: nowrap; }
.rs-pill__mode .icon { width: 1.1em; height: 1.1em; }
.rs-pill__sep { width: 1px; height: 50%; background: rgba(255, 255, 255, .25); }
.rs-pill__diff { display: inline-flex; align-items: center; gap: .08rem; height: 78%; padding: 0 .2rem; font: inherit; font-size: calc(.2 * var(--t)); font-weight: 800; color: var(--d-color); background: var(--d-color); background: color-mix(in srgb, var(--d-color) 22%, #151616); border: 0; border-radius: 999px; cursor: pointer; white-space: nowrap; }
.rs-pill__diff .icon { width: 1.2em; height: 1.2em; }
.rs-pill__diff:disabled { cursor: default; }
.rs-pill__diff:hover:not(:disabled) { filter: brightness(1.2); }
.rs-pill__gear { display: grid; place-items: center; width: max(.52rem, 32px); height: max(.52rem, 32px); padding: 0; color: #1b1e1d; background: linear-gradient(180deg, #e9edeb, #c3cac7);
  border: 2px solid #0e0f0f; border-radius: 50%; cursor: pointer; }
.rs-pill__gear svg { width: 62%; height: 62%; fill: currentColor; }
.rs-pill__gear.is-on, .rs-pill__gear:hover { background: #fff; }
.rs-opts { position: absolute; left: 50%; bottom: calc(100% + .14rem); z-index: 10; transform: translateX(-50%); width: min(5.2rem, 92vw); display: flex; flex-direction: column; gap: .12rem;
  padding: .16rem .2rem; background: linear-gradient(180deg, #202323, #141616); border: 1px solid rgba(255, 255, 255, .16); box-shadow: 0 .1rem .4rem rgba(0, 0, 0, .7);
  animation: sw-in 140ms var(--ease-out) backwards; }
.rs-opts h4 { display: flex; align-items: baseline; justify-content: space-between; margin: 0; font-size: calc(.2 * var(--t)); }
.rs-opts h4 small { font-size: .75em; font-weight: 500; color: #8d9391; }
.rs-opt { display: flex; align-items: center; justify-content: space-between; gap: .14rem; font-size: calc(.18 * var(--t)); }
.rs-opt > span { display: flex; flex-direction: column; }
.rs-opt small { font-size: .8em; color: #8d9391; }
.rs-opt input { order: 2; width: max(.24rem, 16px); height: max(.24rem, 16px); accent-color: var(--mint-500); }
.rs-opt select { font: inherit; color: #eef0ef; background: #111313; border: 1px solid rgba(255, 255, 255, .2); padding: 2px 6px; }
.rs-opt--variant { flex-direction: column; align-items: stretch; }
.rs-opts .ailast { display: flex; align-items: center; gap: .1rem; }
.rs-foot__right { display: flex; align-items: center; justify-content: flex-end; gap: .14rem; }
.rs-search { display: inline-flex; align-items: center; gap: .08rem; height: max(.7rem, 40px); padding: 0 .26rem; font: inherit; font-size: calc(.24 * var(--t)); font-weight: 800;
  color: #5df0c6; background: rgba(10, 30, 25, .85); border: 2px solid rgba(79, 232, 192, .7); cursor: pointer; white-space: nowrap; }
.rs-search:hover:not(:disabled) { background: rgba(20, 60, 48, .9); }
.rs-search:disabled { opacity: .5; cursor: default; }
.rs-search .icon { width: 1.1em; height: 1.1em; }
.rs-go.proto-start { width: min(4.6rem, 40vw); }
.rs-go__box { display: grid; place-items: center; flex: none; width: max(.5rem, 28px); height: max(.5rem, 28px); border: 3px solid currentColor; border-radius: 6px; }
.rs-go__box .icon { width: 80%; height: 80%; }
.rs-go.is-ready { background: linear-gradient(180deg, #7ff3d4, #4fe0bf); }
.rs-searchpanel.mf-search { position: absolute; right: 0; top: 0; bottom: 0; z-index: 5; width: min(6.2rem, 46vw); padding-top: .9rem; padding-bottom: .3rem;
  background: linear-gradient(90deg, transparent, rgba(6, 7, 7, .9) 18%, rgba(6, 7, 7, .96)); animation: mf-found-in 240ms var(--ease-out) backwards; }
.rs > .mf-found { position: absolute; right: 0; top: 0; bottom: 0; z-index: 6; width: min(5.6rem, 44vw); }
.rs-proto { position: absolute; inset: 0; z-index: 7; display: grid; grid-template-columns: minmax(0, 1fr) min(5.6rem, 46vw); background: rgba(5, 6, 6, .6);
  animation: sw-in 160ms var(--ease-out) backwards; }
.rs-proto__scene { position: relative; opacity: .35; pointer-events: none; color: var(--d-color); }
.rs-proto__scene .ps { inset: 0; height: 100%; }
.rs-proto__side { min-height: 0; display: flex; flex-direction: column; gap: .12rem; padding: .2rem .3rem .2rem 0; background: linear-gradient(90deg, transparent, rgba(6, 7, 7, .9) 20%); }
.rs-proto__title { margin: 0; align-self: flex-end; font-size: calc(.34 * var(--t)); font-weight: 900; }
.rs-proto__list { flex: 1 1 auto; }
.rs-proto__ok.proto-start { flex: none; margin-left: .5rem; width: calc(100% - .5rem); }

@media (max-height: 520px) {
  .rs-top { padding-top: 6px; }
  .rs-seats { padding-top: 14px; gap: 12px; }
  .rseat__plate { min-height: 36px; margin-top: 4px; }
  .rseat__doc { display: none; }
  .rs-foot { padding-bottom: 8px; gap: 8px; }
  .rs-go.proto-start, .rs-proto__ok.proto-start { height: 46px; }
  .rs-go .proto-start__mark { display: none; }
  .rs-search { height: 40px; }
  .rs-loadout.hub-plate { min-width: 0; }
  .rs-loadout .btn__label { display: none; }
  .mf-search { gap: 4px; padding: 8px 10px; overflow-y: auto; }
  .mf-search__scene { width: min(100%, 200px); padding: 4px 16px; }
  .mf-search__tip { min-height: 0; }
  .mf-stop { margin-top: 4px; height: 32px; }
  .rs-searchpanel.mf-search { padding-top: 48px; }
  .mf-found__lines { max-height: 40%; }
}
.mf-brand { white-space: nowrap; }
@media (max-width: 900px) {
  .rs-foot { grid-template-columns: auto minmax(0, 1fr); }
  .rs-foot__center { grid-column: 1 / -1; grid-row: 1; }
  .rs-tools { display: none; }
  .rs-key__k { display: none; }
  /* phones: the tools row (its 好友 icon too) is hidden — 邀请好友 stays, a short label on a coarse-pointer-sized target */
  .rs-key__friends { min-width: 44px; justify-content: center; padding: 0 8px; }
}
@media (max-width: 640px) {
  .rs-key__friends span { display: none; }
}
@media (max-aspect-ratio: 1/1) {
  .ally-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, .7fr) auto; }
  .rs-seats { justify-content: flex-start; }
  .rseat { --w: max(1.8rem, 42vw); }
  .rs-searchpanel.mf-search, .rs > .mf-found { width: 100%; background: rgba(6, 7, 7, .94); }
  .rs-proto { grid-template-columns: minmax(0, 1fr); }
  .rs-proto__scene { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .mf-scout *, .mf-scout__wave, .mf-radar__sweep, .mf-radar__blip, .mf-blk.is-lit, .mf-found__lines path, .rseat, .rseat__wait { animation: none !important; }
  .mf-found__lines path { stroke-dashoffset: 0; }
}

/* ==========================================================================================
   转场与动效 (2026-10-13, the owner's request: "游戏原版的转场", read frame by frame from the video 5:22–6:29):
   · a full-screen overlay (选择模拟协议 / 选择同盟方式 / S.W.E.E.P.报告) first darkens the hub to black (~150 ms), then its
     backdrop, top bar and panels come up one after another, sliding in from the right, a diamond marking the load at
     the bottom; leaving, its content fades and then the black lifts off the hub (js/ui/transitions.js useLeave);
   · a screen (the hub, the room) comes up from black the same way — the room's cards one by one, brightened at first;
   · 正在加入同盟…: a light runs along the bottom edge while the room is being opened;
   · in the room: 选择模拟协议 and ⚙ slide in and out, 搜寻中 fades in over the right with its lines one by one,
     搜寻成功 breaks in with green glitch bars before its lines draw down to the seats, a doctor turning 已就绪 flashes
     green with a beam from the card's clip, the empty seats dim while searching;
   · the 已选定 stamp's ring is drawn, the difficulty picture is redrawn for each difficulty.
   Reduced motion: theme.css cuts every animation to 1 ms; the delays are dropped below and the hooks do not wait.
   ========================================================================================== */
:root { --tr-ease: cubic-bezier(.16, .84, .3, 1); }
@keyframes tr-fade { from { opacity: 0; } }
@keyframes tr-out { to { opacity: 0; } }
@keyframes tr-veil { from { background-color: transparent; } }
@keyframes tr-lift { to { background-color: transparent; } }
.ally-card__bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: .14rem;
  height: max(.74rem, 32px, calc(42px * var(--sp-ui, 1)));
  padding: 0 .2rem;
  font-family: inherit;
  font-size: calc(.3 * var(--t));
  font-weight: 900;
  letter-spacing: .06em;
  white-space: nowrap;
  text-align: left;
  color: #08221b;
  background: linear-gradient(180deg, #4fe8c0, #2fcf9f);
  border: 0;
}
/* the difficulty line wraps at the bar's right rather than ending in an ellipsis (§37.51: English 「Difficulty: Standard
   Simulat…」 at 1280–1440 px, Japanese at 1024×600 特大). It keeps a column of at least 10em beside the name, else it
   takes a row of its own under the name and the bar grows (§37.51 review: squeezed into the 96 px the name left in
   English at 特大 on 1024×600, six lines ran out of the 42 px bar); Korean breaks between words only (the review:
   「시뮬레이|션」 once balanced), Japanese by its line-breaking rules */
.ally-card--create .ally-card__bar { flex-wrap: wrap; align-content: center; row-gap: 1px; height: auto; min-height: max(.74rem, 32px, calc(42px * var(--sp-ui, 1)));
  padding-top: 4px; padding-bottom: 4px; }
.ally-card__bar small { flex: 0 1 auto; margin-left: auto; min-width: min(100%, 10em); white-space: normal; text-align: right; text-wrap: balance;
  line-height: 1.2; font-size: calc(.14 * var(--t)); font-weight: 700; letter-spacing: 0; color: rgba(8, 34, 27, .75); }
.ally-card__bar small:lang(ko) { word-break: keep-all; overflow-wrap: break-word; }
.ally-card__bar small:lang(ja) { line-break: strict; }
button.ally-card:disabled { cursor: default; }
button.ally-card:disabled .ally-card__bar { filter: grayscale(.5) brightness(.8); }
/* the test-room box under 创建同盟 (test mode only) */
.ally-test { padding: 0 .2rem; }
.ally-card__bar--join { width: 100%; color: #2a1404; background: linear-gradient(180deg, #ffb24f, #f08a26); }
.ally-card__bar--join:disabled { filter: grayscale(.6) brightness(.75); cursor: default; }
.ally-card__bar--join:hover:not(:disabled), .ally-card__bar--join:focus-visible { filter: brightness(1.06); }
.ally-card__icon { flex: none; display: grid; place-items: center; width: max(.36rem, 22px); height: max(.36rem, 22px); color: currentColor; background: rgba(0, 0, 0, .14); border: 2px solid currentColor; border-radius: 4px; }
.ally-card__icon .icon { width: 74%; height: 74%; }
/* the key field: the project's TextField (.field / .field__box / .field__input) restyled as the event's grey bar, with
   观战 beside it inside the same bar */
.ally-key {
  display: flex;
  align-items: center;
  gap: .1rem;
  height: max(.56rem, 32px, calc(34px * var(--sp-ui, 1)));
  margin: .06rem .2rem .08rem;
  padding: 0 .06rem 0 .12rem;
  background: #262929;
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: .06rem;
}
.ally-key:focus-within { border-color: #ff9a3c; }
.ally-key .field { flex: 1 1 auto; height: 100%; gap: 0; }
.ally-key .field__box { height: 100%; padding: 0; gap: .1rem; background: none; border: 0; box-shadow: none; }
.ally-key .field__box::after { display: none; }
.ally-key .field__icon { flex: none; width: max(.24rem, 15px); height: max(.24rem, 15px); color: #c9cecc; }
.ally-key .field__box:focus-within .field__icon { color: #ff9a3c; }
.ally-key input {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  font: inherit;
  font-size: calc(.22 * var(--t));
  font-weight: 700;
  letter-spacing: .08em;
  text-align: center;
  text-transform: uppercase;
  text-overflow: ellipsis;
  color: #f2f4f3;
  background: none;
  border: 0;
  outline: none;
}
.ally-key input::placeholder { color: #8d9391; font-family: inherit; font-size: calc(.22 * var(--t)); font-weight: 500; letter-spacing: .04em; text-transform: none; }
.ally-key__spec {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: .04rem;
  height: 80%;
  padding: 0 .12rem;
  font: inherit;
  font-size: calc(.15 * var(--t));
  color: #eef0ef;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 4px;
}
.ally-key__spec:hover:not(:disabled), .ally-key__spec:focus-visible { border-color: rgba(255, 255, 255, .5); }
.ally-key__spec:disabled { opacity: .45; cursor: default; }
.ally-key__spec .icon { width: 1.1em; height: 1.1em; }
.ally-recent { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .06rem .1rem; min-height: .3rem; margin: 0 .2rem .1rem; font-size: calc(.14 * var(--t)); text-align: center; }
.code-chip {
  padding: .03rem .12rem .03rem .16rem;
  border: 1px solid var(--line-2);
  background: rgba(0, 0, 0, .3);
  color: var(--amber);
  font-size: calc(.17 * var(--t));
  font-weight: 700;
  letter-spacing: .2em;
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.code-chip:hover { border-color: var(--amber); background: rgba(246, 163, 41, .08); }

/* ---- 选择模拟协议's cards when they do not fit their column (screens/lobby.js pickCardFit: data-fit), above 520 px tall --
   (§37.18's leftover there: at 大 / 特大, in a small window or a long language the list ran under 开始独立模拟 with 终极模拟
   out of view.) 'brief': the description only in the brief at the left, where the chosen difficulty's already is;
   'names': a line each, and the brief adds the chosen difficulty's effects and rounds. At both, the chosen card's name
   ends in an ellipsis beside the stamp should a long language need it (the brief names it in full); the names stop at
   .36rem (base rule: at 特大 in a 1024 px window English ran past the cards). The short-screen block below has its own
   one-line cards. [ASSUMED] the levels and the sizes */
.proto-brief__more { display: none; }
@media (min-height: 521px) {
  .proto__body[data-fit="brief"] .pcard__desc,
  .proto__body[data-fit="names"] .pcard__desc, .proto__body[data-fit="names"] .pcard__effects, .proto__body[data-fit="names"] .pcard__meta { display: none; }
  .proto__body[data-fit="names"] .pcard { padding-top: .08rem; padding-bottom: .08rem; }
  .proto__body[data-fit="brief"] .pcard__head, .proto__body[data-fit="names"] .pcard__head { min-width: 0; }
  .proto__body[data-fit="brief"] .pcard__glyph, .proto__body[data-fit="names"] .pcard__glyph { flex: none; }
  .proto__body[data-fit="brief"] .pcard__name, .proto__body[data-fit="names"] .pcard__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; line-height: 1.3; }
  .proto__body[data-fit="names"] .pcard.is-on .pcard__head { padding-right: max(.9rem, calc(46px * var(--sp-ui, 1))); }
  .proto__body[data-fit="names"] .pcard.is-on .pcard__stamp { right: .1rem; width: max(.8rem, 32px, calc(40px * var(--sp-ui, 1))); height: max(.64rem, 32px, calc(34px * var(--sp-ui, 1))); }
  .proto__body[data-fit="names"] .pcard.is-on .pcard__tick { width: max(.4rem, 22px); height: max(.4rem, 22px); }
  .proto__body[data-fit="names"] .pcard__ok { display: none; }
  .proto__body[data-fit="names"] .proto-brief__more { display: flex; flex-direction: column; gap: .04rem; margin-top: .06rem; padding-top: .06rem; border-top: 1px solid rgba(255, 255, 255, .18); }
  .proto-brief__effects { display: flex; flex-direction: column; font-size: calc(.16 * var(--t)); line-height: 1.4; color: #e9eceb; }
  .proto-brief__effects span::before { content: '·'; margin-right: .06rem; }
  .proto-brief__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .04rem .14rem; font-size: calc(.13 * var(--t)); color: #7f8583; }
  .proto-brief__meta b { color: #cfd3d1; }
}

/* ---- narrow windows: the dialogs stack their halves ------------------------------------------------- */
@media (max-aspect-ratio: 1/1) {
  .proto-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, .7fr) minmax(0, 1.3fr); }
  .ally-body { grid-template-rows: minmax(0, .5fr) minmax(0, 1.5fr); }
  .proto__pic { inset: 0 0 .9rem; }
  /* the list keeps the .5rem the chosen card slides into (§37.51: at .1rem its -.44rem ran past the screen's left edge) */
  .proto-foot { padding-left: .1rem; }
  .ally-side { padding-left: 0; }
  /* the cards and the button span the width here: the caps for the landscape column (a 5.6rem column) give way */
  .pcard__name { font-size: calc(.28 * var(--t)); }
  .proto-foot .proto-start__label { font-size: calc(.4 * var(--t)); }
  .proto-foot .proto-start__rook { font-size: calc(.36 * var(--t)); }
}

/* ---- short landscape phones (≤ 520 CSS px tall) ---------------------------------------------------------- */
/* The hub drops its left column and the radar; the dialogs keep the four cards and the button in view without scrolling
   at every 文字大小 (the cards keep only their names, the selected difficulty's description moves to the brief). */
@media (max-height: 520px) {
  /* the entries span the screen's width here: at least 128 px each, so a wrapped English name has a line of its own
     (at 2.1rem, 84 px, 「Simulation」 was 95 px at 小). [ASSUMED] the width */
  .lobby-hub { --hub-entry-w: max(2.1rem, 32px, calc(128px * var(--sp-ui, 1))); }
  .hub-stage {
    grid-template-columns: minmax(0, 1fr) minmax(0, calc(var(--hub-entry-w) * 2 + var(--hub-gap)));
    grid-template-areas: "center right" "entries entries";
    gap: .14rem .3rem;
    padding: .1rem .4rem .24rem;
  }
  .hub-center { grid-column: 1; }
  .hub-side, .hub-radar { display: none; }
  .hub-center__mark { min-height: 0; margin-bottom: 0; }
  .hub-center__logo { width: .9rem; }
  .hub-center__mark .emblem__svg { width: .9rem; height: 1rem; }
  .hub-center__title { max-width: none; font-size: calc(.46 * var(--t)); }
  .hub-right { padding-top: .1rem; }
  .lobby-hub .hub-plate { min-height: max(.7rem, 32px, calc(40px * var(--sp-ui, 1))); }
  .lobby-hub .hub-plate--ach { display: flex; }
  /* (here the hub's height is the limit: a top padding for the icon made the English and Korean cards so tall at 大 /
     特大 that the line above them ran into the title on a 640 / 740 px phone. The decorative line keeps clear of the icon
     beside it instead, .44rem — at 小 it stays on one line there in every language) */
  .hub-entry { min-height: max(1.1rem, 32px, calc(64px * var(--sp-ui, 1))); padding: .1rem .14rem; }
  .hub-entry__icon .icon { width: .42rem; height: .42rem; }

  .proto-top { padding-top: 8px; }
  /* 选择模拟协议 (§37.18's leftover: at 文字大小 中 and above the four cards ran under 开始独立模拟 — 终极模拟 out of sight,
     the label cut — in every language, 844×390 and smaller): a wider column (7.4rem as 选择同盟方式's, 296 px here), the cards one
     line each — the name, 16–20 px, an ellipsis in the chosen card of a long language (the brief names it in full) —, the
     chosen difficulty's description in the brief at the left (11–13 px, the event's own place for it, as on a desktop),
     the header and the label capped (below) and the label wrapping onto a second line rather than being cut. The list
     still scrolls should a pack's names not fit. [ASSUMED] every cap */
  /* the column and the brief keep their unscaled widths under 界面大小 (÷ --sp-ui): the names' 16 px floor, the brief's
     11 px floor and the px paddings and stamp space do not shrink, so at 75 % a 222 px column cut 'Perilous Simulation'
     in English and the brief broke a Korean word (DESIGN §37.47) */
  .proto-body { grid-template-columns: minmax(0, 1fr) min(calc(7.4rem / var(--sp-ui, 1)), 50vw); gap: 10px; padding-bottom: 10px; }
  .ally-body { grid-template-columns: minmax(0, 1fr) min(calc(7.4rem / var(--sp-ui, 1)), 54vw); }
  .proto__pic { inset: 0 0 1.6rem; }
  .proto-brief { max-width: min(calc(6.4rem / var(--sp-ui, 1)), 100%); padding: 6px 10px 7px; }
  .proto-brief p { margin-top: 2px; font-size: clamp(11px, calc(.26 * var(--t)), 13px); line-height: 1.35; }
  .proto-list { gap: 6px; padding-left: 22px; justify-content: flex-start; }
  .pcard { padding: 6px 10px; gap: 2px; border-radius: 10px; }
  .pcard.is-on { transform: translateX(-16px); }
  .pcard__desc, .pcard__effects, .pcard__meta { display: none; }
  .pcard__head { min-width: 0; }
  .pcard__glyph { flex: none; }
  .pcard__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; line-height: 1.3; }
  .pcard.is-on .pcard__head { padding-right: 46px; }
  .pcard.is-on .pcard__stamp { right: 6px; width: 40px; height: 34px; }
  .pcard.is-on .pcard__tick { width: 22px; height: 22px; }
  .pcard__ok { display: none; }
  .proto-foot { padding-left: 22px; }
  .proto-hint { display: none; }
  .proto-start { height: auto; min-height: 44px; gap: 10px; padding: 3px 0 3px 10px; }
  .proto-start__label { letter-spacing: .02em; }
  /* a column still taller than its space (a long language, the recent keys, the test-room box) scrolls rather than being
     cut off; the 4 px pad on the three other sides keeps the focus ring and the shadows inside the clip */
  .ally-side { gap: 8px; margin: -4px -4px -4px 0; padding: 4px 4px 4px 10px; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; }
  .ally-card__art { display: none; }
  .ally-key { margin: 6px 10px; }
  .ally-recent { margin: 0 10px 6px; }
  .mf-radar { inset: 0 0 .6rem; height: calc(100% - .6rem); }
  /* 1rem is ~40 px here: the text gets its own sizes (still following 文字大小) */
  .hub-center__en { font-size: calc(.24 * var(--t)); }
  /* the plates' labels, the entries' names and their decorative English capped so they stay whole (§37.18 review: at 大 /
     特大 the plates ended in an ellipsis and the entries cut both lines); each cap is its size at 中 and grows a pixel a
     step above it (--t-step, theme.css), the entries 7 px wider a step for the name's longest word (「Simulation」 ~6.2em).
     [ASSUMED] the caps */
  .lobby-hub .hub-plate { font-size: min(calc(.3 * var(--t)), calc(18px + var(--t-step))); }
  .hub-plate__tag { display: none; }
  .hub-entry__group { height: auto; font-size: calc(.22 * var(--t)); }
  /* 同盟模拟's line keeps only 「1–4 名博士」 here (§37.51: the whole line, nowrap, ran 81–320 px past its entry at 特大 —
     two to four lines if it wrapped; the AI teammates are the room's to show) */
  .hub-entry__long { display: none; }
  .hub-entry__short { display: inline; }
  .hub-entry { width: calc(var(--hub-entry-w) + 7 * max(0px, var(--t-step))); }
  .hub-entry__en { padding-right: .44rem; font-size: min(calc(.16 * var(--t)), calc(10px + var(--t-step))); letter-spacing: .12em; }
  .hub-entry__name { font-size: min(calc(.42 * var(--t)), calc(18px + var(--t-step))); }
  .proto-title .modal__title { font-size: min(calc(.46 * var(--t)), 24px); white-space: nowrap; }
  .proto-title__mode, .proto-title__mode i { font-size: min(calc(.24 * var(--t)), 16px); }
  /* the mode line stays one line at a big 文字大小 in a long language (en 特大 broke 「Team Simulation」 in two, the
     header growing by a line the column needs): the decorative ALLIANCE / SOLO SIMULATION stops at 15 px [ASSUMED] and
     drops under as a whole if it still does not fit */
  .proto-title__mode { flex-wrap: wrap; justify-content: flex-end; row-gap: 0; white-space: nowrap; }
  .proto-title__mode i { font-size: min(calc(.24 * var(--t)), 15px); }
  .proto-brief__code { font-size: min(calc(.22 * var(--t)), 14px); }
  .proto-brief__name { font-size: min(calc(.34 * var(--t)), 20px); }
  .pcard__name { font-size: clamp(16px, calc(.4 * var(--t)), 20px); }
  .proto-foot .proto-start__label { font-size: min(calc(.5 * var(--t)), 20px); }
  .proto-foot .proto-start__rook { font-size: min(calc(.36 * var(--t)), 16px); }
  .proto-foot .proto-start__mark small { font-size: min(calc(.08 * var(--t)), 6px); }
  /* the bars' names 16–26 px here ([ASSUMED] the cap: en 「Create Alliance」 on its row at 特大, the column on the screen) */
  .ally-card__bar { font-size: clamp(16px, calc(.3 * var(--t)), 26px); }
  /* 创建同盟 keeps its difficulty line (§37.18's leftover: it was hidden here): two columns, the icon and the name on the
     first row, the line under the name on the second, wrapping rather than cut short; 11–14 px, [ASSUMED] the cap */
  .ally-card--create .ally-card__bar { display: grid; grid-template-columns: auto minmax(0, 1fr); align-content: center; row-gap: 1px; height: auto;
    min-height: max(.74rem, 32px, calc(42px * var(--sp-ui, 1))); padding-top: 5px; padding-bottom: 5px; }
  .ally-card--create .ally-card__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; line-height: 1.2; }
  .ally-card--create .ally-card__bar small { grid-column: 2; margin-left: 0; overflow: visible; white-space: normal; text-align: left; font-size: clamp(11px, calc(.28 * var(--t)), 14px); line-height: 1.3; }
  .ally-key input { font-size: calc(.32 * var(--t)); }
  /* the key field's placeholder fits beside 观战 (§37.18's leftover: clipped at 特大 in English and Japanese): the short
     text (screens/lobby.js AllianceSelect `short`), 11–13 px, and 观战 at most 14 px; an ellipsis should a pack's
     name still be longer. [ASSUMED] the caps */
  .ally-key input::placeholder { font-size: clamp(11px, calc(.26 * var(--t)), 13px); }
  /* the empty field takes the placeholder's size, so the placeholder sits in the middle like the key will (§37.51: on the
     28 px key's baseline it sat 6–9 px below the key icon and 观战 at 特大) */
  .ally-key input:placeholder-shown { font-size: clamp(11px, calc(.26 * var(--t)), 13px); }
  .ally-key__spec { font-size: min(calc(.26 * var(--t)), 14px); }
  .ally-recent { font-size: min(calc(.24 * var(--t)), 14px); line-height: 1.35; } /* [ASSUMED] the cap, like the difficulty line's */
  .code-chip { font-size: calc(.28 * var(--t)); }
  .ally-guide { font-size: calc(.3 * var(--t)); }
}
/* ---- 转场 (PR #643, the event's screen changes): a screen comes up from black, its panels slide in one after another ---- */
.lobby-hub, .modal__box.proto, .modal__box.ally { --tr-ease: cubic-bezier(.16, .84, .3, 1); }
@keyframes tr-fade { from { opacity: 0; } }
@keyframes tr-veil { from { background-color: transparent; } }
@keyframes tr-right { from { opacity: 0; transform: translateX(.36rem); } }
@keyframes tr-left { from { opacity: 0; transform: translateX(-.36rem); } }
@keyframes tr-rise { from { opacity: 0; transform: translateY(.22rem); } }
@keyframes tr-zoom { from { opacity: 0; transform: scale(1.04); } }
@keyframes tr-pop { from { opacity: 0; transform: scale(.4); } }
@keyframes tr-card { from { opacity: 0; transform: translateY(.16rem) scale(1.03); filter: brightness(1.9) saturate(.3); } 55% { filter: none; } }
@keyframes tr-diamond { 0% { opacity: 0; transform: translateX(-50%) rotate(45deg) scale(.5); } 30%, 72% { opacity: 1; transform: translateX(-50%) rotate(45deg) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) rotate(45deg) scale(1.1); } }
@keyframes tr-draw { to { stroke-dashoffset: 0; } }

/* ---- full-screen overlays over the hub ---- */
.sw { background-color: #080909; } /* the black it comes up from (the misty field is .sw__bg) */
.proto, .sw { animation: tr-veil 150ms linear backwards; }
.proto.is-chained { animation: none; }
.proto__bg, .sw__bg { animation: tr-fade 340ms ease-out 140ms backwards; }
.proto-top, .sw-top { animation: tr-fade 260ms ease-out 170ms backwards; }
.proto-title, .sw-tabs { animation: tr-right 400ms var(--tr-ease) 200ms backwards; }
.proto-stage, .ally-stage { animation: tr-zoom 480ms var(--tr-ease) 190ms backwards; }
.proto-list .pcard { animation: tr-right 400ms var(--tr-ease) backwards; animation-delay: calc(240ms + var(--n, 0) * 60ms); }
.proto-list .pcard:nth-child(2) { --n: 1; } .proto-list .pcard:nth-child(3) { --n: 2; } .proto-list .pcard:nth-child(4) { --n: 3; } .proto-list .pcard:nth-child(5) { --n: 4; }
.proto-foot { animation: tr-rise 400ms var(--tr-ease) 440ms backwards; }
.ally-card--create { animation: tr-right 420ms var(--tr-ease) 240ms backwards; }
.ally-links { animation: tr-right 420ms var(--tr-ease) 310ms backwards; }
.ally-card--join { animation: tr-right 420ms var(--tr-ease) 380ms backwards; }
.ally-guide { animation: tr-rise 380ms var(--tr-ease) 450ms backwards; }
.sw-left { animation: tr-left 440ms var(--tr-ease) 230ms backwards; }
.sw-right { animation: tr-right 440ms var(--tr-ease) 280ms backwards; }
.sw-right > * { animation: tr-fade 260ms ease-out backwards; } /* a tab's tiles come up when it is opened */
/* the diamond at the bottom while it loads */
.proto::after, .sw::after { content: ''; position: absolute; left: 50%; bottom: max(.5rem, 24px); z-index: 9; width: max(.3rem, 16px); height: max(.3rem, 16px);
  border: 2px solid rgba(223, 230, 226, .55); box-shadow: inset 0 0 0 3px #0a0b0b, inset 0 0 0 5px rgba(223, 230, 226, .3); pointer-events: none; opacity: 0;
  animation: tr-diamond 720ms ease-out 60ms both; }
.proto.is-chained::after { animation-delay: 0ms; }
/* leaving: the content fades, then the black lifts off the hub (LEAVE_MS 300 = 130 + 170) */
.proto.is-leaving, .sw.is-leaving { pointer-events: none; animation: tr-lift 170ms linear 130ms forwards; }
.proto.is-leaving > *, .sw.is-leaving > * { animation: tr-out 140ms ease-in forwards; }
.proto.is-leaving::after, .sw.is-leaving::after { display: none; }

/* 正在加入同盟… */
.tr-join { position: absolute; left: 0; right: 0; bottom: 0; z-index: 8; display: flex; align-items: center; gap: .1rem; padding: 0 max(.24rem, 12px) max(.05rem, 3px);
  font-size: calc(.19 * var(--t)); font-weight: 700; letter-spacing: .04em; color: #5df0c6; text-shadow: 0 0 .12rem rgba(93, 240, 198, .45); pointer-events: none;
  animation: tr-fade 200ms ease-out backwards; }
.tr-join::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; transform-origin: left;
  background: linear-gradient(90deg, rgba(93, 240, 198, .2), #5df0c6 40%, #c9fff0 50%, #5df0c6 60%, rgba(93, 240, 198, .2)); box-shadow: 0 0 10px #5df0c6;
  animation: tr-run 1.4s var(--tr-ease) both; }
@keyframes tr-run { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.tr-join__mark { width: max(.24rem, 14px); height: max(.24rem, 14px); flex: none; border: 2px solid currentColor; border-radius: 3px;
  background: linear-gradient(currentColor, currentColor) center / 40% 40% no-repeat; animation: spin 1.4s steps(8) infinite; }
.tr-join__dots { display: inline-block; width: 0; overflow: hidden; white-space: nowrap; vertical-align: bottom; animation: tr-dots 1.2s steps(4, jump-none) infinite; }
.tr-join__dots::before { content: '...'; }
@keyframes tr-dots { to { width: 1.1em; } }

/* the stamp's ring is drawn; the difficulty picture comes up again for each difficulty */
.pcard.is-on .pcard__ring path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: tr-draw 380ms ease-out 90ms forwards; }
.pcard.is-on .pcard__ring path + path { animation-delay: 260ms; }
.ps { animation: tr-fade 320ms ease-out backwards; }

/* ---- the hub comes up from black ---- */
.lobby-hub .hub-bg { animation: tr-fade 560ms ease-out backwards; }
.lobby-hub > .topbar { animation: tr-fade 320ms ease-out 120ms backwards; } /* opacity only: its dialogs are fixed */
.hub-center { animation: tr-zoom 600ms var(--tr-ease) 140ms backwards; }
.hub-side { animation: tr-left 480ms var(--tr-ease) 220ms backwards; }
.hub-right { animation: tr-right 480ms var(--tr-ease) 260ms backwards; }
.hub-entries .hub-entry-wrap { animation: tr-rise 440ms var(--tr-ease) 300ms backwards; }
.hub-entries .hub-entry-wrap:nth-child(2) { animation-delay: 360ms; }
.hub-entries .hub-entry-wrap:nth-child(3) { animation-delay: 420ms; }
.hub-entries .hub-entry-wrap:nth-child(4) { animation-delay: 480ms; }

/* ---- the room comes up from black, card by card ---- */
.rs__bg { animation: tr-fade 440ms ease-out backwards; }
.rs-top { animation: tr-fade 320ms ease-out 120ms backwards; }
.rseat { animation: tr-card 480ms var(--tr-ease) backwards; animation-delay: calc(150ms + var(--i, 0) * 70ms); }
.rs--big .rseat { animation-delay: calc(150ms + var(--i, 0) * 35ms); }
.rs-brief { animation: tr-right 440ms var(--tr-ease) 260ms backwards; }
.rs-foot { animation: tr-rise 420ms var(--tr-ease) 300ms backwards; }
.rs-foot__right { animation: tr-right 440ms var(--tr-ease) 380ms backwards; }
.rs.is-leaving { pointer-events: none; }
.rs.is-leaving > * { animation: tr-out 200ms ease-in forwards; }
/* searching: the empty seats step back */
.rseat--empty { transition: opacity 320ms ease; }
.rseat--empty.is-searching { opacity: .5; }

/* 已就绪: a green flash over the portrait, a beam from the clip, the state pops */
.rseat.is-flash .rseat__art { animation: tr-glow 700ms ease-out; }
@keyframes tr-glow { 20% { box-shadow: 0 0 .5rem rgba(120, 255, 215, .9), 0 0 .12rem #b9ffe9; border-color: #b9ffe9; } }
.rseat.is-flash .rseat__art::before { content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(180deg, rgba(214, 255, 243, .95), rgba(79, 232, 192, .7)); animation: tr-wash 700ms ease-out forwards; }
@keyframes tr-wash { 0% { opacity: 0; } 14% { opacity: 1; } 100% { opacity: 0; } }
.rseat.is-flash .rseat__clip::after { content: ''; position: absolute; left: 50%; bottom: 100%; width: 6px; height: .16rem; transform-origin: 50% 100%;
  background: linear-gradient(0deg, #c9fff0, rgba(93, 240, 198, 0)); box-shadow: 0 0 8px #5df0c6; animation: tr-beam 700ms ease-out forwards; }
@keyframes tr-beam { 0% { opacity: 0; transform: translateX(-50%) scaleY(0); } 22% { opacity: 1; transform: translateX(-50%) scaleY(1); }
  100% { opacity: 0; transform: translateX(-50%) scaleY(1.3); } }
.rseat.is-flash .rseat__state { animation: tr-pop 380ms cubic-bezier(.3, 1.7, .5, 1) 100ms backwards; }

/* 选择模拟协议 over the room; ⚙ */
.rs-proto { animation: tr-veil 160ms linear backwards; }
.rs-proto__scene { animation: tr-fade 360ms ease-out 100ms backwards; }
.rs-proto__side { animation: tr-right 380ms var(--tr-ease) 60ms backwards; }
.rs-proto .proto-list .pcard { animation-delay: calc(110ms + var(--n, 0) * 50ms); }
.rs-proto.is-leaving { pointer-events: none; animation: tr-lift 200ms linear forwards; }
.rs-proto.is-leaving > * { animation: tr-slide-out 200ms ease-in forwards; }
@keyframes tr-slide-out { to { opacity: 0; transform: translateX(.36rem); } }
.rs-opts { transform-origin: 50% 100%; animation: tr-pop-up 200ms var(--tr-ease) backwards; }
@keyframes tr-pop-up { from { opacity: 0; transform: translateX(-50%) translateY(.12rem) scale(.96); } }
.rs-opts.is-leaving { pointer-events: none; animation: tr-pop-down 150ms ease-in forwards; }
@keyframes tr-pop-down { to { opacity: 0; transform: translateX(-50%) translateY(.08rem) scale(.97); } }

/* 搜寻中: the panel fades in over the right, its lines one after another */
.rs-searchpanel.mf-search { animation: tr-fade 260ms ease-out backwards; }
.mf-search > * { animation: tr-right 400ms var(--tr-ease) backwards; animation-delay: 60ms; }
.mf-search > :nth-child(2) { animation-delay: 110ms; }
.mf-search > :nth-child(3) { animation-delay: 160ms; }
.mf-search > :nth-child(4) { animation-delay: 210ms; }
.mf-search > :nth-child(5) { animation-delay: 260ms; }
.mf-search > :nth-child(6) { animation-delay: 300ms; }
.mf-search > :nth-child(7) { animation-delay: 340ms; }
.mf-search.is-leaving { pointer-events: none; animation: tr-out 200ms ease-in forwards; }

/* 搜寻成功: green glitch bars, the panel wiped in bright, then the lines, the face, the words */
.mf-found { position: relative; isolation: isolate; overflow: hidden;
  animation: tr-found 380ms var(--tr-ease) backwards, tr-found-glow 1.8s ease-in-out 700ms infinite alternate; }
@keyframes tr-found { 0% { clip-path: inset(0 0 0 100%); filter: brightness(2.4) saturate(.6); } 55% { clip-path: inset(0); filter: brightness(1.7); }
  100% { clip-path: inset(0); filter: none; } }
@keyframes tr-found-glow { from { box-shadow: inset 0 -.2rem .5rem -.2rem rgba(150, 255, 222, .2); } to { box-shadow: inset 0 -.5rem .9rem -.2rem rgba(150, 255, 222, .6); } }
.mf-found::before, .mf-found::after { content: ''; position: absolute; left: 0; right: 0; z-index: 4; pointer-events: none; opacity: 0;
  background: repeating-linear-gradient(0deg, rgba(225, 255, 246, .5) 0 1px, transparent 1px 3px), linear-gradient(90deg, #2fd6a6, #7bffd8 40%, #2fd6a6); }
.mf-found::before { top: 6%; height: 38%; animation: tr-glitch-a 560ms steps(1, end) backwards; }
.mf-found::after { top: 52%; height: 30%; animation: tr-glitch-b 560ms steps(1, end) backwards; }
@keyframes tr-glitch-a { 0% { opacity: 1; transform: translateX(30%); } 14% { opacity: 1; transform: translateX(-8%) scaleY(1.2); } 28% { opacity: .85; transform: translateX(12%) scaleY(.5); }
  42% { opacity: .6; transform: translateX(-4%); } 56% { opacity: .9; transform: scaleY(.2); } 70%, 100% { opacity: 0; transform: none; } }
@keyframes tr-glitch-b { 0% { opacity: 0; } 10% { opacity: .95; transform: translateX(-24%); } 24% { opacity: .95; transform: translateX(10%) scaleY(.6); }
  38% { opacity: .7; transform: translateX(-6%) scaleY(1.3); } 52% { opacity: .4; transform: none; } 64%, 100% { opacity: 0; transform: none; } }
.mf-found > .mf-brand { animation: tr-fade 260ms ease-out 260ms backwards; }
.mf-found__lines { animation: tr-fade 200ms ease-out 240ms backwards; }
.mf-found__lines path { animation-delay: calc(260ms + var(--k) * 40ms); }
.mf-found__face { animation: tr-pop 460ms cubic-bezier(.3, 1.7, .5, 1) 420ms backwards; }
.mf-found__title { animation: tr-rise 320ms var(--tr-ease) 520ms backwards; }
.mf-found__sub { animation: tr-fade 300ms ease-out 620ms backwards; }
.mf-found.is-leaving { animation: tr-out 320ms ease-in forwards; }

@media (prefers-reduced-motion: reduce) {
  .proto, .sw, .proto *, .sw *, .proto::after, .sw::after, .lobby-hub *, .rs *, .rs__bg, .mf-found, .mf-found::before, .mf-found::after { animation-delay: 0ms !important; }
  .proto::after, .sw::after, .mf-found::before, .mf-found::after, .tr-join::after { display: none; }
}

/* ==========================================================================================
   成就统计 (js/ui/achievements.js; the event video 1:25–1:44): the hub's top-left entry card and the
   卫戍协议：盟约 panel. Sizes are the video's 1920-wide pixels / 100.
   ========================================================================================== */
.hub-ach { position: relative; width: 100%; display: flex; flex-direction: column; margin-bottom: .1rem; padding: 0; cursor: pointer; text-align: left; color: #eef3f1;
  background: #0c1110; border: 1px solid rgba(220, 230, 226, .16); box-shadow: 0 .04rem .16rem rgba(0, 0, 0, .45); transition: border-color var(--t-fast, 150ms), filter var(--t-fast, 150ms); }
.hub-ach:hover, .hub-ach:focus-visible { border-color: var(--mint-a35, rgba(78, 216, 175, .35)); filter: brightness(1.08); outline: none; }
.hub-ach:focus-visible { box-shadow: 0 0 0 2px var(--mint-400); }
.hub-ach__scene { position: relative; height: .88rem; overflow: hidden; display: grid; place-items: center; }
.hub-ach__land { position: absolute; inset: 0; width: 100%; height: 100%; }
.hub-ach__scene::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .18) 0 1px, transparent 1px 3px), linear-gradient(90deg, rgba(8, 10, 10, .55), transparent 40%); }
.hub-ach .hub-ach__mark { position: relative; z-index: 1; display: grid; place-items: center; }
.hub-ach .hub-ach__mark .emblem { margin: 0; gap: .06rem; animation: none; }
.hub-ach .hub-ach__mark .emblem__svg { width: .52rem; height: .56rem; filter: drop-shadow(0 0 .04rem rgba(0, 0, 0, .6)); }
.hub-ach .hub-ach__mark .emblem__svg circle { fill: #15110c; animation: none; }
.hub-ach .hub-ach__mark .emblem__svg circle.is-accent { fill: #2cf0b8; }
.hub-ach .hub-ach__mark .emblem__bracket { height: .66rem; width: .07rem; border-width: 1px; border-color: rgba(20, 16, 10, .55); }
.hub-ach__rank { position: absolute; left: .1rem; top: .1rem; z-index: 1; width: .52rem; display: flex; flex-direction: column; align-items: center; gap: .01rem; padding: .04rem 0 .03rem;
  background: rgba(14, 18, 17, .55); border: 1px solid rgba(240, 244, 243, .4); }
.hub-ach__rank > .icon { width: .3rem; height: .3rem; color: #eef3f1; }
.hub-ach__rank small { display: inline-flex; align-items: center; gap: .02rem; font-size: calc(.13 * var(--t)); color: #e6ebe9; }
.hub-ach__rank small .icon { width: .12rem; height: .12rem; }
.hub-ach__label { position: relative; display: flex; align-items: center; gap: .08rem; height: .42rem; padding: 0 .14rem; background: linear-gradient(90deg, rgba(20, 26, 25, .96), rgba(14, 18, 17, .96));
  border-top: 1px solid rgba(220, 230, 226, .14); font-size: calc(.21 * var(--t)); font-weight: 700; white-space: nowrap; }
.hub-ach__label::before, .hub-ach__label::after { content: ''; position: absolute; top: .06rem; bottom: .06rem; width: .06rem; border: 1px solid rgba(220, 230, 226, .3); }
.hub-ach__label::before { left: .04rem; border-right: 0; }
.hub-ach__label::after { right: .04rem; border-left: 0; }
.hub-ach__badge { width: .24rem; height: .24rem; fill: #e8eeec; flex: none; }
.hub-ach__lv { margin-left: auto; font-size: calc(.15 * var(--t)); color: var(--mint-400); font-weight: 600; }
/* a guest: the achievements are the account's (2026-10-14) */
.hub-ach__login { color: #b9c2bf; }
.hub-ach.is-guest .hub-ach__scene { filter: saturate(.55) brightness(.8); }

/* ---- the panel ---- */
/* the reference clip's order: the lobby blurs at once, a diamond loader while the data comes, then the panel fades in */
.ach { position: fixed; inset: 0; z-index: var(--z-modal); display: grid; place-items: center; background: rgba(2, 4, 4, .62); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); animation: ach-fade 140ms both; }
.ach.is-closing { animation: ach-fade 180ms reverse forwards; }
@keyframes ach-fade { from { opacity: 0; } }
.ach__loader { position: absolute; left: 50%; bottom: 9%; width: .9rem; height: .9rem; margin-left: -.45rem; display: grid; place-items: center; pointer-events: none; }
.ach__loader i, .ach__loader b { grid-area: 1 / 1; transform: rotate(45deg); }
.ach__loader i { width: .56rem; height: .56rem; border: 2px solid rgba(240, 244, 243, .9); animation: ach-dia 1.1s var(--ease-out) infinite; }
.ach__loader i + i { animation-delay: .55s; }
.ach__loader b { width: .24rem; height: .24rem; border: 2px solid #f4f7f6; animation: ach-dia-core 1.1s linear infinite; }
@keyframes ach-dia { from { transform: rotate(45deg) scale(.55); opacity: 1; } to { transform: rotate(45deg) scale(1.4); opacity: 0; } }
@keyframes ach-dia-core { to { transform: rotate(225deg); } }
.ach__box { position: relative; width: min(17.4rem, calc(100vw - 1.1rem)); height: min(9.06rem, calc(100dvh - .9rem)); display: flex; flex-direction: column;
  background: radial-gradient(60% 70% at 70% 60%, rgba(30, 70, 62, .3), transparent 70%), #0a0d0d; box-shadow: 0 0 0 1px rgba(220, 230, 226, .1), 0 .2rem .6rem rgba(0, 0, 0, .7);
  animation: ach-in 240ms var(--ease-out) both;
  --t: 1rem; /* laid out to the design's sizes: the 文字大小 boost made the plate and table text overlap */ }
@keyframes ach-in { from { opacity: 0; transform: scale(.985); } }
.ach__box::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .16) 0 1px, transparent 1px 4px); }
.ach__head { position: relative; flex: none; height: 1.27rem; display: flex; align-items: stretch; overflow: hidden;
  background: linear-gradient(180deg, #1b1f1e, #141716); border-bottom: 1px solid rgba(220, 230, 226, .08); }
.ach__head::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4.6rem; opacity: .35; pointer-events: none;
  background: linear-gradient(160deg, transparent 40%, rgba(150, 160, 158, .35) 41% 46%, transparent 47%), linear-gradient(200deg, transparent 50%, rgba(150, 160, 158, .3) 51% 55%, transparent 56%); }
.ach__logo { position: relative; display: flex; align-items: center; gap: .1rem; padding-left: .45rem; color: #a7b0ad; }
.ach__logo svg { width: .5rem; height: .38rem; }
.ach__logo b { font-family: var(--font-display); font-size: calc(.17 * var(--t)); line-height: .95; font-weight: 600; }
.ach__band { position: relative; margin-left: auto; width: 8.7rem; display: flex; align-items: center; gap: .3rem; padding-left: 2.2rem;
  background: linear-gradient(90deg, transparent, rgba(220, 128, 36, .82) 24%, #f0a23a 60%, #f3b04a); }
.ach__band::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(100deg, rgba(0, 0, 0, .08) 0 2px, transparent 2px 9px); }
.ach__dunes { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.ach__dunes path { fill: rgba(150, 64, 8, .3); }
.ach__dunes path.is-far { fill: rgba(255, 220, 150, .2); }
.ach__band .emblem { margin: 0; gap: .06rem; animation: none; }
.ach__band .emblem__svg { width: .7rem; height: .76rem; }
.ach__band .emblem__svg circle { fill: #15110c; animation: none; }
.ach__band .emblem__svg circle.is-accent { fill: #15110c; filter: none; }
.ach__band .emblem__bracket { height: .95rem; width: .1rem; border-width: 2px; border-color: rgba(20, 16, 10, .7); }
.ach__titles { position: relative; display: flex; flex-direction: column; line-height: 1.05; }
.ach__titles i { font-family: var(--font-display); font-style: normal; font-size: calc(.3 * var(--t)); letter-spacing: .06em; color: transparent; -webkit-text-stroke: 1px rgba(30, 22, 12, .6); }
.ach__titles b { font-size: calc(.38 * var(--t)); font-weight: 900; color: #16110a; white-space: nowrap; }
.ach__body { position: relative; z-index: 1; flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: .1rem .7rem .5rem .66rem; scrollbar-width: thin; scrollbar-color: rgba(220, 230, 226, .45) transparent; }
.ach__body::-webkit-scrollbar { width: .07rem; }
.ach__body::-webkit-scrollbar-thumb { background: rgba(220, 230, 226, .45); border-radius: .04rem; }
.ach__close { position: absolute; right: -.52rem; top: -.36rem; z-index: 2; width: .5rem; height: .5rem; display: grid; place-items: center; padding: 0; border: 0; background: none; color: #f4f7f6; cursor: pointer; }
.ach__close .icon { width: .5rem; height: .5rem; filter: drop-shadow(0 0 .04rem #000); }
.ach__close:hover, .ach__close:focus-visible { color: var(--mint-400); outline: none; }
.ach__foot { position: absolute; right: -.06rem; bottom: -.16rem; z-index: 2; padding: .06rem .16rem; font-size: calc(.2 * var(--t)); color: #e2e8e6; background: rgba(16, 22, 21, .94);
  box-shadow: inset 0 0 0 1px rgba(78, 216, 175, .35); }
@media (max-width: 1100px) { .ach__close { right: .06rem; top: .06rem; } }

/* the top area: plate + mode table | the 评语 hexagon */
.ach-top-area { display: grid; grid-template-columns: minmax(0, 9.1rem) minmax(0, 1fr); gap: .3rem; padding-top: .3rem; }
.ach-plate { display: flex; gap: .24rem; align-items: flex-start; }
.ach-card { position: relative; width: 6.15rem; height: 1.92rem; flex: none; display: flex; align-items: center; gap: .18rem; padding: .16rem; overflow: hidden; border-radius: .06rem;
  background: linear-gradient(118deg, #e23443 0 46%, #2b2e33 46% 50%, #f2f4f3 50% 56%, #2fb6c6 56%); }
.ach-card::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(0, 0, 0, .25), transparent 60%); pointer-events: none; }
.ach-card__ava { position: relative; z-index: 1; width: 1.6rem; height: 1.6rem; flex: none; display: grid; place-items: center; background: #1d2423; border: 2px solid #f4f7f6; }
.ach-card__ava img { width: 100%; height: 100%; object-fit: cover; }
.ach-card__glyph { font-size: calc(.7 * var(--t)); font-weight: 900; color: #4af2c4; }
.ach-card__lv { position: absolute; left: -.16rem; top: -.14rem; width: .5rem; height: .5rem; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: .9;
  border-radius: 50%; background: #111; border: 3px solid #ffd21e; color: #fff; }
.ach-card__lv b { font-family: var(--font-display); font-size: calc(.2 * var(--t)); }
.ach-card__lv small { font-size: calc(.09 * var(--t)); }
.ach-card__who { position: relative; z-index: 1; min-width: 0; display: flex; flex-direction: column; gap: .08rem; align-self: flex-start; padding-top: .16rem; }
.ach-card__name { font-size: calc(.3 * var(--t)); font-weight: 600; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 .02rem .04rem rgba(0, 0, 0, .5); }
.ach-card__tag { margin-left: .02rem; color: rgba(255, 255, 255, .8); font-weight: 400; }
.ach-card__id { align-self: flex-start; padding: .02rem .1rem; font-size: calc(.19 * var(--t)); color: #f0d6d8; background: rgba(120, 10, 20, .55); border-radius: .03rem; white-space: nowrap; }
.ach-card__brand { position: absolute; right: .16rem; bottom: .12rem; z-index: 1; font-family: var(--font-display); font-size: calc(.15 * var(--t)); line-height: .95; font-weight: 600; color: rgba(255, 255, 255, .85); text-align: right; }
/* 已获奖杯 / 获赞数, each with its badge */
.ach-counts { display: grid; grid-template-columns: auto auto; column-gap: .12rem; row-gap: .14rem; align-items: center; padding-top: .06rem; }
.ach-counts__badge { width: .64rem; height: .64rem; display: grid; place-items: center; }
.ach-counts__badge svg { width: 100%; height: 100%; }
.ach-counts__badge.is-trophy .tbadge { width: 100%; height: 100%; }
.ach-counts__badge.is-like rect { fill: #e8823a; stroke: #ffe2c6; stroke-width: 2; }
.ach-counts__ink { fill: #2a1606; }
.ach-counts__row { display: flex; flex-direction: column; line-height: 1.1; }
.ach-counts__row small { display: inline-flex; align-items: center; gap: .04rem; font-size: calc(.22 * var(--t)); color: #b9c2bf; white-space: nowrap; }
.ach-counts__row small .icon { width: .18rem; height: .18rem; }
.ach-counts__row b { font-family: var(--font-display); font-size: calc(.3 * var(--t)); color: #f4f7f6; }
.ach-modes { margin-top: .3rem; background: rgba(22, 32, 30, .55); }
.ach-modes__row { display: grid; grid-template-columns: 1.75rem repeat(3, minmax(0, 1fr)); align-items: center; height: 1.8rem; }
.ach-modes__row + .ach-modes__row .ach-modes__cell { border-top: 1px solid rgba(220, 230, 226, .1); }
.ach-modes__mode { height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .06rem; background: rgba(28, 92, 80, .42); color: #4af2c4; }
.ach-modes__mode .icon { width: .24rem; height: .24rem; }
.ach-modes__mode b { font-size: calc(.28 * var(--t)); white-space: nowrap; }
.ach-modes__cell { height: 1.2rem; display: flex; flex-direction: column; justify-content: center; padding-left: .3rem; }
.ach-modes__cell b { font-family: var(--font-display); font-size: calc(.42 * var(--t)); line-height: 1.05; color: #4af2c4; font-weight: 500; }
.ach-modes__cell small { font-size: calc(.25 * var(--t)); color: #a9b3b0; white-space: nowrap; }
.ach-hex { position: relative; min-height: 4.4rem; }
/* the reference's hexagon: six solid mint triangles, dark gaps, a ruler inside each outer edge, a dark hub, a soft glow */
.ach-hex__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 0 .14rem rgba(74, 242, 196, .3)); }
.ach-hex__seg polygon { fill: #5cd3b2; stroke: rgba(225, 255, 246, .32); stroke-width: 1.5; stroke-linejoin: round; }
.ach-hex__ticks line { stroke: rgba(8, 48, 38, .34); stroke-width: 2; }
.ach-hex__hub { fill: #0b100f; stroke: rgba(8, 48, 38, .7); stroke-width: 5; }
.ach-hex__seg { animation: ach-seg 380ms var(--ease-out) calc(60ms + var(--i) * 50ms) both; transform-origin: 0 0; }
@keyframes ach-seg { from { opacity: 0; transform: scale(.72); } }
.ach-hex__cap { position: absolute; left: .1rem; top: 0; display: grid; grid-template-columns: auto auto; column-gap: .08rem; align-items: center; font-family: var(--font-display);
  font-size: calc(.16 * var(--t)); letter-spacing: .04em; color: rgba(220, 230, 226, .3); white-space: nowrap; pointer-events: none; }
.ach-hex__cap i { width: .06rem; height: .06rem; background: var(--mint-400); }
.ach-hex__cap small { grid-column: 2; width: .5rem; height: .08rem; margin-top: .04rem; background: rgba(74, 242, 196, .4); }
.ach-hex__label { position: absolute; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; line-height: 1.15; white-space: nowrap; isolation: isolate;
  animation: ach-pop 320ms var(--ease-out) calc(180ms + var(--i) * 50ms) both; }
.ach-hex__label b { position: relative; padding: 0 .1rem; font-family: var(--font-display); font-size: calc(.32 * var(--t)); color: #dafff4; font-weight: 600; text-shadow: 0 0 .08rem rgba(74, 242, 196, .9); }
.ach-hex__label b::before { content: ''; position: absolute; z-index: -1; inset: 18% -4%; border-radius: .2rem; background: rgba(74, 242, 196, .26); filter: blur(.05rem); }
.ach-hex__label span { font-size: calc(.25 * var(--t)); color: #dfe6e3; }

/* section bars */
.ach-bar { position: relative; display: flex; align-items: center; gap: .2rem; height: .66rem; margin: .5rem 0 .3rem; padding: 0 .3rem 0 1.38rem;
  background: linear-gradient(90deg, rgba(150, 160, 158, .34), rgba(110, 120, 118, .2) 70%, rgba(110, 120, 118, .1)); }
.ach-bar::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .4; background: repeating-linear-gradient(90deg, rgba(0, 0, 0, .25) 0 1px, transparent 1px 7px); }
.ach-bar__icon { position: absolute; left: .3rem; top: -.2rem; width: .9rem; height: 1.04rem; display: grid; place-items: center; background: #2b302f; box-shadow: 0 0 0 2px rgba(200, 210, 206, .32); }
.ach-bar__icon svg { width: .52rem; height: .52rem; fill: #eef3f1; }
.ach-bar__title { position: relative; z-index: 1; font-size: calc(.34 * var(--t)); font-weight: 800; color: #f2f6f5; letter-spacing: .04em; }
.ach-bar__marks { position: relative; z-index: 1; margin-left: auto; display: flex; align-items: center; gap: .06rem; color: rgba(220, 230, 226, .55); }
.ach-bar__marks > i { width: .3rem; height: .3rem; display: grid; place-items: center; border: 1px solid rgba(220, 230, 226, .45); }
.ach-bar__marks > i .icon, .ach-bar__marks > i svg { width: .2rem; height: .2rem; }
.ach-bar__micro { margin-left: .04rem; line-height: 1.1; color: rgba(220, 230, 226, .5); }

/* 卫戍成就 */
.ach-best { display: grid; grid-template-columns: 3.2rem minmax(0, 1fr); gap: .5rem; align-items: center; }
.ach-best__left { display: flex; flex-direction: column; align-items: center; gap: .12rem; }
/* the emblem in its brackets, wired to the lineup's bracket (a dot, the wire, three ticks) */
.ach-best__mount { position: relative; align-self: stretch; display: flex; flex-direction: column; align-items: center; gap: .12rem; padding: .06rem .3rem .1rem; }
.ach-best__mount::before, .ach-best__mount::after { content: ''; position: absolute; top: 0; bottom: .1rem; width: .1rem; border: 2px solid rgba(200, 210, 206, .3); pointer-events: none; }
.ach-best__mount::before { left: 0; border-right: 0; }
.ach-best__mount::after { right: 0; border-left: 0; }
.ach-best__wire { position: absolute; left: 100%; top: 1.21rem; width: .5rem; height: 2px; background: rgba(200, 210, 206, .4); }
.ach-best__wire::before { content: ''; position: absolute; left: -.05rem; top: 50%; width: .1rem; height: .1rem; margin-top: -.05rem; border-radius: 50%; background: rgba(200, 210, 206, .6); }
.ach-best__wire::after { content: ''; position: absolute; right: 0; top: -.14rem; width: .14rem; height: .3rem; background: repeating-linear-gradient(180deg, rgba(200, 210, 206, .45) 0 2px, transparent 2px .14rem); }
.ach-pill { align-self: flex-start; display: inline-flex; align-items: center; gap: .06rem; padding: .04rem .16rem; border-radius: .24rem; background: rgba(220, 230, 226, .14); font-size: calc(.26 * var(--t)); font-weight: 600; }
.ach-pill .icon { width: .2rem; height: .2rem; }
.ach-best__glyph { width: 2.1rem; height: 2.1rem; display: grid; place-items: center; margin-top: .1rem; background: #121716;
  box-shadow: 0 0 0 3px rgba(200, 210, 206, .32), 0 0 0 .1rem #0b0f0e, 0 0 0 calc(.1rem + 1px) rgba(200, 210, 206, .16); }
.ach-best__glyph .bglyph, .ach-top__frame .bglyph { width: 1.3rem; height: 1.3rem; display: grid; place-items: center; }
.ach-best__glyph .bglyph img, .ach-top__frame .bglyph img { width: 100%; height: 100%; object-fit: contain;
  filter: brightness(0) invert(84%) sepia(52%) saturate(640%) hue-rotate(106deg) drop-shadow(0 0 .1rem rgba(74, 242, 196, .6)); }
.ach-best__glyph .bglyph__txt, .ach-top__frame .bglyph__txt { font-size: calc(.8 * var(--t)); font-weight: 900; color: #4af2c4; }
.ach-best__label { font-size: calc(.27 * var(--t)); color: #dfe6e3; }
.ach-best__num { font-family: var(--font-display); font-size: calc(.66 * var(--t)); line-height: 1; color: #4af2c4; font-weight: 500; }
.ach-best__lineup { position: relative; display: flex; gap: .4rem; padding: .3rem .4rem .3rem .5rem; }
.ach-best__lineup::before, .ach-best__lineup::after { content: ''; position: absolute; top: 0; bottom: 0; width: .1rem; border: 2px solid rgba(200, 210, 206, .35); pointer-events: none; }
.ach-best__lineup::before { left: 0; border-right: 0; }
.ach-best__lineup::after { right: 0; border-left: 0; }
.ach-best__rows { display: flex; flex-direction: column; gap: .26rem; }
.ach-best__row { display: flex; gap: .38rem; }
.ach-best__bonds { display: grid; grid-template-columns: repeat(2, auto); gap: .14rem .3rem; align-content: start; padding-left: .1rem; }
.ach-maxima { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3rem; margin-top: .4rem; }
.ach-max { position: relative; height: 1.5rem; display: flex; flex-direction: column; justify-content: center; padding: 0 .3rem; overflow: hidden; }
.ach-max::before, .ach-max::after { content: ''; position: absolute; top: 0; bottom: 0; width: .1rem; border: 2px solid rgba(200, 210, 206, .32); pointer-events: none; }
.ach-max::before { left: 0; border-right: 0; }
.ach-max::after { right: 0; border-left: 0; }
.ach-max__label { position: relative; z-index: 1; font-size: calc(.25 * var(--t)); color: #d4dcd9; white-space: nowrap; }
.ach-max__num { position: relative; z-index: 1; display: flex; align-items: baseline; gap: .02rem; line-height: 1.05; }
.ach-max__num small { font-size: calc(.36 * var(--t)); color: #f4f7f6; }
.ach-max__num .num { font-family: var(--font-display); font-size: calc(.54 * var(--t)); font-weight: 500; color: var(--mx, #4af2c4); }
.ach-max__glyph { position: absolute; right: .36rem; top: 50%; width: 1.1rem; height: 1.1rem; margin-top: -.55rem; fill: var(--mx, #4af2c4); opacity: .45; }
.ach-max.is-gold { --mx: #ffcf1f; } .ach-max.is-orange { --mx: #ff8a2a; } .ach-max.is-mint { --mx: #3fe3b2; }

/* 盟约纪录 / 策略纪录 */
.ach-list { padding-bottom: .1rem; }
.ach-sub { margin: .26rem 0 .2rem .4rem; font-size: calc(.26 * var(--t)); color: #b9c2bf; }
.ach-sub::before { content: '-'; margin-right: .22rem; }
.ach-empty { margin: .1rem 0 .1rem .8rem; font-size: calc(.22 * var(--t)); color: #7d8784; }
.ach-tops { display: flex; gap: 1.45rem; padding-left: 2.1rem; }
.ach-top { display: flex; flex-direction: column; align-items: center; gap: .16rem; animation: ach-pop 380ms var(--ease-out) both; }
@keyframes ach-pop { from { opacity: 0; transform: translateY(.12rem); } }
.ach-top__frame { position: relative; width: 2.4rem; height: 2.4rem; display: grid; place-items: center; background: rgba(12, 18, 17, .7); box-shadow: inset 0 0 0 3px rgba(200, 210, 206, .3); }
.ach-top__rank { position: absolute; left: .12rem; top: .08rem; font-family: var(--font-display); font-style: normal; font-size: calc(.22 * var(--t)); color: rgba(220, 230, 226, .5); }
.ach-top__name { font-size: calc(.28 * var(--t)); font-weight: 700; color: #eef3f1; white-space: nowrap; }
.ach-tops--band { gap: .9rem; padding-left: .9rem; }
.ach-top--band { flex-direction: row; align-items: center; gap: .22rem; }
.ach-top--band .ach-top__frame { width: 2.1rem; height: 2.1rem; }
.ach-top--band .bandicon, .ach-mark__frame .bandicon { width: 1.6rem; height: 1.6rem; }
.ach-top--band .bandicon img, .ach-mark__frame .bandicon img { width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 0 .08rem rgba(74, 242, 196, .45)); }
.ach-top__side { display: flex; flex-direction: column; gap: .06rem; }
.ach-top__count { display: flex; align-items: baseline; gap: .02rem; }
.ach-top__count small { font-size: calc(.28 * var(--t)); color: #eef3f1; }
.ach-top__count b { font-family: var(--font-display); font-size: calc(.44 * var(--t)); line-height: 1; color: #4af2c4; font-weight: 500; }
.ach-ops { display: flex; flex-wrap: wrap; gap: .26rem .5rem; padding-left: .95rem; }
.ach-op { position: relative; width: 1.5rem; height: 1.5rem; display: grid; place-items: center; }
.ach-op .uthumb { --ut: 1.36rem; border-radius: 50%; overflow: hidden; box-shadow: 0 0 0 2px rgba(20, 26, 25, .9), 0 0 .2rem rgba(74, 242, 196, .22); }
.ach-op__tier { position: absolute; left: .02rem; bottom: -.02rem; min-width: .4rem; height: .36rem; padding: 0 .04rem; display: grid; place-items: center; font-family: var(--font-display); font-size: calc(.2 * var(--t));
  font-weight: 700; line-height: 1; color: var(--tc, #e6eae8); background: #151818; border: 2px solid var(--tc, #e6eae8); border-radius: .05rem; }
.ach-op.sop--t5 .ach-op__tier { background: #151818; color: #ffc81e; border-color: #ffc81e; }
.ach-op.sop--t6 .ach-op__tier { background: #151818; color: #ff8a1d; border-color: #ff8a1d; }
.ach-marks { display: flex; flex-wrap: wrap; gap: .4rem; padding-left: 1.2rem; }
.ach-mark { display: flex; flex-direction: column; align-items: center; gap: .12rem; }
.ach-mark b { font-size: calc(.28 * var(--t)); font-weight: 700; }
.ach-mark__frame { position: relative; width: 2rem; height: 2rem; display: grid; place-items: center;
  background: repeating-linear-gradient(135deg, rgba(74, 242, 196, .08) 0 .04rem, transparent .04rem .12rem), rgba(18, 40, 36, .7); box-shadow: inset 0 0 0 1px rgba(74, 242, 196, .3); }
.ach-mark__badge { position: absolute; right: .06rem; top: .06rem; width: .3rem; height: .3rem; display: grid; place-items: center; background: #1c1206; border: 2px solid #ff9a2a; color: #ffad3a; }
.ach-mark__badge svg { width: .2rem; height: .2rem; }
@media (prefers-reduced-motion: reduce) {
  .ach, .ach__box, .ach-hex__seg, .ach-hex__label, .ach-top, .ach__loader i, .ach__loader b { animation: none !important; }
}
/* a guest's panel: the login block */
.ach-gate { min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .2rem; padding: .3rem 1rem; text-align: center; }
.ach-gate__mark .emblem { margin: 0; animation: none; }
.ach-gate__mark .emblem__svg { width: .9rem; height: .98rem; }
.ach-gate__mark .emblem__svg circle { animation: none; }
.ach-gate__title { font-size: calc(.42 * var(--t)); font-weight: 800; color: #f2f6f5; letter-spacing: .04em; }
.ach-gate p { margin: 0; max-width: 10rem; font-size: calc(.26 * var(--t)); line-height: 1.5; color: #b9c2bf; }
.ach-gate p.ach-gate__local { color: var(--mint-400); }

/* ==========================================================================================
   名片 (js/ui/namecards.js, 2026-10-14): the account's namecard under a name — a layer behind the content of a
   `.has-nc` plate (lobby chip, account dialog, 成就统计, 好友 rows, room seats, settlement plates), darker on the
   left where the name sits; then the picker.
   ========================================================================================== */
.has-nc { position: relative; isolation: isolate; text-shadow: 0 1px 2px rgba(0, 0, 0, .8); }
.nc-layer { position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: inherit;
  background: var(--nc-shade, linear-gradient(90deg, rgba(8, 11, 11, .9), rgba(8, 11, 11, .62) 50%, rgba(8, 11, 11, .2))), var(--nc) center / cover no-repeat, #101514; }
.ach-card.has-nc { background: #101514; --nc-shade: linear-gradient(90deg, rgba(6, 9, 9, .5), rgba(6, 9, 9, .12) 55%, transparent); }
.ach-card.has-nc .ach-card__id { background: rgba(8, 12, 11, .62); color: #e6ecea; }
.ach-card.has-nc .ach-card__brand { display: none; }
.acct-me.has-nc { padding: 10px 12px; border: 1px solid rgba(255, 255, 255, .14); border-radius: 4px; --nc-shade: linear-gradient(90deg, rgba(8, 11, 11, .82), rgba(8, 11, 11, .45) 55%, rgba(8, 11, 11, .1)); }
.acct-me.has-nc .acct-who small, .acct-title-card.has-nc .acct-title-card__who small { color: #d6dedb; }
.acct-title-card.has-nc { --nc-shade: linear-gradient(90deg, rgba(8, 11, 11, .84), rgba(8, 11, 11, .5) 55%, rgba(8, 11, 11, .2)); }
.me-chip.has-nc { border-color: rgba(255, 255, 255, .22); }
.rseat__plate.has-nc, .tcard__plate.has-nc, .frow.has-nc { --nc-shade: linear-gradient(90deg, rgba(8, 11, 11, .86), rgba(8, 11, 11, .5) 55%, rgba(8, 11, 11, .12)); }
.dorder__card.has-nc { --nc-shade: linear-gradient(90deg, rgba(8, 11, 11, .84), rgba(8, 11, 11, .45) 40%, rgba(8, 11, 11, .25)); }
.splate__info.has-nc { --nc-shade: linear-gradient(90deg, rgba(8, 30, 25, .78), rgba(8, 20, 18, .4) 60%, rgba(8, 11, 11, .1)); }

.nc-pick { position: fixed; inset: 0; z-index: 420; display: grid; place-items: center; padding: 12px; background: rgba(3, 8, 6, .6); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.nc-pick__panel { width: min(780px, 100%); max-height: min(620px, calc(100dvh - 24px)); display: flex; flex-direction: column; color: #e6ecea;
  background: #0d1211; border: 1px solid rgba(78, 216, 175, .35); box-shadow: 0 12px 40px rgba(0, 0, 0, .6); font-size: 14px; }
.nc-pick__head { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid rgba(255, 255, 255, .08); }
.nc-pick__head strong { font-family: var(--font-display); font-size: 12px; letter-spacing: .12em; color: var(--mint-400); }
.nc-pick__title { font-size: 16px; font-weight: 700; }
.nc-pick__x { margin-left: auto; width: 32px; height: 32px; padding: 0; border: 0; background: none; color: #cfd8d5; font-size: 24px; line-height: 1; cursor: pointer; }
.nc-pick__x:hover { color: var(--mint-400); }
.nc-pick__status { margin: 0; padding: 8px 14px 0; color: #9aa6a2; }
.nc-pick__status:empty { display: none; }
.nc-pick__status.is-error { color: #ff8a7a; }
.nc-pick__grid { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  grid-auto-rows: max-content; align-content: start; gap: 8px; padding: 10px 14px 14px; }
.nc-pick__theme { grid-column: 1 / -1; margin: 8px 0 0; font-size: 13px; font-weight: 700; color: #b9c2bf; }
.nc-pick__theme:first-child { margin-top: 0; }
.nc-pick__card { position: relative; padding: 0; border: 2px solid transparent; border-radius: 4px; background: #101514; cursor: pointer; }
.nc-pick__card img { width: 100%; height: auto; aspect-ratio: 600 / 186; object-fit: cover; display: block; border-radius: 2px; }
.nc-pick__card:hover, .nc-pick__card:focus-visible { border-color: rgba(78, 216, 175, .6); outline: none; }
.nc-pick__card.is-on { border-color: var(--mint-400); }
.nc-pick__card.is-busy { opacity: .55; }
.nc-pick__on { position: absolute; right: 4px; bottom: 4px; padding: 1px 6px; font-size: 11px; font-weight: 700; color: #06231b; background: var(--mint-400); border-radius: 2px; }
.nc-pick__foot { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-top: 1px solid rgba(255, 255, 255, .08); }
.nc-pick__foot small { flex: 1; min-width: 0; color: #8c9894; }
@media (max-width: 560px), (max-height: 520px) {
  .nc-pick__grid { grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); }
  .nc-pick__foot small { display: none; }
}
/* the account's 获赞 on the plate, 导入本机记录 (2026-10-14: the panel reads the account's records) */
.ach-counts__likes small .icon { fill: #ffad3a; }
.ach-counts__likes b { color: #ffad3a; }
.ach-import { display: flex; align-items: center; gap: .14rem; margin: .16rem 0 0; padding: .1rem .16rem; font-size: calc(.2 * var(--t)); color: #dfe6e3;
  background: rgba(74, 242, 196, .08); box-shadow: inset 0 0 0 1px rgba(74, 242, 196, .3); }
.ach-import > .icon { width: .24rem; height: .24rem; flex: none; color: var(--mint-400); }
.ach-import > span { flex: 1; min-width: 0; }

/* ==========================================================================================
   好友 (ui/friends.js, 2026-10-14): the hub tile, the panel (a Modal), the invitation banners.
   ========================================================================================== */
.hub-tile--friends { position: relative; }
.hub-tile__sub { margin-left: .08rem; font-size: calc(.13 * var(--t)); font-weight: 600; color: var(--mint-400); }
.hub-tile__badge { position: absolute; right: .1rem; top: 50%; transform: translateY(-50%); min-width: .3rem; height: .3rem; padding: 0 .07rem; display: grid; place-items: center;
  border-radius: .15rem; background: #ff9a2a; color: #2a1404; font-size: calc(.16 * var(--t)); font-weight: 800; }
.fglyph { width: 1em; height: 1em; fill: currentColor; flex: none; }

.fr { display: flex; flex-direction: column; gap: .14rem; min-width: 0; font-size: max(calc(.18 * var(--t)), 12px); }
.fr--guest { align-items: flex-start; gap: .2rem; color: var(--text-lo); }
.fr__add { display: flex; gap: .12rem; align-items: stretch; }
.fr__add > :first-child { flex: 1; min-width: 0; }
.fr__me { display: flex; flex-wrap: wrap; align-items: center; gap: .08rem .14rem; margin: 0; color: var(--text-lo); }
.fr__me > b { color: var(--text-hi); font-weight: 700; }
.fr__got { display: inline-flex; align-items: center; gap: .05rem; margin-left: auto; color: #ffad3a; font-weight: 700; }
.fr__tabs { display: flex; gap: .06rem; border-bottom: 1px solid rgba(223, 230, 226, .14); }
.fr__tabs button { position: relative; display: inline-flex; align-items: center; gap: .08rem; padding: .08rem .2rem; border: 0; background: none; color: var(--text-lo); font: inherit; font-weight: 700; cursor: pointer; }
.fr__tabs button .num { color: var(--text-dim); font-weight: 600; }
.fr__tabs button.is-on { color: var(--mint-400); box-shadow: inset 0 -2px 0 var(--mint-500); }
.fr__badge { min-width: .26rem; height: .26rem; padding: 0 .06rem; display: grid; place-items: center; border-radius: .13rem; background: #ff9a2a; color: #2a1404; font-size: .8em; }
.fr__list { list-style: none; margin: 0; padding: 0 0 3px; display: flex; flex-direction: column; gap: .08rem; max-height: min(4.6rem, 52vh); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; }
.fr__reqs h4 { margin: .08rem 0 .06rem; font-size: .9em; color: var(--text-dim); font-weight: 700; }
.fr__empty, .fr__note { margin: 0; color: var(--text-dim); }
.fr__note { font-size: .86em; }
.fr__loading { display: grid; place-items: center; min-height: 1.2rem; }
.frow { display: flex; align-items: center; gap: .14rem; padding: .08rem .12rem; background: rgba(255, 255, 255, .03); box-shadow: inset 0 0 0 1px rgba(223, 230, 226, .1); }
.frow.is-on { box-shadow: inset 0 0 0 1px rgba(74, 242, 196, .3); }
.frow__who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .02rem; }
.frow__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; color: var(--text-hi); }
.frow__name .acct-tag { color: var(--text-dim); font-weight: 400; }
.frow__who small { display: flex; align-items: center; gap: .06rem; color: var(--text-dim); white-space: nowrap; }
.frow__dot { width: .1rem; height: .1rem; border-radius: 50%; background: #5d6664; flex: none; }
.frow.is-on .frow__dot { background: var(--mint-400); box-shadow: 0 0 .06rem var(--mint-400); }
.frow.is-on .frow__state { color: var(--mint-400); }
.frow__likes { display: inline-flex; align-items: center; gap: .03rem; margin-left: .1rem; color: #ffad3a; }
.frow__acts { display: flex; align-items: center; gap: .06rem; flex: none; }
.frow__x { width: .4rem; height: .4rem; display: grid; place-items: center; padding: 0; border: 0; background: none; color: var(--text-dim); cursor: pointer; }
.frow__x:hover { color: #ff6a5a; }
.fava { display: grid; place-items: center; flex: none; overflow: hidden; border-radius: 50%; background: #1d2423; box-shadow: 0 0 0 1px rgba(223, 230, 226, .3); color: var(--mint-400); }
.fava img { width: 100%; height: 100%; object-fit: cover; }
.fava--md { width: max(.6rem, 34px); height: max(.6rem, 34px); }
.fava--sm { width: max(.44rem, 26px); height: max(.44rem, 26px); }
.finv-host { position: fixed; right: max(12px, .2rem); top: max(60px, .9rem); z-index: calc(var(--z-modal) + 1); display: flex; flex-direction: column; gap: 8px; width: min(4.6rem, calc(100vw - 24px)); pointer-events: none; }
.finv { display: flex; align-items: center; gap: .12rem; padding: .1rem .14rem; pointer-events: auto; font-size: max(calc(.18 * var(--t)), 12px);
  background: rgba(10, 16, 15, .96); box-shadow: inset 0 0 0 1px rgba(255, 170, 60, .55), 0 .06rem .3rem rgba(0, 0, 0, .6); animation: finv-in 260ms var(--ease-out) both; }
@keyframes finv-in { from { opacity: 0; transform: translateX(.3rem); } }
.finv__text { flex: 1; min-width: 0; display: flex; flex-direction: column; color: var(--text-lo); }
.finv__text b { color: var(--text-hi); }
.finv__text small { color: #ffad3a; }
.finv__x { width: 28px; height: 28px; display: grid; place-items: center; padding: 0; border: 0; background: none; color: var(--text-dim); cursor: pointer; }
@media (max-width: 640px) {
  .frow { flex-wrap: wrap; }
  .frow__acts { width: 100%; justify-content: flex-end; }
}
@media (prefers-reduced-motion: reduce) { .finv { animation: none; } }

/* 成就奖杯等级 (ui/trophies.js): the official chess-piece badge of the cumulative trophies; the SVG rook while the pack is
   missing, tinted per level. Inline after a name in the room seats, the draft order and the settlement team cards. */
.tbadge { display: inline-grid; place-items: center; flex: none; object-fit: contain; width: .3rem; height: .3rem; }
.tbadge--svg .icon { width: 100%; height: 100%; }
.tbadge--svg.tbadge--1 { color: #e8efec; }
.tbadge--svg.tbadge--2 { color: #7fd6c4; }
.tbadge--svg.tbadge--3 { color: #d9c08a; }
.tbadge--svg.tbadge--4 { color: #f2c14e; }
.tbadge--svg.tbadge--5 { color: #f08a3a; }
.tbadge--inline { width: 1.35em; height: 1.35em; margin-right: .2em; vertical-align: middle; filter: drop-shadow(0 0 2px rgba(0, 0, 0, .6)); }
.hub-ach__rank > .tbadge { width: .34rem; height: .34rem; }
.splate__rank > .tbadge { width: .44rem; height: .44rem; }

/* ============================================================================================
   ui-hub-package-20261013 — 本仓库自己的增量（追加在**包版 CSS 末尾**）

   AGENTS.md:70 定死了方向：包版 CSS 是「底」，目标方多出来的样式追加到包版末尾。
   下面这些规则全部是包版没有的**新类**（.seat-cap* / .quickmatch-*），不覆盖包版任何一行；
   包版自己的同名观感照旧生效。

   ⚠️ 上一版把方向做反了（包版整段追加在引擎规则之后），本次按 AGENTS.md §3.4 拨正。
   逐条来源见 _up/uihub-c/ 的迁移清单与本次交付报告。
   ============================================================================================ */

/* ---- 野排匹配 quick match (server/matchmaking.js, docs/META.md §1.6) ---------------------------------- */
.quickmatch-panel { margin-top: .06rem; }
.quickmatch-panel .panel__body { display: flex; flex-direction: column; gap: .08rem; }
.quickmatch-row { display: flex; align-items: center; gap: .14rem; font-size: calc(.2 * var(--t)); }
.quickmatch-count { margin-left: auto; font-size: calc(.24 * var(--t)); color: var(--mint); letter-spacing: .1em; }
.quickmatch-foot { display: flex; align-items: center; justify-content: space-between; gap: .12rem; font-size: calc(.14 * var(--t)); }

/* ---- 本房座位上限 seat cap (业主裁决 B5, docs/META.md §1.9) ---------------------------------------------
   The host's slider lives in the create sheet, co-op only. Everything here is a NEW class: no existing selector of this
   file is touched, so a room that has no picker (solo, and every co-op room created before this feature) renders
   exactly the box it did. The slider borrows the settings screen's visual language ('.set-range' in game.css): a mint
   fill drawn with the '--pct' custom property the component computes, so both sliders look like the same control. */
.seat-cap { display: flex; flex-direction: column; gap: .06rem; padding: .08rem .1rem; background: rgba(0, 0, 0, .22); border: 1px solid var(--line); }
.seat-cap__head { display: flex; align-items: center; gap: .1rem; font-size: calc(.14 * var(--t)); }
.seat-cap__name { color: var(--text-md); }
.seat-cap__value { margin-left: auto; font-size: calc(.2 * var(--t)); color: var(--mint); letter-spacing: .06em; }
.seat-cap__slider {
  -webkit-appearance: none; appearance: none; width: 100%; height: .08rem; margin: .04rem 0;
  background: linear-gradient(90deg, var(--mint-500) var(--pct), #0a0d0c var(--pct));
  border: 1px solid var(--line-2); outline: none; cursor: pointer;
}
.seat-cap__slider::-webkit-slider-thumb { -webkit-appearance: none; width: .2rem; height: .26rem; background: var(--mint-400); clip-path: polygon(50% 0, 100% 30%, 100% 100%, 0 100%, 0 30%); cursor: grab; }
.seat-cap__slider::-moz-range-thumb { width: .2rem; height: .26rem; background: var(--mint-400); border: 0; }
.seat-cap__slider:focus-visible { border-color: var(--mint-400); }
.seat-cap__note { font-size: calc(.13 * var(--t)); line-height: 1.7; color: var(--text-dim); }

/* In the room (public/js/screens/room.js SeatCapSetter) the same control sits in the room's ⚙ 设置 dialog row. So it is
   ONE compact row instead of the lobby's stacked block — nothing outside that box moves. */
.seat-cap--room { flex-direction: row; align-items: center; gap: .1rem; padding: 0; background: none; border: 0; }
.seat-cap--room .seat-cap__name { font-size: calc(.14 * var(--t)); color: var(--text-lo); }
.seat-cap--room .seat-cap__slider { width: 1.1rem; margin: 0; }
.seat-cap--room .seat-cap__value { margin-left: 0; font-size: calc(.16 * var(--t)); }
/* ---- 添加 / 移除 AI 队友（业主裁定：既有功能不能因换 UI 而消失） ------------------------------------------
   包版房间的空席位只有「邀请」，而服务端 room.addBot / room.removeBot 一直都在（引擎房间有这两个按钮）。
   这里补回**入口**，用的是包版自己的角落按钮形状（.rseat__kick，绝对定位、不占布局 ⇒ 席位卡尺寸与排布
   一个像素都不动），只把颜色从「危险红」换成薄荷绿，好和「移出真人」区分开。协议与服务端一字未动。 */
.rseat__kick--bot { color: #7fe8c8; background: #10312a; border-color: rgba(79, 232, 192, .6); }
.rseat__kick--bot:hover:not(:disabled) { filter: brightness(1.25); }
@keyframes tr-draw { to { stroke-dashoffset: 0; } }
@keyframes tr-diamond { 0% { opacity: 0; transform: translateX(-50%) rotate(45deg) scale(.5); } 30%, 72% { opacity: 1; transform: translateX(-50%) rotate(45deg) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) rotate(45deg) scale(1.1); } }
/* the hub */
.lobby-hub .hub-bg { animation: tr-fade 560ms ease-out backwards; }
.lobby-hub > .topbar { animation: tr-fade 320ms ease-out 120ms backwards; } /* opacity only: its dialogs are fixed */
.lobby-hub .hub-center { animation: tr-zoom 600ms var(--tr-ease) 140ms backwards; }
.lobby-hub .hub-side { animation: tr-left 480ms var(--tr-ease) 220ms backwards; }
.lobby-hub .hub-right { animation: tr-right 480ms var(--tr-ease) 260ms backwards; }
.hub-entries .hub-entry-wrap { animation: tr-rise 440ms var(--tr-ease) 300ms backwards; }
.hub-entries .hub-entry-wrap:nth-child(2) { animation-delay: 360ms; }
.hub-entries .hub-entry-wrap:nth-child(3) { animation-delay: 420ms; }
.hub-entries .hub-entry-wrap:nth-child(4) { animation-delay: 480ms; }
/* 选择模拟协议 / 选择同盟方式: from black, then the title, the stage and the cards */
.modal__box.proto, .modal__box.ally { animation: tr-veil 150ms linear backwards; }
.proto__bg { animation: tr-fade 340ms ease-out 140ms backwards; }
.proto-top { animation: tr-fade 260ms ease-out 170ms backwards; }
.proto-title { animation: tr-right 400ms var(--tr-ease) 200ms backwards; }
.proto-stage, .ally-stage { animation: tr-zoom 480ms var(--tr-ease) 190ms backwards; }
.proto-list .pcard { animation: tr-right 400ms var(--tr-ease) backwards; animation-delay: calc(240ms + var(--n, 0) * 60ms); }
.proto-list .pcard:nth-child(2) { --n: 1; }
.proto-list .pcard:nth-child(3) { --n: 2; }
.proto-list .pcard:nth-child(4) { --n: 3; }
.proto-list .pcard:nth-child(5) { --n: 4; }
.proto-foot { animation: tr-rise 400ms var(--tr-ease) 440ms backwards; }
.ally-card--create { animation: tr-right 420ms var(--tr-ease) 240ms backwards; }
.ally-card--join { animation: tr-right 420ms var(--tr-ease) 380ms backwards; }
.ally-guide { animation: tr-rise 380ms var(--tr-ease) 450ms backwards; }
/* the diamond at the bottom while it comes up */
.proto__body::after, .ally__body::after { content: ''; position: absolute; left: 50%; bottom: .5rem; z-index: 9; width: .3rem; height: .3rem; pointer-events: none; opacity: 0;
  border: 2px solid rgba(223, 230, 226, .55); box-shadow: inset 0 0 0 3px #0a0b0b, inset 0 0 0 5px rgba(223, 230, 226, .3); animation: tr-diamond 720ms ease-out 60ms both; }
/* the stamp's ring is drawn each time a difficulty is chosen */
.pcard.is-on .pcard__ring path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: tr-draw 380ms ease-out 90ms forwards; }
.pcard.is-on .pcard__ring path + path { animation-delay: 260ms; }

@media (prefers-reduced-motion: reduce) {
  .hub-bg__ship, .hub-center, .hub-entry-wrap, .hub-radar__sweep, .proto__pic, .modal__box.proto, .modal__box.ally, .pcard.is-on .pcard__stamp,
  .mf-radar__sweep, .mf-radar__blip, .mf-blk.is-lit, .hub-bg__own, .lobby-hub .hub-bg, .lobby-hub > .topbar, .lobby-hub .hub-center, .lobby-hub .hub-side,
  .lobby-hub .hub-right, .hub-entries .hub-entry-wrap, .proto__bg, .proto-top, .proto-title, .proto-stage, .ally-stage, .proto-list .pcard, .proto-foot,
  .ally-card--create, .ally-card--join, .ally-guide, .pcard.is-on .pcard__ring path, .ps, .ps-fig, .ps-spike, .ps-call, .ps-beacon, .ps-scan { animation: none; }
  .ps-cable__pulse { display: none; }
  .pcard.is-on .pcard__ring path { stroke-dashoffset: 0; }
  .proto__body::after, .ally__body::after { display: none; }
}

/* official versions (DESIGN §37.23): the version under the title, the cards' wait while a version's data loads */
.hub-center__ver { position: relative; margin-top: .04rem; font-size: calc(.22 * var(--t)); font-weight: 700; letter-spacing: .08em; color: #9fd3ff; text-shadow: 0 1px .08rem rgba(0, 0, 0, .85); overflow-wrap: anywhere; }
.proto-list__wait { display: flex; align-items: center; gap: .08rem; margin: 0; color: var(--text-lo); font-size: calc(.15 * var(--t)); }
.proto-list__wait.is-failed { flex-wrap: wrap; color: var(--amber); }
.proto-list__wait.is-failed .icon { flex: none; width: 1.1em; height: 1.1em; }
