The cup board: the league ranks, the level breaks the tie
Oliver wanted to rank the level a league was taken at. The challenge held: xp comes only from playing, so a board that rewards a low level rewards not playing — it would pay you to avoid the three rooms the season leans on. It also inverts every other number in the game, freezes after five entries, and makes the player who played more look worse. So the league ranks and the level decides between everyone who got equally far, where "lower is better" reads naturally. BOARDS.u carries subLow; server rank_key is the other half, and the same key decides whether a submission beats the row already standing. The level is written once at the promotion — before the league moves, because it is the level that WON the cup — mirrored like the rest of the profile, and inscribed under the shield it belongs to. Earned shields smoulder while they are on screen: five CSS embers each, no loop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e96b4374d8
commit
80eb60d181
8 files changed
+226
-40
No files matched your search
+50
-12
@@ -266,9 +266,15 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
/* four numbers read better two-up than four-across on a phone — at four the labels wrap and
|
||||
the row becomes a wall of two-line captions */
|
||||
.figs.pair { display: grid; grid-template-columns: 1fr 1fr; }
|
||||
.fig { flex: 1; min-width: 0; padding: 7px 6px; text-align: center; }
|
||||
.figs.pair .fig:nth-child(2n) { border-left: 2px solid var(--line); }
|
||||
.figs.pair .fig:nth-child(n+3) { border-top: 2px solid var(--line); }
|
||||
.fig { flex: 1; min-width: 0; padding: 11px 8px 12px; text-align: center; }
|
||||
.fig + .fig { border-left: 2px solid var(--line); }
|
||||
.fig b { display: block; font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; }
|
||||
/* THE NUMBER NEVER MOVES (2026-08-31, Oliver: "manchmal sind die überschriften ein- manchmal
|
||||
zweizeilig, das drückt die zahl runter"). The label gets two lines of room whether it needs
|
||||
them or not, so every figure in a row sits on the same baseline. */
|
||||
.fig b { display: flex; align-items: flex-start; justify-content: center; min-height: 22px;
|
||||
font: 400 9px/1.25 Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; }
|
||||
.fig i { display: block; font: 700 18px Silkscreen, monospace; color: var(--acid);
|
||||
font-style: normal; letter-spacing: 1px; }
|
||||
.fig.bad i { color: var(--bad); }
|
||||
@@ -344,18 +350,48 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
#cdTop { display: flex; gap: 14px; align-items: flex-start; margin-top: 14px; }
|
||||
#cdLook { position: static; display: block; flex: none; margin: 0; width: auto; height: 200px;
|
||||
touch-action: auto; image-rendering: pixelated; }
|
||||
#cdMeta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
|
||||
#cdBadge { width: 56px; image-rendering: pixelated; }
|
||||
#cdLeague { font: 700 10px Silkscreen, monospace; text-decoration: none; letter-spacing: 1.5px; }
|
||||
#cdLevel { font: 400 30px Bangers, cursive; color: var(--cream); letter-spacing: 1.5px; }
|
||||
#cdMeta { flex: 1; min-width: 0; display: grid; gap: 8px 11px; align-items: center;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-areas: "crest league" "crest level" "bar bar" "xp xp" "career career"; }
|
||||
/* THE CREST STANDS BESIDE THE LEAGUE (2026-08-31, Oliver: on its own row it pushed the text
|
||||
down), so the two things that say WHERE YOU ARE share a line instead of stacking. */
|
||||
#cdBadge { grid-area: crest; width: 56px; image-rendering: pixelated; align-self: center; }
|
||||
#cdLeague { grid-area: league; align-self: end; font: 700 10px/1.5 Silkscreen, monospace;
|
||||
text-decoration: none; letter-spacing: 1.5px; }
|
||||
#cdLeague i { display: block; font-style: normal; font-size: 9px; opacity: 0.85; }
|
||||
#cdBar { grid-area: bar; }
|
||||
#cdXp { grid-area: xp; }
|
||||
#cdCareer { grid-area: career; }
|
||||
#cdLevel { grid-area: level; align-self: start; font: 400 30px Bangers, cursive;
|
||||
color: var(--cream); letter-spacing: 1.5px; }
|
||||
#cdXp { display: block; margin-top: 5px; font: 400 9px Silkscreen, monospace; color: var(--dim);
|
||||
text-decoration: none; letter-spacing: 1px; }
|
||||
/* THE HONOURS ROW: a shield per league, and under an earned one the INSCRIPTION — the level it
|
||||
was taken at (the cup board's tie-break, in the one place a once-in-a-career figure belongs). */
|
||||
#cdBadges { display: flex; gap: 10px; align-items: flex-end; }
|
||||
#cdBadges .badge { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column;
|
||||
align-items: center; gap: 4px; }
|
||||
/* ...and an earned shield SMOULDERS: two-pixel embers drifting off it, each on its own delay and
|
||||
lane (main.embers). Pure CSS — the menu parks the game loop and this has no business waking it. */
|
||||
#cdBadges .badge em { position: absolute; bottom: 22px; width: 3px; height: 3px; background: #f2cf6a;
|
||||
box-shadow: 0 0 4px 1px rgba(232,178,58,0.55);
|
||||
opacity: 0; pointer-events: none; animation-name: ember;
|
||||
animation-timing-function: linear; animation-iteration-count: infinite; }
|
||||
@keyframes ember {
|
||||
0% { transform: translate(0, 0) scale(1); opacity: 0; }
|
||||
18% { opacity: 0.85; }
|
||||
60% { transform: translate(2px, -16px) scale(0.8); opacity: 0.5; }
|
||||
100% { transform: translate(-1px, -30px) scale(0.4); opacity: 0; } }
|
||||
@media (prefers-reduced-motion: reduce) { #cdBadges .badge em { display: none; } }
|
||||
#cdBadges img { height: 46px; image-rendering: pixelated; }
|
||||
#cdBadges .badge u { font: 700 7px Silkscreen, monospace; color: var(--acid); letter-spacing: 0.5px;
|
||||
text-decoration: none; white-space: nowrap; }
|
||||
#cdBadges .badge.dark img { filter: grayscale(1) brightness(0.3); }
|
||||
#cdBadges .badge.dark u { color: #3f4d45; }
|
||||
#cdBadges img.dark { filter: grayscale(1) brightness(0.3); }
|
||||
/* earned badges BREATHE — a subtle gold halo, CSS-only (the menu parks the game loop, CSS
|
||||
animations do not care). The dark slots stay dead, which is the point of them. */
|
||||
#cdBadges img:not(.dark), #cdBadge {
|
||||
#cdBadges .badge:not(.dark) img, #cdBadges img:not(.dark), #cdBadge {
|
||||
animation: badgeGlow 2.6s ease-in-out infinite; }
|
||||
@keyframes badgeGlow {
|
||||
0%, 100% { filter: drop-shadow(0 0 2px rgba(232, 178, 58, 0.25)); }
|
||||
@@ -687,9 +723,10 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
.zrow.boss .pb s { background: var(--bad); }
|
||||
.zb i { grid-column: 1 / -1; margin-top: 4px; font: 400 9px Silkscreen, monospace;
|
||||
font-style: normal; color: var(--dim); letter-spacing: 1px; }
|
||||
#stW { display: flex; flex-wrap: wrap; gap: 6px; }
|
||||
.wtile { flex: 1 1 62px; max-width: 84px; padding: 8px 2px; border: 2px solid var(--line);
|
||||
background: var(--panel); }
|
||||
/* a GRID, not a wrapping flex row: `flex: 1 1 62px` gave the last row's tiles the whole width
|
||||
to share, so a shelf of nine came out in three different sizes (Oliver) */
|
||||
#stW { display: grid; grid-template-columns: repeat(auto-fill, minmax(66px, 1fr)); gap: 6px; }
|
||||
.wtile { padding: 8px 2px; border: 2px solid var(--line); background: var(--panel); }
|
||||
.wtile img { width: 34px; height: 34px; object-fit: contain; display: block; margin: 0 auto 2px;
|
||||
image-rendering: pixelated; }
|
||||
.wtile b { display: block; font: 400 11px Silkscreen, monospace; color: var(--acid); }
|
||||
@@ -996,7 +1033,8 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
<!-- TWO boards, not three (2026-08-31): classic tennis is out of competition by design now
|
||||
— no league, no record, no stakes — so ranking it contradicted the room it lives in. -->
|
||||
<div class="tabs" id="rkModes">
|
||||
<button class="on" data-m="g">SPLATTER</button>
|
||||
<button class="on" data-m="u">THE CUP</button>
|
||||
<button data-m="g">SPLATTER</button>
|
||||
<button data-m="z">THE CLIMB</button>
|
||||
</div>
|
||||
<h3 id="rkHdr">BEST SINGLE RUN<span>KILLS · GAMES</span></h3>
|
||||
@@ -1038,6 +1076,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="src/main.js?v=342"></script>
|
||||
<script type="module" src="src/main.js?v=343"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user