diff --git a/CREDITS.md b/CREDITS.md
index 3ad4599..def0a8f 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -42,14 +42,20 @@ copyleft code is statically linked into the game binary.
| File(s) | Source | License |
|---|---|---|
-| `assets/cards/faces/{RANK}{SUIT}.png` (52 PNGs) | xCards @2x artwork | LGPL-3.0 |
-| `assets/cards/backs/back_0.png` (bicycle_blue) | xCards @2x artwork | LGPL-3.0 |
-| `assets/cards/backs/back_1.png` – `back_4.png` | Original — generated by `solitaire_assetgen::gen_art` | MIT (this project) |
+| `solitaire_engine/assets/themes/default/{suit}_{rank}.svg` (52 SVGs) | [hayeah/playing-cards-assets](https://github.com/hayeah/playing-cards-assets) | MIT |
+| `solitaire_engine/assets/themes/default/back.svg` | Original — Solitaire Quest | MIT (this project) |
+| `assets/cards/faces/{RANK}{SUIT}.png` (52 PNGs) | Pre-rendered from the same `playing-cards-assets` SVGs | MIT (passed through from hayeah) |
+| `assets/cards/backs/back_0.png` – `back_4.png` | Original — generated by `solitaire_assetgen::gen_art` | MIT (this project) |
-xCards is the playing-card artwork bundle by Huub de Beer, published under the
-LGPL-3.0. The art is consumed as unmodified PNG files at runtime; the game
-binary statically links no LGPL code, so distribution as a self-contained
-binary plus the `assets/` directory satisfies the LGPL's relinking clause.
+The face SVGs come from Howard Yeh's `playing-cards-assets` repository, which
+is itself derived from the public-domain `vector-playing-cards` Google Code
+project. The art is redistributed under the MIT license — see the upstream
+repository for the full notice. The files ship unmodified in the bundled
+default theme; user-supplied themes can override them per-installation
+through the runtime SVG theming system documented in `CARD_PLAN.md`.
+
+The default card back is original work by this project, midnight-purple
+themed to match the rest of the UI palette.
### Backgrounds
@@ -92,12 +98,14 @@ Audio files are MIT-licensed alongside the rest of this project.
## License Summary
- **Project code:** MIT — see [LICENSE](LICENSE).
-- **xCards card artwork (52 faces + `back_0.png`):** LGPL-3.0, redistributed
- unmodified. The LGPL applies only to those PNG files; it does not extend to
- the game binary, which links no LGPL code.
+- **Card face artwork (52 SVGs from hayeah/playing-cards-assets, plus the
+ pre-rendered PNGs in `assets/cards/faces/`):** MIT, redistributed
+ unmodified. The original `vector-playing-cards` line art is itself
+ public domain.
- **FiraMono-Medium font:** SIL Open Font License 1.1, redistributed unmodified.
-- **All other assets** (backgrounds, generated card backs, every audio file)
- are original work covered by this project's MIT license.
+- **All other assets** (backgrounds, the default `back.svg`, generated card
+ backs, every audio file) are original work covered by this project's MIT
+ license.
If you redistribute Solitaire Quest, you must ship this `CREDITS.md` and the
`LICENSE` file alongside the binary so the LGPL and OFL notices remain
diff --git a/assets/cards/faces/10C.png b/assets/cards/faces/10C.png
index 8676778..0eec159 100644
Binary files a/assets/cards/faces/10C.png and b/assets/cards/faces/10C.png differ
diff --git a/assets/cards/faces/10D.png b/assets/cards/faces/10D.png
index c9f9515..20dcfa4 100644
Binary files a/assets/cards/faces/10D.png and b/assets/cards/faces/10D.png differ
diff --git a/assets/cards/faces/10H.png b/assets/cards/faces/10H.png
index 8680893..d60838b 100644
Binary files a/assets/cards/faces/10H.png and b/assets/cards/faces/10H.png differ
diff --git a/assets/cards/faces/10S.png b/assets/cards/faces/10S.png
index 5ee6ccc..24ec7c6 100644
Binary files a/assets/cards/faces/10S.png and b/assets/cards/faces/10S.png differ
diff --git a/assets/cards/faces/2C.png b/assets/cards/faces/2C.png
index 5d04e07..6899e79 100644
Binary files a/assets/cards/faces/2C.png and b/assets/cards/faces/2C.png differ
diff --git a/assets/cards/faces/2D.png b/assets/cards/faces/2D.png
index 91090e1..fed9bdc 100644
Binary files a/assets/cards/faces/2D.png and b/assets/cards/faces/2D.png differ
diff --git a/assets/cards/faces/2H.png b/assets/cards/faces/2H.png
index 25f069f..fa94892 100644
Binary files a/assets/cards/faces/2H.png and b/assets/cards/faces/2H.png differ
diff --git a/assets/cards/faces/2S.png b/assets/cards/faces/2S.png
index 05ce74c..a8a5894 100644
Binary files a/assets/cards/faces/2S.png and b/assets/cards/faces/2S.png differ
diff --git a/assets/cards/faces/3C.png b/assets/cards/faces/3C.png
index e21e827..8857ae8 100644
Binary files a/assets/cards/faces/3C.png and b/assets/cards/faces/3C.png differ
diff --git a/assets/cards/faces/3D.png b/assets/cards/faces/3D.png
index b461ded..64a1e12 100644
Binary files a/assets/cards/faces/3D.png and b/assets/cards/faces/3D.png differ
diff --git a/assets/cards/faces/3H.png b/assets/cards/faces/3H.png
index 9846a6d..870fcf1 100644
Binary files a/assets/cards/faces/3H.png and b/assets/cards/faces/3H.png differ
diff --git a/assets/cards/faces/3S.png b/assets/cards/faces/3S.png
index 76112bb..280dd88 100644
Binary files a/assets/cards/faces/3S.png and b/assets/cards/faces/3S.png differ
diff --git a/assets/cards/faces/4C.png b/assets/cards/faces/4C.png
index e79ae1e..6c5bcb1 100644
Binary files a/assets/cards/faces/4C.png and b/assets/cards/faces/4C.png differ
diff --git a/assets/cards/faces/4D.png b/assets/cards/faces/4D.png
index 03b21e2..61a7522 100644
Binary files a/assets/cards/faces/4D.png and b/assets/cards/faces/4D.png differ
diff --git a/assets/cards/faces/4H.png b/assets/cards/faces/4H.png
index 7a9dcdf..f7d2240 100644
Binary files a/assets/cards/faces/4H.png and b/assets/cards/faces/4H.png differ
diff --git a/assets/cards/faces/4S.png b/assets/cards/faces/4S.png
index 7264b9e..14b449a 100644
Binary files a/assets/cards/faces/4S.png and b/assets/cards/faces/4S.png differ
diff --git a/assets/cards/faces/5C.png b/assets/cards/faces/5C.png
index 597ca4f..bd81b70 100644
Binary files a/assets/cards/faces/5C.png and b/assets/cards/faces/5C.png differ
diff --git a/assets/cards/faces/5D.png b/assets/cards/faces/5D.png
index 2d4982a..7f034ee 100644
Binary files a/assets/cards/faces/5D.png and b/assets/cards/faces/5D.png differ
diff --git a/assets/cards/faces/5H.png b/assets/cards/faces/5H.png
index 245d714..febddee 100644
Binary files a/assets/cards/faces/5H.png and b/assets/cards/faces/5H.png differ
diff --git a/assets/cards/faces/5S.png b/assets/cards/faces/5S.png
index edace7d..dd30b3e 100644
Binary files a/assets/cards/faces/5S.png and b/assets/cards/faces/5S.png differ
diff --git a/assets/cards/faces/6C.png b/assets/cards/faces/6C.png
index 9c6344f..ac76ad0 100644
Binary files a/assets/cards/faces/6C.png and b/assets/cards/faces/6C.png differ
diff --git a/assets/cards/faces/6D.png b/assets/cards/faces/6D.png
index 01e4e26..44596bc 100644
Binary files a/assets/cards/faces/6D.png and b/assets/cards/faces/6D.png differ
diff --git a/assets/cards/faces/6H.png b/assets/cards/faces/6H.png
index 5b0ea2b..f34bcc7 100644
Binary files a/assets/cards/faces/6H.png and b/assets/cards/faces/6H.png differ
diff --git a/assets/cards/faces/6S.png b/assets/cards/faces/6S.png
index e187d6f..3fae288 100644
Binary files a/assets/cards/faces/6S.png and b/assets/cards/faces/6S.png differ
diff --git a/assets/cards/faces/7C.png b/assets/cards/faces/7C.png
index 1c0ace5..bcc188f 100644
Binary files a/assets/cards/faces/7C.png and b/assets/cards/faces/7C.png differ
diff --git a/assets/cards/faces/7D.png b/assets/cards/faces/7D.png
index e8bedb8..6a9726c 100644
Binary files a/assets/cards/faces/7D.png and b/assets/cards/faces/7D.png differ
diff --git a/assets/cards/faces/7H.png b/assets/cards/faces/7H.png
index 75e99a8..8eac5bc 100644
Binary files a/assets/cards/faces/7H.png and b/assets/cards/faces/7H.png differ
diff --git a/assets/cards/faces/7S.png b/assets/cards/faces/7S.png
index 159c080..3576b02 100644
Binary files a/assets/cards/faces/7S.png and b/assets/cards/faces/7S.png differ
diff --git a/assets/cards/faces/8C.png b/assets/cards/faces/8C.png
index 13f4009..826a1d3 100644
Binary files a/assets/cards/faces/8C.png and b/assets/cards/faces/8C.png differ
diff --git a/assets/cards/faces/8D.png b/assets/cards/faces/8D.png
index 8fc76fd..282199d 100644
Binary files a/assets/cards/faces/8D.png and b/assets/cards/faces/8D.png differ
diff --git a/assets/cards/faces/8H.png b/assets/cards/faces/8H.png
index 79133bd..00931af 100644
Binary files a/assets/cards/faces/8H.png and b/assets/cards/faces/8H.png differ
diff --git a/assets/cards/faces/8S.png b/assets/cards/faces/8S.png
index c28ee94..5dc7719 100644
Binary files a/assets/cards/faces/8S.png and b/assets/cards/faces/8S.png differ
diff --git a/assets/cards/faces/9C.png b/assets/cards/faces/9C.png
index 5404b34..026e2b8 100644
Binary files a/assets/cards/faces/9C.png and b/assets/cards/faces/9C.png differ
diff --git a/assets/cards/faces/9D.png b/assets/cards/faces/9D.png
index b92c266..58f35d2 100644
Binary files a/assets/cards/faces/9D.png and b/assets/cards/faces/9D.png differ
diff --git a/assets/cards/faces/9H.png b/assets/cards/faces/9H.png
index 240b38a..0443dd9 100644
Binary files a/assets/cards/faces/9H.png and b/assets/cards/faces/9H.png differ
diff --git a/assets/cards/faces/9S.png b/assets/cards/faces/9S.png
index 4d5b93b..aab5a88 100644
Binary files a/assets/cards/faces/9S.png and b/assets/cards/faces/9S.png differ
diff --git a/assets/cards/faces/AC.png b/assets/cards/faces/AC.png
index 96eb269..5300624 100644
Binary files a/assets/cards/faces/AC.png and b/assets/cards/faces/AC.png differ
diff --git a/assets/cards/faces/AD.png b/assets/cards/faces/AD.png
index c6b1f1c..8e5b0ea 100644
Binary files a/assets/cards/faces/AD.png and b/assets/cards/faces/AD.png differ
diff --git a/assets/cards/faces/AH.png b/assets/cards/faces/AH.png
index 752165d..635c3b3 100644
Binary files a/assets/cards/faces/AH.png and b/assets/cards/faces/AH.png differ
diff --git a/assets/cards/faces/AS.png b/assets/cards/faces/AS.png
index 89ad5e2..9438649 100644
Binary files a/assets/cards/faces/AS.png and b/assets/cards/faces/AS.png differ
diff --git a/assets/cards/faces/JC.png b/assets/cards/faces/JC.png
index 985fbde..7684306 100644
Binary files a/assets/cards/faces/JC.png and b/assets/cards/faces/JC.png differ
diff --git a/assets/cards/faces/JD.png b/assets/cards/faces/JD.png
index e9c0684..9d58a97 100644
Binary files a/assets/cards/faces/JD.png and b/assets/cards/faces/JD.png differ
diff --git a/assets/cards/faces/JH.png b/assets/cards/faces/JH.png
index f357287..796b6da 100644
Binary files a/assets/cards/faces/JH.png and b/assets/cards/faces/JH.png differ
diff --git a/assets/cards/faces/JS.png b/assets/cards/faces/JS.png
index 87244c0..72e7ca5 100644
Binary files a/assets/cards/faces/JS.png and b/assets/cards/faces/JS.png differ
diff --git a/assets/cards/faces/KC.png b/assets/cards/faces/KC.png
index ddfe332..b50eb29 100644
Binary files a/assets/cards/faces/KC.png and b/assets/cards/faces/KC.png differ
diff --git a/assets/cards/faces/KD.png b/assets/cards/faces/KD.png
index 89f1346..5878812 100644
Binary files a/assets/cards/faces/KD.png and b/assets/cards/faces/KD.png differ
diff --git a/assets/cards/faces/KH.png b/assets/cards/faces/KH.png
index b0186b6..94f5d6c 100644
Binary files a/assets/cards/faces/KH.png and b/assets/cards/faces/KH.png differ
diff --git a/assets/cards/faces/KS.png b/assets/cards/faces/KS.png
index 314e39c..510bf07 100644
Binary files a/assets/cards/faces/KS.png and b/assets/cards/faces/KS.png differ
diff --git a/assets/cards/faces/QC.png b/assets/cards/faces/QC.png
index 37c528e..dd6cc6a 100644
Binary files a/assets/cards/faces/QC.png and b/assets/cards/faces/QC.png differ
diff --git a/assets/cards/faces/QD.png b/assets/cards/faces/QD.png
index 5a5066a..1fc8c97 100644
Binary files a/assets/cards/faces/QD.png and b/assets/cards/faces/QD.png differ
diff --git a/assets/cards/faces/QH.png b/assets/cards/faces/QH.png
index 9e962e6..b99f466 100644
Binary files a/assets/cards/faces/QH.png and b/assets/cards/faces/QH.png differ
diff --git a/assets/cards/faces/QS.png b/assets/cards/faces/QS.png
index 0cb6de4..55516f2 100644
Binary files a/assets/cards/faces/QS.png and b/assets/cards/faces/QS.png differ
diff --git a/solitaire_engine/assets/themes/default/back.svg b/solitaire_engine/assets/themes/default/back.svg
new file mode 100644
index 0000000..06454d4
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/back.svg
@@ -0,0 +1,40 @@
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_10.svg b/solitaire_engine/assets/themes/default/clubs_10.svg
new file mode 100644
index 0000000..2e7788c
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_10.svg
@@ -0,0 +1,281 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_2.svg b/solitaire_engine/assets/themes/default/clubs_2.svg
new file mode 100644
index 0000000..0334dec
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_2.svg
@@ -0,0 +1,216 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_3.svg b/solitaire_engine/assets/themes/default/clubs_3.svg
new file mode 100644
index 0000000..0fb95b3
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_3.svg
@@ -0,0 +1,224 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_4.svg b/solitaire_engine/assets/themes/default/clubs_4.svg
new file mode 100644
index 0000000..70f8904
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_4.svg
@@ -0,0 +1,230 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_5.svg b/solitaire_engine/assets/themes/default/clubs_5.svg
new file mode 100644
index 0000000..864d2f2
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_5.svg
@@ -0,0 +1,238 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_6.svg b/solitaire_engine/assets/themes/default/clubs_6.svg
new file mode 100644
index 0000000..306754e
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_6.svg
@@ -0,0 +1,244 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_7.svg b/solitaire_engine/assets/themes/default/clubs_7.svg
new file mode 100644
index 0000000..11329b1
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_7.svg
@@ -0,0 +1,252 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_8.svg b/solitaire_engine/assets/themes/default/clubs_8.svg
new file mode 100644
index 0000000..28ae6fb
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_8.svg
@@ -0,0 +1,260 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_9.svg b/solitaire_engine/assets/themes/default/clubs_9.svg
new file mode 100644
index 0000000..85cde35
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_9.svg
@@ -0,0 +1,254 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_ace.svg b/solitaire_engine/assets/themes/default/clubs_ace.svg
new file mode 100644
index 0000000..be74fe0
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_ace.svg
@@ -0,0 +1,258 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_jack.svg b/solitaire_engine/assets/themes/default/clubs_jack.svg
new file mode 100644
index 0000000..a350305
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_jack.svg
@@ -0,0 +1,224 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_king.svg b/solitaire_engine/assets/themes/default/clubs_king.svg
new file mode 100644
index 0000000..fe6e676
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_king.svg
@@ -0,0 +1,254 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/clubs_queen.svg b/solitaire_engine/assets/themes/default/clubs_queen.svg
new file mode 100644
index 0000000..6a636f7
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/clubs_queen.svg
@@ -0,0 +1,250 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_10.svg b/solitaire_engine/assets/themes/default/diamonds_10.svg
new file mode 100644
index 0000000..3d0b1c0
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_10.svg
@@ -0,0 +1,401 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_2.svg b/solitaire_engine/assets/themes/default/diamonds_2.svg
new file mode 100644
index 0000000..4956234
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_2.svg
@@ -0,0 +1,318 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_3.svg b/solitaire_engine/assets/themes/default/diamonds_3.svg
new file mode 100644
index 0000000..a562f1f
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_3.svg
@@ -0,0 +1,319 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_4.svg b/solitaire_engine/assets/themes/default/diamonds_4.svg
new file mode 100644
index 0000000..8677737
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_4.svg
@@ -0,0 +1,324 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_5.svg b/solitaire_engine/assets/themes/default/diamonds_5.svg
new file mode 100644
index 0000000..a8cb2b5
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_5.svg
@@ -0,0 +1,333 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_6.svg b/solitaire_engine/assets/themes/default/diamonds_6.svg
new file mode 100644
index 0000000..6f12a53
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_6.svg
@@ -0,0 +1,340 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_7.svg b/solitaire_engine/assets/themes/default/diamonds_7.svg
new file mode 100644
index 0000000..d8483a7
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_7.svg
@@ -0,0 +1,349 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_8.svg b/solitaire_engine/assets/themes/default/diamonds_8.svg
new file mode 100644
index 0000000..d6d1b0e
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_8.svg
@@ -0,0 +1,358 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_9.svg b/solitaire_engine/assets/themes/default/diamonds_9.svg
new file mode 100644
index 0000000..05292f2
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_9.svg
@@ -0,0 +1,367 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_ace.svg b/solitaire_engine/assets/themes/default/diamonds_ace.svg
new file mode 100644
index 0000000..e5636a4
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_ace.svg
@@ -0,0 +1,311 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_jack.svg b/solitaire_engine/assets/themes/default/diamonds_jack.svg
new file mode 100644
index 0000000..d531541
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_jack.svg
@@ -0,0 +1,338 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_king.svg b/solitaire_engine/assets/themes/default/diamonds_king.svg
new file mode 100644
index 0000000..f983c6a
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_king.svg
@@ -0,0 +1,351 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/diamonds_queen.svg b/solitaire_engine/assets/themes/default/diamonds_queen.svg
new file mode 100644
index 0000000..76b62db
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/diamonds_queen.svg
@@ -0,0 +1,339 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_10.svg b/solitaire_engine/assets/themes/default/hearts_10.svg
new file mode 100644
index 0000000..c57575e
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_10.svg
@@ -0,0 +1,407 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_2.svg b/solitaire_engine/assets/themes/default/hearts_2.svg
new file mode 100644
index 0000000..f6c9540
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_2.svg
@@ -0,0 +1,308 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_3.svg b/solitaire_engine/assets/themes/default/hearts_3.svg
new file mode 100644
index 0000000..aecd1ff
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_3.svg
@@ -0,0 +1,318 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_4.svg b/solitaire_engine/assets/themes/default/hearts_4.svg
new file mode 100644
index 0000000..9b7f0a7
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_4.svg
@@ -0,0 +1,335 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_5.svg b/solitaire_engine/assets/themes/default/hearts_5.svg
new file mode 100644
index 0000000..af7415a
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_5.svg
@@ -0,0 +1,336 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_6.svg b/solitaire_engine/assets/themes/default/hearts_6.svg
new file mode 100644
index 0000000..9c319ad
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_6.svg
@@ -0,0 +1,344 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_7.svg b/solitaire_engine/assets/themes/default/hearts_7.svg
new file mode 100644
index 0000000..8d5fd98
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_7.svg
@@ -0,0 +1,356 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_8.svg b/solitaire_engine/assets/themes/default/hearts_8.svg
new file mode 100644
index 0000000..ac8d5ba
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_8.svg
@@ -0,0 +1,364 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_9.svg b/solitaire_engine/assets/themes/default/hearts_9.svg
new file mode 100644
index 0000000..0f6a211
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_9.svg
@@ -0,0 +1,378 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_ace.svg b/solitaire_engine/assets/themes/default/hearts_ace.svg
new file mode 100644
index 0000000..24702e2
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_ace.svg
@@ -0,0 +1,324 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_jack.svg b/solitaire_engine/assets/themes/default/hearts_jack.svg
new file mode 100644
index 0000000..dc95ce1
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_jack.svg
@@ -0,0 +1,330 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_king.svg b/solitaire_engine/assets/themes/default/hearts_king.svg
new file mode 100644
index 0000000..7250745
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_king.svg
@@ -0,0 +1,337 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/hearts_queen.svg b/solitaire_engine/assets/themes/default/hearts_queen.svg
new file mode 100644
index 0000000..90ede78
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/hearts_queen.svg
@@ -0,0 +1,331 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_10.svg b/solitaire_engine/assets/themes/default/spades_10.svg
new file mode 100644
index 0000000..a14767c
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_10.svg
@@ -0,0 +1,230 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_2.svg b/solitaire_engine/assets/themes/default/spades_2.svg
new file mode 100644
index 0000000..759abf6
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_2.svg
@@ -0,0 +1,147 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_3.svg b/solitaire_engine/assets/themes/default/spades_3.svg
new file mode 100644
index 0000000..8963195
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_3.svg
@@ -0,0 +1,154 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_4.svg b/solitaire_engine/assets/themes/default/spades_4.svg
new file mode 100644
index 0000000..01e27e4
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_4.svg
@@ -0,0 +1,163 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_5.svg b/solitaire_engine/assets/themes/default/spades_5.svg
new file mode 100644
index 0000000..d9492ba
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_5.svg
@@ -0,0 +1,170 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_6.svg b/solitaire_engine/assets/themes/default/spades_6.svg
new file mode 100644
index 0000000..83e8feb
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_6.svg
@@ -0,0 +1,177 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_7.svg b/solitaire_engine/assets/themes/default/spades_7.svg
new file mode 100644
index 0000000..3146b44
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_7.svg
@@ -0,0 +1,186 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_8.svg b/solitaire_engine/assets/themes/default/spades_8.svg
new file mode 100644
index 0000000..0e5bd89
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_8.svg
@@ -0,0 +1,195 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_9.svg b/solitaire_engine/assets/themes/default/spades_9.svg
new file mode 100644
index 0000000..2359db5
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_9.svg
@@ -0,0 +1,198 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_ace.svg b/solitaire_engine/assets/themes/default/spades_ace.svg
new file mode 100644
index 0000000..db32c06
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_ace.svg
@@ -0,0 +1,131 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_jack.svg b/solitaire_engine/assets/themes/default/spades_jack.svg
new file mode 100644
index 0000000..281113f
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_jack.svg
@@ -0,0 +1,336 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_king.svg b/solitaire_engine/assets/themes/default/spades_king.svg
new file mode 100644
index 0000000..ac4338d
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_king.svg
@@ -0,0 +1,329 @@
+
+
+
+
+
diff --git a/solitaire_engine/assets/themes/default/spades_queen.svg b/solitaire_engine/assets/themes/default/spades_queen.svg
new file mode 100644
index 0000000..8dc5540
--- /dev/null
+++ b/solitaire_engine/assets/themes/default/spades_queen.svg
@@ -0,0 +1,324 @@
+
+
+
+
+
diff --git a/solitaire_engine/src/assets/sources.rs b/solitaire_engine/src/assets/sources.rs
index fe09ea8..d607f16 100644
--- a/solitaire_engine/src/assets/sources.rs
+++ b/solitaire_engine/src/assets/sources.rs
@@ -83,6 +83,78 @@ const DEFAULT_THEME_MANIFEST_PATH: &str = "solitaire_engine/assets/themes/defaul
const DEFAULT_THEME_MANIFEST_BYTES: &[u8] =
include_bytes!("../../assets/themes/default/theme.ron");
+/// Generates a `(stable_path, bytes)` entry for one default-theme
+/// SVG so the bulk-embed table below stays declarative. The path
+/// matches what `theme.ron` references; `include_bytes!` resolves
+/// relative to this source file.
+macro_rules! embed_default_svg {
+ ($name:literal) => {
+ (
+ concat!("solitaire_engine/assets/themes/default/", $name),
+ include_bytes!(concat!("../../assets/themes/default/", $name)) as &[u8],
+ )
+ };
+}
+
+/// Every default-theme SVG file bundled into the binary. Adding a new
+/// face / back artwork is a single `embed_default_svg!(...)` line —
+/// the populate function below iterates this table.
+const DEFAULT_THEME_SVGS: &[(&str, &[u8])] = &[
+ embed_default_svg!("back.svg"),
+ embed_default_svg!("clubs_ace.svg"),
+ embed_default_svg!("clubs_2.svg"),
+ embed_default_svg!("clubs_3.svg"),
+ embed_default_svg!("clubs_4.svg"),
+ embed_default_svg!("clubs_5.svg"),
+ embed_default_svg!("clubs_6.svg"),
+ embed_default_svg!("clubs_7.svg"),
+ embed_default_svg!("clubs_8.svg"),
+ embed_default_svg!("clubs_9.svg"),
+ embed_default_svg!("clubs_10.svg"),
+ embed_default_svg!("clubs_jack.svg"),
+ embed_default_svg!("clubs_queen.svg"),
+ embed_default_svg!("clubs_king.svg"),
+ embed_default_svg!("diamonds_ace.svg"),
+ embed_default_svg!("diamonds_2.svg"),
+ embed_default_svg!("diamonds_3.svg"),
+ embed_default_svg!("diamonds_4.svg"),
+ embed_default_svg!("diamonds_5.svg"),
+ embed_default_svg!("diamonds_6.svg"),
+ embed_default_svg!("diamonds_7.svg"),
+ embed_default_svg!("diamonds_8.svg"),
+ embed_default_svg!("diamonds_9.svg"),
+ embed_default_svg!("diamonds_10.svg"),
+ embed_default_svg!("diamonds_jack.svg"),
+ embed_default_svg!("diamonds_queen.svg"),
+ embed_default_svg!("diamonds_king.svg"),
+ embed_default_svg!("hearts_ace.svg"),
+ embed_default_svg!("hearts_2.svg"),
+ embed_default_svg!("hearts_3.svg"),
+ embed_default_svg!("hearts_4.svg"),
+ embed_default_svg!("hearts_5.svg"),
+ embed_default_svg!("hearts_6.svg"),
+ embed_default_svg!("hearts_7.svg"),
+ embed_default_svg!("hearts_8.svg"),
+ embed_default_svg!("hearts_9.svg"),
+ embed_default_svg!("hearts_10.svg"),
+ embed_default_svg!("hearts_jack.svg"),
+ embed_default_svg!("hearts_queen.svg"),
+ embed_default_svg!("hearts_king.svg"),
+ embed_default_svg!("spades_ace.svg"),
+ embed_default_svg!("spades_2.svg"),
+ embed_default_svg!("spades_3.svg"),
+ embed_default_svg!("spades_4.svg"),
+ embed_default_svg!("spades_5.svg"),
+ embed_default_svg!("spades_6.svg"),
+ embed_default_svg!("spades_7.svg"),
+ embed_default_svg!("spades_8.svg"),
+ embed_default_svg!("spades_9.svg"),
+ embed_default_svg!("spades_10.svg"),
+ embed_default_svg!("spades_jack.svg"),
+ embed_default_svg!("spades_queen.svg"),
+ embed_default_svg!("spades_king.svg"),
+];
+
/// Registers asset sources that must be in place *before*
/// `AssetPlugin` is built.
///
@@ -128,26 +200,39 @@ impl Plugin for AssetSourcesPlugin {
/// unit test below can exercise it without spinning up a full Bevy
/// `App` with `AssetPlugin`.
///
-/// **Adding files to the bundled default theme** is a single edit
-/// per file: add an `include_bytes!` constant that points at the file
-/// under `solitaire_engine/assets/themes/default/`, then add a
-/// matching `registry.insert_asset(...)` call here. Keep the
-/// `asset_path` argument exactly the relative path that the manifest
-/// references (e.g. `solitaire_engine/assets/themes/default/back.svg`).
+/// **Adding files to the bundled default theme** is a single edit:
+/// append one `embed_default_svg!("filename.svg")` line to the
+/// `DEFAULT_THEME_SVGS` table above. The file resolves relative to
+/// `solitaire_engine/assets/themes/default/` and registers under
+/// the matching `embedded://` URL automatically.
pub fn populate_embedded_default_theme(app: &mut App) {
let registry = app
.world_mut()
.get_resource_or_insert_with(EmbeddedAssetRegistry::default);
- // `full_path` is only consulted by the optional
- // `embedded_watcher` cargo feature (which we don't enable). Use
- // the manifest's logical workspace path so a future debugger
- // session sees a sensible source-of-truth string.
+ // The manifest first — its asset URL is the entry point everything
+ // else (`set_theme`, the registry, the loader) references via
+ // `DEFAULT_THEME_MANIFEST_URL`.
+ //
+ // `full_path` is only consulted by the optional `embedded_watcher`
+ // cargo feature (which we don't enable). Use the manifest's
+ // logical workspace path so a future debugger session sees a
+ // sensible source-of-truth string.
registry.insert_asset(
std::path::PathBuf::from(DEFAULT_THEME_MANIFEST_PATH),
std::path::Path::new(DEFAULT_THEME_MANIFEST_PATH),
DEFAULT_THEME_MANIFEST_BYTES,
);
+
+ // Then every face + back SVG. The manifest references each by the
+ // same relative path used here.
+ for (path, bytes) in DEFAULT_THEME_SVGS {
+ registry.insert_asset(
+ std::path::PathBuf::from(*path),
+ std::path::Path::new(*path),
+ *bytes,
+ );
+ }
}
#[cfg(test)]