[object Object]

← back to Wallco Ai

stoned-animals: new collection — Grateful Dead × Warhol, red eyes, woodland

5f6728cfe93ca99ea9c2b1ea3b4f393365f7cbb1 · 2026-05-13 08:14:09 -0700 · SteveStudio2

Sibling collection to drunk-animals. Every prompt locks in:
  - red eyes / bloodshot / crimson sclera on the animal
  - weed paraphernalia (joints / bongs / gummies / edibles / smoke spirals)
  - Grateful Dead aesthetic vocab (Stealie skull, dancing bears, tie-dye,
    Stanley Mouse, Fillmore posters, skull-and-roses)
  - WOODLAND botanicals only — explicit NO palm / NO monstera / NO banana
    in the negative prompt. Ferns / mushrooms / chamomile / hemp / hops /
    wildflowers / mossy birch / fairy-rings instead.

Artifacts:
  - scripts/stoned_animal_prompts.js   (15×15×10×10×10×10 vocab)
  - scripts/stoned_animals_batch.js    (fire N immediately)
  - scripts/stoned_animals_tick.js     (single-tick, cross-tick dedup window=8)
  - scripts/stoned_animals_daemon.js   (pm2 24/7, preflight self-heal, 5min kill)
  - server.js titler NOUNS adds 'stoned-animals' pool:
      Stealie/Trip/Stardust/Daydream/Vespers/Hazefield/Sundrift/Spore/Lullaby/Halcyon
  - scripts/refresh_designs_snapshot.py mirrors the Python titler pool
  - /stoned-animals friendly URL → /designs?cat=stoned-animals
  - Hero block on /designs?cat=stoned-animals — yellow + orange '4·20 Edition' palette

Initial batch of 20 firing now via wallco-stoned-animals pm2 daemon.
24/7 cadence (not the 18:00→06:00 overnight gate of drunk-animals) since
Steve asked in the morning. Stop with: pm2 stop wallco-stoned-animals

Files touched

Diff

commit 5f6728cfe93ca99ea9c2b1ea3b4f393365f7cbb1
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 13 08:14:09 2026 -0700

    stoned-animals: new collection — Grateful Dead × Warhol, red eyes, woodland
    
    Sibling collection to drunk-animals. Every prompt locks in:
      - red eyes / bloodshot / crimson sclera on the animal
      - weed paraphernalia (joints / bongs / gummies / edibles / smoke spirals)
      - Grateful Dead aesthetic vocab (Stealie skull, dancing bears, tie-dye,
        Stanley Mouse, Fillmore posters, skull-and-roses)
      - WOODLAND botanicals only — explicit NO palm / NO monstera / NO banana
        in the negative prompt. Ferns / mushrooms / chamomile / hemp / hops /
        wildflowers / mossy birch / fairy-rings instead.
    
    Artifacts:
      - scripts/stoned_animal_prompts.js   (15×15×10×10×10×10 vocab)
      - scripts/stoned_animals_batch.js    (fire N immediately)
      - scripts/stoned_animals_tick.js     (single-tick, cross-tick dedup window=8)
      - scripts/stoned_animals_daemon.js   (pm2 24/7, preflight self-heal, 5min kill)
      - server.js titler NOUNS adds 'stoned-animals' pool:
          Stealie/Trip/Stardust/Daydream/Vespers/Hazefield/Sundrift/Spore/Lullaby/Halcyon
      - scripts/refresh_designs_snapshot.py mirrors the Python titler pool
      - /stoned-animals friendly URL → /designs?cat=stoned-animals
      - Hero block on /designs?cat=stoned-animals — yellow + orange '4·20 Edition' palette
    
    Initial batch of 20 firing now via wallco-stoned-animals pm2 daemon.
    24/7 cadence (not the 18:00→06:00 overnight gate of drunk-animals) since
    Steve asked in the morning. Stop with: pm2 stop wallco-stoned-animals
