← back to Crazy News Channel Shadowman
cleanup: remove filibuster-marathon (duplicate of Cloture o'Clock) + test scratch files
0f638f483e44e85a89176b431f20c5f19873579e · 2026-09-24 15:03:55 -0700 · Steve Abrams
Files touched
D cartoons/20260924-filibuster-marathon.html
Diff
commit 0f638f483e44e85a89176b431f20c5f19873579e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 24 15:03:55 2026 -0700
cleanup: remove filibuster-marathon (duplicate of Cloture o'Clock) + test scratch files
---
cartoons/20260924-filibuster-marathon.html | 330 -----------------------------
1 file changed, 330 deletions(-)
diff --git a/cartoons/20260924-filibuster-marathon.html b/cartoons/20260924-filibuster-marathon.html
deleted file mode 100644
index 7e72c98..0000000
--- a/cartoons/20260924-filibuster-marathon.html
+++ /dev/null
@@ -1,330 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta charset="UTF-8" />
-<meta name="viewport" content="width=device-width, initial-scale=1.0" />
-<title>The Filibuster Marathon — P24 Political Cartoon Desk</title>
-<meta name="description" content="An original invented-satire strip: Delegate Holloway filibusters the fictional Assembly by reading anything within arm's reach, while a Dali-style clock melts and the chamber falls asleep standing up." />
-<link rel="stylesheet" href="../assets/style.css" />
-<style>
-header{padding:16px 20px 10px;border-bottom:3px solid var(--rule);display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:10px}
-header a.back{font-family:-apple-system,sans-serif;font-size:.8rem;color:var(--ink-dim);text-decoration:none;border:1px solid var(--ink-dim);border-radius:6px;padding:5px 10px}
-.kicker{font-family:-apple-system,sans-serif;font-size:.7rem;letter-spacing:.08em;text-transform:uppercase;color:var(--accent)}
-h1{font-size:1.7rem;margin-top:2px}
-.dek{font-style:italic;color:var(--ink-dim);max-width:60ch;margin-top:4px}
-main{max-width:900px;margin:0 auto;padding:18px 20px}
-.strip{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
-@media (max-width:720px){ .strip{grid-template-columns:1fr} }
-figure{margin:0;background:var(--panel);border:3px solid var(--rule);border-radius:8px;overflow:hidden;display:flex;flex-direction:column}
-.phead{display:flex;justify-content:space-between;font-family:-apple-system,sans-serif;font-size:.65rem;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-dim);padding:6px 10px;border-bottom:1px solid var(--ink-dim)}
-.art{width:100%;aspect-ratio:1/1;display:block;cursor:pointer;background:transparent}
-.art:focus-visible{outline:3px solid var(--focus); outline-offset:-3px}
-figcaption{font-family:-apple-system,sans-serif;font-size:.8rem;color:var(--ink-dim);padding:8px 10px}
-.cover{width:100%;height:100%;background:repeating-linear-gradient(45deg,var(--panel),var(--panel) 10px,color-mix(in srgb, var(--panel) 85%, var(--ink)) 10px,color-mix(in srgb, var(--panel) 85%, var(--ink)) 20px);border:none;display:flex;align-items:center;justify-content:center;font-family:-apple-system,sans-serif;font-size:.85rem;color:var(--ink-dim);cursor:pointer;aspect-ratio:1/1}
-.cover:hover{color:var(--ink)}
-.dock{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:16px 0;font-family:-apple-system,sans-serif}
-button.primary,button.twist{font-family:-apple-system,sans-serif;font-size:.9rem;font-weight:700;border-radius:6px;padding:9px 16px;cursor:pointer;border:2px solid var(--rule)}
-button.primary{background:var(--ink);color:var(--panel)}
-button.twist{background:var(--seal);color:#241c14;border-color:var(--seal)}
-button:disabled{opacity:.45;cursor:not-allowed}
-button.theme{margin-left:auto;background:transparent;border:1px solid var(--ink-dim);color:var(--ink-dim);border-radius:6px;padding:6px 10px;font-family:-apple-system,sans-serif;font-size:.8rem;cursor:pointer}
-#status{font-family:-apple-system,sans-serif;font-size:.82rem;padding:8px 12px;border-radius:6px;border:1px solid var(--ink-dim);color:var(--ink-dim);min-height:1.2em}
-#status.ok{border-color:var(--accent2);color:var(--accent2)}
-#status.err{border-color:var(--accent);color:var(--accent)}
-#status.info{border-color:var(--focus);color:var(--focus)}
-footer{max-width:900px;margin:20px auto 0;padding:0 20px;font-family:-apple-system,sans-serif;font-size:.72rem;color:var(--ink-dim)}
-.hint{font-family:-apple-system,sans-serif;font-size:.72rem;color:var(--ink-dim);margin-top:6px}
-.seal-anim{transition:transform .3s ease}
-@media (prefers-reduced-motion: reduce){ .seal-anim{transition:none} }
-</style>
-</head>
-<body data-mood="politics">
-<header>
- <div>
- <div class="kicker">P24 Political Cartoon Desk · Invented Satire</div>
- <h1>The Filibuster Marathon</h1>
- <p class="dek">Delegate Holloway holds the floor of the invented Assembly by reading anything within arm's reach. Nobody has stopped him. Nobody remembers why he started.</p>
- </div>
- <div style="display:flex;flex-direction:column;gap:8px;align-items:flex-end">
- <a class="back" href="index.html">← Cartoon Desk</a>
- <button class="theme" id="themeBtn" type="button" aria-pressed="false">Dark mode: off</button>
- </div>
-</header>
-<main>
- <div class="strip" id="strip">
- <figure class="panel" data-i="0">
- <div class="phead"><span>Panel 1 · The Floor Is His</span><span id="stamp0"></span></div>
- <svg class="art" id="art0" viewBox="0 0 300 300" role="img" tabindex="0"></svg>
- <button class="cover" id="cover0" type="button">Click, tap, or press N to begin</button>
- <figcaption id="cap0"></figcaption>
- </figure>
- <figure class="panel" data-i="1">
- <div class="phead"><span>Panel 2 · Time, Melting</span><span id="stamp1"></span></div>
- <svg class="art" id="art1" viewBox="0 0 300 300" role="img" tabindex="0"></svg>
- <button class="cover" id="cover1" type="button" disabled>In queue</button>
- <figcaption id="cap1"></figcaption>
- </figure>
- <figure class="panel" data-i="2">
- <div class="phead"><span>Panel 3 · The Chamber Sleeps</span><span id="stamp2"></span></div>
- <svg class="art" id="art2" viewBox="0 0 300 300" role="img" tabindex="0"></svg>
- <button class="cover" id="cover2" type="button" disabled>In queue</button>
- <figcaption id="cap2"></figcaption>
- </figure>
- </div>
-
- <div class="dock">
- <button class="primary" id="nextBtn" type="button">Process Panel 1</button>
- <button class="twist" id="twistBtn" type="button">Plot Twist!</button>
- <div id="status" role="status" aria-live="polite"></div>
- </div>
- <p class="hint">Keys: N/→ next panel · T plot twist (swaps Holloway's reading material) · click a panel to advance</p>
-</main>
-<footer>All delegates, the Assembly, and its chamber are invented. No actual legislative body was inconvenienced, though several fictional ones dozed off. Part of PANDEMONIUM-24.</footer>
-
-<script>
-(function(){
- const NS = 'http://www.w3.org/2000/svg';
- function el(tag, attrs, parent){
- const n = document.createElementNS(NS, tag);
- for (const k in attrs) n.setAttribute(k, attrs[k]);
- if (parent) parent.appendChild(n);
- return n;
- }
- function reduced(){ return matchMedia('(prefers-reduced-motion: reduce)').matches; }
-
- // ---- invented reading material Holloway filibusters with, cycled by Plot Twist ----
- const MATERIALS = [
- { label: 'the Springfield County phone book', sub: 'Vol. 2, "Aab–Kle"', color: '#b5302f' },
- { label: 'a family-size cereal box', sub: 'nutrition panel, both sides', color: '#0f6b52' },
- { label: 'bookshelf assembly instructions', sub: 'translated from Swedish, badly', color: '#c9a227' },
- { label: 'his own bill', sub: 'still stuck in committee', color: '#6b4fa0' },
- ];
- let materialIdx = 0;
-
- // ---- invented Assembly members, asleep at their desks in panel 3 ----
- const MEMBERS = [
- { name: 'Delegate Oduya', color: '#b5302f' },
- { name: 'Delegate Prine', color: '#0f6b52' },
- { name: 'Delegate Vance-Kettle', color: '#c9a227' },
- { name: 'Delegate Abernathy', color: '#6b4fa0' },
- { name: 'Delegate Suh', color: '#0b3d91' },
- { name: 'Delegate Marrow', color: '#b5302f' },
- ];
-
- function podium(svg, cx, cy){
- el('rect', { x: cx-24, y: cy, width:48, height:60, fill:'currentColor', opacity:0.35, rx:4 }, svg);
- el('rect', { x: cx-30, y: cy-6, width:60, height:10, fill:'currentColor', opacity:0.5, rx:2 }, svg);
- }
-
- function holloway(svg, cx, cy, r, color, material){
- const g = el('g', {}, svg);
- // body
- el('path', { d: `M ${cx - r*0.55} ${cy + r*0.7} Q ${cx} ${cy + r*0.25} ${cx + r*0.55} ${cy + r*0.7}`, fill: 'none', stroke: color, 'stroke-width': r*0.32, 'stroke-linecap':'round' }, g);
- // head
- el('circle', { cx, cy: cy - r*0.15, r: r*0.34, fill: color }, g);
- // held reading material (a rectangle tilted up, "held open")
- const mg = el('g', { transform: `rotate(-8 ${cx + r*0.35} ${cy + r*0.25})` }, g);
- el('rect', { x: cx + r*0.05, y: cy + r*0.05, width: r*0.75, height: r*0.55, fill: 'var(--panel)', stroke: color, 'stroke-width': 2, rx: 2 }, mg);
- for (let i=0;i<3;i++){
- el('line', { x1: cx + r*0.15, y1: cy + r*0.2 + i*8, x2: cx + r*0.68, y2: cy + r*0.2 + i*8, stroke: color, 'stroke-width': 1.4, opacity:0.5 }, mg);
- }
- if (material) {
- const t = el('text', { x: cx, y: cy + r + 34, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-weight':'700', 'font-size':'11', fill: 'currentColor' }, g);
- t.textContent = 'Delegate Holloway';
- const t2 = el('text', { x: cx, y: cy + r + 48, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'9.5', fill: 'var(--ink-dim)' }, g);
- t2.textContent = 'reading: ' + material.label;
- }
- return g;
- }
-
- function chamberClock(svg, cx, cy, r, color){
- el('circle', { cx, cy, r, fill:'none', stroke: color, 'stroke-width': 3 }, svg);
- el('line', { x1:cx, y1:cy, x2:cx, y2:cy-r*0.6, stroke: color, 'stroke-width':2.4, 'stroke-linecap':'round' }, svg);
- el('line', { x1:cx, y1:cy, x2:cx+r*0.4, y2:cy+r*0.25, stroke: color, 'stroke-width':2.4, 'stroke-linecap':'round' }, svg);
- }
-
- function meltingClock(svg, cx, cy, r, color, melt){
- // a Dali-style melting clock: the face droops over an edge, hands bend with it
- const droop = 18 + melt * 14;
- const path = `M ${cx-r} ${cy-r*0.2}
- C ${cx-r} ${cy-r}, ${cx+r} ${cy-r}, ${cx+r} ${cy-r*0.2}
- C ${cx+r} ${cy+r*0.5}, ${cx+r*0.5} ${cy+r*0.9+droop}, ${cx} ${cy+r*0.95+droop}
- C ${cx-r*0.5} ${cy+r*0.9+droop}, ${cx-r} ${cy+r*0.5}, ${cx-r} ${cy-r*0.2} Z`;
- el('path', { d: path, fill:'var(--panel)', stroke: color, 'stroke-width': 3 }, svg);
- // droopy hands, bent partway down the melt
- el('path', { d: `M ${cx} ${cy} Q ${cx-4} ${cy-r*0.35} ${cx-2} ${cy-r*0.55}`, fill:'none', stroke: color, 'stroke-width':2.2, 'stroke-linecap':'round' }, svg);
- el('path', { d: `M ${cx} ${cy} Q ${cx+r*0.2} ${cy+r*0.15} ${cx+r*0.3+droop*0.3} ${cy+r*0.35+droop*0.5}`, fill:'none', stroke: color, 'stroke-width':2.2, 'stroke-linecap':'round' }, svg);
- // a few numerals sliding down the droop
- ['XII','III','VI'].forEach((n,i) => {
- const t = el('text', { x: cx - r*0.5 + i*r*0.5, y: cy - r*0.05 + i*(3+melt*3), 'text-anchor':'middle', 'font-family':'Georgia,serif', 'font-size':'9', fill: color, opacity: 0.75 }, svg);
- t.textContent = n;
- });
- }
-
- function sleepingMember(svg, cx, cy, r, color, standing){
- const g = el('g', {}, svg);
- if (standing) {
- // asleep standing up, head lolled back
- el('path', { d: `M ${cx - r*0.4} ${cy + r*0.9} L ${cx - r*0.3} ${cy - r*0.1} L ${cx + r*0.3} ${cy - r*0.1} L ${cx + r*0.4} ${cy + r*0.9} Z`, fill: color, opacity:0.3 }, g);
- el('circle', { cx: cx + r*0.12, cy: cy - r*0.45, r: r*0.3, fill: color }, g);
- } else {
- // slumped forward over a desk
- el('rect', { x: cx - r*0.6, y: cy + r*0.35, width: r*1.2, height: r*0.18, fill:'currentColor', opacity:0.35, rx:2 }, g);
- el('ellipse', { cx, cy: cy + r*0.15, rx: r*0.5, ry: r*0.32, fill: color, opacity: 0.9 }, g);
- el('circle', { cx: cx - r*0.15, cy: cy - r*0.05, r: r*0.28, fill: color }, g);
- }
- // "Z" sleep marks
- const zg = el('g', { opacity: 0.7 }, g);
- ['z','Z','Z'].forEach((z,i) => {
- const t = el('text', { x: cx + r*0.55 + i*7, y: cy - r*0.5 - i*10, 'font-family':'-apple-system,sans-serif', 'font-weight':'700', 'font-size': 8 + i*3, fill: color }, zg);
- t.textContent = z;
- });
- return g;
- }
-
- function panel0(svg, material){
- svg.innerHTML = '';
- podium(svg, 130, 190);
- holloway(svg, 130, 130, 46, material.color, material);
- chamberClock(svg, 250, 55, 22, 'var(--ink-dim)');
- const t = el('text', { x: 250, y: 90, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'8.5', fill:'var(--ink-dim)' }, svg);
- t.textContent = 'Day 1, Hour 1';
- const b = el('text', { x:150, y:270, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'11', 'font-weight':'700', fill:'currentColor' }, svg);
- b.textContent = '"I yield to no one," says Delegate Holloway.';
- const b2 = el('text', { x:150, y:286, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'9.5', fill:'var(--ink-dim)' }, svg);
- b2.textContent = 'He opens ' + material.label + ' to page one.';
- }
-
- function panel1(svg, material, melt){
- svg.innerHTML = '';
- podium(svg, 100, 195);
- holloway(svg, 100, 138, 40, material.color, null);
- meltingClock(svg, 205, 120, 46, 'var(--accent)', melt);
- const t = el('text', { x: 205, y: 60, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'8.5', fill:'var(--ink-dim)' }, svg);
- t.textContent = 'Hour ' + (14 + melt*11) + ', give or take';
- const b = el('text', { x:150, y:270, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'11', 'font-weight':'700', fill:'currentColor' }, svg);
- b.textContent = 'He is now on ' + material.sub + '.';
- const b2 = el('text', { x:150, y:286, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'9.5', fill:'var(--ink-dim)' }, svg);
- b2.textContent = 'The chamber clock has stopped pretending to be on time.';
- }
-
- function panel2(svg, wave){
- svg.innerHTML = '';
- // rows of desks; some slumped, one asleep standing at the aisle mic
- const cols = 3, rows = 2;
- let i = 0;
- for (let r0=0; r0<rows; r0++){
- for (let c0=0; c0<cols; c0++){
- const mx = 62 + c0*90;
- const my = 90 + r0*95;
- const mem = MEMBERS[(i + wave) % MEMBERS.length];
- sleepingMember(svg, mx, my, 26, mem.color, false);
- i++;
- }
- }
- // one delegate asleep standing at the aisle microphone, mid-objection
- sleepingMember(svg, 250, 235, 24, MEMBERS[(wave+2)%MEMBERS.length].color, true);
- el('rect', { x: 244, y: 258, width: 4, height: 24, fill:'currentColor', opacity:0.4 }, svg);
- el('circle', { cx: 246, cy: 256, r: 4, fill:'currentColor', opacity:0.5 }, svg);
- const b = el('text', { x:150, y:280, 'text-anchor':'middle', 'font-family':'-apple-system,sans-serif', 'font-size':'11', 'font-weight':'700', fill:'currentColor' }, svg);
- b.textContent = 'Nobody has left the chamber. Several have left consciousness.';
- }
-
- const CAPTIONS = [
- 'Delegate Holloway takes the floor of the invented Assembly to object to a routine motion, and does not intend to give it back.',
- 'Hours blur. The reading material changes; the objection, somehow, does not resolve.',
- 'The Assembly remains, technically, in session.',
- ];
-
- const state = { revealed: 0, twists: 0 };
-
- function renderPanel(i){
- const svg = document.getElementById('art' + i);
- const material = MATERIALS[materialIdx];
- if (i === 0) panel0(svg, material);
- if (i === 1) panel1(svg, material, state.twists % 3);
- if (i === 2) panel2(svg, state.twists);
- document.getElementById('cap' + i).textContent = CAPTIONS[i];
- document.getElementById('stamp' + i).textContent = i <= state.revealed ? ['ON THE RECORD','STILL SPEAKING','QUORUM UNCLEAR'][i] : '';
- const cover = document.getElementById('cover' + i);
- cover.hidden = i <= state.revealed - 1 || (i === state.revealed);
- if (i === state.revealed) { cover.hidden = false; cover.disabled = false; cover.textContent = i === 0 ? 'Click, tap, or press N to begin' : 'Click, tap, or press N to process'; }
- }
-
- function paintAll(){
- for (let i=0;i<3;i++) {
- renderPanel(i);
- document.getElementById('art'+i).setAttribute('tabindex', i === state.revealed ? '0' : '-1');
- }
- syncButtons();
- }
-
- function syncButtons(){
- const nextBtn = document.getElementById('nextBtn');
- if (state.revealed >= 3) { nextBtn.textContent = 'All 3 panels processed ✓'; nextBtn.disabled = true; }
- else { nextBtn.textContent = `Process Panel ${state.revealed+1}`; nextBtn.disabled = false; }
- }
-
- function say(kind, msg){
- const s = document.getElementById('status');
- s.className = kind; s.textContent = msg;
- }
-
- function next(){
- if (state.revealed >= 3) { say('info', 'All 3 panels are already on file. Try Plot Twist!'); return; }
- state.revealed++;
- for (let i=0;i<3;i++) {
- const cover = document.getElementById('cover'+i);
- cover.hidden = i < state.revealed;
- cover.disabled = i > state.revealed;
- document.getElementById('art'+i).setAttribute('tabindex', i === state.revealed ? '0' : '-1');
- }
- renderPanel(state.revealed - 1); // the panel that just got processed
- if (state.revealed < 3) renderPanel(state.revealed); // the newly-active cover's label
- say('ok', `Panel ${state.revealed} processed.`);
- syncButtons();
- if (state.revealed >= 3) say('ok', 'All 3 panels processed. Press Plot Twist! to change what Holloway is reading.');
- }
-
- function twist(){
- if (state.revealed < 3) { say('err', 'ERROR FB-409 · Premature twist — process all 3 panels first.'); return; }
- materialIdx = (materialIdx + 1) % MATERIALS.length;
- state.twists++;
- renderPanel(0); renderPanel(1); renderPanel(2);
- say('ok', `Plot twist #${state.twists}: Delegate Holloway has moved on to ${MATERIALS[materialIdx].label}.`);
- }
-
- document.getElementById('nextBtn').addEventListener('click', next);
- document.getElementById('twistBtn').addEventListener('click', twist);
- for (let i=0;i<3;i++) {
- document.getElementById('cover'+i).addEventListener('click', () => { if (i === state.revealed) next(); });
- document.getElementById('art'+i).addEventListener('click', () => { if (i === state.revealed) next(); });
- document.getElementById('art'+i).addEventListener('keydown', (e) => { if ((e.key==='Enter'||e.key===' ') && i===state.revealed) { e.preventDefault(); next(); } });
- }
-
- const themeBtn = document.getElementById('themeBtn');
- function safeGet(k,d){ try { return localStorage.getItem(k) ?? d; } catch { return d; } }
- function safeSet(k,v){ try { localStorage.setItem(k,v); } catch {} }
- let theme = safeGet('p24cartoon.theme', 'auto');
- function applyTheme(){
- if (theme === 'dark') { document.documentElement.setAttribute('data-theme','dark'); themeBtn.textContent='Dark mode: on'; themeBtn.setAttribute('aria-pressed','true'); }
- else { document.documentElement.setAttribute('data-theme','light'); themeBtn.textContent='Dark mode: off'; themeBtn.setAttribute('aria-pressed','false'); }
- }
- applyTheme();
- themeBtn.addEventListener('click', () => { theme = theme === 'dark' ? 'light' : 'dark'; safeSet('p24cartoon.theme', theme); applyTheme(); });
-
- document.addEventListener('keydown', (e) => {
- if (e.metaKey || e.ctrlKey || e.altKey) return;
- const tag = (e.target.tagName || '').toLowerCase();
- if (tag === 'input' || tag === 'textarea') return;
- const k = e.key.toLowerCase();
- if (k === 'n' || e.key === 'ArrowRight') { e.preventDefault(); next(); }
- else if (k === 't') { e.preventDefault(); twist(); }
- });
-
- paintAll();
- say('info', 'Case file open. Press N or click Panel 1 to begin.');
-})();
-</script>
-</body>
-</html>
← e224274 gitignore: cover shots*/ , _tmp-*/ , cartoons/_shot-*.png
·
back to Crazy News Channel Shadowman
·
reschedule P24 daily cartoon batch: 9:15 AM → 3:30 AM dc17f16 →