Phase 4 of turning the game into the company landing page. - Only the menu button, a compact objective chip and the touch controls stay on screen; speed shows only while driving. - The objective chip shows the next goal in one line, its distance and an arrow that turns towards it (replaces the compass strip); tapping it opens the mission list. - One floating menu holds map, missions, status, products, real-world, camera, stable mode, sound, graphics, minimap, fullscreen, help, restart and back to the start screen. It closes on a second tap, a tap outside, Escape, or after an action. - Missions, status and help open as sheets; street label, rank bar, status panel, toolbar and compass are gone. The minimap is optional and off by default. - Share the icon set and sheet dialog between start screen and HUD. - Layout checked for phone portrait, landscape and safe areas. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
46 lines
1.8 KiB
JavaScript
46 lines
1.8 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { gameTheme } from './gameTheme.js';
|
|
|
|
/**
|
|
* Collects every CSS value in the theme, including those inside media blocks.
|
|
* @param {object} rules - Theme rules keyed by selector or at-rule.
|
|
* @returns {string[]} All declaration values.
|
|
*/
|
|
function allValues(rules) {
|
|
return Object.values(rules).flatMap((body) =>
|
|
Object.values(body).flatMap((value) =>
|
|
typeof value === 'object' ? allValues({ value }) : [value],
|
|
),
|
|
);
|
|
}
|
|
|
|
describe('game theme', () => {
|
|
it('uses no negated var(), which browsers drop as invalid', () => {
|
|
expect(allValues(gameTheme).filter((value) => String(value).includes('-var('))).toEqual([]);
|
|
});
|
|
|
|
it('keeps the floating menu and objective clear of the phone notch', () => {
|
|
expect(gameTheme['#game-menu'].top).toContain('safe-area-inset-top');
|
|
expect(gameTheme['#objective'].top).toContain('safe-area-inset-top');
|
|
});
|
|
|
|
it('gives every floating menu item a 44px tap target', () => {
|
|
expect(gameTheme['.menu-item']['min-height']).toBe('var(--game-token-32)');
|
|
expect(gameTheme[':root']['--game-token-32']).toBe('44px');
|
|
});
|
|
|
|
it('keeps the landscape phone layout as a top-level media block', () => {
|
|
expect(gameTheme['@media (max-height: 520px)']?.['#minimap-button']).toBeDefined();
|
|
expect(gameTheme['@media (max-width: 760px)']['@media (max-height: 520px)']).toBeUndefined();
|
|
});
|
|
|
|
it('lets the start screen scroll so its buttons stay reachable on short screens', () => {
|
|
expect(gameTheme['#landing']['overflow-y']).toBe('auto');
|
|
});
|
|
|
|
it('keeps start screen buttons large enough to tap', () => {
|
|
expect(gameTheme['.start-option']['min-height']).toBe('var(--game-token-77)');
|
|
expect(gameTheme['.start-chip']['min-height']).toBe('var(--game-token-74)');
|
|
});
|
|
});
|