<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jason Bann</title>
    <description>The latest articles on DEV Community by Jason Bann (@viablemedia).</description>
    <link>https://dev.to/viablemedia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1129591%2F6250723b-f88f-4eed-b087-7db463ae362f.jpg</url>
      <title>DEV Community: Jason Bann</title>
      <link>https://dev.to/viablemedia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viablemedia"/>
    <language>en</language>
    <item>
      <title>Your "AI Video Detector" is Snake Oil. I Built a Frame Ripper Instead.</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Wed, 06 May 2026 13:00:02 +0000</pubDate>
      <link>https://dev.to/viablemedia/your-ai-video-detector-is-snake-oil-i-built-a-frame-ripper-instead-2fm0</link>
      <guid>https://dev.to/viablemedia/your-ai-video-detector-is-snake-oil-i-built-a-frame-ripper-instead-2fm0</guid>
      <description>&lt;p&gt;Everyone on this site is currently arguing about whether prompt engineering is a real job, while simultaneously ignoring that the actual tooling being built to detect generative slop is fundamentally broken.&lt;/p&gt;

&lt;p&gt;If you look at the current market of "AI Video Detectors," 90% of them are just lazy, black-box API wrappers. You upload a video, a loading bar spins, and it spits out a completely opaque metric: "We are 87% confident this is AI." Based on what? What is the model actually looking at?&lt;/p&gt;

&lt;p&gt;The problem with standard AI video detection is that it usually tries to analyze the video as a video. It looks at the container and the compressed stream. But standard video compression algorithms (H.264, HEVC) rely heavily on interframe compression—using motion vectors to predict and smooth over data between keyframes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx808dkjtzdeyr7htsexv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx808dkjtzdeyr7htsexv.webp" alt=" " width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you realize what that means? The compression algorithm is actively doing the generative AI's cover-up work for it. It takes the AI's temporal hallucinations and smooths them out. If your detector is looking at the compressed stream, it's analyzing the codec, not the underlying generational rot.&lt;/p&gt;

&lt;p&gt;So, I built a &lt;a href="https://vibeaxis.com/vibeaxis-slop-analyzer-ai-video-detector/" rel="noopener noreferrer"&gt;Frame Ripper&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;The Technical Flex: Stop Guessing, Start Tearing&lt;/p&gt;

&lt;p&gt;Generative video models do not possess object permanence. They don't render 3D space; they hallucinate pixel probabilities frame by frame. To catch them, you have to strip away the temporal smoothing and destroy the video container completely.&lt;/p&gt;

&lt;p&gt;I built the Vibeaxis Frame Ripper to do exactly this. It doesn't give you a mystical confidence score. It is a brutalist diagnostic tool that physically rips the video timeline apart into its raw, isolated bitmaps.&lt;/p&gt;

&lt;p&gt;When you force a piece of media to exist as raw, uncompressed, sequential frames, the AI's logic completely collapses.&lt;/p&gt;

&lt;p&gt;Look at Frame 142: The lighting source makes sense.&lt;/p&gt;

&lt;p&gt;Look at Frame 143: The geometry of the background architecture has entirely shifted.&lt;/p&gt;

&lt;p&gt;Look at Frame 144: A hand has seven fingers melting into a coffee cup.&lt;/p&gt;

&lt;p&gt;We don't need another proprietary neural network trained to detect other neural networks in an endless arms race of slop. We just need tools that rip the data down to its rawest, ugliest components so the human eye can see the foundational errors the AI couldn't hide.&lt;/p&gt;

&lt;p&gt;Code Should Show Its Work&lt;/p&gt;

&lt;p&gt;If your diagnostic tool can't show you the exact pixel-level anomaly that triggered its flag, it’s useless to you as a developer. Stop relying on opaque confidence scores from companies selling you the cure to the disease they created.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Show DEV: I refused to pay $40 for a clunky PC sensor panel, so I built my own with React &amp; Electron.</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Tue, 28 Apr 2026 05:01:25 +0000</pubDate>
      <link>https://dev.to/viablemedia/show-dev-i-refused-to-pay-40-for-a-clunky-pc-sensor-panel-so-i-built-my-own-with-react--1n0p</link>
      <guid>https://dev.to/viablemedia/show-dev-i-refused-to-pay-40-for-a-clunky-pc-sensor-panel-so-i-built-my-own-with-react--1n0p</guid>
      <description>&lt;p&gt;If you’ve built a custom PC recently, you’ve probably looked into putting a 5-inch or 8.8-inch ultra-wide "sensor panel" inside your case. It looks incredible, but the software ecosystem running these displays is a nightmare.&lt;/p&gt;

&lt;p&gt;Your options are basically:&lt;/p&gt;

&lt;p&gt;Pay $40 for AIDA64, which features a UI that hasn't been updated since 2004, and manually drag the window to your secondary display every time you reboot.&lt;/p&gt;

