Add existing to tracked
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
# Side Cards — art direction
|
||||
|
||||
The approved visual reference is the J/Q/K of Hearts family in `concepts/`.
|
||||
Court figures are final raster illustrations generated locally with Draw Things;
|
||||
they are not hand-traced. `tools/build_deck.py` embeds each illustration inside
|
||||
a standalone SVG and adds dependable card geometry.
|
||||
|
||||
## Look
|
||||
|
||||
- Original Anglo-American court-card illustration
|
||||
- Crisp flat fills with strong black keylines
|
||||
- Traditional two-way composition
|
||||
- Ornate garments without photorealistic lighting or 3D rendering
|
||||
- Restrained red, black, gold, muted-blue and warm-skin palette
|
||||
- No generated rank letters, typography, logos or watermarks
|
||||
|
||||
Approximate palette sampled from the approved family:
|
||||
|
||||
| Role | Colour |
|
||||
|---|---|
|
||||
| Stock | `#fcfcfa` |
|
||||
| Keyline | `#0e0d0d` |
|
||||
| Red | `#a21b1e` |
|
||||
| Gold | `#b99a34` |
|
||||
| Muted blue | `#354c58` |
|
||||
| Skin | `#f0d2b6` |
|
||||
|
||||
These values guide generation; the raster art is not mechanically recoloured.
|
||||
|
||||
## Court family
|
||||
|
||||
| Rank | Figure | Prop |
|
||||
|---|---|---|
|
||||
| Jack | young knave, shoulder-length hair | upright halberd |
|
||||
| Queen | crowned queen | stylized flower |
|
||||
| King | mature bearded king, crowned | upright sword |
|
||||
|
||||
Diamonds emphasize angular red-and-gold ornament. Clubs and Spades emphasize
|
||||
black and muted blue with red-and-gold accents. All twelve should feel related,
|
||||
but they do not need identical faces or frames.
|
||||
|
||||
## Deterministic card elements
|
||||
|
||||
`tools/build_deck.py`, not the image model, owns:
|
||||
|
||||
- corner rank indices
|
||||
- suit marks and number-card pip layouts
|
||||
- one continuous inner court frame
|
||||
- final 5:7 card geometry
|
||||
- the outer card edge
|
||||
|
||||
The outer card and artwork clip use a 24-unit circular radius on the 500 x 700
|
||||
viewBox, equivalent to approximately 3.05 mm on a 63.5 x 88.9 mm poker card.
|
||||
The two-unit inset outline uses radius 22 so its curve remains concentric. The
|
||||
gallery expresses the same circular curve as `4.8% / 3.4286%`; a single CSS
|
||||
percentage would create an elliptical radius on a 5:7 element.
|
||||
|
||||
Rank indices use Roboto Slab SemiBold, converted to SVG outlines during the
|
||||
build without synthetic horizontal distortion. This provides large, clear slab
|
||||
forms without depending on an installed font. Roboto Slab is distributed under
|
||||
Apache License 2.0; the local license copy is
|
||||
`assets/fonts/RobotoSlab-Apache-2.0.txt`.
|
||||
|
||||
Rank outlines share a font baseline at y=85 and are sized from cap height,
|
||||
rather than top-aligned or fitted around descenders. This lets Q retain its
|
||||
natural tail and weight without a synthetic outline. Single ranks have a
|
||||
63-unit width allowance so the naturally wide A/K reach full cap height; the
|
||||
two-character `10` has 76 units so it also remains comparable.
|
||||
|
||||
Mini suits remain centred at y=127 and are optically scaled by silhouette
|
||||
(S 0.78, H 0.71, D 0.92, C 0.78), rather than being forced to one geometric
|
||||
scale. Their rendered footprints—not equal ink density—are checked as a group
|
||||
during the deck audit so dense marks are not made visually undersized.
|
||||
|
||||
The Heart is a purpose-drawn, classic silhouette with a pronounced cleft,
|
||||
distinct lobes, a near-square proportion, and a long sharp point. Number-card
|
||||
field pips are likewise optically balanced by suit (S 1.50, H 1.28, D 1.75,
|
||||
C 1.43).
|
||||
Ace and court marks have their own role-specific optical scales so each Ace
|
||||
carries comparable ink and the fuller Heart does not crowd a court figure.
|
||||
|
||||
The Club follows the familiar traditional card form rather than an equilateral
|
||||
trefoil: equal lower lobes sit wider and lower than the top lobe, a smaller
|
||||
central boss joins the three, and a short flared stem finishes the mark. Its
|
||||
required symmetry is bilateral, not three-fold rotational symmetry.
|
||||
|
||||
Generated suit pips are replaced with the correct SVG suit mark. Generated
|
||||
frame segments are locally inpainted out while the figure is extracted, then
|
||||
one continuous SVG frame is drawn behind the figure. The approved upper figure
|
||||
is rotated exactly 180 degrees for the lower end, with a symmetric blended join
|
||||
through the centre.
|
||||
|
||||
The assembly step also normalizes the generated figure envelope around the
|
||||
card centre using uniform scaling only: K♣/K♦ use 0.95 and K♥/K♠ use 0.97.
|
||||
Jacks and Queens remain at native scale. The resulting painted areas stay
|
||||
within roughly five percent without distorting faces or garments. Club and
|
||||
Spade field emblems receive a five-pixel optical shift away from the figure;
|
||||
their mirrored lower marks are derived from the same coordinates.
|
||||
|
||||
## Generation settings
|
||||
|
||||
- Model: `qwen_image_2512_bf16_i8x.ckpt`
|
||||
- Working size: 640×896
|
||||
- Sampler: DPMPP2MTrailing
|
||||
- Steps: 30
|
||||
- Guidance: 4.0
|
||||
- img2img strength: 0.68
|
||||
|
||||
The corresponding Heart card is the composition/style reference for every
|
||||
non-Heart court. Run `tools/render_court.py --remaining` to create missing
|
||||
renders without overwriting existing ones.
|
||||
|
||||
## Output sizes
|
||||
|
||||
No smallest production size has been chosen. The SVG cards scale freely; court
|
||||
illustrations remain 640×896 raster artwork inside them. If a future use needs
|
||||
large-format print, upscale or regenerate the courts for that real requirement.
|
||||
Do not build alternate thumbnail art until the game actually needs it.
|
||||
|
||||
`masters/queen-hearts.svg` is an archived hand-vector experiment and is not
|
||||
part of the current deck pipeline.
|
||||
@@ -0,0 +1,263 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 500 700" width="500" height="700">
|
||||
<title>Side Cards — Queen of Hearts (vector master)</title>
|
||||
<desc>
|
||||
Full-detail master. Card is 5:7 (500x700 user units); all geometry is
|
||||
proportional, so it scales to any output size.
|
||||
|
||||
Construction: only the UPPER half of the court figure exists
|
||||
(g#court-half). The lower half is a single <use> of it rotated
|
||||
exactly 180 degrees about the card centre (250,350). Never draw the lower
|
||||
half by hand — edit the upper half and the mirror follows, which is what
|
||||
guarantees identical faces, hands, ornament and line weight.
|
||||
|
||||
Editable groups: frame, indices, veil, garments, ornament, props,
|
||||
hair-back, face, hair-front, crown, keylines.
|
||||
|
||||
Palette is the six inks plus stock, defined once in the stylesheet below.
|
||||
Change an ink there and it changes everywhere.
|
||||
</desc>
|
||||
|
||||
<style>
|
||||
/* ---- palette: the only place colour is defined ---- */
|
||||
.ink { fill: #0e0d0d; } /* keyline black */
|
||||
.red { fill: #a21b1e; }
|
||||
.gold { fill: #b99a34; }
|
||||
.blue { fill: #354c58; }
|
||||
.skin { fill: #f0d2b6; }
|
||||
.stock { fill: #fcfcfa; } /* card stock / veil highlight */
|
||||
|
||||
.s-ink { stroke: #0e0d0d; }
|
||||
.s-gold { stroke: #b99a34; }
|
||||
|
||||
/* ---- line weights, proportional to the 500-unit card width ----
|
||||
Main keyline 3.0 = 0.60% of card width, inside the 0.47-0.62%
|
||||
measured on the concept family. Detail 1.6 = 0.32%. */
|
||||
.k { stroke: #0e0d0d; stroke-width: 3.0; stroke-linejoin: round;
|
||||
stroke-linecap: round; }
|
||||
.k-fine { stroke: #0e0d0d; stroke-width: 1.6; stroke-linejoin: round;
|
||||
stroke-linecap: round; fill: none; }
|
||||
.k-hair { stroke: #0e0d0d; stroke-width: 1.1; stroke-linecap: round;
|
||||
fill: none; }
|
||||
.no-fill { fill: none; }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<!-- Upper half only. The clip travels with the group, so the rotated
|
||||
instance is clipped to the lower half automatically. -->
|
||||
<clipPath id="clip-upper">
|
||||
<rect x="0" y="0" width="500" height="350"/>
|
||||
</clipPath>
|
||||
|
||||
<!-- suit symbol, drawn at origin, nominal 40 units tall -->
|
||||
<g id="suit-heart">
|
||||
<path class="red" d="M0,15 C-19,-2 -14,-21 0,-12 C14,-21 19,-2 0,15 Z"/>
|
||||
</g>
|
||||
|
||||
<!-- rank glyph, geometric so it needs no font at render time -->
|
||||
<g id="glyph-q">
|
||||
<circle class="no-fill s-ink" cx="0" cy="0" r="12.5" stroke-width="5.5"
|
||||
style="stroke:#a21b1e"/>
|
||||
<path d="M5,7 L15,19" style="stroke:#a21b1e;stroke-width:5.5;
|
||||
stroke-linecap:round" fill="none"/>
|
||||
</g>
|
||||
|
||||
<!-- corner index: rank over pip, sits outside the inner panel -->
|
||||
<g id="index">
|
||||
<use xlink:href="#glyph-q" href="#glyph-q" x="52" y="60"/>
|
||||
<use xlink:href="#suit-heart" href="#suit-heart" x="52" y="104"
|
||||
transform="translate(0,0)"/>
|
||||
</g>
|
||||
|
||||
<!-- ================= COURT FIGURE — UPPER HALF ================= -->
|
||||
<g id="court-half" clip-path="url(#clip-upper)">
|
||||
|
||||
<!-- veil: two cloth panels falling behind the hair to the seam.
|
||||
Kept as separate open panels, not a closed silhouette. -->
|
||||
<g id="veil">
|
||||
<path class="stock k" d="M228,168
|
||||
C200,176 182,200 174,232
|
||||
C168,258 164,300 160,352
|
||||
L196,352 C198,306 202,266 210,238
|
||||
C216,214 224,190 236,176 Z"/>
|
||||
<path class="stock k" d="M272,168
|
||||
C300,176 318,200 326,232
|
||||
C332,258 336,300 340,352
|
||||
L304,352 C302,306 298,266 290,238
|
||||
C284,214 276,190 264,176 Z"/>
|
||||
<path class="k-fine" d="M186,244 C180,282 176,318 174,352"/>
|
||||
<path class="k-fine" d="M314,244 C320,282 324,318 326,352"/>
|
||||
</g>
|
||||
|
||||
<!-- garments: robe, mantle, sleeve, central placket -->
|
||||
<g id="garments">
|
||||
<!-- neck sits under the collar -->
|
||||
<path class="skin k" d="M236,242 L264,242 L264,272
|
||||
C256,278 244,278 236,272 Z"/>
|
||||
<!-- red robe body, flaring to the panel edges at the seam -->
|
||||
<path class="red k" d="M250,286
|
||||
C204,286 168,306 146,332
|
||||
C136,342 130,348 127,352
|
||||
L373,352
|
||||
C370,348 364,342 354,332
|
||||
C332,306 296,286 250,286 Z"/>
|
||||
<!-- blue mantle over the outer shoulders -->
|
||||
<path class="blue k" d="M196,300 C172,314 150,334 133,352
|
||||
L192,352 C196,332 204,314 214,300 Z"/>
|
||||
<path class="blue k" d="M304,300 C328,314 350,334 367,352
|
||||
L308,352 C304,332 296,314 286,300 Z"/>
|
||||
<!-- left sleeve, carrying the arm out to the flower hand -->
|
||||
<path class="blue k" d="M210,292 C188,296 168,306 157,318
|
||||
C168,328 186,330 202,322 C206,310 208,300 210,292 Z"/>
|
||||
<!-- gold placket down the centre -->
|
||||
<path class="gold k" d="M228,292 L272,292 L282,352 L218,352 Z"/>
|
||||
<!-- collar -->
|
||||
<path class="gold k" d="M226,268 C238,280 262,280 274,268
|
||||
L288,290 C266,306 234,306 212,290 Z"/>
|
||||
</g>
|
||||
|
||||
<!-- ornament: jewels and filigree. Full detail — do not thin this out
|
||||
for small sizes; make a separate thumbnail variant instead. -->
|
||||
<g id="ornament">
|
||||
<!-- placket jewels -->
|
||||
<circle class="red k-fine" cx="250" cy="308" r="9"/>
|
||||
<circle class="blue k-fine" cx="250" cy="330" r="7.5"/>
|
||||
<circle class="red k-fine" cx="250" cy="348" r="6"/>
|
||||
<!-- collar beading -->
|
||||
<circle class="stock k-hair" cx="230" cy="283" r="3.4"/>
|
||||
<circle class="stock k-hair" cx="242" cy="290" r="3.4"/>
|
||||
<circle class="stock k-hair" cx="258" cy="290" r="3.4"/>
|
||||
<circle class="stock k-hair" cx="270" cy="283" r="3.4"/>
|
||||
<!-- mantle folds -->
|
||||
<path class="k-fine" d="M190,314 C180,328 170,340 160,352"/>
|
||||
<path class="k-fine" d="M206,312 C198,326 192,340 188,352"/>
|
||||
<path class="k-fine" d="M310,314 C320,328 330,340 340,352"/>
|
||||
<path class="k-fine" d="M294,312 C302,326 308,340 312,352"/>
|
||||
<!-- robe diaper pattern -->
|
||||
<path class="gold k-hair" d="M212,322 L220,332 L212,342 L204,332 Z"/>
|
||||
<path class="gold k-hair" d="M288,322 L296,332 L288,342 L280,332 Z"/>
|
||||
<path class="gold k-hair" d="M196,344 L203,352 L189,352 Z"/>
|
||||
<path class="gold k-hair" d="M304,344 L311,352 L297,352 Z"/>
|
||||
</g>
|
||||
|
||||
<!-- props: the Queen's flower, held viewer-left.
|
||||
Petals are separated by radial cuts rather than overlapping stroked
|
||||
circles, so the outline stays clean at every scale. -->
|
||||
<g id="props">
|
||||
<!-- hand emerging from the sleeve -->
|
||||
<path class="skin k" d="M152,302 C162,296 173,301 174,311
|
||||
C175,322 165,330 155,327 C145,324 143,308 152,302 Z"/>
|
||||
<path class="k-hair" d="M157,308 L169,307 M157,314 L171,313
|
||||
M159,320 L170,319"/>
|
||||
<!-- stem and leaf -->
|
||||
<path class="s-gold" d="M154,302 L146,270" stroke-width="3.4"
|
||||
fill="none" stroke-linecap="round"/>
|
||||
<path class="blue k-hair" d="M150,288 C140,285 135,277 137,271
|
||||
C143,271 149,277 151,285 Z"/>
|
||||
<!-- rosette -->
|
||||
<g transform="translate(144,256)">
|
||||
<circle class="red k" cx="0" cy="0" r="18"/>
|
||||
<path class="k-hair" d="M0,-18 L0,-6 M17,-6 L6,-2
|
||||
M11,15 L4,5 M-11,15 L-4,5 M-17,-6 L-6,-2"/>
|
||||
<circle class="gold k-fine" cx="0" cy="0" r="6.5"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- hair behind the face -->
|
||||
<g id="hair-back">
|
||||
<path class="ink k" d="M250,150
|
||||
C212,150 192,178 190,216
|
||||
C189,242 196,268 206,286
|
||||
L218,262 C210,226 214,190 232,172
|
||||
C240,164 260,164 268,172
|
||||
C286,190 290,226 282,262
|
||||
L294,286 C304,268 311,242 310,216
|
||||
C308,178 288,150 250,150 Z"/>
|
||||
</g>
|
||||
|
||||
<!-- face -->
|
||||
<g id="face">
|
||||
<ellipse class="skin k" cx="250" cy="208" rx="38" ry="45"/>
|
||||
<!-- brows -->
|
||||
<path class="k-fine" d="M232,195 C237,190 245,190 249,194"/>
|
||||
<path class="k-fine" d="M268,195 C263,190 255,190 251,194"/>
|
||||
<!-- eyes: almond, lid line heavier than the lower lash -->
|
||||
<path class="k-fine" d="M234,206 C238,201 246,201 250,206
|
||||
C246,210 238,210 234,206 Z"/>
|
||||
<path class="k-fine" d="M250,206 C254,201 262,201 266,206
|
||||
C262,210 254,210 250,206 Z"/>
|
||||
<circle class="ink" cx="242" cy="206" r="2.4"/>
|
||||
<circle class="ink" cx="258" cy="206" r="2.4"/>
|
||||
<!-- nose -->
|
||||
<path class="k-fine" d="M250,212 L247,226 C248,228 252,228 253,226"/>
|
||||
<!-- mouth -->
|
||||
<path class="red k-fine" d="M243,236 C246,233 254,233 257,236
|
||||
C254,240 246,240 243,236 Z"/>
|
||||
<!-- earrings -->
|
||||
<circle class="gold k-hair" cx="213" cy="216" r="4.5"/>
|
||||
<circle class="gold k-hair" cx="287" cy="216" r="4.5"/>
|
||||
</g>
|
||||
|
||||
<!-- hair falling in front of the shoulders -->
|
||||
<g id="hair-front">
|
||||
<path class="ink k" d="M216,198 C208,216 208,242 214,264
|
||||
C218,278 218,290 214,300
|
||||
C205,290 200,268 200,242 C200,220 206,204 216,198 Z"/>
|
||||
<path class="ink k" d="M284,198 C292,216 292,242 286,264
|
||||
C282,278 282,290 286,300
|
||||
C295,290 300,268 300,242 C300,220 294,204 284,198 Z"/>
|
||||
<path class="k-hair" d="M211,216 C206,234 207,256 212,272"/>
|
||||
<path class="k-hair" d="M289,216 C294,234 293,256 288,272"/>
|
||||
</g>
|
||||
|
||||
<!-- crown -->
|
||||
<g id="crown">
|
||||
<path class="gold k" d="M196,152 L304,152 L300,170 L200,170 Z"/>
|
||||
<path class="gold k" d="M196,152 L204,114 L222,144 L250,102
|
||||
L278,144 L296,114 L304,152 Z"/>
|
||||
<circle class="red k-fine" cx="204" cy="118" r="5.5"/>
|
||||
<circle class="blue k-fine" cx="250" cy="108" r="6.5"/>
|
||||
<circle class="red k-fine" cx="296" cy="118" r="5.5"/>
|
||||
<circle class="blue k-hair" cx="224" cy="161" r="4.5"/>
|
||||
<circle class="red k-hair" cx="250" cy="161" r="4.5"/>
|
||||
<circle class="blue k-hair" cx="276" cy="161" r="4.5"/>
|
||||
</g>
|
||||
|
||||
<!-- interior linework drawn on top of the fills -->
|
||||
<g id="keylines">
|
||||
<path class="k-fine" d="M228,292 L218,352 M272,292 L282,352"/>
|
||||
<path class="k-fine" d="M214,302 C208,320 204,338 202,352"/>
|
||||
<path class="k-fine" d="M286,302 C292,320 296,338 298,352"/>
|
||||
</g>
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<!-- ============================ CARD ============================ -->
|
||||
<g id="card">
|
||||
<rect id="stock" class="stock" x="0" y="0" width="500" height="700" rx="26"/>
|
||||
|
||||
<g id="frame" fill="none">
|
||||
<rect class="k" x="10" y="10" width="480" height="680" rx="20"
|
||||
stroke-width="2.2"/>
|
||||
<rect class="k" x="86" y="88" width="328" height="524" rx="6"/>
|
||||
<rect class="k-fine" x="92" y="94" width="316" height="512" rx="4"/>
|
||||
</g>
|
||||
|
||||
<!-- upper half, then the same artwork rotated 180 about the card centre -->
|
||||
<g id="figure">
|
||||
<use xlink:href="#court-half" href="#court-half"/>
|
||||
<use xlink:href="#court-half" href="#court-half"
|
||||
transform="rotate(180 250 350)"/>
|
||||
</g>
|
||||
|
||||
<g id="seam">
|
||||
<path class="k-fine" d="M92,350 L408,350"/>
|
||||
</g>
|
||||
|
||||
<g id="indices">
|
||||
<use xlink:href="#index" href="#index"/>
|
||||
<use xlink:href="#index" href="#index" transform="rotate(180 250 350)"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
Reference in New Issue
Block a user