# Browser UI style ## 1. Purpose This document defines the canonical visual language, controls, responsive layout, and presentation behavior for every maze32 browser mode. Product rules remain in `MVP.md`, and browser authority boundaries remain in `ARCHITECTURE.md`. ## 2. Visual direction and tone - Use a dark retro arcade-game style throughout network provisioning, name selection, lobby, player, and observer modes. - Use humorous copy, imagery, animation, object names, and suggested player names wherever the game remains clear and usable. - Humor must be understandable to children, non-offensive, and based on internet humor that is current when the release is designed. Runtime access to external meme or content services is forbidden. - Use only a dark theme. A light theme is outside the MVP. - Use small SVG icons, pixel-art graphics, or graphics styled to resemble pixel art. Locally authored icons must not require an external icon library. - Use a system monospace font stack with CSS pixel-style treatment. The UI must not download Google Fonts or any other external font at runtime. ## 3. Color system The exact color values may be tuned during implementation, but their semantic roles must remain stable: - black or near-black for the application and map background; - purple for panels and elevated surfaces; - turquoise for interactive accents; - yellow for Player 1 and blue for Player 2 across every screen, map object, and message; each player's matching key and exit use the same ownership color; - green for success, amber for warnings, red for errors, periwinkle for pause, and orange for disconnection; - green vegetation, bushes, and plants for maze walls. When two semantic roles use related colors, icons, labels, outlines, or shapes must keep them unambiguous. Important player and object information must not be communicated by color alone. Key objects use an additional label, outline, or marker. The gameplay icon family is locally authored SVG artwork derived from the approved running-player, key, arched-exit, crystal, opened-exit, and spike reference silhouettes. The spike icon remains a catalog asset only; blocked movement uses the maze feedback defined below and never represents a trap or a new gameplay mechanic. WCAG AA contrast certification and dedicated color-vision-deficiency palettes are not MVP requirements. ## 4. Animation, sound, and haptics - Use frequent but purposeful animation for screen transitions, movement, pickups, game events, and humorous feedback. - Pending controls blink until their command is resolved. - A visible reduced-motion toggle is required in player mode. It must suppress non-essential animation without changing gameplay feedback or authority. - Sound and vibration are enabled by default. They begin only after the first user interaction when required by the browser, and are used only when the browser and device support them. - A visible mute toggle is required in player mode. It disables local sound and vibration feedback only; it must never change protocol behavior. ## 5. Shared controls - Controls use a retro arcade appearance with clear normal, hover, pressed, disabled, and pending states. - Visible keyboard-focus outlines are not required for the MVP. - On computers, movement works from the keyboard and from an on-screen directional control cluster fixed in the lower-right corner. - On touch devices, an always-visible four-button directional pad in the lower right is the primary movement control. Its centre is inactive, each button is at least 48 by 48 CSS pixels, and it sends only one cardinal intention. The centered player avatar remains an optional movement handle. Its transparent touch target is at least 96 by 96 CSS pixels and its visible character remains unobscured. During a drag, it deflects no more than 28 CSS pixels from center and returns exactly to center on release, cancellation, pause, disconnect, lost pointer capture, hidden document, and browser blur. - The avatar drag has a 12 CSS-pixel dead zone and directional hysteresis. Its bounded repeat cadence changes monotonically from 360 ms at a small intentional displacement to 170 ms at the target edge; it never exceeds the server's 150 ms movement cooldown. The pad's hold repeat is 170 ms. Touch swipes remain supported. The pad, avatar drag, swipe, and keyboard inputs share one bounded latest-intent path. - The always-visible key-drop control is labelled `OK`, includes a key icon, and is positioned closer to the upper edge of the screen than the directional controls. Dropping does not require confirmation. - The key-drop control has the Russian accessible label `Сбросить ключ`. ## 6. Shared layout - The map fills all viewport space not required by fixed status and control panels. The player match screen must not require page scrolling. - A fixed status panel occupies the top of the screen. - The persistent player status shows the player name, carried key when one is held, active vision effect, and match state. - The player identity is represented by a distinct character shape, not `P1` or `P2`. Object, blocked-move, pause, and result feedback must pair a shape or icon with its color. - Connection details and the Wi-Fi settings link belong in a secondary panel, not in the persistent status row. - Countdown, pause, and result states appear as modal overlays above the map. - Textual system notices use one live message rail above the top bar and player status area. It shows one message at a time: connection loss has highest priority and persists until recovery; all other messages replace lower priority content, deduplicate by event, and dismiss after 2.6 seconds. - The lobby uses separate blocks for players, observers, and match actions. - Network provisioning uses the same colors, type, controls, and humor as the game application. ## 7. Player map presentation - Keep the portrait player horizontally centered at approximately 30% of the usable map height, above the directional-pad hand zone. In compact landscape, use the stable left-biased focal point in the largest unobstructed map area. Recalculate it after resize and rotation without moving the authoritative player away from its received `self` cell. - Render unknown space as a solid background. Never infer, retain, animate, or decorate maze geometry outside the server-provided visible projection. - Compute cell size from the current server projection and available map area. At the minimum supported phone viewport a common 7 by 7 projection must use at least 46 CSS-pixel cells, while smaller projections may grow to 72 pixels. Do not alter, retain, or infer hidden maze cells to fill spare space. - Player zoom and pan controls are not part of the MVP. - Use different colors plus labels, outlines, shapes, or icons to distinguish player ownership and object types. - Server-approved breakthrough impacts one through four bend the visible bush wall with four increasing restrained stages and no text or spike notice. A fifth accepted move is reflected by a permanent textured trampled-bush gap. The browser uses one restartable impact timer and no generated particles. `rate_limited` still darkens and blurs only the maze for at most 520 ms. - Reduced-motion mode uses static deformation and the same trampled-gap state. ### Hedge art review contract - Hedge samples are direct top-down vectors for review only; they are not runtime assets in this milestone. A segment occupies one cell edge and uses a centered, 10 CSS-pixel-wide foliage band at 40 CSS pixels per cell, scaling proportionally at 34 and 46 pixels. - The family uses deep shadow `#173d2a`, branch `#765033`, foliage dark `#296443`, foliage mid `#4f9b55`, foliage light `#8cc968`, and pale leaf highlight `#c7e68a`. A dark outline and branch fork preserve silhouette in grayscale; color is supplementary depth, not the only boundary cue. - Each intact symbol combines three or more named leaf clusters with visible twig forks, a restrained shadow, and an irregular outer silhouette. Straight symbols tile end-to-end without double borders; corner, crossing, and end symbols share their edge centre and may rotate or mirror without directional lighting. - Impact stages one through four retain the same wall centre while increasingly compressing foliage, bending twigs, and shedding a fixed small number of leaves. The breakthrough and trampled symbols leave a clear centred passage at least 16 CSS pixels wide at 40-pixel scale, with flattened vegetation on both sides. They never imply movement beyond that one authoritative edge. - Review sheets show the source symbols on neutral and dark-cell backgrounds at 34, 40, and 46 CSS pixels. They contain no coordinates, objects, ownership, hidden topology, animation, or runtime dependencies. ### Runtime hedge rendering - The local `/hedges.svg` sprite is derived from the approved review source. It contains only reusable runtime symbols and no scripts, raster data, or external dependencies. The review sheet in `docs/` is never requested by a browser page. - A map uses one non-interactive hedge-edge element for each canonical closed or server-opened edge in its current projection. Closed shared edges are owned by their north or west cell; east and south edges are rendered only at the current projection boundary. This bounds a full 32 by 32 map to 2,112 hedge elements and avoids duplicated foliage. - A stable integer hash of the canonical edge index and orientation selects one of the six approved intact variants. Opened edges select one of the three approved breach variants. The same projection edge always receives the same art without random state, retained exploration, or a protocol field. - Gameplay readability takes priority over foliage density. Hedge foliage is at most 20% of one cell, and the center line of every horizontal or vertical symbol must coincide with its authoritative cell edge. Rotation must preserve that center line instead of shifting a vertical hedge through cell centers. Every runtime SVG instance uses the approved `160 x 40` view box scaled to exactly one cell edge; source-coordinate artwork must never overflow into unrelated cells. Cell interiors remain visually quiet and continuous so passages read as open floor rather than as a grid of highlighted rectangles. - Hedge edges are decorative, have `pointer-events: none`, sit below map objects and players, and may overhang an edge by at most 15% of a cell. A projection replacement removes all obsolete edge nodes. One restartable breakthrough timer may briefly show the approved breakthrough frame; reduced motion settles immediately on the permanent breach. ## 8. Responsive behavior - The minimum supported player viewport is `412 x 916` CSS pixels. - Support both portrait and landscape orientations. Suggest landscape when it materially improves play, but do not block portrait play. - Respect display safe areas and keep essential status and controls visible. - At `412 x 916`, the map is the dominant visual region; controls overlay it instead of creating an empty lower region. Status remains icon-first and readable without requiring reading as the normal interaction path. - Scale icons and controls up on tablets and computers while preserving map priority and fixed panel placement. - Validate the MVP against the current stable releases of Chrome, Safari, Firefox, and Edge available at the time of validation. Record the tested browser versions and date; legacy browser support is outside the MVP. ## 9. Observer presentation - Observer mode is supported only at viewports of at least `1024 x 768` CSS pixels. Smaller viewports show a Russian message explaining that a larger screen is required. - Place player and match status blocks above the full maze. - Initially fit the complete `32 x 32` map into the available map area. - Provide zoom and pan without granting any gameplay control or changing server authority. ## 10. Asset and dependency budget - Use plain project CSS without a third-party CSS framework. - All runtime web assets must be served locally from the ESP. The UI must not require internet access, remote fonts, external icons, analytics, or content services. - Precompress production web assets. Their complete compressed payload must not exceed 1.5 MiB and must fit the existing 1,984 KiB LittleFS partition. - The LittleFS partition size and Flash layout remain unchanged. ## 11. Visual verification - Verify player layout at the minimum `412 x 916` viewport and representative tablet and desktop viewports. - Verify observer layout at `1024 x 768` and at a larger desktop viewport. - Verify every control state, modal state, responsive transition, Russian message, and semantic color role manually and through focused browser tests where practical. - Golden-image or screenshot-regression tests are not required for the MVP. ## 12. Pre-reader onboarding and usability - On a player's first active projection, show an eight-step, wordless-first walkthrough for avatar drag and release, walls, key, vision, compass, exit, and meeting the other player. Each step uses a large icon; short Russian text is secondary support for an adult. - The walkthrough provides a replay button and an explicit Russian skip button for adults. It is browser-local UI only and never changes server state. - A child must be able to distinguish their character, the other character, key, vision, compass, exit, blocked movement, and results through at least two channels such as shape/icon, position, motion, outline, color, sound, or haptic feedback. - Before release, record a representative pre-reader observation using `docs/PRE_READER_USABILITY.md`, or record a project-owner-approved deviation with its reason and impact.