&lt;p&gt;Spend a weekend editing .ini text files in Rainmeter just to get a reliable GPU temperature reading.&lt;/p&gt;

&lt;p&gt;I got tired of negotiating with friction. I didn't want to write C++, and I didn't want to pay for legacy bloatware. So, over the weekend, I engineered a bypass using React, Electron, and Node.js.&lt;/p&gt;

&lt;p&gt;Here is how I built VibeAxis Telemetry, a 1-click, completely borderless hardware monitor.&lt;/p&gt;

&lt;p&gt;The Architecture: Solving the "Dual Window" Problem&lt;br&gt;
The biggest UX problem with desktop widgets is configuration. You want the dashboard to be borderless, locked, and un-clickable. But you still need a way to change themes and upload backgrounds.&lt;/p&gt;

&lt;p&gt;I needed two separate windows: a locked Dashboard and a standard Control Panel.&lt;/p&gt;

&lt;p&gt;Instead of building and compiling two completely separate React applications, I used a URL Hashing trick inside a single Vite/React build. When Electron spawns the windows, it simply appends a hash to the local file path:&lt;/p&gt;

&lt;p&gt;TypeScript&lt;br&gt;
// main.ts (Electron Backend)&lt;br&gt;
function createDashboardWindow() {&lt;br&gt;
  dashboardWin = new BrowserWindow({ width: 1280, height: 400, frame: false });&lt;br&gt;
  dashboardWin.loadFile('index.html', { hash: 'dashboard' });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function createSettingsWindow() {&lt;br&gt;
  settingsWin = new BrowserWindow({ width: 600, height: 700 });&lt;br&gt;
  settingsWin.loadFile('index.html', { hash: 'settings' });&lt;br&gt;
}&lt;br&gt;
On the React side, a single useEffect hook listens to the URL route. If it sees /#dashboard, it renders the SVG dials. If it sees /#settings, it renders the buttons and file upload inputs. One codebase, two completely decoupled UIs.&lt;/p&gt;

&lt;p&gt;The IPC Bridge: Talking Across the Void&lt;br&gt;
Because the two windows are separate Chromium processes, they can't share a React state. If a user uploads a new background image in the Settings window, I need to instantly beam that image to the Dashboard.&lt;/p&gt;

&lt;p&gt;I built a secure IPC (Inter-Process Communication) bridge using Electron's contextBridge.&lt;/p&gt;

&lt;p&gt;When you upload an image in the Settings window, React converts the file into a Base64 string and fires it across the bridge to the Node backend:&lt;/p&gt;

&lt;p&gt;JavaScript&lt;br&gt;
// App.jsx (Settings Window)&lt;br&gt;
const handleImageUpload = (e) =&amp;gt; {&lt;br&gt;
  const reader = new FileReader();&lt;br&gt;
  reader.onload = (event) =&amp;gt; window.api.sendBg(event.target.result);&lt;br&gt;
  reader.readAsDataURL(e.target.files[0]);&lt;br&gt;
}&lt;br&gt;
The Node backend catches it, acts as a relay station, and blasts it directly into the isolated Dashboard window, updating the CSS instantly without a reload.&lt;/p&gt;

&lt;p&gt;Reading Hardware Temps without C++&lt;br&gt;
To get kernel-level CPU and GPU data, I bypassed writing native Windows plugins and utilized the systeminformation npm package. By running the Electron backend with administrative privileges, Node can read the motherboard sensors directly.&lt;/p&gt;

&lt;p&gt;TypeScript&lt;br&gt;
// Hardware Polling loop&lt;br&gt;
setInterval(async () =&amp;gt; {&lt;br&gt;
  const graphics = await si.graphics();&lt;br&gt;
  // Find the dedicated GPU (safely handle undefined temp sensors)&lt;br&gt;
  const gpu = graphics.controllers.find(g =&amp;gt; (g.temperatureGpu ?? 0) &amp;gt; 0) || graphics.controllers[0];&lt;/p&gt;

&lt;p&gt;dashboardWin.webContents.send('telemetry-update', {&lt;br&gt;
    gpuTemp: gpu.temperatureGpu,&lt;br&gt;
    gpuLoad: gpu.utilizationGpu&lt;br&gt;
  });&lt;br&gt;
}, 2000);&lt;br&gt;
The 1-Click Lock&lt;br&gt;
The final piece of the puzzle was killing the "drag and drop" friction. Using Electron's screen API, the app automatically scans your hardware for a display matching the 1280x400 aspect ratio. When you click "Lock to Mini-Display," it calculates the exact X/Y coordinates of that monitor, teleports the dashboard there, and locks it into full screen.&lt;/p&gt;

&lt;p&gt;The Result&lt;br&gt;
I packaged it up with electron-builder into a standalone .exe. It takes up a fraction of the system resources of legacy tools, natively supports CSS variable theming, and most importantly, it's completely free.&lt;/p&gt;

&lt;p&gt;Stop paying for clunky software.&lt;/p&gt;

&lt;p&gt;Links:&lt;/p&gt;

&lt;p&gt;Download the 1-Click Windows &lt;a href="https://vibeaxis.com/headline-rip-aida64-why-we-built-a-1-click-sensor-panel-from-scratch/" rel="noopener noreferrer"&gt;Installer at VibeAxis.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Star the Repo or fork the &lt;a href="https://github.com/Vibeaxis/VibeAxis-Telemetry/releases" rel="noopener noreferrer"&gt;code on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know what you think of the architecture, or if you have any ideas on how to optimize the IPC bridge even further!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>webdev</category>
      <category>electron</category>
    </item>
    <item>
      <title>How TikTok’s Safety Bot Forced Me to Optimize My JS Canvas Engine</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sun, 19 Apr 2026 03:01:30 +0000</pubDate>
      <link>https://dev.to/viablemedia/how-tiktoks-safety-bot-forced-me-to-optimize-my-js-canvas-engine-4fpl</link>
      <guid>https://dev.to/viablemedia/how-tiktoks-safety-bot-forced-me-to-optimize-my-js-canvas-engine-4fpl</guid>
      <description>&lt;p&gt;If you’ve ever tried marketing an indie game on short-form video platforms, you already know the golden rule: Make it flashy, make it fast, and make it pop. I’m currently building an in-browser sci-fi defense game called Divine Orbit. You play as an AI defending a planet from cosmic threats using orbital superweapons. Because it’s a web game, I wanted to prove that an HTML5  could produce chaotic, massive, cinematic explosions that rival desktop games.&lt;/p&gt;

&lt;p&gt;So, I cranked the visual juice to the absolute max. I wanted every nuke and meteor impact to feel devastating.&lt;/p&gt;

&lt;p&gt;The result? My gameplay clips looked awesome.&lt;br&gt;
The problem? TikTok’s algorithm shadowbanned my account to exactly 0 views.&lt;/p&gt;

&lt;p&gt;Here is how an automated safety bot forced me to rethink my rendering path, ditch my DOM animations, and build a high-performance, zero-allocation volumetric particle engine.&lt;/p&gt;

&lt;p&gt;The Problem: Accidentally Coding a Flashbang&lt;br&gt;
In my pursuit of "flashy," I made a classic visual effects mistake. I was relying heavily on two things to make my explosions look powerful:&lt;/p&gt;

&lt;p&gt;CSS/DOM-based Shockwaves: Every time a meteor hit, I was pushing a new object into a React state array (setMeteorExplosions) that rendered a rapidly expanding, stroked HTML &lt;/p&gt; ring over the canvas.

&lt;p&gt;Screen Blending: Inside the actual canvas particle system, I was rendering hundreds of particles using ctx.globalCompositeOperation = 'screen'.&lt;/p&gt;

&lt;p&gt;If you know how screen blending works, you already know where this is going. When 50 red and gold particles overlap in the exact same coordinate space, the colors compound. It doesn’t look red anymore; it blows out into pure, blinding #FFFFFF white.&lt;/p&gt;

&lt;p&gt;Add in the rapidly expanding CSS rings on a pitch-black space background, and my game wasn’t just flashy—it was a literal strobe light. TikTok’s automated trust and safety bots flagged the high-frequency contrast shifts as an epilepsy hazard, and silently dropped my reach to zero.&lt;/p&gt;

&lt;p&gt;The Fix: Volumetric Plasma &amp;amp; Zero-Allocation&lt;br&gt;
I couldn't just turn down the opacity; it made the game look weak. I needed the explosions to feel heavy and cinematic without triggering the strobe filters.&lt;/p&gt;

&lt;p&gt;I completely gutted the visual pipeline and made three major architectural changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Killing the React DOM Rings&lt;br&gt;
I was making React do layout recalculations in the middle of heavy combat just to render CSS circles. I completely deleted the setMeteorExplosions state and moved 100% of the explosion logic directly into the  engine. No more sharp, high-contrast geometric outlines—just soft pixels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switching to 'Source-Over' Volumetrics&lt;br&gt;
I stripped out the screen blending. Instead of letting colors compound into pure white light, I locked the context to source-over and hard-coded warm, capped-opacity gradients.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Zero-Allocation Pool&lt;br&gt;
To handle the increased load of drawing all these soft-body particles on the canvas, I used a pre-allocated object pool. Instead of creating and garbage-collecting hundreds of objects per frame, I recycle them:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;JavaScript&lt;br&gt;
// The TikTok-Safe Volumetric Render Loop&lt;br&gt;
ctx.globalCompositeOperation = 'source-over'; // No more blinding screen blends!&lt;/p&gt;

&lt;p&gt;const partLen = particlePool.length;&lt;br&gt;
for (let i = 0; i &amp;lt; partLen; i++) {&lt;br&gt;
    const p = particlePool[i];&lt;br&gt;
    if (!p.active) continue;&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p.life -= delta * 5.0; 
if (p.life &amp;lt;= 0) { p.active = false; continue; }

p.size += ((p.maxSize) - p.size) * (delta * 25);
const currentRadius = Math.max(1, p.size);

// THE GLOWING GAS CLOUD (Soft Filled, Capped Opacity)
const cachedSprite = spriteCacheRef.current[p.color];
if (cachedSprite) {
    ctx.globalAlpha = Math.max(0, p.life * 0.7); // Never hits 100%
    ctx.drawImage(cachedSprite, p.x - currentRadius, p.y - currentRadius, currentRadius * 2, currentRadius * 2);
} else {
    ctx.globalAlpha = Math.max(0, p.life * 0.6);
    ctx.fillStyle = p.color;
    ctx.beginPath();
    ctx.arc(p.x, p.y, currentRadius, 0, Math.PI * 2);
    ctx.fill();
}

// THE SEARING CORE (Warm &amp;amp; Muted)
// Removed pure white. Uses a warm orange/yellow that fades out instantly.
ctx.globalAlpha = Math.max(0, (p.life - 0.4) * 0.5); 
ctx.beginPath();
ctx.arc(p.x, p.y, currentRadius * 0.35, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(250, 200, 100, 0.8)'; 
ctx.fill();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;br&gt;
ctx.globalAlpha = 1.0;&lt;br&gt;
The Result&lt;br&gt;
The irony of this whole nightmare is that the TikTok algorithm was actually right.&lt;/p&gt;

&lt;p&gt;By forcing me to remove the cheap strobe effects and screen blending, the game looks objectively better. The explosions now look like heavy, billowing cinematic plasma instead of a neon geometry rave.&lt;/p&gt;

&lt;p&gt;More importantly, by migrating everything away from React state updates and strictly into a zero-allocation canvas pool, my frame times stabilized drastically during late-game waves when the screen is covered in orbital strikes.&lt;/p&gt;

&lt;p&gt;If you are building browser games, be very careful with screen or lighter composite operations on dark backgrounds. What looks like a cool laser blast to you might look like a liability to a social media algorithm.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fyq4igbf73mju4ep9r3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fyq4igbf73mju4ep9r3.jpg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to see the new optimized engine in action, you can play the live web build right now on &lt;a href="https://vibeaxis.com/divine-orbit-free-demo-play-in-browser-now/" rel="noopener noreferrer"&gt;VibeAxis&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you hate the idea of Earth being destroyed by giant rocks, consider dropping a &lt;a href="https://store.steampowered.com/app/4421760/Divine_Orbit/" rel="noopener noreferrer"&gt;Wishlist for Divine Orbit on Steam!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>gamedev</category>
      <category>performance</category>
    </item>
    <item>
      <title>A 90-second drill for release notes (that you’ll actually use)</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sat, 11 Oct 2025 17:03:45 +0000</pubDate>
      <link>https://dev.to/viablemedia/a-90-second-drill-for-release-notes-that-youll-actually-use-21i6</link>
      <guid>https://dev.to/viablemedia/a-90-second-drill-for-release-notes-that-youll-actually-use-21i6</guid>
      <description>&lt;p&gt;Release notes pile up. People skim. Outages happen.&lt;/p&gt;

&lt;p&gt;I use a tiny drill:&lt;br&gt;
1) Paste the changelog (or fetch the URL).&lt;br&gt;
2) Pull out breaking changes, new defaults, flags/toggles.&lt;br&gt;
3) Produce a migration/rollback checklist + Markdown buckets.&lt;/p&gt;

