← back to Crazy News Channel
p24: fix cartoon-page generators to emit zero inline styles going forward
3619366df0689a4110194c2a8c20fa74e68d0a29 · 2026-09-25 09:16:24 -0700 · Steve
daily-cartoons/approve.py (writes a new cartoons/<date>-<slug>.html for every
newly-approved cartoon) and daily-cartoons/build_review.py (writes the local
admin review queue) each emitted their own <style> block with a hardcoded
palette (--cream/--ink/--mint, or --bg/--ink/--mint/--card/--dim + a
prefers-color-scheme dark swap) and a Georgia font, on top of already
linking ../assets/style.css. Fixed both generators to link only the shared
stylesheet and use new body classes (cartoon-page-simple, cartoon-queue-page)
whose rules now live in style.css, so every page these scripts produce from
here on stays on the one site-wide palette/font. Regenerated review.html
(local-only queue, 5 items) to verify.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Files touched
M daily-cartoons/approve.pyM daily-cartoons/build_review.pyM daily-cartoons/review.html
Diff
commit 3619366df0689a4110194c2a8c20fa74e68d0a29
Author: Steve <steve@designerwallcoverings.com>
Date: Fri Sep 25 09:16:24 2026 -0700
p24: fix cartoon-page generators to emit zero inline styles going forward
daily-cartoons/approve.py (writes a new cartoons/<date>-<slug>.html for every
newly-approved cartoon) and daily-cartoons/build_review.py (writes the local
admin review queue) each emitted their own <style> block with a hardcoded
palette (--cream/--ink/--mint, or --bg/--ink/--mint/--card/--dim + a
prefers-color-scheme dark swap) and a Georgia font, on top of already
linking ../assets/style.css. Fixed both generators to link only the shared
stylesheet and use new body classes (cartoon-page-simple, cartoon-queue-page)
whose rules now live in style.css, so every page these scripts produce from
here on stays on the one site-wide palette/font. Regenerated review.html
(local-only queue, 5 items) to verify.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---
daily-cartoons/approve.py | 11 +++++---
daily-cartoons/build_review.py | 18 +++----------
daily-cartoons/review.html | 61 ++++++++++++++++++++++++++++++------------
3 files changed, 55 insertions(+), 35 deletions(-)
diff --git a/daily-cartoons/approve.py b/daily-cartoons/approve.py
index 9908a9a..3f13bd4 100755
--- a/daily-cartoons/approve.py
+++ b/daily-cartoons/approve.py
@@ -36,12 +36,15 @@ def main():
e = html.escape
media = (f'<video controls playsinline poster="media/{base}.jpg" src="media/{base}.mp4"></video>' if has_clip
else f'<img src="media/{base}.jpg" alt="{e(m["title"])}">')
+ # TK-12226: link ONLY the shared stylesheet — no per-page <style> block,
+ # no locally hardcoded palette/font. Layout lives in assets/style.css
+ # under body.cartoon-page-simple so every future approved cartoon page
+ # renders in the site's one fixed palette + one font, same as every
+ # other page, with nothing that changes on click.
open(os.path.join(CART, base + ".html"), "w").write(f'''<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1"><title>{e(m["title"])}</title>
-<link rel="stylesheet" href="../assets/style.css"><style>:root{{--cream:#cdf5e0;--ink:#0b0b0c;--mint:#0f9d78}}
-body{{font-family:Georgia,"Times New Roman",serif;max-width:1000px;margin:0 auto;padding:24px 16px}}
-video,img{{display:block;width:100%;border:4px solid var(--ink)}} h1{{margin:14px 0 4px}} .cap{{font-style:italic}}</style></head>
-<body><p><a href="index.html">← Cartoon Desk</a></p>{media}<h1>{e(m["title"])}</h1>
+<link rel="stylesheet" href="../assets/style.css"></head>
+<body class="cartoon-page-simple"><p><a href="index.html">← Cartoon Desk</a></p>{media}<h1>{e(m["title"])}</h1>
<p class="cap">“{e(m["caption"])}”</p><p><small>AI-generated editorial cartoon in the manner of Paul Conrad. Invented figures only.</small></p></body></html>''')
mf = os.path.join(CART, "manifest.js"); src = open(mf).read()
mm = re.search(r"(window\.P24_CARTOONS\s*=\s*)(\[[\s\S]*\])(\s*;\s*)$", src)
diff --git a/daily-cartoons/build_review.py b/daily-cartoons/build_review.py
index 9abf4cc..2f7e5f6 100755
--- a/daily-cartoons/build_review.py
+++ b/daily-cartoons/build_review.py
@@ -39,22 +39,12 @@ def build():
its = items()
its.sort(key=lambda m: m.get("created_at", ""), reverse=True)
total = sum(m.get("cost", {}).get("total", 0) for m in its)
+ # TK-12226: link ONLY the shared stylesheet (assets/style.css) — no
+ # per-page <style> block, no locally hardcoded palette/font/dark-mode
+ # media query. Layout lives in style.css under body.cartoon-queue-page.
page = f'''<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>P24 Cartoon Queue</title>
-<style>
-:root{{--bg:#cdf5e0;--ink:#0b0b0c;--mint:#0f9d78;--card:#f3fbee;--dim:#3d5a4f}}
-@media (prefers-color-scheme:dark){{:root:not([data-theme="light"]){{--bg:#0b0b0c;--ink:#e8f6ee;--card:#15201c;--dim:#9fc4b4}}}}
-*{{box-sizing:border-box}} body{{margin:0;background:var(--bg);color:var(--ink);font-family:Georgia,"Times New Roman",serif;padding:16px}}
-header{{max-width:1400px;margin:0 auto 14px;display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}}
-header>div{{min-width:0}} code{{word-break:break-all}} h1{{margin:0;font-size:1.5rem}} .note{{color:var(--dim);font-size:.9rem;margin:4px 0 0}}
-.ctrl{{display:flex;gap:12px;align-items:center;font-size:.9rem}} select,input{{font:inherit}}
-#grid{{max-width:1400px;margin:0 auto;display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(min(var(--min,340px),100%),1fr))}}
-.card{{background:var(--card);border:3px solid var(--ink);overflow:hidden}} .card video,.card img{{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;background:#000}}
-.body{{padding:10px 12px}} h2{{margin:0 0 4px;font-size:1.15rem}} .cap{{margin:0 0 8px;font-style:italic;color:var(--dim)}}
-.chips{{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}} .chip{{font:12px/1.6 system-ui,sans-serif;border:1px solid var(--mint);padding:0 8px;border-radius:10px}}
-.st-error,.st-incomplete-cap{{border-color:#c0392b;color:#c0392b}} .st-approved{{background:var(--mint);color:#fff}}
-details{{font-size:.8rem;color:var(--dim)}} .cmd{{display:block;margin-top:8px;font-size:11px;background:var(--ink);color:var(--bg);padding:6px;cursor:pointer;word-break:break-all}}
-</style></head><body>
+<link rel="stylesheet" href="../assets/style.css"></head><body class="cartoon-queue-page">
<header><div><h1>🖋️ P24 Daily Cartoon Queue</h1>
<p class="note">{len(its)} queued · total spend ${total:.3f} · LOCAL review only — approving copies into <code>cartoons/</code> locally; nothing deploys.</p></div>
<div class="ctrl"><label>Sort <select id="sort"><option value="new">Newest</option><option value="old">Oldest</option><option value="title">Title A→Z</option><option value="cost">Cost ↓</option></select></label>
diff --git a/daily-cartoons/review.html b/daily-cartoons/review.html
index 769cf1a..43ad30d 100644
--- a/daily-cartoons/review.html
+++ b/daily-cartoons/review.html
@@ -1,25 +1,52 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>P24 Cartoon Queue</title>
-<style>
-:root{--bg:#cdf5e0;--ink:#0b0b0c;--mint:#0f9d78;--card:#f3fbee;--dim:#3d5a4f}
-@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--bg:#0b0b0c;--ink:#e8f6ee;--card:#15201c;--dim:#9fc4b4}}
-*{box-sizing:border-box} body{margin:0;background:var(--bg);color:var(--ink);font-family:Georgia,"Times New Roman",serif;padding:16px}
-header{max-width:1400px;margin:0 auto 14px;display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}
-header>div{min-width:0} code{word-break:break-all} h1{margin:0;font-size:1.5rem} .note{color:var(--dim);font-size:.9rem;margin:4px 0 0}
-.ctrl{display:flex;gap:12px;align-items:center;font-size:.9rem} select,input{font:inherit}
-#grid{max-width:1400px;margin:0 auto;display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(min(var(--min,340px),100%),1fr))}
-.card{background:var(--card);border:3px solid var(--ink);overflow:hidden} .card video,.card img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;background:#000}
-.body{padding:10px 12px} h2{margin:0 0 4px;font-size:1.15rem} .cap{margin:0 0 8px;font-style:italic;color:var(--dim)}
-.chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px} .chip{font:12px/1.6 system-ui,sans-serif;border:1px solid var(--mint);padding:0 8px;border-radius:10px}
-.st-error,.st-incomplete-cap{border-color:#c0392b;color:#c0392b} .st-approved{background:var(--mint);color:#fff}
-details{font-size:.8rem;color:var(--dim)} .cmd{display:block;margin-top:8px;font-size:11px;background:var(--ink);color:var(--bg);padding:6px;cursor:pointer;word-break:break-all}
-</style></head><body>
+<link rel="stylesheet" href="../assets/style.css"></head><body class="cartoon-queue-page">
<header><div><h1>🖋️ P24 Daily Cartoon Queue</h1>
-<p class="note">1 queued · total spend $0.103 · LOCAL review only — approving copies into <code>cartoons/</code> locally; nothing deploys.</p></div>
+<p class="note">5 queued · total spend $0.515 · LOCAL review only — approving copies into <code>cartoons/</code> locally; nothing deploys.</p></div>
<div class="ctrl"><label>Sort <select id="sort"><option value="new">Newest</option><option value="old">Oldest</option><option value="title">Title A→Z</option><option value="cost">Cost ↓</option></select></label>
<label>Size <input id="dens" type="range" min="220" max="640" step="20" value="340"></label></div></header>
-<main id="grid"><article class="card" data-created="2026-09-24T22:12:18+00:00" data-title="Committee of Shadows" data-cost="0.103">
- <video controls preload="none" poster="queue/2026-09-24/committee-of-shadows/poster.jpg" src="queue/2026-09-24/committee-of-shadows/clip.mp4"></video>
+<main id="grid"><article class="card" data-created="2026-09-25T14:29:23+00:00" data-title="Infinite Scroll" data-cost="0.103">
+ <div class="nomedia">no media</div>
+ <div class="body">
+ <h2>Infinite Scroll</h2>
+ <p class="cap">“Scrolling: where time goes to die.”</p>
+ <div class="chips"><span class="chip when" title="2026-09-25T14:29:23+00:00" data-iso="2026-09-25T14:29:23+00:00">🕓 2026-09-25T14:29:23+00:00</span>
+ <span class="chip">$0.103</span><span class="chip st-queued">queued</span></div>
+ <details><summary>prompts</summary><p><b>image:</b> Black and white single-panel editorial cartoon in the style of Paul Conrad, 1970s newspaper op-ed page. Pen-and-ink with loose, confident, slightly jagged brush contour lines and dense directional crosshatching, scratchboard-like white highlights cut out of heavy solid black. A disheveled figure hunched over a laptop, endlessly scrolling through an infinite scroll of repetitive cat memes. The endless repetition is illustrated with identical cat faces and 'lol' captions filling the screen. Figures are invented anonymous caricatures, not any real person. High contrast, stark, absurd, ink-heavy, hand-drawn newspaper cartoon. No color, no gradients, no 3D render, no photorealism, no vector clip art, no text, no letters, no caption, no speech bubbles, no watermark, no signature.</p><p><b>motion:</b> Animate this black-and-white pen-and-ink editorial cartoon, keep the hand-drawn ink style throughout, static camera. The cat images rapidly scroll past in a blur, each with the same exaggerated 'lol' caption, making a monotonous typing sound. Slow, dry, deadpan comedy timing.</p></details>
+ <code class="cmd" title="click to copy">python3 daily-cartoons/approve.py infinite-scroll --date 2026-09-25 --story-id <story-id></code>
+ </div>
+</article><article class="card" data-created="2026-09-25T14:27:36+00:00" data-title="Tech Tyrant" data-cost="0.103">
+ <div class="nomedia">no media</div>
+ <div class="body">
+ <h2>Tech Tyrant</h2>
+ <p class="cap">“The algorithm always knows best.”</p>
+ <div class="chips"><span class="chip when" title="2026-09-25T14:27:36+00:00" data-iso="2026-09-25T14:27:36+00:00">🕓 2026-09-25T14:27:36+00:00</span>
+ <span class="chip">$0.103</span><span class="chip st-queued">queued</span></div>
+ <details><summary>prompts</summary><p><b>image:</b> Black and white single-panel editorial cartoon in the style of Paul Conrad, 1970s newspaper op-ed page. Pen-and-ink with loose, confident, slightly jagged brush contour lines and dense directional crosshatching, scratchboard-like white highlights cut out of heavy solid black. A stern-faced figure sits on a high-tech throne surrounded by screens. A glowing blue hand projects from one of the screens, gesturing towards an abstract image on another screen, which represents 'the people' being manipulated and guided like puppets. Figures are invented anonymous caricatures, not any real person. High contrast, stark, absurd, ink-heavy, hand-drawn newspaper cartoon. No color, no gradients, no 3D render, no photorealism, no vector clip art, no text, no letters, no caption, no speech bubbles, no watermark, no signature.</p><p><b>motion:</b> Animate this black-and-white pen-and-ink editorial cartoon, keep the hand-drawn ink style throughout, static camera. The blue hand swipes across the screens rapidly, causing the abstract representation of the people to nod in unison as if controlled by a puppet master. Slow, dry, deadpan comedy timing.</p></details>
+ <code class="cmd" title="click to copy">python3 daily-cartoons/approve.py tech-tyrant --date 2026-09-25 --story-id <story-id></code>
+ </div>
+</article><article class="card" data-created="2026-09-25T14:25:59+00:00" data-title="Senator's Shadow War" data-cost="0.103">
+ <div class="nomedia">no media</div>
+ <div class="body">
+ <h2>Senator's Shadow War</h2>
+ <p class="cap">“In shadowy negotiations, power is real.”</p>
+ <div class="chips"><span class="chip when" title="2026-09-25T14:25:59+00:00" data-iso="2026-09-25T14:25:59+00:00">🕓 2026-09-25T14:25:59+00:00</span>
+ <span class="chip">$0.103</span><span class="chip st-queued">queued</span></div>
+ <details><summary>prompts</summary><p><b>image:</b> Black and white single-panel editorial cartoon in the style of Paul Conrad, 1970s newspaper op-ed page. Pen-and-ink with loose, confident, slightly jagged brush contour lines and dense directional crosshatching, scratchboard-like white highlights cut out of heavy solid black. A jowly senator stands on a podium casting an enormous shadow across a dimly lit room. His shadowy figure morphs into menacing figures and abstract shapes, like swords or masks, battling each other in the background. Figures are invented anonymous caricatures, not any real person. High contrast, stark, absurd, ink-heavy, hand-drawn newspaper cartoon. No color, no gradients, no 3D render, no photorealism, no vector clip art, no text, no letters, no caption, no speech bubbles, no watermark, no signature.</p><p><b>motion:</b> Animate this black-and-white pen-and-ink editorial cartoon, keep the hand-drawn ink style throughout, static camera. The senator's silhouette winks and gestures, causing his shadow to morph into different forms that clash violently. Slow, dry, deadpan comedy timing.</p></details>
+ <code class="cmd" title="click to copy">python3 daily-cartoons/approve.py senator-s-shadow-war --date 2026-09-25 --story-id <story-id></code>
+ </div>
+</article><article class="card" data-created="2026-09-25T14:23:48+00:00" data-title="Bureaucrats and Bubbles" data-cost="0.103">
+ <div class="nomedia">no media</div>
+ <div class="body">
+ <h2>Bureaucrats and Bubbles</h2>
+ <p class="cap">“When committees debate, they just inflate ideas.”</p>
+ <div class="chips"><span class="chip when" title="2026-09-25T14:23:48+00:00" data-iso="2026-09-25T14:23:48+00:00">🕓 2026-09-25T14:23:48+00:00</span>
+ <span class="chip">$0.103</span><span class="chip st-queued">queued</span></div>
+ <details><summary>prompts</summary><p><b>image:</b> Black and white single-panel editorial cartoon in the style of Paul Conrad, 1970s newspaper op-ed page. Pen-and-ink with loose, confident, slightly jagged brush contour lines and dense directional crosshatching, scratchboard-like white highlights cut out of heavy solid black. A committee of identical bureaucrats sit at a rectangular table, each surrounded by floating soap bubbles. They gesture excitedly towards the bubbles, which seem to grow larger with their every word, obscuring their faces in an absurd balloon maze. Figures are invented anonymous caricatures, not any real person. High contrast, stark, absurd, ink-heavy, hand-drawn newspaper cartoon. No color, no gradients, no 3D render, no photorealism, no vector clip art, no text, no letters, no caption, no speech bubbles, no watermark, no signature.</p><p><b>motion:</b> Animate this black-and-white pen-and-ink editorial cartoon, keep the hand-drawn ink style throughout, static camera. The bureaucrats' hands wave rapidly as the bubbles expand and pop in exaggerated slow motion, making funny popping sounds. Slow, dry, deadpan comedy timing.</p></details>
+ <code class="cmd" title="click to copy">python3 daily-cartoons/approve.py bureaucrats-and-bubbles --date 2026-09-25 --story-id <story-id></code>
+ </div>
+</article><article class="card" data-created="2026-09-24T22:12:18+00:00" data-title="Committee of Shadows" data-cost="0.103">
+ <img src="queue/2026-09-24/committee-of-shadows/poster.jpg" alt="">
<div class="body">
<h2>Committee of Shadows</h2>
<p class="cap">“In darkness, they find clarity.”</p>
← f3c1a2d p24: move all 22 cartoon-strip pages + the reference page on
·
back to Crazy News Channel
·
auto-data-snapshot: 2026-09-25T09:20:47 (1 data files) — .cl 010df2d →