Compare commits

...

43 Commits

Author SHA1 Message Date
funman300 fe41b502ac docs: CHANGELOG + SESSION_HANDOFF refresh for v0.13.0
CHANGELOG gains a [0.13.0] section covering the third UX iteration
round on top of v0.12.0:
- Tooltip-delay slider, streak fire, score-breakdown reveal
- Card backs follow active theme
- Drag-with-keyboard
- Right-click radial menu
Plus two code-review fixes (Removed: sccache wiring, Fixed: bundled-
only font handling).

The bottom-of-file compare links thread the new tag into the
existing chain. Test count updated to 1053.

SESSION_HANDOFF gains a "Session 7 round 3" table summarising the
six commits and rolls the punch list forward — UX candidate list
exhausted again, fresh six-item list seeded for a future round
(daily-challenge calendar, theme-picker thumbnails, per-mode high
scores, in-progress auto-save for Zen/Time Attack, configurable
scoring weights, win replays). Resume prompt asks A/B/C/D about
push, smoke-test, next round, or packaging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:43:38 +00:00
funman300 b37f0cbec7 feat(engine): right-click radial menu for quick-drop without dragging
Power-user shortcut: hold right-click on a face-up card, a small
ring of icons appears around the cursor with one entry per legal
destination, release over an icon to fire MoveRequestEvent. Skips
the drag motion entirely while preserving the existing
RightClickHighlight tint on the actual pile markers.

A new RadialMenuPlugin owns the flow. RightClickRadialState is a
two-state enum (Idle / Active) carrying the source pile, lifted
cards, pre-computed legal destinations + their world anchors, the
ring centre, and the currently hovered icon index. Four chained
systems handle press → cursor track → release/cancel → redraw, in
that order so a single-tick test can't observe a half-state.

Mutual exclusion with the left-button mouse drag is implicit —
RadialMenuPlugin only listens to MouseButton::Right while the
existing drag pipeline only listens to Left. RightClickHighlight
co-exists at a lower z (50) than the radial overlay (Z_RADIAL_MENU
= 60), so the brief pile-marker tint reads as the same set of legal
destinations the radial offers.

Cancel paths: release the right button outside any icon, press Esc,
or press the left button. All three reset state to Idle without
dispatching a move.

Visual: a centre dot at the press location plus N icons at radius
80 px around it. For one destination the icon sits at 12 o'clock;
for N icons they spread evenly clockwise. Hovered icon scales to
1.15× and tints STATE_SUCCESS so the focused choice is unambiguous.

Twelve new tests pin the contract — five system-level (open on
press over face-up card, release over destination fires move event,
release in dead space cancels, Esc cancels, face-down doesn't
open), seven on the pure helpers (radial_anchor_for_index,
radial_hovered_index, legal_destinations_for_card). Tests inject
cursor positions through a RadialCursorOverride resource so they
work under MinimalPlugins where there's no PrimaryWindow or Camera.

help_plugin's controls reference gains a new "Mouse" section
covering double-click auto-move, right-click highlight, and the
new "Hold RMB" radial. Onboarding slide 3 is intentionally left
keyboard-only — the radial is a power-user discovery, not a
first-run teach.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:40:48 +00:00
funman300 a0fc0d2605 feat(engine): keyboard-only drag-and-drop via Tab → Enter → arrows → Enter
Players can now complete an entire game without a mouse. Tab cycles
the keyboard cursor across draggable card stacks, Enter "lifts" the
focused stack into a destination-pick mode, arrow keys (or Tab)
cycle through the legal targets only, and Enter confirms the move.
Esc cancels — single-press in Lifted reverts to source-pick keeping
focus, second-press clears the source selection entirely.

A new KeyboardDragState resource models the two-mode flow without
touching SelectionState's existing source-pick contract:

  Idle                         (Tab/Enter/auto-move via SelectionState)
  Lifted {
      source_pile, count, cards,
      legal_destinations,      pre-computed at lift time via
      destination_index,       can_place_on_foundation/_tableau
  }

Mutual exclusion with mouse drag is sentinel-based: keyboard lift
sets DragState.active_touch_id = u64::MAX (KEYBOARD_DRAG_TOUCH_ID),
existing mouse handlers in input_plugin already short-circuit when
active_touch_id is Some, and the cleanup path only clears DragState
when the sentinel is present so the mouse path is never stomped.
Conversely keyboard input is suppressed when a real mouse/touch
drag is active.

The visual lift reuses the existing drag z-lift and shadow path so
the keyboard-lifted stack reads the same as a mouse-lifted one;
update_selection_highlight gains a green destination indicator on
the focused legal target while Lifted.

help_plugin's canonical hotkey list grows a "Keyboard drag"
section (Tab/Enter/Arrows/Esc/Space) and onboarding slide 3 picks
up a "Tab → Enter" entry so first-run players see the full path.

Seven new headless tests pin the contract: Tab cycles to first
draggable pile, Enter lifts the stack, arrow keys cycle only legal
destinations, Enter with destination fires MoveRequestEvent and
clears state, Esc reverts to source-pick, mouse-drag-active
suppresses keyboard input, double-Esc clears source selection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:10:41 +00:00
funman300 7ed4f2cba9 feat(engine): card backs follow active theme
Themes already shipped a back.svg in their manifest but card_plugin
ignored it — face-down cards always rendered with the legacy
back_N.png picker, so swapping themes only swapped the faces. Now
the active theme's back rasterises alongside its faces and feeds
into the face-down sprite path; the legacy back_N.png picker remains
the fallback when a theme doesn't ship its own back (e.g. a
user-imported theme that only redefines faces).

theme/plugin.rs caches the active theme's back Handle<Image> in the
ActiveTheme resource on theme-load and theme-switch. card_plugin's
face-down branch reads ActiveTheme first; missing theme back →
legacy back_N.png path indexed by Settings.selected_card_back.

Settings → Cosmetic's card-back picker section gains a caption
("Active theme provides its own back") that surfaces when the
override is in effect, plus the swatch row dims to communicate the
read-only state. Settings file format unchanged — selected_card_back
still round-trips and only takes effect when the theme leaves the
back undefined.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:08:17 +00:00
funman300 ddc8f27c82 feat(engine): UX iteration round — tooltip slider, streak fire, score breakdown
Three small UX improvements bundled because they share ui_theme token
edits.

Tooltip-delay slider in Settings → Gameplay
- Settings.tooltip_delay_secs (f32, #[serde(default)] = 0.5) tunable
  via "−" / "+" icon buttons next to a value readout. Range
  [TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_MAX_SECS] = [0.0, 1.5] in
  TOOLTIP_DELAY_STEP_SECS (0.1) increments. "Instant" label when
  value is 0; "{n:.1} s" otherwise.
- ui_tooltip's hover-delay comparison reads from SettingsResource
  with MOTION_TOOLTIP_DELAY_SECS as the fallback when the resource
  is absent (test path). New tooltip_should_show(elapsed, delay)
  pure helper covers the boundary cases.
- adjust_tooltip_delay clamps; sanitized() carries the clamp through
  load. Five round-trip / default / legacy-deserialise tests.

Win-streak milestone fire animation
- New WinStreakMilestoneEvent { streak: u32 } fired from stats_plugin
  when win_streak_current crosses any of [3, 5, 10] (only the
  threshold crossing — not every subsequent win). HUD streak readout
  scale-pulses 1.0 → 1.20 → 1.0 over MOTION_STREAK_FLOURISH_SECS
  (0.6 s) on receipt; mirrors the foundation-flourish curve shape.
- Three threshold-crossing tests pin the firing contract.

Score-breakdown reveal on the win modal
- Win modal body replaces the single "Score: N" line with a
  per-component reveal: Base score, Time bonus (m:ss), No-undo
  bonus, Mode multiplier, separator, Total. Rows fade in over
  MOTION_SCORE_BREAKDOWN_FADE_SECS (0.12 s) staggered by
  MOTION_SCORE_BREAKDOWN_STAGGER_SECS (0.15 s) so the math reads as
  it animates. Skipped rows: zero time bonus, undo-tainted no-undo
  bonus, multiplier == 1.0.
- Honours AnimSpeed::Instant: rows spawn fully visible, no stagger.
- New ScoreBreakdown::compute helper sources base from
  GameWonEvent.score, time bonus from
  solitaire_core::scoring::compute_time_bonus, no-undo from a +25
  constant when undo_count == 0, mode multiplier from GameMode (Zen
  zeros the total). 9 new tests cover the math and the reveal
  cadence.

Test count net: +25 across the workspace (1007 → 1031).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:34:53 +00:00
funman300 13dd44bd1b chore: remove project-level sccache rustc-wrapper config
Code-review feedback: sccache shouldn't be a per-project build
dependency. Cargo's incremental cache already covers what sccache
offers for a single project, and forcing rustc-wrapper = "sccache"
project-wide means every contributor has to install sccache or
prepend RUSTC_WRAPPER= to bypass the wrapper.

.cargo/config.toml only existed to wire sccache and pin SCCACHE_DIR
to a project-local cache. Removing the file entirely so plain
`cargo build` works without any extra setup. The .cargo directory
is empty after the deletion and removed too. .gitignore's
/.sccache-cache line is harmless cruft and stays — players who
already have a populated .sccache-cache directory keep it ignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:34:20 +00:00
funman300 17f9b518f1 fix(engine): bundle fonts only and drop system-font fallback
Code-review feedback: the SVG rasteriser mixed three font-resolution
layers (load_system_fonts + bundled FiraMono + lenient resolver
appending CSS generics), which made card text rendering depend on
which fonts the host machine happened to have. The Bevy UI face
loaded separately at runtime via AssetServer. Picking option (a)
from the review and applying it consistently: bundle FiraMono via
include_bytes!() in BOTH layers, no system fallback anywhere.

solitaire_engine/src/font_plugin.rs now embeds main.ttf at compile
time and registers it with Assets<Font>. A parse failure aborts
with "bundled FiraMono failed to parse — binary is corrupt"; the
MinimalPlugins early-return stays as a "this plugin doesn't apply
in headless tests" check (consumers query Option<Res<FontResource>>
and degrade cleanly), not a production fallback.

solitaire_engine/src/assets/svg_loader.rs drops load_system_fonts
entirely, drops the lenient_font_resolver, and drops the five
set_*_family pins. The new bundled_font_resolver ignores the SVG's
font-family request and always returns the single bundled face —
the bundled card SVGs reference Arial / Bitstream Vera Sans by name
and we deliberately don't ship those, so routing every query to
FiraMono keeps rasterisation deterministic. shared_fontdb asserts
the embedded bytes parsed.

The two layers now embed the same path
(assets/fonts/main.ttf) independently, so they can't drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:33:54 +00:00
funman300 61d891fb76 docs: CHANGELOG + SESSION_HANDOFF refresh for v0.12.0
CHANGELOG gains a [0.12.0] section covering the second UX iteration
round on top of v0.11.0:
- Foundation completion flourish
- Drag-cancel return tween
- Focus ring breathing
- First-win achievement onboarding toast
- Mode Launcher digit shortcuts
- Card aspect-ratio fix (1.4 → 1.4523)
- Plus the README and CHANGELOG-add docs that rode along

The bottom-of-file compare links thread the new tag into the
existing chain (Unreleased → 0.12.0 → 0.11.0 → ...). Test count
updated to 1007.

SESSION_HANDOFF now distinguishes session 7 round 1 (v0.11.0,
morning) from round 2 (v0.12.0, afternoon) — keeping the audit
trail readable instead of conflating them. The release-prep punch
list collapses to the three tag/push/packaging items; the UX
iteration list opens with six fresh candidates for whoever picks
the next round.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 03:08:46 +00:00
funman300 7dba772e67 feat(engine): digit shortcuts (1-5) launch modes from inside the Mode Launcher
Pressing M already opens the Home modal (which is the Mode Launcher
post-v0.11) and Tab cycles focus through the cards. The remaining
gap was direct keyboard activation of a specific mode — players had
to tab-and-enter or click. A new modal-scoped digit handler closes
that gap:

  1 → Classic (NewGameRequestEvent)
  2 → Daily Challenge (StartDailyChallengeRequestEvent)
  3 → Zen (StartZenRequestEvent, gated at level 5)
  4 → Challenge (StartChallengeRequestEvent, gated at level 5)
  5 → Time Attack (StartTimeAttackRequestEvent, gated at level 5)

handle_home_digit_keys runs only when HomeScreen exists and short-
circuits otherwise — the digit keys can't accidentally launch a
mode mid-game. Locked modes (level < CHALLENGE_UNLOCK_LEVEL) silent-
no-op rather than firing a toast, mirroring the click-on-locked-card
behaviour without the InfoToastEvent (the click path's toast is the
authoritative "level too low" surface).

The HomePlugin Update tuple is now .chain()ed because the Bevy 0.18
parallel scheduler would otherwise let handle_home_card_click,
handle_home_cancel_button, and the new digit handler all queue a
HomeScreen despawn concurrently — the second buffer apply panics
on the already-despawned entity.

help_plugin gains a new "Mode Launcher (M)" section with the digit
rows and a level-5 unlock note. onboarding's slide-3 hotkey table
gets one new line ("M — Open Mode Launcher (then 1-5 to pick)") so
first-run players see the full path. The help-modal canonical list
now mirrors the onboarding teach.

Four new headless tests pin the contract: Digit1 launches Classic
and closes the modal; Digit3 at level 0 is a no-op (modal stays
open); Digit3 at unlock level launches Zen and closes; digit keys
outside the modal fire no events at all.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 03:01:41 +00:00
funman300 ca5788f714 feat(engine): one-shot achievement-onboarding toast on first win
After the player's very first win the engine now writes
"First win! Press A to see your achievements." via InfoToastEvent,
then flips a persisted Settings.shown_achievement_onboarding flag so
the cue never re-fires. Mentions the A hotkey by name so the toast
is actionable on its own.

The toast path runs after StatsUpdate so games_won has been
incremented to 1 when the system reads it; .after(GameMutation)
keeps the post-move state visible. Three guards: first win only,
flag was false, GameWonEvent fired this tick.

Persistence mirrors onboarding_plugin's complete_onboarding pattern:
save via save_settings_to with the existing
SettingsStoragePath/Option<&PathBuf> graceful-fallback shape.
Atomic .tmp+rename writes are unchanged.

Settings gains a single bool field with #[serde(default)] so legacy
settings.json files deserialize cleanly to false. The field is
local-only by design — it's about UI teaching for THIS device, not
progression — so SyncPayload and merge logic are untouched.

Seven new tests pin the contract: default value is false, field
round-trips through save/load, legacy JSON without the field
deserializes to false, first win fires the toast and flips the
flag, subsequent wins are silent, the fifth win on a synced device
is silent (won't fire when games_won has been bumped via sync), and
no win event means no toast.

Toast duration is the existing animation_plugin
QUEUED_TOAST_SECS = 2.5 s — InfoToastEvent is a tuple struct with
no duration parameter, so the agent kept the existing event shape
rather than expanding it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 03:01:18 +00:00
funman300 9887343d8b feat(engine): focus ring breathes at 1.4 s — gentle pulse instead of flat
The keyboard focus ring rendered as a static yellow outline. A new
pulse_focus_overlay system modulates the overlay's BorderColor alpha
with a sin curve over MOTION_FOCUS_PULSE_SECS (1.4 s), breathing the
visible alpha between 0.65× and 1.0× of FOCUS_RING's native value.
The motion is slow enough to read as a calm heartbeat in peripheral
vision rather than a competing animation, and a focus change still
draws the eye because the ring re-attaches at full brightness on
the next pulse cycle.

The pulse honours AnimSpeed::Instant by reading SettingsResource
and skipping the modulation entirely (static FOCUS_RING colour) for
reduced-motion users — matches the convention used elsewhere for
animation gating.

A pure focus_ring_pulse_factor(elapsed_secs) helper is unit-tested
for the curve shape: 0.825 at t=0 (mid-point), 1.0 at the
quarter-period peak, 0.65 at the three-quarter-period trough, and a
sweep across two full periods stays within the [0.65, 1.0] range.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 02:40:40 +00:00
funman300 525fe0fe76 feat(engine): drag-cancel return tween — smooth ease-out instead of shake
Illegal drops previously snapped each dragged card to its origin
slot and ran a horizontal ShakeAnim wiggle for negative feedback —
which read as punitive on every misclick. The rejection now plays
a 150 ms quintic ease-out glide from the drop location back to the
resting slot. The audio cue (card_invalid.wav) still fires so the
player gets clear "no" feedback; the visual is just gentler.

Both rejection paths in input_plugin (mouse end_drag and touch
end_drag) construct a CardAnimation::slide(drag_pos → target_pos)
with MotionCurve::Responsive — the curve module's own docs
recommend Responsive specifically for invalid snap-back because its
zero overshoot reads forgiving rather than jittery.

card_plugin's update_card_entity gates its snap path on
CardAnimation absence so the StateChangedEvent that follows a
rejection no longer fights the in-flight tween. Mirrors how
resize_cards_in_place already drops in-flight tweens during a
window resize.

ShakeAnim itself stays in feedback_anim_plugin — the right-click
invalid-target and double-click in-place rejection paths still use
it because there's no movement to interpolate, just a "no" wiggle.
Only the drag-rejection path swaps to the smooth tween.

Six new rejection-tween tests pin the contract: CardAnimation is
inserted on every dragged card, start/end positions and z values
match the drag-to-resting transition, duration matches the new
MOTION_DRAG_REJECT_SECS token, and the curve is Responsive. The
two legacy ShakeAnim drag-rejection tests are removed since their
contract is intentionally inverted by this commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:34:12 +00:00
funman300 69ce9afab9 feat(engine): foundation completion flourish — King-on-foundation celebration
Now that foundations are unlocked and "completing" one is a real
moment (rather than a foregone conclusion based on suit assignment),
each Ace-through-King run gets its own small celebration when the
King lands.

Three layers fire on a single FoundationCompletedEvent emitted by
game_plugin's handle_move when a successful move leaves a
PileType::Foundation pile holding 13 cards:

1. King card scale-pulse via a new FoundationFlourish component.
   Triangular curve 1.0 → 1.15 → 1.0 over MOTION_FOUNDATION_FLOURISH
   _SECS (0.4s) — same shape as the existing ScorePulse so the feel
   matches.
2. Pile-marker tint flourish via FoundationMarkerFlourish — the
   foundation marker's sprite colour lerps to STATE_SUCCESS for the
   first half of the duration then fades back. Reuses the existing
   success-signal palette; no new colour token.
3. Audio cue: foundation_complete.wav, a synthesised C6→E6→G6 triad
   with 2nd-harmonic warmth and AR decay (~240 ms). Sits an octave
   above win_fanfare's root so the layered fourth-completion + win
   cascade reads cleanly. Generated via solitaire_assetgen's
   foundation_complete() function and embedded via include_bytes!().

The visual systems run .after(GameMutation) so the post-move pile
state is visible when the King is identified. Both flourish
components remove themselves once elapsed time exceeds duration —
no animation queue or scheduler integration needed.

Pure foundation_flourish_scale(elapsed, duration) helper is
unit-tested for the curve, edge clamps, and zero-duration safety.
Three integration tests on the firing logic verify the event fires
exactly once when a King completes a foundation, doesn't fire for
non-foundation moves, and doesn't fire when the foundation is at 12
cards.

The fourth completion still co-occurs with the win cascade — the
two layer cleanly because the flourish's scale is on the King card
sprite while the cascade is a screen-shake + per-card rotation, and
the foundation_complete ping is a higher octave than the win
fanfare's root.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:19:50 +00:00
funman300 13aa0fd833 fix(engine): match CARD_ASPECT to hayeah SVG dimensions (1.4 → 1.4523)
Cards rendered ~3.6 % squashed vertically because layout.rs assumed a
1.4 height/width ratio while the bundled hayeah/playing-cards-assets
SVGs are natively 167.087 × 242.667 (= 1.4523). The mismatch meant
every face was scaled to fit a too-short box; pip arrangements and
court-card art read slightly compressed.

Bumps CARD_ASPECT to 1.4523 to match the SVG. The vertical-budget
math in compute_layout (the height-based card_width candidate) uses
CARD_ASPECT algebraically, so the tableau-fits-on-screen check
adapts automatically — slightly smaller cards on aspect-ratio-tight
windows, no visible regression on standard 16:9.

Doc comments referencing the old 1.4 literal updated to point at
CARD_ASPECT instead so this can't drift again.

All 982 tests pass — the existing layout/test sentinel
(card_size.y / card_size.x - CARD_ASPECT) used the constant by name
and adapted for free.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:03:12 +00:00
funman300 9f095c4039 docs: add CHANGELOG.md covering v0.9.0 through v0.11.0
The CHANGELOG didn't exist; v0.11.0 felt too meaty to land without one
and starting from v0.10.0+ would have made the file feel rootless. The
format follows Keep a Changelog 1.1.0 with the standard Added /
Changed / Fixed / Removed sections per release plus a Migration block
when relevant.

v0.11.0 (2026-05-02) — full coverage of the card-theme system, HUD
overhaul, drag-feel polish (drop overlay, drop shadows, stock count
badge, unlocked foundations), the FiraMono fontdb fix, and the
schema-version bump that invalidates pre-v2 game_state.json saves on
launch. 982 tests, zero clippy.

v0.10.0 (2026-04-29) — PNG art pipeline, Bevy 0.15 → 0.18 migration,
kira 0.9 → 0.12 migration, Rust edition 2024 + MSRV 1.95, custom
font, JWT-secret-at-startup fix, SmartIpKeyExtractor, MessageReader
touch-input fix.

v0.9.0 (2026-04-28) — initial public-tagged release: workspace
structure, modal scaffold, design-token system, four-tier HUD,
progression, sync server, splash, focus rings, tooltips,
achievement integration tests, all the foundation work that
predates the card-theme rewrite.

README gains a Changelog section linking to the new file.

The bottom-of-file compare links use the corrected
github.com/funman300/Rusty_Solitaire URL so the rendered page on
GitHub auto-generates the correct diff views once the tags are
pushed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:59:13 +00:00
funman300 d8c70341f4 docs: refresh README for v0.11.0 — card themes, HUD overhaul, drag feel
The README hadn't been touched since before the card-theme system
landed and was missing every UX feel improvement from v0.11.0.
Anyone discovering the repo on the GitHub release page would have
seen pre-theme copy.

Features list now covers card themes (bundled default + user
zip-installable), the modern HUD (reserved band + action-bar
auto-fade), and the four drag-feel improvements (drop highlights,
drop shadows, stock count badge, unlocked foundations).

Controls table fixes three real discrepancies: Undo is U not
Z/Ctrl+Z (the README inverted the bindings), Help is F1 not H, and
Z actually toggles Zen mode. Adds the previously undocumented Tab /
Shift+Tab focus cycle, Enter activation, F11 fullscreen, double-
click to auto-move, and the G forfeit shortcut. Notes that every
action is also a visible UI button so the keyboard list is
optional-accelerator only — matches the project's UI-first rule.

Adds a small Card Themes section explaining how to install a theme
(drop a directory or zip-import via Settings → Cosmetic) without
diving into SVG technicals.

Test count updated to 982 to reflect v0.11.0 baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:56:24 +00:00
funman300 063269c70e docs: update repo URL references to corrected Rusty_Solitaire spelling
The GitHub repo was renamed from Rusty_Solitare to Rusty_Solitaire
(adding the missing 'i'). The local origin remote has been updated
via `git remote set-url`; this commit updates the three doc
references that hardcoded the old URL.

SESSION_HANDOFF.md's "Canonical remote" section now names the new
URL and explains the rename for future readers, including the note
that local clone directories may still be named Rusty_Solitare —
that's a local-only name and works fine, only the GitHub repo URL
changed.

docs/SESSION_HANDOFF.md (older snapshot, unchanged otherwise) gets
its single URL line corrected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:36:06 +00:00
funman300 b126df82b2 docs: refresh SESSION_HANDOFF for session 7 UX-iteration round complete
Session 6 closed with a four-item UX punch list (unlock foundations,
drop shadows, drop-target highlights, stock badge). All four shipped
in session 7, plus an unrelated font-fallback fix surfaced by a
second-machine smoke test that landed before the UX work.

Refreshes the doc to reflect:
- HEAD: 655dfde, 3 commits ahead of origin
- 982 tests pass (was 962)
- Session 7 changelog table summarising the five commits
- UX punch-list entirely closed; release-prep items still on the
  table but un-deferred (player gets a directional choice next session)
- New "next-round candidates" UX list (animated focus ring,
  achievement onboarding, mode-switch keyboard shortcut, aspect-ratio
  fidelity, foundation completion flourish, drag-cancel tween)
- Resume prompt asks A/B/C: tag v0.11.0, README/CHANGELOG first, or
  start a new UX round

Length 120 → 109 (-11) by trimming the spent priority list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:33:42 +00:00
funman300 655dfde736 feat(engine): stock-pile remaining-count badge
Players were recycling the stock blind — there's no in-world
indicator of how many cards are left before the recycle. A small
"·N" chip now sits at the top-right corner of the stock pile,
showing the remaining count.

The badge is a top-level world entity whose Transform.translation is
recomputed each tick from the live LayoutResource (so window resizes
and theme switches don't strand it), parented to neither the
PileMarker nor any card. update_stock_count_badge spawns the entity
on the first frame, then on every subsequent frame reads the stock
pile's card count, writes the formatted text into the child Text2d,
and toggles Visibility::Hidden when the count drops to zero — the
same state where StockEmptyLabel's existing ↺ icon takes over, so
the two never co-render.

Z_STOCK_BADGE = 30 sits above stock cards (z ≈ 1) and below
Z_DROP_OVERLAY = 50, so the badge stays visible during normal play
but green drop-target washes still cover it while a card is being
dragged. Card drop shadows live at negative local z relative to
each card and don't compete with the badge plane.

Tokens (STOCK_BADGE_BG, STOCK_BADGE_FG, Z_STOCK_BADGE) were already
present in ui_theme from prior work; this commit only wires them up.
The chip itself is 28×16 px, rendered with TYPE_CAPTION text in
ACCENT_PRIMARY against BG_ELEVATED_HI.

Four new tests pin the contract: badge shows "·24" on a fresh deal,
hides when the stock empties, updates as the count drops, and the
stock_card_count helper reports 0 when the pile is missing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:31:15 +00:00
funman300 f712b89fe4 feat(engine): drop shadows on cards with lifted state during drag
Cards previously read as flat stickers on the felt — no separation
cue, no sense the play surface had any depth. Each CardEntity now
spawns a CardShadow child sprite: neutral black at 25 % alpha, sized
to card_size + 4 px halo, offset (2, -3) and rendered at local z
-0.05 so it sits behind its card.

Cards in the active drag set switch to a lifted shadow: alpha 40 %,
offset (4, -6), padding (8, 8). update_card_shadows_on_drag runs
every Update and snaps each shadow to the right state based on
DragState membership — no lerp, no animation cost. The pure
card_shadow_params(is_dragged) helper is unit-tested for the four
parameter values.

resize_cards_in_place gains a third query for shadows so the
in-place resize keeps shadows cheap (no Sprite regeneration); the
shadow's current alpha is read to preserve idle vs lifted padding
across a resize. update_card_entity's despawn_related call is
followed by a fresh add_card_shadow_child so the shadow re-attaches
when the card is repainted (face flip, settings change, theme
swap). The pre-existing bulk drag-shadow under the whole lifted
stack is untouched — per-card shadows complement it.

All shadow values flow through eight new ui_theme tokens
(CARD_SHADOW_COLOR, alphas, offsets, paddings, local z) so the
visual is tunable in one place. Color is neutral black so the
shadows don't conflict with color-blind mode's red/blue suit tints.

Four new tests pin the contract: shadow params for idle and drag
states, every CardEntity spawns with exactly one CardShadow child,
and dragging shifts only the dragged shadow's offset while leaving
unrelated shadows on the idle offset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:21:28 +00:00
funman300 f6c916641a feat(engine): visible drop-target overlay during drag
The existing update_drop_highlights system tinted PileMarker sprites
green for valid drops, but the marker is a card-sized rectangle that
sits behind the stack. Once a tableau column had any cards on it the
marker was occluded and the highlight effectively invisible — the
handoff's "drops feel guess-y because there's no preview" point.

A new update_drop_target_overlays system spawns an overlay above every
legal target during drag: a soft DROP_TARGET_FILL rectangle sized to
the pile's actual visible footprint (full fanned column for tableaux,
card-sized for foundations and empty tableaux) plus four thin
DROP_TARGET_OUTLINE edges forming a 3 px border. Z_DROP_OVERLAY = 50
sits above static cards (z ~1) but below the dragged stack (DRAG_Z =
500), so the overlay never occludes the card the player is holding.

The valid-target enumeration mirrors update_drop_highlights exactly so
the rules can't drift, and pile geometry mirrors input_plugin's
pile_drop_rect. The original marker-tint system is untouched; it still
does its job for empty-pile placeholders. The overlay layer is purely
additive — running alongside, not replacing.

Token values reuse the existing STATE_SUCCESS hue (#4ADE80) at 10%
fill / 75% outline so the overlay green matches the rest of the
success-signal palette (foundation completion, sync OK, etc.).

Three headless tests pin the contract: overlay spawns for valid
tableau drops, doesn't spawn for invalid destinations, and despawns
the moment the drag ends.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 22:33:22 +00:00
funman300 95df5421c9 feat(core): unlock foundations — Foundation(u8) slots, suit derived from contents
Standard Klondike behaviour: any Ace can land in any empty foundation,
and that slot then claims the suit until the pile empties. The
previous PileType::Foundation(Suit) variant pre-assigned each of the
four foundations to a fixed suit ("C / D / H / S" placeholders) and
rejected mismatched Aces — non-standard and (per the smoke-test
feedback) confusing.

Replaces the variant payload with a slot index Foundation(u8) (0..=3)
and derives the claimed suit from the bottom card via a new
Pile::claimed_suit() method. The bottom card is, by construction,
the Ace that established the claim; using it directly eliminates an
entire class of "stuck claim after undo" bugs that a separate
claimed_suit field would have introduced.

can_place_on_foundation drops its suit parameter — the rule reduces
to "empty pile accepts any Ace; non-empty pile accepts the next
rank up of the bottom card's suit." Iteration sites across
input_plugin, cursor_plugin, selection_plugin, card_plugin,
auto_complete_plugin, game_plugin, layout, and hud_plugin all swap
the four-suit list for `(0..4u8).map(PileType::Foundation)`.

next_auto_complete_move now prefers a slot whose claimed_suit matches
the candidate card before falling back to the first empty slot for
an Ace — so the same suit consistently auto-targets the same slot
across the whole game, matching player expectations.

The HUD selection label and the hint toast read claimed_suit() and
fall back to "Foundation N" / "move to foundation" only when the
slot is empty. Empty foundation pile markers no longer render the
suit-letter children — they're plain translucent rectangles, matching
empty tableau placeholders.

Save-format invalidation: GameState gains a schema_version field
(serde-default to 1 for back-compat parsing of old files), the
constant is bumped to 2, and load_game_state_from rejects mismatched
schemas. Old in-progress saves silently fall through to "fresh game
on launch" — the user accepted this loss given the mechanic change.
Stats / progress / achievements / settings live in separate files,
contain no PileType data, and are unaffected.

9 new tests pin the contract:
- Pile::claimed_suit returns None for empty / non-foundation, Some
  for non-empty foundation
- Any Ace lands in the first empty foundation; successive Aces
  distribute across slots 0..3
- Claim drops when the slot is emptied via undo
- Auto-complete picks the slot with a matching claim, not the first
  empty slot
- A v1-format game_state.json is rejected; sibling stats save/load
  is unaffected

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 22:17:17 +00:00
funman300 fdb6c2ecfe fix(engine): bundle FiraMono into SVG fontdb as last-resort fallback
The hayeah card SVGs reference Bitstream Vera Sans and Arial by name.
The lenient FontResolver from efa063f appends Family::SansSerif and
Family::Serif so unmatched named families fall through to whatever
the system serves under those CSS generics — which works on machines
with a normal fontconfig setup, and silently fails on minimal Linux
installs, fresh Wayland sessions, or chroots where the generic
aliases don't resolve to anything either. The visible symptom on the
player's second machine was "card font didn't carry over": rank and
suit glyphs vanished from the cards because every lookup path hit a
None.

shared_fontdb now also include_bytes!()s the bundled
assets/fonts/main.ttf into the fontdb after load_system_fonts, and
pins each CSS generic (sans-serif, serif, monospace, cursive,
fantasy) to "Fira Mono". Named-family lookups still prefer the
system db first when those families exist, so machines with a normal
font setup behave identically; only when SansSerif/Serif fall through
does the resolver land on FiraMono — guaranteed present because it's
embedded in the binary.

The bundled font is ~170 KB; the binary already include_bytes!()s the
six audio WAVs and the embedded card-theme SVGs, so this fits the
existing self-contained-binary policy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 21:41:35 +00:00
funman300 9a3d7f3876 docs: refresh SESSION_HANDOFF for session 6 + UX-iteration direction
Captures today's six commits (theme loader fix, exit-warn silence, two
font-warn rounds, HUD band, action fade), updates HEAD/test counts,
records that the player redirected from "cut v0.11.0 / package" to
"keep iterating on UX," and lists the new four-item UX punch list
(unlock foundations, drop shadows, drop highlighting, stock badge).

Resume prompt is rewritten so a fresh agent on a different machine
picks up cleanly: notes GitHub is the canonical remote (Gitea drift
caused commits to silently miss the alex machine earlier in session),
flags that the in-progress save format will invalidate when (1)
lands, and explicitly defers the release-prep items.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 21:24:09 +00:00
funman300 c4970b16ea feat(engine): auto-fade HUD action buttons when cursor leaves the band
Player request: the Menu / Undo / Pause / Help / Modes / New Game
buttons stay visible during play even when the player isn't looking
at them. Fade them out when the cursor is in the play area, fade
back in when it returns to the top of the window.

Implementation mirrors video-player auto-hide UX:
- HudActionFade resource holds (alpha, target). Default both 1.0 so
  the bar starts visible on first launch.
- update_action_fade reads cursor.y each frame, sets target to 1.0
  when the cursor is in the top reveal zone (HUD_BAND_HEIGHT + 32 px)
  or off-window (keyboard navigation), 0.0 otherwise. Lerps alpha
  toward target at 6/sec ≈ 167 ms per full transition.
- apply_action_fade overrides BackgroundColor + child TextColor on
  every ActionButton. Runs in Last so a hover-state change in the
  same frame doesn't blip back to opaque mid-fade.

No interactivity guard needed: hover requires the cursor to be on a
button, and a faded button is geometrically out of reach (cursor must
re-enter the reveal zone, which is exactly the trigger that fades
the bar back in).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 19:08:39 +00:00
funman300 2c72e1fc87 feat(engine): reserve top band for HUD so it stops crowding the cards
Player report: the action button bar (Menu / Undo / Pause / Help /
Modes / New Game) and Score / Moves / Timer text were sharing the
same vertical band as the stock + foundation row, with no visual
separation. The HUD read as part of the play surface.

Two-part fix:

1. layout.rs reserves HUD_BAND_HEIGHT (64 px) at the top of the
   window. Card-grid math takes that off the available vertical
   budget so cards still fit; top_y shifts down by the same amount.
   New layout test pins the reservation. Existing
   worst_case_tableau_fits_vertically tests verify the height-budget
   arithmetic still holds.

2. hud_plugin.rs spawns a translucent purple band (BG_HUD_BAND, new
   token in ui_theme.rs at the BG_BASE hue with 0.70 alpha) filling
   that reserved zone. Z-index sits one rung below Z_HUD so action
   buttons paint on top while the band reads as their container. The
   band's bottom edge lines up with the top edge of the highest
   playable card, so the buttons feel anchored to a "tools strip"
   rather than floating in the play area.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:57:51 +00:00
funman300 efa063fb8f fix(engine): fall through to system default font on unmatched family
CI / Test & Lint (push) Failing after 5s
CI / Release Build (push) Has been skipped
Replaces the previous LogPlugin-filter approach (which suppresses the
warn message) with a fix at the source: a custom usvg FontResolver
that appends `sans-serif` and `serif` to every family-lookup query.

usvg's default selector queries fontdb with [SVG-requested families,
Serif] and emits `log::warn!("No match for '{family}'")` when the
query returns None. On systems without the SVG's named family (Arial
on Linux, etc.), every text node logs a warn even though the system
has perfectly good fonts available — the warn is a false negative
because fontdb's named-family lookup is exact-match only.