---
 scripts/refresh_designs_snapshot.py |   4 +-
 scripts/stoned_animal_prompts.js    | 149 ++++++++++++++++++++++++++++++++++++
 scripts/stoned_animals_batch.js     |  40 ++++++++++
 scripts/stoned_animals_daemon.js    |  72 +++++++++++++++++
 scripts/stoned_animals_tick.js      |  75 ++++++++++++++++++
 server.js                           |  20 ++++-
 6 files changed, 358 insertions(+), 2 deletions(-)

diff --git a/scripts/refresh_designs_snapshot.py b/scripts/refresh_designs_snapshot.py
index 0a4592a..fd95a2b 100644
--- a/scripts/refresh_designs_snapshot.py
+++ b/scripts/refresh_designs_snapshot.py
@@ -56,7 +56,9 @@ NOUNS = {
     'damask':    ['Baroque', 'Damask', 'Heirloom', 'Atelier', 'Salon'],
     'mixed':     ['Atelier', 'Studio', 'Origin', 'Folio', 'Reverie'],
     'drunk-animals': ['Hiccup', 'Tipple', 'Tableau', 'Reverie', 'Soirée',
-                      'Vignette', 'Carouse', 'Caprice', 'Saunter', 'Folly']
+                      'Vignette', 'Carouse', 'Caprice', 'Saunter', 'Folly'],
+    'stoned-animals': ['Stealie', 'Trip', 'Stardust', 'Daydream', 'Vespers',
+                       'Hazefield', 'Sundrift', 'Spore', 'Lullaby', 'Halcyon']
 }
 def title_for(cat, hex_, id_):
     pool = NOUNS.get(cat, NOUNS['mixed'])
