feat(ui): landscape two-column game layout, board fitted by height
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 58s
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 58s
When the viewport is wider than tall (matchMedia orientation: landscape) the game screen switches from the portrait stack to a two-column layout: the board fills the right column as the largest square that fits the height (no zoom, shrinking by width when cramped — lowest priority), while the left panel stacks the rack (+ make), the status line, the score plaques, the always-open docked history and the controls. Board zoom, the history slide-drawer gestures and the growing nav bar are gated off in landscape; the portrait layout is unchanged and both render from the same snippets so behaviour stays single-sourced. The mock e2e now defaults to a portrait viewport (the mobile-first app the gesture/zoom/history specs are written for); landscape.spec.ts covers the wide layout in its own viewport.
This commit is contained in:
+14
-1
@@ -8,6 +8,7 @@
|
||||
slots,
|
||||
variant,
|
||||
selected,
|
||||
landscape = false,
|
||||
shuffling = false,
|
||||
draggingId = null,
|
||||
dropIndex = null,
|
||||
@@ -18,6 +19,9 @@
|
||||
slots: (RackSlot & { id: number })[];
|
||||
variant: Variant;
|
||||
selected: number | null;
|
||||
/** Landscape layout: size the tiles to share the (narrow) left-panel width instead of the
|
||||
* viewport-width measure, so seven tiles never overflow the panel. */
|
||||
landscape?: boolean;
|
||||
shuffling?: boolean;
|
||||
// While a rack tile is being dragged to reorder it, draggingId is its id (hidden here —
|
||||
// the drag ghost stands in) and dropIndex is the slot where a gap opens.
|
||||
@@ -52,7 +56,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="rack" class:reordering={draggingId != null} data-rack>
|
||||
<div class="rack" class:reordering={draggingId != null} class:landscape data-rack>
|
||||
{#each shown as slot, i (slot.id)}
|
||||
<button
|
||||
class="tile"
|
||||
@@ -100,6 +104,15 @@
|
||||
outline: 3px solid var(--accent);
|
||||
outline-offset: -3px;
|
||||
}
|
||||
/* Landscape: the rack sits in a fixed-width left panel, so the tiles share the panel width
|
||||
(capped at the portrait size) and shrink below it when the panel is narrow, instead of the
|
||||
viewport-width measure that would overflow seven tiles in a column. */
|
||||
.rack.landscape .tile {
|
||||
flex: 1 1 0;
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
max-width: 46px;
|
||||
}
|
||||
/* While reordering, tiles at/after the drop slot slide right to open a gap there (one
|
||||
tile width plus the rack gap), so the drop position is visible. */
|
||||
.rack.reordering .tile {
|
||||
|
||||
Reference in New Issue
Block a user