1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5
5<script> 6 /* Night printing resolver â runs before CSS so first paint is correct. 7 3-state: localStorage "wtfjht-theme" = "day" | "night" | absent (= AUTO, follow OS). */ 8 (function () { 9 var KEY = 'wtfjht-theme', root = document.documentElement, mq = null; 10 function stored() { 11 var v = null; 12 try { v = localStorage.getItem(KEY); } catch (e) { return null; } 13 if (v === 'day' || v === 'night') return v; 14 if (v !== null) { try { localStorage.removeItem(KEY); } catch (e) {} } 15 return null; 16 } 17 function apply(pref) { 18 var night = pref ? pref === 'night' : !!(mq && mq.matches); 19 root.classList.add('theme-snap'); // suppress transitions: theme flips are instant 20 if (night) root.setAttribute('data-theme', 'night'); 21 else root.removeAttribute('data-theme'); 22 if (window.requestAnimationFrame) { 23 requestAnimationFrame(function () { requestAnimationFrame(function () { root.classList.remove('theme-snap'); }); }); 24 } else { root.classList.remove('theme-snap'); } 25 } 26 try { mq = window.matchMedia('(prefers-color-scheme: dark)'); } catch (e) {} 27 function onOsChange() { if (stored() === null) apply(null); } 28 if (mq) { 29 if (mq.addEventListener) { mq.addEventListener('change', onOsChange); } 30 else if (mq.addListener) { mq.addListener(onOsChange); } 31 } 32 window.addEventListener('storage', function (e) { 33 if (e.key === KEY || e.key === null) { apply(stored()); } 34 }); 35 window.WTFTheme = { KEY: KEY, stored: stored, apply: apply }; 36 apply(stored()); 37 })(); 38 </script>
38 39 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 40 <meta name="theme-color" content="#000000"> 41 <meta name="color-scheme" content="light dark"> 42 43 <!-- AnchorJS styles, pre-supplied WITHOUT its embedded icon font: the library 44 only injects its own <style> (incl. @font-face) if style.anchorjs is absent. 45 Icon is a text glyph via data-anchorjs-icon, so it never enters textContent 46 (share cards, selection copy stay clean). --> 47 <style class="anchorjs">.anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*:hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}</style> 48 <meta name="apple-mobile-web-app-title" content="WTFJHT" /> 49 50 <!-- Preconnect to external origins for faster resource loading --> 51 <link rel="preconnect" href="https://www.googletagmanager.com" crossorigin> 52 <link rel="dns-prefetch" href="https://www.googletagmanager.com"> 53 54 55 <!-- Preload critical above-the-fold image --> 56 <link rel="preload" href="https://whatthefuckjusthappenedtoday.com/favicon.svg?v=3" as="image" type="image/svg+xml"> 57 58 <link rel="stylesheet" href="https://whatthefuckjusthappenedtoday.com/styles.css?v=1790254453" type="text/css"> 59 <link rel="manifest" href="https://whatthefuckjusthappenedtoday.com/manifest.json?v=3"> 60 <link rel="icon" href="https://whatthefuckjusthappenedtoday.com/favicon.ico?v=3"> 61 <link rel="icon" type="image/png" sizes="96x96" href="https://whatthefuckjusthappenedtoday.com/favicon-96x96.png?v=3"> 62 <link rel="icon" type="image/png" sizes="32x32" href="https://whatthefuckjusthappenedtoday.com/favicon-32x32.png?v=3"> 63 <link rel="icon" type="image/png" sizes="16x16" href="https://whatthefuckjusthappenedtoday.com/favicon-16x16.png?v=3"> 64 <link rel="icon" type="image/svg+xml" href="https://whatthefuckjusthappenedtoday.com/favicon.svg?v=3"> 65 <link rel="apple-touch-icon" sizes="180x180" href="https://whatthefuckjusthappenedtoday.com/apple-touch-icon.png?v=3" /> 66 <link rel="alternate" type="application/rss+xml" title="WTFJHT (RSS)" href="https://whatthefuckjusthappenedtoday.com/rss.xml"> 67 <link rel="alternate" type="application/atom+xml" title="WTFJHT (Atom)" href="https://whatthefuckjusthappenedtoday.com/atom.xml"> 68 <link rel="alternate" type="application/feed+json" title="WTFJHT (JSON)" href="https://whatthefuckjusthappenedtoday.com/feed.json"> 69 70 71 <!-- Begin Jekyll SEO tag v2.8.0-wtfjht(WTFJHT Customized) --> 72<title>A political newsletter for normal people | What The Fuck Just Happened Today?</title> 73<meta name="generator" content="Jekyll v3.10.0" /> 74<meta property="og:title" content="A political newsletter for normal people" /> 75<meta name="author" content="Matt Kiser" /> 76<meta property="og:locale" content="en_US" /> 77<meta name="description" content="WTF Just Happened Today? is a sane, once-a-day newsletter helping normal people make sense of the news. Curated daily by Matt Kiser and delivered to 200,000+ people every afternoon around 3 pm Pacific" /> 78<meta property="og:description" content="WTF Just Happened Today? is a sane, once-a-day newsletter helping normal people make sense of the news. Curated daily by Matt Kiser and delivered to 200,000+ people every afternoon around 3 pm Pacific" /> 79<link rel="canonical" href="https://whatthefuckjusthappenedtoday.com/subscribe/" /> 80<meta property="og:url" content="https://whatthefuckjusthappenedtoday.com/subscribe/" /> 81<meta property="og:site_name" content="What The Fuck Just Happened Today?" /> 82<meta property="og:image" content="https://whatthefuckjusthappenedtoday.com/uploads/og-image.jpg" /> 83<meta property="og:type" content="website" /> 84<meta name="twitter:card" content="summary_large_image" /> 85<meta property="twitter:image" content="https://whatthefuckjusthappenedtoday.com/uploads/og-image.jpg" /> 86<meta property="twitter:title" content="A political newsletter for normal people" /> 87<meta property="twitter:description" content="WTF Just Happened Today? is a sane, once-a-day newsletter helping normal people make sense of the news. Curated daily by Matt Kiser and delivered to 200,000+ people every afternoon around 3 pm Pacific" /> 88<meta name="twitter:site" content="@WTFJHT" /> 89<meta name="twitter:creator" content="@matt_kiser" /> 90<meta property="fb:admins" content="29904434" /> 91<meta property="article:publisher" content="1415262761838827" /> 92<meta property="fb:app_id" content="601457263382211" />
93<script type="application/ld+json"> 94{"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"Matt Kiser","url":"https://whatthefuckjusthappenedtoday.com"},"description":"WTF Just Happened Today? is a sane, once-a-day newsletter helping normal people make sense of the news. Curated daily by Matt Kiser and delivered to 200,000+ people every afternoon around 3 pm Pacific.","headline":"A political newsletter for normal people","image":"https://whatthefuckjusthappenedtoday.com/uploads/og-image.jpg","publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"https://whatthefuckjusthappenedtoday.com/og-image.jpg?v=3"},"name":"Matt Kiser"},"url":"https://whatthefuckjusthappenedtoday.com/subscribe/"}</script>
vendor: 1 bytes, line 94
94
95<script type="application/ld+json"> 96{"@context": "https://schema.org", 97"@type": "BreadcrumbList", 98"itemListElement": [ 99 {"@type": "ListItem", 100"position": 1, 101"name": "Home", 102"item": "https://whatthefuckjusthappenedtoday.com"},{"@type": "ListItem", 103"position": 2, 104"name": "A political newsletter for normal people", 105"item": "https://whatthefuckjusthappenedtoday.com/subscribe/"}] 106}</script>
106 107<!-- End Jekyll SEO tag --> 108 109 110 111 <meta property="fb:pages" content="1415262761838827" /> 112 <meta name="google-site-verification" content="ny31Ianz2HLvyY_ynQAoMvX8_F8asoIbuBo3PnnDbRo" /> 113 114
114<script src="https://whatthefuckjusthappenedtoday.com/public/js/subscribe.js" defer></script>
vendor: 73 bytes, lines 114-116
114 115 116 <script async src="https://www.googletagmanager.com/gtag/js?id=
116G-P3G02CXQXW
vendor: 16 bytes, lines 116-117
116"></script> 117
117<script> 118
vendor: 145 bytes, lines 118-121
118window.dataLayer = window.dataLayer || []; 119 function gtag(){dataLayer.push(arguments);} 120 gtag('js', new Date()); 121 gtag('config', '
121G-P3G02CXQXW
vendor: 8 bytes, lines 121-122
121'); 122
122</script>
122 123
123<script> 124 document.addEventListener('DOMContentLoaded', function() { 125 document.querySelectorAll('form[action*="list-manage.com/subscribe"]').forEach(function(form) { 126 form.addEventListener('submit', function(event) { 127 // public/js/subscribe.js preventDefaults this submit and fires sign_up 128 // itself once the worker confirms the address, so counting here too 129 // would count the addresses the worker rejects. Anything that still 130 // posts natively to Mailchimp is counted here, on intent. 131 if (event.defaultPrevented) return; 132 gtag('event', 'sign_up', { 133 // Split into the STANDARD method param on purpose: a custom param 134 // would need a dimension registered in the GA4 admin to be reportable. 135 method: /^\/unsubscribe(\/|$)/.test(window.location.pathname) ? 'newsletter-resubscribe' : 'newsletter' 136 }); 137 }); 138 }); 139 140 // Member CTA click 141 var memberCta = document.querySelector('a.nav-cta[href*="membership"]'); 142 if (memberCta) { 143 memberCta.addEventListener('click', function() { 144 if (typeof gtag === 'function') gtag('event', 'member_cta_click'); 145 }); 146 } 147 148 // Scroll depth tracking (25%, 50%, 75%, 100%) 149 var scrollThresholds = [25, 50, 75, 100]; 150 var scrollFired = {}; 151 function checkScrollDepth() { 152 var docHeight = document.documentElement.scrollHeight - window.innerHeight; 153 if (docHeight <= 0) return; 154 var percent = Math.round((window.scrollY / docHeight) * 100); 155 for (var i = 0; i < scrollThresholds.length; i++) { 156 var t = scrollThresholds[i]; 157 if (percent >= t && !scrollFired[t]) { 158 scrollFired[t] = true; 159 if (typeof gtag === 'function') gtag('event', 'scroll_depth', { percent: t }); 160 } 161 } 162 } 163 var scrollTimer; 164 window.addEventListener('scroll', function() { 165 clearTimeout(scrollTimer); 166 scrollTimer = setTimeout(checkScrollDepth, 150); 167 }, { passive: true }); 168 169 // On This Day link clicks 170 var otdLinks = document.querySelectorAll('.historical-posts__item'); 171 for (var oi = 0; oi < otdLinks.length; oi++) { 172 otdLinks[oi].addEventListener('click', function() { 173 var yearsEl = this.querySelector('.historical-posts__years'); 174 var years = yearsEl ? parseInt(yearsEl.textContent) : 0; 175 if (typeof gtag === 'function') gtag('event', 'on_this_day_click', { years_ago: years }); 176 }); 177 } 178 179 // Read complete â fires once when bottom of post content is reached 180 var postContent = document.querySelector('.post-content'); 181 if (postContent && window.IntersectionObserver) { 182 var sentinel = document.createElement('div'); 183 sentinel.style.height = '1px'; 184 postContent.appendChild(sentinel); 185 var readObserver = new IntersectionObserver(function(entries) { 186 if (entries[0].isIntersecting) { 187 if (typeof gtag === 'function') gtag('event', 'read_complete'); 188 readObserver.disconnect(); 189 } 190 }, { threshold: 1.0 }); 191 readObserver.observe(sentinel); 192 } 193 194 }); 195 </script>
195 196 197 </head> 198 <body> 199 <a href="#main-content" class="skip-link">Skip to main content</a> 200 <div class="container content"> 201 <nav class="site-nav" aria-label="Main navigation"> 202 <div class="nav-container"> 203 <div class="nav-left"> 204 <a href="https://whatthefuckjusthappenedtoday.com/" class="nav-home" aria-label="WTF Just Happened Today Home"> 205 <img src="https://whatthefuckjusthappenedtoday.com/favicon.svg?v=3" alt="WTFJHT" class="nav-logo" width="32" height="32"> 206 </a> 207 <ul class="nav-quick"> 208 <li><a href="/2026/09/23/day-2073/">Latest</a></li> 209 <li><a href="/2026/09/22/day-2072/">Previous</a></li> 210 </ul> 211 </div> 212 213 <ul class="nav-links" role="list"> 214 <li><a href="https://whatthefuckjusthappenedtoday.com/about/">About</a></li> 215 <li><a href="https://whatthefuckjusthappenedtoday.com/subscribe/">Newsletter</a></li> 216 <li><a href="https://whatthefuckjusthappenedtoday.com/membership/" class="nav-cta">Become a Member</a></li> 217 </ul> 218 </div> 219 </nav> 220 221 <header class="masthead"> 222 <p class="masthead-title"> 223 <a href="https://whatthefuckjusthappenedtoday.com/" title="What The Fuck Just Happened Today?">What The Fuck Just Happened Today?</a> 224 </p> 225 <p class="masthead-description">Your essential guide to the shock and awe in national politics. Read in moderation.</p> 226 <p class="masthead-meta"> 227 Curated by <a href="https://whatthefuckjusthappenedtoday.com/author/matt-kiser/">Matt Kiser</a> 228 </p> 229 230 <div class="wtf-search" role="search"> 231 <div class="outer-wrapper"> 232 <div class="input-wrapper"> 233 234<svg class="icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg> 235 236 237 <input type="text" class="algolia__input js-algolia__input" autocomplete="off" name="query" placeholder="Search articles..." aria-label="Search articles" /> 238 </div> 239 </div> 240 </div> 241 </header> 242 243 244 245 <main id="main-content"> 246 <div class="wtf-search-results"> 247 <div class="algolia__search-content js-algolia__search-content"> 248 <h2 class="search-results__title">Search Results</h2> 249 <div class="posts algolia__results" aria-live="polite"></div> 250 </div> 251 </div> 252 253 <div class="algolia__initial-content js-algolia__initial-content"> 254 <article class="page"> 255 256 <!-- Do nothing --> 257 258 <div class="subscribe-box"> 259 <h1 class="subscribe-box__title">A political newsletter for normal people</h1> 260 <p class="lead">WTF Just Happened Today? is a sane, once-a-day newsletter helping normal people make sense of the news. Curated daily by <a href="https://whatthefuckjusthappenedtoday.com/author/matt-kiser/" target="_blank" class="external">Matt Kiser</a> and delivered to 200,000+ people every afternoon around 3 pm Pacific.</p> 261 <div class="subscribe-form"> 262 <form action="https://whatthefuckjusthappenedtoday.us7.list-manage.com/subscribe/post?u=104aa3abb9fec8b4d037ed51d&id=9813b73b1a" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate data-subscribe-api="https://wtfjht-just-asking-questions.matt-kiser.workers.dev"> 263 <div class="subscribe-form__row"> 264 <label for="mce-EMAIL" class="sr-only">Email address</label> 265 <input type="email" value="" name="EMAIL" class="subscribe-form__input" id="mce-EMAIL" placeholder="Type your email..." autocomplete="email" required> 266 <input type="submit" value="Subscribe for free" name="subscribe" id="mc-embedded-subscribe" class="subscribe-form__button"> 267 </div> 268 <div style="position:absolute;left:-5000px;" aria-hidden="true"> 269 <input type="text" name="website" tabindex="-1" value="" autocomplete="off"> 270 <input type="text" name="b_104aa3abb9fec8b4d037ed51d_9813b73b1a" tabindex="-1" value="" autocomplete="off"> 271 </div> 272<div class="cf-turnstile" data-sitekey="0x4AAAAAADAzC0xAFcUN12kn" data-appearance="interaction-only" data-execution="execute" data-callback="wtfjhtSubscribeToken" data-error-callback="wtfjhtSubscribeError" data-response-field-name="cf-turnstile-response"></div>
273<p class="subscribe-form__trust" role="status" aria-live="polite">Free. No spam. Unsubscribe anytime.</p> 274 </form> 275</div> 276</div> 277<hr> 278<ul> 279<li><em><strong>Quite possibly the only email list Iâm on that hasnât annoyed me even once.</strong> âDrew H.</em></li> 280<li><em><strong>I have been on the internet since 1994 and WTFJHT is the best damn political resource Iâve ever come across</strong>. Canât wait to read it each day. âLarry B.</em></li> 281<li><em><strong>Single subject, distinct tone, clear formatting, total understanding of what its audience wants</strong>. WTF Just Happened Today? is the best email newsletter. âDave L.</em></li> 282<li><em><strong>The only news-related email that I make a point of reading every day</strong>. âLorraine N.</em></li> 283<li><em><strong>WTFJHT has changed my relationship to the news and made keeping up with this whole crazy time bearable</strong>. âJulie R.</em></li> 284<li><em><strong>Itâs so nice to have found a news resource not bought out by a rich asshat</strong>. âLiz D.</em></li> 285<li><em><strong>A brilliant journalistic response to an urgent civic need</strong>. And itâs very depressing. âJeff J.</em></li> 286<li><em><strong>WTFJHT is the only newsletter I let into my inbox</strong>. Itâs brief, clear, and covers the perfect selection of news in the perfect amount of words. âSteffi K.</em></li> 287<li><em><strong>Very readable, not confusing facts and opinions, the type of reporting Iâve really missed</strong>. âPeter B.</em></li> 288<li><em><strong>Thanks for staring into the abyss so I donât have to</strong>. âLynn P.</em></li> 289<li><em><strong>WTFJHT has become my lifeline</strong>. I feel like I can tune out the chaos because I know I will receive the newsletter at the end of the day and can pursue further topics with the links you provide. I put aside a quiet time in the evening to do so and it makes all the horribleness that occurs each day a bit more manageable. âLaura K.</em></li> 290<li><em><strong>I donât need a blow-by-blow accounting of the news</strong>. I continue to want a high-level, conversational summary that leaves me informed and Iâm willing to forego details in favor of the summary WTF Just Happened Today provides.â âCasey C.</em></li> 291<li><em><strong>Thanks to WTF Just Happened Today I donât have to read the news more than once a day</strong>. My quality of life is higher and I still have a clue about WTF just happened today. âBuster</em></li> 292<li><em><strong>WTFJHT is a lifesaver</strong> - a voice of sanity, reliability, and humanity - coming to us out of the darkness and the chaos. âSusan B.</em></li> 293<li><em><strong>I could not deal with the current administration and the mess they create without WTFJHT</strong>. Well, I still canât deal with it, but at least I can understand what is happening because of WTFJHT! âConnie S.</em></li> 294<li><em><strong>Concise, thoughtful newsbites</strong>. Without WTFJHT there would be darkness and chaos. âCatherine B.</em></li> 295<li><em><strong>Insightful, clever, and intelligent</strong>. WTF Just Happened Today keeps me abreast of all of the political happenings, and is presented with a viewpoint that I can relate to. âFran P.</em></li> 296<li><em><strong>The spirit of WTFâs attempt to present all of the dumbfuckery in as non-biased a manner as possible is laudable.</strong> âJoe D.</em></li> 297<li><em><strong>I have nine news apps on my phone, but WTFJHT is what I look at at the end of the day</strong>. âPatricia M.</em></li> 298<li><em><strong>I want to keep current but I cannot bear to hear it sometimes</strong>. WTFJHTâs bite-size summaries are perfect. -Cara M.</em></li> 299<li><em><strong>It is a toss up if I just like saying the name or really like the daily recaps</strong>. âDominique A.</em></li> 300<li><em><strong>The succinct presentation and easy links led me to take action on that for the first time in my nearly 40 years on this earth</strong> and I sincerely appreciate it. âSassy M.</em></li> 301<li><em><strong>The daily summation of news paints a clear and pointed picture of the morass</strong>
301. By putting together these various - attributed - articles in one concise blog, even someone who graduated at the bottom of his class at the Wharton School could understand the mess we are in. âBob G.</em></li> 302<li><em><strong>This newsletter should win a news media award</strong>. Indispensable. âDaniel L.</em></li> 303<li> 304<em>Iâve only been reading for a few weeks, but I must send you my regards for the excellent work you are doing here. <strong>The clear and concise nature of your formatting/editing/sourcing is top notch</strong>. Itâs also something rare to find out there; your sober style seems to elude most other writers/reporters/organizations. Which is not to say all the others are offering up pure junk (though many areâ¦) but rather to say that <strong>what you offer is something that Iâve long, long felt lacking from my news options</strong>. Our lives are fast. Theyâre busy with work and family. This stuffâthe news?âitâs boring, agitating, confusing, you name it. People want to be distracted from the grind and the bullshit, particularly now in the social media era more than ever. And so <strong>your newsletter attempts to encapsulate that one particular world of the American federal government in a way that respects the readers time while still giving them the option to dig deeper</strong> into the details and sources when they wish to. Frankly, Matt? <strong>Itâs brilliant</strong>. I wish I had stumbled upon this 1,420 days ago. But I suppose the present is the next best time. Iâve already forwarded and recommended to one friend, and Iâm sure there will be more to follow. Lastly, Iâd like to keep reading on for a few months first, but I definitely intend down the road to pitch in financially and help in whatever small way I can. For now, keep up the good fight.</em> âKevin F.</li> 305<li><em><strong>A shining light in a cave full of shit</strong>. âJoe P.</em></li> 306</ul> 307 308</article> 309 310 </div> 311 </main> 312 <footer class="footer"> 313 <section class="ft-subscribe"> 314 <h3 class="ft-subscribe__title">A political newsletter for normal people.</h3> 315 <p class="ft-subscribe__desc">A sane, once-a-day newsletter helping normal people make sense of the news. </p> 316 <div class="subscribe-form"> 317 <form action="https://whatthefuckjusthappenedtoday.us7.list-manage.com/subscribe/post?u=104aa3abb9fec8b4d037ed51d&id=9813b73b1a" method="post" id="mc-embedded-subscribe-form-ft" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate data-subscribe-api="https://wtfjht-just-asking-questions.matt-kiser.workers.dev"> 318 <div class="subscribe-form__row"> 319 <label for="mce-EMAIL-ft" class="sr-only">Email address</label> 320 <input type="email" value="" name="EMAIL" class="subscribe-form__input" id="mce-EMAIL-ft" placeholder="Type your email..." autocomplete="email" required> 321 <input type="submit" value="Subscribe for free" name="subscribe" id="mc-embedded-subscribe-ft" class="subscribe-form__button"> 322 </div> 323 <div style="position:absolute;left:-5000px;" aria-hidden="true"> 324 <input type="text" name="website" tabindex="-1" value="" autocomplete="off"> 325 <input type="text" name="b_104aa3abb9fec8b4d037ed51d_9813b73b1a" tabindex="-1" value="" autocomplete="off"> 326 </div><div class="cf-turnstile" data-sitekey="0x4AAAAAADAzC0xAFcUN12kn" data-appearance="interaction-only" data-execution="execute" data-callback="wtfjhtSubscribeToken" data-error-callback="wtfjhtSubscribeError" data-response-field-name="cf-turnstile-response"></div><p class="subscribe-form__trust" role="status" aria-live="polite">Free. No spam. Unsubscribe anytime.</p> 327 </form> 328</div> 329 330 </section> 331 332 <section class="ft-main"> 333 <div class="ft-main-item"> 334 <h3 class="ft-title">About</h3> 335 <ul> 336 <li><a href="https://whatthefuckjusthappenedtoday.com/about/">About</a></li> 337 <li><a href="https://whatthefuckjusthappenedtoday.com/faq/">FAQ</a></li> 338 <li><a href="https://whatthefuckjusthappenedtoday.com/corrections/">Corrections</a></li> 339 <li><a href="https://whatthefuckjusthappenedtoday.com/membership/">Membership</a></li> 340 <li><a href="https://wtfjht.memberful.com/account" target="_blank" rel="noopener">Member Sign-in</a></li> 341 <li><a href="https://cottonbureau.com/people/wtf-just-happened-today" target="_blank" rel="noopener">Merch</a></li> 342 343 </ul> 344 </div> 345 346 <div class="ft-main-item"> 347 <h3 class="ft-title">Resources</h3> 348 <ul> 349 <!-- <li><a href="https://whatthefuckjusthappenedtoday.com/podcasts/">Podcast</a></li> --> 350 <li><a href="https://whatthefuckjusthappenedtoday.com/subscribe/">Newsletter</a></li> 351 <li><a href="https://whatthefuckjusthappenedtoday.com/do-something/">Do Something.</a></li> 352 <li><a href="https://currentstatus.io/" target="_blank" rel="noopener">Current Status</a></li> 353 <li><a href="https://www.amazon.com/shop/matt_kiser?listId=MX8CHE4TE8JY" target="_blank" rel="noopener">Recommended Books</a></li> 354 <li><a href="https://whatthefuckjusthappenedtoday.com/big-grid/">The Big Grid.â¢</a></li> 355 <li><a href="https://whatthefuckjusthappenedtoday.com/big-board/">The Big Board.â¢</a></li> 356 <li><a href="https://whatthefuckjusthappenedtoday.com/big-dumb-dashboard/">The Big Dumb Dashboard.â¢</a></li> 357 </ul> 358 </div> 359 360 <div class="ft-main-item"> 361 <h3 class="ft-title">Archives</h3> 362 <ul> 363 <li><a href="https://whatthefuckjusthappenedtoday.com/archive/">Archives</a></li> 364 <li><a href="https://whatthefuckjusthappenedtoday.com/trump-first-100-days/">Trump's First 100 Days</a></li> 365 <li><a href="https://whatthefuckjusthappenedtoday.com/biden-first-100-days/">Biden's First 100 Days</a></li> 366 <li><a href="https://whatthefuckjusthappenedtoday.com/trump-second-100-days/">Trump's Second 100 Days</a></li> 367 </ul> 368 </div> 369 </section> 370 371 <section class="ft-connect"> 372 <div class="ft-row">
373 <span class="ft-row-label">Follow</span> 374 <ul class="ft-icon-list"> 375 <li><a href="https://bsky.app/profile/whatthefuckjusthappenedtoday.com" target="_blank" rel="noopener" aria-label="Bluesky"> 376<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.882 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z"/></svg> 377 378</a></li> 379 <li><a href="https://www.threads.net/@wtfjht" target="_blank" rel="noopener" aria-label="Threads"> 380<svg class="icon" width="18" height="18" viewBox="0 0 192 192" fill="currentColor"><path d="M141.537 88.9883C140.71 88.5919 139.87 88.2104 139.019 87.8451C137.537 60.5382 122.616 44.905 97.5619 44.745C97.4484 44.7443 97.3355 44.7443 97.222 44.7443C82.2364 44.7443 69.7731 51.1409 62.102 62.7807L75.881 72.2328C81.6116 63.5383 90.6052 61.6848 97.2286 61.6848C97.3051 61.6848 97.3819 61.6848 97.4576 61.6855C105.707 61.7381 111.932 64.1366 115.961 68.814C118.893 72.2193 120.854 76.925 121.825 82.8638C114.511 81.6207 106.601 81.2385 98.145 81.7233C74.3247 83.0954 59.0111 96.9879 60.0396 116.292C60.5615 126.084 65.4397 134.508 73.775 140.011C80.8224 144.663 89.899 146.938 99.3323 146.423C111.79 145.74 121.563 140.987 128.381 132.296C133.559 125.696 136.834 117.143 138.28 106.366C144.217 109.949 148.617 114.664 151.047 120.332C155.179 129.967 155.42 145.8 142.501 158.708C131.182 170.016 117.576 174.908 97.0135 175.059C74.2042 174.89 56.9538 167.575 45.7381 153.317C35.2355 139.966 29.8077 120.682 29.6052 96C29.8077 71.3178 35.2355 52.0336 45.7381 38.6827C56.9538 24.4249 74.2039 17.11 97.0132 16.9405C119.988 17.1113 137.539 24.4614 149.184 38.788C154.894 45.8136 159.199 54.6488 162.037 64.9503L178.184 60.6422C174.744 47.9622 169.331 37.0357 161.965 27.974C147.036 9.60668 125.202 0.195148 97.0695 0H96.9569C68.8816 0.19447 47.2921 9.6418 32.7883 28.0793C19.8819 44.4864 13.2244 67.3157 13.0007 95.9325L13 96L13.0007 96.0675C13.2244 124.684 19.8819 147.514 32.7883 163.921C47.2921 182.358 68.8816 191.806 96.9569 192H97.0695C122.03 191.827 139.624 185.292 154.118 170.811C173.081 151.866 172.51 128.119 166.26 113.541C161.776 103.087 153.227 94.5962 141.537 88.9883ZM98.4405 129.507C88.0005 130.095 77.1544 125.409 76.6196 115.372C76.2232 107.93 81.9158 99.626 99.0812 98.6368C101.047 98.5234 102.976 98.468 104.871 98.468C111.106 98.468 116.939 99.0737 122.242 100.233C120.264 124.935 108.662 128.946 98.4405 129.507Z"/></svg> 381 382</a></li> 383 <li><a href="https://x.com/wtfjht" target="_blank" rel="noopener" aria-label="Twitter/X"> 384<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg> 385 386</a></li> 387 <li><a href="https://mastodon.social/@wtfjht" target="_blank" rel="noopener" aria-label="Mastodon"> 388<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545Zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12v6.406Z"/></svg> 389 390</a></li> 391 <li><a href="https://www.instagram.com/wtfjht/" target="_blank" rel="noopener" aria-label="Instagram"> 392<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg> 393 394</a></li> 395 <li><a href="https://www.facebook.com/wtfjht" target="_blank" rel="noopener" aria-label="Facebook"> 396<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg> 397 398</a></li> 399 <li><a href="https://github.com/mkiser/WTFJHT" target="_blank" rel="noopener" aria-label="GitHub"> 400<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg> 401 402</a></li> 403 </ul> 404 </div> 405 <div class="ft-row">
406 <span class="ft-row-label">Feeds</span> 407 <ul class="ft-icon-list ft-feeds"> 408 <li><a href="https://whatthefuckjusthappenedtoday.com/rss.xml">RSS</a></li> 409 <li><a href="https://whatthefuckjusthappenedtoday.com/atom.xml">Atom</a></li> 410 <li><a href="https://whatthefuckjusthappenedtoday.com/feed.json">JSON</a></li> 411 </ul> 412 </div> 413 </section> 414 415 <section class="ft-legal"> 416 <p> 417 <a href="https://whatthefuckjusthappenedtoday.com/archive/" id="random-post-link" class="easter-egg" aria-label="Random post">©</a> 418 2017â2026 419 <a href="https://whatthefuckjusthappenedtoday.com/about/">WTF Just Happened? LLC</a> 420 · <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noopener">CC BY-NC-SA 4.0</a> 421 · <a href="https://whatthefuckjusthappenedtoday.com/license/">Content license & trademarks</a> 422 </p> 423 <p class="theme-control" role="radiogroup" aria-label="Appearance"> 424 <span class="theme-control__label">Appearance:</span> 425 <button type="button" role="radio" class="theme-control__btn" data-theme-pref="auto">Auto</button> 426 <span aria-hidden="true">·</span> 427 <button type="button" role="radio" class="theme-control__btn" data-theme-pref="day">Day</button> 428 <span aria-hidden="true">·</span> 429 <button type="button" role="radio" class="theme-control__btn" data-theme-pref="night">Night</button> 430 </p> 431 </section> 432 </footer> 433 </div> 434 <!-- SEARCH (lazy-loaded on first interaction) --> 435
435<script src="https://whatthefuckjusthappenedtoday.com/public/js/search.js?v=1790254453" defer></script>
435 436
436<script src="https://whatthefuckjusthappenedtoday.com/public/js/randomPost.js?v=1790254453" defer></script>
436 437
437<script src="https://whatthefuckjusthappenedtoday.com/public/js/theme-control.js?v=1790254453" defer></script>
437 438 <!-- PWA SERVICE WORKER --> 439
439<script> 440 window.addEventListener('load', function() { 441 var sw = document.createElement('script'); 442 sw.src = 'https://whatthefuckjusthappenedtoday.com/register-sw.js'; 443 document.body.appendChild(sw); 444 }); 445 </script>
445 446 447 448
448<script src="https://whatthefuckjusthappenedtoday.com/public/js/anchor.min.js" defer></script>
448 449 450 451 452 453 454 455 <!-- ANCHORS FOR PAGES --> 456
456<script> 457 document.addEventListener("DOMContentLoaded", function(event) { 458 anchors.options = { 459 placement: 'left', 460 visible: 'hover', 461 truncate: "36", 462 icon: '\u00a7' 463 }; 464 anchors.add('.page > p > strong, .page > p > small > strong, .page h3 > em, .membership-faq p > strong'); 465 anchors.remove('.tios, .masthead-title, li.header, .historical-posts, .historical-posts__title, footer, footer *'); 466 467 document.addEventListener('click', function (e) { 468 var a = e.target.closest('.anchorjs-link'); 469 if (!a) return; 470 var url = window.location.origin + window.location.pathname + a.getAttribute('href'); 471 function toast(msg) { 472 var existing = document.querySelector('.share-toast'); 473 if (existing) existing.remove(); 474 var el = document.createElement('div'); 475 el.className = 'share-toast'; 476 el.setAttribute('role', 'status'); 477 el.textContent = msg; 478 document.body.appendChild(el); 479 setTimeout(function () { el.classList.add('fade-out'); }, 1600); 480 setTimeout(function () { el.remove(); }, 2100); 481 } 482 if (navigator.clipboard && navigator.clipboard.writeText) { 483 navigator.clipboard.writeText(url).then(function () { toast('Link copied'); }).catch(function () {}); 484 } 485 }); 486 }); 487 </script>
487 488 489 490 491 492 <!-- Highlight-to-share --> 493
493<script> 494 (function() { 495 var tooltip = null; 496 var selectedText = ''; 497 var selectedUrl = ''; 498 var mouseDown = false; 499 var interactingUntil = 0; 500 var timer = null; 501 var SHAPE = /^(STRONG|EM|SPAN|H[1-6])$/; 502 var LIST = /^(LI|UL|OL)$/; 503 504 // Create tooltip element 505 function createTooltip() { 506 var el = document.createElement('div'); 507 el.className = 'share-tooltip'; 508 el.innerHTML = 509 '<button type="button" data-action="copy">' + 510 '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>' + 511 'Copy' + 512 '</button>' + 513 '<button type="button" data-action="share">' + 514 '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/><polyline points="16 6 12 2 8 6"/><line x1="12" x2="12" y1="2" y2="15"/></svg>' + 515 'Share' + 516 '</button>'; 517 el.addEventListener('mousedown', function(e) { 518 e.preventDefault(); 519 interactingUntil = Date.now() + 700; 520 }); 521 el.addEventListener('touchstart', function() { 522 interactingUntil = Date.now() + 700; 523 }, { passive: true }); 524 return el; 525 } 526 527 // Show tooltip above selection 528 function showTooltip(rect) { 529 if (!tooltip) { 530 tooltip = createTooltip(); 531 document.body.appendChild(tooltip); 532 } 533 534 var top = rect.top + window.scrollY - tooltip.offsetHeight - 10; 535 if (rect.top - tooltip.offsetHeight - 10 < 0) { 536 top = rect.bottom + window.scrollY + 10; 537 } 538 top = Math.max(window.scrollY + 10, Math.min(top, window.scrollY + window.innerHeight - tooltip.offsetHeight - 10)); 539 var left = rect.left + window.scrollX + (rect.width / 2) - (tooltip.offsetWidth / 2); 540 541 // Keep tooltip within viewport 542 left = Math.max(10, Math.min(left, window.innerWidth - tooltip.offsetWidth - 10)); 543 544 tooltip.style.top = top + 'px'; 545 tooltip.style.left = left + 'px'; 546 } 547 548 // Hide tooltip 549 function hideTooltip() { 550 clearTimeout(timer); 551 if (tooltip && tooltip.parentNode) { 552 tooltip.parentNode.removeChild(tooltip); 553 tooltip = null; 554 } 555 selectedText = ''; 556 selectedUrl = ''; 557 } 558 559 function elementOf(node) { 560 return node.nodeType === 1 ? node : node.parentNode; 561 } 562 563 function childId(el, tag) { 564 for (var c = el.firstElementChild; c; c = c.nextElementSibling) { 565 if (c.tagName === tag && c.id) return c.id; 566 if (tag === 'STRONG' && c.tagName === 'SMALL') { 567 var inner = childId(c, 'STRONG'); 568 if (inner) return inner; 569 } 570 } 571 return ''; 572 } 573 574 function leadInId(el) { 575 if (el.tagName === 'P') return childId(el, 'STRONG'); 576 if (el.tagName === 'H3') return childId(el, 'EM'); 577 return ''; 578 } 579 580 function pageAnchorId(start, scope) { 581 var node = elementOf(start); 582 while (node && node !== scope && node !== document.body) { 583 if (node.id && SHAPE.test(node.tagName)) return node.id; 584 var id = leadInId(node); 585 if (id) return id; 586 if (LIST.test(node.tagName)) { 587 var list = node; 588 while (list.parentNode && LIST.test(list.parentNode.tagName)) list = list.parentNode; 589 var prev = list.previousElementSibling; 590 for (var i = 0; prev && i < 4; i++, prev = prev.previousElementSibling) { 591 id = leadInId(prev); 592 if (id) return id; 593 if (/^(P|H[1-6])$/.test(prev.tagName)) break; 594 } 595 return ''; 596 } 597 node = node.parentNode; 598 } 599 return ''; 600 } 601 602 function postAnchorId(start) { 603 var node = elementOf(start); 604 while (node && node !== document.body) { 605 if (node.id) return node.id; 606 node = node.parentNode; 607 } 608 return ''; 609 } 610 611 function evaluate() { 612 if (mouseDown || Date.now() < interactingUntil) return; 613 var selection = window.getSelection(); 614 var text = selection && selection.rangeCount ? selection.toString().trim() : ''; 615 616 if (text.length > 5) { 617 var range = selection.getRangeAt(0); 618 var scope = elementOf(range.commonAncestorContainer); 619 var page = scope && scope.closest ? scope.closest('article.page') : null; 620 var post = page || !scope || !scope.closest ? null : scope.closest('.post-content'); 621 var id = page ? pageAnchorId(range.startContainer, page) : (post ? postAnchorId(range.startContainer) : ''); 622 623 if (page ? id : post) { 624 var article = scope.closest('article.post[data-post-url]'); 625 var base = article ? article.getAttribute('data-post-url') : window.location.pathname; 626 selectedText = text; 627 selectedUrl = id ? window.location.origin + base + '#' + id : window.location.href; 628 showTooltip(range.getBoundingClientRect()); 629 return; 630 } 631 } 632 633 hideTooltip(); 634 } 635 636 function schedule(delay) { 637 clearTimeout(timer); 638 timer = setTimeout(evaluate, delay); 639 } 640 641 // Show toast 642 function showToast(message) { 643 var existing = document.querySelector('.share-toast'); 644 if (existing) existing.remove(); 645 646 var toast = document.createElement('div'); 647 toast.className = 'share-toast'; 648 toast.textContent = message; 649 document.body.appendChild(toast); 650 setTimeout(function() { 651 toast.classList.add('fade-out'); 652 setTimeout(function() { toast.remove(); }, 300); 653 }, 1500); 654 } 655 656 // Handle text selection 657 document.addEventListener('mousedown', function() { 658 mouseDown = true; 659 }); 660 document.addEventListener('touchend', function() { 661 mouseDown = false;
662 }, { passive: true }); 663 window.addEventListener('blur', function() { 664 mouseDown = false; 665 }); 666 document.addEventListener('mouseup', function(e) { 667 mouseDown = false; 668 // Ignore if clicking inside tooltip 669 if (e.target.closest('.share-tooltip')) return; 670 schedule(10); 671 }); 672 document.addEventListener('selectionchange', function() { 673 if (mouseDown || Date.now() < interactingUntil) return; 674 schedule(120); 675 }); 676 677 // Handle tooltip button clicks 678 document.addEventListener('click', function(e) { 679 var btn = e.target.closest('.share-tooltip button'); 680 if (!btn) return; 681 682 var action = btn.dataset.action; 683 var url = selectedUrl; 684 var quotedText = '"' + selectedText + '"'; 685 if (quotedText.length > 280) { 686 quotedText = '"' + selectedText.substring(0, 250) + '..."'; 687 } 688 // Combine text + URL for better compatibility 689 var fullText = quotedText + '\n\n' + url; 690 691 if (typeof gtag === 'function') gtag('event', 'highlight_share', { method: action }); 692 693 if (action === 'share' && navigator.share) { 694 navigator.share({ 695 text: fullText 696 }).catch(function(err) { 697 if (err.name !== 'AbortError') console.log('Share failed:', err); 698 }); 699 } else if (navigator.clipboard && navigator.clipboard.writeText) { 700 navigator.clipboard.writeText(fullText).then(function() { 701 showToast('Copied to clipboard!'); 702 }).catch(function() { 703 prompt('Copy this:', fullText); 704 }); 705 } else { 706 prompt('Copy this:', fullText); 707 } 708 709 interactingUntil = 0; 710 hideTooltip(); 711 window.getSelection().removeAllRanges(); 712 }); 713 714 // Hide tooltip on scroll or escape 715 document.addEventListener('scroll', function() { 716 if (tooltip) schedule(120); 717 }); 718 document.addEventListener('keydown', function(e) { 719 if (e.key === 'Escape') hideTooltip(); 720 }); 721 })(); 722 </script>
722 723 724 725 <!-- Dropdown menus (share widget & more menu) --> 726
726<script> 727 (function() { 728 // Show native share button if supported 729 if (navigator.share) { 730 document.querySelectorAll('.share-widget__native').forEach(function(btn) { 731 btn.removeAttribute('hidden'); 732 }); 733 } 734 735 // Close all dropdown cards 736 function closeAllCards() { 737 document.querySelectorAll('.share-widget__card.is-open, .more-menu__card.is-open').forEach(function(card) { 738 card.classList.remove('is-open'); 739 card.setAttribute('aria-hidden', 'true'); 740 var trigger = card.previousElementSibling; 741 if (trigger) trigger.setAttribute('aria-expanded', 'false'); 742 }); 743 } 744 745 // Event delegation 746 document.addEventListener('click', function(e) { 747 // Toggle share card 748 var shareTrigger = e.target.closest('.share-widget__trigger'); 749 if (shareTrigger) { 750 e.preventDefault(); 751 var card = shareTrigger.nextElementSibling; 752 var isOpen = card.classList.contains('is-open'); 753 closeAllCards(); 754 if (!isOpen) { 755 card.classList.add('is-open'); 756 card.setAttribute('aria-hidden', 'false'); 757 shareTrigger.setAttribute('aria-expanded', 'true'); 758 } 759 return; 760 } 761 762 // Toggle more menu card 763 var moreTrigger = e.target.closest('.more-menu__trigger'); 764 if (moreTrigger) { 765 e.preventDefault(); 766 var card = moreTrigger.nextElementSibling; 767 var isOpen = card.classList.contains('is-open'); 768 closeAllCards(); 769 if (!isOpen) { 770 card.classList.add('is-open'); 771 card.setAttribute('aria-hidden', 'false'); 772 moreTrigger.setAttribute('aria-expanded', 'true'); 773 } 774 return; 775 } 776 777 // Open TIOS carousel 778 var tiosBtn = e.target.closest('[data-action="open-tios"]'); 779 if (tiosBtn) { 780 e.preventDefault(); 781 closeAllCards(); 782 if (typeof openTiosCarousel === 'function') { 783 try { openTiosCarousel(0); } catch (err) { console.error('TIOS carousel error:', err); } 784 } 785 return; 786 } 787 788 // Copy link 789 var copyBtn = e.target.closest('.share-widget [data-action="copy"]'); 790 if (copyBtn) { 791 e.preventDefault(); 792 if (typeof gtag === 'function') gtag('event', 'share_widget', { method: 'copy' }); 793 var widget = copyBtn.closest('.share-widget'); 794 var url = widget.dataset.shareUrl; 795 navigator.clipboard.writeText(url).then(function() { 796 var span = copyBtn.querySelector('.share-widget__label'); 797 var original = span.textContent; 798 span.textContent = 'Copied!'; 799 setTimeout(function() { span.textContent = original; }, 1500); 800 }).catch(function() { 801 prompt('Copy this link:', url); 802 }); 803 return; 804 } 805 806 // Native share 807 var nativeShareBtn = e.target.closest('[data-action="native-share"]'); 808 if (nativeShareBtn && navigator.share) { 809 e.preventDefault(); 810 if (typeof gtag === 'function') gtag('event', 'share_widget', { method: 'native' }); 811 var widget = nativeShareBtn.closest('.share-widget'); 812 var url = widget.dataset.shareUrl; 813 var title = widget.dataset.shareTitle || document.title; 814 navigator.share({ title: title, url: url }).then(function() { 815 closeAllCards(); 816 }).catch(function(err) { 817 // User cancelled or error - silently ignore 818 if (err.name !== 'AbortError') console.log('Share failed:', err); 819 }); 820 return; 821 } 822 823 // Social share link clicks 824 var shareOption = e.target.closest('.share-widget__card a.share-widget__option'); 825 if (shareOption) { 826 var label = shareOption.querySelector('.share-widget__label'); 827 if (typeof gtag === 'function') gtag('event', 'share_widget', { method: label ? label.textContent.toLowerCase() : 'social' }); 828 } 829 830 // Print 831 var printBtn = e.target.closest('[data-action="print"]'); 832 if (printBtn) { 833 e.preventDefault(); 834 if (typeof gtag === 'function') gtag('event', 'share_widget', { method: 'print' }); 835 closeAllCards(); 836 window.print(); 837 return; 838 } 839 840 // Close cards when clicking outside 841 if (!e.target.closest('.share-widget') && !e.target.closest('.more-menu')) { 842 closeAllCards(); 843 } 844 }); 845 846 // Close on escape key 847 document.addEventListener('keydown', function(e) { 848 if (e.key === 'Escape') closeAllCards(); 849 }); 850 851 // Random post (footer easter egg); falls back to /archive/ if the JS failed to load 852 var rnd = document.getElementById('random-post-link'); 853 if (rnd) rnd.addEventListener('click', function (e) { 854 if (typeof randomPost === 'function') { e.preventDefault(); randomPost(); } 855 }); 856 857 })(); 858 </script>
858 859 860 <!-- Keyboard navigation: j/Right = newer, k/Left = older --> 861
861<script> 862 (function() { 863 document.addEventListener('keydown', function(e) { 864 // Ignore if user is typing in an input 865 if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) { 866 return; 867 } 868 869 if (document.body.classList.contains('carousel-open')) return; 870 871 // Get nav links for homepage navigation 872 var navLinks = document.querySelector('.nav-quick'); 873 var latestLink = navLinks ? navLinks.querySelector('a:first-of-type') : null; 874 var prevLink = navLinks ? navLinks.querySelectorAll('a')[1] : null; 875 876 if (e.key === 'j' || e.key === 'ArrowRight' || e.key === 'k' || e.key === 'ArrowLeft') { 877 if (typeof gtag === 'function') gtag('event', 'keyboard_nav'); 878 } 879 880 if (e.key === 'j' || e.key === 'ArrowRight') { 881 // j/Right = go to newer post 882 883 } else if (e.key === 'k' || e.key === 'ArrowLeft') { 884 // k/Left = go to older post 885 886 } 887 }); 888 })(); 889 </script>
889 890 891
891<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"4fc0bdeab84b4e5ca656c4c0b31de3ac","r":1,"spa":2}' crossorigin="anonymous"></script>
891 892</body> 893</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.