← back to Filibuster Marathon Cartoon
Add The Filibuster Marathon editorial cartoon (Paul Conrad style, HTML/SVG artifact)
45c32c15f00f2eaae028977414abcdada81a0297 · 2026-09-24 12:07:00 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VGPARcQepnFT49pzMk1ZE5
Files touched
Diff
commit 45c32c15f00f2eaae028977414abcdada81a0297
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 24 12:07:00 2026 -0700
Add The Filibuster Marathon editorial cartoon (Paul Conrad style, HTML/SVG artifact)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VGPARcQepnFT49pzMk1ZE5
---
.gitignore | 8 ++
index.html | 477 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 485 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1924158
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..687cae6
--- /dev/null
+++ b/index.html
@@ -0,0 +1,477 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>The Filibuster Marathon</title>
+<style>
+ :root{
+ --cream:#cdf5e0;
+ --ink:#0b0b0c;
+ --mint:#0f9d78;
+ --mint-dim:#0c7d5f;
+ --page-bg:#cdf5e0;
+ --chrome-fg:#0b0b0c;
+ --frame-shadow: 0 18px 45px rgba(0,0,0,.28);
+ }
+ @media (prefers-color-scheme: dark){
+ :root:not([data-theme="light"]){
+ --page-bg:#0e1512;
+ --chrome-fg:#e9fbf1;
+ --frame-shadow: 0 22px 60px rgba(0,0,0,.6);
+ }
+ }
+ :root[data-theme="dark"]{
+ --page-bg:#0e1512;
+ --chrome-fg:#e9fbf1;
+ --frame-shadow: 0 22px 60px rgba(0,0,0,.6);
+ }
+
+ *{box-sizing:border-box;}
+ html,body{margin:0;padding:0;}
+ body{
+ background:var(--page-bg);
+ color:var(--chrome-fg);
+ font-family:"Georgia","Times New Roman",Cambria,serif;
+ min-height:100vh;
+ display:flex;
+ flex-direction:column;
+ align-items:center;
+ justify-content:flex-start;
+ padding:clamp(16px,4vw,48px) clamp(12px,3vw,32px) clamp(28px,5vw,56px);
+ transition:background .3s ease,color .3s ease;
+ }
+
+ .masthead{
+ width:100%;
+ max-width:1040px;
+ text-align:center;
+ margin-bottom:clamp(10px,2vw,22px);
+ }
+ .masthead .kicker{
+ font-family:Georgia,serif;
+ font-style:italic;
+ letter-spacing:.14em;
+ text-transform:uppercase;
+ font-size:clamp(10px,1.4vw,13px);
+ color:var(--mint);
+ margin:0 0 6px;
+ }
+ .masthead h1{
+ font-family:"Times New Roman",Georgia,serif;
+ font-weight:900;
+ letter-spacing:.01em;
+ font-size:clamp(26px,5vw,52px);
+ margin:0;
+ line-height:1.02;
+ color:var(--chrome-fg);
+ }
+ .masthead .deck{
+ font-style:italic;
+ font-weight:400;
+ font-size:clamp(12px,1.8vw,16px);
+ color:var(--chrome-fg);
+ opacity:.72;
+ margin:8px 0 0;
+ }
+
+ .frame-wrap{
+ width:100%;
+ max-width:1040px;
+ min-width:min(100%,390px);
+ background:var(--cream);
+ border-radius:6px;
+ box-shadow:var(--frame-shadow);
+ padding:clamp(10px,1.6vw,18px);
+ }
+
+ .cartoon-svg{
+ display:block;
+ width:100%;
+ height:auto;
+ }
+
+ .caption-row{
+ width:100%;
+ max-width:1040px;
+ display:flex;
+ justify-content:space-between;
+ align-items:baseline;
+ flex-wrap:wrap;
+ gap:8px;
+ margin-top:clamp(10px,2vw,18px);
+ padding:0 4px;
+ font-family:Georgia,serif;
+ }
+ .caption-row .cred{
+ font-size:clamp(11px,1.5vw,13px);
+ font-style:italic;
+ opacity:.65;
+ color:var(--chrome-fg);
+ }
+ .caption-row .stamp{
+ font-size:clamp(10px,1.4vw,12px);
+ letter-spacing:.08em;
+ text-transform:uppercase;
+ color:var(--mint);
+ font-weight:700;
+ }
+
+ .theme-toggle{
+ position:fixed;
+ top:14px;
+ right:14px;
+ font-family:Georgia,serif;
+ font-size:11px;
+ letter-spacing:.06em;
+ text-transform:uppercase;
+ background:transparent;
+ border:1.5px solid var(--mint);
+ color:var(--mint);
+ border-radius:20px;
+ padding:6px 12px;
+ cursor:pointer;
+ }
+ .theme-toggle:hover{background:var(--mint);color:var(--cream);}
+
+ @media (max-width:520px){
+ .masthead h1{letter-spacing:0;}
+ .caption-row{justify-content:center;text-align:center;}
+ }
+</style>
+</head>
+<body>
+
+<button class="theme-toggle" id="themeToggle" type="button" aria-label="Toggle light / dark chrome">Dark mode</button>
+
+<header class="masthead">
+ <p class="kicker">Editorial Cartoon</p>
+ <h1>The Filibuster Marathon</h1>
+ <p class="deck">In the style of Paul Conrad — invented delegate, invented chamber, invented bill.</p>
+</header>
+
+<div class="frame-wrap">
+ <svg class="cartoon-svg" viewBox="0 0 1000 760" xmlns="http://www.w3.org/2000/svg" role="img"
+ aria-label="An editorial cartoon: a flat-faced delegate reads aloud from an enormous phone book at a lectern while the darkened Capitol chamber behind him slouches asleep, and a Dali-style melted clock on the wall drips, one hand drooping down to touch the floor.">
+
+ <defs>
+ <linearGradient id="chamberGrad" x1="0" y1="0" x2="0" y2="1">
+ <stop offset="0%" stop-color="#050506"/>
+ <stop offset="70%" stop-color="#141417"/>
+ <stop offset="100%" stop-color="#1c1d21"/>
+ </linearGradient>
+
+ <radialGradient id="spotlight" cx="50%" cy="30%" r="75%">
+ <stop offset="0%" stop-color="#fffef4" stop-opacity=".55"/>
+ <stop offset="55%" stop-color="#fffef4" stop-opacity=".12"/>
+ <stop offset="100%" stop-color="#fffef4" stop-opacity="0"/>
+ </radialGradient>
+
+ <!-- reusable slumped congress-member silhouette -->
+ <g id="slumper">
+ <ellipse cx="0" cy="8" rx="24" ry="27" fill="#000"/>
+ <circle cx="4" cy="-19" r="14" fill="#000"/>
+ <path d="M -6 -12 Q 4 -2 15 -10" stroke="var(--cream)" stroke-width="2" fill="none" opacity=".5"/>
+ </g>
+
+ <!-- reusable fluttering page -->
+ <g id="flutterPage">
+ <rect x="-16" y="-11" width="32" height="22" fill="#f3fbee" stroke="#0b0b0c" stroke-width="2"/>
+ <line x1="-10" y1="-4" x2="10" y2="-4" stroke="#0b0b0c" stroke-width="1.4"/>
+ <line x1="-10" y1="0" x2="10" y2="0" stroke="#0b0b0c" stroke-width="1.4"/>
+ <line x1="-10" y1="4" x2="6" y2="4" stroke="#0b0b0c" stroke-width="1.4"/>
+ </g>
+ </defs>
+
+ <!-- ============ OUTER FRAME (classic editorial double-rule) ============ -->
+ <rect x="6" y="6" width="988" height="748" fill="var(--cream)"/>
+ <rect x="6" y="6" width="988" height="748" fill="none" stroke="#0b0b0c" stroke-width="9"/>
+ <rect x="22" y="22" width="956" height="716" fill="none" stroke="#0b0b0c" stroke-width="2"/>
+
+ <!-- inner drawing field -->
+ <rect x="26" y="26" width="948" height="708" fill="var(--cream)"/>
+
+ <!-- ============ DARK CHAMBER BEHIND ============ -->
+ <rect x="26" y="26" width="948" height="330" fill="url(#chamberGrad)"/>
+
+ <!-- ceiling coffers, faint -->
+ <g stroke="#000" stroke-width="1" opacity=".35">
+ <line x1="26" y1="60" x2="974" y2="60"/>
+ <line x1="180" y1="26" x2="180" y2="330"/>
+ <line x1="360" y1="26" x2="360" y2="330"/>
+ <line x1="640" y1="26" x2="640" y2="330"/>
+ <line x1="820" y1="26" x2="820" y2="330"/>
+ </g>
+
+ <!-- rows of slouched, drowsy Congress -->
+ <g opacity=".92">
+ <use href="#slumper" transform="translate(90,240)"/>
+ <use href="#slumper" transform="translate(160,260) scale(.9)"/>
+ <use href="#slumper" transform="translate(235,235)"/>
+ <use href="#slumper" transform="translate(305,258) scale(.85)"/>
+ <use href="#slumper" transform="translate(700,255) scale(.9)"/>
+ <use href="#slumper" transform="translate(775,232)"/>
+ <use href="#slumper" transform="translate(850,258) scale(.85)"/>
+ <use href="#slumper" transform="translate(920,238)"/>
+ <use href="#slumper" transform="translate(130,190) scale(.7)" opacity=".8"/>
+ <use href="#slumper" transform="translate(270,185) scale(.65)" opacity=".75"/>
+ <use href="#slumper" transform="translate(760,188) scale(.7)" opacity=".8"/>
+ <use href="#slumper" transform="translate(890,182) scale(.65)" opacity=".75"/>
+ </g>
+
+ <!-- dais / desk rail separating chamber from foreground -->
+ <rect x="26" y="300" width="948" height="30" fill="#050506"/>
+ <g stroke="var(--cream)" stroke-width="1.4" opacity=".35">
+ <line x1="70" y1="300" x2="70" y2="330"/>
+ <line x1="220" y1="300" x2="220" y2="330"/>
+ <line x1="770" y1="300" x2="770" y2="330"/>
+ <line x1="915" y1="300" x2="915" y2="330"/>
+ </g>
+
+ <!-- ============ MELTED DALI CLOCK (visual anchor) ============ -->
+ <g id="meltedClock" transform="translate(818,148)">
+ <!-- soft mint halo so it reads against the dark chamber -->
+ <ellipse cx="0" cy="0" rx="95" ry="80" fill="var(--mint)" opacity=".14"/>
+
+ <!-- melted clock body: a soft, sagging disc -->
+ <path d="M -62 -8
+ C -62 -46 -30 -70 2 -70
+ C 36 -70 64 -44 62 -8
+ C 61 18 46 34 30 48
+ C 20 58 26 78 10 92
+ C -2 100 -14 84 -10 66
+ C -14 50 -34 46 -46 30
+ C -58 18 -62 6 -62 -8 Z"
+ fill="#f3fbee" stroke="#0b0b0c" stroke-width="5" stroke-linejoin="round"/>
+
+ <!-- clock rim ticks -->
+ <g stroke="#0b0b0c" stroke-width="2.4">
+ <line x1="0" y1="-58" x2="0" y2="-49"/>
+ <line x1="46" y1="-8" x2="37" y2="-8"/>
+ <line x1="-53" y1="-8" x2="-44" y2="-8"/>
+ </g>
+ <text x="-3" y="-44" font-family="Georgia,serif" font-size="15" font-weight="700" fill="#0b0b0c">12</text>
+ <text x="24" y="-2" font-family="Georgia,serif" font-size="15" font-weight="700" fill="#0b0b0c">3</text>
+ <text x="-40" y="-2" font-family="Georgia,serif" font-size="15" font-weight="700" fill="#0b0b0c">9</text>
+
+ <!-- the "6" has dripped away into a long melt-string -->
+ <path d="M 4 40 C -2 60 10 76 4 96 C -1 112 8 128 2 150"
+ fill="none" stroke="#0b0b0c" stroke-width="4" stroke-linecap="round"/>
+ <circle cx="2" cy="150" r="5" fill="#0b0b0c"/>
+
+ <!-- other numerals shown mid-drip -->
+ <text x="-40" y="36" font-family="Georgia,serif" font-size="13" fill="#0b0b0c" opacity=".85">7</text>
+ <path d="M -37 40 q -2 10 2 16" stroke="#0b0b0c" stroke-width="2" fill="none" opacity=".85"/>
+ <text x="26" y="36" font-family="Georgia,serif" font-size="13" fill="#0b0b0c" opacity=".85">5</text>
+ <path d="M 30 40 q 4 10 -1 17" stroke="#0b0b0c" stroke-width="2" fill="none" opacity=".85"/>
+
+ <!-- clock centre -->
+ <circle cx="0" cy="-8" r="4.5" fill="#0b0b0c"/>
+
+ <!-- short hand -->
+ <line x1="0" y1="-8" x2="-18" y2="-28" stroke="#0b0b0c" stroke-width="4" stroke-linecap="round"/>
+
+ <!-- THE long melted hand: droops off the clock, down the wall, through the dais,
+ all the way to the chamber floor -->
+ <path d="M 0 -8
+ C 30 30 8 90 28 150
+ C 46 205 6 250 26 300
+ C 40 345 4 400 18 470
+ C 26 520 -6 560 6 596"
+ fill="none" stroke="#0b0b0c" stroke-width="6" stroke-linecap="round"/>
+ <!-- puddle where the melted hand touches the floor -->
+ <ellipse cx="6" cy="602" rx="20" ry="6" fill="#0b0b0c" opacity=".85"/>
+ </g>
+
+ <!-- ============ FOREGROUND: spotlight wash on the delegate ============ -->
+ <ellipse cx="430" cy="420" rx="420" ry="330" fill="url(#spotlight)"/>
+
+ <!-- floor line -->
+ <line x1="26" y1="620" x2="974" y2="620" stroke="#0b0b0c" stroke-width="3"/>
+ <rect x="26" y="620" width="948" height="114" fill="var(--cream)"/>
+ <line x1="26" y1="620" x2="974" y2="620" stroke="#0b0b0c" stroke-width="3"/>
+ <g stroke="#0b0b0c" stroke-width="1" opacity=".25">
+ <line x1="26" y1="650" x2="974" y2="650"/>
+ <line x1="26" y1="682" x2="974" y2="682"/>
+ </g>
+
+ <!-- fluttering phone-book pages, scattered -->
+ <g opacity=".97">
+ <use href="#flutterPage" transform="translate(232,300) rotate(-18)"/>
+ <use href="#flutterPage" transform="translate(268,360) rotate(24) scale(.85)"/>
+ <use href="#flutterPage" transform="translate(210,420) rotate(-9) scale(1.05)"/>
+ <use href="#flutterPage" transform="translate(640,300) rotate(16)"/>
+ <use href="#flutterPage" transform="translate(690,350) rotate(-22) scale(.9)"/>
+ <use href="#flutterPage" transform="translate(650,410) rotate(10) scale(1.1)"/>
+ <use href="#flutterPage" transform="translate(300,470) rotate(30) scale(.75)"/>
+ <use href="#flutterPage" transform="translate(600,470) rotate(-27) scale(.8)"/>
+ <use href="#flutterPage" transform="translate(500,255) rotate(6) scale(.7)"/>
+ </g>
+
+ <!-- ============ LECTERN ============ -->
+ <g id="lectern">
+ <path d="M 380 620 L 420 468 L 540 468 L 580 620 Z" fill="#0b0b0c"/>
+ <rect x="404" y="474" width="152" height="10" fill="var(--cream)" opacity=".9"/>
+ <!-- seal / plaque, mint accent -->
+ <circle cx="480" cy="540" r="26" fill="none" stroke="var(--mint)" stroke-width="4"/>
+ <path d="M 468 540 l 8 8 l 18 -20" fill="none" stroke="var(--mint)" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
+ <rect x="392" y="450" width="176" height="20" rx="3" fill="#0b0b0c"/>
+ </g>
+
+ <!-- ============ GIANT PHONE BOOK (bigger than the delegate) ============ -->
+ <g id="phonebook">
+ <!-- page block edge, absurdly thick -->
+ <rect x="330" y="330" width="300" height="150" fill="#f3fbee" stroke="#0b0b0c" stroke-width="5"/>
+ <g stroke="#0b0b0c" stroke-width="1.1" opacity=".8">
+ <line x1="330" y1="338" x2="630" y2="338"/>
+ <line x1="330" y1="346" x2="630" y2="346"/>
+ <line x1="330" y1="354" x2="630" y2="354"/>
+ <line x1="330" y1="362" x2="630" y2="362"/>
+ <line x1="330" y1="370" x2="630" y2="370"/>
+ <line x1="330" y1="378" x2="630" y2="378"/>
+ <line x1="330" y1="386" x2="630" y2="386"/>
+ <line x1="330" y1="394" x2="630" y2="394"/>
+ <line x1="330" y1="402" x2="630" y2="402"/>
+ <line x1="330" y1="410" x2="630" y2="410"/>
+ <line x1="330" y1="418" x2="630" y2="418"/>
+ <line x1="330" y1="426" x2="630" y2="426"/>
+ <line x1="330" y1="434" x2="630" y2="434"/>
+ <line x1="330" y1="442" x2="630" y2="442"/>
+ <line x1="330" y1="450" x2="630" y2="450"/>
+ <line x1="330" y1="458" x2="630" y2="458"/>
+ <line x1="330" y1="466" x2="630" y2="466"/>
+ <line x1="330" y1="474" x2="630" y2="474"/>
+ </g>
+ <!-- open cover fans, held up open by the delegate -->
+ <path d="M 480 330 L 326 300 L 330 480 L 480 460 Z" fill="#0b0b0c"/>
+ <path d="M 480 330 L 634 300 L 630 480 L 480 460 Z" fill="#0b0b0c"/>
+ <path d="M 480 330 L 340 314 L 342 460 L 480 444 Z" fill="#f3fbee" stroke="#0b0b0c" stroke-width="2"/>
+ <path d="M 480 330 L 620 314 L 618 460 L 480 444 Z" fill="#f3fbee" stroke="#0b0b0c" stroke-width="2"/>
+ <g stroke="#0b0b0c" stroke-width="1.1" opacity=".7">
+ <line x1="352" y1="336" x2="470" y2="326"/>
+ <line x1="352" y1="352" x2="470" y2="342"/>
+ <line x1="352" y1="368" x2="470" y2="358"/>
+ <line x1="352" y1="384" x2="470" y2="374"/>
+ <line x1="352" y1="400" x2="470" y2="391"/>
+ <line x1="490" y1="326" x2="608" y2="336"/>
+ <line x1="490" y1="342" x2="608" y2="352"/>
+ <line x1="490" y1="358" x2="608" y2="368"/>
+ <line x1="490" y1="374" x2="608" y2="384"/>
+ <line x1="490" y1="391" x2="608" y2="400"/>
+ </g>
+ <text x="392" y="420" font-family="Georgia,serif" font-weight="700" font-size="13" fill="#0b0b0c" letter-spacing="1">TELEPHONE</text>
+ <text x="500" y="420" font-family="Georgia,serif" font-weight="700" font-size="13" fill="#0b0b0c" letter-spacing="1">DIRECTORY</text>
+ <text x="326" y="296" text-anchor="middle" font-family="Georgia,serif" font-style="italic" font-size="12" fill="#0b0b0c" opacity=".7" transform="rotate(-6 326 296)">Vol. XIV</text>
+ </g>
+
+ <!-- ============ THE DELEGATE, flat and unmoved ============ -->
+ <g id="delegate">
+ <!-- far arm, gripping book edge -->
+ <path d="M 420 440 Q 380 450 372 475 Q 370 486 384 486 Q 402 486 410 470 Q 420 452 420 440 Z" fill="#0b0b0c"/>
+ <!-- near arm -->
+ <path d="M 540 440 Q 580 452 588 476 Q 590 488 576 488 Q 558 488 550 470 Q 540 452 540 440 Z" fill="#0b0b0c"/>
+
+ <!-- torso / suit -->
+ <path d="M 440 300 L 560 300 L 578 460 L 422 460 Z" fill="#0b0b0c"/>
+ <!-- shirt front + mint tie, the one spot of color on him -->
+ <path d="M 470 300 L 530 300 L 520 460 L 480 460 Z" fill="#f3fbee"/>
+ <path d="M 494 300 L 506 300 L 516 336 L 500 460 L 484 336 Z" fill="var(--mint)"/>
+ <!-- lapels -->
+ <path d="M 470 300 L 450 340 L 480 330 Z" fill="#0b0b0c"/>
+ <path d="M 530 300 L 550 340 L 520 330 Z" fill="#0b0b0c"/>
+
+ <!-- neck -->
+ <rect x="486" y="272" width="28" height="30" fill="#e9c9a3"/>
+
+ <!-- head, perfectly level, perfectly flat expression -->
+ <circle cx="500" cy="246" r="42" fill="#e9c9a3"/>
+ <!-- side-parted hair, unmoved by the chaos -->
+ <path d="M 458 236 Q 462 198 500 196 Q 540 198 542 238 Q 520 220 500 222 Q 478 220 458 236 Z" fill="#0b0b0c"/>
+ <!-- ears -->
+ <circle cx="459" cy="248" r="7" fill="#e9c9a3"/>
+ <circle cx="541" cy="248" r="7" fill="#e9c9a3"/>
+
+ <!-- flat spectacles -->
+ <g stroke="#0b0b0c" stroke-width="3.4" fill="none">
+ <circle cx="483" cy="248" r="14"/>
+ <circle cx="517" cy="248" r="14"/>
+ <line x1="497" y1="248" x2="503" y2="248"/>
+ <line x1="469" y1="246" x2="459" y2="242"/>
+ <line x1="531" y1="246" x2="541" y2="242"/>
+ </g>
+
+ <!-- dead-flat dot eyes -->
+ <circle cx="483" cy="249" r="2.6" fill="#0b0b0c"/>
+ <circle cx="517" cy="249" r="2.6" fill="#0b0b0c"/>
+
+ <!-- brows: dead level, no arch, no reaction -->
+ <line x1="472" y1="234" x2="494" y2="234" stroke="#0b0b0c" stroke-width="3" stroke-linecap="round"/>
+ <line x1="506" y1="234" x2="528" y2="234" stroke="#0b0b0c" stroke-width="3" stroke-linecap="round"/>
+
+ <!-- nose -->
+ <path d="M 500 252 L 496 268 Q 500 272 504 268 Z" fill="none" stroke="#0b0b0c" stroke-width="2"/>
+
+ <!-- perfectly straight, unmoved mouth -->
+ <line x1="482" y1="284" x2="518" y2="284" stroke="#0b0b0c" stroke-width="3" stroke-linecap="round"/>
+ </g>
+
+ <!-- ============ SUBTITLE, inside the panel like a classic cartoon caption ============ -->
+ <text x="500" y="716" text-anchor="middle" font-family="Georgia,'Times New Roman',serif"
+ font-weight="700" font-size="30" letter-spacing=".5" fill="var(--mint)">
+ “THE FILIBUSTER MARATHON”
+ </text>
+ <text x="500" y="738" text-anchor="middle" font-family="Georgia,serif" font-style="italic"
+ font-size="14" fill="#0b0b0c" opacity=".75">
+ Reading, uninterrupted, since the numbers began to melt.
+ </text>
+
+ <!-- cartoonist signature squiggle, lower right -->
+ <g transform="translate(900,608) rotate(-4)" stroke="#0b0b0c" stroke-width="2" fill="none" opacity=".8">
+ <path d="M 0 0 q 6 -12 12 0 t 12 0 t 12 0"/>
+ </g>
+
+ </svg>
+</div>
+
+<div class="caption-row">
+ <span class="cred">after Paul Conrad — single panel, ink on paper (digital facsimile)</span>
+ <span class="stamp">Vol. I • No. 1</span>
+</div>
+
+<script>
+(function(){
+ var KEY = 'filibuster-marathon-theme';
+ var btn = document.getElementById('themeToggle');
+ var root = document.documentElement;
+
+ function apply(mode){
+ if(mode === 'dark'){
+ root.setAttribute('data-theme','dark');
+ btn.textContent = 'Light mode';
+ } else if(mode === 'light'){
+ root.setAttribute('data-theme','light');
+ btn.textContent = 'Dark mode';
+ } else {
+ root.removeAttribute('data-theme');
+ var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
+ btn.textContent = prefersDark ? 'Light mode' : 'Dark mode';
+ }
+ }
+
+ var saved = null;
+ try { saved = localStorage.getItem(KEY); } catch(e) {}
+ apply(saved);
+
+ btn.addEventListener('click', function(){
+ var current = root.getAttribute('data-theme');
+ var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
+ var effectiveDark = current === 'dark' || (!current && prefersDark);
+ var next = effectiveDark ? 'light' : 'dark';
+ apply(next);
+ try { localStorage.setItem(KEY, next); } catch(e) {}
+ });
+})();
+</script>
+
+</body>
+</html>
(oldest)
·
back to Filibuster Marathon Cartoon
·
Fix melted clock hand overrun, delegate hair silhouette, and 156b2c3 →