fix(engine): drop card-face border to remove gray-corner artifact

Player feedback after the 2-colour revert: "I do not like the
grey corners on the cards." The visible artifact was anti-
aliasing physics — the 1 px suit-coloured stroke (red for
hearts/diamonds, near-white for clubs/spades) faded through
gray pixels into the dark play surface at each rounded corner,
producing a visible "gray sliver" at the four arcs of every
card.

Fix: drop the stroke entirely. The card body fill defines the
shape against the play surface; the 5-unit brightness gap
between `#1a1a1a` body and `#151515` surface is enough to read
as a card edge without an explicit stroke. Anti-aliasing on a
fill-only rounded rect blends `#1a1a1a → #151515` over a few
pixels — barely perceptible compared to the
`stroke → transparent` gradient that produced the artifact.

### Changes

- `card_face_svg.rs`: removed `stroke="{colour}" stroke-width="2"`
  from the card body rect. Reverted the 1 px stroke inset back
  to `(x=0, y=0, width=256, height=384)` since there's no
  longer a stroke to keep inside the pixmap. Module-level
  comment updated to document the reasoning.
- `design-system.md` § Game Cards line 225 updated: "Border:
  1px solid in suit color" → "Border: none." with the
  artifact rationale recorded as audit trail.
- `card_face_svg_pin.rs` rebaselined: all 52 face hashes drift
  (every card's perimeter pixels changed); 5 back hashes
  unchanged.

Workspace clippy + cargo test --workspace clean. 1191 passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-08 12:41:54 -07:00
parent ddb65403c2
commit dd970215cc
107 changed files with 168 additions and 162 deletions
@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e35353" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="#1a1a1a" stroke="#e8e8e8" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="#1a1a1a"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

+11 -5
View File
@@ -213,15 +213,21 @@ pub fn face_svg(rank: Rank, suit: Suit) -> String {
let large_glyph_attrs = glyph_paint_attrs(colour, paint);
// Numbers come from `design-system.md` § Game Cards, scaled 2×:
// border: 1 px → 2 px stroke-width
// corner radius: 8 px → 16 px rx/ry
// rank font: 18 px → 36 px
// small glyph: 10 px → 20 px (suit_path_d is authored at 32 →
// scale 0.625 to land at 20)
// large glyph: 32 px → 64 px (scale 2.0)
//
// Inset the border by 1 px so the 2 px stroke renders fully
// inside the 256 × 384 pixmap rather than getting clipped.
// No stroke on the card body. The earlier 1 px suit-coloured
// border created anti-aliasing artifacts at the rounded corners
// where the colored stroke faded through gray pixels into the
// dark play surface beneath — a visible "gray sliver" at each
// rounded corner that read as a rendering bug. Without the
// stroke, the card shape is defined purely by the body fill
// against the play surface; the 5-unit brightness gap between
// `#1a1a1a` (card body) and `#151515` (play surface) is small
// enough that anti-aliasing is barely perceptible.
//
// Suit glyphs are rendered as inline SVG paths (not `<text>`)
// because the bundled `FiraMono` font doesn't carry usable
@@ -236,8 +242,8 @@ pub fn face_svg(rank: Rank, suit: Suit) -> String {
// `design-system.md` § Game Cards for the spec deviation.
format!(
r##"<svg xmlns="http://www.w3.org/2000/svg" width="256" height="384" viewBox="0 0 256 384">
<rect x="1" y="1" width="254" height="382" rx="16" ry="16"
fill="{BG_FACE}" stroke="{colour}" stroke-width="2"/>
<rect x="0" y="0" width="256" height="384" rx="16" ry="16"
fill="{BG_FACE}"/>
<!-- Top-left rank in JetBrains-Mono-styled FiraMono (rank digits
and letters render correctly in FiraMono; only the suit glyphs
+52 -52
View File
@@ -24,58 +24,58 @@ use solitaire_engine::assets::card_face_svg::{
use solitaire_engine::assets::rasterize_svg;
const EXPECTED: &[(&str, u64)] = &[
("face_AC", 0xecfed9881dab58cc),
("face_2C", 0x9d226854e375a071),
("face_3C", 0x57635bd3396b1c6f),
("face_4C", 0x3db4ebca46202411),
("face_5C", 0x6aaaa97f8d64d141),
("face_6C", 0x45ab0e3692f5086f),
("face_7C", 0xb6c6d47a9c41c042),
("face_8C", 0x95e467bebfe1f43f),
("face_9C", 0x78c67114e728f726),
("face_10C", 0x59ea22af2a519731),
("face_JC", 0x0757d9cae053863e),
("face_QC", 0xc3de9e10c2e8819e),
("face_KC", 0xefd2e9dd4c6f734f),
("face_AD", 0x95e2954416f7051d),
("face_2D", 0xfa494e129a7d130b),
("face_3D", 0x493f32ac1b4f1365),
("face_4D", 0x1303407818e3896d),
("face_5D", 0x3c68bc01d5661c9b),
("face_6D", 0x4ae0872812942c95),
("face_7D", 0xf4a040f288b53a3d),
("face_8D", 0xb5964ffbcc1834c0),
("face_9D", 0xfc2b244f9e6c987c),
("face_10D", 0xc9648dfd2f74e387),
("face_JD", 0x055c9e4b1f56b2b4),
("face_QD", 0x05d0d7e3be132b36),
("face_KD", 0x540753328025961e),
("face_AH", 0x8ac76ac84674dae6),
("face_2H", 0xf20c188bc5cf1008),
("face_3H", 0xc604901c0da15c0e),
("face_4H", 0x371c115d9292fa56),
("face_5H", 0x5cabef7840c6e378),
("face_6H", 0x48948872acab515e),
("face_7H", 0x49e96e37591f8c86),
("face_8H", 0xe30b740fd0f3575b),
("face_9H", 0x4067a838eeff2ea7),
("face_10H", 0xd9e9913fa5d9b974),
("face_JH", 0xe4344bff58d04e7f),
("face_QH", 0xf33df3f193827f25),
("face_KH", 0x8ada887b665fa3fd),
("face_AS", 0x586d5587ad518f46),
("face_2S", 0xbc0deb204e690d57),
("face_3S", 0xac04b5df8741d889),
("face_4S", 0x6a2ebcdb517b7ab7),
("face_5S", 0x9868f72763bbdae7),
("face_6S", 0x9a4c6842e0cbc489),
("face_7S", 0x15d17732dadf2ec0),
("face_8S", 0xb581df40dace0e59),
("face_9S", 0xce92a55ddcc6b4fc),
("face_10S", 0x1d92560a36938e97),
("face_JS", 0xd339b7a54139f9d4),
("face_QS", 0x59eae032af251c74),
("face_KS", 0x901e0d1ace6ff6a9),
("face_AC", 0x615e0ae429f479d5),
("face_2C", 0xb882a01af5338788),
("face_3C", 0x2ca39e5044b20caa),
("face_4C", 0xf1439571d0877e48),
("face_5C", 0x30254c808947a0e8),
("face_6C", 0xb23c1bec933a3a2a),
("face_7C", 0x250d5dca1cd7f72f),
("face_8C", 0xe663eb85d871e71a),
("face_9C", 0xd60724ce062f1c3b),
("face_10C", 0x271554347971c038),
("face_JC", 0xe9e6d9105d4fdd73),
("face_QC", 0x3e9c1094ce524373),
("face_KC", 0x8bdd75d0c9b2f23a),
("face_AD", 0x452313abfc8ae82b),
("face_2D", 0x5e7bfe77ab0b28a5),
("face_3D", 0x327a1e905aea8beb),
("face_4D", 0x86a4d1f243c60687),
("face_5D", 0x0e806a2b7350efc5),
("face_6D", 0x18150445cdba5fcb),
("face_7D", 0x25891a7b57050f7f),
("face_8D", 0x17096711946662be),
("face_9D", 0x1015f68680fc63b6),
("face_10D", 0x828bb4a68d291b3d),
("face_JD", 0x07b88b412f1357de),
("face_QD", 0x79d83db7e08d6338),
("face_KD", 0x72e59e0b36af3ac0),
("face_AH", 0xe8591acb1b311f68),
("face_2H", 0x0ecbabd6851a6e06),
("face_3H", 0x26f618607d72fb28),
("face_4H", 0xd678c1b9fe409d54),
("face_5H", 0xc6d600ca7b935aa6),
("face_6H", 0xcccc4f21cdf2c708),
("face_7H", 0x5c73195762121eec),
("face_8H", 0xc8e5adc5a1878635),
("face_9H", 0xfc1a1962879e3fed),
("face_10H", 0x0e2bcd01a63bb11e),
("face_JH", 0x9b18ac201230d355),
("face_QH", 0xc98e562402c11083),
("face_KH", 0x36a1eca09821b25b),
("face_AS", 0x0a62cb01f3c6a27b),
("face_2S", 0xa42a55c0df68c582),
("face_3S", 0xf789fa97b5e9fff0),
("face_4S", 0x7ffe2bc702a019c2),
("face_5S", 0xe38731d462109022),
("face_6S", 0xf7e7570631786c70),
("face_7S", 0x4b70162e6a977a91),
("face_8S", 0xe45989c24d21fda0),
("face_9S", 0x5ae9856cd14f6e65),
("face_10S", 0x77ff64bff391d7f2),
("face_JS", 0xb27564785cb9d07d),
("face_QS", 0x072a9bfccdbc367d),
("face_KS", 0xbd1464c949ffa380),
("back_0", 0xfd1742ebe330481a),
("back_1", 0x446fdc0a3c83a03a),
("back_2", 0xcf188fdec9f5819a),