games: draw the card, don't type it
The last attempt built a card face out of text: a "♠" in a span for every pip. At the size a card actually is, a suit character renders as a speck — the shape is whatever font answered, it doesn't scale, and it can't be put on the half-row a real pip layout needs. The result read worse than the plain rank it replaced. So each face is one SVG on a 100×140 field, suits as vector shapes, pips at the coordinates a printed deck puts them. Courts get a framed panel with the suit above the letter and again below it upside down — mirroring a letter, which is what the first pass did, just stacks two of them into a blob; a real court mirrors a figure. Also restores .pete-card-back, which went out with the text rules it was sitting among: without it a face-down card had no back at all, so the dealer's hole card was invisible on the felt. Caught by driving a hand.
This commit is contained in:
@@ -565,15 +565,15 @@ html[data-phase="night"] {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.6rem;
|
||||
min-height: 6.6rem;
|
||||
min-height: 8.6rem;
|
||||
}
|
||||
|
||||
/* One card. The wrapper does the flight, the inner face does the flip, so the
|
||||
two never fight over the same transform. */
|
||||
.pete-card {
|
||||
perspective: 700px;
|
||||
height: 7rem;
|
||||
width: 5rem;
|
||||
height: 8.4rem;
|
||||
width: 6rem;
|
||||
animation: pete-deal 0.42s cubic-bezier(0.22, 1, 0.36, 1) backwards;
|
||||
}
|
||||
.pete-card-inner {
|
||||
@@ -597,70 +597,23 @@ html[data-phase="night"] {
|
||||
-webkit-backface-visibility: hidden;
|
||||
box-shadow: 0 3px 0 rgba(0,0,0,0.18), 0 6px 14px rgba(0,0,0,0.22);
|
||||
}
|
||||
/* A real card face: index in two opposite corners, pips or a court figure in
|
||||
the middle. Laid out as three rows — corner, body, corner — so the body gets
|
||||
whatever's left and the indices stay pinned where they're printed. */
|
||||
/* The face is a single SVG on a 100×140 field (see blackjack.js) — suits as
|
||||
vector shapes, pips at printed-deck coordinates. The card element only has
|
||||
to hold it and colour it: `fill: currentColor` means the red/black switch
|
||||
below repaints every pip, index and court letter at once. */
|
||||
.pete-card-front {
|
||||
/* minmax(0,…) on the body row, or the pip grid's min-content height (seven
|
||||
rows of glyphs) wins the argument and pushes the bottom index off the
|
||||
card entirely. */
|
||||
grid-template-rows: auto minmax(0, 1fr) auto;
|
||||
overflow: hidden;
|
||||
padding: 0.2rem 0.28rem;
|
||||
place-items: stretch;
|
||||
background: #fdfaf2;
|
||||
border: 2px solid rgba(30,20,10,0.12);
|
||||
color: #2b2118;
|
||||
font-family: "Fredoka", "Nunito", system-ui, sans-serif;
|
||||
line-height: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.pete-card-front[data-red="1"] { color: #cc3d4a; }
|
||||
|
||||
/* The corner index: rank over suit, tight. The bottom-right one is the same
|
||||
thing upside down, because that's what makes a card readable from a fanned
|
||||
hand held either way up. */
|
||||
.pete-card-corner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
line-height: 0.95;
|
||||
}
|
||||
.pete-card-corner-tl { justify-self: start; }
|
||||
.pete-card-corner-br { justify-self: end; transform: rotate(180deg); }
|
||||
.pete-card-corner-rank { font-size: 0.9rem; font-weight: 700; }
|
||||
.pete-card-corner-suit { font-size: 0.72rem; }
|
||||
|
||||
/* The pip field: three columns, seven rows — the skeleton every printed deck
|
||||
shares. blackjack.js places each pip on it. */
|
||||
.pete-card-pips {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: repeat(7, minmax(0, 1fr));
|
||||
place-items: center;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 0.08rem;
|
||||
}
|
||||
.pete-card-pip { font-size: 0.82rem; line-height: 1; }
|
||||
.pete-card-pip[data-flip="1"] { transform: rotate(180deg); }
|
||||
|
||||
/* An ace is one pip, and it's allowed to be enormous. */
|
||||
.pete-card-pips[data-ace="1"] .pete-card-pip { font-size: 2.1rem; }
|
||||
|
||||
/* Court cards: the letter with a suit over each shoulder. */
|
||||
.pete-card-court {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.05rem;
|
||||
}
|
||||
.pete-card-court-letter {
|
||||
font-size: 1.7rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.pete-card-court-suit { font-size: 0.8rem; }
|
||||
.pete-card-court-suit[data-flip="1"] { transform: rotate(180deg); }
|
||||
/* The back. Turned away from you until the card is: this is what the dealer's
|
||||
hole card shows while you're still acting. */
|
||||
.pete-card-back {
|
||||
transform: rotateY(180deg);
|
||||
background:
|
||||
@@ -669,6 +622,36 @@ html[data-phase="night"] {
|
||||
border: 2px solid rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.pete-card-svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* The corner index. Tabular-ish and tight, so a 10 doesn't shove the suit. */
|
||||
.pete-card-idx {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
text-anchor: middle;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* The court panel: a frame, not a portrait. */
|
||||
.pete-card-panel {
|
||||
fill: currentColor;
|
||||
fill-opacity: 0.06;
|
||||
stroke: currentColor;
|
||||
stroke-opacity: 0.35;
|
||||
stroke-width: 1.5;
|
||||
}
|
||||
.pete-card-court {
|
||||
font-size: 34px;
|
||||
font-weight: 700;
|
||||
text-anchor: middle;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* The flight itself: out of the shoe (up and to the right), scaled down and
|
||||
spinning slightly, into place. */
|
||||
@keyframes pete-deal {
|
||||
|
||||
Reference in New Issue
Block a user