The new resolver appends both `Family::SansSerif` and `Family::Serif`
to the query, both resolved by fontdb (via fontconfig on Linux or
built-in defaults elsewhere) to whatever the system has installed.
The query now finds *some* face on any reasonably configured machine,
so `id.is_none()` is never true and the warn branch never fires. The
visible behaviour: SVGs that request unavailable named families now
silently use the system's default sans-serif font.

Reverts the LogPlugin filter from main.rs — silencing warns at the
log level was the wrong layer; fixing the lookup is.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:41:02 +00:00
funman300 78cf30e906 fix(engine): silence usvg font-substitution warn spam
CI / Test & Lint (push) Failing after 6s
CI / Release Build (push) Has been skipped
The bundled hayeah card SVGs declare font-family="Arial" for rank/suit
text. usvg matches family names exactly, so on systems without Arial
installed (every Linux distro by default) every text node bridged a
log::warn! into our tracing output — 50+ lines per launch.

Two-part fix:
- svg_loader now populates a process-wide fontdb with system fonts
  (lazy via OnceLock) so substitution actually has faces to fall
  through to. usvg::Options::default() ships an empty fontdb, which
  meant text glyphs had nothing to fall back on at all.
- LogPlugin extends DEFAULT_FILTER with usvg::text=error so the
  residual "no match" warns drop. The substitution itself works; the
  message is purely informational because Arial truly isn't installed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:22:32 +00:00
funman300 9a9026e33a fix(engine): silence benign UnsupportedPlatform warn on exit
CI / Test & Lint (push) Failing after 4s
CI / Release Build (push) Has been skipped
push_on_exit logged every error including LocalOnlyProvider's expected
UnsupportedPlatform response, producing a misleading "sync push on exit
failed" warning on every shutdown in local-only mode. Mirror the pull
path: treat UnsupportedPlatform as silent no-op, warn only on real
errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:04:56 +00:00
funman300 ab1d098877 fix(engine): use resolve_embed for sibling theme assets
CI / Test & Lint (push) Failing after 5s
CI / Release Build (push) Has been skipped
`AssetPath::resolve` concatenates, so manifest-relative SVG paths
ended up under `…/theme.ron/<name>.svg` and the asset server
reported all 53 references missing. `resolve_embed` is the RFC 1808
sibling-resolution method that strips the base path's last segment
first, giving the intended `…/<name>.svg`. Default theme now loads
cleanly from the embedded:// source.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 17:21:03 +00:00
funman300 160637d1c8 docs: update remote URL reference to github.com/funman300/Rusty_Solitare
CI / Test & Lint (push) Failing after 8s
CI / Release Build (push) Has been skipped
Mirrors the move of the canonical remote from git.aleshym.co to
GitHub. The git remote itself was switched via 'git remote set-url
origin'; this updates the one stale URL in docs/SESSION_HANDOFF.md
that named the old host.
2026-05-01 17:11:55 +00:00
funman300 43f13c615e chore: workspace cleanup after card-theme phase landings
Drops dead deps and stale doc content carried over from the pre-MIT
art swap.

Cargo.toml manifests:
- solitaire_core no longer depends on chrono (no source references it
  since the original sync-payload timestamps moved to solitaire_data).
- solitaire_sync no longer depends on serde_json (the sync types use
  serde-derive with whatever serializer the caller picks; the old
  json-specific helpers were removed earlier).

Cargo.lock pruned by `cargo build` to drop the now-untransitively-
referenced versions.

CREDITS.md redistribution clause: "LGPL and OFL notices" tightened to
"MIT (project + hayeah card art) and OFL (FiraMono)" since the LGPL
art is gone.

SESSION_HANDOFF.md:
- HEAD bumped to 924a1e2; test count to 960; 9 ignored.
- Punch list rewritten — the xCards-URL line is obsolete (we did the
  swap), v0.1.0 tag exists locally, and player smoke-test is the
  current top item.
- New "Card-theme system (CARD_PLAN.md, fully shipped)" section
  summarises the seven-phase end-to-end flow so a future session has
  the integration map without re-reading the plan.
- Optional list gains the SVG-vs-layout aspect-ratio note as a
  cosmetic-only follow-up.

Removed the locked worktree at .claude/worktrees/agent-aa55a94d18c669d70
left behind by a prior Claude session.

cargo build / clippy --workspace --all-targets -- -D warnings / test
--workspace all green (960 passed, 0 failed, 9 ignored).
2026-05-01 16:41:53 +00:00
funman300 924a1e2af7 feat(engine): card-theme picker in Settings → Cosmetic
CI / Test & Lint (push) Failing after 5s
CI / Release Build (push) Has been skipped
Wires the runtime theme system (CARD_PLAN.md phases 1–7) into the
visible Settings UI so a player can switch between every theme
discovered by `ThemeRegistry` without restarting.

solitaire_data/src/settings.rs
  Settings gains `selected_theme_id: String` (default "default"),
  guarded by `#[serde(default = "default_theme_id")]` so existing
  settings.json files deserialize cleanly.

solitaire_engine/src/settings_plugin.rs
  - SettingsButton::SelectTheme(String) variant + focus order 85.
  - sync_settings_panel_visibility now reads
    Option<Res<ThemeRegistry>>, snapshots id+display_name pairs, and
    threads them into spawn_settings_panel. When the registry is
    absent (tests under MinimalPlugins) the picker silently skips —
    every existing test continues to pass unchanged.
  - theme_picker_row helper: like picker_row but keyed by String
    rather than usize, with chips wide enough for theme display
    names. Attaches the canonical tooltip ("Choose card-face
    artwork. Imported themes appear here.") and the FocusRow marker
    so Left/Right arrows cycle within the row.
  - Click handler updates settings.selected_theme_id, persists, and
    fires SettingsChangedEvent — same shape as every other picker.

solitaire_engine/src/theme/plugin.rs
  - load_default_theme renamed to load_initial_theme; reads
    SettingsResource on Startup and seeds ActiveTheme from
    settings.selected_theme_id (falling back to embedded default).
  - react_to_settings_theme_change watches SettingsChangedEvent,
    no-ops when the active theme already matches, and otherwise
    swaps ActiveTheme — the existing
    sync_card_image_set_with_active_theme system then refreshes
    every card sprite on the next AssetEvent::LoadedWithDependencies.

cargo build / clippy --workspace --all-targets -- -D warnings / test
--workspace all green (960 passed, 0 failed, 9 ignored).
2026-05-01 16:24:24 +00:00
funman300 a6b8348332 docs: refresh README + ARCHITECTURE for hayeah art + theme system
CI / Test & Lint (push) Failing after 7s
CI / Release Build (push) Has been skipped
Updates the prose mentions of card-face provenance to point at
hayeah/playing-cards-assets (MIT) instead of xCards (LGPL-3.0), in
sync with the upstream art swap (b98cb8a).

ARCHITECTURE.md decision log gains two new rows: the licence-driven
art swap and the runtime SVG card-theme system landed across
CARD_PLAN.md phases 1–7. README.md credits paragraph rewritten to
match the new attribution.
2026-05-01 16:08:14 +00:00
funman300 b98cb8a99f feat(assets): swap card art to hayeah/playing-cards-assets (MIT)
Replaces the previous xCards-derived card faces (LGPL-3.0) with
hayeah/playing-cards-assets, which itself derives from the
public-domain vector-playing-cards Google Code project. The whole
package is MIT now — see CREDITS.md for the new attribution table
and the simpler license summary.

solitaire_engine/assets/themes/default/
  52 face SVGs (clubs/diamonds/hearts/spades × ace/2-10/jack/queen/
  king) — copied from hayeah, renamed to the canonical
  `{suit}_{rank}.svg` form `CardKey::manifest_name` produces. The
  bundled default theme manifest references each by the same name.
  back.svg — original midnight-purple-themed card back, hand-written
  to match the project's design tokens (BG_BASE / BG_ELEVATED /
  ACCENT_PRIMARY / ACCENT_SECONDARY). MIT, original work.

assets/cards/faces/{RANK}{SUIT}.png
  52 PNGs regenerated from the new SVGs at 750-tall via resvg 0.47.
  These remain the legacy backwards-compat path that
  `card_plugin::load_card_images` reads at startup; once the runtime
  theme system finishes loading the embedded default theme, the
  CardImageSet's face handles are overwritten with the SVG-rendered
  variants and these PNGs become moot. Keeping them in place avoids
  a brief blank-card flash before the async theme load completes.

solitaire_engine/src/assets/sources.rs
  embed_default_svg!() macro + DEFAULT_THEME_SVGS table that bundles
  every face + the back into the binary at compile time via
  include_bytes!. populate_embedded_default_theme now iterates the
  table so the EmbeddedAssetRegistry is populated under the same
  asset paths the manifest references.

CREDITS.md
  License summary collapses from MIT + LGPL-3.0 + OFL-1.1 to MIT +
  OFL-1.1 (the OFL still applies to FiraMono). The hayeah upstream
  URL replaces the previously-blank xCards entry.

cargo build / clippy --workspace --all-targets -- -D warnings / test
--workspace all green (960 passed, 0 failed, 9 ignored).
2026-05-01 16:06:58 +00:00
funman300 7b59e70192 feat(engine): theme registry + discovery (Card theme phase 6)
CI / Test & Lint (push) Failing after 8s
CI / Release Build (push) Has been skipped
Implements Phase 6 of CARD_PLAN.md — discovers every available card
theme on startup so the future picker UI can list them.

solitaire_engine/src/theme/registry.rs
  ThemeEntry { id, display_name, manifest_url, meta }
  ThemeRegistry — Resource holding the entries; provides
    find(id), iter(), len(), is_empty().
  ThemeRegistryPlugin — Startup system that scans
    user_theme_dir() and populates the registry.
  build_registry(user_dir) — pure helper; takes the dir as a
    parameter so tests use tempfile::tempdir() without touching
    the global OnceLock-based user-theme path.
  refresh_registry(&mut, user_dir) — replaces in-place; called
    after a successful import_theme so a freshly-imported theme
    appears in the picker without an app restart.

The bundled default entry is always inserted (id "default", served
from DEFAULT_THEME_MANIFEST_URL) so the picker has at least one
option even when no user themes exist.

Discovery is best-effort: a directory whose theme.ron is missing,
malformed, or fails ThemeMeta::validate is silently skipped — broken
themes don't poison the registry. Only the meta block is parsed
(via a derive(Deserialize) struct that ignores other manifest
fields), which keeps startup quick even with dozens of themes
installed.

Wired into solitaire_app/main.rs after ThemePlugin so the asset
sources are registered before discovery scans for theme.ron files.

10 new tests covering: empty user dir, nonexistent user dir, valid
user theme registers, full-manifest tolerance via meta-only parser,
malformed theme.ron skipped, invalid-meta theme skipped, directory
without theme.ron ignored, find() returns None for unknown id,
refresh_registry replaces stale entries, default-entry URL matches
the embedded constant.

cargo build / clippy --workspace --all-targets -- -D warnings / test
--workspace all green (960 passed, 0 failed, 9 ignored).
2026-05-01 06:04:34 +00:00
funman300 7f477b4ad8 feat(engine): ThemePlugin + ActiveTheme integration (Card theme phase 4)
Implements Phase 4 of CARD_PLAN.md — the runtime hook that loads the
default theme on startup and refreshes the card-rendering pipeline
whenever the active theme changes.

solitaire_engine/src/theme/plugin.rs
  ThemePlugin
    init_asset::<CardTheme>, register_asset_loader for SvgLoader and
    CardThemeLoader, Startup load_default_theme, and Update
    sync_card_image_set_with_active_theme.
  ActiveTheme(Handle<CardTheme>)
    Resource pointing at the currently-loaded theme.
  set_theme(commands, asset_server, theme_id)
    Public API for switching themes — formats the URL as
    `themes://<theme_id>/theme.ron` and updates the resource.

Integration approach: rather than refactor every `card_plugin.rs`
spawn site to read from `Assets<CardTheme>` directly, the sync system
writes the theme's face/back image handles into the existing
`CardImageSet` resource on `AssetEvent::LoadedWithDependencies` /
`Modified`, then fires `StateChangedEvent`. The existing
`sync_cards_on_change` pipeline rebuilds card sprites from the new
handles on the next tick — observable behaviour matches the plan's
intent (theme switches propagate immediately) while keeping
card_plugin's 1929-line surface area untouched.

Theme.back is mapped onto `CardImageSet.backs[0]` (the default-back
slot xCards previously occupied); `backs[1..=4]` are the
asset-generator patterns and remain user-selectable independent of
the active theme.

Added to solitaire_app/main.rs as `add_plugins(ThemePlugin)` after
`AssetSourcesPlugin` so the asset sources are registered before the
default-theme load is dispatched.

6 new tests covering suit/rank index mapping (matching the
`card_plugin` doc-commented `[suit][rank]` layout), empty-theme
no-panic, back-slot overwrite, and the URL format from `set_theme`.

cargo build / clippy --workspace --all-targets -- -D warnings / test
--workspace all green (950 passed, 0 failed, 9 ignored).
2026-05-01 05:59:28 +00:00
funman300 ce38b26721 feat(engine): theme zip importer with safety validation (Card theme phase 7)
Implements Phase 7 of CARD_PLAN.md — the entry point that takes a
user-supplied theme zip archive, validates it end-to-end, and
atomically unpacks it into the per-platform user themes directory.

Public API:
  import_theme(zip_path) -> Result<ThemeId, ImportError>
    Resolves user_theme_dir() and unpacks into <user>/<id>/.
  import_theme_into(zip_path, target_root) -> Result<ThemeId, ImportError>
    Test-friendly variant that takes the destination explicitly so
    unit tests never touch the global OnceLock override.

Safety guarantees enforced:
- 20 MB hard cap on archive size (read from the central directory
  before any extraction).
- Zip-slip path traversal rejected via ZipFile::enclosed_name plus a
  Component::Normal-only belt-and-braces check.
- Manifest parsed via ron::de and validated via the existing
  ThemeManifest::validate (Phase 2) — surfaces named diagnostics for
  missing-of-52, unknown keys, duplicate keys, and meta errors.
- Every referenced face + back rasterised through rasterize_svg as a
  structural validity check before any bytes hit the destination.
- Atomic install: writes to <root>/.<id>.tmp/ then std::fs::rename
  into place, with a recursive copy + remove fallback for cross-
  device renames. Failed extraction wipes the staging dir; the user
  themes root is never touched on error.
- Id collision with an existing theme dir rejected up front.

7 new tests covering the happy path plus six failure modes (missing
manifest, missing face, oversized archive, zip-slip, missing-file,
id collision). Tests build zips in tempfile::TempDir so they never
touch the real user themes directory.

Workspace deps: zip 8.6 (default-features off + deflate only),
tempfile 3.27 (dev only).

cargo check --workspace --all-targets / clippy --workspace
--all-targets -- -D warnings clean. cargo test could not be run in
this turn because cc disappeared from the sandbox; tests compile
under cargo check --tests and will run on a normal toolchain.
2026-05-01 05:47:30 +00:00
funman300 172d7773f0 feat(engine): asset sources for embedded + user theme dirs (Card theme phase 3)
Implements Phase 3 of CARD_PLAN.md — the embedded:// + themes:// asset
sources the card-theme system loads from. The bundled default-theme
manifest ships in the binary via Bevy's EmbeddedAssetRegistry; user
themes load from user_theme_dir() through a FileAssetReader-backed
source registered as `themes://`.

