feat(engine): revert to traditional 2-colour deck with saturated red + near-white

Per player feedback after the brief 4-colour-deck experiment:
"can we make the card suit colors the same as a regular
solitaire game would." Reverts the 4-colour split (`62b61cc`)
and bumps both 2-colour hues to read more like a real
Microsoft-Solitaire-on-dark-mode deck.

### Constants

- `RED_SUIT_COLOUR`: `#fb9fb1` (Terminal pink, then briefly
  hearts-only) → `#e35353` (saturated red). More chromatic, less
  pastel; reads as "the red suit" rather than "a Terminal-
  themed pink." Visually distinct from `ACCENT_PRIMARY`
  `#a54242` (the brick-red CTA accent) so chrome and suit don't
  collapse to the same hue.
- `BLACK_SUIT_COLOUR`: `#d0d0d0` (matched `TEXT_PRIMARY`) →
  `#e8e8e8` (near-white). Bumped slightly brighter so it reads
  as a chromatic-neutral counterpart to the new saturated red,
  not as "the same gray as body text." `TEXT_PRIMARY_HC`
  (`#f5f5f5`) is still brighter for the high-contrast boost
  path.
- `RED_SUIT_COLOUR_HC`: `#ff8aa0` (pinkish boost matching the
  v0.21.0 pink default) → `#ff6868` (brighter saturated red).
  Now reads as "more chromatic" than the new default red, not
  "less saturated."
- `DIAMOND_SUIT_COLOUR` and `CLUB_SUIT_COLOUR` deleted — the
  4-colour split is gone, hearts/diamonds re-pair under
  `RED_SUIT_COLOUR` and clubs/spades under
  `BLACK_SUIT_COLOUR`.

### `card_face_svg.rs`

- Module-level constants collapse from four (`SUIT_HEART` /
  `SUIT_DIAMOND` / `SUIT_CLUB` / `SUIT_SPADE`) back to two
  (`SUIT_RED` / `SUIT_DARK`) at the new saturated-red /
  near-white values.
- `suit_paint()` reverts to the 2-colour pairing: hearts
  filled-red, diamonds outlined-red, spades filled-near-white,
  clubs outlined-near-white. Filled-vs-outlined glyph
  differentiation stays the always-on CBM fallback.

### `card_plugin.rs`

- `text_colour()` reverts to a `card.suit.is_red()`
  bifurcation. Comment block updated to reflect the new
  truth table: red suits → saturated red (or CBM lime / HC
  brighter red); dark suits → near-white (or HC brighter
  near-white).

### Tests

Test block restructured back to the pre-4-colour shape: two
red/black pairing tests instead of one 4-colour distinctness
test. CBM/HC compose tests retuned to the 2-colour world (red
suits compose, dark suits compose; no separate diamonds-immune
or clubs-immune cases). 1191 passing / 0 failing — net 0 from
the prior commit (3 tests removed: the 4-colour distinctness
test + the diamonds/clubs-immune test; 2 tests added back: the
red-pairing + dark-pairing tests; existing tests amended to
new colour assumptions).

### `card_face_svg_pin`

All 52 face hashes drift (every suit's colour shifted); 5 back
hashes unchanged. Surgical rebaseline.

### `design-system.md`

§Suit Colors retitled "Two-color traditional pairing", table
updated with the new hex values, CBM section text simplified
back to red→lime swap on both red suits.

Workspace clippy clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-08 12:35:36 -07:00
parent 62b61cc786
commit ddb65403c2
108 changed files with 365 additions and 441 deletions
+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", 0x287e3293f95990a5),
("face_2C", 0x01c66d8e461fb0c4),
("face_3C", 0xfdae6be53af8b7c8),
("face_4C", 0x4b2a7aef966c6cc2),
("face_5C", 0xa4ca0ce3759b5cc9),
("face_6C", 0xe1a730d1ce810314),
("face_7C", 0x9c8de5c7d014eca3),
("face_8C", 0x39e09f90c957b192),
("face_9C", 0xd6627707fb2d5079),
("face_10C", 0xbe8411c60411195c),
("face_JC", 0x7c33abf5619477ac),
("face_QC", 0xe75657d63c99a892),
("face_KC", 0xf4a445b771026496),
("face_AD", 0xad8820c694c464d7),
("face_2D", 0xef771dbb39ae4f5a),
("face_3D", 0xe955ec9a96e1256a),
("face_4D", 0x6bb5979ef6004957),
("face_5D", 0x55715fd2353b2126),
("face_6D", 0x87fbd6efce1b1f9f),
("face_7D", 0xabb2d52d363e93ab),
("face_8D", 0xde78161ee9093b05),
("face_9D", 0x1475987ba1e66036),
("face_10D", 0x3a52d7fda7158aeb),
("face_JD", 0xc9078d8a7b2e6372),
("face_QD", 0x84c9011b916fdbe8),
("face_KD", 0xbcd20dbb6b1c8cdf),
("face_AH", 0x2c8e05964b5e3a5f),
("face_2H", 0xb44e68b79bb3842e),
("face_3H", 0x15226ed29769e1c4),
("face_4H", 0xe28c86ba92a3aee9),
("face_5H", 0x18276e48b28d0f6b),
("face_6H", 0xcca5e60e65724eaa),
("face_7H", 0x7f3eee634137f13a),
("face_8H", 0x8974515a8904d6c4),
("face_9H", 0x2f8155cd7690d4b9),
("face_10H", 0x78142f898fd66578),
("face_JH", 0x5e6df78654a1de73),
("face_QH", 0xc231ae8c25d877a9),
("face_KH", 0x55a0a772baf3e97f),
("face_AS", 0xc90e798aebdc1c5f),
("face_2S", 0x4178c699a726ea70),
("face_3S", 0xdfcd34480bb06f4c),
("face_4S", 0xdbd4938042afb02e),
("face_5S", 0x8741456ab1ec58ab),
("face_6S", 0x6d2632f648f1c34d),
("face_7S", 0x3c05c70ff3d93ea6),
("face_8S", 0x12d7f456efbaffe0),
("face_9S", 0x11b6ade208b8fa12),
("face_10S", 0x475d4110834b6b2a),
("face_JS", 0x52525a2200c07246),
("face_QS", 0xb4f0251a2757cbb1),
("face_KS", 0x1e1975919bb9a029),
("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),
("back_0", 0xfd1742ebe330481a),
("back_1", 0x446fdc0a3c83a03a),
("back_2", 0xcf188fdec9f5819a),