&lt;p&gt;Tool: &lt;a href="https://vibeaxis.com/patch-notes-summarizer/" rel="noopener noreferrer"&gt;https://vibeaxis.com/patch-notes-summarizer/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Buckets: Added / Changed / Fixed / Removed / Deprecated / Known issues / Open questions / Highlights.&lt;br&gt;&lt;br&gt;
Export JSON if you want to feed a docs pipeline.&lt;/p&gt;

&lt;p&gt;Bonus: gut-check your prose with Slop Index → &lt;a href="https://vibeaxis.com/slop-index/" rel="noopener noreferrer"&gt;https://vibeaxis.com/slop-index/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Shipping Without the Slop: A Receipts-First Workflow for Marketing Copy</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sun, 05 Oct 2025 19:14:43 +0000</pubDate>
      <link>https://dev.to/viablemedia/shipping-without-the-slop-a-receipts-first-workflow-for-marketing-copy-nao</link>
      <guid>https://dev.to/viablemedia/shipping-without-the-slop-a-receipts-first-workflow-for-marketing-copy-nao</guid>
      <description>&lt;p&gt;If you’re moving fast, you’re probably shipping a little slop. Not because you’re lazy because the marketing web is booby-trapped with FOMO, fake intimacy, techno-mysticism, and “trust us, bro” vibes that sneak into drafts when you’re sprinting.&lt;/p&gt;