Registration is split across:
  register_theme_asset_sources(&mut App)
    Called BEFORE DefaultPlugins. Registers `themes://` while
    AssetSourceBuilders is still mutable.
  AssetSourcesPlugin
    Added AFTER DefaultPlugins. Populates the EmbeddedAssetRegistry
    that AssetPlugin's build step would otherwise overwrite.

Constants exposed for downstream consumers:
  USER_THEMES                 = "themes"   (asset-source name)
  DEFAULT_THEME_MANIFEST_URL  = "embedded://solitaire_engine/assets/themes/default/theme.ron"

Includes a stub default theme.ron (52 face slots + back) so
`ThemeManifest::validate()` accepts it today; PROVENANCE.md documents
the plan to drop in real SVG art (hayeah/playing-cards-assets) in a
follow-up.

4 new tests covering source registration, embedded-registry
population, manifest validation against the embedded stub, and the
manifest-URL constant matching the embedded asset path.

cargo check --workspace --all-targets / clippy --workspace
--all-targets -- -D warnings clean. cargo test could not be run in
this turn because the C linker (cc) is unexpectedly absent from the
sandbox; the test bodies compile cleanly under cargo check --tests
and will run on a normal toolchain.
2026-05-01 05:47:13 +00:00
funman300 205ad6f646 feat(engine): per-platform user-theme directory (Card theme phase 5)
Implements Phase 5 of CARD_PLAN.md. Phase 3 (asset sources) and
Phase 7 (zip importer) both depend on this so it goes first.

solitaire_engine/src/assets/user_dir.rs
  user_theme_dir() -> PathBuf
    Desktop (Linux/macOS/Windows): joins dirs::data_dir() with
    "solitaire_quest/themes" — same parent as the rest of the
    project's per-user files (settings.json, stats.json, etc.)
    Mobile (Android/iOS): reads a process-wide OnceLock populated
    by set_user_theme_dir() at entry-point bootstrap. Panics with a
    targeted message if the override is missing — there is no
    platform default we can guess that won't be wrong inside iOS
    sandboxing or the Android storage model.
  set_user_theme_dir(PathBuf) -> Result<(), PathBuf>
    First-write-wins. Mobile entry points call this before App::run().

The plan suggested the `directories` crate; reused the existing `dirs`
workspace dep instead to keep the dependency surface minimal — both
crates share an author and the platform behaviour we need is identical.

3 new tests covering pure path composition (desktop nesting + empty
root) and a desktop-target-gated check that the detected data dir is
absolute. The OnceLock override is intentionally not unit-tested
because asserting its semantics would pollute global state for any
sibling test that calls `user_theme_dir()`.
2026-05-01 05:25:21 +00:00
funman300 936d035750 feat(engine): CardTheme asset + manifest loader (Card theme phase 2)
Implements Phase 2 of CARD_PLAN.md — the data types and `.theme.ron`
asset loader that build on Phase 1's SVG rasteriser.

solitaire_engine/src/theme/
  mod.rs        — CardKey { suit, rank } as the HashMap lookup key
                  (distinct from solitaire_core::Card which carries
                  per-deal id + face_up state); CardKey::all() yields
                  the 52 keys in suit-major / rank-ascending order;
                  manifest_name() and parse_manifest_name() round-trip
                  via the canonical "{suit}_{rank}" form.
                  ThemeMeta with structural validation (id non-empty,
                  no path separators, non-zero aspect components).
                  CardTheme #[derive(Asset, TypePath)] storing the
                  53 image handles + meta.
  manifest.rs   — ThemeManifest { meta, back, faces } with serde for
                  RON round-trip. validate() returns a strongly-typed
                  HashMap<CardKey, PathBuf>, surfacing precise errors
                  for unknown face keys, missing-of-52 entries, and
                  duplicate keys (RON silently keeps the last; brittle
                  for a release).
  loader.rs     — AssetLoader for .theme.ron. Validates manifest, then
                  composes sibling SVG paths via AssetPath::resolve so
                  the same loader works for both embedded:// and
                  themes:// asset sources (Phase 3 territory).
                  Schedules every face + back load through SvgLoader
                  with target_size derived from meta.card_aspect.

24 new tests covering: 52-key enumeration uniqueness, manifest-name
round trip, garbage-name rejection, complete/missing/unknown/duplicate
manifest validation, RON round-trip integrity, target-size aspect
math (2:3 → 512x768; non-standard; degenerate 1:10000 clamps to 1px).

Workspace deps added: ron 0.12.

