← back to Wallco Ai
cards: pattern-only resting state, full meta on hover (admin + user + designer)
0a9b0d47543abd8a22f51424fc8b37bb00537b0d · 2026-05-13 13:54:01 -0700 · SteveStudio2
Steve's rule (2026-05-13): grids of patterns should read as PURE pattern
until the visitor commits attention. Pre-change: every .p-card (admin)
and .design-card (user/designer) showed name/SKU/color/tags below the
image, plus an occasional bare-digit '.p-coll' (1 / 3) leaking from the
vendor feed's row-count classification.
Changes:
1. public/css/admin.css — .p-meta becomes an absolute-positioned smoke-
gradient overlay over the bottom of the pattern image, hidden by
default (opacity 0 + pointer-events:none + translateY(6px)), revealed
on .p-card:hover or .p-card:focus-within (keyboard a11y). Resting
card = pure pattern. Adjusted text colors so meta is legible against
the dark gradient.
2. public/css/site.css — same overlay pattern lifted onto .design-card
.card-meta so the user + designer surfaces match. .review-card opts
OUT (review-flyout already handles its own hover behaviour) — pinned
via a .review-card .card-meta { position: static; opacity: 1; … }
override so review-mode keeps its existing layout.
3. src/admin.js — strip purely-numeric .p-coll values (isMeaningfulColl
regex). Bare '1' / '3' classification ids never reach the DOM now.
Single-letter codes ('C', 'G', 'A') still render — those ARE
meaningful and they belong in the hover overlay.
Files touched
M data/designs.jsonM public/css/admin.cssM public/css/site.cssM src/admin.js
Diff
commit 0a9b0d47543abd8a22f51424fc8b37bb00537b0d
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 13:54:01 2026 -0700
cards: pattern-only resting state, full meta on hover (admin + user + designer)
Steve's rule (2026-05-13): grids of patterns should read as PURE pattern
until the visitor commits attention. Pre-change: every .p-card (admin)
and .design-card (user/designer) showed name/SKU/color/tags below the
image, plus an occasional bare-digit '.p-coll' (1 / 3) leaking from the
vendor feed's row-count classification.
Changes:
1. public/css/admin.css — .p-meta becomes an absolute-positioned smoke-
gradient overlay over the bottom of the pattern image, hidden by
default (opacity 0 + pointer-events:none + translateY(6px)), revealed
on .p-card:hover or .p-card:focus-within (keyboard a11y). Resting
card = pure pattern. Adjusted text colors so meta is legible against
the dark gradient.
2. public/css/site.css — same overlay pattern lifted onto .design-card
.card-meta so the user + designer surfaces match. .review-card opts
OUT (review-flyout already handles its own hover behaviour) — pinned
via a .review-card .card-meta { position: static; opacity: 1; … }
override so review-mode keeps its existing layout.
3. src/admin.js — strip purely-numeric .p-coll values (isMeaningfulColl
regex). Bare '1' / '3' classification ids never reach the DOM now.
Single-letter codes ('C', 'G', 'A') still render — those ARE
meaningful and they belong in the hover overlay.
---
data/designs.json | 990 +++++++++++++++++++++++++++++++++++++++++++++++++++
public/css/admin.css | 42 ++-
public/css/site.css | 37 +-
src/admin.js | 9 +-
4 files changed, 1062 insertions(+), 16 deletions(-)
diff --git a/data/designs.json b/data/designs.json
index ce357fa..0fb6e47 100644
--- a/data/designs.json
+++ b/data/designs.json
@@ -80821,5 +80821,995 @@
"user_scale_good": null,
"user_stars": null,
"room_mockups": []
+ },
+ {
+ "id": 3903,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#4d412a",
+ "saturation": 0.294,
+ "title": "Honey Daydream No.3903",
+ "handle": "wallco-3903",
+ "image_url": "/designs/img/1778704861670_1463623954.png",
+ "filename": "1778704861670_1463623954.png",
+ "generator": "wallco.ai",
+ "seed": 1463623954,
+ "is_published": false,
+ "created_at": "2026-05-13T20:41:13.420353+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3904,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#1d171f",
+ "saturation": 0.148,
+ "title": "Mauve Soir\u00e9e No.3904",
+ "handle": "wallco-3904",
+ "image_url": "/designs/img/1778704861670_1835996605.png",
+ "filename": "1778704861670_1835996605.png",
+ "generator": "wallco.ai",
+ "seed": 1835996605,
+ "is_published": false,
+ "created_at": "2026-05-13T20:41:20.143073+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3905,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#252825",
+ "saturation": 0.039,
+ "title": "Noir Baroque No.3905",
+ "handle": "wallco-3905",
+ "image_url": "/designs/img/1778704935727_1961722886.png",
+ "filename": "1778704935727_1961722886.png",
+ "generator": "wallco.ai",
+ "seed": 1961722886,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:24.078063+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3906,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#252825",
+ "saturation": 0.039,
+ "title": "Noir Damask No.3906",
+ "handle": "wallco-3906",
+ "image_url": "/designs/img/var_3905_hue+60_1778704944199.png",
+ "filename": "var_3905_hue+60_1778704944199.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:26.279978+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3907,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#252825",
+ "saturation": 0.039,
+ "title": "Noir Heirloom No.3907",
+ "handle": "wallco-3907",
+ "image_url": "/designs/img/var_3905_hue+120_1778704946284.png",
+ "filename": "var_3905_hue+120_1778704946284.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:28.421671+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3908,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#252825",
+ "saturation": 0.039,
+ "title": "Noir Atelier No.3908",
+ "handle": "wallco-3908",
+ "image_url": "/designs/img/var_3905_hue+180_1778704948428.png",
+ "filename": "var_3905_hue+180_1778704948428.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:30.603317+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3909,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#252825",
+ "saturation": 0.039,
+ "title": "Noir Salon No.3909",
+ "handle": "wallco-3909",
+ "image_url": "/designs/img/var_3905_hue-60_1778704950607.png",
+ "filename": "var_3905_hue-60_1778704950607.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:32.74504+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3910,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#252825",
+ "saturation": 0.039,
+ "title": "Noir Baroque No.3910",
+ "handle": "wallco-3910",
+ "image_url": "/designs/img/var_3905_mono_1778704952748.png",
+ "filename": "var_3905_mono_1778704952748.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:34.913993+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3911,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#33343a",
+ "saturation": 0.064,
+ "title": "Noir Trip No.3911",
+ "handle": "wallco-3911",
+ "image_url": "/designs/img/1778704951632_1017201910.png",
+ "filename": "1778704951632_1017201910.png",
+ "generator": "wallco.ai",
+ "seed": 1017201910,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:43.069077+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3912,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#30243d",
+ "saturation": 0.258,
+ "title": "Mauve Tableau No.3912",
+ "handle": "wallco-3912",
+ "image_url": "/designs/img/1778704951632_918302026.png",
+ "filename": "1778704951632_918302026.png",
+ "generator": "wallco.ai",
+ "seed": 918302026,
+ "is_published": false,
+ "created_at": "2026-05-13T20:42:46.975684+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3913,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#7b8051",
+ "saturation": 0.225,
+ "title": "Olive Reverie No.3913",
+ "handle": "wallco-3913",
+ "image_url": "/designs/img/1778705041635_1970017345.png",
+ "filename": "1778705041635_1970017345.png",
+ "generator": "wallco.ai",
+ "seed": 1970017345,
+ "is_published": false,
+ "created_at": "2026-05-13T20:44:10.224582+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3914,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#5f5e48",
+ "saturation": 0.138,
+ "title": "Olive Vespers No.3914",
+ "handle": "wallco-3914",
+ "image_url": "/designs/img/1778705041636_53840879.png",
+ "filename": "1778705041636_53840879.png",
+ "generator": "wallco.ai",
+ "seed": 53840879,
+ "is_published": false,
+ "created_at": "2026-05-13T20:44:13.171979+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3915,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#5d7a46",
+ "saturation": 0.271,
+ "title": "Sage Vignette No.3915",
+ "handle": "wallco-3915",
+ "image_url": "/designs/img/1778705079274_1126336368.png",
+ "filename": "1778705079274_1126336368.png",
+ "generator": "wallco.ai",
+ "seed": 1126336368,
+ "is_published": false,
+ "created_at": "2026-05-13T20:44:47.507093+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3916,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#1d1b19",
+ "saturation": 0.074,
+ "title": "Noir Damask No.3916",
+ "handle": "wallco-3916",
+ "image_url": "/designs/img/1778705124366_1263352054.png",
+ "filename": "1778705124366_1263352054.png",
+ "generator": "wallco.ai",
+ "seed": 1263352054,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:32.594014+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3917,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#1d1b19",
+ "saturation": 0.074,
+ "title": "Noir Heirloom No.3917",
+ "handle": "wallco-3917",
+ "image_url": "/designs/img/var_3916_hue+60_1778705132700.png",
+ "filename": "var_3916_hue+60_1778705132700.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:34.800014+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3918,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#1d1b19",
+ "saturation": 0.074,
+ "title": "Noir Atelier No.3918",
+ "handle": "wallco-3918",
+ "image_url": "/designs/img/var_3916_hue+120_1778705134804.png",
+ "filename": "var_3916_hue+120_1778705134804.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:36.905165+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3919,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#1d1b19",
+ "saturation": 0.074,
+ "title": "Noir Salon No.3919",
+ "handle": "wallco-3919",
+ "image_url": "/designs/img/var_3916_hue+180_1778705136908.png",
+ "filename": "var_3916_hue+180_1778705136908.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:39.119846+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3920,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#1d1b19",
+ "saturation": 0.074,
+ "title": "Noir Baroque No.3920",
+ "handle": "wallco-3920",
+ "image_url": "/designs/img/var_3916_hue-60_1778705139124.png",
+ "filename": "var_3916_hue-60_1778705139124.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:41.209255+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3921,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#b86043",
+ "saturation": 0.466,
+ "title": "Rose Tipple No.3921",
+ "handle": "wallco-3921",
+ "image_url": "/designs/img/1778705131658_1238648482.png",
+ "filename": "1778705131658_1238648482.png",
+ "generator": "wallco.ai",
+ "seed": 1238648482,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:43.145219+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3922,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#1d1b19",
+ "saturation": 0.074,
+ "title": "Noir Heirloom No.3922",
+ "handle": "wallco-3922",
+ "image_url": "/designs/img/var_3916_mono_1778705141223.png",
+ "filename": "var_3916_mono_1778705141223.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:43.422836+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3923,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#a9545a",
+ "saturation": 0.336,
+ "title": "Rose Daydream No.3923",
+ "handle": "wallco-3923",
+ "image_url": "/designs/img/1778705131658_1563133687.png",
+ "filename": "1778705131658_1563133687.png",
+ "generator": "wallco.ai",
+ "seed": 1563133687,
+ "is_published": false,
+ "created_at": "2026-05-13T20:45:46.630556+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3924,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#a77c8e",
+ "saturation": 0.196,
+ "title": "Rose Soir\u00e9e No.3924",
+ "handle": "wallco-3924",
+ "image_url": "/designs/img/1778705221659_916892215.png",
+ "filename": "1778705221659_916892215.png",
+ "generator": "wallco.ai",
+ "seed": 916892215,
+ "is_published": false,
+ "created_at": "2026-05-13T20:47:13.881213+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3925,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#554c44",
+ "saturation": 0.111,
+ "title": "Amber Hazefield No.3925",
+ "handle": "wallco-3925",
+ "image_url": "/designs/img/1778705221659_1582160021.png",
+ "filename": "1778705221659_1582160021.png",
+ "generator": "wallco.ai",
+ "seed": 1582160021,
+ "is_published": false,
+ "created_at": "2026-05-13T20:47:16.561515+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3926,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#bf3e72",
+ "saturation": 0.51,
+ "title": "Rose Carouse No.3926",
+ "handle": "wallco-3926",
+ "image_url": "/designs/img/1778705311674_773727836.png",
+ "filename": "1778705311674_773727836.png",
+ "generator": "wallco.ai",
+ "seed": 773727836,
+ "is_published": false,
+ "created_at": "2026-05-13T20:48:39.963126+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3927,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#2d3431",
+ "saturation": 0.072,
+ "title": "Noir Spore No.3927",
+ "handle": "wallco-3927",
+ "image_url": "/designs/img/1778705311674_1650227775.png",
+ "filename": "1778705311674_1650227775.png",
+ "generator": "wallco.ai",
+ "seed": 1650227775,
+ "is_published": false,
+ "created_at": "2026-05-13T20:48:43.364025+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3928,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#aa663a",
+ "saturation": 0.491,
+ "title": "Amber Atelier No.3928",
+ "handle": "wallco-3928",
+ "image_url": "/designs/img/1778705312801_1457130399.png",
+ "filename": "1778705312801_1457130399.png",
+ "generator": "wallco.ai",
+ "seed": 1457130399,
+ "is_published": false,
+ "created_at": "2026-05-13T20:48:47.826912+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3929,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#aa663a",
+ "saturation": 0.491,
+ "title": "Amber Salon No.3929",
+ "handle": "wallco-3929",
+ "image_url": "/designs/img/var_3928_hue+60_1778705327934.png",
+ "filename": "var_3928_hue+60_1778705327934.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:48:58.700162+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3930,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#bf3686",
+ "saturation": 0.559,
+ "title": "Plum Hiccup No.3930",
+ "handle": "wallco-3930",
+ "image_url": "/designs/img/1778705327758_1368658369.png",
+ "filename": "1778705327758_1368658369.png",
+ "generator": "wallco.ai",
+ "seed": 1368658369,
+ "is_published": false,
+ "created_at": "2026-05-13T20:48:59.215434+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3931,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#aa663a",
+ "saturation": 0.491,
+ "title": "Amber Damask No.3931",
+ "handle": "wallco-3931",
+ "image_url": "/designs/img/var_3928_hue+120_1778705338706.png",
+ "filename": "var_3928_hue+120_1778705338706.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:49:01.296996+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3932,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#aa663a",
+ "saturation": 0.491,
+ "title": "Amber Heirloom No.3932",
+ "handle": "wallco-3932",
+ "image_url": "/designs/img/var_3928_hue+180_1778705341301.png",
+ "filename": "var_3928_hue+180_1778705341301.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:49:03.941482+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3933,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#aa663a",
+ "saturation": 0.491,
+ "title": "Amber Atelier No.3933",
+ "handle": "wallco-3933",
+ "image_url": "/designs/img/var_3928_hue-60_1778705343946.png",
+ "filename": "var_3928_hue-60_1778705343946.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:49:06.196698+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3934,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#aa663a",
+ "saturation": 0.491,
+ "title": "Amber Salon No.3934",
+ "handle": "wallco-3934",
+ "image_url": "/designs/img/var_3928_mono_1778705346201.png",
+ "filename": "var_3928_mono_1778705346201.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:49:08.430251+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3935,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#423330",
+ "saturation": 0.158,
+ "title": "Rose Hazefield No.3935",
+ "handle": "wallco-3935",
+ "image_url": "/designs/img/1778705401651_30232495.png",
+ "filename": "1778705401651_30232495.png",
+ "generator": "wallco.ai",
+ "seed": 30232495,
+ "is_published": false,
+ "created_at": "2026-05-13T20:50:10.131894+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3936,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#c5779f",
+ "saturation": 0.402,
+ "title": "Plum Carouse No.3936",
+ "handle": "wallco-3936",
+ "image_url": "/designs/img/1778705401651_1927022588.png",
+ "filename": "1778705401651_1927022588.png",
+ "generator": "wallco.ai",
+ "seed": 1927022588,
+ "is_published": false,
+ "created_at": "2026-05-13T20:50:13.358719+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3937,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#6d4f48",
+ "saturation": 0.204,
+ "title": "Rose Spore No.3937",
+ "handle": "wallco-3937",
+ "image_url": "/designs/img/1778705491723_1434522777.png",
+ "filename": "1778705491723_1434522777.png",
+ "generator": "wallco.ai",
+ "seed": 1434522777,
+ "is_published": false,
+ "created_at": "2026-05-13T20:51:44.320771+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3938,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#aa7051",
+ "saturation": 0.355,
+ "title": "Amber Saunter No.3938",
+ "handle": "wallco-3938",
+ "image_url": "/designs/img/1778705491725_826133047.png",
+ "filename": "1778705491725_826133047.png",
+ "generator": "wallco.ai",
+ "seed": 826133047,
+ "is_published": false,
+ "created_at": "2026-05-13T20:51:44.320858+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3939,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#344734",
+ "saturation": 0.154,
+ "title": "Sage Salon No.3939",
+ "handle": "wallco-3939",
+ "image_url": "/designs/img/1778705508626_1904649931.png",
+ "filename": "1778705508626_1904649931.png",
+ "generator": "wallco.ai",
+ "seed": 1904649931,
+ "is_published": false,
+ "created_at": "2026-05-13T20:52:01.173853+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3940,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#344734",
+ "saturation": 0.154,
+ "title": "Sage Baroque No.3940",
+ "handle": "wallco-3940",
+ "image_url": "/designs/img/var_3939_hue+60_1778705521763.png",
+ "filename": "var_3939_hue+60_1778705521763.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:52:05.470962+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3941,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#344734",
+ "saturation": 0.154,
+ "title": "Sage Damask No.3941",
+ "handle": "wallco-3941",
+ "image_url": "/designs/img/var_3939_hue+120_1778705525479.png",
+ "filename": "var_3939_hue+120_1778705525479.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:52:10.16569+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3942,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#344734",
+ "saturation": 0.154,
+ "title": "Sage Heirloom No.3942",
+ "handle": "wallco-3942",
+ "image_url": "/designs/img/var_3939_hue+180_1778705530169.png",
+ "filename": "var_3939_hue+180_1778705530169.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:52:12.349343+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3943,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#344734",
+ "saturation": 0.154,
+ "title": "Sage Atelier No.3943",
+ "handle": "wallco-3943",
+ "image_url": "/designs/img/var_3939_hue-60_1778705532356.png",
+ "filename": "var_3939_hue-60_1778705532356.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:52:15.458957+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3944,
+ "kind": "seamless_tile",
+ "category": "damask",
+ "dominant_hex": "#344734",
+ "saturation": 0.154,
+ "title": "Sage Salon No.3944",
+ "handle": "wallco-3944",
+ "image_url": "/designs/img/var_3939_mono_1778705535464.png",
+ "filename": "var_3939_mono_1778705535464.png",
+ "generator": "wallco.ai",
+ "seed": 0,
+ "is_published": false,
+ "created_at": "2026-05-13T20:52:17.996877+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3945,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#2c3d42",
+ "saturation": 0.2,
+ "title": "Marine Vignette No.3945",
+ "handle": "wallco-3945",
+ "image_url": "/designs/img/1778705579541_1049994541.png",
+ "filename": "1778705579541_1049994541.png",
+ "generator": "wallco.ai",
+ "seed": 1049994541,
+ "is_published": false,
+ "created_at": "2026-05-13T20:53:13.647893+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3946,
+ "kind": "seamless_tile",
+ "category": "drunk-animals",
+ "dominant_hex": "#a5326c",
+ "saturation": 0.535,
+ "title": "Plum Carouse No.3946",
+ "handle": "wallco-3946",
+ "image_url": "/designs/img/1778705581700_1084361872.png",
+ "filename": "1778705581700_1084361872.png",
+ "generator": "wallco.ai",
+ "seed": 1084361872,
+ "is_published": false,
+ "created_at": "2026-05-13T20:53:13.758454+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
+ },
+ {
+ "id": 3947,
+ "kind": "seamless_tile",
+ "category": "stoned-animals",
+ "dominant_hex": "#97558a",
+ "saturation": 0.28,
+ "title": "Plum Spore No.3947",
+ "handle": "wallco-3947",
+ "image_url": "/designs/img/1778705581700_1184818447.png",
+ "filename": "1778705581700_1184818447.png",
+ "generator": "wallco.ai",
+ "seed": 1184818447,
+ "is_published": false,
+ "created_at": "2026-05-13T20:53:14.743416+00:00",
+ "motifs": [],
+ "user_removed": false,
+ "user_color_good": null,
+ "user_style_good": null,
+ "user_scale_good": null,
+ "user_stars": null,
+ "room_mockups": []
}
]
\ No newline at end of file
diff --git a/public/css/admin.css b/public/css/admin.css
index 6616d36..d99797b 100644
--- a/public/css/admin.css
+++ b/public/css/admin.css
@@ -65,28 +65,52 @@ body[data-admin="true"] { background: var(--bg); color: var(--ink); }
.v-name { font-family: var(--serif); font-size: 17px; text-transform: capitalize; line-height: 1.1; }
.v-count { font-size: 11px; color: var(--ink-faint); margin-top: 4px; letter-spacing: 0.05em; }
-/* Product grid (vendor + aesthetic + inspiration) */
+/* Product grid (vendor + aesthetic + inspiration).
+ Steve's rule (2026-05-13): pattern image alone in the resting card —
+ no name, no SKU, no collection number bleed-through. The full meta
+ block surfaces as an overlay on :hover / :focus-within (keyboard
+ a11y). Applies to admin AND user AND designer surfaces. See the
+ companion overlay block in site.css for .design-card. */
.p-grid { display: grid; gap: 14px; grid-template-columns: repeat(var(--cols, 5), 1fr); }
.p-card {
background: var(--card-bg); border: 1px solid var(--line); border-radius: 6px;
overflow: hidden; display: flex; flex-direction: column;
+ position: relative;
}
.p-card.is-picked { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(201, 161, 75, .25); }
-.p-img { aspect-ratio: 1; background: var(--bg) no-repeat center/cover; }
-.p-meta { padding: 9px 11px 11px; font-size: 11.5px; display: flex; flex-direction: column; gap: 3px; flex: 1; }
-.p-name { font-weight: 500; color: var(--ink); line-height: 1.25; }
-.p-color { color: var(--ink-soft); font-size: 11px; }
-.p-coll { color: var(--ink-faint); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
+.p-img { aspect-ratio: 1; background: var(--bg) no-repeat center/cover; flex: 1; }
+
+/* Resting state: pattern only. Meta absolutely positions over the
+ bottom of the image with a smoke-gradient backdrop so text is
+ legible against any pattern color. */
+.p-meta {
+ position: absolute; left: 0; right: 0; bottom: 0;
+ padding: 12px 14px 14px;
+ font-size: 11.5px;
+ display: flex; flex-direction: column; gap: 4px;
+ background: linear-gradient(to top, rgba(20,16,8,0.94) 0%, rgba(20,16,8,0.78) 55%, rgba(20,16,8,0) 100%);
+ color: #f4ecd9;
+ opacity: 0; pointer-events: none;
+ transform: translateY(6px);
+ transition: opacity .18s ease, transform .18s ease;
+}
+.p-card:hover .p-meta,
+.p-card:focus-within .p-meta {
+ opacity: 1; pointer-events: auto; transform: none;
+}
+.p-name { font-weight: 500; color: #fff; line-height: 1.25; }
+.p-color { color: #e3d6b2; font-size: 11px; }
+.p-coll { color: #c9a14b; font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
.p-add, .p-remove {
margin-top: 6px; align-self: flex-start;
- background: transparent; border: 1px solid var(--line); color: var(--ink-soft);
+ background: transparent; border: 1px solid rgba(244,236,217,0.5); color: #f4ecd9;
font: 10.5px/1 var(--sans); text-transform: uppercase; letter-spacing: 0.06em;
padding: 5px 9px; border-radius: 3px; cursor: pointer;
}
.p-add:hover { background: var(--gold); color: var(--accent); border-color: var(--gold); }
.p-card.is-picked .p-add { background: var(--gold); color: var(--accent); border-color: var(--gold); }
-.p-remove { color: #b03a2e; border-color: #f3c2b6; }
-.p-remove:hover { background: #fde6e1; }
+.p-remove { color: #ffb4a8; border-color: rgba(255,180,168,0.45); }
+.p-remove:hover { background: rgba(192,68,52,0.85); color: #fff; border-color: rgba(192,68,52,0.85); }
.btn-gen {
background: var(--accent); color: var(--bg); border: 0; border-radius: 8px;
diff --git a/public/css/site.css b/public/css/site.css
index 7a7e3cd..6031d97 100644
--- a/public/css/site.css
+++ b/public/css/site.css
@@ -359,43 +359,70 @@ main { padding-top: 73px; }
.skip-link { transition: none !important; }
}
+/* Steve's rule (2026-05-13): resting card is pattern-only. Title / SKU /
+ color / tags surface as a smoke-gradient overlay on hover/focus, so
+ the grid reads as pure pattern until the visitor commits attention.
+ :focus-within preserves keyboard a11y. Review-card flyout (admin
+ review mode) opts out — see .review-card .card-meta below. */
.card-meta {
+ position: absolute; left: 0; right: 0; bottom: 0;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 3px;
- padding: 8px 10px 10px;
+ padding: 10px 12px 12px;
+ background: linear-gradient(to top, rgba(20,16,8,0.94) 0%, rgba(20,16,8,0.78) 55%, rgba(20,16,8,0) 100%);
+ color: #f4ecd9;
+ opacity: 0; pointer-events: none;
+ transform: translateY(6px);
+ transition: opacity .18s ease, transform .18s ease;
+ border-top: 0;
+}
+.design-card:hover .card-meta,
+.design-card:focus-within .card-meta { opacity: 1; pointer-events: auto; transform: none; }
+
+/* Review-card has its own flyout — don't double-overlay. */
+.review-card .card-meta {
+ position: static;
+ opacity: 1; pointer-events: auto; transform: none;
+ background: transparent; color: var(--ink);
border-top: 1px solid var(--line);
+ padding: 8px 10px 10px;
}
+
.card-title {
font-family: var(--serif);
font-size: 13px;
- color: var(--ink);
+ color: #fff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.2;
}
+.review-card .card-title { color: var(--ink); }
.card-sku {
font: 9px/1 ui-monospace, Menlo, monospace;
letter-spacing: 0.06em;
- color: var(--ink-faint);
+ color: rgba(244,236,217,0.62);
text-transform: uppercase;
}
+.review-card .card-sku { color: var(--ink-faint); }
.card-colorname {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 10px;
- color: var(--ink-soft, #555);
+ color: #e3d6b2;
text-transform: capitalize;
line-height: 1.2;
}
+.review-card .card-colorname { color: var(--ink-soft, #555); }
.card-hex {
font: 9px/1 ui-monospace, Menlo, monospace;
- color: var(--ink-faint);
+ color: rgba(244,236,217,0.62);
letter-spacing: 0.04em;
}
+.review-card .card-hex { color: var(--ink-faint); }
.card-tags {
display: inline-flex;
align-items: center;
diff --git a/src/admin.js b/src/admin.js
index 3eb587d..f09270a 100644
--- a/src/admin.js
+++ b/src/admin.js
@@ -209,13 +209,17 @@ function mount(app) {
const code = req.params.code;
const q = (req.query.q || '').toString().trim();
const products = vendorProducts(code, { q, page: 1, per: 120 });
+ // Strip purely-numeric collection values — those are row-count / classification
+ // ids leaking from the source feed (e.g., "1", "3"); they're noise to humans
+ // and they were rendering as bare digits under the color name.
+ const isMeaningfulColl = c => c && !/^\d+$/.test(String(c).trim());
const cards = products.map(p => `
<div class="p-card" data-id="${p.id}" data-vendor="${p.vendor_code}" data-sku="${p.mfr_sku || ''}" data-pattern="${(p.pattern_name||'').replace(/"/g,'"')}" data-img="${p.image_url}" data-url="${p.product_url||''}">
<div class="p-img" style="background-image:url('${p.image_url}')"></div>
<div class="p-meta">
<div class="p-name">${p.pattern_name || p.mfr_sku || '—'}</div>
${p.color_name ? `<div class="p-color">${p.color_name}</div>` : ''}
- ${p.collection ? `<div class="p-coll">${p.collection}</div>` : ''}
+ ${isMeaningfulColl(p.collection) ? `<div class="p-coll">${p.collection}</div>` : ''}
<button class="p-add" type="button">+ Inspiration</button>
</div>
</div>`).join('');
@@ -239,12 +243,13 @@ function mount(app) {
const tag = (req.query.q || '').toString().trim();
if (!tag) return res.redirect('/admin');
const products = aestheticSearch(tag, { limit: 200 });
+ const isMeaningfulColl = c => c && !/^\d+$/.test(String(c).trim());
const cards = products.map(p => `
<div class="p-card" data-id="${p.id}" data-vendor="${p.vendor_code}" data-sku="${p.mfr_sku || ''}" data-pattern="${(p.pattern_name||'').replace(/"/g,'"')}" data-img="${p.image_url}" data-url="${p.product_url||''}">
<div class="p-img" style="background-image:url('${p.image_url}')"></div>
<div class="p-meta">
<div class="p-name">${p.pattern_name || p.mfr_sku || '—'}</div>
- <div class="p-coll">${p.vendor_code.replace(/_/g,' ')}${p.collection ? ' · ' + p.collection : ''}</div>
+ <div class="p-coll">${p.vendor_code.replace(/_/g,' ')}${isMeaningfulColl(p.collection) ? ' · ' + p.collection : ''}</div>
<button class="p-add" type="button">+ Inspiration</button>
</div>
</div>`).join('');
← ab7d5d5 design page: AI card Duplicate/Edit buttons always visible (
·
back to Wallco Ai
·
wallco: add full sort options (oldest/title-desc/vivid/muted 829515f →