&lt;p&gt;Here’s how we’ve been shipping cleaner, faster: a receipts-first workflow that flags manipulation language, rewrites it neutral, and leaves a paper trail you can point to later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The one-click check: Adblock for Feelings&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We built Adblock for Feelings&lt;br&gt;
 to lint persuasion tactics the way ESLint lints code.&lt;br&gt;
Paste copy (or run the bookmarklet on any page) and it highlights:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;FOMO &amp;amp; scarcity (last chance, ends tonight, waitlist…)&lt;/li&gt;
&lt;li&gt;Authority-laundering (experts agree, scientifically proven…)&lt;/li&gt;
&lt;li&gt;Fake intimacy (just between us, we noticed you…)&lt;/li&gt;
&lt;li&gt;Hype (revolutionize, 10x, world-class…)&lt;/li&gt;
&lt;li&gt;Fear bait &amp;amp; flattery&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;…plus a cleaned version you can ship without sounding like a cartoon villain.&lt;/p&gt;

&lt;p&gt;It’s all client-side, no login, and you can export the flags as CSV or download a “receipt” (HTML) with hashes so future-you can prove you did the right thing.&lt;/p&gt;

&lt;p&gt;Why receipts? Because arguments on the internet end when the evidence starts. See: How To Run Your Own Receipt Study&lt;/p&gt;

