← back to Crazy News Channel Shadowman
cartoons/20260924-hedge-non-aggression-pact.html
162 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>The Hedge Non-Aggression Pact — P24 Political Cartoon Desk</title>
<meta name="description" content="An original invented-satire cartoon: Washington regulates statue-shaped hedges, fines a homeowner, gets accused of hedge espionage, and signs a topiary treaty with Idaho." />
<link rel="stylesheet" href="../assets/style.css" />
</head>
<body data-mood="politics" class="cartoon-page">
<header>
<div>
<div class="kicker">P24 Political Cartoon Desk · Invented Satire · Spokane, WA</div>
<h1>The Hedge Non-Aggression Pact</h1>
<p class="dek">Washington lawmakers are proposing a height limit on hedges trimmed to resemble statues after complaints that some now overshadow actual public monuments.</p>
</div>
<div class="header-actions">
<a class="back" href="index.html">← Cartoon Desk</a>
</div>
</header>
<main>
<figure>
<div class="phead"><span>SB 41-T, Topiary Height & Likeness</span><span id="stamp"></span></div>
<svg class="art" id="art" viewBox="0 0 480 320" role="img" tabindex="0" aria-label="Editorial cartoon about a topiary hedge escalating into an interstate treaty"></svg>
<figcaption id="cap"></figcaption>
</figure>
<div class="dock">
<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 / → advance the story · Enter/Space on the art also advances</p>
</main>
<footer>All officials, hedges, and territorial governors are invented. No actual shrubbery was extradited. 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 txt(svg, x, y, size, weight, fill, content, anchor){
const t = el('text', { x, y, 'text-anchor': anchor||'middle', 'font-family':'-apple-system,sans-serif', 'font-size':size, 'font-weight':weight||'400', fill: fill||'currentColor' }, svg);
t.textContent = content;
return t;
}
function official(svg, cx, cy, r, color, label){
const g = el('g', {}, svg);
el('circle', { cx, cy, r, fill: color, 'fill-opacity': '0.15', stroke: color, 'stroke-width': 3 }, g);
el('circle', { cx, cy: cy - r*0.35, r: r*0.28, fill: color }, g);
el('path', { d: `M ${cx - r*0.5} ${cy + r*0.5} Q ${cx} ${cy + r*0.1} ${cx + r*0.5} ${cy + r*0.5}`, fill: 'none', stroke: color, 'stroke-width': r*0.22, 'stroke-linecap':'round' }, g);
if (label) txt(svg, cx, cy + r + 16, 11, '400', 'var(--ink-dim)', label);
return g;
}
function hedge(svg, cx, cy, s, arm){
const g = el('g', {}, svg);
el('rect', { x: cx-s*0.22, y: cy+s*0.3, width: s*0.44, height: s*0.5, fill: '#0f6b52' }, g);
el('circle', { cx, cy: cy, r: s*0.24, fill: '#12805f' }, g);
el('circle', { cx: cx-s*0.18, cy: cy-s*0.06, r: s*0.16, fill: '#12805f' }, g);
el('circle', { cx: cx+s*0.18, cy: cy-s*0.06, r: s*0.16, fill: '#12805f' }, g);
el('circle', { cx, cy: cy-s*0.34, r: s*0.14, fill: '#0d5c46' }, g);
if (arm === 'wave') {
el('rect', { x: cx+s*0.2, y: cy-s*0.15, width: s*0.14, height: s*0.42, rx: 8, fill: '#0d5c46', transform: `rotate(-25 ${cx+s*0.2} ${cy+s*0.05})` }, g);
}
return g;
}
const HEADLINES = [
'Washington Lawmakers Propose Height Limit on Hedges Shaped Like Statues',
'Hedge Height Bill Passes, Requires Permits for Topiary Resembling a Historical Figure',
'State Fines Spokane Homeowner Over Unpermitted Topiary Resembling Territorial Governor',
"Neighboring State Accuses Washington of 'Hedge Espionage' Over Topiary Resembling Its Governor",
'Washington and Idaho Sign Formal Hedge Non-Aggression Pact'
];
const STAMPS = ['PROPOSED', 'PERMITTED', 'FINED', 'ACCUSED', 'RATIFIED'];
const state = { stage: 0 };
function scene(svg, stage){
svg.innerHTML = '';
if (stage === 0) {
el('rect', { x: 40, y: 260, width: 400, height: 10, fill: 'currentColor', opacity: .3, rx: 3 }, svg);
hedge(svg, 150, 190, 220, false);
const ruler = el('g', {}, svg);
el('line', { x1: 260, y1: 80, x2: 260, y2: 260, stroke: 'var(--seal)', 'stroke-width': 3, 'stroke-dasharray':'4 4' }, ruler);
txt(svg, 275, 90, 10.5, '700', 'var(--seal)', 'HEIGHT LIMIT?', 'start');
official(svg, 390, 220, 26, '#0f6b52', 'State Rep. Ohlsen');
} else if (stage === 1) {
hedge(svg, 180, 190, 210, false);
el('rect', { x: 300, y: 130, width: 140, height: 66, rx: 6, fill: 'var(--panel)', stroke: 'var(--rule)', 'stroke-width': 3 }, svg);
txt(svg, 370, 154, 10, '700', 'currentColor', 'TOPIARY PERMIT');
txt(svg, 370, 172, 9, '400', 'var(--ink-dim)', 'likeness: historical figure');
txt(svg, 370, 186, 9, '400', 'var(--ink-dim)', 'status: PENDING REVIEW');
} else if (stage === 2) {
hedge(svg, 170, 190, 220, false);
const stamp = el('g', { transform: 'translate(360,140) rotate(-14)' }, svg);
el('circle', { cx: 0, cy: 0, r: 40, fill: 'none', stroke: 'var(--accent)', 'stroke-width': 5 }, stamp);
txt(svg, 360, 148, 15, '800', 'var(--accent)', 'FINED');
txt(svg, 170, 300, 11, '400', 'var(--ink-dim)', 'Unpermitted likeness: a territorial governor.');
} else if (stage === 3) {
el('rect', { x: 260, y: 70, width: 6, height: 210, fill: 'var(--rule)', opacity: .5 }, svg);
txt(svg, 270, 84, 9, '700', 'var(--ink-dim)', 'STATE LINE', 'start');
hedge(svg, 150, 190, 210, false);
official(svg, 370, 200, 30, '#b5302f', 'Neighboring Delegate');
const bin = el('g', { transform: 'translate(340,140)' }, svg);
el('rect', { x: -18, y: -10, width: 36, height: 18, rx: 3, fill: '#241c14' }, bin);
el('circle', { cx: -8, cy: 0, r: 6, fill: 'none', stroke: '#f2ead9', 'stroke-width': 2.4 }, bin);
el('circle', { cx: 8, cy: 0, r: 6, fill: 'none', stroke: '#f2ead9', 'stroke-width': 2.4 }, bin);
txt(svg, 340, 175, 10, '700', 'var(--accent)', '"Hedge espionage!"');
} else if (stage === 4) {
hedge(svg, 150, 190, 190, 'wave');
hedge(svg, 330, 190, 190, 'wave');
el('rect', { x: 205, y: 250, width: 70, height: 44, rx: 4, fill: 'var(--panel)', stroke: 'var(--rule)', 'stroke-width': 2.5 }, svg);
txt(svg, 240, 268, 8.5, '700', 'currentColor', 'HEDGE');
txt(svg, 240, 280, 8.5, '700', 'currentColor', 'TREATY');
txt(svg, 240, 70, 12, '800', 'currentColor', 'WA and ID Hedge Non-Aggression Pact, signed.');
}
}
function say(kind, msg){ const s = document.getElementById('status'); s.className = kind; s.textContent = msg; }
function paint(){
scene(document.getElementById('art'), state.stage);
document.getElementById('cap').textContent = HEADLINES[state.stage];
document.getElementById('stamp').textContent = STAMPS[state.stage];
const btn = document.getElementById('twistBtn');
if (state.stage >= HEADLINES.length - 1) { btn.textContent = 'Story Concluded'; btn.disabled = true; }
else { btn.textContent = 'Plot Twist!'; btn.disabled = false; }
}
function advance(){
if (state.stage >= HEADLINES.length - 1) { say('info', 'The story has concluded. Peace in our time, hedge-wise.'); return; }
state.stage++;
paint();
say('ok', `Stage ${state.stage + 1} of ${HEADLINES.length}.`);
}
document.getElementById('twistBtn').addEventListener('click', advance);
const art = document.getElementById('art');
art.addEventListener('click', advance);
art.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); advance(); } });
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(); advance(); }
});
paint();
say('info', 'Case file open. Press N, click the art, or hit Plot Twist to advance the story.');
})();
</script>
</body>
</html>