The leagues, the polish round: the way-up ribbon, upright chevrons, the breathing badges, the card counts up
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
87ac3294bc
commit
fa6db7f77b
4 files changed
+113
-42
No files matched your search
+43
-25
@@ -209,8 +209,10 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
background: var(--solid);
|
||||
padding-top: max(10px, env(safe-area-inset-top)); }
|
||||
.hdr h2 { padding-left: 2px; }
|
||||
/* UPRIGHT, not Bangers: the announcement face is drawn slanted, and a slanted arrow read as
|
||||
italic on every screen. Silkscreen's ASCII < > are straight pixel arrows. */
|
||||
.chev { width: 34px; height: 34px; flex: none; background: none; border: 2px solid var(--line);
|
||||
color: var(--acid); font: 400 20px Bangers, cursive; line-height: 1; cursor: pointer;
|
||||
color: var(--acid); font: 700 14px Silkscreen, monospace; line-height: 1; cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent; }
|
||||
/* the BODY COUNT headline row: three boxed figures sharing one frame */
|
||||
.figs { display: flex; border: 2px solid var(--line); background: var(--panel); }
|
||||
@@ -291,6 +293,13 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
#cdBadges { display: flex; gap: 10px; align-items: flex-end; }
|
||||
#cdBadges img { height: 46px; image-rendering: pixelated; }
|
||||
#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 {
|
||||
animation: badgeGlow 2.6s ease-in-out infinite; }
|
||||
@keyframes badgeGlow {
|
||||
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)); } }
|
||||
.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. */
|
||||
@@ -301,8 +310,9 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
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: 10px; width: 100%; margin: 0 0 10px;
|
||||
padding: 8px 10px; background: var(--solid); border: 2px solid var(--line);
|
||||
#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; }
|
||||
@@ -313,20 +323,27 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
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: 400 22px Bangers, cursive; font-style: normal; color: var(--acid); }
|
||||
#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 mode picker's WAY-UP tag: the standing answer to "how do I advance", worn by the cup */
|
||||
.way { position: absolute; top: 8px; left: 8px; padding: 3px 6px; font: 700 8px Silkscreen, monospace;
|
||||
font-style: normal; color: var(--ink); background: var(--acid); letter-spacing: 1px;
|
||||
text-decoration: none; }
|
||||
/* the WAY-UP RIBBON: the standing answer to "how do I advance", worn as a banderole wrapped
|
||||
over the poster's corner (Oliver: bigger, red, thick white type, light shadow). The poster
|
||||
clips its ends diagonally (overflow hidden + the -45deg rotation), which is what sells the
|
||||
wrap. */
|
||||
.way { position: absolute; top: 20px; left: -42px; width: 150px; transform: rotate(-45deg);
|
||||
padding: 6px 0; font: 700 11px Silkscreen, monospace; font-style: normal;
|
||||
text-align: center; color: #fff; background: var(--red);
|
||||
border-top: 1px solid rgba(255,255,255,0.35); border-bottom: 1px solid #69201c;
|
||||
text-shadow: 1px 1px 0 rgba(0,0,0,0.55); box-shadow: 0 2px 6px rgba(0,0,0,0.4);
|
||||
letter-spacing: 1px; text-decoration: none; }
|
||||
#plRow s i, #cdBar s i, #cdCareer s i { display: block; height: 100%; width: 0%;
|
||||
background: linear-gradient(90deg, #3f9560, var(--acid) 55%, #e8b23a);
|
||||
transition: width 0.4s ease; }
|
||||
#cdBar s i, #cdCareer s i { transition: width 0.7s cubic-bezier(0.2, 0.7, 0.3, 1); }
|
||||
/* KIT and SKIN: a row of colour squares, under a label that names whatever is selected. That is
|
||||
the whole UI — the pick has no meters and no art to show, and a labelled tile per colour would
|
||||
be five times the screen for a choice you make by looking at the colour. */
|
||||
@@ -391,7 +408,8 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
a live answer to the header's question; tapping answers and advances. The only memory shown is
|
||||
the LAST tag — an indicator, not a selection. A border that means "SERVE UP will use this"
|
||||
exists solely on the final screen, where a confirm button actually follows. */
|
||||
#modeList button.mode, #modeSub button.mode { display: flex; align-items: flex-end; width: 100%; min-height: 96px;
|
||||
#modeList button.mode, #modeSub button.mode { overflow: hidden; /* clips the WAY-UP ribbon's ends */
|
||||
display: flex; align-items: flex-end; width: 100%; min-height: 96px;
|
||||
margin: 0 0 8px; padding: 7px 9px; background-size: cover; background-position: center bottom;
|
||||
image-rendering: pixelated; border: 2px solid var(--line); color: inherit; font: inherit;
|
||||
text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent;
|
||||
@@ -425,8 +443,8 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
#courtList img { width: 92px; height: 66px; display: block; image-rendering: pixelated; flex: none;
|
||||
object-fit: cover; }
|
||||
#courtList .cb, #modeList .cb, #modeSub .cb { flex: 1; min-width: 0; }
|
||||
#courtList b, #modeList b, #modeSub b { display: block; font: 400 12px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; }
|
||||
#courtList i, #modeList i, #modeSub i { display: block; margin: 3px 0 6px; font: 400 9px Silkscreen, monospace; color: var(--dim); font-style: normal; }
|
||||
#courtList b, #modeList b, #modeSub b { display: block; font: 700 15px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; }
|
||||
#courtList i, #modeList i, #modeSub i { display: block; margin: 4px 0 6px; font: 400 10px Silkscreen, monospace; color: #c9c4b8; font-style: normal; }
|
||||
/* The two meters read straight off the court's own bounce numbers (see main.js), so they cannot
|
||||
drift away from what the ball actually does on it. */
|
||||
.meter { display: flex; align-items: center; gap: 6px; margin-top: 4px;
|
||||
@@ -587,7 +605,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
<span id="plRow"><u id="plLv">LEVEL 1</u><s><i id="plFill"></i></s></span>
|
||||
<i id="plGoal"></i>
|
||||
</span>
|
||||
<em>›</em>
|
||||
<em>></em>
|
||||
</button>
|
||||
<button class="btn big" id="mStart">PLAY MATCH</button>
|
||||
<div class="two">
|
||||
@@ -605,15 +623,15 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
who-and-where with SERVE UP. Every step comes up pre-selected from last time, so a
|
||||
returning player is three taps from serving. -->
|
||||
<div id="stmode">
|
||||
<div class="hdr"><button class="chev" id="mBack">‹</button><h2>PICK A GAME</h2></div>
|
||||
<div class="hdr"><button class="chev" id="mBack"><</button><h2>PICK A GAME</h2></div>
|
||||
<div id="modeList"></div>
|
||||
</div>
|
||||
<div id="stsub">
|
||||
<div class="hdr"><button class="chev" id="subBack">‹</button><h2 id="subTitle">DIFFICULTY</h2></div>
|
||||
<div class="hdr"><button class="chev" id="subBack"><</button><h2 id="subTitle">DIFFICULTY</h2></div>
|
||||
<div id="modeSub"></div>
|
||||
</div>
|
||||
<div id="setup">
|
||||
<div class="hdr"><button class="chev" id="sBack">‹</button><h2>MATCH SETUP</h2></div>
|
||||
<div class="hdr"><button class="chev" id="sBack"><</button><h2>MATCH SETUP</h2></div>
|
||||
<!-- ONE PLAYER BLOCK. It was four stacked sections — two big portrait tiles, then the live
|
||||
player, then a kit row, then a skin row — which said the same thing twice (the tiles were
|
||||
a second, FRONT-FACING drawing of a man who does not react to any of the colours) and ran
|
||||
@@ -644,7 +662,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
keys), so the two screens cannot disagree about who you are. Rebuilt on every visit by
|
||||
main.buildPlayer, so the .on states track the setup screen's. -->
|
||||
<div id="player">
|
||||
<div class="hdr"><button class="chev" id="pBack">‹</button><h2>YOUR PLAYER</h2></div>
|
||||
<div class="hdr"><button class="chev" id="pBack"><</button><h2>YOUR PLAYER</h2></div>
|
||||
<h3>NAME<span>YOURS ON EVERY BOARD</span></h3>
|
||||
<div id="nameRow">
|
||||
<input id="pName" class="tin" maxlength="12" autocomplete="off" spellcheck="false">
|
||||
@@ -684,7 +702,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
main.buildCard from the profile + stats; the honours row shows every badge slot, earned
|
||||
bright and unearned dark. -->
|
||||
<div id="card">
|
||||
<div class="hdr"><button class="chev" id="cdBack">‹</button><h2 id="cdName">YOUR PLAYER</h2></div>
|
||||
<div class="hdr"><button class="chev" id="cdBack"><</button><h2 id="cdName">YOUR PLAYER</h2></div>
|
||||
<div id="cdTop">
|
||||
<canvas id="cdLook" width="96" height="224"></canvas>
|
||||
<div id="cdMeta">
|
||||
@@ -710,7 +728,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
(main.js hands the settled rungs to startMatch). The rows are built in main.js from
|
||||
config.CUP_ROUNDS, so a round added there needs no markup. -->
|
||||
<div id="bracket">
|
||||
<div class="hdr"><button class="chev" id="brBack">‹</button><h2>THE DRAW</h2></div>
|
||||
<div class="hdr"><button class="chev" id="brBack"><</button><h2>THE DRAW</h2></div>
|
||||
<h3>FOUR ROUNDS<span id="brState">DRAWING…</span></h3>
|
||||
<div id="cupRows"></div>
|
||||
<div class="foot">
|
||||
@@ -721,7 +739,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
<!-- THE TRAINING COURT's opponent picker: the whole ladder face-up, tap a body to drill it.
|
||||
Built in main.js from config's roster (matchFoe/LADDER), so a new rung needs no markup. -->
|
||||
<div id="train">
|
||||
<div class="hdr"><button class="chev" id="trBack">‹</button><h2>TRAINING</h2></div>
|
||||
<div class="hdr"><button class="chev" id="trBack"><</button><h2>TRAINING</h2></div>
|
||||
<h3>PICK YOUR OPPONENT<span>ONE GAME · GO AGAIN</span></h3>
|
||||
<div id="trainList"></div>
|
||||
</div>
|
||||
@@ -730,7 +748,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
a socket is open, so the room code and its SHARE button stand where the buttons were and
|
||||
the game stays parked behind this overlay until the room fills (main.js, THE LOBBY). -->
|
||||
<div id="vs">
|
||||
<div class="hdr"><button class="chev" id="vsBack">‹</button><h2>VS A FRIEND</h2></div>
|
||||
<div class="hdr"><button class="chev" id="vsBack"><</button><h2>VS A FRIEND</h2></div>
|
||||
<div id="vsPick">
|
||||
<h3>01 · YOUR NAME<span>ON THEIR SCOREBOARD</span></h3>
|
||||
<input id="vsName" class="tin" maxlength="12" placeholder="YOUR NAME" autocomplete="off"
|
||||
@@ -758,7 +776,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
</div>
|
||||
<!-- BODY COUNT. Every row in here is built by stats.js from the run records in localStorage. -->
|
||||
<div id="stats">
|
||||
<div class="hdr"><button class="chev" id="stBack">‹</button><h2 id="stTitle">BODY COUNT</h2></div>
|
||||
<div class="hdr"><button class="chev" id="stBack"><</button><h2 id="stTitle">BODY COUNT</h2></div>
|
||||
<!-- WHICH MODE, then which period. The three modes do not measure the same thing (see the
|
||||
record-shape note in stats.endRun), so this strip changes the whole screen under it —
|
||||
the title, the three figures, the roster's heading and the footer. -->
|
||||
@@ -783,7 +801,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
a ranking. Same tab strip as the stats screen's, and stats.drawRanks rewrites the column
|
||||
heading with the tab, because the number means something different on each one. -->
|
||||
<div id="ranks">
|
||||
<div class="hdr"><button class="chev" id="rkBack">‹</button><h2>WORLD BOARD</h2></div>
|
||||
<div class="hdr"><button class="chev" id="rkBack"><</button><h2>WORLD BOARD</h2></div>
|
||||
<div class="tabs" id="rkModes">
|
||||
<button class="on" data-m="g">SPLATTER</button>
|
||||
<button data-m="z">TENNIS</button>
|
||||
@@ -796,7 +814,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
at it, which is the whole point: it replaced a triple-tap on the in-play scoreboard that
|
||||
players kept tripping by accident. -->
|
||||
<div id="secret">
|
||||
<div class="hdr"><button class="chev" id="scBack">‹</button><h2>BACK ROOM</h2></div>
|
||||
<div class="hdr"><button class="chev" id="scBack"><</button><h2>BACK ROOM</h2></div>
|
||||
<div class="foot bare">
|
||||
<button class="btn big" id="scWeapons">WEAPON TEST</button>
|
||||
<button class="btn big" id="scBosses">BOSS TEST</button>
|
||||
@@ -808,7 +826,7 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
<!-- one tile per chapter boss, built from config.bossArt in main.js: adding a design to the
|
||||
roster puts it on this screen and never touches this markup -->
|
||||
<div id="bosses">
|
||||
<div class="hdr"><button class="chev" id="bsBack">‹</button><h2>BOSS TEST</h2></div>
|
||||
<div class="hdr"><button class="chev" id="bsBack"><</button><h2>BOSS TEST</h2></div>
|
||||
<h3>PICK A CHAPTER<span>FULL ARSENAL</span></h3>
|
||||
<div id="bossList"></div>
|
||||
</div>
|
||||
@@ -828,6 +846,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="src/main.js?v=316"></script>
|
||||
<script type="module" src="src/main.js?v=317"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user