diff --git a/scripts/stoned_animal_prompts.js b/scripts/stoned_animal_prompts.js
new file mode 100644
index 0000000..e517b0d
--- /dev/null
+++ b/scripts/stoned_animal_prompts.js
@@ -0,0 +1,149 @@
+#!/usr/bin/env node
+/**
+ * Stoned-animals prompt library — Grateful Dead × Warhol aesthetic, woodland
+ * botanicals (NOT tropical), every animal red-eyed/bloodshot, weed paraphernalia
+ * (joints, bongs, gummies, edibles, smoke spirals).
+ *
+ * Sibling to drunk_animal_prompts.js. Same generator, different vibe.
+ */
+
+const ANIMALS = [
+  'bloodshot-eyed Grateful-Dead bear with a peace-sign collar',
+  'bleary-eyed shaggy three-toed sloth, crimson sclera',
+  'rasta-capped iguana with glowing red eyes',
+  'mellow-eyed alpaca, scarlet half-moon eyelids',
+  'hazy-eyed timber wolf, smoke ringing its ears',
+  'spaced-out raccoon with thousand-yard ruby eyes',
+  'dopey-eyed red fox, crimson-rimmed lashes',
+  'drowsy white-tailed deer, red velvet eyes, slow blink',
+  'glassy-eyed great horned owl, eyes pure ember',
+  'stoned koala, slow-blink crimson stare',
+  'trip-eyed river otter, eyes spiraling kaleidoscopic',
+  'zonked basset hound, drooping crimson lids',
+  'couch-locked white rabbit with bloodshot pink eyes',
+  'spacey beaver with smoke ringing its incisors',
+  'tie-dye-furred lemur with cherry-red eyes',
+];
+
+const TABLEAUX = [
+  'holding a smoldering joint, exhale curling into a peace sign',
+  'mid-toke on a hand-blown spiral glass bong, eyes half-lidded',
+  'nibbling a rainbow gummy bear the size of its head, dopey grin',
+  'passing a joint to a smaller animal, eyes meeting through the smoke',
+  'floating in a halo of THC molecule diagrams, eyes spiraling',
+  'reclining on a giant mushroom cap, gummy worms draped across antlers',
+  'bonging through a hand-blown psychedelic glass piece, smoke fills the frame',
+  'watching the smoke spiral upward, red eyes glowing through the haze',
+  'guarding a row of edibles laid out like a sacrament',
+  'ascending in a tie-dye fog, eyes pure crimson',
+  'cradling a Stealie skull lighter, joint between its teeth',
+  'munching a chocolate-chip edible with one eye closed',
+  'centered in a halo of skull-and-roses, joint smoldering',
+  'staring at a Steal-Your-Face skull floating overhead, mouth agape',
+  'curled around a glass bong taller than itself, content sigh',
+];
+
+// WOODLAND botanicals — strictly NOT tropical. No monstera, palm, banana,
+// philodendron, bromeliad. Yes ferns, mushrooms, wildflowers, herbs, mosses.
+const BOTANICALS = [
+  'wild oak ferns, white-spotted toadstools, mossy granite, woodland clovers',
+  'chamomile, lavender stalks, hemp leaves, fiddlehead curls, sage bushes',
+  'wild iris, foxglove, valerian, milk-thistle, mountain laurel',
+  'meadowsweet, queen-anne\'s-lace, wild violets, deer ferns, oxalis',
+  'oxeye daisies, hemlock pines, white birch, wood sorrel',
+  'wildflower meadow — poppies, cornflowers, dandelions gone to seed',
+  'mossy birch grove, lichen-encrusted stones, woodland strawberries',
+  'dense fern understory, wood sorrel, trillium, jack-in-the-pulpit',
+  'herb garden — basil, mint, rosemary, lavender, hemp leaves',
+  'fairy ring of mushrooms at dusk, ivy creeping, ferns unfurling',
+];
+
+// Grateful Dead × Warhol palettes — tie-dye energy meets silkscreen flat-color.
+const PALETTES = [
+  'tie-dye rainbow swirl + Warhol acid-pink + skull-bone white + bloodshot crimson',
+  'electric tangerine + grape-jam purple + lime green + hot magenta + crimson',
+  'Stealie cobalt blue + Stealie red + lightning-bolt yellow + skull white on jet black',
+  'rasta gold + rasta green + rasta red + Warhol acid-pink + crimson stain',
+  'mushroom-cap red + spore white + forest green + amber + crimson eyes',
+  'pop-art sour-cherry red + lime green + cobalt + saffron yellow + crimson',
+  'tie-dye cyan + magenta + lemon yellow + leaf green + crimson sclera',
+  'terrarium moss-green + amethyst purple + amber + crimson-red + cream',
+  'Day-Glo highlighter pink + cobalt + lemon + lime + crimson',
+  'woodland sage + ochre + crimson + dusty rose + chalk white',
+];
+
+const STYLES = [
+  'classic Andy Warhol silkscreen, 4-panel color-swap repeat, registration offset, halftone grain',
+  '1969 Fillmore concert poster: thick organic outlines, vibrating complementaries, tie-dye fade',
+  'psychedelic black-light poster aesthetic, dense linework, throbbing complementary colors',
+  'Mouse-and-Kelley dancing-bears illustration, bold pop colors, hand-drawn outline',
+  'Stanley Mouse skull-and-roses illustration crossed with Warhol silkscreen finish',
+  'mid-century pop illustration crossed with 1968 underground comix linework',
+  'hand-pulled risograph print, 4-color overlap, lush bleed, register slip',
+  '1972 Dead show silkscreen poster, faded ink, off-register layers, paper grain',
+  'Lichtenstein pop-comic outline, Warhol color swap, halftone Ben-Day dots',
+  'psychedelic op-art repeat, Stealie skull centered, kaleidoscope edges, vibrating colors',
+];
+
+const COMPOSITIONS = [
+  'seamless half-drop repeat, animals tessellated, smoke trails threading between',
+  'mirror-axis kaleidoscope, Stealie skull at center, animals fanned to the edges',
+  'Warhol grid-of-portraits, 4 cells × 4 palettes, color-swap registration',
+  'vertical stripe column repeat, animals in psychedelic vertical bands',
+  'continuous scatter with smoke spirals threading through the field',
+  'mandala-radial repeat, hero animal at center, joints + leaves on the spokes',
+  'tossed-bouquet repeat, animals + edibles + leaves intermixed',
+  'large-scale focal repeat, hero stoned animal centered, motifs scattered periphery',
+  'dense allover with bongs / joints / gummies / leaves intermixed',
+  'tight 12-inch tile repeat, dense psychedelic scatter',
+];
+
+function pickRand(arr, exclude = new Set()) {
+  for (let tries = 0; tries < 50; tries++) {
+    const v = arr[Math.floor(Math.random() * arr.length)];
+    if (!exclude.has(v)) return v;
+  }
+  return arr[Math.floor(Math.random() * arr.length)];
+}
+
+function buildPrompt() {
+  return [
+    pickRand(ANIMALS),
+    pickRand(TABLEAUX),
+    `set among ${pickRand(BOTANICALS)}`,
+    `palette: ${pickRand(PALETTES)}`,
+    pickRand(STYLES),
+    pickRand(COMPOSITIONS),
+    'seamless wallpaper repeat, archival quality, NO tropical plants, NO monstera, NO palm, NO banana leaves, no text or watermark'
+  ].join(', ');
+}
+
+function buildN(n) {
+  const usedAnimals = new Set();
+  const usedStyles = new Set();
+  const out = [];
+  for (let i = 0; i < n; i++) {
+    if (usedAnimals.size >= ANIMALS.length - 1) usedAnimals.clear();
+    if (usedStyles.size >= STYLES.length - 1) usedStyles.clear();
+    const animal = pickRand(ANIMALS, usedAnimals);  usedAnimals.add(animal);
+    const style  = pickRand(STYLES, usedStyles);    usedStyles.add(style);
+    const parts = [
+      animal,
+      pickRand(TABLEAUX),
+      `set among ${pickRand(BOTANICALS)}`,
+      `palette: ${pickRand(PALETTES)}`,
+      style,
+      pickRand(COMPOSITIONS),
+      'seamless wallpaper repeat, archival quality, NO tropical plants, NO monstera, NO palm, NO banana leaves, no text or watermark'
+    ];
+    out.push(parts.join(', '));
+  }
+  return out;
+}
+
+module.exports = { buildPrompt, buildN, ANIMALS, TABLEAUX, BOTANICALS, PALETTES, STYLES, COMPOSITIONS };
+
+if (require.main === module) {
+  const n = parseInt(process.argv[2] || '5', 10);
+  for (const p of buildN(n)) console.log(p + '\n');
+}
diff --git a/scripts/stoned_animals_batch.js b/scripts/stoned_animals_batch.js
new file mode 100644
index 0000000..d1c2426
--- /dev/null
+++ b/scripts/stoned_animals_batch.js
@@ -0,0 +1,40 @@
+#!/usr/bin/env node
+/**
+ * Fire a batch of N stoned-animal-in-woodland, Grateful-Dead-meets-Warhol
+ * designs through scripts/generate_designs.js.
+ *
+ * Usage:  node scripts/stoned_animals_batch.js [N]   (default 20)
+ */
+const { spawnSync } = require('child_process');
+const path = require('path');
+const { buildN } = require('./stoned_animal_prompts');
+
+const N = parseInt(process.argv[2] || '20', 10);
+const ROOT = path.join(__dirname, '..');
+
+console.log(`\n=== Stoned-animal batch: firing ${N} designs ===\n`);
+
+const prompts = buildN(N);
+let ok = 0, fail = 0;
+
+for (let i = 0; i < prompts.length; i++) {
+  const p = prompts[i];
+  console.log(`\n--- [${i+1}/${N}] ${p.slice(0, 90)}…`);
+  const r = spawnSync('node', [
+    path.join(ROOT, 'scripts', 'generate_designs.js'),
+    '--n', '1',
+    '--kind', 'seamless_tile',
+    '--category', 'stoned-animals',
+    '--prompts', p,
+  ], { stdio: 'inherit', cwd: ROOT });
+  if (r.status === 0) ok++; else fail++;
+}
+
+console.log(`\n=== Batch done: ${ok} ok, ${fail} failed ===`);
+
+spawnSync('python3', [path.join(ROOT, 'scripts', 'refresh_designs_snapshot.py')],
+          { stdio: 'inherit', cwd: ROOT, timeout: 120_000 });
+spawnSync('curl', ['-sf', '-m', '5', '-X', 'POST', 'http://127.0.0.1:9792/admin/reload-designs'],
+          { stdio: 'inherit', cwd: ROOT, timeout: 10_000 });
+
+process.exit(fail === 0 ? 0 : 1);
diff --git a/scripts/stoned_animals_daemon.js b/scripts/stoned_animals_daemon.js
new file mode 100644
index 0000000..2e0af74
--- /dev/null
+++ b/scripts/stoned_animals_daemon.js
@@ -0,0 +1,72 @@
+#!/usr/bin/env node
+/**
+ * Stoned-animals daemon — pm2-managed long-lived process, fires
+ * scripts/stoned_animals_tick.js every TICK_MS ms.
+ *
+ * Parallel sibling to drunk_animals_daemon — both run simultaneously,
+ * doubling overnight throughput. Each writes its own category to
+ * spoon_all_designs so they never collide.
+ *
+ * Includes the same preflight (self-heal spoon_all_designs_id_seq
+ * desync) and 5-min SIGKILL on hung ticks.
+ */
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+
+const TICK_MS    = parseInt(process.env.TICK_MS || '240000', 10);
+const STOP_HOUR  = parseInt(process.env.STOP_HOUR || '6', 10);
+const ROOT       = path.join(__dirname, '..');
+const TICK_SCRIPT = path.join(__dirname, 'stoned_animals_tick.js');
+
+function preflight() {
+  try {
+    const raw = execSync(
+      `psql dw_unified -At -F'|' -c "SELECT last_value, (SELECT max(id) FROM spoon_all_designs) FROM spoon_all_designs_id_seq;"`,
+      { encoding: 'utf8' }
+    ).trim();
+    const [seqStr, maxStr] = raw.split('|');
+    const seq = parseInt(seqStr, 10);
+    const max = parseInt(maxStr, 10);
+    if (!isFinite(seq) || !isFinite(max)) return;
+    if (seq < max) {
+      console.log(`[${new Date().toISOString()}] PREFLIGHT FIX: id_seq=${seq} < max=${max} — self-healing`);
+      execSync(`psql dw_unified -At -c "SELECT setval('spoon_all_designs_id_seq', ${max + 1}, false);"`);
+    }
+  } catch (e) {
+    console.error(`[${new Date().toISOString()}] preflight err: ${e.message}`);
+  }
+}
+
+let running = false;
+
+function fire() {
+  if (running) {
+    console.log(`[${new Date().toISOString()}] previous tick still running, skipping`);
+    return;
+  }
+  running = true;
+  preflight();
+  const t0 = Date.now();
+  const child = spawn('node', [TICK_SCRIPT], { stdio: 'inherit', cwd: ROOT });
+  const killTimer = setTimeout(() => {
+    if (!child.killed) {
+      console.error(`[${new Date().toISOString()}] tick exceeded 5min — sending SIGKILL`);
+      try { child.kill('SIGKILL'); } catch {}
+    }
+  }, 5 * 60_000);
+  child.on('exit', code => {
+    clearTimeout(killTimer);
+    running = false;
+    console.log(`[${new Date().toISOString()}] tick done in ${((Date.now()-t0)/1000).toFixed(1)}s (exit ${code})`);
+  });
+  child.on('error', err => {
+    clearTimeout(killTimer);
+    running = false;
+    console.error(`[${new Date().toISOString()}] tick spawn error:`, err.message);
+  });
+}
+
+console.log(`[${new Date().toISOString()}] stoned-animals daemon up · TICK_MS=${TICK_MS} STOP_HOUR=${STOP_HOUR}PT`);
+console.log(`[${new Date().toISOString()}] first tick in ${TICK_MS/1000}s`);
+setInterval(fire, TICK_MS);
diff --git a/scripts/stoned_animals_tick.js b/scripts/stoned_animals_tick.js
new file mode 100644
index 0000000..a791f13
--- /dev/null
+++ b/scripts/stoned_animals_tick.js
@@ -0,0 +1,75 @@
+#!/usr/bin/env node
+/**
+ * Single-tick stoned-animal design generator.
+ *
+ * Fired every 4 min by the wallco-stoned-animals pm2 daemon. Cross-tick
+ * deduper reads last 8 stoned-animal prompts from PG and rolls a fresh
+ * candidate that dodges the recent animal + style choices.
+ *
+ * Skips outside 18:00→05:59 PT window (same overnight cadence as
+ * drunk-animals).
+ */
+const { spawnSync, execSync } = require('child_process');
+const path = require('path');
+const { buildPrompt, ANIMALS, STYLES } = require('./stoned_animal_prompts');
+
+// No overnight gate — stoned-animals runs 24/7 until Steve stops the daemon
+// (`pm2 stop wallco-stoned-animals`). Drunk-animals had the 18:00→06:00 window
+// because Steve asked for "overnight only"; stoned-animals was requested in
+// the morning so we keep it firing.
+
+function recentlyUsed(n = 8) {
+  try {
+    const raw = execSync(
+      `psql dw_unified -At -F'|' -c "SELECT prompt FROM spoon_all_designs ` +
+      `WHERE category='stoned-animals' ORDER BY id DESC LIMIT ${n};"`,
+      { encoding: 'utf8' }
+    );
+    const animals = new Set();
+    const styles  = new Set();
+    for (const line of raw.split('\n').filter(Boolean)) {
+      for (const a of ANIMALS) if (line.includes(a)) { animals.add(a); break; }
+      for (const s of STYLES)  if (line.includes(s)) { styles.add(s);  break; }
+    }
+    return { animals, styles };
+  } catch { return { animals: new Set(), styles: new Set() }; }
+}
+
+function freshPrompt() {
+  const used = recentlyUsed(8);
+  for (let i = 0; i < 40; i++) {
+    const p = buildPrompt();
+    const a = ANIMALS.find(x => p.includes(x));
+    const s = STYLES.find(x => p.includes(x));
+    if (a && used.animals.has(a)) continue;
+    if (s && used.styles.has(s))  continue;
+    return p;
+  }
+  for (let i = 0; i < 20; i++) {
+    const p = buildPrompt();
+    const a = ANIMALS.find(x => p.includes(x));
+    const lastAnimal = [...used.animals].pop();
+    if (a && a === lastAnimal) continue;
+    return p;
+  }
+  return buildPrompt();
+}
+
+const ROOT = path.join(__dirname, '..');
+const prompt = freshPrompt();
+console.log(`[tick ${new Date().toISOString()}] ${prompt.slice(0, 100)}…`);
+
+const r = spawnSync('node', [
+  path.join(ROOT, 'scripts', 'generate_designs.js'),
+  '--n', '1',
+  '--kind', 'seamless_tile',
+  '--category', 'stoned-animals',
+  '--prompts', prompt,
+], { stdio: 'inherit', cwd: ROOT, timeout: 4 * 60_000 });
+
+spawnSync('python3', [path.join(ROOT, 'scripts', 'refresh_designs_snapshot.py')],
+          { stdio: 'inherit', cwd: ROOT, timeout: 60_000 });
+spawnSync('curl', ['-sf', '-m', '5', '-X', 'POST', 'http://127.0.0.1:9792/admin/reload-designs'],
+          { stdio: 'inherit', cwd: ROOT, timeout: 10_000 });
+
+process.exit(r.status || 0);
diff --git a/server.js b/server.js
index dbba39b..2969016 100644
--- a/server.js
+++ b/server.js
@@ -561,7 +561,8 @@ const NOUNS = {
   mixed:     ['Atelier','Studio','Origin','Folio','Sketch','Edit'],
   'art deco':       ['Deco','Fan','Sunburst','Chevron','Marquee'],
   'arts and crafts':['Morris','Crafts','Bough','Trellis','Vine'],
-  'drunk-animals':  ['Hiccup','Tipple','Tableau','Reverie','Soirée','Vignette','Carouse','Caprice','Saunter','Folly']
+  'drunk-animals':  ['Hiccup','Tipple','Tableau','Reverie','Soirée','Vignette','Carouse','Caprice','Saunter','Folly'],
+  'stoned-animals': ['Stealie','Trip','Stardust','Daydream','Vespers','Hazefield','Sundrift','Spore','Lullaby','Halcyon']
 };
 function hueName(hex) {
   if (!hex) return 'Bone';
@@ -2211,6 +2212,10 @@ app.get('/drunk-animals', (req, res) => {
   const qs = new URLSearchParams({ cat: 'drunk-animals', ...req.query }).toString();
   res.redirect(302, '/designs?' + qs);
 });
+app.get('/stoned-animals', (req, res) => {
+  const qs = new URLSearchParams({ cat: 'stoned-animals', ...req.query }).toString();
+  res.redirect(302, '/designs?' + qs);
+});
 
 // ── JSON feed for the /drunk-animals/live page — newest 60 designs with
 // just the fields the viewer needs (id/title/image_url/dominant_hex/prompt).
@@ -2686,6 +2691,19 @@ ${cat === 'drunk-animals' ? `
   </div>
 </section>
 ` : ''}
+${cat === 'stoned-animals' ? `
+<section style="padding:48px 24px 24px;text-align:center;background:linear-gradient(180deg,#0a1810 0%,#1a2a14 60%,#3a1830 100%);color:#fff;margin-bottom:0">
+  <div style="max-width:760px;margin:0 auto">
+    <p style="font-size:11px;letter-spacing:.28em;text-transform:uppercase;color:#ffeb3b;margin:0 0 8px;font-weight:600">Limited capsule · 4·20 Edition</p>
+    <h1 style="font-family:'Playfair Display',serif;font-weight:400;font-size:clamp(34px,5vw,56px);line-height:1.05;margin:0 0 14px;color:#fff">The Stoned Animals Collection</h1>
+    <p style="font-size:15px;line-height:1.6;color:#dfe4d0;margin:0 auto;max-width:560px">Grateful Dead meets Warhol in a woodland fog. Bloodshot bears, hazy wolves, glassy-eyed owls reclining on mushroom caps with bongs, gummies, and joints. Strictly NO palms — ferns, wildflowers, herbs, mosses only.</p>
+    <div style="margin-top:18px;display:flex;gap:10px;justify-content:center;flex-wrap:wrap;font-size:12px">
+      <span style="padding:4px 10px;border:1px solid #ffeb3b;border-radius:14px;color:#ffeb3b"><strong>${total}</strong> designs &middot; one every 4 min</span>
+      <span style="padding:4px 10px;border:1px solid #ff7c4d;border-radius:14px;color:#ff7c4d">live until 06:00 PT</span>
+    </div>
+  </div>
+</section>
+` : ''}
 <section class="catalog-section">
   <div class="catalog-toolbar">
     <form method="get" action="/designs" class="filter-form">

← 6fb2136 drunk-animals: daemon 5-min hard timeout on hung ticks  ·  back to Wallco Ai  ·  drunk-animals v2 — flowers only (no leaves), drinks in hand, 9ee1fef →