&lt;p&gt;The receipts-first loop (15 minutes)&lt;/p&gt;

&lt;p&gt;Draft like you mean it. Don’t self-censor in the first pass.&lt;/p&gt;

&lt;p&gt;Run a feelings-lint. Paste into Adblock for Feelings → set strictness to Normal or Ruthless.&lt;/p&gt;

&lt;p&gt;Neutralize &amp;amp; compare. Skim the Cleaned output; if meaning holds, keep it.&lt;/p&gt;

&lt;p&gt;Export flags. Save CSV (for content QA) or the Receipt HTML (for audits).&lt;/p&gt;

&lt;p&gt;Re-score the page. If it’s a long form, scan the published URL too.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Log the win. Drop the receipt link into your PR/issue to prevent “who changed the tone?” fights later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re fighting platform sludge in general, you might like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/ai-slop-index/" rel="noopener noreferrer"&gt;AI Slop Index: Text&lt;/a&gt;&lt;br&gt;
 — grade a page’s “slop density” in ~60 seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/boring-on-purpose-why-our-plugins-dont-chase-hype/" rel="noopener noreferrer"&gt;Boring On Purpose: Why Our Plugins Don’t Chase Hype&lt;/a&gt;&lt;br&gt;
 — the philosophy behind all this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/algorithmic-possession-a-diy-exorcism-for-your-recommender/" rel="noopener noreferrer"&gt;Algorithmic Possession: A DIY Exorcism for Your Recommender&lt;/a&gt;&lt;br&gt;
 — detox when feeds go feral.&lt;/p&gt;

&lt;p&gt;When to turn the dial up (or down)&lt;/p&gt;

&lt;p&gt;High-stakes pages (pricing, policy, comparison pages): set strictness to Ruthless and enable FOMO/Fear/Authority.&lt;/p&gt;

&lt;p&gt;Community posts: go Gentle, leave Ambiguity on to catch weasel words.&lt;/p&gt;

&lt;p&gt;Performance ads: try Neutralize mode (no highlights), compare CTR vs. bounce—then decide which tradeoffs you actually want.&lt;/p&gt;

&lt;p&gt;Bookmarklet for field work&lt;/p&gt;

&lt;p&gt;Adblock for Feelings has a “Copy Bookmarklet” button so you can run highlights on any page you’re analyzing yours, competitors’, or internal drafts in your CMS. Great for teardown threads or “before/after” screenshots.&lt;/p&gt;

&lt;p&gt;Speaking of teardowns:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/digital-dumpster-diving-reverse-engineering-deleted-tiktoks-for-fun-horror/" rel="noopener noreferrer"&gt;Digital Dumpster Diving: Reverse-Engineering Deleted TikToks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/rage-click-olympics-timing-the-webs-petty-war-crimes/" rel="noopener noreferrer"&gt;Rage-Click Olympics: Timing the Web’s Petty War Crimes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ethics is velocity&lt;/p&gt;

&lt;p&gt;The fastest teams codify taste. Linting language isn’t about being nice it’s about being consistent and defensible. If your brand voice is “honest over hype,” your toolchain should enforce it.&lt;/p&gt;

&lt;p&gt;Start here: &lt;a href="https://vibeaxis.com/adblock-for-feelings/" rel="noopener noreferrer"&gt;Adblock for Feelings&lt;/a&gt;&lt;br&gt;
.&lt;br&gt;
Ship copy you don’t have to apologize for later.&lt;/p&gt;

