Tapping a seat gives you that seat #60
@@ -568,8 +568,19 @@ button,
|
||||
|
||||
.dealerChip {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: -10px;
|
||||
/* Inside its own seat, not on the rim.
|
||||
|
||||
It used to sit at -10px/-10px, hanging over the seat's corner — which on an oval
|
||||
of overlapping seats means hanging over the seat *next to it*. Measured on a
|
||||
nine-seat table: tapping the centre of seat 1 gave the button to seat 9. That
|
||||
was always slightly true and the enlarged hit area made it much worse; three of
|
||||
nine seats were losing taps, one of them losing its own middle.
|
||||
|
||||
Tucked inside, the overlap is zero at every size. It reads as a puck in the
|
||||
corner of the seat rather than on its edge, which is a small price for tapping
|
||||
a player and getting that player. */
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
@@ -595,10 +606,20 @@ button,
|
||||
.dealerChip::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -9px;
|
||||
right: -7px;
|
||||
bottom: -15px;
|
||||
left: -14px;
|
||||
/* Grows inward, over its own seat, not outward onto the neighbours.
|
||||
|
||||
The chip already sits outside its seat by design — top:-10px, right:-10px — so
|
||||
a pad that also reaches up and right lands on whatever seat is next around the
|
||||
oval. It did: three of nine seats had taps taken by a neighbour's chip, seat 1
|
||||
losing 10 of 49 sampled points including its own centre, which meant tapping
|
||||
the middle of seat 1 gave the button to seat 9.
|
||||
|
||||
Down and left is its own seat, which is a large target that can spare the
|
||||
corner. The two pixels of outward reach are just to cover the chip's border. */
|
||||
top: -3px;
|
||||
right: -3px;
|
||||
bottom: -18px;
|
||||
left: -18px;
|
||||
}
|
||||
|
||||
.dealerChip:focus-visible {
|
||||
@@ -2787,9 +2808,20 @@ body.hasActionBar #toastHost {
|
||||
against the containing block's width, not the element's own, so narrowing the
|
||||
wrap on its own left it full height regardless. */
|
||||
#pokerTableWrap {
|
||||
--feltRoom: calc(100vh - var(--actionBarHeight, 0px) - 8.5rem);
|
||||
width: min(100%, calc(var(--feltRoom) / 0.72));
|
||||
/* A wide ellipse, which is what a real poker table is.
|
||||
|
||||
Capping the width by the height to hold the portrait aspect ratio was
|
||||
throwing away most of the screen: at 640x360 the felt came out 135px wide
|
||||
inside a 601px column — 22% of the width — leaving 366px of rim for nine
|
||||
seats that need 662px. Adjacent seat centres ended up 13px apart, which is
|
||||
why a seat's centre belonged to its neighbour.
|
||||
|
||||
Landscape has width and no height, so the table takes the width it has and
|
||||
is only as tall as the room left over. */
|
||||
--feltRoom: calc(100vh - var(--actionBarHeight, 0px) - 7rem);
|
||||
width: 100%;
|
||||
height: var(--feltRoom);
|
||||
min-height: 7rem;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -2826,6 +2858,7 @@ body.hasActionBar #toastHost {
|
||||
width: 62px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ---------- Short phones, upright ----------
|
||||
|
||||
+48
-1
@@ -133,7 +133,18 @@ const LayoutAudit = {
|
||||
if (el.contains(top) || top === el || top.contains(el)) return;
|
||||
// Seats ring a round table and overlap each other at the rim by
|
||||
// design; that is crowding, not an overlay hiding a control.
|
||||
if (top.closest && top.closest(".seat")) return;
|
||||
//
|
||||
// But only the seat's *body* is harmless. A neighbouring seat's own
|
||||
// controls sitting on top of this one is a control being stolen, and
|
||||
// exempting the whole seat subtree hid exactly that: an enlarged
|
||||
// dealer-chip hit area was taking the centre of the seat three
|
||||
// places round the table, and this check called it crowding and
|
||||
// moved on.
|
||||
const neighbourSeat = top.closest && top.closest(".seat");
|
||||
if (neighbourSeat) {
|
||||
const isControl = top.matches && top.matches("button, a, input, select, textarea, [role='button']");
|
||||
if (!isControl) return;
|
||||
}
|
||||
blocked++;
|
||||
if (!blockedBy) blockedBy = this.describe(top);
|
||||
});
|
||||
@@ -468,6 +479,41 @@ const LayoutAudit = {
|
||||
return { name: `touch targets at least ${minimum}px`, offenders };
|
||||
},
|
||||
|
||||
// Tapping the middle of a seat must give you that seat.
|
||||
//
|
||||
// Added after a dealer-chip hit area, meant to make a 22px puck thumb-sized, grew
|
||||
// outward from a chip that already hung over its seat's corner — and therefore
|
||||
// over the seat next to it. On a nine-seat table, tapping the centre of seat 1
|
||||
// handed the button to seat 9. The occlusion check missed it because it treated
|
||||
// anything inside a `.seat` as harmless crowding.
|
||||
//
|
||||
// Reported separately from occlusion because the cause is different: not an
|
||||
// overlay on top of the table, but two pieces of the table fighting over a tap.
|
||||
seatOwnership() {
|
||||
const seats = [...document.querySelectorAll(".seat")];
|
||||
const offenders = [];
|
||||
|
||||
seats.forEach((seat, index) => {
|
||||
const rect = seat.getBoundingClientRect();
|
||||
if (rect.width === 0 || rect.height === 0) return;
|
||||
const x = rect.left + rect.width / 2;
|
||||
const y = rect.top + rect.height / 2;
|
||||
if (x < 0 || y < 0 || x >= innerWidth || y >= innerHeight) return;
|
||||
|
||||
const hit = document.elementFromPoint(x, y);
|
||||
if (!hit || seat.contains(hit) || hit === seat) return;
|
||||
|
||||
const other = hit.closest(".seat");
|
||||
const who = other ? `seat ${seats.indexOf(other) + 1}` : this.describe(hit);
|
||||
const control = hit.matches && hit.matches("button, a, input, select, [role='button']");
|
||||
offenders.push(
|
||||
`seat ${index + 1}'s centre goes to ${who}${control ? "'s " + this.describe(hit) : ""}`
|
||||
);
|
||||
});
|
||||
|
||||
return { name: "a seat's centre belongs to that seat", offenders };
|
||||
},
|
||||
|
||||
// ---- Runner ----
|
||||
|
||||
runAll(options = {}) {
|
||||
@@ -480,6 +526,7 @@ const LayoutAudit = {
|
||||
this.textSpill(),
|
||||
this.horizontalOverflow(),
|
||||
this.fieldFontSize(),
|
||||
this.seatOwnership(),
|
||||
];
|
||||
if (options.includeTouchTargets) checks.push(this.touchTargets(options.minimumTarget));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user