Keep the table above the action bar on wide screens
The bar publishes its height so the layout can stay clear of it. Only the phone and landscape rules ever read it. The wide layout sized the felt from its own width -- a box 72% as tall as it is wide -- and so had no idea what was underneath it. That was survivable while the bar was a constant. It isn't: it grows from 117px to 172px the moment a hand needs a side pot, which is exactly the hand where the dealer most needs to see who is still in. Measured with two side pots, six seats, the bottom seat sat this far behind the bar: 1280x900 22px 1600x1000 54px 768x1024 23px 1024x768 clear 360x640 39px 390x844 clear The first attempt at this didn't work and the failure is worth recording: the wrap was a padding-bottom: 72% box, and percentage padding resolves against the containing block's width rather than the element's own. Capping the width narrowed the felt from 822px to 746px and left it exactly 617px tall, so the seat stayed where it was. It is an aspect-ratio box now, and the shape is stated once as --feltAspect so the height and the cap both derive from it. 1280x900 felt 857x617 -> 746x537 seat 22px behind the bar -> 51px clear 1600x1000 ...760 -> 885x637 54px behind -> 59px clear 768x1024 felt 689x689 -> 603x603 23px behind -> 56px clear Six-seat tables at 1280x900, 1600x1000, 1024x768 and 768x1024 all go from one covered seat to a clean audit. Not applied below 700px. The narrow layout already had an answer -- it reserves the bar's height as scroll room under the table, and a phone is a thing you scroll -- and capping there was measured and rejected: at 360x640 it took the felt from 321px to 226px, which fixed the six-seat ring and broke the nine-seat one, two covered seats traded for two seats whose centre landed on a neighbour. Landscape phones opt out too. They set their own height from the bar already and are sitting on their 7rem floor; 844x390 and 667x375 still have the bottom seat in the bar, and nothing about a 112px-tall table with 73px seats can fix that. The seat overhang is a constant rather than something measured off the layout it is about to change -- a seat is ~73px tall at every width -- so this settles in one pass instead of asking a different question each time it shrinks the felt. 172 tests still passing; no console errors; contrast clean. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
This commit is contained in:
@@ -308,9 +308,22 @@ button,
|
||||
|
||||
#pokerTableWrap {
|
||||
position: relative;
|
||||
/* The shape is stated once, and both the height and the cap below are derived from
|
||||
it. It used to be a `padding-bottom: 72%` box, which has a trap in it: percentage
|
||||
padding resolves against the *containing block's* width, not the element's own,
|
||||
so narrowing the wrap left it exactly as tall as before. Capping the width was
|
||||
therefore no way to shorten the table — measured, after trying it: the felt went
|
||||
822px wide to 746px and stayed 617px tall, and the bottom seat sat as far into
|
||||
the action bar as it had. aspect-ratio ties the two together properly. */
|
||||
--feltAspect: 0.72;
|
||||
width: 100%;
|
||||
padding-bottom: 72%;
|
||||
aspect-ratio: 1 / var(--feltAspect);
|
||||
margin: 0 auto;
|
||||
/* Capping the width is how the felt is told to stay above the action bar.
|
||||
--feltRoomPx is published by actionBar.js with the bar's real height and the
|
||||
bottom seat's overhang already taken out; the fallback leaves the table its full
|
||||
size if that ever fails to arrive. */
|
||||
max-width: calc(var(--feltRoomPx, 100vh) / var(--feltAspect));
|
||||
}
|
||||
|
||||
|
||||
@@ -2126,6 +2139,23 @@ body.hasActionBar #holdemSidebar {
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
/* "ALL IN" takes the stack line's place, so it has to not read as a stack. Wider
|
||||
letters and a warm colour separate it from the grey money above it at a glance —
|
||||
which is the whole job, because the dealer is scanning the ring for who can still
|
||||
be bet at. */
|
||||
.seatPuckStack.seatPuckAllIn {
|
||||
color: #ffcf6b;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
|
||||
/* And the seat itself carries a hint of it, so the mark survives being read out of
|
||||
the corner of an eye. Deliberately quieter than .seatActing — all-in is a standing
|
||||
fact about a player, not a request for the dealer's attention. */
|
||||
.seat.seatAllIn {
|
||||
border-color: rgba(255, 207, 107, 0.45);
|
||||
}
|
||||
|
||||
/* Tournament-sized amounts. A number has no spaces to break on, so an amount too
|
||||
wide for the 64px puck neither wraps nor ellipsises — it draws straight out over
|
||||
the seat next to it. These step the size down so every digit stays on its own
|
||||
@@ -2504,6 +2534,16 @@ body.hasActionBar #toastHost {
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
/* The narrow layout already had an answer for the bar: it reserves the bar's height
|
||||
as scroll room below the table, and a phone is a thing you scroll. Capping the
|
||||
felt here as well was measured and rejected — at 360x640 it took the table from
|
||||
321px to 226px, which fixed the six-seat ring but broke the nine-seat one, two
|
||||
covered seats traded for two seats whose centre landed on a neighbour. The cap is
|
||||
for the wide layout, which never consulted the bar's height at all. */
|
||||
#pokerTableWrap {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
/* Stacked, with the action that ends the hand furthest from a stray thumb. */
|
||||
.potWizardActions {
|
||||
flex-direction: column-reverse;
|
||||
@@ -2519,8 +2559,9 @@ body.hasActionBar #toastHost {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
/* One column, so the table has the full width and can afford to be round. */
|
||||
#pokerTableWrap {
|
||||
padding-bottom: 100%;
|
||||
--feltAspect: 1;
|
||||
}
|
||||
|
||||
.seat {
|
||||
@@ -2845,7 +2886,11 @@ body.hasActionBar #toastHost {
|
||||
width: 100%;
|
||||
height: var(--feltRoom);
|
||||
min-height: 7rem;
|
||||
padding-bottom: 0;
|
||||
/* This branch sets its own height outright, so neither the aspect ratio nor the
|
||||
cap derived from it has anything to say here — and the cap would only narrow
|
||||
a table that is already as short as the screen allows. */
|
||||
aspect-ratio: auto;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
/* The header ate 148px of a 390px-tall window, which was most of the reason the
|
||||
|
||||
@@ -29,6 +29,7 @@ const ActionBar = {
|
||||
const visible = !host.hidden;
|
||||
const height = visible ? host.getBoundingClientRect().height : 0;
|
||||
document.documentElement.style.setProperty("--actionBarHeight", `${Math.round(height)}px`);
|
||||
this.publishFeltRoom(height);
|
||||
};
|
||||
|
||||
if (typeof ResizeObserver === "function") {
|
||||
@@ -40,6 +41,36 @@ const ActionBar = {
|
||||
publish();
|
||||
},
|
||||
|
||||
// Half a seat, the gap left under the lowest one, and the smallest felt worth
|
||||
// drawing. A seat is about 73px tall at every width — the puck is text-sized, not
|
||||
// table-sized — so the overhang is a constant rather than something read back off
|
||||
// the layout this is about to change. Measuring it would mean shrinking the felt,
|
||||
// moving the seats, and getting a different answer on the next pass.
|
||||
SEAT_OVERHANG_PX: 37,
|
||||
FELT_GAP_PX: 8,
|
||||
FELT_MIN_PX: 220,
|
||||
|
||||
// How tall the felt can be and still leave the whole ring of seats above the bar.
|
||||
//
|
||||
// Publishing the bar's height was only half the job. The wide layout never used it:
|
||||
// the felt sizes itself from its own width — a box 72% as tall as it is wide — and
|
||||
// so has no idea what is underneath it. The bar meanwhile grows with the hand, from
|
||||
// 117px to 172px the moment there's a side pot to show, which is exactly when the
|
||||
// dealer most needs to see who is still in. Measured with two side pots, the bottom
|
||||
// seat sat 22px into the bar at 1280x900, 54px at 1600x1000, 23px at 768x1024.
|
||||
//
|
||||
// The wrap's offset is taken in document space rather than viewport space, so
|
||||
// scrolling the page doesn't resize the table under the dealer's hands.
|
||||
publishFeltRoom(barHeight) {
|
||||
const wrap = document.getElementById("pokerTableWrap");
|
||||
if (!wrap) return;
|
||||
const topInDocument = wrap.getBoundingClientRect().top + window.scrollY;
|
||||
const room = window.innerHeight - barHeight - topInDocument -
|
||||
this.SEAT_OVERHANG_PX - this.FELT_GAP_PX;
|
||||
document.documentElement.style.setProperty(
|
||||
"--feltRoomPx", `${Math.max(this.FELT_MIN_PX, Math.round(room))}px`);
|
||||
},
|
||||
|
||||
// Anything to act on? A hand with nobody dealt in doesn't get a bar — and that
|
||||
// still holds during setup, because a seated player is a live seat whether or not
|
||||
// the betting has been opened. An empty table stays uncluttered.
|
||||
|
||||
Reference in New Issue
Block a user