0.2.3: prepare follow-up fixes and client features (#407, #408, #410, #413, #431, #435, #436, #440, #444)

Add special-target activation without bypassing attack cadence, cooperative
card preferences and emotes, skill sound banks, per-operator voice choices,
text sizing, install prompts, closed-tab recovery and unanimous setup rerolls.
Retain late deployment elapsed time and resolve echo/counter pulses without
recursive hook overflow. Independent final review remains pending.

Golden: roster-016, roster-035, roster-036, roster-045;
boss-boss_1-pair, boss-boss_3-pair, boss-boss_5-pair, boss-boss_7-pair,
hidden-boss_9-pair; solo-HARD-9-boosted: Lemuen attack cadence.
diy-132: Necras extra activation targets.
coop2-NORMAL-14-standins: cooperative purchase preference and simulation fixes.
hidden-boss_10-solo: echo pulse FIFO resolution.
See DESIGN 28.13-28.24 for assumptions, sources and contributor credit.
This commit is contained in:
sganggs committed 2026-10-09 22:55:24 +08:00
1 parent 314564c139
commit f3658a0dd4
104 files changed
+3674 -741

No files matched your search

+41 -41
View File
@@ -27,7 +27,7 @@
border: 1px solid var(--btn-bd);
background: var(--btn-bg);
color: var(--btn-fg);
font-size: .18rem;
font-size: calc(.18 * var(--t));
font-weight: 700;
letter-spacing: .06em;
line-height: 1;
@@ -164,9 +164,9 @@
.btn.is-loading { cursor: default; --btn-fg: var(--text-lo); }
.btn--primary.is-loading { --btn-bg: var(--mint-700); --btn-fg: var(--text-on-mint); }
.btn--sm { height: .36rem; min-width: .36rem; padding: 0 .16rem; font-size: .15rem; gap: .07rem; }
.btn--lg { height: .64rem; min-width: .64rem; padding: 0 .34rem; font-size: .22rem; gap: .12rem; }
.btn--xl { height: .84rem; min-width: .84rem; padding: 0 .48rem; font-size: .28rem; letter-spacing: .24em; gap: .16rem; }
.btn--sm { height: .36rem; min-width: .36rem; padding: 0 .16rem; font-size: calc(.15 * var(--t)); gap: .07rem; }
.btn--lg { height: .64rem; min-width: .64rem; padding: 0 .34rem; font-size: calc(.22 * var(--t)); gap: .12rem; }
.btn--xl { height: .84rem; min-width: .84rem; padding: 0 .48rem; font-size: calc(.28 * var(--t)); letter-spacing: .24em; gap: .16rem; }
.btn--block { display: flex; width: 100%; }
.btn--square { padding: 0; width: var(--sq, .5rem); }
.btn--square.btn--sm { --sq: .36rem; }
@@ -204,7 +204,7 @@
border-bottom: 1px solid var(--line);
}
.panel__titles { display: flex; flex-direction: column; gap: .03rem; min-width: 0; }
.panel__title { font-size: .21rem; font-weight: 700; letter-spacing: .04em; }
.panel__title { font-size: calc(.21 * var(--t)); font-weight: 700; letter-spacing: .04em; }
.panel__actions { display: flex; gap: .08rem; align-items: center; }
.panel__body { position: relative; padding: .22rem; min-height: 0; }
.panel--flush .panel__body { padding: 0; }
@@ -472,9 +472,9 @@
opacity: .55;
}
.modal__head { display: flex; flex-direction: column; gap: .04rem; padding: .22rem .3rem .04rem; }
.modal__title { font-size: .26rem; font-weight: 700; letter-spacing: .04em; }
.modal__title { font-size: calc(.26 * var(--t)); font-weight: 700; letter-spacing: .04em; }
.modal__body { padding: .14rem .3rem .26rem; color: var(--text-md); overflow: auto; }
.modal__text { font-size: .18rem; line-height: 1.7; }
.modal__text { font-size: calc(.18 * var(--t)); line-height: 1.7; }
.modal__actions {
flex: none;
display: flex;
@@ -500,7 +500,7 @@
border-left: 2px solid var(--mint-500);
box-shadow: 0 .06rem .2rem rgba(0, 0, 0, .55);
color: var(--text-md);
font-size: .15rem;
font-size: calc(.15 * var(--t));
line-height: 1.55;
pointer-events: none;
opacity: 0;
@@ -515,8 +515,8 @@
/* ---- progress bar ----------------------------------------------------------------------------------- */
.pbar { --pc: var(--mint-500); --ph: .1rem; display: flex; flex-direction: column; gap: .05rem; min-width: .8rem; }
.pbar__meta { display: flex; justify-content: space-between; align-items: baseline; gap: .1rem; font-size: .14rem; color: var(--text-lo); }
.pbar__value { font-family: var(--font-num); font-weight: 700; color: var(--text-hi); font-size: .16rem; }
.pbar__meta { display: flex; justify-content: space-between; align-items: baseline; gap: .1rem; font-size: calc(.14 * var(--t)); color: var(--text-lo); }
.pbar__value { font-family: var(--font-num); font-weight: 700; color: var(--text-hi); font-size: calc(.16 * var(--t)); }
.pbar__value small { color: var(--text-dim); font-size: .8em; }
.pbar__track { position: relative; height: var(--ph); background: #080a09; border: 1px solid var(--line); overflow: hidden; }
.pbar__fill {
@@ -549,7 +549,7 @@
border: 0;
background: none;
color: var(--text-lo);
font-size: .17rem;
font-size: calc(.17 * var(--t));
font-weight: 500;
letter-spacing: .04em;
transition: color var(--t-fast) var(--ease-out), background-color var(--t-fast);
@@ -570,11 +570,11 @@
}
.tabs__tab.is-active { color: var(--mint-400); }
.tabs__tab.is-active::after { transform: scaleX(1); }
.tabs__badge { font-family: var(--font-num); font-size: .13rem; padding: .01rem .06rem; background: var(--bg-3); color: var(--text-md); }
.tabs--sm .tabs__tab { font-size: .15rem; padding: .07rem .16rem .09rem; }
.tabs__badge { font-family: var(--font-num); font-size: calc(.13 * var(--t)); padding: .01rem .06rem; background: var(--bg-3); color: var(--text-md); }
.tabs--sm .tabs__tab { font-size: calc(.15 * var(--t)); padding: .07rem .16rem .09rem; }
/* ---- spinner -------------------------------------------------------------------------------------- */
.spinner { --sp: .36rem; --sc: var(--mint-500); display: inline-flex; align-items: center; gap: .1rem; color: var(--text-lo); font-size: .15rem; }
.spinner { --sp: .36rem; --sc: var(--mint-500); display: inline-flex; align-items: center; gap: .1rem; color: var(--text-lo); font-size: calc(.15 * var(--t)); }
.spinner svg { width: var(--sp); height: var(--sp); animation: spin 1.6s linear infinite; overflow: visible; }
.spinner__track { fill: none; stroke: var(--line-2); stroke-width: 3; }
.spinner__arc { fill: none; stroke: var(--sc); stroke-width: 3; stroke-dasharray: 34 98; animation: spinner-dash 1.1s var(--ease-in-out) infinite; filter: drop-shadow(0 0 3px var(--sc)); }
@@ -582,7 +582,7 @@
.spinner--lg { --sp: .56rem; }
.spinner--gold { --sc: var(--gold); }
.spinner--amber { --sc: var(--amber); }
.spinner__label { font-family: var(--font-display); letter-spacing: .2em; font-size: .12rem; text-transform: uppercase; }
.spinner__label { font-family: var(--font-display); letter-spacing: .2em; font-size: calc(.12 * var(--t)); text-transform: uppercase; }
@keyframes spinner-dash { 0% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: -132; } }
/* ---- avatar frame ---------------------------------------------------------------------------------- */
@@ -710,9 +710,9 @@
animation: pb-sweep 700ms 250ms var(--ease-out) forwards;
opacity: 0;
}
.pbanner__micro { font-family: var(--font-display); font-size: .12rem; letter-spacing: .5em; color: var(--pb); padding-left: .5em; }
.pbanner__micro { font-family: var(--font-display); font-size: calc(.12 * var(--t)); letter-spacing: .5em; color: var(--pb); padding-left: .5em; }
.pbanner__title {
font-size: .56rem;
font-size: calc(.56 * var(--t));
font-weight: 900;
letter-spacing: .16em;
padding-left: .16em;
@@ -720,7 +720,7 @@
color: #fff;
text-shadow: 0 0 .22rem var(--pb-glow), 0 2px 0 rgba(0, 0, 0, .5);
}
.pbanner__sub { font-size: .16rem; color: var(--text-lo); letter-spacing: .12em; }
.pbanner__sub { font-size: calc(.16 * var(--t)); color: var(--text-lo); letter-spacing: .12em; }
.pbanner__chev { --ch-h: .42rem; height: .42rem; flex: none; }
.pbanner--inline .pbanner__band { animation-duration: var(--t-slow); }
.pbanner.is-leaving .pbanner__band { animation: pb-close 240ms var(--ease-in-out) forwards; }
@@ -783,7 +783,7 @@
.rdialog__tick--br { bottom: 8px; right: 8px; border-left: 0; border-top: 0; }
.rdialog__micro {
font-family: var(--font-display);
font-size: .13rem;
font-size: calc(.13 * var(--t));
letter-spacing: .48em;
padding-left: .48em;
color: var(--rd);
@@ -811,7 +811,7 @@
animation: rd-sweep 780ms 300ms var(--ease-out) forwards;
}
.rdialog__title {
font-size: .62rem;
font-size: calc(.62 * var(--t));
font-weight: 900;
letter-spacing: .14em;
padding-left: .14em;
@@ -821,7 +821,7 @@
}
.rdialog__chev { --ch-h: .46rem; height: .46rem; flex: none; }
.rdialog__sub {
font-size: .18rem;
font-size: calc(.18 * var(--t));
letter-spacing: .1em;
color: var(--text-lo);
text-align: center;
@@ -834,7 +834,7 @@
@keyframes rd-sweep { 0% { left: -25%; opacity: 1; } 100% { left: 115%; opacity: 0; } }
@media (max-width: 720px) {
.rdialog__box { min-width: 0; width: 92vw; padding: .26rem .3rem .22rem; }
.rdialog__title { font-size: .42rem; }
.rdialog__title { font-size: calc(.42 * var(--t)); }
.rdialog__chev { --ch-h: .34rem; height: .34rem; }
}
@media (prefers-reduced-motion: reduce) {
@@ -854,29 +854,29 @@
border: 1px solid var(--line);
color: var(--pc);
font-family: var(--font-num);
font-size: .18rem;
font-size: calc(.18 * var(--t));
font-weight: 700;
line-height: 1;
font-variant-numeric: tabular-nums;
}
.ping__icon { width: .15rem; height: .15rem; margin-right: .03rem; }
.ping__unit { font-size: .13rem; color: var(--text-lo); font-weight: 500; }
.ping__unit { font-size: calc(.13 * var(--t)); color: var(--text-lo); font-weight: 500; }
.ping--low { --pc: var(--mint-400); }
.ping--medium { --pc: var(--amber); }
.ping--high { --pc: var(--red-premium); }
.ping--off { --pc: var(--text-dim); }
/* ---- difficulty tag ---------------------------------------------------------------------------------- */
.dtag { --d-color: var(--amber); display: inline-flex; align-items: center; gap: .06rem; color: var(--d-color); font-weight: 700; font-size: .18rem; letter-spacing: .04em; white-space: nowrap; }
.dtag { --d-color: var(--amber); display: inline-flex; align-items: center; gap: .06rem; color: var(--d-color); font-weight: 700; font-size: calc(.18 * var(--t)); letter-spacing: .04em; white-space: nowrap; }
.dtag__icon { width: 1.15em; height: 1.15em; filter: drop-shadow(0 0 4px var(--d-color)); filter: drop-shadow(0 0 4px color-mix(in srgb, var(--d-color) 65%, transparent)); }
.dicon { object-fit: contain; image-rendering: auto; }
.dtag__code { font-family: var(--font-num); font-size: .72em; font-weight: 500; color: var(--text-dim); letter-spacing: .1em; margin-left: .03rem; }
.dtag--sm { font-size: .15rem; }
.dtag--lg { font-size: .24rem; }
.dtag--sm { font-size: calc(.15 * var(--t)); }
.dtag--lg { font-size: calc(.24 * var(--t)); }
/* ---- text field ------------------------------------------------------------------------------------ */
.field { display: flex; flex-direction: column; gap: .07rem; min-width: 0; }
.field__label { display: flex; align-items: baseline; gap: .1rem; font-size: .15rem; color: var(--text-lo); font-weight: 500; letter-spacing: .04em; }
.field__label { display: flex; align-items: baseline; gap: .1rem; font-size: calc(.15 * var(--t)); color: var(--text-lo); font-weight: 500; letter-spacing: .04em; }
.field__box {
--bk-c: var(--line-3);
--bk-l: .1rem;
@@ -899,15 +899,15 @@
border: 0;
outline: none;
color: var(--text-hi);
font-size: .2rem;
font-size: calc(.2 * var(--t));
letter-spacing: .04em;
}
.field__input::placeholder { color: var(--text-dim); font-weight: 400; letter-spacing: .04em; }
.field__icon { width: .22rem; height: .22rem; color: var(--text-dim); }
.field__box:focus-within .field__icon { color: var(--mint-500); }
.field__hint { font-size: .13rem; color: var(--text-dim); }
.field__hint { font-size: calc(.13 * var(--t)); color: var(--text-dim); }
.field--lg .field__box { height: .68rem; }
.field--lg .field__input { font-size: .26rem; font-weight: 700; }
.field--lg .field__input { font-size: calc(.26 * var(--t)); font-weight: 700; }
.field--code .field__box { height: .64rem; }
.field--code .field__input { font-family: var(--font-num); font-size: .34rem; font-weight: 700; letter-spacing: .42em; text-transform: uppercase; }
.field--code .field__input::placeholder { font-family: var(--font-cjk); font-size: .18rem; letter-spacing: .06em; font-weight: 400; text-transform: none; }
@@ -943,14 +943,14 @@
border-left: 3px solid var(--tc);
box-shadow: 0 .08rem .24rem rgba(0, 0, 0, .55), -.04rem 0 .16rem transparent; box-shadow: 0 .08rem .24rem rgba(0, 0, 0, .55), -.04rem 0 .16rem color-mix(in srgb, var(--tc) 25%, transparent);
color: var(--text-hi);
font-size: .17rem;
font-size: calc(.17 * var(--t));
line-height: 1.45;
cursor: pointer;
animation: toast-in var(--t-med) var(--ease-out);
}
.toast__icon { width: .2rem; height: .2rem; fill: var(--tc); flex: none; }
.toast__text { flex: 1; }
.toast__count { font-family: var(--font-num); font-size: .14rem; color: var(--text-lo); }
.toast__count { font-family: var(--font-num); font-size: calc(.14 * var(--t)); color: var(--text-lo); }
.toast--success { --tc: var(--mint-400); }
.toast--warn { --tc: var(--amber); }
.toast--error { --tc: var(--red-premium); }
@@ -973,7 +973,7 @@
border: 1px solid rgba(232, 90, 26, .55);
box-shadow: 0 .08rem .3rem rgba(0, 0, 0, .6), 0 0 .2rem rgba(232, 90, 26, .15);
color: var(--text-hi);
font-size: .16rem;
font-size: calc(.16 * var(--t));
/* own keyframes: toast-in's transform would drop the translateX(-50%) centring mid-animation */
animation: conn-in var(--t-med) var(--ease-out);
}
@@ -990,11 +990,11 @@
.sp-in-match .conn-banner { top: calc(1.34rem + var(--sa-t, 0px)); bottom: auto; }
.sp-in-match.sp-conn .toast-host { top: calc(2.0rem + var(--sa-t, 0px)); }
.conn-banner .icon { width: .22rem; height: .22rem; color: var(--orange-hi); }
.conn-banner__sub { color: var(--text-lo); font-family: var(--font-num); font-size: .15rem; }
.conn-banner__sub { color: var(--text-lo); font-family: var(--font-num); font-size: calc(.15 * var(--t)); }
/* ---- misc shared bits ------------------------------------------------------------------------------ */
.kv { display: flex; align-items: baseline; gap: .08rem; }
.kv__k { color: var(--text-lo); font-size: .14rem; }
.kv__k { color: var(--text-lo); font-size: calc(.14 * var(--t)); }
.kv__v { font-family: var(--font-num); font-weight: 700; }
.divider { height: 1px; background: linear-gradient(90deg, transparent, var(--line-2) 15%, var(--line-2) 85%, transparent); }
.status-dot { width: .09rem; height: .09rem; border-radius: 50%; background: var(--text-dim); flex: none; display: inline-block; }
@@ -1028,16 +1028,16 @@
}
.topbar__left { justify-self: start; display: flex; align-items: center; gap: .18rem; min-width: 0; }
.topbar__center { display: flex; flex-direction: column; align-items: center; gap: .03rem; text-align: center; }
.topbar__title { display: flex; align-items: center; gap: .18rem; font-size: .3rem; font-weight: 700; letter-spacing: .1em; line-height: 1.2; }
.topbar__title { display: flex; align-items: center; gap: .18rem; font-size: calc(.3 * var(--t)); font-weight: 700; letter-spacing: .1em; line-height: 1.2; }
.topbar__sep { width: 1px; height: .28rem; background: var(--line-2); }
.topbar__right { justify-self: end; display: flex; align-items: center; gap: .16rem; min-width: 0; }
.section-label { display: flex; align-items: baseline; gap: .12rem; margin: 0 0 .14rem; font-size: .2rem; font-weight: 700; letter-spacing: .08em; }
.section-label__idx { font-size: .15rem; color: var(--mint-500); padding: 0 .06rem; border: 1px solid var(--mint-800); line-height: 1.35; letter-spacing: .06em; }
.section-label { display: flex; align-items: baseline; gap: .12rem; margin: 0 0 .14rem; font-size: calc(.2 * var(--t)); font-weight: 700; letter-spacing: .08em; }
.section-label__idx { font-size: calc(.15 * var(--t)); color: var(--mint-500); padding: 0 .06rem; border: 1px solid var(--mint-800); line-height: 1.35; letter-spacing: .06em; }
.me-chip { display: flex; align-items: center; gap: .12rem; padding: .06rem .18rem .06rem .06rem; border: 1px solid var(--line); background: rgba(0, 0, 0, .35); }
.me-chip__text { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.me-chip__name { font-weight: 700; font-size: .18rem; max-width: 2.4rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.me-chip__name { font-weight: 700; font-size: calc(.18 * var(--t)); max-width: 2.4rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crash { align-items: center; justify-content: center; }
.crash__box {
@@ -1051,4 +1051,4 @@
border: 1px solid var(--line-2);
--bk-c: var(--red-premium);
}
.crash__box h2 { font-size: .3rem; }
.crash__box h2 { font-size: calc(.3 * var(--t)); }