The plaque floats mid-court on glass, the blood pool breathes, and the 94vw card stops scrolling sideways

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-08-29 16:36:48 +02:00
1 parent 689550d2d5
commit 1a39c9fdcb
2 files changed
+57 -65

No files matched your search

+19
View File
@@ -491,6 +491,25 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
`RETURNED`, `DOUBLE KILL`) is a footnote to something you already watched happen. Sharing the loud `RETURNED`, `DOUBLE KILL`) is a footnote to something you already watched happen. Sharing the loud
FACE with the milestone cards is right; sharing their SIZE made every footnote read as a milestone. FACE with the milestone cards is right; sharing their SIZE made every footnote read as a milestone.
## Session log: THE LEAGUES — the plaque moves mid-court, and the 94vw scrollbar (2026-08-29, same day, STAGING ONLY)
Live review with Oliver on the pane, three finds:
- **The plaque left the foot** — its solid panel sat exactly on the backdrop's blood pool, and
LEVEL/LEAGUE were 8px footnotes. It floats CENTRED under the title now, on a translucent
surface (rgba ink 0.48, radius 12, no border — the art shows through), with the wappen on top,
the name, **LEVEL · LEAGUE in Bangers 27** as the announcement it is, the bar, and the goal
line (warm, wrapping). The foot is back to PLAY MATCH + two buttons and the blood pool breathes.
- **The phantom horizontal scrollbar** (Oliver spotted a sliver of h-scroll): TWO causes. The
goal line's `white-space: nowrap` set the card's min-content past the viewport (the longest
goal is ~380px) — it wraps now. And the ROOT cause predates the leagues: `.card { width:
min(370px, 94vw) }` is CONTENT width beside 28px of padding, so the card overflowed every
phone below 466px (0.94w + 28 > w) and #intro's `overflow-y: auto` computes overflow-x to
auto. Now `min(370px, 100vw - 28px)` — desktop cap intact, phones exactly viewport-wide.
- **The stylesheet carried a full duplicate block** (level strip + old plaque + bar tracks +
career rules, twice) — leftovers of the mis-spliced ribbon edit that the .way dedupe missed.
Removed; the dead #xpRow rules went with it.
## Session log: THE CLIMB — the arcade gets its identity back (2026-08-29, same day, STAGING ONLY) ## Session log: THE CLIMB — the arcade gets its identity back (2026-08-29, same day, STAGING ONLY)
Oliver: "arcade verhält sich genau so [wie der cup].. die grenzen werden unscharf." Right — the Oliver: "arcade verhält sich genau so [wie der cup].. die grenzen werden unscharf." Right — the
+38 -65
View File
@@ -151,7 +151,10 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
#hot { position: fixed; top: 0; left: 0; width: 26vw; max-width: 150px; height: 15vh; #hot { position: fixed; top: 0; left: 0; width: 26vw; max-width: 150px; height: 15vh;
max-height: 130px; z-index: 4; } max-height: 130px; z-index: 4; }
#intro .card { font: 400 12px Silkscreen, monospace; color: var(--cream); text-align: center; #intro .card { font: 400 12px Silkscreen, monospace; color: var(--cream); text-align: center;
line-height: 1.9; padding: 16px 14px 20px; width: min(370px, 94vw); line-height: 1.9; padding: 16px 14px 20px; width: min(370px, 100vw - 28px); /* CONTENT width (content-box) beside 14px+14px padding:
94vw put the card 5-28px past the viewport on every phone (0.94w+28 > w below
466px) and #intro's overflow-y:auto computes overflow-x to auto — that was the
sliver of horizontal scroll Oliver caught on the splash */
animation: drop 0.5s ease-out; } animation: drop 0.5s ease-out; }
@keyframes drop { from { transform: translateY(-14px); opacity: 0; } } @keyframes drop { from { transform: translateY(-14px); opacity: 0; } }
/* EVERY SCREEN FILLS THE VIEWPORT, and every screen is the same three bands: something pinned to /* EVERY SCREEN FILLS THE VIEWPORT, and every screen is the same three bands: something pinned to
@@ -301,35 +304,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
0%, 100% { filter: drop-shadow(0 0 2px rgba(232, 178, 58, 0.25)); } 0%, 100% { filter: drop-shadow(0 0 2px rgba(232, 178, 58, 0.25)); }
50% { filter: drop-shadow(0 0 7px rgba(232, 178, 58, 0.75)); } } 50% { filter: drop-shadow(0 0 7px rgba(232, 178, 58, 0.75)); } }
.rkbadge { height: 15px; margin-right: 6px; image-rendering: pixelated; flex: none; } .rkbadge { height: 15px; margin-right: 6px; image-rendering: pixelated; flex: none; }
/* THE LEVEL STRIP: the one meta number over a thin bar, riding the splash foot. The fill colour
is the acid accent for now; the leagues will hand it the skill colour in phase 3. */
#xpRow { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; }
#xpRow u { font: 700 9px Silkscreen, monospace; color: var(--cream); text-decoration: none;
letter-spacing: 1px; white-space: nowrap; }
/* THE PLAYER PLAQUE (replaces the bare level strip): ONE button-styled panel — wappen, name,
level+league over the bar, and the standing GOAL LINE ("win the X cup to advance"), with a
chevron that says it opens. The splash stays two buttons + one plaque; the badge COLLECTION
stays on the card, one (now discoverable) tap away. */
#plaque { display: flex; align-items: center; gap: 12px; width: 100%; margin: 0 0 10px;
padding: 12px 14px; background: var(--solid); border: 2px solid var(--line);
border-radius: 8px;
cursor: pointer; text-align: left; -webkit-tap-highlight-color: transparent; }
#plBadge { height: 34px; flex: none; image-rendering: pixelated; }
#plBody { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
#plName { font: 700 10px Silkscreen, monospace; color: var(--cream); letter-spacing: 1.5px;
white-space: nowrap; overflow: hidden; }
#plRow { display: flex; align-items: center; gap: 8px; }
#plRow u { font: 700 8px Silkscreen, monospace; color: var(--dim); text-decoration: none;
letter-spacing: 1px; white-space: nowrap; }
#plGoal { font: 400 8px Silkscreen, monospace; font-style: normal; color: var(--acid);
letter-spacing: 1px; }
#plaque em { flex: none; font: 700 16px Silkscreen, monospace; font-style: normal; color: var(--acid); }
#plRow s, #cdBar s, #cdCareer s { flex: 1; height: 6px; background: rgba(255,255,255,0.10);
border: 1px solid var(--line); text-decoration: none; display: block; }
#cdBar s { height: 8px; }
#cdCareer { display: flex; align-items: center; gap: 8px; }
#cdCareer u { font: 700 8px Silkscreen, monospace; color: var(--dim); text-decoration: none;
letter-spacing: 1px; }
/* THE LEAGUE PANEL: the setup's league-mode face. The badge breathes like the card's, the /* THE LEAGUE PANEL: the setup's league-mode face. The badge breathes like the card's, the
name is the announcement face in the league's own colour, and the band's roster stands in a name is the announcement face in the league's own colour, and the band's roster stands in a
row — felled bodies in colour with their all-time count, the rest grey and waiting. */ row — felled bodies in colour with their all-time count, the rest grey and waiting. */
@@ -374,29 +348,29 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
-webkit-mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; -webkit-mask-size: 100% 100%; -webkit-mask-repeat: no-repeat;
mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%20200%2024%22%20shape-rendering=%22crispEdges%22%3E%3Cg%20fill=%22%23000%22%3E%3Crect%20x=%220%22%20y=%220%22%20width=%22140%22%20height=%2224%22/%3E%3Crect%20x=%22140%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22140%22%20y=%226%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22140%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22140%22%20y=%2218%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22146%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22146%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22152%22%20y=%226%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22152%22%20y=%2218%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22158%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22158%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22170%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22170%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3C/g%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%20200%2024%22%20shape-rendering=%22crispEdges%22%3E%3Cg%20fill=%22%23000%22%3E%3Crect%20x=%220%22%20y=%220%22%20width=%22140%22%20height=%2224%22/%3E%3Crect%20x=%22140%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22140%22%20y=%226%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22140%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22140%22%20y=%2218%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22146%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22146%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22152%22%20y=%226%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22152%22%20y=%2218%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22158%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22158%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22170%22%20y=%220%22%20width=%226%22%20height=%226%22/%3E%3Crect%20x=%22170%22%20y=%2212%22%20width=%226%22%20height=%226%22/%3E%3C/g%3E%3C/svg%3E");
mask-size: 100% 100%; mask-repeat: no-repeat; } mask-size: 100% 100%; mask-repeat: no-repeat; }
/* THE LEVEL STRIP: the one meta number over a thin bar, riding the splash foot. The fill colour /* THE PLAYER PLAQUE: centred under the title on a TRANSLUCENT surface (no solid panel — the
is the acid accent for now; the leagues will hand it the skill colour in phase 3. */ splash art, blood pool included, stays visible through and around it; Oliver's call, the
#xpRow { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; } solid panel in the foot sat exactly on the backdrop's blood). LEVEL · LEAGUE wears the
#xpRow u { font: 700 9px Silkscreen, monospace; color: var(--cream); text-decoration: none; announcement face now, writ large; the goal line stands under the bar; the chevron on the
letter-spacing: 1px; white-space: nowrap; } right edge says the whole thing opens. The badge COLLECTION stays on the card. */
/* THE PLAYER PLAQUE (replaces the bare level strip): ONE button-styled panel — wappen, name, #plaque { position: relative; display: flex; flex-direction: column; align-items: center;
level+league over the bar, and the standing GOAL LINE ("win the X cup to advance"), with a gap: 6px; margin: 22px auto 0; width: auto; max-width: 88%;
chevron that says it opens. The splash stays two buttons + one plaque; the badge COLLECTION padding: 14px 40px 12px; background: rgba(8, 14, 10, 0.48); border: 0;
stays on the card, one (now discoverable) tap away. */ border-radius: 12px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
#plaque { display: flex; align-items: center; gap: 12px; width: 100%; margin: 0 0 10px; #plBadge { height: 46px; image-rendering: pixelated;
padding: 12px 14px; background: var(--solid); border: 2px solid var(--line); filter: drop-shadow(0 2px 4px rgba(0,0,0,0.5)); }
border-radius: 8px; #plName { font: 700 11px Silkscreen, monospace; color: var(--cream); letter-spacing: 2px;
cursor: pointer; text-align: left; -webkit-tap-highlight-color: transparent; } white-space: nowrap; }
#plBadge { height: 34px; flex: none; image-rendering: pixelated; } #plLv { font: 400 27px Bangers, cursive; color: var(--acid); letter-spacing: 1.5px;
#plBody { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; } text-decoration: none; text-shadow: 2px 2px 0 rgba(0,0,0,0.5); }
#plName { font: 700 10px Silkscreen, monospace; color: var(--cream); letter-spacing: 1.5px; #plRow { display: block; width: 200px; max-width: 100%; }
white-space: nowrap; overflow: hidden; } /* NO nowrap here: the longest goal line is ~380px and a nowrap child sets the CARD's
#plRow { display: flex; align-items: center; gap: 8px; } min-content past the viewport — that was the phantom horizontal scrollbar Oliver spotted */
#plRow u { font: 700 8px Silkscreen, monospace; color: var(--dim); text-decoration: none; #plGoal { font: 400 9px Silkscreen, monospace; font-style: normal; color: var(--warm);
letter-spacing: 1px; white-space: nowrap; } letter-spacing: 1px; text-shadow: 1px 1px 0 rgba(0,0,0,0.5); text-align: center;
#plGoal { font: 400 8px Silkscreen, monospace; font-style: normal; color: var(--acid); line-height: 1.6; }
letter-spacing: 1px; } #plaque em { position: absolute; right: 13px; top: 50%; margin-top: -8px;
#plaque em { flex: none; font: 700 16px Silkscreen, monospace; font-style: normal; color: var(--acid); } font: 700 15px Silkscreen, monospace; font-style: normal; color: var(--acid); }
#plRow s, #cdBar s, #cdCareer s { flex: 1; height: 6px; background: rgba(255,255,255,0.10); #plRow s, #cdBar s, #cdCareer s { flex: 1; height: 6px; background: rgba(255,255,255,0.10);
border: 1px solid var(--line); text-decoration: none; display: block; } border: 1px solid var(--line); text-decoration: none; display: block; }
#cdBar s { height: 8px; } #cdBar s { height: 8px; }
@@ -651,6 +625,16 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
<div class="mid"> <div class="mid">
<img class="logo" src="assets/logo.png" alt="Splatter Tennis"> <img class="logo" src="assets/logo.png" alt="Splatter Tennis">
<p class="slogan">Fifteen. Thirty. Forty. <b>Dead.</b></p> <p class="slogan">Fifteen. Thirty. Forty. <b>Dead.</b></p>
<!-- THE PLAYER PLAQUE (the leagues): centred under the title on a translucent surface,
so the foot's blood pool stays visible. One tap opens the card (refreshSplash fills). -->
<button id="plaque">
<img id="plBadge" alt="">
<b id="plName"></b>
<u id="plLv">LEVEL 1</u>
<span id="plRow"><s><i id="plFill"></i></s></span>
<i id="plGoal"></i>
<em>&gt;</em>
</button>
</div> </div>
<div class="foot bare"> <div class="foot bare">
<!-- THE BOOT BAR. Every sprite is requested the moment render.js is imported; this only <!-- THE BOOT BAR. Every sprite is requested the moment render.js is imported; this only
@@ -658,17 +642,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
you can press before the sheets have landed is how you reach the stats screen with half you can press before the sheets have landed is how you reach the stats screen with half
the zombies missing. Swapped by #splash.busy, see main.js. --> the zombies missing. Swapped by #splash.busy, see main.js. -->
<div id="boot"><s><i></i></s><u>LOADING</u></div> <div id="boot"><s><i></i></s><u>LOADING</u></div>
<!-- THE PLAYER PLAQUE (the leagues): wappen, name, level+league, the bar, and the
standing goal line. One tap opens the character card. Filled by refreshSplash. -->
<button id="plaque">
<img id="plBadge" alt="">
<span id="plBody">
<b id="plName"></b>
<span id="plRow"><u id="plLv">LEVEL 1</u><s><i id="plFill"></i></s></span>
<i id="plGoal"></i>
</span>
<em>&gt;</em>
</button>
<button class="btn big" id="mStart">PLAY MATCH</button> <button class="btn big" id="mStart">PLAY MATCH</button>
<div class="two"> <div class="two">
<button class="btn sec" id="mStats">STATS<i id="mKills">0 KILLS</i></button> <button class="btn sec" id="mStats">STATS<i id="mKills">0 KILLS</i></button>
@@ -920,6 +893,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
</div> </div>
</div> </div>
</div> </div>
<script type="module" src="src/main.js?v=325"></script> <script type="module" src="src/main.js?v=326"></script>
</body> </body>
</html> </html>