&lt;p&gt;PS: More experiments you might like&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/friendly-vs-honest-which-ai-voice-actually-builds-trust/" rel="noopener noreferrer"&gt;Friendly vs. Honest: Which AI Voice Actually Builds Trust?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/open-source-ai-vs-closed-models-who-wins/" rel="noopener noreferrer"&gt;Open-Source AI vs Closed Models: Who Wins?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vibeaxis.com/ai-hallucinations-why-they-happen-and-how-to-stop-them/" rel="noopener noreferrer"&gt;AI Hallucinations: Why They Happen and How to Stop Them&lt;/a&gt;&lt;/p&gt;

</description>
      <category>marketing</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A No-JS ‘Back to Top’ that isn’t cringe (VAX Micro UX)</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sat, 13 Sep 2025 12:32:10 +0000</pubDate>
      <link>https://dev.to/viablemedia/a-no-js-back-to-top-that-isnt-cringe-vax-micro-ux-52he</link>
      <guid>https://dev.to/viablemedia/a-no-js-back-to-top-that-isnt-cringe-vax-micro-ux-52he</guid>
      <description>&lt;p&gt;title: "A No-JS ‘Back to Top’ that isn’t cringe (VAX Micro UX)"&lt;br&gt;
published: true&lt;br&gt;
tags: wordpress, accessibility, performance, ux&lt;br&gt;
series: "Micro UX That Respects Users"&lt;/p&gt;

&lt;h1&gt;
  
  
  canonical_url: "&lt;a href="https://vibeaxis.com/Ai-tools/" rel="noopener noreferrer"&gt;https://vibeaxis.com/Ai-tools/&lt;/a&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  description: "A tiny ‘Back to Top’ that ships zero JS, respects reduced motion, and only shows on long posts."
&lt;/h2&gt;

&lt;p&gt;TL;DR: I shipped a WordPress plugin that adds a “Back to Top” button without JavaScript. It only renders on long posts, hides on desktop, respects prefers-reduced-motion, and doesn’t dunk your CLS. It’s called VAX Micro UX.&lt;/p&gt;

&lt;p&gt;Why this exists&lt;br&gt;
Most “Back to Top” widgets are 30KB of JS to do a native anchor jump. We turned a one-line feature into a cottage industry of scroll listeners, icon fonts, and layout jank.&lt;/p&gt;

&lt;p&gt;I wanted the opposite: something you forget you installed.&lt;/p&gt;

&lt;p&gt;No JS. Native anchor + smooth scroll (and we disable it for reduced-motion).&lt;/p&gt;

&lt;p&gt;Contextual. Only appears on long posts (default ≥ 900 words).&lt;/p&gt;

&lt;p&gt;Mobile-first. Hidden ≥ 900px by default—because desktops have page-up keys and sane scroll wheels.&lt;/p&gt;

&lt;p&gt;Zero settings. Activate and move on.&lt;/p&gt;

&lt;p&gt;How it works (boring on purpose)&lt;br&gt;
Prints a #va-top anchor with wp_body_open.&lt;/p&gt;

&lt;p&gt;On long single posts, prints a floating link with a small inline SVG arrow.&lt;/p&gt;

&lt;p&gt;Injects a tiny CSS block for native smooth scroll and a focus ring.&lt;/p&gt;

&lt;p&gt;No database writes, no tracking, no external assets.&lt;/p&gt;

&lt;p&gt;Customize without opening the plugin&lt;br&gt;
You can tweak thresholds and colors with filters:&lt;/p&gt;

&lt;p&gt;php&lt;br&gt;
Copy code&lt;br&gt;
// functions.php or a small mu-plugin&lt;br&gt;
add_filter('vax_backtop_min_words', fn()=&amp;gt; 1200);   // show only on 1200+ words&lt;br&gt;
add_filter('vax_backtop_mobile_breakpoint', fn()=&amp;gt; 768); // hide on &amp;gt;= 768px&lt;br&gt;
add_filter('vax_backtop_bg', fn()=&amp;gt; '#ffd400');     // acid yellow button&lt;br&gt;
add_filter('vax_backtop_fg', fn()=&amp;gt; '#000000');     // black arrow&lt;br&gt;
That’s it. No admin pages. No “Pro” upsell. If you want a control panel for a back-to-top link, we disagree about life.&lt;/p&gt;

&lt;p&gt;Accessibility notes&lt;br&gt;
Uses a real link with aria-label, so it’s keyboardable and screen-reader friendly.&lt;/p&gt;

&lt;p&gt;Adds a focus-visible ring.&lt;/p&gt;

&lt;p&gt;Honors prefers-reduced-motion (native smooth scroll off).&lt;/p&gt;

&lt;p&gt;Install&lt;br&gt;
Install VAX Micro UX from wp.org (or upload the ZIP).&lt;/p&gt;

&lt;p&gt;Activate.&lt;/p&gt;

&lt;p&gt;Write something long and actually worth scrolling. The button appears on mobile near the bottom right.&lt;/p&gt;

&lt;p&gt;When a feature can be done in CSS and markup, do it in CSS and markup. Save your JS budget for things that aren’t already built into the browser.&lt;/p&gt;

