diff --git a/config.js b/config.js index 0fa1e0c..661a4ea 100644 --- a/config.js +++ b/config.js @@ -490,6 +490,10 @@ export const ENEMIES = { h: { name: 'THE BOUNCER', spr: 'z_h1', sub: 'BUILT LIKE A DOOR' }, k: { name: 'THE ROLLER MAN', spr: 'z_k1', sub: 'HAULS THE COURT ROLLER' }, s: { name: 'THE SPECTATOR', spr: 'z_s1', sub: 'BLOCKS WITH HIS CHAIR' }, + // The man you were playing, after the transition turns him (gameplay.js spawns him as 'c'). One + // per run, and he is NOT the racket zombie below — that one keeps coming back. Missing this row + // is what put a second "SHAMBLER" on the screen: an unmapped key falls back to the shambler art. + c: { name: 'THE OPPONENT', spr: 'z_c1', sub: 'HE TURNED MID-MATCH' }, r: { name: 'THE CLUB PRO', spr: 'z_c1', sub: 'STILL HAS A BACKHAND' }, m: { name: 'THE BALL MACHINE', spr: 'z_mach1', sub: 'FIRES BACK · FURNITURE' }, }; diff --git a/index.html b/index.html index ae9ae8c..663eac7 100644 --- a/index.html +++ b/index.html @@ -91,7 +91,7 @@ rgba(12,20,17,0.58) 100%), url('assets/menu_bg.png?v=86') 50% 42% / cover no-repeat var(--ink); image-rendering: pixelated; } - #intro .card { font: 400 11px 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); animation: drop 0.5s ease-out; } @keyframes drop { from { transform: translateY(-14px); opacity: 0; } } @@ -130,8 +130,8 @@ for SET and CHAPTER. A screen title is a thing that shouts. Everything that is a NUMBER or a label stays Silkscreen, so the two registers keep meaning what they have always meant. */ #intro h2 { margin: 0; font: 400 26px Bangers, cursive; color: var(--acid); letter-spacing: 1.5px; } - #intro h3 { display: flex; justify-content: space-between; margin: 18px 0 8px; - font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 2px; + #intro h3 { display: flex; justify-content: space-between; margin: 20px 0 9px; + font: 400 10px Silkscreen, monospace; color: var(--dim); letter-spacing: 2px; text-align: left; } /* header strip: back chevron + title. Every screen but the splash wears one, pinned to the top. */ .hdr { position: sticky; top: 0; z-index: 3; display: flex; align-items: center; gap: 10px; @@ -146,8 +146,8 @@ .figs { display: flex; border: 2px solid var(--line); background: var(--panel); } .fig { flex: 1; min-width: 0; padding: 7px 6px; text-align: center; } .fig + .fig { border-left: 2px solid var(--line); } - .fig b { display: block; font: 400 8px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; } - .fig i { display: block; font: 700 15px Silkscreen, monospace; color: var(--acid); + .fig b { display: block; font: 400 9px 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); } /* one button look for every menu screen */ @@ -156,7 +156,7 @@ straight through the lettering, and the button stops reading as a button. */ .btn { display: block; width: 100%; margin: 0 auto 10px; padding: 12px 10px; background: var(--solid); border: 2px solid var(--line); color: var(--cream); - font: 400 12px Silkscreen, monospace; letter-spacing: 1px; cursor: pointer; + font: 400 13px Silkscreen, monospace; letter-spacing: 1px; cursor: pointer; -webkit-tap-highlight-color: transparent; } /* The generated button plates are gone with the tutorial. The primary is a flat crimson block now: it survives being resized, which a fixed-size plate crop never did, and the mockup's @@ -165,7 +165,7 @@ font: 400 26px Bangers, cursive; letter-spacing: 2px; line-height: 1.15; } .two { display: flex; gap: 8px; } .two .btn { margin-bottom: 0; } - .btn.sec i { display: block; margin-top: 3px; font: 400 8px Silkscreen, monospace; + .btn.sec i { display: block; margin-top: 4px; font: 400 9px Silkscreen, monospace; font-style: normal; color: var(--dim); letter-spacing: 0.5px; } /* the tour: two tiles SIDE BY SIDE, not two more full-width rows. The figures face the camera — in play you only ever see your player from behind, so a rear view would show nothing. */ @@ -175,7 +175,7 @@ color: inherit; font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; } #tours button.on { border-color: var(--acid); background: rgba(188,212,85,0.09); } #tours img { height: 88px; width: auto; display: block; image-rendering: pixelated; } - #tours b { font: 400 10px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; } + #tours b { font: 400 11px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; } /* a row, not a stacked tile: three 3:2 tiles stacked fill a phone twice over, and the art still reads at this size. -webkit-tap-highlight-color kills iOS's blue flash over the pixel art. */ #courtList button.court { display: flex; align-items: center; gap: 11px; width: 100%; @@ -186,13 +186,13 @@ #courtList img { width: 92px; height: 66px; display: block; image-rendering: pixelated; flex: none; object-fit: cover; } #courtList .cb { flex: 1; min-width: 0; } - #courtList b { display: block; font: 400 11px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; } - #courtList i { display: block; margin: 2px 0 5px; font: 400 8px Silkscreen, monospace; color: var(--dim); font-style: normal; } + #courtList b { display: block; font: 400 12px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; } + #courtList i { display: block; margin: 3px 0 6px; font: 400 9px Silkscreen, monospace; color: var(--dim); 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: 3px; - font: 400 7px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; } - .meter u { flex: none; width: 40px; text-decoration: none; } + .meter { display: flex; align-items: center; gap: 6px; margin-top: 4px; + font: 400 8px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; } + .meter u { flex: none; width: 46px; text-decoration: none; } .meter s { flex: 1; height: 5px; background: rgba(0,0,0,0.45); text-decoration: none; display: block; } .meter s > i { display: block; height: 100%; background: var(--acid); } .meter.b s > i { background: #4e8fa6; } @@ -207,49 +207,49 @@ .foot.bare { border: 0; background: none; } .foot.bare .btn.big { margin-bottom: 10px; } #sSum { display: flex; justify-content: space-between; gap: 8px; margin: 0 0 8px; - font: 400 8px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; } + font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; } .tabs { display: flex; gap: 6px; margin: 12px 0 14px; } - .tabs button { flex: 1; padding: 9px 2px; background: var(--panel); border: 2px solid var(--line); - color: var(--dim); font: 400 8px Silkscreen, monospace; letter-spacing: 1px; + .tabs button { flex: 1; padding: 11px 2px; background: var(--panel); border: 2px solid var(--line); + color: var(--dim); font: 400 10px Silkscreen, monospace; letter-spacing: 1px; cursor: pointer; -webkit-tap-highlight-color: transparent; } .tabs button.on { border-color: var(--acid); color: var(--acid); } /* one opponent. The sprite is the walk frame the game already draws, sat on its own baseline. */ - .zrow { display: flex; align-items: center; gap: 10px; padding: 7px 9px; margin-bottom: 6px; + .zrow { display: flex; align-items: center; gap: 11px; padding: 9px 10px; margin-bottom: 6px; border: 2px solid var(--line); background: var(--panel); text-align: left; } .zrow.boss { border-color: #6e2a24; background: rgba(110,42,36,0.22); } - .zrow img { width: 34px; height: 46px; object-fit: contain; object-position: bottom; + .zrow img { width: 48px; height: 62px; object-fit: contain; object-position: bottom; image-rendering: pixelated; flex: none; } .zb { flex: 1; min-width: 0; display: grid; grid-template-columns: 1fr auto; gap: 0 8px; line-height: 1.4; } - .zb b { font: 400 10px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; + .zb b { font: 400 12px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } - .zb > span { font: 700 12px Silkscreen, monospace; color: var(--acid); text-align: right; } + .zb > span { font: 700 15px Silkscreen, monospace; color: var(--acid); text-align: right; } .zrow.boss .zb > span { color: var(--bad); } - .pb { grid-column: 1 / -1; height: 5px; margin-top: 4px; background: rgba(0,0,0,0.45); } + .pb { grid-column: 1 / -1; height: 6px; margin-top: 4px; background: rgba(0,0,0,0.45); } .pb s { display: block; height: 100%; background: var(--acid); text-decoration: none; } .zrow.boss .pb s { background: var(--bad); } - .zb i { grid-column: 1 / -1; margin-top: 3px; font: 400 7px Silkscreen, monospace; + .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 54px; max-width: 76px; padding: 6px 2px; border: 2px solid var(--line); + .wtile { flex: 1 1 62px; max-width: 84px; padding: 8px 2px; border: 2px solid var(--line); background: var(--panel); } - .wtile img { width: 26px; height: 26px; object-fit: contain; display: block; margin: 0 auto 2px; + .wtile img { width: 34px; height: 34px; object-fit: contain; display: block; margin: 0 auto 2px; image-rendering: pixelated; } - .wtile b { display: block; font: 400 9px Silkscreen, monospace; color: var(--acid); } - .none { margin: 4px 0 0; font: 400 8px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; + .wtile b { display: block; font: 400 11px Silkscreen, monospace; color: var(--acid); } + .none { margin: 4px 0 0; font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; text-align: left; } #stFoot { display: flex; justify-content: space-between; align-items: baseline; border-top: 2px solid var(--line); } - #stFoot b { font: 400 8px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; } - #stFoot i { font: 700 13px Silkscreen, monospace; color: var(--acid); font-style: normal; } + #stFoot b { font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; } + #stFoot i { font: 700 16px Silkscreen, monospace; color: var(--acid); font-style: normal; } .rkrow { display: flex; align-items: center; gap: 10px; padding: 8px 10px; margin-bottom: 5px; border: 2px solid var(--line); background: var(--panel); text-align: left; } .rkrow.me { border-color: var(--acid); background: rgba(188,212,85,0.11); } - .rkrow b { flex: none; width: 60px; font: 700 10px Silkscreen, monospace; color: var(--dim); } + .rkrow b { flex: none; width: 68px; font: 700 12px Silkscreen, monospace; color: var(--dim); } .rkrow.me b { color: var(--acid); } - .rkrow span { flex: 1; min-width: 0; font: 400 9px Silkscreen, monospace; color: var(--cream); + .rkrow span { flex: 1; min-width: 0; font: 400 11px Silkscreen, monospace; color: var(--cream); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } - .rkrow i { font: 400 9px Silkscreen, monospace; font-style: normal; color: var(--dim); } + .rkrow i { font: 400 11px Silkscreen, monospace; font-style: normal; color: var(--dim); }