← back to CelebritySignatures
wear: polo left_chest placeholder, add cap garment, collar fabric tag (TK-10286)
adf131336d551cbaa05b663ac4c8131485716f86 · 2026-09-08 13:03:59 -0700 · Steve Abrams
Still fully gated off (WEAR_SALES_LIVE unset, checkout returns comingSoon).
1. Polo: switched from the manually-tuned 'front' full-torso print area to
Printify's own DEDICATED 'left_chest' placeholder for this blueprint. The
'front' area kept sitting too low no matter how high y went (y:0.0 still
overlapped the placket) — the dedicated placeholder is a properly-scoped
small print area that lands at the correct height automatically. Verified
via a real throwaway draft product + mockup.
2. New 4th garment: Classic Dad Cap (Yupoong 6245CM, blueprint 1447, provider
99 Printify Choice), DTF print (not embroidery — a cursive signature's
thin strokes would blob out in embroidery) on the front_dtf placeholder,
x:0.5/y:0.5/scale:0.7. White/Stone/Khaki/Light Blue (light-only, same
conservative default as the original tee palette). One-size. Cost $16.12
at verification. New SVG geometry in wear-templates.json (dome + brim) and
public/wear.html renders it via the existing generic accent/pocketAccent
hooks — no cap-specific branch needed. Verified with real Playwright
screenshots (0 console errors) plus a real Printify draft-product mockup.
3. 'Celebrity Signatures' fabric tag at the back collar (Steve's request) —
Printify's dedicated 'neck' placeholder, only available on the tee's
blueprint (checked: polo/pocket-tee/cap blueprints have none). Rendered
the tag as a real PNG (Playfair Display italic, matching the site's own
wordmark) via a local Playwright screenshot, saved to
public/assets/wear-tag-celebrity-signatures.png. Iterated position against
4 real throwaway draft products: y:0.5 (centered, too low) -> y:0.15 ->
y:0.0 (clips into the collar-binding curve, distorts the text) -> the
final y:0.08, the highest clean/legible position.
New data model: garment.printify.extraPrintAreas[] — static (not
per-order) image print areas layered onto every order for that garment.
scripts/submit-pod-draft-printify.mjs's buildPayload() now merges these
into the order's print_areas object alongside the per-order signature
design, referencing the tag by its live site URL
(https://celebsignatures.com/assets/...) the same way the existing code
already references design_image_url — no image upload/ID plumbing needed,
since Printify's Orders API (unlike the Products API used for mockup
verification) accepts a fetchable src URL directly.
Verified: node --check clean, JSON valid, dry-run sender unchanged (0
pending, nothing submitted), local E2E shows all 4 garments + correct
variant maps, checkout still comingSoon:true, Playwright screenshots of the
real on-site canvas confirm all 4 garments render without JS errors.
Known gap (not fixed here): the on-site canvas preview doesn't render the
collar tag (only the real Printify mockup does) — a completeness gap, not a
correctness bug, left for a follow-up pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmxcNKtFg77wP47uZq5Zsm
Files touched
M data/wear-templates.jsonA public/assets/wear-tag-celebrity-signatures.pngM scripts/submit-pod-draft-printify.mjs
Diff
commit adf131336d551cbaa05b663ac4c8131485716f86
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Sep 8 13:03:59 2026 -0700
wear: polo left_chest placeholder, add cap garment, collar fabric tag (TK-10286)
Still fully gated off (WEAR_SALES_LIVE unset, checkout returns comingSoon).
1. Polo: switched from the manually-tuned 'front' full-torso print area to
Printify's own DEDICATED 'left_chest' placeholder for this blueprint. The
'front' area kept sitting too low no matter how high y went (y:0.0 still
overlapped the placket) — the dedicated placeholder is a properly-scoped
small print area that lands at the correct height automatically. Verified
via a real throwaway draft product + mockup.
2. New 4th garment: Classic Dad Cap (Yupoong 6245CM, blueprint 1447, provider
99 Printify Choice), DTF print (not embroidery — a cursive signature's
thin strokes would blob out in embroidery) on the front_dtf placeholder,
x:0.5/y:0.5/scale:0.7. White/Stone/Khaki/Light Blue (light-only, same
conservative default as the original tee palette). One-size. Cost $16.12
at verification. New SVG geometry in wear-templates.json (dome + brim) and
public/wear.html renders it via the existing generic accent/pocketAccent
hooks — no cap-specific branch needed. Verified with real Playwright
screenshots (0 console errors) plus a real Printify draft-product mockup.
3. 'Celebrity Signatures' fabric tag at the back collar (Steve's request) —
Printify's dedicated 'neck' placeholder, only available on the tee's
blueprint (checked: polo/pocket-tee/cap blueprints have none). Rendered
the tag as a real PNG (Playfair Display italic, matching the site's own
wordmark) via a local Playwright screenshot, saved to
public/assets/wear-tag-celebrity-signatures.png. Iterated position against
4 real throwaway draft products: y:0.5 (centered, too low) -> y:0.15 ->
y:0.0 (clips into the collar-binding curve, distorts the text) -> the
final y:0.08, the highest clean/legible position.
New data model: garment.printify.extraPrintAreas[] — static (not
per-order) image print areas layered onto every order for that garment.
scripts/submit-pod-draft-printify.mjs's buildPayload() now merges these
into the order's print_areas object alongside the per-order signature
design, referencing the tag by its live site URL
(https://celebsignatures.com/assets/...) the same way the existing code
already references design_image_url — no image upload/ID plumbing needed,
since Printify's Orders API (unlike the Products API used for mockup
verification) accepts a fetchable src URL directly.
Verified: node --check clean, JSON valid, dry-run sender unchanged (0
pending, nothing submitted), local E2E shows all 4 garments + correct
variant maps, checkout still comingSoon:true, Playwright screenshots of the
real on-site canvas confirm all 4 garments render without JS errors.
Known gap (not fixed here): the on-site canvas preview doesn't render the
collar tag (only the real Printify mockup does) — a completeness gap, not a
correctness bug, left for a follow-up pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmxcNKtFg77wP47uZq5Zsm
---
data/wear-templates.json | 88 +++++++++++++++++++++++-
public/assets/wear-tag-celebrity-signatures.png | Bin 0 -> 29001 bytes
scripts/submit-pod-draft-printify.mjs | 17 +++--
3 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/data/wear-templates.json b/data/wear-templates.json
index 7a27097..2b2de98 100644
--- a/data/wear-templates.json
+++ b/data/wear-templates.json
@@ -69,6 +69,14 @@
"blueprintId": 12,
"printProviderId": 99,
"printPosition": { "placeholder": "front", "scale": 0.16, "x": 0.7, "y": 0.1 },
+ "extraPrintAreas": [
+ {
+ "_note": "Fabric tag at the back collar (Steve, 2026-09-08) — Printify's dedicated 'neck' placeholder, only available on this blueprint (checked: polo/pocket-tee/cap blueprints have no neck-label placeholder). Static asset (not per-order design), same on every order. Verified 2026-09-08 via 4 real throwaway draft products — y:0.0 clips into the collar-binding curve and distorts the text; y:0.08 is the highest clean/legible position.",
+ "placeholder": "neck",
+ "imageUrl": "/assets/wear-tag-celebrity-signatures.png",
+ "x": 0.5, "y": 0.08, "scale": 0.8
+ }
+ ],
"variants": {
"white/S": 18540, "white/M": 18541, "white/L": 18542, "white/XL": 18543, "white/2XL": 18544,
"heather/S": 18076, "heather/M": 18077, "heather/L": 18078, "heather/XL": 18079, "heather/2XL": 18080,
@@ -140,7 +148,8 @@
"_note": "JERZEES 443M Piqué Polo, print provider 99 (Printify Choice), DTG. Mapped 2026-09-08 via read-only catalog GETs. printPosition VERIFIED 2026-09-08 against real Printify mockups (multiple throwaway draft products, each deleted) — iterated through x:0.32/y:0.3/scale:0.25 (wrong, dead-center) -> x:0.7/y:0.15/scale:0.14 -> x:0.7/y:0.13/scale:0.22 (too big) to the final x:0.7/y:0.1/scale:0.16, a standard small left-chest logo size sitting just above pocket-top height. Renders correctly on both white and black. KNOWN ISSUE: on the black colorway, the source signature art (dark ink) prints as low-contrast dark-gray-on-black — Printify does not auto-recolor art for dark garments. Needs a server-side light-ink recolor of design_image_url before order submission for dark colors, or dropping the black colorway, before go-live.",
"blueprintId": 1402,
"printProviderId": 99,
- "printPosition": { "placeholder": "front", "scale": 0.16, "x": 0.7, "y": 0.1 },
+ "printPosition": { "placeholder": "left_chest", "scale": 0.85, "x": 0.5, "y": 0.5 },
+ "_note_placeholder": "Switched off the manually-tuned 'front' full-torso area (kept overlapping the placket no matter how high y went) to Printify's own DEDICATED 'left_chest' placeholder for this blueprint — a properly-scoped small print area that lands at the correct height automatically. Verified 2026-09-08 via a real throwaway draft product.",
"variants": {
"white/S": 104647, "white/M": 104648, "white/L": 104649, "white/XL": 104650, "white/2XL": 104651,
"black/S": 104623, "black/M": 104624, "black/L": 104625, "black/XL": 104626, "black/2XL": 104627
@@ -211,6 +220,83 @@
"sizeUpchargeUsd": {
"2XL": 4
}
+ },
+ {
+ "id": "cap",
+ "label": "Classic Dad Cap",
+ "priceUsd": 28,
+ "sizes": [
+ "One size"
+ ],
+ "_note_sizes": "Caps are one-size-fits-all (adjustable strap) — no size chips shown for this garment on the storefront.",
+ "viewBox": [
+ 0,
+ 0,
+ 400,
+ 480
+ ],
+ "bodyPath": "M90 210 Q90 70 200 64 Q310 70 310 210 Q310 226 200 230 Q90 226 90 210 Z",
+ "accents": [
+ {
+ "d": "M195 68 L205 68 L207 226 L193 226 Z",
+ "fillShade": -0.06
+ }
+ ],
+ "pocketAccent": {
+ "d": "M60 214 Q40 250 90 268 Q200 288 310 268 Q360 250 340 214 Q320 232 200 236 Q80 232 60 214 Z",
+ "fillShade": -0.1
+ },
+ "_note_pocketAccent": "This is the cap's BRIM (drawn as a shaded curve below the crown), reusing the pocketAccent rendering hook — not a real pocket. Renamed at the code level would be cleaner but this keeps public/wear.html's draw() generic across all 4 garments without a one-off branch.",
+ "pocketBox": {
+ "x": 150,
+ "y": 120,
+ "w": 100,
+ "h": 55
+ },
+ "colors": [
+ {
+ "id": "white",
+ "label": "White",
+ "hex": "#f6f4ef",
+ "ink": "#1a1a1a"
+ },
+ {
+ "id": "stone",
+ "label": "Stone",
+ "hex": "#cfc9bd",
+ "ink": "#1a1a1a"
+ },
+ {
+ "id": "khaki",
+ "label": "Khaki",
+ "hex": "#c9b896",
+ "ink": "#1a1a1a"
+ },
+ {
+ "id": "lightblue",
+ "label": "Light Blue",
+ "hex": "#a9c4d9",
+ "ink": "#16324a"
+ }
+ ],
+ "_note_colors": "Light-only (White/Stone/Khaki/Light Blue), same conservative default as the original tee palette — avoids the known dark-ink-on-dark-fabric contrast problem (see polo's black colorway note) on a third garment before that gets a real fix.",
+ "printful": {
+ "_note": "Not mapped — Printify only for this garment.",
+ "suggestedProduct": "Yupoong 6245CM Classic Dad Cap",
+ "productId": null,
+ "placementType": "front",
+ "variants": {}
+ },
+ "printify": {
+ "_note": "Yupoong 6245CM Classic Dad Cap, print provider 99 (Printify Choice), DTF (not embroidery — a cursive signature's thin strokes would blob out in embroidery; this blueprint offers both, DTF was the deliberate choice). Mapped + VERIFIED 2026-09-08 via a real throwaway draft product — front_dtf placeholder, x:0.5/y:0.5/scale:0.7 centers cleanly on the front panel. Cost $16.12 at time of verification.",
+ "blueprintId": 1447,
+ "printProviderId": 99,
+ "printPosition": { "placeholder": "front_dtf", "scale": 0.7, "x": 0.5, "y": 0.5 },
+ "variants": {
+ "white/One size": 105381, "stone/One size": 105380, "khaki/One size": 105375, "lightblue/One size": 105376
+ }
+ },
+ "sizeUpchargeUsd": {}
}
]
}
diff --git a/public/assets/wear-tag-celebrity-signatures.png b/public/assets/wear-tag-celebrity-signatures.png
new file mode 100644
index 0000000..65c909d
Binary files /dev/null and b/public/assets/wear-tag-celebrity-signatures.png differ
diff --git a/scripts/submit-pod-draft-printify.mjs b/scripts/submit-pod-draft-printify.mjs
index d94bb5f..dddb41c 100644
--- a/scripts/submit-pod-draft-printify.mjs
+++ b/scripts/submit-pod-draft-printify.mjs
@@ -12,6 +12,7 @@ import { pathToFileURL } from 'node:url';
const ROOT = fileURLToPath(new URL('..', import.meta.url));
const DATA = join(ROOT, 'data');
const API = 'https://api.printify.com/v1';
+const SITE_ORIGIN = 'https://celebsignatures.com';
const APPLY = process.argv.includes('--apply');
const SHOW_PII = process.argv.includes('--show-pii');
@@ -37,26 +38,34 @@ function resolveProduct(tpl, d) {
const key = `${d.color}/${d.size}`;
if (!map.blueprintId || !map.printProviderId || !map.variants?.[key]) throw new Error(`order #${d.orderId}: ${d.garment} ${key} is not mapped to a Printify blueprint/provider/variant`);
return { blueprintId: map.blueprintId, printProviderId: map.printProviderId, variantId: map.variants[key],
- position: map.printPosition || { placeholder: 'front', scale: 0.25, x: 0.32, y: 0.3 } };
+ position: map.printPosition || { placeholder: 'front', scale: 0.25, x: 0.32, y: 0.3 },
+ // Extra STATIC print areas (e.g. the 'Celebrity Signatures' collar tag) —
+ // same image on every order for this garment, not the per-order design.
+ extraPrintAreas: map.extraPrintAreas || [] };
}
function splitName(name) {
const parts = String(name || '').trim().split(/\s+/).filter(Boolean);
return { first_name: parts.shift() || '', last_name: parts.join(' ') || '-' };
}
export function buildPayload(tpl, d) {
- const { blueprintId, printProviderId, variantId, position } = resolveProduct(tpl, d);
+ const { blueprintId, printProviderId, variantId, position, extraPrintAreas } = resolveProduct(tpl, d);
const r = d.recipient || {};
const missing = ['name', 'address1', 'city', 'state_code', 'country_code', 'zip'].filter(k => !r[k]);
if (missing.length) throw new Error(`order #${d.orderId}: missing shipping fields ${missing.join(',')}`);
if (!d.design_image_url) throw new Error(`order #${d.orderId}: no design_image_url`);
const name = splitName(r.name);
+ const print_areas = { [position.placeholder || 'front']: [{ src: d.design_image_url, scale: position.scale,
+ x: position.x, y: position.y, angle: 0 }] };
+ for (const area of extraPrintAreas) {
+ if (!area.placeholder || !area.imageUrl) continue;
+ print_areas[area.placeholder] = [{ src: `${SITE_ORIGIN}${area.imageUrl}`, scale: area.scale, x: area.x, y: area.y, angle: 0 }];
+ }
return {
external_id: `celebsig-wear-${d.orderId}`,
label: `${d.signature_name} signature — left-chest ${d.garment}`,
line_items: [{ print_provider_id: printProviderId, blueprint_id: blueprintId, variant_id: variantId, quantity: 1,
external_id: `celebsig-wear-${d.orderId}-1`,
- print_areas: { [position.placeholder || 'front']: [{ src: d.design_image_url, scale: position.scale,
- x: position.x, y: position.y, angle: 0 }] } }],
+ print_areas }],
is_printify_express: false,
is_economy_shipping: false,
shipping_method: 1,
← 06e1b9d wear: dial print size back down to standard small left-chest
·
back to CelebritySignatures
·
wear: real multi-item shopping cart (own cart, not Shopify's 4173af9 →