&lt;p&gt;— VibeAxis (receipts, not vibes)&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>a11y</category>
      <category>ux</category>
      <category>performance</category>
    </item>
    <item>
      <title>Anti-Influence Suit — Armor for the Feed</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sun, 07 Sep 2025 14:26:11 +0000</pubDate>
      <link>https://dev.to/viablemedia/anti-influence-suit-armor-for-the-feed-4d44</link>
      <guid>https://dev.to/viablemedia/anti-influence-suit-armor-for-the-feed-4d44</guid>
      <description>&lt;p&gt;title: Anti-Influence Suit — Armor for the Feed&lt;br&gt;
published: true&lt;br&gt;
tags: attention, productivity, psychology, social&lt;/p&gt;

&lt;h2&gt;
  
  
  canonical_url: &lt;a href="https://vibeaxis.com/the-anti-influence-suit-browse-without-being-modeled/" rel="noopener noreferrer"&gt;https://vibeaxis.com/the-anti-influence-suit-browse-without-being-modeled/&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The feed isn’t content. It’s a centrifuge for your mood.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Anti-Influence Suit&lt;/strong&gt; is a 30-second protocol you run once a week. It’s not a “digital detox.” It’s plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  0) Baseline (1 minute)
&lt;/h2&gt;

&lt;p&gt;Take a screenshot of your home feeds (YouTube, TikTok/IG, X/Threads). Label it with today’s date. If your pulse jumps, good—you’ve found the leak.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Kill the bait (90 seconds)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mute words&lt;/strong&gt; you compulsively click (celebrity names, outrage bait, your ex’s new hobby).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turn off “personalized” notifications.&lt;/strong&gt; Keep only DMs, calendar, payments, delivery.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block the puppeteers&lt;/strong&gt; who farm you for “engagement” then sell the corpse.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule: if it hijacks your Sunday, it doesn’t get Monday.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2) Rewire “recommended” into “requested” (60 seconds)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;YouTube/Spotify: &lt;strong&gt;unsubscribe&lt;/strong&gt; everything you don’t want &lt;em&gt;weekly&lt;/em&gt;.
&lt;/li&gt;
&lt;li&gt;Home feeds: &lt;strong&gt;Follow → Lists&lt;/strong&gt; (X) / &lt;strong&gt;Favorites&lt;/strong&gt; (IG) / &lt;strong&gt;Collections&lt;/strong&gt; (Threads). Visit lists first; kill home second.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3) Friction layer (30 seconds)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add a &lt;strong&gt;1-tap filter&lt;/strong&gt;: “Today only,” “New uploads only,” or a saved search.
&lt;/li&gt;
&lt;li&gt;Put your &lt;strong&gt;creation app&lt;/strong&gt; on the home screen; bury the infinite feeds on page 3.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4) Weekly audit (30 seconds)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open last week’s screenshot. Is today noisier? If yes, you got re-trained. Re-fit the suit (mute more words, remove one app’s notifications entirely).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick checklist (paste into notes)
&lt;/h3&gt;

&lt;p&gt;[ ] Weekly screenshots saved&lt;br&gt;
[ ] Mute list updated (5+ words)&lt;br&gt;
[ ] Notifications: DMs/calendar only&lt;br&gt;
[ ] Lists/Collections used first&lt;br&gt;
[ ] Re-followed 0; unfollowed 5+&lt;br&gt;
[ ] One app demoted to page 3&lt;/p&gt;

&lt;h3&gt;
  
  
  What this fixes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Doomscroll dopamine loops&lt;/strong&gt; → muted triggers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parasocial junk&lt;/strong&gt; → lists/favorites instead of home&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;“Just one more”&lt;/strong&gt; → friction on infinite feeds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision fatigue&lt;/strong&gt; → scheduled audit, not willpower&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Canonicals / Receipts:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Full breakdown lives here → &lt;a href="https://vibeaxis.com/anti-influence-suit/" rel="noopener noreferrer"&gt;https://vibeaxis.com/anti-influence-suit/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CLI for fast links:  &lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
pip install -U vax-receipts-cli
vax-receipts list
# Windows cranky?  py -m vax_receipts_cli.cli list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>attention</category>
      <category>psychology</category>
      <category>social</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Source Fidelity Playbook — Catch AI's Fake Citations in 90 Seconds</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sun, 07 Sep 2025 12:39:43 +0000</pubDate>
      <link>https://dev.to/viablemedia/source-fidelity-playbook-catch-ais-fake-citations-in-90-seconds-2jen</link>
      <guid>https://dev.to/viablemedia/source-fidelity-playbook-catch-ais-fake-citations-in-90-seconds-2jen</guid>
      <description>&lt;p&gt;Confident answer, dead link. Classic.&lt;/p&gt;

