css: grid-only layout — convert every flex container to grid + pin column widths

Two fixes in one — the immediate layout bug from the screenshot (timeline
sliding into column 1 with controls eating ~80% of the viewport) and
the architectural rule that all zebra page layout uses grid.

Layout bug (was: when cameras-col gets .hidden + the global .hidden
utility's display:none !important, the grid auto-placement promoted
.timeline into column 1 and .controls into column 2 → controls took
the 1fr middle track). Fix:

- explicit grid-column: 1/2/3 on cameras-col / timeline / controls so
  each child stays in its assigned column regardless of siblings going
  display:none
- .cameras-col uses 'display: grid !important' to override the global
  .hidden util, then only its content (h2 + #cameras) goes display:none
  via separate selectors when the .hidden class is present
- controls track clamped to min(360px, 50vw) so a wide window can't
  let the side panel eat the screen-share area

Grid-only refactor:
- every flex container converted: .timeline, .cameras-col, .game-tabs,
  .screen-tile, .screen-meta, .tap-play, .camera-tile, .row,
  .mod-actions, .invite-banner, .invite-actions, .notice-banner
- chat.html + zebra-audio.html same treatment (.row, .field-row,
  .share-box .copy-row, the inline H2 style, .mode-toggle, .dot)
- inline 'style=flex:1' on inputs/meters in chat.html replaced with
  'style=width:100%'
- now zero 'display: flex' / 'inline-flex' across all five zebra pages
- CLAUDE.md documents the grid-only rule under web-page authoring
This commit is contained in:
Russell Ballestrini 2026-06-02 09:12:38 -04:00
parent 95851371bc
commit eed5348567
No known key found for this signature in database
4 changed files with 137 additions and 55 deletions

View file

@ -130,6 +130,41 @@ is not on the screen, peers cannot dox each other. Candidate types
`rem.address` / `rem.port` are not. The WebRTC stack already obfuscates host
candidates via mDNS by default — do not undo that work in the UI.
### CSS layout — grid only, no flex
All page layout on every zebra page is **CSS grid**. No `display: flex` for
layout. Reasons we settled on this:
- Grid lets us pin children to explicit columns (`grid-column: 1/2/3`) so
a `display:none` on one child never causes siblings to slide into its
slot. Flex auto-reorders, grid does not.
- One mental model for both axes. Flex needs rules per row + per item,
grid expresses the same intent in one `grid-template-*` block.
- A global `.hidden { display: none !important }` utility lives in the
page CSS — combined with explicit grid placement it produces a layout
that survives any child being toggled in or out.
When refactoring or adding UI, use:
- `display: grid` + `grid-template-columns` for column layout
- `grid-column: N` on every child of a grid so its position is explicit
- `grid-template-rows` + `grid-row` for vertical placement when needed
- `grid-template-areas` for small named-region layouts
- `gap` for spacing (instead of margins)
Avoid:
- `display: flex` on any container that arranges multiple elements
horizontally or vertically as part of the page layout
- Implicit positioning that relies on DOM order — always set
`grid-column` (and `grid-row` if relevant) on every grid child
- `flex-basis` / `flex-grow` mathematics — `1fr` is the equivalent and
reads cleaner
If you need a one-off horizontal alignment of two short inline things
(e.g. a label + a value), grid still works fine
(`grid-template-columns: auto 1fr`). Don't reach for flex.
### Web page integrity stamping
Each deployed page (`web/chat.html`, `web/zebra-audio.html`, `web/how-it-works.html`,