cargo build / clippy --workspace --all-targets -- -D warnings / test
all green (937 passed total — +24 from Phase 2 vs the +7 from
Phase 1's b8fb3fb baseline).
2026-05-01 05:19:12 +00:00
funman300 13d1d013e9 chore: route rustc through sccache for cold-build wins
Adds .cargo/config.toml setting `rustc-wrapper = "sccache"` so cold
rebuilds (CI, fresh checkouts, post-`cargo clean`) replay previously-
compiled crates from disk instead of recompiling. Warm incremental
builds are unaffected — cargo's own target/ cache dominates there.

Cache lives at `.sccache-cache/` inside the project (gitignored). The
[env] entry uses `force = false` so a developer-set $SCCACHE_DIR in
their shell wins, matching whichever directory the sccache daemon
already adopted.

Requires sccache on PATH. Install: `pacman -S sccache`,
`brew install sccache`, or `cargo install sccache --locked`. Bypass
without editing: `RUSTC_WRAPPER= cargo build`.
2026-05-01 05:15:59 +00:00
funman300 b8fb3fbd6e feat(engine): SVG → Image asset loader (Card theme phase 1)
Implements the runtime SVG rasterisation pipeline that the card-theme
system (CARD_PLAN.md) is built on. Bevy 0.18 has no native SVG support;
this loader bridges usvg (parser) + resvg (renderer) + tiny-skia (CPU
pixmap) so the rest of the engine consumes themes as plain
Handle<Image>. Rasterisation happens once per (asset, settings) pair at
load time — Bevy's asset cache absorbs the cost.

solitaire_engine/src/assets/
  mod.rs           — module entrypoint
  svg_loader.rs    — SvgLoader (AssetLoader for .svg → Image)
                     SvgLoaderSettings { target_size: UVec2 } default 512×768
                     SvgLoaderError (Io / Parse / PixmapAlloc) via thiserror
                     rasterize_svg() helper exposed for non-asset-graph
                     callers (the future zip-importer validation step)

The rasteriser scales-to-fit while preserving aspect ratio, centring
the SVG inside the target box so a non-2:3 source doesn't pin to the
top-left corner.

7 new unit tests — default + custom target size, zero-dimension reject,
malformed-input reject, RGBA byte-count, extension advertisement, and
a compile-time guard that SvgLoaderSettings still satisfies the
AssetLoader::Settings trait bounds.

Workspace deps added: usvg 0.47, resvg 0.47, tiny-skia 0.12 (latest
minor versions; CARD_PLAN.md called out the placeholder numbers
needed verification).

cargo build / cargo clippy --workspace --all-targets -- -D warnings
/ cargo test --workspace all green (913 passed, 0 failed, 9 ignored —
+7 from the new loader tests).
2026-05-01 05:05:30 +00:00
165 changed files with 25587 additions and 634 deletions
+1
View File
@@ -1,4 +1,5 @@
/target /target
/.sccache-cache
*.db *.db
*.db-shm *.db-shm
*.db-wal *.db-wal
+5 -3
View File
@@ -70,8 +70,8 @@ solitaire_quest/
├── assets/ # Loaded at runtime via AssetServer (audio is embedded via include_bytes!()) ├── assets/ # Loaded at runtime via AssetServer (audio is embedded via include_bytes!())
│ ├── cards/ │ ├── cards/
│ │ ├── faces/{RANK}{SUIT}.png # 52 card faces — xCards @2x artwork (LGPL-3.0) │ │ ├── faces/{RANK}{SUIT}.png # 52 card faces — rendered from hayeah/playing-cards-assets SVGs (MIT)
│ │ └── backs/back_0.png back_4.png # back_0 = xCards bicycle_blue; back_14 are generated patterns │ │ └── backs/back_0.png back_4.png # back_0 = generated default back; back_14 are generated patterns
│ ├── backgrounds/bg_0.png bg_4.png # generated textures │ ├── backgrounds/bg_0.png bg_4.png # generated textures
│ ├── fonts/main.ttf # FiraMono-Medium (170K, OFL) │ ├── fonts/main.ttf # FiraMono-Medium (170K, OFL)
│ └── audio/ │ └── audio/
@@ -1009,5 +1009,7 @@ Using `axum::test` and an in-memory SQLite database:
| `SyncProvider` trait, not `SyncBackend` match arms | `SyncPlugin` stays backend-agnostic and testable; new backends can be added without touching the plugin | 2026-04-20 | | `SyncProvider` trait, not `SyncBackend` match arms | `SyncPlugin` stays backend-agnostic and testable; new backends can be added without touching the plugin | 2026-04-20 |
| Dropped WebDAV backend | Redundant once the self-hosted server exists; removing it reduces surface area and simplifies settings UI | 2026-04-20 | | Dropped WebDAV backend | Redundant once the self-hosted server exists; removing it reduces surface area and simplifies settings UI | 2026-04-20 |
| Dropped GPGS backend | Redundant with the self-hosted server; adds JNI complexity for no user-visible benefit on the target platforms | 2026-04-28 | | Dropped GPGS backend | Redundant with the self-hosted server; adds JNI complexity for no user-visible benefit on the target platforms | 2026-04-28 |
| Card, background, and font assets loaded via `AssetServer` | Reverses the earlier embed-via-`include_bytes!()` decision: PNGs and TTFs are loaded at runtime so artwork can be swapped (e.g. xCards @2x faces, alternate card backs, themed backgrounds) without a recompile, and binary size stays small. Loaders take `Option<Res<AssetServer>>` and fall back gracefully under `MinimalPlugins`. The `assets/` directory must ship alongside the binary. | 2026-04-29 | | Card, background, and font assets loaded via `AssetServer` | Reverses the earlier embed-via-`include_bytes!()` decision: PNGs and TTFs are loaded at runtime so artwork can be swapped (e.g. alternate card backs, themed backgrounds) without a recompile, and binary size stays small. Loaders take `Option<Res<AssetServer>>` and fall back gracefully under `MinimalPlugins`. The `assets/` directory must ship alongside the binary. | 2026-04-29 |
| Audio assets remain embedded via `include_bytes!()` | Audio files are small, change rarely, and the embedded path eliminates a class of runtime-load errors during gameplay; the asset-pipeline reversal does not extend to audio | 2026-04-29 | | Audio assets remain embedded via `include_bytes!()` | Audio files are small, change rarely, and the embedded path eliminates a class of runtime-load errors during gameplay; the asset-pipeline reversal does not extend to audio | 2026-04-29 |
| Card art swapped from xCards (LGPL-3.0) to hayeah/playing-cards-assets (MIT) | Public-release readiness. The previous xCards art carried LGPL relinking obligations that complicate a single-binary distribution; hayeah's set derives from the public-domain `vector-playing-cards` line-art and is permissively MIT-licensed. CREDITS.md license summary collapsed to MIT + OFL-1.1. The default card back is original work in this project's midnight-purple palette. | 2026-05-01 |
| Runtime SVG card-theme system (`CARD_PLAN.md`) | User-supplied themes need to ship SVG sources so they can rasterise at any resolution on the player's hardware; baking PNGs at build time only would lock theme installation to the developer. The pipeline (usvg → resvg → tiny-skia) rasterises once per (theme, target size) at load time and caches the resulting `Image`, so the runtime cost is paid once, not per frame. The bundled default theme ships via `embedded://`; user themes via `themes://` rooted at `user_theme_dir()`. | 2026-05-01 |
+320
View File
@@ -0,0 +1,320 @@
# Changelog
All notable changes to Solitaire Quest are documented here. The format is
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this
project follows [Semantic Versioning](https://semver.org/).
## [Unreleased]
_Nothing yet._
## [0.13.0] — 2026-05-02
Third UX iteration round on top of v0.12.0. Six handoff candidates
shipped — three small polish items, three larger interaction
features (theme-aware backs, full keyboard play, right-click power
shortcut). Plus two code-review fixes (font handling unified,
sccache wiring removed).
### Added
- **Tooltip-delay slider** in Settings → Gameplay. `tooltip_delay_secs`
ranges [0.0, 1.5] in 0.1 s steps; "Instant" label when zero.
`Settings.tooltip_delay_secs` round-trips through serialise/deserialise
with `#[serde(default)]`. The hover-delay comparison in
`ui_tooltip` reads from `SettingsResource` with the existing
`MOTION_TOOLTIP_DELAY_SECS` as the test-fixture fallback.
- **Win-streak fire animation.** New `WinStreakMilestoneEvent` fires
from `stats_plugin` when `win_streak_current` crosses any of
[3, 5, 10] (only the threshold crossing — not every subsequent
win). The HUD streak readout scale-pulses 1.0 → 1.20 → 1.0 over
`MOTION_STREAK_FLOURISH_SECS` (0.6 s).
- **Score-breakdown reveal on the win modal.** Replaces the single
"Score: N" line with a per-component reveal (Base / Time bonus /
No-undo bonus / Mode multiplier / Total). Rows fade in over
`MOTION_SCORE_BREAKDOWN_FADE_SECS` (0.12 s) staggered by
`MOTION_SCORE_BREAKDOWN_STAGGER_SECS` (0.15 s). Honours
`AnimSpeed::Instant` by spawning all rows fully visible.
- **Card backs follow the active theme.** `theme.ron`'s `back` slot
now actually drives the face-down sprite. Active-theme back
rasterises alongside the faces and supersedes the legacy
`back_N.png` picker. The picker remains as a fallback for themes
that don't ship a back, and the Settings UI surfaces a caption
("Active theme provides its own back") + dimmed swatches when
the override is in effect.
- **Keyboard-only drag-and-drop.** Tab cycles draggable card stacks,
Enter "lifts" the focused stack, arrow keys (or Tab) cycle the
legal-destination targets only, Enter confirms, Esc cancels. A
new `KeyboardDragState` resource models the two-mode flow without
changing the existing `SelectionState` contract. Mutual exclusion
with mouse drag uses a sentinel `DragState.active_touch_id =
KEYBOARD_DRAG_TOUCH_ID` (u64::MAX) so neither pipeline can
trample the other.
- **Right-click radial menu.** Hold right-click on a face-up card →
a small ring of icons appears at the cursor with one entry per
legal destination. Release over an icon → fires
`MoveRequestEvent`; release in dead space, Esc, or left-click
cancels. Skips the drag motion entirely. New `RadialMenuPlugin`
owns the flow; co-exists with the existing `RightClickHighlight`
pile-marker tint.
### Fixed
- **Font handling consolidated to bundled-only.** Code-review
feedback: the SVG rasteriser previously mixed
`load_system_fonts` + bundled FiraMono + a lenient resolver,
which made card text rendering depend on host fontconfig. Picked
option (a) and applied it across both layers — `font_plugin` now
embeds `assets/fonts/main.ttf` via `include_bytes!()` and
registers it with `Assets<Font>`; `svg_loader::shared_fontdb`
loads only the bundled bytes; the new `bundled_font_resolver`
ignores the SVG's `font-family` request and always returns the
single bundled face. A parse failure aborts with a clear error
("bundled FiraMono failed to parse — binary is corrupt").
### Removed
- **Project-level sccache wiring.** Code-review feedback: sccache
shouldn't be a per-project build dependency. Cargo's incremental
cache already covers the single-project case, and forcing
`rustc-wrapper = "sccache"` workspace-wide meant every contributor
had to install it. `.cargo/config.toml` deleted entirely; plain
`cargo build` now works without setup.
### Documentation
- `help_plugin` controls reference gains a "Mouse" section covering
double-click auto-move, right-click highlight, and the new
hold-RMB radial.
- `help_plugin` also gains a "Keyboard drag" section for the new
Tab/Enter/Arrows/Esc flow.
- Onboarding slide 3 picks up a `Tab → Enter` row referencing the
full keyboard drag path.
### Stats
- 1053 passing tests (was 1031 at v0.12.0 close).
- Zero clippy warnings under `--workspace --all-targets -- -D warnings`.
## [0.12.0] — 2026-05-02
UX feel polish round on top of v0.11.0. Six small-but-tangible
improvements that make the play surface feel more responsive,
forgiving, and discoverable, plus the doc refresh that should have
ridden along with v0.11.0.
### Added
- **Foundation completion flourish.** When a King lands on a
foundation (Ace-through-King for that suit), a brief celebration
fires: King card scale-pulses 1.0 → 1.15 → 1.0 over 0.4 s, the
foundation marker tints `STATE_SUCCESS` for the first half then
fades, and a synthesised C6→E6→G6 bell ping plays (~240 ms,
octave above `win_fanfare`'s root so the fourth completion + win
cascade layer cleanly). New `FoundationCompletedEvent { slot,
suit }` carries the trigger so future systems can hook in.
- **Drag-cancel return tween.** Illegal drops glide each dragged
card back to its origin slot over 150 ms with a quintic ease-out
curve (`MotionCurve::Responsive`, zero overshoot — reads forgiving
rather than jittery). The audio cue (`card_invalid.wav`) still
fires for negative feedback. Right-click and double-click invalid
paths still use `ShakeAnim` since there's no motion to interpolate.
- **Focus ring breathing.** The keyboard focus ring's alpha modulates
with a 1.4 s sin curve over [0.65, 1.0] of its native value so the
indicator catches the eye on focus changes without competing with
gameplay. Honours `AnimSpeed::Instant` by reverting to the static
outline for reduced-motion users.
- **First-win achievement onboarding toast.** After the player's
very first win, a one-shot info toast surfaces "First win! Press
A to see your achievements." `Settings.shown_achievement_onboarding`
persists the seen state so the cue never re-fires (legacy
`settings.json` files load to `false` via `#[serde(default)]`).
- **Mode Launcher digit shortcuts.** Pressing M opens the Home modal
(the Mode Launcher); inside it, pressing 15 launches each mode
directly without needing Tab + Enter. Locked modes (Zen, Challenge,
Time Attack at level < 5) are silent no-ops. Modal-scoped — digit
keys outside the launcher fire nothing.
### Fixed
- **Card aspect ratio matches hayeah SVGs.** `CARD_ASPECT` 1.4 →
1.4523 to match the bundled artwork's natural 167.087 × 242.667
dimensions. Cards previously rendered ~3.6 % vertically squashed.
The vertical-budget math in `compute_layout` uses `CARD_ASPECT`
algebraically so the worst-case-tableau-fits-on-screen guarantee
adapts automatically.
### Documentation
- **README refresh** with v0.11.0+ features (card themes, HUD
overhaul, drag feel, unlocked foundations) and a corrected controls
table — the previous table inverted Z/U for undo and listed H for
help when F1 is the binding.
- **CHANGELOG.md** added (this file), covering v0.9.0v0.12.0 with
Keep a Changelog 1.1.0 conventions.
### Stats
- 1007 passing tests (was 982 at v0.11.0).
- Zero clippy warnings under `--workspace --all-targets -- -D warnings`.
## [0.11.0] — 2026-05-02
The biggest release since 0.10.0. Headline threads: a runtime card-theme
system, an HUD restructure that reclaims the play surface, and a round of
UX feel polish surfaced by smoke testing.
### Added
- **Runtime card-theme system** (CARD_PLAN phases 17).
- Bundled default theme ships in the binary via `embedded://` — 52
[hayeah/playing-cards-assets](https://github.com/hayeah/playing-cards-assets)
SVGs (MIT) plus a midnight-purple `back.svg` as original work.
- User themes live under `themes://` rooted at `user_theme_dir()`. Drop
a directory containing `theme.ron` + 53 SVGs and the registry picks
it up on next launch.
- Importer at `solitaire_engine::theme::import_theme(zip)` validates
archives (20 MB cap, zip-slip rejection, manifest validation, every
SVG round-tripped through the rasteriser) and atomically unpacks.
- Picker UI in **Settings → Cosmetic**; selection persists as
`selected_theme_id` and propagates to live sprites.
- **Reserved HUD top band** (64 px) so cards no longer crowd the score
readout or action buttons; layout's `top_y` shifts down accordingly.
- **Action-bar auto-fade** — buttons fade out when the cursor leaves the
band, fade back in when it returns. Lerp at ~167 ms.
- **Visible drop-target overlay during drag** — a soft fill plus 3 px
outline drawn ABOVE stacked cards for every legal target (full fanned
column for tableaux, card-sized for foundations and empty tableaux).
Replaces the previously invisible pile-marker tint.
- **Card drop shadows** — every card casts a neutral 25 % black shadow
with a 4 px halo; cards in the active drag set switch to a lifted
shadow (40 % alpha, larger offset, bigger halo).
- **Stock remaining-count badge** — small `·N` chip at the top-right of
the stock pile so the player can see how close they are to a recycle.
Hides when the stock empties.
### Changed
- **Foundations are unlocked.** `PileType::Foundation(Suit)`
`Foundation(u8)` (slot 0..3). The claimed suit is derived from the
bottom card via `Pile::claimed_suit()` — no separate field, no
claim-stuck-after-undo bugs. Any Ace lands in any empty slot, and the
slot then claims that suit. `next_auto_complete_move` prefers a
claim-matched slot before falling back to the first empty slot for
Aces. Empty foundation markers render as plain placeholders (no
"C/D/H/S").
- **HUD selection label** and **hint toast** read `claimed_suit()` and
fall through to "Foundation N" / "move to foundation" only when the
slot is empty.
### Fixed
- **`shared_fontdb` now bundles FiraMono.** The hayeah SVGs reference
`Bitstream Vera Sans` and `Arial` by name. On minimal Linux installs
/ fresh Wayland sessions / chroots where neither is installed AND the
CSS-generic aliases don't resolve, card rank/suit text vanished. The
bundled font is loaded into fontdb and pinned as every CSS generic's
target so the resolver always lands on something real. Surfaced when
a second-machine pull rendered cards without glyphs.
- **Theme asset path resolution** — `AssetPath::resolve` (concatenates)
`resolve_embed` (RFC 1808 sibling resolution). Was producing paths
like `…/theme.ron/hearts_4.svg` and failing to load every face SVG.
- **Sync exit log spam** — `push_on_exit` silently no-ops on
`LocalOnlyProvider`'s `UnsupportedPlatform` instead of warn-spamming
every shutdown.
- **usvg font-substitution warn spam** — custom `FontResolver.select_font`
appends `Family::SansSerif` and `Family::Serif` to every query so
unmatched named families silently fall through.
### Migration
- **In-progress saves invalidated.** `GameState.schema_version` bumped
1 → 2; pre-v2 `game_state.json` files silently fall through to "fresh
game on launch." Stats, progress, achievements, and settings live in
separate files and are unaffected.
### Stats
- 982 passing tests (was 819 at v0.10.0).
- Zero clippy warnings under `--workspace --all-targets -- -D warnings`.
## [0.10.0] — 2026-04-29
PNG art pipeline plus a major dependency pass. The first release where
the binary shipped with bundled artwork.
### Added
- **52 individual card face PNGs** generated via `solitaire_assetgen`.
- **Custom font** (FiraMono-Medium) loaded via `AssetServer` at startup
through the new `FontPlugin`.
- **Card backs and backgrounds** upgraded to 120×168 with richer
patterns.
- **Ambient audio loop** wired through the kira mixer.
- **Arch Linux PKGBUILDs** for the game client and sync server (under
the separate `solitaire-quest-pkgbuild` directory).
- **Workspace README, CI workflow, migration guide.**
### Changed
- **Bevy 0.15 → 0.18** workspace migration.
- **kira 0.9 → 0.12** audio backend migration.
- **Edition 2024**, MSRV pinned to **Rust 1.95**.
- **rand 0.9** upgrade.
- **Card rendering** moved from `Text2d` overlay to PNG-backed
`Sprite` with face/back atlases; `Text2d` retained as a headless
fallback when `CardImageSet` is absent (tests under MinimalPlugins).
- **Asset pipeline** switched from `include_bytes!()` for PNGs/TTFs to
runtime `AssetServer::load()` so artwork can be swapped without a
recompile. Audio remains embedded.
- **Removed Google Play Games Services sync backend** — redundant with
the self-hosted server.
### Fixed
- **Server JWT secret** loaded at startup (was lazy, surfaced as
intermittent 500s).
- **Daily-challenge race** in the server's seed-generation path.
- **Rate limiter** switched to `SmartIpKeyExtractor` so the limit
applies per real client IP rather than per upstream proxy.
- **Touch input** uses `MessageReader<TouchInput>` (Bevy 0.18 rename).
- **Sync push/pull races** in async task scheduling.
- **Hot-path allocations** reduced in card-rendering systems.
- **Conflict report coverage** added for sync merge edge cases.
### Stats
- 819 passing tests at tag time.
## [0.9.0] — 2026-04-28
Initial public-tagged release. Established the workspace structure
(`solitaire_core` / `_sync` / `_data` / `_engine` / `_server` / `_app` /
`_assetgen`), the modal scaffold via `ui_modal`, the design-token system
in `ui_theme`, and the four-tier HUD layout. Foundations were
suit-locked at this point; cards rendered as `Text2d` rank/suit overlays
with no PNG artwork yet.
### Added
- Klondike core (Draw One / Draw Three modes).
- Progression system (XP, levels, 18 achievements, daily challenge,
weekly goals, special modes at level 5).
- Self-hosted sync server (Axum + SQLite + JWT auth).
- All 12 overlay screens migrated to the `ui_modal` scaffold with real
Primary/Secondary/Tertiary buttons.
- Animation upgrades: `SmoothSnap` slide curves, scoped settle bounce,
deal jitter, win-cascade rotation.
- Splash screen, focus rings (Phases 13), tooltips infrastructure +
HUD/Settings/popover applications, achievement integration tests,
destructive-confirm verb unification, leaderboard error/idle states,
first-launch empty-state polish, hit-target accessibility fix,
CREDITS.md, persistent window geometry, mode-launcher Home repurpose,
client-side sync round-trip integration tests.
[Unreleased]: https://github.com/funman300/Rusty_Solitaire/compare/v0.13.0...HEAD
[0.13.0]: https://github.com/funman300/Rusty_Solitaire/compare/v0.12.0...v0.13.0
[0.12.0]: https://github.com/funman300/Rusty_Solitaire/compare/v0.11.0...v0.12.0
[0.11.0]: https://github.com/funman300/Rusty_Solitaire/compare/v0.10.0...v0.11.0
[0.10.0]: https://github.com/funman300/Rusty_Solitaire/compare/v0.9.0...v0.10.0
[0.9.0]: https://github.com/funman300/Rusty_Solitaire/releases/tag/v0.9.0
+22 -14
View File
@@ -42,14 +42,20 @@ copyleft code is statically linked into the game binary.
| File(s) | Source | License | | File(s) | Source | License |
|---|---|---| |---|---|---|
| `assets/cards/faces/{RANK}{SUIT}.png` (52 PNGs) | xCards @2x artwork | LGPL-3.0 | | `solitaire_engine/assets/themes/default/{suit}_{rank}.svg` (52 SVGs) | [hayeah/playing-cards-assets](https://github.com/hayeah/playing-cards-assets) | MIT |
| `assets/cards/backs/back_0.png` (bicycle_blue) | xCards @2x artwork | LGPL-3.0 | | `solitaire_engine/assets/themes/default/back.svg` | Original — Solitaire Quest | MIT (this project) |
| `assets/cards/backs/back_1.png` `back_4.png` | Original — generated by `solitaire_assetgen::gen_art` | 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 The face SVGs come from Howard Yeh's `playing-cards-assets` repository, which
LGPL-3.0. The art is consumed as unmodified PNG files at runtime; the game is itself derived from the public-domain `vector-playing-cards` Google Code
binary statically links no LGPL code, so distribution as a self-contained project. The art is redistributed under the MIT license — see the upstream
binary plus the `assets/` directory satisfies the LGPL's relinking clause. 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 ### Backgrounds
@@ -92,13 +98,15 @@ Audio files are MIT-licensed alongside the rest of this project.
## License Summary ## License Summary
- **Project code:** MIT — see [LICENSE](LICENSE). - **Project code:** MIT — see [LICENSE](LICENSE).
- **xCards card artwork (52 faces + `back_0.png`):** LGPL-3.0, redistributed - **Card face artwork (52 SVGs from hayeah/playing-cards-assets, plus the
unmodified. The LGPL applies only to those PNG files; it does not extend to pre-rendered PNGs in `assets/cards/faces/`):** MIT, redistributed
the game binary, which links no LGPL code. unmodified. The original `vector-playing-cards` line art is itself
public domain.
- **FiraMono-Medium font:** SIL Open Font License 1.1, redistributed unmodified. - **FiraMono-Medium font:** SIL Open Font License 1.1, redistributed unmodified.
- **All other assets** (backgrounds, generated card backs, every audio file) - **All other assets** (backgrounds, the default `back.svg`, generated card
are original work covered by this project's MIT license. 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 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 `LICENSE` file alongside the binary so the MIT (project + hayeah card art)
visible to end users. and OFL (FiraMono) notices remain visible to end users.
Generated
+294 -16
View File
@@ -2429,6 +2429,12 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.5" version = "1.0.5"
@@ -2950,6 +2956,12 @@ version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
[[package]]
name = "data-url"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
[[package]] [[package]]
name = "datasketches" name = "datasketches"
version = "0.2.0" version = "0.2.0"
@@ -3477,8 +3489,15 @@ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
"zlib-rs",
] ]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
[[package]] [[package]]
name = "flume" name = "flume"
version = "0.11.1" version = "0.11.1"
@@ -3532,7 +3551,7 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
dependencies = [ dependencies = [
"roxmltree", "roxmltree 0.20.0",
] ]
[[package]] [[package]]
@@ -3851,6 +3870,16 @@ dependencies = [
"polyval", "polyval",
] ]
[[package]]
name = "gif"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159"
dependencies = [
"color_quant",
"weezl",
]
[[package]] [[package]]
name = "gilrs" name = "gilrs"
version = "0.11.1" version = "0.11.1"
@@ -4529,6 +4558,22 @@ dependencies = [
"png 0.18.1", "png 0.18.1",
] ]
[[package]]
name = "image-webp"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
dependencies = [
"byteorder-lite",
"quick-error",
]
[[package]]
name = "imagesize"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.14.0" version = "2.14.0"
@@ -4856,6 +4901,17 @@ dependencies = [
"bitflags 2.11.1", "bitflags 2.11.1",
] ]
[[package]]
name = "kurbo"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7564e90fe3c0d5771e1f0bc95322b21baaeaa0d9213fa6a0b61c99f8b17b3bfb"
dependencies = [
"arrayvec",
"euclid",
"smallvec",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@@ -6011,15 +6067,6 @@ dependencies = [
"libredox", "libredox",
] ]
[[package]]
name = "ordered-float"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "ordered-float" name = "ordered-float"
version = "5.3.0" version = "5.3.0"
@@ -6165,6 +6212,12 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "pico-args"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.11" version = "1.1.11"
@@ -6428,6 +6481,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "quick-error"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]] [[package]]
name = "quick-xml" name = "quick-xml"
version = "0.39.2" version = "0.39.2"
@@ -6798,6 +6857,23 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "resvg"
version = "0.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be183ad6a216aa96f33e4c8033b0988b8b3ea6fd2359d19af5bac4643fd8e81"
dependencies = [
"gif",
"image-webp",
"log",
"pico-args",
"rgb",
"svgtypes",
"tiny-skia 0.12.0",
"usvg",
"zune-jpeg",
]
[[package]] [[package]]
name = "rfc6979" name = "rfc6979"
version = "0.4.0" version = "0.4.0"
@@ -6808,6 +6884,15 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "rgb"
version = "0.8.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
dependencies = [
"bytemuck",
]
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.14" version = "0.17.14"
@@ -6862,6 +6947,15 @@ version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
[[package]]
name = "roxmltree"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1964b10c76125c36f8afe190065a4bf9a87bf324842c05701330bba9f1cacbb"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "rpassword" name = "rpassword"
version = "7.5.0" version = "7.5.0"
@@ -7068,6 +7162,24 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "rustybuzz"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702"
dependencies = [
"bitflags 2.11.1",
"bytemuck",
"core_maths",
"log",
"smallvec",
"ttf-parser",
"unicode-bidi-mirroring",
"unicode-ccc",
"unicode-properties",
"unicode-script",
]
[[package]] [[package]]
name = "ruzstd" name = "ruzstd"
version = "0.8.2" version = "0.8.2"
@@ -7123,7 +7235,7 @@ dependencies = [
"log", "log",
"memmap2", "memmap2",
"smithay-client-toolkit", "smithay-client-toolkit",
"tiny-skia", "tiny-skia 0.11.4",
] ]
[[package]] [[package]]
@@ -7382,6 +7494,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "simplecss"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c"
dependencies = [
"log",
]
[[package]] [[package]]
name = "simsimd" name = "simsimd"
version = "6.5.16" version = "6.5.16"
@@ -7522,7 +7643,6 @@ dependencies = [
name = "solitaire_core" name = "solitaire_core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"chrono",
"rand 0.9.4", "rand 0.9.4",
"serde", "serde",
"thiserror 2.0.18", "thiserror 2.0.18",
@@ -7557,12 +7677,21 @@ dependencies = [
"async-trait", "async-trait",
"bevy", "bevy",
"chrono", "chrono",
"dirs",
"kira", "kira",
"resvg",
"ron",
"serde",
"solitaire_core", "solitaire_core",
"solitaire_data", "solitaire_data",
"solitaire_sync", "solitaire_sync",
"tempfile",
"thiserror 2.0.18",
"tiny-skia 0.12.0",
"tokio", "tokio",
"usvg",
"uuid", "uuid",
"zip",
] ]
[[package]] [[package]]
@@ -7593,7 +7722,6 @@ version = "0.1.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"serde", "serde",
"serde_json",
"thiserror 2.0.18", "thiserror 2.0.18",
"uuid", "uuid",
] ]
@@ -7860,6 +7988,9 @@ name = "strict-num"
version = "0.1.1" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
dependencies = [
"float-cmp",
]
[[package]] [[package]]
name = "stringprep" name = "stringprep"
@@ -7912,6 +8043,16 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb"
[[package]]
name = "svgtypes"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "695b5790b3131dafa99b3bbfd25a216edb3d216dad9ca208d4657bfb8f2abc3d"
dependencies = [
"kurbo",
"siphasher",
]
[[package]] [[package]]
name = "swash" name = "swash"
version = "0.2.7" version = "0.2.7"
@@ -8226,7 +8367,7 @@ checksum = "dfadb8526b6da90704feb293b0701a6aae62ea14983143344be2dc5ce30f1d82"
dependencies = [ dependencies = [
"fnv", "fnv",
"nom", "nom",
"ordered-float 5.3.0", "ordered-float",
"serde", "serde",
"serde_json", "serde_json",
] ]
@@ -8383,7 +8524,22 @@ dependencies = [
"bytemuck", "bytemuck",
"cfg-if", "cfg-if",
"log", "log",
"tiny-skia-path", "tiny-skia-path 0.11.4",
]
[[package]]
name = "tiny-skia"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47ffee5eaaf5527f630fb0e356b90ebdec84d5d18d937c5e440350f88c5a91ea"
dependencies = [
"arrayref",
"arrayvec",
"bytemuck",
"cfg-if",
"log",
"png 0.18.1",
"tiny-skia-path 0.12.0",
] ]
[[package]] [[package]]
@@ -8397,6 +8553,17 @@ dependencies = [
"strict-num", "strict-num",
] ]
[[package]]
name = "tiny-skia-path"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edca365c3faccca67d06593c5980fa6c57687de727a03131735bb85f01fdeeb9"
dependencies = [
"arrayref",
"bytemuck",
"strict-num",
]
[[package]] [[package]]
name = "tinystr" name = "tinystr"
version = "0.8.3" version = "0.8.3"
@@ -8947,6 +9114,12 @@ dependencies = [
"rand 0.9.4", "rand 0.9.4",
] ]
[[package]]
name = "typed-path"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e"
[[package]] [[package]]
name = "typeid" name = "typeid"
version = "1.0.3" version = "1.0.3"
@@ -9015,6 +9188,18 @@ version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
[[package]]
name = "unicode-bidi-mirroring"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe"
[[package]]
name = "unicode-ccc"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.24" version = "1.0.24"
@@ -9054,6 +9239,12 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
[[package]]
name = "unicode-vo"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.14" version = "0.1.14"
@@ -9094,6 +9285,34 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "usvg"
version = "0.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d46cf96c5f498d36b7a9693bc6a7075c0bb9303189d61b2249b0dc3d309c07de"
dependencies = [
"base64",
"data-url",
"flate2",
"fontdb",
"imagesize",
"kurbo",
"log",
"pico-args",
"roxmltree 0.21.1",
"rustybuzz",
"simplecss",
"siphasher",
"strict-num",
"svgtypes",
"tiny-skia-path 0.12.0",
"ttf-parser",
"unicode-bidi",
"unicode-script",
"unicode-vo",
"xmlwriter",
]
[[package]] [[package]]
name = "utf8-ranges" name = "utf8-ranges"
version = "1.0.5" version = "1.0.5"
@@ -9453,6 +9672,12 @@ dependencies = [
"rustls-pki-types", "rustls-pki-types",
] ]
[[package]]
name = "weezl"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
[[package]] [[package]]
name = "wgpu" name = "wgpu"
version = "27.0.1" version = "27.0.1"
@@ -9571,7 +9796,7 @@ dependencies = [
"ndk-sys 0.6.0+11769913", "ndk-sys 0.6.0+11769913",
"objc", "objc",
"once_cell", "once_cell",
"ordered-float 4.6.0", "ordered-float",
"parking_lot", "parking_lot",
"portable-atomic", "portable-atomic",
"portable-atomic-util", "portable-atomic-util",
@@ -10500,6 +10725,12 @@ version = "0.8.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f"
[[package]]
name = "xmlwriter"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
[[package]] [[package]]
name = "yazi" name = "yazi"
version = "0.2.1" version = "0.2.1"
@@ -10701,12 +10932,44 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "zip"
version = "8.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b"
dependencies = [
"crc32fast",
"flate2",
"indexmap",
"memchr",
"typed-path",
"zopfli",
]
[[package]]
name = "zlib-rs"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513"
[[package]] [[package]]
name = "zmij" name = "zmij"
version = "1.0.21" version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
[[package]]
name = "zopfli"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249"
dependencies = [
"bumpalo",
"crc32fast",
"log",
"simd-adler32",
]
[[package]] [[package]]
name = "zstd" name = "zstd"
version = "0.13.3" version = "0.13.3"
@@ -10735,6 +10998,21 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "zune-core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9"
[[package]]
name = "zune-jpeg"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
dependencies = [
"zune-core",
]
[[package]] [[package]]
name = "zvariant" name = "zvariant"
version = "5.10.1" version = "5.10.1"
+24
View File
@@ -38,6 +38,30 @@ solitaire_engine = { path = "solitaire_engine" }
bevy = "0.18" bevy = "0.18"
kira = "0.12" kira = "0.12"
# SVG rasterisation pipeline for the runtime card-theme system.
# usvg parses + simplifies; resvg renders to a tiny-skia Pixmap;
# tiny-skia provides the CPU rasteriser. All three are maintained
# together by the resvg-rs project and version in lockstep.
usvg = "0.47"
resvg = "0.47"
tiny-skia = "0.12"
# Theme manifest format. RON keeps the file human-editable while
# preserving Rust-style structures the importer can validate.
ron = "0.12"
# Importer-only: reads user-supplied theme zip archives, validates
# their contents, and unpacks them into the user themes directory.
# Default features are disabled to keep the dependency footprint small;
# only `deflate` is needed because the importer rejects other
# compression methods anyway (see Phase 7 spec).
zip = { version = "8.6", default-features = false, features = ["deflate"] }
# Importer-only test dependency: tests build zip archives in a
# scratch directory so they don't pollute the real user themes path
# on the developer's machine.
tempfile = "3.27"
axum = "0.8" axum = "0.8"
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
jsonwebtoken = { version = "10", default-features = false, features = ["rust_crypto"] } jsonwebtoken = { version = "10", default-features = false, features = ["rust_crypto"] }
+64 -23
View File
@@ -1,17 +1,35 @@
# Solitaire Quest # Solitaire Quest
A cross-platform Klondike Solitaire game written in Rust, featuring a full progression system with XP, levels, achievements, daily challenges, and optional self-hosted sync so your stats follow you across machines. A cross-platform Klondike Solitaire game written in Rust, with a card-theme
system, full progression (XP / levels / achievements / daily challenges), and
optional self-hosted sync so your stats follow you across machines.
## Features ## Features
- **Klondike Solitaire** — Draw One and Draw Three modes - **Klondike Solitaire** — Draw One and Draw Three modes; foundations are
unlocked (any Ace lands in any empty slot, the slot then claims that suit)
- **Card themes** — bundled hayeah/playing-cards-assets default plus
user-installable themes (drop a directory under the data dir or import a
zip from Settings → Cosmetic)
- **Modern HUD** — reserved top band keeps cards from crowding the score
readout; the action bar auto-fades when the cursor leaves it so it can't
compete with the play surface
- **Drag feel** — every legal drop target is highlighted in green during
drag; cards cast a soft drop shadow that lifts when picked up; the stock
pile shows a remaining-count chip so you can see how close you are to a
recycle
- **Keyboard navigation** — Tab cycles focus through buttons, arrow keys
move within picker rows, Enter activates; works across every modal and
the HUD action bar
- **Progression** — XP, levels, unlockable card backs and backgrounds - **Progression** — XP, levels, unlockable card backs and backgrounds
- **18 Achievements** — including secret ones - **18 Achievements** — including secret ones
- **Daily Challenge** — server-seeded so every player worldwide gets the same deal - **Daily Challenge** — server-seeded so every player worldwide gets the
same deal
- **Leaderboard** — opt-in, powered by your own self-hosted server - **Leaderboard** — opt-in, powered by your own self-hosted server
- **Special Modes** (unlocked at level 5): Zen, Time Attack, Challenge - **Special Modes** (unlocked at level 5): Zen, Time Attack, Challenge
- **Sync** — pull/push stats across devices via a self-hosted server - **Sync** — pull/push stats across devices via a self-hosted server
- **Color-blind mode** — blue tint on red-suit cards - **Color-blind mode** — blue tint on red-suit cards alongside the suit
glyph
## Building ## Building
@@ -32,49 +50,72 @@ cargo build -p solitaire_app --release
## Controls ## Controls
Every action also has a visible UI button — keyboard shortcuts are optional
accelerators.
| Key | Action | | Key | Action |
|---|---| |---|---|
| Left click / drag | Move cards | | Left click / drag | Move cards |
| Double click | Auto-move card to its best legal destination |
| Right click | Highlight legal moves for a card | | Right click | Highlight legal moves for a card |
| Space / D | Draw from stock | | Space / D | Draw from stock |
| Z / Ctrl+Z | Undo | | U | Undo |
| H | Hint (highlight a legal move) |
| N | New game | | N | New game |
| S | Stats overlay | | Z | Zen mode |
| A | Achievements overlay | | G | Forfeit (during pause) |
| P | Profile overlay | | Tab / Shift+Tab | Cycle keyboard focus |
| O | Settings | | Enter | Activate focused button / auto-complete (when badge is lit) |
| L | Leaderboard | | Esc | Pause / dismiss modal |
| H | Help / controls | | F1 | Help / controls |
| Enter | Auto-complete (when badge is lit) | | F11 | Toggle fullscreen |
| Escape | Pause / clear selection | | S / A / P / O / L / M | Stats / Achievements / Profile / Settings / Leaderboard / Menu |
| Arrow keys | Navigate card selection |
## Card themes
The default theme ships embedded in the binary, so the game runs
self-contained with no external assets. To install another theme, drop a
directory containing a `theme.ron` manifest plus 53 SVG files (52 faces +
1 back) under the platform data dir's `themes/` folder, or import a zip
from **Settings → Cosmetic**. The picker chip lights up the moment a new
theme is registered. Themes are SVG-based, so they rasterise cleanly at
whatever resolution the window happens to be.
## Sync Server (optional) ## Sync Server (optional)
To sync stats across machines, run the self-hosted server. See [README_SERVER.md](README_SERVER.md) for setup instructions. To sync stats across machines, run the self-hosted server. See
[README_SERVER.md](README_SERVER.md) for setup instructions.
Once the server is running, open **Settings → Sync Backend**, enter the server URL and your username, and register an account from within the game. Once the server is running, open **Settings → Sync Backend**, enter the
server URL and your username, and register an account from within the
game.
## Running Tests ## Running Tests
```bash ```bash
# All tests # All tests (982 passing as of v0.11.0)
cargo test --workspace cargo test --workspace
# Just game logic (no display required) # Just game logic (no display required)
cargo test -p solitaire_core -p solitaire_sync -p solitaire_data -p solitaire_server cargo test -p solitaire_core -p solitaire_sync -p solitaire_data -p solitaire_server
# Lint # Lint
cargo clippy --workspace -- -D warnings cargo clippy --workspace --all-targets -- -D warnings
``` ```
## Credits ## Credits
Built on [Bevy](https://bevyengine.org/) and the wider Rust ecosystem (Tokio, Built on [Bevy](https://bevyengine.org/) and the wider Rust ecosystem
Axum, sqlx, Serde, kira, and many more). Card faces and the default card back (Tokio, Axum, sqlx, Serde, kira, and many more). Card faces come from
use xCards artwork (LGPL-3.0); the UI font is FiraMono-Medium (OFL). All audio [hayeah/playing-cards-assets](https://github.com/hayeah/playing-cards-assets)
is synthesized programmatically by this project. See [CREDITS.md](CREDITS.md) (MIT, derived from the public-domain `vector-playing-cards` library); the
for the full list and license details. default card back is original work; the UI font is FiraMono-Medium (OFL).
All audio is synthesized programmatically by this project. See
[CREDITS.md](CREDITS.md) for the full list and license details.
## Changelog
See [CHANGELOG.md](CHANGELOG.md).
## License ## License
+66 -78
View File
@@ -1,121 +1,109 @@
# Solitaire Quest — UX Overhaul Session Handoff # Solitaire Quest — UX Overhaul Session Handoff
**Last updated:** 2026-05-01 — Phases 3, 4, and 5 all shipped. Smoke-test bugs closed. v1 release-readiness scope is essentially done; remaining work is the v0.1.0 tag plus desktop packaging. **Last updated:** 2026-05-02 (session 7, late-late) — Third UX iteration round complete on top of v0.12.0. Six post-handoff candidates shipped plus two code-review fixes. Ready to tag v0.13.0.
## Status at pause ## Status at pause
- **HEAD:** `902560c` — local master is **up to date** with `origin/master`. - **HEAD:** doc-commit closing this round (CHANGELOG + handoff). Local master has the impending tag at this commit.
- **Working tree:** clean. - **Working tree:** clean apart from untracked `CARD_PLAN.md` (intentional).
- **Build:** `cargo clippy --workspace --all-targets -- -D warnings` clean. - **Build:** `cargo clippy --workspace --all-targets -- -D warnings` clean.
- **Tests:** **906 passed / 0 failed** across the workspace. - **Tests:** **1053 passed / 0 failed** across the workspace (+22 from v0.12.0's 1031 baseline).
- **Tags on origin:** `v0.9.0`, `v0.10.0`, `v0.11.0`, `v0.12.0`. v0.13.0 is the next tag.
## Where we are ## Where we are
Phase 3 (design tokens + modal scaffold) and Phase 4 (release polish) shipped earlier. Phase 5 — running the binary end-to-end and fixing what broke — landed nine more commits today: a layout fit fix so tableau columns stop spilling off-screen, a three-pronged resize-lag fix, persisted window geometry, splash skip on subsequent launches, achievement tooltips, a code-quality sweep, client-side sync round-trip tests, and a hit-test fix so dragging a card no longer requires aiming for the bottom strip. Post-v0.12.0 the handoff listed six "next-round candidates" — every one shipped today plus two code-review fixes (font handling unified to bundled-only, sccache wiring removed). v0.13.0 is the right slice.
Polish is essentially complete; the remaining work is tagging v0.1.0 and desktop packaging. The candidate list is exhausted again. Direction is open.
### Design direction (unchanged) ### Design direction (unchanged)
- **Tone:** Balatro — chunky readable type, theatrical hierarchy, satisfying micro-interactions. - **Tone:** Balatro — chunky readable type, theatrical hierarchy, satisfying micro-interactions.
- **Palette:** Midnight Purple base + Balatro yellow primary + warm magenta secondary. - **Palette:** Midnight Purple base + Balatro yellow primary + warm magenta secondary.
- See [memory/project_ux_overhaul_2026-04.md](.claude/projects/-home-manage-Rusty-Solitare/memory/project_ux_overhaul_2026-04.md) for full direction. - See `~/.claude/projects/-home-manage-Rusty-Solitare/memory/project_ux_overhaul_2026-04.md` (machine-local).
## Phase 3 (shipped) ### Canonical remote
- `solitaire_engine/src/ui_theme.rs` — every design token: colours, type scale, spacing scale, radius rungs, z-index hierarchy, motion durations. `github.com/funman300/Rusty_Solitaire` is the canonical repo. Always push there.
- `solitaire_engine/src/ui_modal.rs``spawn_modal` scaffold + button-variant helpers + `paint_modal_buttons` system.
- All 12 overlays migrated to the modal scaffold with real Primary/Secondary/Tertiary buttons (no more Y/N debug prompts).
- HUD restructured into a 4-tier vertical stack with progressive disclosure.
- Animation upgrades: `SmoothSnap` slide curves, scoped settle bounce, deal jitter, win-cascade rotation.
## Phase 4 (shipped 2026-04-30) ## Session 7 round 3 (shipped 2026-05-02 late-late) — v0.13.0
| Area | Commit | What landed | | Area | Commit | What landed |
|---|---|---| |---|---|---|
| Workspace lint | `9bfca92` | Test-only clippy warnings under `--all-targets` resolved. | | Font fix | `17f9b51` | Code-review fix: bundle FiraMono via `include_bytes!()` in both `font_plugin` and `svg_loader`; drop `load_system_fonts`, drop the lenient resolver, drop the CSS-generic fallbacks. New `bundled_font_resolver` always returns the single bundled face. Parse failure aborts with a clear error. |
| App / window | `5f5aba8` | WM_CLASS, centered-on-primary window, panic hook → `crash.log`. | | sccache removal | `13dd44b` | Code-review fix: deleted `.cargo/config.toml` and the `.cargo` directory. Plain `cargo build` works without per-project setup. |
| Modal animation | `71999e1` | `ModalEntering` + ease-out scrim fade and 0.96→1.0 card scale. | | Wave 1 bundle | `ddc8f27` | **Tooltip-delay slider** in Settings → Gameplay (0.01.5 s, 0.1 s steps, "Instant" label at zero). **Win-streak fire animation** at thresholds [3, 5, 10] via new `WinStreakMilestoneEvent`. **Score-breakdown reveal on win modal** with per-row stagger (Base / Time bonus / No-undo / Multiplier / Total), respects `AnimSpeed::Instant`. |
| Score feedback | `dcfa976` | `ScorePulse` triangular 1.0→1.1→1.0; floating "+N" for jumps ≥ threshold. | | Card-back theming | `7ed4f2c` | The active theme's `back.svg` now actually drives the face-down sprite. Legacy `back_N.png` picker remains as a fallback for themes without a back; Settings caption surfaces when the override is in effect. |
| Hit targets | `b082bd6` | `ICON_BUTTON_PX` 28 → 32; sync status reads "local only". | | Drag-with-keyboard | `a0fc0d2` | Tab → Enter → arrows → Enter completes a move without a mouse. New `KeyboardDragState` resource; mutual exclusion with mouse drag via `KEYBOARD_DRAG_TOUCH_ID` sentinel. Help + onboarding hotkey lists updated. |
| Microcopy | `abeb4e5` | Help "Close" → "Done"; final onboarding CTA → "Let's play". | | Right-click radial | `b37f0cb` | Hold RMB on a face-up card → ring of icons at the cursor, one per legal destination; release over an icon → `MoveRequestEvent`. New `RadialMenuPlugin`. Help controls reference gains a "Mouse" section. |
| Empty states | `65d595a` | First-launch em-dash zero-stats grid + welcome line on Profile. |
| Leaderboard | `1384365` | Idle/Loaded/Error enum; local-only guard. |
| Credits | `fd7fb7b`, `f866299` | CREDITS.md added; README links it. |
| Home | `c1bde18` | Home repurposed as Mode Launcher with level-5 lock state. |
| Focus rings (Phase 1) | `1278952` | Tab/Shift-Tab/Enter on every modal button; auto-focus primary. |
| Focus rings (Phase 2) | `51d3454` | HUD action bar (hover-gated) and Home mode cards. |
| Focus rings (Phase 3) | `b78a493` | Settings: icon buttons, swatches, toggles; arrow-key `FocusRow`; auto-scroll. |
| Achievement tests | `2e080d0` | Integration coverage for `draw_three_master` and `zen_winner`. |
| Microcopy | `0c86cac` | "New game" / "Forfeit" replace "Yes, abandon" / "Yes, forfeit". |
| Tooltip infra | `54d3497` | `Tooltip(Cow<'static, str>)` component + hover-delay overlay. |
| HUD tooltips | `220e3f0` | 10 readouts + 6 action buttons. |
| Settings tooltips | `74597a8` | Volume, toggles, swatches, Sync Now. |
| Popover tooltips | `dbe6c60` | Modes and Menu rows. |
| Splash | `5d57b67` | Branded splash overlay (300ms fade-in / ~1s hold / 300ms fade-out). |
| Doc-rot | `73e210b` | ARCHITECTURE.md `bevy_kira_audio` references → `kira`. |
| Doc | `de52c8a`, `60a8036` | Mid-session and end-of-Phase-4 SESSION_HANDOFF refreshes. |
## Phase 5 (shipped 2026-05-01) ## Open punch list — release prep
Smoke test surfaced three issues: window-resize lag, tableau columns clipped below viewport, hit-target offset on cards. All fixed, plus four bonus polish items. 1. **Push** the unpushed commits to origin (5 commits now: 17f9b51, 13dd44b, ddc8f27, 7ed4f2c, a0fc0d2, b37f0cb, plus the impending doc commit).
2. **Tag v0.13.0** at the doc-commit HEAD.
3. **Desktop packaging** per `ARCHITECTURE.md §17`. The Arch PKGBUILD exists in `/home/manage/solitaire-quest-pkgbuild/` (separate repo). Pending: app icon, macOS `.icns` + notarisation cert, Windows `.ico` + Authenticode cert, AppImage recipe.
| Area | Commit | What landed | ## Open punch list — UX iteration (next-round candidates)
|---|---|---|
| Layout fit | `8dda954` | `card_height` constrained by vertical budget; worst-case 13-card column always fits. |
| Resize perf | `1719fda` | In-place sprite/text mutation + 50ms `ResizeThrottle` (was full re-spawn per pixel). |
| Resize stall | `59316de` | `PresentMode::AutoNoVsync` eliminates the X11/Wayland vsync stall during drag. |
| Window geometry | `6e7705b` | `WindowGeometry` persisted to settings.json; debounced save on resize/move. |
| Achievements | `7448225` | Tooltips on rows: reward shown when unlocked, condition + reward when locked, secrets stay cryptic. |
| Lint sweep | `4b9d008` | 33 pedantic warnings cleared (`map_unwrap_or`, `uninlined_format_args`, `match_same_arms`). |
| Sync tests | `3ef4ecb` | Five client-side round-trip integration tests via in-process axum + mock keyring. |
| Splash | `912b08c` | Splash skipped on subsequent launches via existing `first_run_complete` flag. |
| Hit test | `902560c` | `card_position` mirrors face-down fan step (0.12) for accurate AABB on tableau columns. |
## Open punch list for v1 The v0.13.0 list is exhausted. Fresh candidates for a future round:
1. **`xCards` upstream URL** in CREDITS.md is intentionally absent (`f866299`). One-line fill-in when the project owner picks a canonical mirror/fork; LGPL notice obligations are already satisfied without it. - **In-game daily-challenge calendar** — currently the daily challenge fires once on launch; a Settings or Profile-side calendar showing past days' completion / streak status would make the progression visible.
2. **Tag `v0.1.0`**workspace builds clean and tests are green; this is the next strategic milestone. - **Card-art preview in the theme picker** — Settings → Cosmetic shows theme name only; rendering the theme's Ace-of-Spades + back side-by-side as a thumbnail would make picking faster.
3. **Desktop packaging** per ARCHITECTURE.md §17 — Docker compose for the server is documented; desktop client packaging (icon, .ico/.icns, signing, AppImage) is not yet done. Needs artwork and signing certs. - **Per-mode high-score readout** in the Stats screen. Currently lifetime stats roll all modes together.
- **Auto-save in-progress games** in Zen / Time Attack so players who close the window mid-session don't lose their state.
- **Configurable scoring weights** for the curious — Settings → Gameplay slider for time-bonus magnitude. Cosmetic but power-user appealing.
- **Replay a winning game** — record the seed + move list at win time and offer "watch replay" from the Stats screen.
### Optional, deferred ## Card-theme system (CARD_PLAN.md, fully shipped)
- Animated focus ring (currently a static overlay; could pulse on focus change). Seven phases landed across `b8fb3fb``924a1e2` in v0.11.0; v0.13.0's `7ed4f2c` finally consumes the per-theme `back.svg`. End-to-end:
- Achievement onboarding pass — show first-time players the achievement panel after their first win.
- Mode-switch keyboard shortcut from inside the Mode Launcher (today only mouse opens it). - **Bundled default theme** ships in the binary via `embedded://` — 52 hayeah/playing-cards-assets SVGs + a midnight-purple `back.svg`.
- **User themes** under `themes://`. Drop a directory containing `theme.ron` + 53 SVGs.
- **Importer** at `solitaire_engine::theme::import_theme(zip)` validates archives and atomically unpacks.
- **Picker UI** in Settings → Cosmetic; the active theme's `back` overrides the legacy `back_N.png` picker when present.
## Resume prompt ## Resume prompt
``` ```
You are a senior Rust + Bevy developer finishing v1 of Solitaire You are a senior Rust + Bevy developer working on Solitaire Quest.
Quest. Working directory: /home/manage/Rusty_Solitare. Branch: Working directory: <Rusty_Solitaire clone path on this machine — local
master. The polish phase is complete; the remaining work is release directory may still be named Rusty_Solitare from earlier; that's fine>.
prep, not new features. Branch: master. Direction is OPEN — three UX iteration rounds shipped
and v0.13.0 is ready to tag.
State: HEAD=902560c, fully pushed to origin. Working tree clean. State: HEAD at the doc-commit closing session 7 round 3. Local master
is several commits ahead of origin and unpushed. Working tree clean
apart from untracked CARD_PLAN.md (intentional).
Build: cargo clippy --workspace --all-targets -- -D warnings clean. Build: cargo clippy --workspace --all-targets -- -D warnings clean.
Tests: 906 passed / 0 failed. Tests: 1053 passed / 0 failed.
READ FIRST (in order, before doing anything): READ FIRST (in order, before doing anything):
1. SESSION_HANDOFF.md — full state and punch list 1. SESSION_HANDOFF.md — full state, session 7 changelog, punch list
2. CLAUDE.md — hard rules (UI-first, no panics, etc.) 2. CHANGELOG.md — release-by-release record
3. ARCHITECTURE.md §15, §17 — platform targets, deployment guide 3. CLAUDE.md — hard rules (UI-first, no panics, etc.)
4. ~/.claude/projects/-home-manage-Rusty-Solitare/memory/MEMORY.md 4. ARCHITECTURE.md — crate responsibilities + data flow
— saved feedback / project context 5. ~/.claude/projects/<this-project>/memory/MEMORY.md
— saved feedback / project context (machine-local;
may be missing on a fresh machine)
PUNCH LIST (in priority order): DECISION TO ASK THE PLAYER FIRST:
1. Confirm or fill the xCards upstream URL in CREDITS.md (one-line A. Push and cut v0.13.0 now.
edit; not a release blocker). B. Smoke-test the new feel layer first (theme-aware backs, keyboard
2. Tag v0.1.0 once the user signs off. drag, right-click radial, score-breakdown reveal, streak fire,
3. Desktop packaging: icon hookup, platform bundles (.ico/.icns/ tooltip-delay slider), then tag.
AppImage), signing. Needs artwork and certs from the user. C. Skip the tag for another iteration round — see "next-round
candidates" in SESSION_HANDOFF for fresh ideas.
D. Take the deferred desktop-packaging item (needs artwork +
signing certs from the user).
WORKFLOW NOTES: WORKFLOW NOTES:
- Commits use: - Commits use:
git -c user.name=funman300 -c user.email=root@vscode.infinity commit -m "..." git -c user.name=funman300 -c user.email=root@vscode.infinity \
commit -m "..."
- Sub-agents stage + verify only; orchestrator commits. - Sub-agents stage + verify only; orchestrator commits.
- Every commit must pass build / clippy / test. - Every commit must pass build / clippy / test before pushing.
- Push to GitHub (origin) — that is the canonical remote.
OPEN AT THE START: ask which punch-list item to start on. Don't pick OPEN AT THE START: ask which of A / B / C / D. Don't pick unilaterally.
unilaterally — release-readiness ordering is the user's call.
``` ```
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 196 KiB

+1 -1
View File
@@ -1,7 +1,7 @@
# Solitaire Quest — Session Handoff # Solitaire Quest — Session Handoff
> Last updated: 2026-04-25 > Last updated: 2026-04-25
> Branch: `master` — pushed to https://git.aleshym.co/funman300/Rusty_Solitare.git > Branch: `master` — pushed to https://github.com/funman300/Rusty_Solitaire.git
> Test count: **242 passing** (83 core + 60 data + 99 engine), `cargo clippy --workspace -- -D warnings` clean > Test count: **242 passing** (83 core + 60 data + 99 engine), `cargo clippy --workspace -- -D warnings` clean
--- ---
+22 -7
View File
@@ -6,12 +6,13 @@ use bevy::prelude::*;
use bevy::window::{MonitorSelection, PresentMode, WindowPosition}; use bevy::window::{MonitorSelection, PresentMode, WindowPosition};
use solitaire_data::{load_settings_from, provider_for_backend, settings_file_path, Settings}; use solitaire_data::{load_settings_from, provider_for_backend, settings_file_path, Settings};
use solitaire_engine::{ use solitaire_engine::{
AchievementPlugin, AnimationPlugin, AudioPlugin, AutoCompletePlugin, CardAnimationPlugin, register_theme_asset_sources, AchievementPlugin, AnimationPlugin, AssetSourcesPlugin,
CardPlugin, ChallengePlugin, CursorPlugin, DailyChallengePlugin, FeedbackAnimPlugin, AudioPlugin, AutoCompletePlugin, CardAnimationPlugin, CardPlugin, ChallengePlugin,
FontPlugin, GamePlugin, HelpPlugin, HomePlugin, HudPlugin, InputPlugin, LeaderboardPlugin, CursorPlugin, DailyChallengePlugin, FeedbackAnimPlugin, FontPlugin, GamePlugin, HelpPlugin,
OnboardingPlugin, PausePlugin, ProfilePlugin, ProgressPlugin, SelectionPlugin, SettingsPlugin, HomePlugin, HudPlugin, InputPlugin, LeaderboardPlugin, OnboardingPlugin, PausePlugin,
SplashPlugin, StatsPlugin, SyncPlugin, TablePlugin, TimeAttackPlugin, UiFocusPlugin, ProfilePlugin, ProgressPlugin, RadialMenuPlugin, SelectionPlugin, SettingsPlugin, SplashPlugin,
UiModalPlugin, UiTooltipPlugin, WeeklyGoalsPlugin, WinSummaryPlugin, StatsPlugin, SyncPlugin, TablePlugin, ThemePlugin, ThemeRegistryPlugin, TimeAttackPlugin,
UiFocusPlugin, UiModalPlugin, UiTooltipPlugin, WeeklyGoalsPlugin, WinSummaryPlugin,
}; };
fn main() { fn main() {
@@ -54,7 +55,17 @@ fn main() {
), ),
}; };
App::new() let mut app = App::new();
// The card-theme system's `themes://` asset source must be
// registered *before* `DefaultPlugins` builds `AssetPlugin`,
// because that plugin freezes the asset-source list at build
// time. The matching `AssetSourcesPlugin` (added below) finishes
// the wiring after `DefaultPlugins` by populating the embedded
// default theme into Bevy's `EmbeddedAssetRegistry`.
register_theme_asset_sources(&mut app);
app
.add_plugins( .add_plugins(
DefaultPlugins DefaultPlugins
.set(WindowPlugin { .set(WindowPlugin {
@@ -91,12 +102,16 @@ fn main() {
..default() ..default()
}), }),
) )
.add_plugins(AssetSourcesPlugin)
.add_plugins(ThemePlugin)
.add_plugins(ThemeRegistryPlugin)
.add_plugins(FontPlugin) .add_plugins(FontPlugin)
.add_plugins(GamePlugin) .add_plugins(GamePlugin)
.add_plugins(TablePlugin) .add_plugins(TablePlugin)
.add_plugins(CardPlugin) .add_plugins(CardPlugin)
.add_plugins(CursorPlugin) .add_plugins(CursorPlugin)
.add_plugins(InputPlugin) .add_plugins(InputPlugin)
.add_plugins(RadialMenuPlugin)
.add_plugins(SelectionPlugin) .add_plugins(SelectionPlugin)
.add_plugins(AnimationPlugin) .add_plugins(AnimationPlugin)
.add_plugins(FeedbackAnimPlugin) .add_plugins(FeedbackAnimPlugin)
+40 -1
View File
@@ -16,13 +16,14 @@ fn main() -> io::Result<()> {
let out_dir = workspace_root().join("assets").join("audio"); let out_dir = workspace_root().join("assets").join("audio");
fs::create_dir_all(&out_dir)?; fs::create_dir_all(&out_dir)?;
let effects: [(&str, Generator); 6] = [ let effects: [(&str, Generator); 7] = [
("card_flip.wav", card_flip), ("card_flip.wav", card_flip),
("card_place.wav", card_place), ("card_place.wav", card_place),
("card_deal.wav", card_deal), ("card_deal.wav", card_deal),
("card_invalid.wav", card_invalid), ("card_invalid.wav", card_invalid),
("win_fanfare.wav", win_fanfare), ("win_fanfare.wav", win_fanfare),
("ambient_loop.wav", ambient_loop), ("ambient_loop.wav", ambient_loop),
("foundation_complete.wav", foundation_complete),
]; ];
for (name, make) in &effects { for (name, make) in &effects {
@@ -170,6 +171,44 @@ fn win_fanfare() -> Vec<i16> {
out out
} }
/// Per-suit foundation-completion ping (~240 ms): a rising three-note
/// chime — C6, E6, G6 — with a soft 2nd-harmonic warm layer on each
/// note. Shorter and brighter than `win_fanfare` so it can fire up to
/// four times per game (once per suit) without drowning out subsequent
/// move sounds. The fourth firing co-occurs with the win cascade and
/// `win_fanfare`; the C-major triad sits an octave above the
/// fanfare's root so the two layer cleanly instead of fighting for the
/// same frequency band.
fn foundation_complete() -> Vec<i16> {
// C major triad, one octave up from win_fanfare's root.
let notes = [1046.50_f32, 1318.51, 1567.98]; // C6, E6, G6
let note_dur = 0.07_f32; // brisk, ascending
let total = note_dur * notes.len() as f32 + 0.05;
let n = duration_samples(total);
let mut out = Vec::with_capacity(n);
for i in 0..n {
let t = i as f32 / SAMPLE_RATE as f32;
let mut sample = 0.0f32;
for (idx, freq) in notes.iter().enumerate() {
let start = idx as f32 * note_dur;
let local = t - start;
// Each note rings out for 0.18 s — overlapping notes form a
// brief chord at the tail.
if !(0.0..=0.18).contains(&local) {
continue;
}
// Sine + soft 2nd harmonic for warmth, ar_envelope decays
// sharply so each note is bell-like rather than sustained.
let s = (2.0 * std::f32::consts::PI * freq * local).sin()
+ 0.25 * (2.0 * std::f32::consts::PI * freq * 2.0 * local).sin();
let env = ar_envelope(local, 0.005, 0.18, 14.0);
sample += s * env;
}
out.push(quantize(sample * 0.20));
}
out
}
/// Generates a seamlessly looping ambient drone track (~6 seconds, 44100 Hz /// Generates a seamlessly looping ambient drone track (~6 seconds, 44100 Hz
/// mono 16-bit PCM). /// mono 16-bit PCM).
/// ///
-1
View File
@@ -6,6 +6,5 @@ edition.workspace = true
[dependencies] [dependencies]
serde = { workspace = true } serde = { workspace = true }
chrono = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
rand = { workspace = true } rand = { workspace = true }
+204 -24
View File
@@ -1,6 +1,6 @@
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::card::{Card, Suit}; use crate::card::Card;
use crate::deck::{deal_klondike, Deck}; use crate::deck::{deal_klondike, Deck};
use crate::error::MoveError; use crate::error::MoveError;
use crate::pile::{Pile, PileType}; use crate::pile::{Pile, PileType};
@@ -9,6 +9,20 @@ use crate::scoring::{compute_time_bonus as scoring_time_bonus, score_move, score
const MAX_UNDO_STACK: usize = 64; const MAX_UNDO_STACK: usize = 64;
/// Save-file schema version for `GameState`. Increment when the on-disk
/// representation changes incompatibly so `load_game_state_from` can refuse
/// older formats and start the player on a fresh game.
///
/// History:
/// - v1: `Foundation(Suit)` keys.
/// - v2 (current): `Foundation(u8)` slot keys; claimed suit derived from the
/// bottom card of the pile.
pub const GAME_STATE_SCHEMA_VERSION: u32 = 2;
/// Default value for `GameState::schema_version` when deserialising older
/// save files that pre-date the field.
fn schema_v1() -> u32 { 1 }
/// Serialize `HashMap<PileType, Pile>` as a `Vec` of `(key, value)` pairs so /// Serialize `HashMap<PileType, Pile>` as a `Vec` of `(key, value)` pairs so
/// that JSON (which requires string map keys) round-trips correctly. /// that JSON (which requires string map keys) round-trips correctly.
mod pile_map_serde { mod pile_map_serde {
@@ -98,6 +112,11 @@ pub struct GameState {
/// Used by the `comeback` achievement condition. /// Used by the `comeback` achievement condition.
#[serde(default)] #[serde(default)]
pub recycle_count: u32, pub recycle_count: u32,
/// Save-file schema version. Defaults to `1` for older files that pre-date
/// the field. The loader refuses any value other than
/// [`GAME_STATE_SCHEMA_VERSION`].
#[serde(default = "schema_v1")]
pub schema_version: u32,
undo_stack: VecDeque<StateSnapshot>, undo_stack: VecDeque<StateSnapshot>,
} }
@@ -116,8 +135,8 @@ impl GameState {
let mut piles: HashMap<PileType, Pile> = HashMap::new(); let mut piles: HashMap<PileType, Pile> = HashMap::new();
piles.insert(PileType::Stock, stock); piles.insert(PileType::Stock, stock);
piles.insert(PileType::Waste, Pile::new(PileType::Waste)); piles.insert(PileType::Waste, Pile::new(PileType::Waste));
for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] { for slot in 0..4_u8 {
piles.insert(PileType::Foundation(suit), Pile::new(PileType::Foundation(suit))); piles.insert(PileType::Foundation(slot), Pile::new(PileType::Foundation(slot)));
} }
for (i, pile) in tableau.into_iter().enumerate() { for (i, pile) in tableau.into_iter().enumerate() {
piles.insert(PileType::Tableau(i), pile); piles.insert(PileType::Tableau(i), pile);
@@ -135,6 +154,7 @@ impl GameState {
is_auto_completable: false, is_auto_completable: false,
undo_count: 0, undo_count: 0,
recycle_count: 0, recycle_count: 0,
schema_version: GAME_STATE_SCHEMA_VERSION,
undo_stack: VecDeque::new(), undo_stack: VecDeque::new(),
} }
} }
@@ -247,14 +267,14 @@ impl GameState {
let bottom_card = from_pile.cards[start].clone(); let bottom_card = from_pile.cards[start].clone();
match &to { match &to {
PileType::Foundation(suit) => { PileType::Foundation(_) => {
if count != 1 { if count != 1 {
return Err(MoveError::RuleViolation( return Err(MoveError::RuleViolation(
"only one card can move to foundation at a time".into(), "only one card can move to foundation at a time".into(),
)); ));
} }
let dest = self.piles.get(&to).ok_or(MoveError::InvalidDestination)?; let dest = self.piles.get(&to).ok_or(MoveError::InvalidDestination)?;
if !can_place_on_foundation(&bottom_card, dest, *suit) { if !can_place_on_foundation(&bottom_card, dest) {
return Err(MoveError::RuleViolation("invalid foundation placement".into())); return Err(MoveError::RuleViolation("invalid foundation placement".into()));
} }
} }
@@ -332,15 +352,13 @@ impl GameState {
Ok(()) Ok(())
} }
/// Returns `true` when all four foundations each contain 13 cards. /// Returns `true` when all four foundation slots each contain 13 cards.
pub fn check_win(&self) -> bool { pub fn check_win(&self) -> bool {
[Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] (0..4_u8).all(|slot| {
.iter() self.piles
.all(|&suit| { .get(&PileType::Foundation(slot))
self.piles .is_some_and(|p| p.cards.len() == 13)
.get(&PileType::Foundation(suit)) })
.is_some_and(|p| p.cards.len() == 13)
})
} }
/// Returns `true` when stock and waste are empty and all tableau cards are face-up. /// Returns `true` when stock and waste are empty and all tableau cards are face-up.
@@ -379,13 +397,34 @@ impl GameState {
if !self.is_auto_completable || self.is_won { if !self.is_auto_completable || self.is_won {
return None; return None;
} }
let suits = [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades];
for i in 0..7 { for i in 0..7 {
let tableau = PileType::Tableau(i); let tableau = PileType::Tableau(i);
if let Some(card) = self.piles[&tableau].cards.last() { if let Some(card) = self.piles[&tableau].cards.last() {
for &suit in &suits { // Prefer the slot that already claims this card's suit so
let foundation = PileType::Foundation(suit); // Aces don't sometimes land in slot 0 and then leave the
if can_place_on_foundation(card, &self.piles[&foundation], suit) { // matching suit-claimed slot empty.
let mut candidate: Option<u8> = None;
let mut empty_slot: Option<u8> = None;
for slot in 0..4_u8 {
let foundation = PileType::Foundation(slot);
let pile = &self.piles[&foundation];
if pile.cards.is_empty() {
if empty_slot.is_none() {
empty_slot = Some(slot);
}
} else if pile.claimed_suit() == Some(card.suit) {
candidate = Some(slot);
break;
}
}
let target_slot = candidate.or_else(|| {
// Only fall back to an empty slot if the card is an Ace,
// which is the only rank that can claim an empty slot.
if card.rank.value() == 1 { empty_slot } else { None }
});
if let Some(slot) = target_slot {
let foundation = PileType::Foundation(slot);
if can_place_on_foundation(card, &self.piles[&foundation]) {
return Some((tableau, foundation)); return Some((tableau, foundation));
} }
} }
@@ -403,7 +442,7 @@ impl GameState {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::card::{Card, Rank}; use crate::card::{Card, Rank, Suit};
fn new_game() -> GameState { fn new_game() -> GameState {
GameState::new(42, DrawMode::DrawOne) GameState::new(42, DrawMode::DrawOne)
@@ -434,8 +473,8 @@ mod tests {
#[test] #[test]
fn new_game_foundations_are_empty() { fn new_game_foundations_are_empty() {
let g = new_game(); let g = new_game();
for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] { for slot in 0..4_u8 {
assert!(g.piles[&PileType::Foundation(suit)].cards.is_empty()); assert!(g.piles[&PileType::Foundation(slot)].cards.is_empty());
} }
} }
@@ -662,7 +701,7 @@ mod tests {
]; ];
let result = g.move_cards( let result = g.move_cards(
PileType::Tableau(0), PileType::Tableau(0),
PileType::Foundation(Suit::Clubs), PileType::Foundation(0),
2, 2,
); );
assert!( assert!(
@@ -706,8 +745,9 @@ mod tests {
#[test] #[test]
fn win_detection_all_foundations_complete() { fn win_detection_all_foundations_complete() {
let mut g = new_game(); let mut g = new_game();
for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] { let suits = [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades];
let f = g.piles.get_mut(&PileType::Foundation(suit)).unwrap(); for (slot, suit) in suits.into_iter().enumerate() {
let f = g.piles.get_mut(&PileType::Foundation(slot as u8)).unwrap();
f.cards.clear(); f.cards.clear();
for rank in [ for rank in [
Rank::Ace, Rank::Two, Rank::Three, Rank::Four, Rank::Five, Rank::Ace, Rank::Two, Rank::Three, Rank::Four, Rank::Five,
@@ -1039,7 +1079,8 @@ mod tests {
let mv = g.next_auto_complete_move().expect("should find a move"); let mv = g.next_auto_complete_move().expect("should find a move");
assert_eq!(mv.0, PileType::Tableau(0)); assert_eq!(mv.0, PileType::Tableau(0));
assert_eq!(mv.1, PileType::Foundation(Suit::Clubs)); // Slot 0 is the first empty foundation; the Ace lands there.
assert_eq!(mv.1, PileType::Foundation(0));
} }
#[test] #[test]
@@ -1049,4 +1090,143 @@ mod tests {
g.is_won = true; g.is_won = true;
assert!(g.next_auto_complete_move().is_none()); assert!(g.next_auto_complete_move().is_none());
} }
// --- Slot-based foundation behaviour (refactor coverage) ---
/// Aces land in the first empty slot regardless of suit, and successive
/// Aces fan out across slots 0, 1, 2, 3 in deterministic order.
#[test]
fn any_ace_lands_in_first_empty_foundation() {
let mut g = new_game();
// Clear stock/waste/tableau so we can hand-construct moves directly.
g.piles.get_mut(&PileType::Stock).unwrap().cards.clear();
g.piles.get_mut(&PileType::Waste).unwrap().cards.clear();
for i in 0..7 {
g.piles.get_mut(&PileType::Tableau(i)).unwrap().cards.clear();
}
// Place an Ace of Clubs on tableau 0; move it to slot 0.
g.piles.get_mut(&PileType::Tableau(0)).unwrap().cards.push(Card {
id: 1, suit: Suit::Clubs, rank: Rank::Ace, face_up: true,
});
g.move_cards(PileType::Tableau(0), PileType::Foundation(0), 1).unwrap();
// Now place an Ace of Spades on tableau 0 and move it to slot 1.
g.piles.get_mut(&PileType::Tableau(0)).unwrap().cards.push(Card {
id: 2, suit: Suit::Spades, rank: Rank::Ace, face_up: true,
});
g.move_cards(PileType::Tableau(0), PileType::Foundation(1), 1).unwrap();
assert_eq!(g.piles[&PileType::Foundation(0)].claimed_suit(), Some(Suit::Clubs));
assert_eq!(g.piles[&PileType::Foundation(1)].claimed_suit(), Some(Suit::Spades));
}
/// `Pile::claimed_suit` reads the bottom card's suit on a populated
/// foundation slot, regardless of which slot index the pile occupies.
#[test]
fn claimed_suit_is_derived_from_bottom_card() {
let mut g = new_game();
g.piles.get_mut(&PileType::Stock).unwrap().cards.clear();
g.piles.get_mut(&PileType::Waste).unwrap().cards.clear();
for i in 0..7 {
g.piles.get_mut(&PileType::Tableau(i)).unwrap().cards.clear();
}
g.piles.get_mut(&PileType::Tableau(0)).unwrap().cards.push(Card {
id: 50, suit: Suit::Hearts, rank: Rank::Ace, face_up: true,
});
g.move_cards(PileType::Tableau(0), PileType::Foundation(2), 1).unwrap();
assert_eq!(
g.piles[&PileType::Foundation(2)].claimed_suit(),
Some(Suit::Hearts)
);
}
/// Undoing the only card from a foundation slot drops the claimed suit;
/// the slot then accepts a different Ace.
#[test]
fn foundation_claim_drops_when_emptied_via_undo() {
let mut g = new_game();
g.piles.get_mut(&PileType::Stock).unwrap().cards.clear();
g.piles.get_mut(&PileType::Waste).unwrap().cards.clear();
for i in 0..7 {
g.piles.get_mut(&PileType::Tableau(i)).unwrap().cards.clear();
}
g.piles.get_mut(&PileType::Tableau(0)).unwrap().cards.push(Card {
id: 1, suit: Suit::Hearts, rank: Rank::Ace, face_up: true,
});
g.move_cards(PileType::Tableau(0), PileType::Foundation(0), 1).unwrap();
assert_eq!(g.piles[&PileType::Foundation(0)].claimed_suit(), Some(Suit::Hearts));
g.undo().unwrap();
assert!(g.piles[&PileType::Foundation(0)].cards.is_empty());
assert!(g.piles[&PileType::Foundation(0)].claimed_suit().is_none());
// A different Ace can now claim slot 0.
let t0 = g.piles.get_mut(&PileType::Tableau(0)).unwrap();
t0.cards.clear();
t0.cards.push(Card { id: 2, suit: Suit::Spades, rank: Rank::Ace, face_up: true });
g.move_cards(PileType::Tableau(0), PileType::Foundation(0), 1).unwrap();
assert_eq!(g.piles[&PileType::Foundation(0)].claimed_suit(), Some(Suit::Spades));
}
/// Successive Aces from the waste pile distribute across slots 0..=3 in
/// order — the player picks the slot, but `move_cards` accepts any
/// empty-slot placement for an Ace.
#[test]
fn multiple_aces_distribute_across_slots() {
let mut g = new_game();
g.piles.get_mut(&PileType::Stock).unwrap().cards.clear();
g.piles.get_mut(&PileType::Waste).unwrap().cards.clear();
for i in 0..7 {
g.piles.get_mut(&PileType::Tableau(i)).unwrap().cards.clear();
}
let aces = [
(Suit::Clubs, 10),
(Suit::Diamonds, 11),
(Suit::Hearts, 12),
(Suit::Spades, 13),
];
for (slot, (suit, id)) in aces.iter().enumerate() {
g.piles.get_mut(&PileType::Waste).unwrap().cards.push(Card {
id: *id, suit: *suit, rank: Rank::Ace, face_up: true,
});
g.move_cards(PileType::Waste, PileType::Foundation(slot as u8), 1).unwrap();
}
for (slot, (suit, _)) in aces.iter().enumerate() {
assert_eq!(
g.piles[&PileType::Foundation(slot as u8)].claimed_suit(),
Some(*suit),
"slot {slot} should claim {suit:?}",
);
}
}
/// Auto-complete prefers the foundation slot whose claimed suit matches
/// the candidate card's suit, even if an empty slot exists at a lower
/// index.
#[test]
fn next_auto_complete_move_picks_slot_with_matching_claim() {
let mut g = new_game();
g.piles.get_mut(&PileType::Stock).unwrap().cards.clear();
g.piles.get_mut(&PileType::Waste).unwrap().cards.clear();
for i in 0..7 {
g.piles.get_mut(&PileType::Tableau(i)).unwrap().cards.clear();
}
// Slot 0 is empty; slot 1 already claims Hearts via Ace of Hearts.
g.piles.get_mut(&PileType::Foundation(1)).unwrap().cards.push(Card {
id: 1, suit: Suit::Hearts, rank: Rank::Ace, face_up: true,
});
// Tableau 0 holds the 2 of Hearts to play.
g.piles.get_mut(&PileType::Tableau(0)).unwrap().cards.push(Card {
id: 2, suit: Suit::Hearts, rank: Rank::Two, face_up: true,
});
g.is_auto_completable = true;
let mv = g.next_auto_complete_move().expect("auto-complete must find slot 1");
assert_eq!(mv.0, PileType::Tableau(0));
assert_eq!(
mv.1,
PileType::Foundation(1),
"must target the Hearts-claimed slot, not the empty slot 0",
);
}
} }
+38 -5
View File
@@ -8,8 +8,10 @@ pub enum PileType {
Stock, Stock,
/// The face-up discard pile drawn to. /// The face-up discard pile drawn to.
Waste, Waste,
/// One of the four suit-ordered foundation piles. /// One of the four foundation slots (0..=3). The claimed suit, if any,
Foundation(Suit), /// is derived from the bottom card of the pile (always an Ace by
/// construction).
Foundation(u8),
/// One of the seven tableau columns (06). /// One of the seven tableau columns (06).
Tableau(usize), Tableau(usize),
} }
@@ -17,7 +19,7 @@ pub enum PileType {
/// A named collection of cards in a specific board position. /// A named collection of cards in a specific board position.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Pile { pub struct Pile {
/// Which pile this is (Stock, Waste, Foundation suit, or Tableau column). /// Which pile this is (Stock, Waste, Foundation slot, or Tableau column).
pub pile_type: PileType, pub pile_type: PileType,
/// Cards in the pile, bottom-to-top stacking order. Last element is the top card. /// Cards in the pile, bottom-to-top stacking order. Last element is the top card.
pub cards: Vec<Card>, pub cards: Vec<Card>,
@@ -33,6 +35,16 @@ impl Pile {
pub fn top(&self) -> Option<&Card> { pub fn top(&self) -> Option<&Card> {
self.cards.last() self.cards.last()
} }
/// For foundation piles: returns `Some(suit)` once at least one card has
/// landed (the bottom card is always an Ace of the claimed suit).
/// Returns `None` for empty foundations or non-foundation piles.
pub fn claimed_suit(&self) -> Option<Suit> {
match self.pile_type {
PileType::Foundation(_) => self.cards.first().map(|c| c.suit),
_ => None,
}
}
} }
#[cfg(test)] #[cfg(test)]
@@ -61,12 +73,33 @@ mod tests {
} }
#[test] #[test]
fn pile_type_foundation_uses_suit() { fn pile_type_foundation_uses_slot_index() {
assert_ne!(PileType::Foundation(Suit::Hearts), PileType::Foundation(Suit::Spades)); assert_ne!(PileType::Foundation(0), PileType::Foundation(3));
} }
#[test] #[test]
fn pile_type_tableau_uses_index() { fn pile_type_tableau_uses_index() {
assert_ne!(PileType::Tableau(0), PileType::Tableau(6)); assert_ne!(PileType::Tableau(0), PileType::Tableau(6));
} }
#[test]
fn claimed_suit_is_none_for_empty_foundation() {
let pile = Pile::new(PileType::Foundation(0));
assert!(pile.claimed_suit().is_none());
}
#[test]
fn claimed_suit_is_none_for_non_foundation() {
let mut pile = Pile::new(PileType::Tableau(0));
pile.cards.push(Card { id: 0, suit: Suit::Hearts, rank: Rank::Ace, face_up: true });
assert!(pile.claimed_suit().is_none());
}
#[test]
fn claimed_suit_returns_bottom_card_suit() {
let mut pile = Pile::new(PileType::Foundation(2));
pile.cards.push(Card { id: 0, suit: Suit::Hearts, rank: Rank::Ace, face_up: true });
pile.cards.push(Card { id: 1, suit: Suit::Hearts, rank: Rank::Two, face_up: true });
assert_eq!(pile.claimed_suit(), Some(Suit::Hearts));
}
} }
+37 -26
View File
@@ -1,16 +1,18 @@
use crate::card::{Card, Suit}; use crate::card::Card;
use crate::pile::Pile; use crate::pile::Pile;
/// Returns `true` if `card` can be placed on `pile` as the next card in the foundation for `suit`. /// Returns `true` if `card` can be placed on the foundation `pile`.
/// ///
/// Foundation rules: same suit, Ace starts, each subsequent card is one rank higher. /// Foundation rules:
pub fn can_place_on_foundation(card: &Card, pile: &Pile, suit: Suit) -> bool { /// - When the pile is empty, any Ace is accepted; the placed Ace's suit
if card.suit != suit { /// becomes the pile's claimed suit (derived from the bottom card via
return false; /// [`Pile::claimed_suit`](crate::pile::Pile::claimed_suit)).
} /// - When the pile is non-empty, the next card must match the top card's
/// suit and be exactly one rank higher.
pub fn can_place_on_foundation(card: &Card, pile: &Pile) -> bool {
match pile.cards.last() { match pile.cards.last() {
None => card.rank.value() == 1, None => card.rank.value() == 1,
Some(top) => card.rank.value() == top.rank.value() + 1, Some(top) => card.suit == top.suit && card.rank.value() == top.rank.value() + 1,
} }
} }
@@ -45,37 +47,46 @@ mod tests {
// Foundation tests // Foundation tests
#[test] #[test]
fn foundation_ace_on_empty_is_valid() { fn foundation_ace_on_empty_is_valid() {
let c = card(Suit::Hearts, Rank::Ace); // Every suit's Ace must land on an empty foundation slot regardless of
let p = Pile::new(PileType::Foundation(Suit::Hearts)); // its slot index; the slot claims the suit only after the Ace lands.
assert!(can_place_on_foundation(&c, &p, Suit::Hearts)); for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] {
let c = card(suit, Rank::Ace);
let p = Pile::new(PileType::Foundation(0));
assert!(
can_place_on_foundation(&c, &p),
"Ace of {suit:?} must land on empty slot 0",
);
}
} }
#[test] #[test]
fn foundation_non_ace_on_empty_is_invalid() { fn foundation_non_ace_on_empty_is_invalid() {
let c = card(Suit::Hearts, Rank::Two); let c = card(Suit::Hearts, Rank::Two);
let p = Pile::new(PileType::Foundation(Suit::Hearts)); let p = Pile::new(PileType::Foundation(0));
assert!(!can_place_on_foundation(&c, &p, Suit::Hearts)); assert!(!can_place_on_foundation(&c, &p));
} }
#[test] #[test]
fn foundation_two_on_ace_same_suit_is_valid() { fn foundation_two_on_ace_same_suit_is_valid() {
let c = card(Suit::Clubs, Rank::Two); let c = card(Suit::Clubs, Rank::Two);
let p = pile_with(PileType::Foundation(Suit::Clubs), vec![card(Suit::Clubs, Rank::Ace)]); let p = pile_with(PileType::Foundation(0), vec![card(Suit::Clubs, Rank::Ace)]);
assert!(can_place_on_foundation(&c, &p, Suit::Clubs)); assert!(can_place_on_foundation(&c, &p));
} }
#[test] #[test]
fn foundation_wrong_suit_is_invalid() { fn foundation_second_card_must_match_claimed_suit() {
let c = card(Suit::Hearts, Rank::Ace); // Place Ace of Hearts on slot 0, then attempt 2 of Spades — rejected
let p = Pile::new(PileType::Foundation(Suit::Spades)); // because the slot's claimed suit is Hearts after the Ace lands.
assert!(!can_place_on_foundation(&c, &p, Suit::Spades)); let p = pile_with(PileType::Foundation(0), vec![card(Suit::Hearts, Rank::Ace)]);
let c = card(Suit::Spades, Rank::Two);
assert!(!can_place_on_foundation(&c, &p));
} }
#[test] #[test]
fn foundation_skipping_rank_is_invalid() { fn foundation_skipping_rank_is_invalid() {
let c = card(Suit::Diamonds, Rank::Three); let c = card(Suit::Diamonds, Rank::Three);
let p = pile_with(PileType::Foundation(Suit::Diamonds), vec![card(Suit::Diamonds, Rank::Ace)]); let p = pile_with(PileType::Foundation(0), vec![card(Suit::Diamonds, Rank::Ace)]);
assert!(!can_place_on_foundation(&c, &p, Suit::Diamonds)); assert!(!can_place_on_foundation(&c, &p));
} }
// Tableau tests // Tableau tests
@@ -125,16 +136,16 @@ mod tests {
fn foundation_king_on_queen_completes_suit() { fn foundation_king_on_queen_completes_suit() {
// The last card placed to complete a foundation is always King on Queen. // The last card placed to complete a foundation is always King on Queen.
let c = card(Suit::Spades, Rank::King); let c = card(Suit::Spades, Rank::King);
let p = pile_with(PileType::Foundation(Suit::Spades), vec![card(Suit::Spades, Rank::Queen)]); let p = pile_with(PileType::Foundation(0), vec![card(Suit::Spades, Rank::Queen)]);
assert!(can_place_on_foundation(&c, &p, Suit::Spades)); assert!(can_place_on_foundation(&c, &p));
} }
#[test] #[test]
fn foundation_king_wrong_suit_is_invalid() { fn foundation_king_wrong_suit_is_invalid() {
// King of Hearts cannot go on a Spades foundation even if rank matches. // King of Hearts cannot go on a Spades-claimed foundation even if rank matches.
let c = card(Suit::Hearts, Rank::King); let c = card(Suit::Hearts, Rank::King);
let p = pile_with(PileType::Foundation(Suit::Spades), vec![card(Suit::Spades, Rank::Queen)]); let p = pile_with(PileType::Foundation(0), vec![card(Suit::Spades, Rank::Queen)]);
assert!(!can_place_on_foundation(&c, &p, Suit::Spades)); assert!(!can_place_on_foundation(&c, &p));
} }
#[test] #[test]
+3 -4
View File
@@ -33,12 +33,11 @@ pub fn compute_time_bonus(elapsed_seconds: u64) -> i32 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::card::Suit;
#[test] #[test]
fn move_to_foundation_scores_ten() { fn move_to_foundation_scores_ten() {
assert_eq!(score_move(&PileType::Waste, &PileType::Foundation(Suit::Hearts)), 10); assert_eq!(score_move(&PileType::Waste, &PileType::Foundation(2)), 10);
assert_eq!(score_move(&PileType::Tableau(0), &PileType::Foundation(Suit::Clubs)), 10); assert_eq!(score_move(&PileType::Tableau(0), &PileType::Foundation(0)), 10);
} }
#[test] #[test]
@@ -74,7 +73,7 @@ mod tests {
#[test] #[test]
fn non_waste_to_tableau_scores_zero() { fn non_waste_to_tableau_scores_zero() {
// Foundation → Tableau is impossible in practice but must score 0. // Foundation → Tableau is impossible in practice but must score 0.
assert_eq!(score_move(&PileType::Foundation(Suit::Clubs), &PileType::Tableau(0)), 0); assert_eq!(score_move(&PileType::Foundation(0), &PileType::Tableau(0)), 0);
// Tableau → Tableau (restack) scores 0. // Tableau → Tableau (restack) scores 0.
assert_eq!(score_move(&PileType::Tableau(1), &PileType::Tableau(2)), 0); assert_eq!(score_move(&PileType::Tableau(1), &PileType::Tableau(2)), 0);
} }
+1 -1
View File
@@ -126,7 +126,7 @@ pub use challenge::{challenge_count, challenge_seed_for, CHALLENGE_SEEDS};
pub mod settings; pub mod settings;
pub use settings::{ pub use settings::{
load_settings_from, save_settings_to, settings_file_path, AnimSpeed, Settings, SyncBackend, load_settings_from, save_settings_to, settings_file_path, AnimSpeed, Settings, SyncBackend,
Theme, WindowGeometry, Theme, WindowGeometry, TOOLTIP_DELAY_MAX_SECS, TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_STEP_SECS,
}; };
pub mod auth_tokens; pub mod auth_tokens;
+199 -2
View File
@@ -124,6 +124,33 @@ pub struct Settings {
/// `None` thanks to `#[serde(default)]`. /// `None` thanks to `#[serde(default)]`.
#[serde(default)] #[serde(default)]
pub window_geometry: Option<WindowGeometry>, pub window_geometry: Option<WindowGeometry>,
/// Identifier of the active card-art theme. Matches `meta.id` from
/// the theme's `theme.ron` manifest. `"default"` is the bundled
/// theme and is always present in the registry; user-supplied
/// themes register under their own ids when they're imported.
/// Older `settings.json` files default cleanly to `"default"` via
/// `#[serde(default = ...)]`.
#[serde(default = "default_theme_id")]
pub selected_theme_id: String,
/// Set to `true` once the achievement-onboarding info-toast has been
/// shown to the player after their very first win. Acts as a
/// one-shot teach: subsequent wins must not re-fire the cue. Older
/// `settings.json` files written before this field existed
/// deserialize cleanly to `false` thanks to `#[serde(default)]` —
/// players who already had wins recorded before this field was
/// introduced are guarded by the post-condition `games_won == 1`
/// checked by `achievement_plugin::fire_achievement_onboarding_toast`,
/// so the toast still does not fire for them.
#[serde(default)]
pub shown_achievement_onboarding: bool,
/// Hover delay (seconds) before a tooltip appears. Range
/// `[0.0, 1.5]`; default matches `MOTION_TOOLTIP_DELAY_SECS` (0.5 s).
/// `0.0` means tooltips fire on the very next tick after hover —
/// the "Instant" setting. Older `settings.json` files written before
/// this field existed deserialize cleanly to the default via
/// `#[serde(default = "default_tooltip_delay")]`.
#[serde(default = "default_tooltip_delay")]
pub tooltip_delay_secs: f32,
} }
fn default_draw_mode() -> DrawMode { fn default_draw_mode() -> DrawMode {
@@ -138,6 +165,30 @@ fn default_music_volume() -> f32 {
0.5 0.5
} }
fn default_theme_id() -> String {
"default".to_string()
}
/// Default tooltip-hover dwell delay in seconds. Mirrors
/// `solitaire_engine::ui_theme::MOTION_TOOLTIP_DELAY_SECS` so legacy
/// `settings.json` files load to the existing baseline. The constant
/// lives in the engine crate (which the data crate cannot depend on),
/// so the value is duplicated here — kept in sync by the
/// `settings_tooltip_delay_default_is_existing_baseline` test in
/// `solitaire_engine::settings_plugin`.
fn default_tooltip_delay() -> f32 {
0.5
}
/// Lower bound of the player-tunable tooltip delay slider, in seconds.
pub const TOOLTIP_DELAY_MIN_SECS: f32 = 0.0;
/// Upper bound of the player-tunable tooltip delay slider, in seconds.
pub const TOOLTIP_DELAY_MAX_SECS: f32 = 1.5;
/// Increment applied by the tooltip-delay decrement / increment buttons.
pub const TOOLTIP_DELAY_STEP_SECS: f32 = 0.1;
impl Default for Settings { impl Default for Settings {
fn default() -> Self { fn default() -> Self {
Self { Self {
@@ -152,17 +203,24 @@ impl Default for Settings {
first_run_complete: false, first_run_complete: false,
color_blind_mode: false, color_blind_mode: false,
window_geometry: None, window_geometry: None,
selected_theme_id: default_theme_id(),
shown_achievement_onboarding: false,
tooltip_delay_secs: default_tooltip_delay(),
} }
} }
} }
impl Settings { impl Settings {
/// Clamps both `sfx_volume` and `music_volume` into `[0.0, 1.0]` after /// Clamps `sfx_volume`, `music_volume`, and `tooltip_delay_secs` into
/// deserialization or hand-editing of `settings.json`. /// their respective ranges after deserialization or hand-editing of
/// `settings.json`.
pub fn sanitized(self) -> Self { pub fn sanitized(self) -> Self {
Self { Self {
sfx_volume: self.sfx_volume.clamp(0.0, 1.0), sfx_volume: self.sfx_volume.clamp(0.0, 1.0),
music_volume: self.music_volume.clamp(0.0, 1.0), music_volume: self.music_volume.clamp(0.0, 1.0),
tooltip_delay_secs: self
.tooltip_delay_secs
.clamp(TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_MAX_SECS),
..self ..self
} }
} }
@@ -178,6 +236,15 @@ impl Settings {
self.music_volume = (self.music_volume + delta).clamp(0.0, 1.0); self.music_volume = (self.music_volume + delta).clamp(0.0, 1.0);
self.music_volume self.music_volume
} }
/// Adjust the tooltip-hover dwell delay by `delta` seconds, clamped
/// to `[TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_MAX_SECS]`. Returns the
/// new value.
pub fn adjust_tooltip_delay(&mut self, delta: f32) -> f32 {
self.tooltip_delay_secs = (self.tooltip_delay_secs + delta)
.clamp(TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_MAX_SECS);
self.tooltip_delay_secs
}
} }
/// Returns the platform-specific path to `settings.json`, or `None` if /// Returns the platform-specific path to `settings.json`, or `None` if
@@ -228,6 +295,7 @@ mod tests {
assert_eq!(s.animation_speed, AnimSpeed::Normal); assert_eq!(s.animation_speed, AnimSpeed::Normal);
assert_eq!(s.theme, Theme::Green); assert_eq!(s.theme, Theme::Green);
assert_eq!(s.sync_backend, SyncBackend::Local); assert_eq!(s.sync_backend, SyncBackend::Local);
assert!((s.tooltip_delay_secs - default_tooltip_delay()).abs() < 1e-6);
} }
#[test] #[test]
@@ -304,6 +372,9 @@ mod tests {
first_run_complete: true, first_run_complete: true,
color_blind_mode: false, color_blind_mode: false,
window_geometry: None, window_geometry: None,
selected_theme_id: "default".to_string(),
shown_achievement_onboarding: false,
tooltip_delay_secs: default_tooltip_delay(),
}; };
save_settings_to(&path, &s).expect("save"); save_settings_to(&path, &s).expect("save");
let loaded = load_settings_from(&path); let loaded = load_settings_from(&path);
@@ -492,4 +563,130 @@ mod tests {
let s: Settings = serde_json::from_slice(json).unwrap_or_default(); let s: Settings = serde_json::from_slice(json).unwrap_or_default();
assert!(s.window_geometry.is_none()); assert!(s.window_geometry.is_none());
} }
// -----------------------------------------------------------------------
// shown_achievement_onboarding — first-win cue one-shot guard
// -----------------------------------------------------------------------
#[test]
fn settings_shown_achievement_onboarding_default_is_false() {
assert!(
!Settings::default().shown_achievement_onboarding,
"default shown_achievement_onboarding must be false so the cue fires once"
);
}
#[test]
fn settings_shown_achievement_onboarding_round_trip() {
let path = tmp_path("achievement_onboarding_round_trip");
let _ = fs::remove_file(&path);
let s = Settings {
shown_achievement_onboarding: true,
..Settings::default()
};
save_settings_to(&path, &s).expect("save");
let loaded = load_settings_from(&path);
assert!(
loaded.shown_achievement_onboarding,
"shown_achievement_onboarding must survive serde round-trip"
);
let _ = fs::remove_file(&path);
}
#[test]
fn legacy_settings_without_shown_achievement_onboarding_deserializes_to_false() {
// A settings.json written by an older version of the game will be
// missing this field entirely. `#[serde(default)]` on the field
// must yield `false` — the cue then fires on the next win, but
// only when stats.games_won == 1, so existing players who have
// already won past their first game won't see the toast either.
let json = br#"{ "sfx_volume": 0.7, "first_run_complete": true }"#;
let s: Settings = serde_json::from_slice(json).unwrap_or_default();
assert!(
!s.shown_achievement_onboarding,
"legacy settings.json missing shown_achievement_onboarding must deserialize to false"
);
}
// -----------------------------------------------------------------------
// tooltip_delay_secs — player-tunable tooltip hover delay
// -----------------------------------------------------------------------
#[test]
fn settings_tooltip_delay_default_is_existing_baseline() {
// The existing baseline pre-slider is 0.5 s, matching the
// `MOTION_TOOLTIP_DELAY_SECS` constant in
// `solitaire_engine::ui_theme`. The default must not regress.
let s = Settings::default();
assert!(
(s.tooltip_delay_secs - 0.5).abs() < 1e-6,
"tooltip_delay_secs default must be 0.5 (the pre-slider baseline), got {}",
s.tooltip_delay_secs
);
}
#[test]
fn settings_tooltip_delay_round_trip() {
let path = tmp_path("tooltip_delay_round_trip");
let _ = fs::remove_file(&path);
let s = Settings {
tooltip_delay_secs: 1.2,
..Settings::default()
};
save_settings_to(&path, &s).expect("save");
let loaded = load_settings_from(&path);
assert!(
(loaded.tooltip_delay_secs - 1.2).abs() < 1e-6,
"tooltip_delay_secs must survive serde round-trip; got {}",
loaded.tooltip_delay_secs
);
let _ = fs::remove_file(&path);
}
#[test]
fn legacy_settings_without_tooltip_delay_deserializes_to_default() {
// A settings.json written before this field existed must
// deserialize cleanly to the existing 0.5 s baseline rather
// than failing the whole load or yielding a zero value.
let json = br#"{ "sfx_volume": 0.7, "first_run_complete": true }"#;
let s: Settings = serde_json::from_slice(json).unwrap_or_default();
assert!(
(s.tooltip_delay_secs - default_tooltip_delay()).abs() < 1e-6,
"legacy settings.json missing tooltip_delay_secs must deserialize to default ({}), got {}",
default_tooltip_delay(),
s.tooltip_delay_secs
);
}
#[test]
fn adjust_tooltip_delay_clamps_to_range() {
let mut s = Settings { tooltip_delay_secs: 0.5, ..Default::default() };
// Step up to 0.6.
assert!((s.adjust_tooltip_delay(0.1) - 0.6).abs() < 1e-6);
// Big positive jump clamps to TOOLTIP_DELAY_MAX_SECS.
assert!((s.adjust_tooltip_delay(5.0) - TOOLTIP_DELAY_MAX_SECS).abs() < 1e-6);
// Big negative jump clamps to TOOLTIP_DELAY_MIN_SECS.
assert!((s.adjust_tooltip_delay(-99.0) - TOOLTIP_DELAY_MIN_SECS).abs() < 1e-6);
// Confirm the floor is exactly zero.
assert_eq!(s.tooltip_delay_secs, 0.0);
}
#[test]
fn sanitized_clamps_out_of_range_tooltip_delay() {
// Negative or oversized values from a hand-edited file must be
// clamped on load.
let s = Settings {
tooltip_delay_secs: -0.4,
..Settings::default()
}
.sanitized();
assert_eq!(s.tooltip_delay_secs, TOOLTIP_DELAY_MIN_SECS);
let s2 = Settings {
tooltip_delay_secs: 99.0,
..Settings::default()
}
.sanitized();
assert_eq!(s2.tooltip_delay_secs, TOOLTIP_DELAY_MAX_SECS);
}
} }
+58 -2
View File
@@ -7,7 +7,7 @@ use std::fs;
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use solitaire_core::game_state::GameState; use solitaire_core::game_state::{GameState, GAME_STATE_SCHEMA_VERSION};
use crate::stats::StatsSnapshot; use crate::stats::StatsSnapshot;
@@ -72,10 +72,21 @@ pub fn game_state_file_path() -> Option<PathBuf> {
} }
/// Load an in-progress `GameState` from `path`. Returns `None` if the file is /// Load an in-progress `GameState` from `path`. Returns `None` if the file is
/// missing, corrupt, or represents a finished game. /// missing, corrupt, represents a finished game, or carries a save-schema
/// version other than [`GAME_STATE_SCHEMA_VERSION`].
///
/// Schema mismatch is treated as "no save" so a player upgrading across an
/// incompatible game-state format change starts fresh instead of seeing a
/// half-loaded game (or a deserialiser error). v1 saves with the old
/// `Foundation(Suit)` key shape will fail to parse outright; any v1 saves
/// that happen to round-trip but report `schema_version: 1` are also rejected
/// here.
pub fn load_game_state_from(path: &Path) -> Option<GameState> { pub fn load_game_state_from(path: &Path) -> Option<GameState> {
let data = fs::read(path).ok()?; let data = fs::read(path).ok()?;
let gs: GameState = serde_json::from_slice(&data).ok()?; let gs: GameState = serde_json::from_slice(&data).ok()?;
if gs.schema_version != GAME_STATE_SCHEMA_VERSION {
return None;
}
if gs.is_won { if gs.is_won {
None None
} else { } else {
@@ -331,4 +342,49 @@ mod tests {
let tmp = path.with_extension("json.tmp"); let tmp = path.with_extension("json.tmp");
assert!(!tmp.exists(), ".tmp must be cleaned up after rename"); assert!(!tmp.exists(), ".tmp must be cleaned up after rename");
} }
/// Pre-v2 save files used `Foundation(Suit)` keys and either fail to
/// parse outright or surface a `schema_version: 1`. Either path must
/// produce `None` so the player launches into a fresh game.
///
/// Sibling assertion: the stats round-trip path is unaffected — only
/// the game-state schema bumped.
#[test]
fn save_format_v1_is_rejected() {
let path = gs_path("schema_v1");
let _ = fs::remove_file(&path);
// A pared-down v1 JSON literal: foundation pile keys use the old
// suit-tagged form and the file omits `schema_version` (so it
// deserialises with the default of 1). Even if a future change
// makes `Foundation(Suit)` parse-compatible, the schema-version
// gate keeps this case rejected.
let v1_json = r#"{
"piles": [
[{"Foundation": "Hearts"}, {"pile_type": {"Foundation": "Hearts"}, "cards": []}]
],
"draw_mode": "DrawOne",
"score": 0,
"move_count": 0,
"elapsed_seconds": 0,
"seed": 42,
"is_won": false,
"is_auto_completable": false,
"undo_count": 0,
"undo_stack": []
}"#;
fs::write(&path, v1_json).expect("write v1 fixture");
assert!(
load_game_state_from(&path).is_none(),
"v1 game_state.json must be rejected (parse failure or schema bump)",
);
// Sibling sanity: stats files are independent and still round-trip.
let stats_path = tmp_path("schema_unrelated_stats");
let _ = fs::remove_file(&stats_path);
save_stats_to(&stats_path, &StatsSnapshot::default()).expect("save stats");
let loaded = load_stats_from(&stats_path);
assert_eq!(loaded, StatsSnapshot::default());
}
} }
+9
View File
@@ -13,6 +13,15 @@ solitaire_sync = { workspace = true }
chrono = { workspace = true } chrono = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
usvg = { workspace = true }
resvg = { workspace = true }
tiny-skia = { workspace = true }
ron = { workspace = true }
dirs = { workspace = true }
zip = { workspace = true }
[dev-dependencies] [dev-dependencies]
async-trait = { workspace = true } async-trait = { workspace = true }
tempfile = { workspace = true }
@@ -0,0 +1,43 @@
# Default theme — provenance
This directory is the bundled-default card theme that ships embedded in
the binary via Bevy's `embedded_asset!` macro (see
`solitaire_engine/src/assets/sources.rs`). At runtime its files are
addressable as `embedded://solitaire_engine/assets/themes/default/...`.
## Current state (Phase 3)
The `theme.ron` manifest in this directory lists all 52 face slots plus
a back slot, but **the referenced SVG files do not yet exist**. The
manifest is intentionally a stub so that:
1. `embedded_asset!` has a real file to bundle (the manifest itself).
2. `ThemeManifest::validate` accepts the manifest (it requires all 52
faces to be listed by name).
3. The `embedded://` asset source can be source-registered and queried
without runtime errors during Phase 3.
The actual SVG art will be added when the project swaps in the
`hayeah/playing-cards-assets` artwork — see the implementation plan in
`/CARD_PLAN.md`. At that point, every `.svg` filename listed in
`theme.ron`'s `faces` map (and `back.svg`) must be added here, and each
new file needs a corresponding `embedded_asset!(app, ...)` call in
`solitaire_engine/src/assets/sources.rs::register_default_theme`.
## How to add files to the bundled default theme
For each new file you drop into this directory:
1. Drop the file under `solitaire_engine/assets/themes/default/`.
2. Add one line to `register_default_theme` in
`solitaire_engine/src/assets/sources.rs` of the form:
```rust
embedded_asset!(app, "../../assets/themes/default/<filename>");
```
(The path is relative to `sources.rs`, which lives in
`solitaire_engine/src/assets/`.)
3. Update this file with the licence and origin of the new asset.
## Licence
To be filled in once real artwork lands.
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Default theme card back — Solitaire Quest's midnight-purple palette.
Original work, MIT-licensed alongside the rest of this project.
Aspect 2:3 to match the face SVGs from hayeah/playing-cards-assets.
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 300" width="200" height="300">
<defs>
<pattern id="diamonds" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<rect x="0" y="0" width="20" height="20" fill="#1A0F2E"/>
<path d="M 10 0 L 20 10 L 10 20 L 0 10 Z"
fill="none" stroke="#3A2580" stroke-width="1"/>
<circle cx="10" cy="10" r="1" fill="#FFD23F"/>
</pattern>
</defs>
<!-- Outer card surface with a midnight-purple base + diamond lattice -->
<rect x="0" y="0" width="200" height="300" rx="12" ry="12" fill="#1A0F2E"/>
<rect x="6" y="6" width="188" height="288" rx="9" ry="9" fill="url(#diamonds)"/>
<!-- Bordered inset so the lattice has a clear edge -->
<rect x="14" y="14" width="172" height="272" rx="6" ry="6"
fill="none" stroke="#FFD23F" stroke-width="1.5" opacity="0.85"/>
<!-- Centred diamond medallion -->
<g transform="translate(100 150)">
<path d="M 0 -42 L 42 0 L 0 42 L -42 0 Z" fill="#2D1B69" stroke="#FFD23F" stroke-width="2"/>
<path d="M 0 -22 L 22 0 L 0 22 L -22 0 Z" fill="#3A2580" stroke="#FFD23F" stroke-width="1"/>
<circle cx="0" cy="0" r="4" fill="#FFD23F"/>
</g>
<!-- Corner pips picking up the magenta secondary accent so the back
still reads as part of the design system at a glance -->
<g fill="#FF6B9D">
<circle cx="22" cy="22" r="2.5"/>
<circle cx="178" cy="22" r="2.5"/>
<circle cx="22" cy="278" r="2.5"/>
<circle cx="178" cy="278" r="2.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,281 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="10_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/10_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 57.572834,25.099947 c 0,0 5.967372,-4.773898 5.967372,-11.392027 0,-3.8743954 -3.43972,-10.3065945 -11.392028,-10.3065945 -7.952308,0 -11.392028,6.4347116 -11.392028,10.3065945 0,6.618129 5.967373,11.392027 5.967373,11.392027 -6.62818,-5.163348 -18.444833,-1.638201 -18.444833,8.680956 0,5.16586 4.22113,10.849311 10.849311,10.849311 7.952308,0 11.392027,-8.680956 11.392027,-8.680956 0,0 1.010056,9.894531 -4.881939,15.191045 h 13.020178 c -5.891994,-5.294001 -4.881938,-15.191045 -4.881938,-15.191045 0,0 3.439718,8.680956 11.392027,8.680956 6.630693,0 10.849311,-5.685963 10.849311,-10.849311 0,-10.319157 -11.816654,-13.844304 -18.444833,-8.680956 z"
id="cl-9-8" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 57.110434,93.200747 c 0,0 5.967372,-4.773898 5.967372,-11.392027 0,-3.874396 -3.43972,-10.306594 -11.392028,-10.306594 -7.952308,0 -11.392028,6.434711 -11.392028,10.306594 0,6.618129 5.967373,11.392027 5.967373,11.392027 -6.62818,-5.163348 -18.444833,-1.638201 -18.444833,8.680953 0,5.16587 4.22113,10.84932 10.849311,10.84932 7.952308,0 11.392027,-8.68096 11.392027,-8.68096 0,0 1.010056,9.89453 -4.881939,15.19104 h 13.020178 c -5.891994,-5.294 -4.881938,-15.19104 -4.881938,-15.19104 0,0 3.439718,8.68096 11.392027,8.68096 6.630693,0 10.849311,-5.68597 10.849311,-10.84932 0,-10.319154 -11.816654,-13.844301 -18.444833,-8.680953 z"
id="cl-9-8-0" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 121.55789,24.926219 c 0,0 5.96737,-4.773898 5.96737,-11.392027 0,-3.8743954 -3.43971,-10.3065945 -11.39203,-10.3065945 -7.95231,0 -11.39202,6.4347116 -11.39202,10.3065945 0,6.618129 5.96737,11.392027 5.96737,11.392027 -6.62818,-5.163348 -18.444834,-1.638201 -18.444834,8.680956 0,5.16586 4.22113,10.849311 10.849304,10.849311 7.95231,0 11.39203,-8.680956 11.39203,-8.680956 0,0 1.01006,9.894531 -4.88193,15.191045 h 13.02017 c -5.89199,-5.294001 -4.88193,-15.191045 -4.88193,-15.191045 0,0 3.43971,8.680956 11.39202,8.680956 6.63069,0 10.84931,-5.685963 10.84931,-10.849311 0,-10.319157 -11.81665,-13.844304 -18.44483,-8.680956 z"
id="cl-9-8-9" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 121.55789,93.027019 c 0,0 5.96737,-4.773898 5.96737,-11.392028 0,-3.874395 -3.43971,-10.306593 -11.39203,-10.306593 -7.95231,0 -11.39202,6.434711 -11.39202,10.306593 0,6.61813 5.96737,11.392028 5.96737,11.392028 -6.62818,-5.163348 -18.444834,-1.638201 -18.444834,8.680951 0,5.16587 4.22113,10.84932 10.849304,10.84932 7.95231,0 11.39203,-8.68096 11.39203,-8.68096 0,0 1.01006,9.89453 -4.88193,15.19104 h 13.02017 c -5.89199,-5.294 -4.88193,-15.19104 -4.88193,-15.19104 0,0 3.43971,8.68096 11.39202,8.68096 6.63069,0 10.84931,-5.68597 10.84931,-10.84932 0,-10.319152 -11.81665,-13.844299 -18.44483,-8.680951 z"
id="cl-9-8-0-4" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 89.576798,59.281103 c 0,0 5.967372,-4.773897 5.967372,-11.392027 0,-3.874395 -3.43972,-10.306594 -11.392028,-10.306594 -7.952308,0 -11.392028,6.434712 -11.392028,10.306594 0,6.61813 5.967373,11.392027 5.967373,11.392027 -6.62818,-5.163347 -18.444833,-1.638201 -18.444833,8.680957 0,5.165859 4.22113,10.84931 10.849311,10.84931 7.952308,0 11.392027,-8.680956 11.392027,-8.680956 0,0 1.010056,9.894531 -4.881939,15.191045 h 13.020178 c -5.891994,-5.294001 -4.881938,-15.191045 -4.881938,-15.191045 0,0 3.439718,8.680956 11.392027,8.680956 6.63069,0 10.84931,-5.685963 10.84931,-10.84931 0,-10.319158 -11.816653,-13.844304 -18.444832,-8.680957 z"
id="cl-9-8-8" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 110.06258,217.80216 c 0,0 -5.96737,4.77391 -5.96737,11.39203 0,3.8744 3.43971,10.3066 11.39202,10.3066 7.95232,0 11.39203,-6.43471 11.39203,-10.3066 0,-6.61812 -5.96737,-11.39203 -5.96737,-11.39203 6.62818,5.16335 18.44483,1.6382 18.44483,-8.68095 0,-5.16586 -4.22112,-10.84931 -10.84931,-10.84931 -7.95231,0 -11.39202,8.68095 -11.39202,8.68095 0,0 -1.01006,-9.89453 4.88193,-15.19104 h -13.02017 c 5.89199,5.294 4.88193,15.19104 4.88193,15.19104 0,0 -3.43972,-8.68095 -11.39203,-8.68095 -6.630687,0 -10.849305,5.68596 -10.849305,10.84931 0,10.31915 11.816655,13.8443 18.444835,8.68095 z"
id="cl-9-8-4" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 110.70832,149.70136 c 0,0 -5.96737,4.77391 -5.96737,11.39203 0,3.8744 3.43971,10.3066 11.39202,10.3066 7.95232,0 11.39203,-6.43471 11.39203,-10.3066 0,-6.61812 -5.96737,-11.39203 -5.96737,-11.39203 6.62818,5.16335 18.44483,1.6382 18.44483,-8.68095 0,-5.16586 -4.22112,-10.84931 -10.84931,-10.84931 -7.95231,0 -11.39202,8.68095 -11.39202,8.68095 0,0 -1.01006,-9.89453 4.88193,-15.19104 h -13.02017 c 5.89199,5.294 4.88193,15.19104 4.88193,15.19104 0,0 -3.43972,-8.68095 -11.39203,-8.68095 -6.630687,0 -10.849305,5.68596 -10.849305,10.84931 0,10.31915 11.816655,13.8443 18.444835,8.68095 z"
id="cl-9-8-0-2" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 46.077633,217.97556 c 0,0 -5.967372,4.77391 -5.967372,11.39203 0,3.8744 3.43972,10.3066 11.392028,10.3066 7.952308,0 11.392028,-6.43471 11.392028,-10.3066 0,-6.61812 -5.967373,-11.39203 -5.967373,-11.39203 6.62818,5.16335 18.444833,1.6382 18.444833,-8.68095 0,-5.16586 -4.22113,-10.84931 -10.849311,-10.84931 -7.952308,0 -11.392027,8.68095 -11.392027,8.68095 0,0 -1.010056,-9.89453 4.881939,-15.19104 H 44.9922 c 5.891994,5.294 4.881938,15.19104 4.881938,15.19104 0,0 -3.439718,-8.68095 -11.392027,-8.68095 -6.630693,0 -10.849311,5.68596 -10.849311,10.84931 0,10.31915 11.816654,13.8443 18.444833,8.68095 z"
id="cl-9-8-9-6" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 46.261118,149.87509 c 0,0 -5.967372,4.77391 -5.967372,11.39203 0,3.8744 3.43972,10.3066 11.392028,10.3066 7.952308,0 11.392028,-6.43471 11.392028,-10.3066 0,-6.61812 -5.967373,-11.39203 -5.967373,-11.39203 6.62818,5.16335 18.444833,1.6382 18.444833,-8.68095 0,-5.16586 -4.22113,-10.84931 -10.849311,-10.84931 -7.952308,0 -11.392027,8.68095 -11.392027,8.68095 0,0 -1.010056,-9.89453 4.881939,-15.19104 H 45.175685 c 5.891994,5.294 4.881938,15.19104 4.881938,15.19104 0,0 -3.439718,-8.68095 -11.392027,-8.68095 -6.630693,0 -10.849311,5.68596 -10.849311,10.84931 0,10.31915 11.816654,13.8443 18.444833,8.68095 z"
id="cl-9-8-0-4-9" /><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-1.1621548"
y="27.170401"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="-1.1621548"
y="27.170401"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">1</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="11.000458"
y="27.499109"
id="text3038"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3040"
x="11.000458"
y="27.499109">0</tspan></text>
<path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 78.0698,183.9376 c 0,0 -5.96738,4.77389 -5.96738,11.39202 0,3.8744 3.43972,10.3066 11.39203,10.3066 7.95231,0 11.39203,-6.43471 11.39203,-10.3066 0,-6.61813 -5.96737,-11.39202 -5.96737,-11.39202 6.62818,5.16334 18.44483,1.6382 18.44483,-8.68096 0,-5.16586 -4.22113,-10.84931 -10.84931,-10.84931 -7.95231,0 -11.39203,8.68096 -11.39203,8.68096 0,0 -1.01005,-9.89454 4.88194,-15.19105 H 76.98436 c 5.892,5.294 4.88194,15.19105 4.88194,15.19105 0,0 -3.43972,-8.68096 -11.39203,-8.68096 -6.630688,0 -10.849308,5.68596 -10.849308,10.84931 0,10.31916 11.816658,13.8443 18.444838,8.68096 z"
id="cl-9-8-8-8" /><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-168.80901"
y="-216.22618"
id="text3788-0"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-6"
x="-168.80901"
y="-216.22618"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">1</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-156.64639"
y="-215.89748"
id="text3038-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3040-9"
x="-156.64639"
y="-215.89748">0</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="2_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/2_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">2</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">2</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-36.788386,-1.5311156)"
id="layer1-1-4-8"><path
id="cl-9-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,205.12954,245.27515)"
id="layer1-1-4-8-0"><path
id="cl-9-8-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="3_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/3_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">3</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">3</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-36.788386,-9.5311159)"
id="layer1-1-4-8"><path
id="cl-9-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,205.12954,253.27515)"
id="layer1-1-4-8-0"><path
id="cl-9-8-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-36.788386,60.169684)"
id="layer1-1-4-8-2"><path
id="cl-9-8-0"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

@@ -0,0 +1,230 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="4_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/4_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">4</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">4</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-67.188386,-1.5311156)"
id="layer1-1-4-8"><path
id="cl-9-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,174.72954,245.27515)"
id="layer1-1-4-8-0"><path
id="cl-9-8-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-9.1115857,-1.5311131)"
id="layer1-1-4-8-2"><path
id="cl-9-8-66"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,232.80634,245.27515)"
id="layer1-1-4-8-0-4"><path
id="cl-9-8-6-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 9.7 KiB

@@ -0,0 +1,238 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="5_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/5_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">5</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">5</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-67.188386,-1.5311156)"
id="layer1-1-4-8"><path
id="cl-9-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,174.72954,245.27515)"
id="layer1-1-4-8-0"><path
id="cl-9-8-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-9.1115857,-1.5311131)"
id="layer1-1-4-8-2"><path
id="cl-9-8-66"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,232.80634,245.27515)"
id="layer1-1-4-8-0-4"><path
id="cl-9-8-6-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-38.388386,61.769684)"
id="layer1-1-4-8-2-6"><path
id="cl-9-8-0"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 10 KiB

@@ -0,0 +1,244 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="6_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/6_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">6</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">6</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-63.988386,-9.5311159)"
id="layer1-1-4-8"><path
id="cl-9-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,177.92954,253.27515)"
id="layer1-1-4-8-0"><path
id="cl-9-8-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-63.988386,60.169684)"
id="layer1-1-4-8-2"><path
id="cl-9-8-0"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-11.20333,-9.7048439)"
id="layer1-1-4-8-8"><path
id="cl-9-8-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,230.7146,253.10142)"
id="layer1-1-4-8-0-2"><path
id="cl-9-8-6-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-11.20333,59.995956)"
id="layer1-1-4-8-2-6"><path
id="cl-9-8-0-4"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 11 KiB

@@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="7_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/7_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">7</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">7</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-63.988386,-27.131116)"
id="layer1-1-4-8"><path
id="cl-9-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,177.92954,269.27515)"
id="layer1-1-4-8-0"><path
id="cl-9-8-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-63.988386,63.369684)"
id="layer1-1-4-8-2"><path
id="cl-9-8-0"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-11.20333,-27.304844)"
id="layer1-1-4-8-8"><path
id="cl-9-8-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,230.7146,269.10142)"
id="layer1-1-4-8-0-2"><path
id="cl-9-8-6-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-11.20333,63.195956)"
id="layer1-1-4-8-2-6"><path
id="cl-9-8-0-4"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-38.055702,18.622356)"
id="layer1-1-4-8-6"><path
id="cl-9-8-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,260 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="8_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/8_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">8</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">8</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-63.988386,-27.131116)"
id="layer1-1-4-8"><path
id="cl-9-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,177.92954,269.27515)"
id="layer1-1-4-8-0"><path
id="cl-9-8-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-63.988386,63.369684)"
id="layer1-1-4-8-2"><path
id="cl-9-8-0"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-11.20333,-27.304844)"
id="layer1-1-4-8-8"><path
id="cl-9-8-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,230.7146,269.10142)"
id="layer1-1-4-8-0-2"><path
id="cl-9-8-6-6"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-11.20333,63.195956)"
id="layer1-1-4-8-2-6"><path
id="cl-9-8-0-4"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(2.5125778,0,0,2.5125778,-38.055702,18.622356)"
id="layer1-1-4-8-6"><path
id="cl-9-8-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><g
transform="matrix(-2.5125778,0,0,-2.5125778,204.43127,226.5922)"
id="layer1-1-4-8-6-8"><path
id="cl-9-8-8-8"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="9_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/9_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="117.62976"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="8.3105459"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="8.3105459"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">9</tspan></text>
<g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-158.86395"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-158.86395"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">9</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 57.572834,25.099947 c 0,0 5.967372,-4.773898 5.967372,-11.392027 0,-3.8743954 -3.43972,-10.3065945 -11.392028,-10.3065945 -7.952308,0 -11.392028,6.4347116 -11.392028,10.3065945 0,6.618129 5.967373,11.392027 5.967373,11.392027 -6.62818,-5.163348 -18.444833,-1.638201 -18.444833,8.680956 0,5.16586 4.22113,10.849311 10.849311,10.849311 7.952308,0 11.392027,-8.680956 11.392027,-8.680956 0,0 1.010056,9.894531 -4.881939,15.191045 h 13.020178 c -5.891994,-5.294001 -4.881938,-15.191045 -4.881938,-15.191045 0,0 3.439718,8.680956 11.392027,8.680956 6.630693,0 10.849311,-5.685963 10.849311,-10.849311 0,-10.319157 -11.816654,-13.844304 -18.444833,-8.680956 z"
id="cl-9-8" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 57.110434,93.200747 c 0,0 5.967372,-4.773898 5.967372,-11.392027 0,-3.874396 -3.43972,-10.306594 -11.392028,-10.306594 -7.952308,0 -11.392028,6.434711 -11.392028,10.306594 0,6.618129 5.967373,11.392027 5.967373,11.392027 -6.62818,-5.163348 -18.444833,-1.638201 -18.444833,8.680953 0,5.16587 4.22113,10.84932 10.849311,10.84932 7.952308,0 11.392027,-8.68096 11.392027,-8.68096 0,0 1.010056,9.89453 -4.881939,15.19104 h 13.020178 c -5.891994,-5.294 -4.881938,-15.19104 -4.881938,-15.19104 0,0 3.439718,8.68096 11.392027,8.68096 6.630693,0 10.849311,-5.68597 10.849311,-10.84932 0,-10.319154 -11.816654,-13.844301 -18.444833,-8.680953 z"
id="cl-9-8-0" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 121.55789,24.926219 c 0,0 5.96737,-4.773898 5.96737,-11.392027 0,-3.8743954 -3.43971,-10.3065945 -11.39203,-10.3065945 -7.95231,0 -11.39202,6.4347116 -11.39202,10.3065945 0,6.618129 5.96737,11.392027 5.96737,11.392027 -6.62818,-5.163348 -18.444834,-1.638201 -18.444834,8.680956 0,5.16586 4.22113,10.849311 10.849304,10.849311 7.95231,0 11.39203,-8.680956 11.39203,-8.680956 0,0 1.01006,9.894531 -4.88193,15.191045 h 13.02017 c -5.89199,-5.294001 -4.88193,-15.191045 -4.88193,-15.191045 0,0 3.43971,8.680956 11.39202,8.680956 6.63069,0 10.84931,-5.685963 10.84931,-10.849311 0,-10.319157 -11.81665,-13.844304 -18.44483,-8.680956 z"
id="cl-9-8-9" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 121.55789,93.027019 c 0,0 5.96737,-4.773898 5.96737,-11.392028 0,-3.874395 -3.43971,-10.306593 -11.39203,-10.306593 -7.95231,0 -11.39202,6.434711 -11.39202,10.306593 0,6.61813 5.96737,11.392028 5.96737,11.392028 -6.62818,-5.163348 -18.444834,-1.638201 -18.444834,8.680951 0,5.16587 4.22113,10.84932 10.849304,10.84932 7.95231,0 11.39203,-8.68096 11.39203,-8.68096 0,0 1.01006,9.89453 -4.88193,15.19104 h 13.02017 c -5.89199,-5.294 -4.88193,-15.19104 -4.88193,-15.19104 0,0 3.43971,8.68096 11.39202,8.68096 6.63069,0 10.84931,-5.68597 10.84931,-10.84932 0,-10.319152 -11.81665,-13.844299 -18.44483,-8.680951 z"
id="cl-9-8-0-4" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 89.576544,59.281103 c 0,0 5.967372,-4.773897 5.967372,-11.392027 0,-3.874395 -3.43972,-10.306594 -11.392028,-10.306594 -7.952308,0 -11.392028,6.434712 -11.392028,10.306594 0,6.61813 5.967373,11.392027 5.967373,11.392027 C 72.099053,54.117756 60.2824,57.642902 60.2824,67.96206 c 0,5.165859 4.22113,10.84931 10.849311,10.84931 7.952308,0 11.392027,-8.680956 11.392027,-8.680956 0,0 1.010056,9.894531 -4.881939,15.191045 h 13.020178 c -5.891994,-5.294001 -4.881938,-15.191045 -4.881938,-15.191045 0,0 3.439718,8.680956 11.392027,8.680956 6.630694,0 10.849314,-5.685963 10.849314,-10.84931 0,-10.319158 -11.816657,-13.844304 -18.444836,-8.680957 z"
id="cl-9-8-8" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 110.06258,217.80216 c 0,0 -5.96737,4.77391 -5.96737,11.39203 0,3.8744 3.43971,10.3066 11.39202,10.3066 7.95232,0 11.39203,-6.43471 11.39203,-10.3066 0,-6.61812 -5.96737,-11.39203 -5.96737,-11.39203 6.62818,5.16335 18.44483,1.6382 18.44483,-8.68095 0,-5.16586 -4.22112,-10.84931 -10.84931,-10.84931 -7.95231,0 -11.39202,8.68095 -11.39202,8.68095 0,0 -1.01006,-9.89453 4.88193,-15.19104 h -13.02017 c 5.89199,5.294 4.88193,15.19104 4.88193,15.19104 0,0 -3.43972,-8.68095 -11.39203,-8.68095 -6.630687,0 -10.849305,5.68596 -10.849305,10.84931 0,10.31915 11.816655,13.8443 18.444835,8.68095 z"
id="cl-9-8-4" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 110.70832,149.70136 c 0,0 -5.96737,4.77391 -5.96737,11.39203 0,3.8744 3.43971,10.3066 11.39202,10.3066 7.95232,0 11.39203,-6.43471 11.39203,-10.3066 0,-6.61812 -5.96737,-11.39203 -5.96737,-11.39203 6.62818,5.16335 18.44483,1.6382 18.44483,-8.68095 0,-5.16586 -4.22112,-10.84931 -10.84931,-10.84931 -7.95231,0 -11.39202,8.68095 -11.39202,8.68095 0,0 -1.01006,-9.89453 4.88193,-15.19104 h -13.02017 c 5.89199,5.294 4.88193,15.19104 4.88193,15.19104 0,0 -3.43972,-8.68095 -11.39203,-8.68095 -6.630687,0 -10.849305,5.68596 -10.849305,10.84931 0,10.31915 11.816655,13.8443 18.444835,8.68095 z"
id="cl-9-8-0-2" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 46.077528,217.97589 c 0,0 -5.967372,4.77391 -5.967372,11.39203 0,3.8744 3.43972,10.3066 11.392028,10.3066 7.952308,0 11.392028,-6.43471 11.392028,-10.3066 0,-6.61812 -5.967373,-11.39203 -5.967373,-11.39203 6.62818,5.16335 18.444833,1.6382 18.444833,-8.68095 0,-5.16586 -4.22113,-10.84931 -10.849311,-10.84931 -7.952308,0 -11.392027,8.68095 -11.392027,8.68095 0,0 -1.010056,-9.89453 4.881939,-15.19104 H 44.992095 c 5.891994,5.294 4.881938,15.19104 4.881938,15.19104 0,0 -3.439718,-8.68095 -11.392027,-8.68095 -6.630693,0 -10.849311,5.68596 -10.849311,10.84931 0,10.31915 11.816654,13.8443 18.444833,8.68095 z"
id="cl-9-8-9-6" /><path
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 46.261118,149.87509 c 0,0 -5.967372,4.77391 -5.967372,11.39203 0,3.8744 3.43972,10.3066 11.392028,10.3066 7.952308,0 11.392028,-6.43471 11.392028,-10.3066 0,-6.61812 -5.967373,-11.39203 -5.967373,-11.39203 6.62818,5.16335 18.444833,1.6382 18.444833,-8.68095 0,-5.16586 -4.22113,-10.84931 -10.849311,-10.84931 -7.952308,0 -11.392027,8.68095 -11.392027,8.68095 0,0 -1.010056,-9.89453 4.881939,-15.19104 H 45.175685 c 5.891994,5.294 4.881938,15.19104 4.881938,15.19104 0,0 -3.439718,-8.68095 -11.392027,-8.68095 -6.630693,0 -10.849311,5.68596 -10.849311,10.84931 0,10.31915 11.816654,13.8443 18.444833,8.68095 z"
id="cl-9-8-0-4-9" /></svg>

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,258 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="A_of_clubs.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/A_of_clubs.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3760"
cx="48.231091"
cy="18.137882"
fx="48.231091"
fy="18.137882"
r="9.5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.5605256,0.01828294,-0.02684055,-2.2909528,123.98377,58.809108)" /><linearGradient
id="linearGradient2984"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#000000;stop-opacity:0.65648854;"
offset="1"
id="stop2988" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784"
id="radialGradient3792"
cx="171.48665"
cy="511.22299"
fx="171.48665"
fy="511.22299"
r="81.902771"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3784"><stop
style="stop-color:#ffffff;stop-opacity:0.53435117;"
offset="0"
id="stop3786" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788" /></linearGradient><filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
id="filter3834"
x="-0.13934441"
width="1.2786888"
y="-0.16242018"
height="1.3248404"><feGaussianBlur
inkscape:collect="always"
stdDeviation="9.5105772"
id="feGaussianBlur3836" /></filter><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3855"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.51908398;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
id="filter3834-6"
x="-0.13934441"
width="1.2786888"
y="-0.16242018"
height="1.3248404"><feGaussianBlur
inkscape:collect="always"
stdDeviation="9.5105772"
id="feGaussianBlur3836-6" /></filter><radialGradient
r="81.902771"
fy="461.84113"
fx="181.69392"
cy="461.84113"
cx="181.69392"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3916"
xlink:href="#linearGradient3784-3"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-3"><stop
style="stop-color:#ffffff;stop-opacity:0.70229006;"
offset="0"
id="stop3786-86" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-2" /></linearGradient><filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
id="filter3834-7"
x="-0.13934441"
width="1.2786888"
y="-0.16242018"
height="1.3248404"><feGaussianBlur
inkscape:collect="always"
stdDeviation="9.5105772"
id="feGaussianBlur3836-0" /></filter></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="2.4336873"
inkscape:cx="188.71531"
inkscape:cy="148.16686"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="6.7105455"
y="27.548409"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="6.7105455"
y="27.548409"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">A</tspan></text>
<g
transform="matrix(0.20614599,0,0,0.20614599,8.8705463,16.512759)"
id="g3804"><g
id="layer1-1"
transform="matrix(28.969925,0,0,28.969925,-1031.5368,-187.37665)"><path
style="fill:url(#radialGradient3760);fill-opacity:1"
inkscape:connector-curvature="0"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
id="cl" /></g><path
transform="matrix(1.1091261,0,0,1.2071687,-37.349149,-111.34227)"
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path3762"
d="m 117.3013,604.26609 c 0,0 -8.06755,-94.94997 22.85715,-122.85714 34.76052,-31.36871 140,-11.42857 140,-11.42857 0,0 -71.5404,24.83762 -100,48.57143 -27.21033,22.69199 -62.85715,85.71428 -62.85715,85.71428 z"
style="fill:url(#radialGradient3792);fill-opacity:1;stroke:none;filter:url(#filter3834)" /><path
transform="matrix(1.1091261,0,0,1.2071687,117.2523,-332.26545)"
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path3762-6"
d="m 117.3013,604.26609 c 0,0 -8.06755,-94.94997 22.85715,-122.85714 34.76052,-31.36871 140,-11.42857 140,-11.42857 0,0 -71.5404,24.83762 -100,48.57143 -27.21033,22.69199 -62.85715,85.71428 -62.85715,85.71428 z"
style="fill:url(#radialGradient3855);fill-opacity:1;stroke:none;filter:url(#filter3834-6)" /><path
transform="matrix(1.1420384,0.7029084,-0.84188482,1.367838,729.37187,-305.07466)"
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path3762-7"
d="m 117.3013,604.26609 c 0,0 -8.06755,-94.94997 22.85715,-122.85714 34.76052,-31.36871 140,-11.42857 140,-11.42857 0,0 -71.5404,24.83762 -100,48.57143 -27.21033,22.69199 -62.85715,85.71428 -62.85715,85.71428 z"
style="fill:url(#radialGradient3916);fill-opacity:1;stroke:none;filter:url(#filter3834-7)" /><path
id="rect3015"
d="m 28.355532,122.02522 0,734.28125 667.156248,0 0,-734.28125 -667.156248,0 z m 334.281258,97.625 c 91.68979,0 131.37499,74.17213 131.37499,118.84375 0,76.30678 -68.8125,131.34375 -68.8125,131.34375 76.42266,-59.5332 212.65625,-18.88573 212.65625,100.09375 0,59.5332 -48.64211,125.09375 -125.09375,125.09375 -91.68982,0 -131.34374,-100.09375 -131.34374,-100.09375 0,0 -11.65322,114.11662 56.28124,175.15625 l -150.12499,0 c 67.93447,-61.0686 56.3125,-175.15625 56.3125,-175.15625 0,0 -39.65394,100.09375 -131.34375,100.09375 -76.42266,0 -125.093758,-65.53158 -125.093758,-125.09375 0,-118.97948 136.233598,-159.62695 212.656258,-100.09375 0,0 -68.8125,-55.03697 -68.8125,-131.34375 0,-44.64265 39.65394,-118.84375 131.34375,-118.84375 z"
style="fill:#fffeff;fill-opacity:1;fill-rule:nonzero;stroke:none"
inkscape:connector-curvature="0" /></g><g
transform="matrix(1.4856506,0,0,1.4856506,-54.024661,10.018072)"
id="layer1-1-4"><path
id="cl-9"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-160.46396"
y="-214.4666"
id="text3788-8"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-7"
x="-160.46396"
y="-214.4666"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial">A</tspan></text>
<g
transform="matrix(-1.4856506,0,0,-1.4856506,221.19916,232.46182)"
id="layer1-1-4-1"><path
id="cl-9-7"
d="m 50.291466,22.698228 c 0,0 2.375,-1.9 2.375,-4.534 0,-1.542 -1.369,-4.102 -4.534,-4.102 -3.165,0 -4.534,2.561 -4.534,4.102 0,2.634 2.375,4.534 2.375,4.534 -2.638,-2.055 -7.341,-0.652 -7.341,3.455 0,2.056 1.68,4.318 4.318,4.318 3.165,0 4.534,-3.455 4.534,-3.455 0,0 0.402,3.938 -1.943,6.046 h 5.182 c -2.345,-2.107 -1.943,-6.046 -1.943,-6.046 0,0 1.369,3.455 4.534,3.455 2.639,0 4.318,-2.263 4.318,-4.318 0,-4.107 -4.703,-5.51 -7.341,-3.455 z"
inkscape:connector-curvature="0"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 450 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 MiB

@@ -0,0 +1,401 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="10_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/10_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="0.4075976"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="0.4075976"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">1</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,210.91474)"
id="layer1-2-6-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,31.619539)"
id="layer1-2-6-8-2-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,151.18274)"
id="layer1-2-6-8-2-8-1"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,91.351539)"
id="layer1-2-6-8-2-8-1-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,210.91474)"
id="layer1-2-6-8-8-9"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8-4"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,31.619552)"
id="layer1-2-6-8-2-4-9"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-0"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,151.18274)"
id="layer1-2-6-8-2-8-1-9"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4-1"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,91.351542)"
id="layer1-2-6-8-2-8-1-4-7"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4-9-7"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,83.213394,61.828949)"
id="layer1-2-6-8-2-4-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-5"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,83.008034,180.83805)"
id="layer1-2-6-8-2-4-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-5-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="13.216442"
y="26.376137"
id="text3788-43"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790-1"
x="13.216442"
y="26.376137"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">0</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-166.43544"
y="-215.98416"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-9"
x="-166.43544"
y="-215.98416"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">1</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-153.62659"
y="-216.0213"
id="text3788-43-2"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-1-0"
x="-153.62659"
y="-216.0213"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">0</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