&lt;p&gt;This is a 90-second drill to test whether an “AI answer” cites reality or decorates fiction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 90-Second Drill
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1) Copy the claim.&lt;/strong&gt; Pull the exact sentence the model is selling.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;2) Open 3 tabs.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;site:&lt;/strong&gt; filter for primary sources (e.g., &lt;code&gt;site:.gov&lt;/code&gt;, &lt;code&gt;site:nature.com&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;filetype:&lt;/strong&gt; for reports and methods (&lt;code&gt;filetype:pdf OR filetype:csv&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;date range:&lt;/strong&gt; match the timeframe the claim pretends to cover.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3) Verify author + provenance.&lt;/strong&gt; Is the author real? Is the publisher the originator or a blog copying a blog?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4) Label the verdict.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;✅ trustworthy&lt;/code&gt; / &lt;code&gt;❓ unknown&lt;/code&gt; / &lt;code&gt;❌ garbage (decorative link or irrelevant source)&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Patterns (Copy/Paste)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"quoted phrase from the claim" site:.edu&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;topic name filetype:pdf 2022..2025&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;site:arxiv.org "exact method"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your 5-Line Receipt
&lt;/h2&gt;

&lt;p&gt;Claim:&lt;br&gt;
Primary source:&lt;br&gt;
Method check:&lt;br&gt;
Date match:&lt;br&gt;
Verdict:&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Perplexity/Bing vs. Go Direct
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use aggregators to &lt;strong&gt;discover&lt;/strong&gt; candidates (fast).
&lt;/li&gt;
&lt;li&gt;Go direct for &lt;strong&gt;verification&lt;/strong&gt; (slow by design).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full breakdown, examples, and failure cases: &lt;strong&gt;(canonical)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://vibeaxis.com/perplexity-vs-google-find-the-source-not-the-hype/" rel="noopener noreferrer"&gt;https://vibeaxis.com/perplexity-vs-google-find-the-source-not-the-hype/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>We built a Slop Index: fingerprints for templated AI writing</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sun, 31 Aug 2025 08:34:08 +0000</pubDate>
      <link>https://dev.to/viablemedia/we-built-a-slop-index-fingerprints-for-templated-ai-writing-2c52</link>
      <guid>https://dev.to/viablemedia/we-built-a-slop-index-fingerprints-for-templated-ai-writing-2c52</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Clean ≠ human. The Slop Index scores template fingerprints—repetition loops, hedges, passive spikes, buzzword foam, paragraph uniformity—without tracking or uploading your text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why
&lt;/h3&gt;

&lt;p&gt;“Looks fine” content often reads like it was extruded from a mold. We wanted measurable tells that a human can reason about—not a black-box “truth score.”&lt;/p&gt;

&lt;h3&gt;
  
  
  Signals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repetition&lt;/strong&gt;: share of top bigram vs all bigrams
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Burstiness&lt;/strong&gt;: sentence length variance
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lexical diversity&lt;/strong&gt;: type–token ratio
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clichés / Buzzwords / Hedges&lt;/strong&gt; per 100w
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passive hits&lt;/strong&gt; per sentence
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paragraph uniformity&lt;/strong&gt; (rhythm sameness)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too-simple grade&lt;/strong&gt; (only penalized when other signals fire)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Try it fast
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Paste text or &lt;strong&gt;fetch a URL&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Export JSON for receipts.
&lt;/li&gt;
&lt;li&gt;Privacy: runs client-side; the optional fetcher strips scripts and caches for 10 minutes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Live tool:&lt;/strong&gt; &lt;a href="https://vibeaxis.com/tools/slop-index/?utm_source=devto&amp;amp;utm_medium=post" rel="noopener noreferrer"&gt;https://vibeaxis.com/tools/slop-index/?utm_source=devto&amp;amp;utm_medium=post&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/vibeaxis/slop-index" rel="noopener noreferrer"&gt;https://github.com/vibeaxis/slop-index&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want a one-click bookmarklet:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
js
javascript:(()=&amp;gt;{location.href='https://vibeaxis.com/tools/slop-index/?url='+encodeURIComponent(location.href)})()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>writing</category>
      <category>editorial</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>First post - hi all</title>
      <dc:creator>Jason Bann</dc:creator>
      <pubDate>Sun, 30 Jul 2023 20:34:43 +0000</pubDate>
      <link>https://dev.to/viablemedia/first-post-hi-all-40o7</link>
      <guid>https://dev.to/viablemedia/first-post-hi-all-40o7</guid>
      <description>&lt;p&gt;🚧 Building Emotional Resilience: Overcoming Guilt Trips 🚧&lt;/p&gt;

&lt;p&gt;&lt;a href="https://viableoutreach.com/guilt-trip-meaning/" rel="noopener noreferrer"&gt;https://viableoutreach.com/guilt-trip-meaning/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No more feeling trapped! 💪 Learn effective communication strategies, assertiveness, and setting boundaries to combat guilt-tripping behavior. &lt;/p&gt;

&lt;p&gt;You've got the power to reclaim control over your emotions and decisions! &lt;/p&gt;

</description>
      <category>testing</category>
    </item>
  </channel>
</rss>