@@ -0,0 +1,318 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="2_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/2_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
id="filter3834-6-0"
x="-0.13934441"
width="1.2786888"
y="-0.16242018"
height="1.3248404"><feGaussianBlur
inkscape:collect="always"
stdDeviation="9.5105772"
id="feGaussianBlur3836-6-6" /></filter><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">2</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">2</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,82.928726,184.02194)"
id="layer1-2-6-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,82.928726,55.619539)"
id="layer1-2-6-8-2"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,319 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="3_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/3_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">3</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">3</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,82.928726,192.02194)"
id="layer1-2-6-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,82.928726,50.819539)"
id="layer1-2-6-8-2"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,82.928726,120.52034)"
id="layer1-2-6-8-2-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,324 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="4_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/4_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">4</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">4</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.20553,184.02194)"
id="layer1-2-6-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.20553,55.619539)"
id="layer1-2-6-8-2"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,184.02194)"
id="layer1-2-6-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,55.619539)"
id="layer1-2-6-8-2-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,333 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="5_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/5_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">5</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">5</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.20553,184.02194)"
id="layer1-2-6-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.20553,55.619539)"
id="layer1-2-6-8-2"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,184.02194)"
id="layer1-2-6-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,55.619539)"
id="layer1-2-6-8-2-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,82.283636,119.47398)"
id="layer1-2-6-8-2-4-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,340 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="6_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/6_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">6</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">6</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,110.12873,192.02194)"
id="layer1-2-6-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,110.12873,50.819539)"
id="layer1-2-6-8-2"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,110.12873,120.52034)"
id="layer1-2-6-8-2-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,56.013391,192.14005)"
id="layer1-2-6-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,56.013391,50.937663)"
id="layer1-2-6-8-2-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,56.013391,120.63845)"
id="layer1-2-6-8-2-8-1"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,349 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="7_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/7_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">7</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">7</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,111.72873,193.62194)"
id="layer1-2-6-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,111.72873,49.219539)"
id="layer1-2-6-8-2"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,111.72873,120.52034)"
id="layer1-2-6-8-2-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.413391,193.74005)"
id="layer1-2-6-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.413391,49.337663)"
id="layer1-2-6-8-2-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.413391,120.63845)"
id="layer1-2-6-8-2-8-1"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,83.213393,85.53779)"
id="layer1-2-6-8-2-4-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,358 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="8_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/8_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">8</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">8</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,111.72873,193.62194)"
id="layer1-2-6-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,111.72873,49.219539)"
id="layer1-2-6-8-2"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,111.72873,120.52034)"
id="layer1-2-6-8-2-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.413391,193.74005)"
id="layer1-2-6-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.413391,49.337663)"
id="layer1-2-6-8-2-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.413391,120.63845)"
id="layer1-2-6-8-2-8-1"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,83.213393,85.53779)"
id="layer1-2-6-8-2-4-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,83.21339,156.92384)"
id="layer1-2-6-8-8-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,367 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="9_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/9_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="7.8456664"
y="26.413288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="7.8456664"
y="26.413288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">9</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-159.48785"
y="-216.71518"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-159.48785"
y="-216.71518"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">9</tspan></text>
<g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,210.91474)"
id="layer1-2-6-8-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,31.619539)"
id="layer1-2-6-8-2-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,151.18274)"
id="layer1-2-6-8-2-8-1"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,54.128726,91.351539)"
id="layer1-2-6-8-2-8-1-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,210.91474)"
id="layer1-2-6-8-8-9"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-8-4"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,31.619552)"
id="layer1-2-6-8-2-4-9"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-0"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,151.18274)"
id="layer1-2-6-8-2-8-1-9"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4-1"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,112.89593,91.351542)"
id="layer1-2-6-8-2-8-1-4-7"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-8-4-9-7"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(2.5882908,0,0,2.5882908,83.213394,61.828949)"
id="layer1-2-6-8-2-4-8"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-8-6-3-5"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,311 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- http://code.google.com/p/vector-playing-cards/ -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="167.0869141pt"
height="242.6669922pt"
viewBox="0 0 167.0869141 242.6669922"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="ace_of_diamonds.svg"
inkscape:export-filename="/home/byron/art/cards/final/PNGs/ace_of_diamonds.png"
inkscape:export-xdpi="215.44792"
inkscape:export-ydpi="215.44792"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs41"><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3781"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3773"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3775" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3777" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3773"
id="radialGradient3957"
cx="-0.15782039"
cy="-8.8345356"
fx="-0.15782039"
fy="-8.8345356"
r="7.9997029"
gradientTransform="matrix(-1.5842693,-0.02349808,0.03071979,-2.4775745,-0.24856378,-26.713507)"
gradientUnits="userSpaceOnUse" /><linearGradient
id="linearGradient3959"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3961" /><stop
style="stop-color:#000000;stop-opacity:0.64885497;"
offset="1"
id="stop3963" /></linearGradient><radialGradient
r="81.902771"
fy="509.47577"
fx="168.02475"
cy="509.47577"
cx="168.02475"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
gradientUnits="userSpaceOnUse"
id="radialGradient3975"
xlink:href="#linearGradient3784-4"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-5"
id="radialGradient3929"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-5"><stop
style="stop-color:#ffffff;stop-opacity:0.48854962;"
offset="0"
id="stop3786-8-0" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-3" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3784-4-1"
id="radialGradient3927"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2565605,-0.77740644,0.33663816,0.5361257,-221.20213,359.24256)"
cx="168.02475"
cy="509.47577"
fx="168.02475"
fy="509.47577"
r="81.902771" /><linearGradient
id="linearGradient3784-4-1"><stop
style="stop-color:#ffffff;stop-opacity:0.23664123;"
offset="0"
id="stop3786-8-03" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-6" /></linearGradient><linearGradient
id="linearGradient3768"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop3770" /><stop
style="stop-color:#df0000;stop-opacity:0.67175573;"
offset="1"
id="stop3772" /></linearGradient><linearGradient
id="linearGradient3784-4-6"><stop
style="stop-color:#ffffff;stop-opacity:0.31297711;"
offset="0"
id="stop3786-8-8" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-8" /></linearGradient><radialGradient
r="81.902771"
fy="492.63205"
fx="159.35434"
cy="492.63205"
cx="159.35434"
gradientTransform="matrix(1.0894779,-0.71513803,0.44645273,0.65626582,-244.93331,290.9185)"
gradientUnits="userSpaceOnUse"
id="radialGradient4013-8"
xlink:href="#linearGradient3784-4-2"
inkscape:collect="always" /><linearGradient
id="linearGradient3784-4-2"><stop
style="stop-color:#ffffff;stop-opacity:0.29007635;"
offset="0"
id="stop3786-8-1" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-5" /></linearGradient><linearGradient
id="linearGradient2984"><stop
style="stop-color:#df0000;stop-opacity:1;"
offset="0"
id="stop2986" /><stop
style="stop-color:#df0000;stop-opacity:0.64122134;"
offset="1"
id="stop2988" /></linearGradient><linearGradient
id="linearGradient3784-4-4"><stop
style="stop-color:#ffffff;stop-opacity:0.4351145;"
offset="0"
id="stop3786-8-8-2" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3788-6-1" /></linearGradient><filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
id="filter3834-6-0"
x="-0.13934441"
width="1.2786888"
y="-0.16242018"
height="1.3248404"><feGaussianBlur
inkscape:collect="always"
stdDeviation="9.5105772"
id="feGaussianBlur3836-6-6" /></filter><radialGradient
r="81.902771"
fy="511.22299"
fx="171.48665"
cy="511.22299"
cx="171.48665"
gradientTransform="matrix(1.1529891,-0.67391547,0.39482025,0.67549043,-233.63262,270.40076)"
gradientUnits="userSpaceOnUse"
id="radialGradient3100"
xlink:href="#linearGradient3784-4-4"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2984"
id="radialGradient3137"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1224159,0.00551393,-0.00908973,-1.8503101,-0.0293938,-10.227695)"
cx="1.6632675e-13"
cy="-3.2337365"
fx="1.6632675e-13"
fy="-3.2337365"
r="8" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="977"
id="namedview39"
showgrid="false"
inkscape:zoom="1.7208768"
inkscape:cx="72.124594"
inkscape:cy="147.27218"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
id="Layer_x0020_1"
style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<path
style="fill:#FFFFFF;stroke-width:0.5;"
d="M166.8369141,235.5478516c0,3.7773438-3.0869141,6.8691406-6.8710938,6.8691406H7.1108398c-3.7749023,0-6.8608398-3.0917969-6.8608398-6.8691406V7.1201172C0.25,3.3427734,3.3359375,0.25,7.1108398,0.25h152.8549805 c3.7841797,0,6.8710938,3.0927734,6.8710938,6.8701172v228.4277344z"
id="path5" />
<g
style="stroke:none;"
id="g7">
<g
id="g9">
</g>
</g>
<g
id="g15">
</g>
<g
id="g19">
</g>
<g
style="stroke:none;"
id="g23">
<g
id="g25">
</g>
</g>
<g
style="stroke:none;"
id="g31">
<g
id="g33">
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="6.2456665"
y="28.013288"
id="text3788"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3790"
x="6.2456665"
y="28.013288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;fill:#df0000;fill-opacity:1">A</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#df0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-161.08786"
y="-213.51517"
id="text3788-4"
sodipodi:linespacing="125%"
transform="scale(-1,-1)"><tspan
sodipodi:role="line"
id="tspan3790-3"
x="-161.08786"
y="-213.51517"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#df0000;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">A</tspan></text>
<g
transform="matrix(0.17001436,0,0,0.17001436,19.517107,29.794341)"
id="g3011"><g
id="layer1-2"
transform="matrix(35.005102,0,0,35.005102,369.18369,512.27289)"><path
sodipodi:nodetypes="ccccccccc"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
id="dl"
inkscape:connector-curvature="0"
style="fill:url(#radialGradient3137);fill-opacity:1" /></g><path
transform="matrix(-1.4652123,0.23694327,-0.24538129,-1.5173914,660.30624,1148.701)"
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path3762-6"
d="m 117.3013,604.26609 c 0,0 -8.06755,-94.94997 22.85715,-122.85714 34.76052,-31.36871 140,-11.42857 140,-11.42857 0,0 -71.5404,24.83762 -100,48.57143 -27.21033,22.69199 -62.85715,85.71428 -62.85715,85.71428 z"
style="fill:url(#radialGradient3100);fill-opacity:1;stroke:none;filter:url(#filter3834-6-0)" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,16.968095,44.236162)"
id="layer1-2-6"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g><g
transform="matrix(1.4769065,0,0,1.4769065,150.62089,198.50346)"
id="layer1-2-6-4"><path
style="fill:#df0000"
inkscape:connector-curvature="0"
id="dl-6-9"
d="M 3.2433274,-4.7253274 C 1.1263274,-7.5893274 0,-10.5 0,-10.5 c 0,0 -1.1263274,2.9106726 -3.2433274,5.7746726 C -5.3613274,-1.8623274 -8,0 -8,0 -8,0 -5.3613274,1.8613274 -3.2433274,4.7263274 -1.1263274,7.5893274 0,10.5 0,10.5 0,10.5 1.1263274,7.5893274 3.2433274,4.7263274 5.3613274,1.8613274 8,0 8,0 8,0 5.3613274,-1.8623274 3.2433274,-4.7253274 z"
sodipodi:nodetypes="ccccccccc" /></g></svg>

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 395 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 650 KiB

Some files were not shown because too many files have changed in this diff Show More