[object Object]

← back to Crazy News Channel

5x sweep 3: Cody's 3 verified findings — article back/Escape returns to its own category (not Home), one canonical home URL, empty-state link is real

b86884693d103594bba06bf81532c3df91b997fd · 2026-09-24 08:34:15 -0700 · Steve Abrams

- goBackToGrid() now derives its target from the OPEN ARTICLE's own category
  (works the same for a direct deep link), not from a since-changed shared
  variable — fixes the regression Cody's proposed one-liner would have
  introduced (Escape/back-link on a category page with no article open would
  have silently done nothing, since state.category already equals the target).
- New goHome() is the single path to hash="": the logo and the category
  page's "All Categories" link both route through it now, instead of the
  logo native-navigating to a second, non-canonical "#/" URL.
- Escape now closes one layer per press (article -> its category -> Home),
  matching the UI's own depth instead of collapsing two steps into one.
- The category-empty-state's "All Categories" text is a real link now,
  not inert bold text next to a working one two lines up.

Verified: composed category->article->back/Escape journeys, deep-linked
article back, categoryBackLink always-home even mid-category, second-Escape
depth, logo->home canonical hash, empty-state link href. 0 console errors,
390/1440/reduced-motion clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLjoHsyGTDeVCa1rdrAxnk

Files touched

Diff

commit b86884693d103594bba06bf81532c3df91b997fd
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Sep 24 08:34:15 2026 -0700

    5x sweep 3: Cody's 3 verified findings — article back/Escape returns to its own category (not Home), one canonical home URL, empty-state link is real
    
    - goBackToGrid() now derives its target from the OPEN ARTICLE's own category
      (works the same for a direct deep link), not from a since-changed shared
      variable — fixes the regression Cody's proposed one-liner would have
      introduced (Escape/back-link on a category page with no article open would
      have silently done nothing, since state.category already equals the target).
    - New goHome() is the single path to hash="": the logo and the category
      page's "All Categories" link both route through it now, instead of the
      logo native-navigating to a second, non-canonical "#/" URL.
    - Escape now closes one layer per press (article -> its category -> Home),
      matching the UI's own depth instead of collapsing two steps into one.
    - The category-empty-state's "All Categories" text is a real link now,
      not inert bold text next to a working one two lines up.
    
    Verified: composed category->article->back/Escape journeys, deep-linked
    article back, categoryBackLink always-home even mid-category, second-Escape
    depth, logo->home canonical hash, empty-state link href. 0 console errors,
    390/1440/reduced-motion clean.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01VLjoHsyGTDeVCa1rdrAxnk
---
 index.html | 46 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/index.html b/index.html
index 7ba7418..7e00257 100644
--- a/index.html
+++ b/index.html
@@ -730,7 +730,7 @@ body.chaos-tier-3 main#channelContainer {
      CHROME: brand, live clock, klaxon toggle, sound toggle
      ============================================================ -->
 <header class="chrome">
-  <a class="brand" href="#/" aria-label="PANDEMONIUM-24 — back to all coverage">
+  <a id="brandLink" class="brand" href="#/" aria-label="PANDEMONIUM-24 — back to all coverage">
     <span class="logo-badge" aria-hidden="true">P24</span>
     <div>
       <h1 class="wordmark">PANDEMONIUM-24</h1>
@@ -916,7 +916,7 @@ body.chaos-tier-3 main#channelContainer {
       <span class="es-emoji" aria-hidden="true">🫥</span>
       <h3>No stories currently breaking in this category.</h3>
       <p>Our desk is on a coffee break because nothing dramatic enough has happened&nbsp;yet.<br />
-         Check back never possibly soon — or switch back to <strong>All Categories</strong>.</p>
+         Check back never possibly soon — or switch back to <a href="#/">All Categories</a>.</p>
     </div>
 
     <div id="meltdownBanner" class="meltdown-banner" hidden>
@@ -1374,6 +1374,7 @@ const els = {
   articleView: document.getElementById("articleView"),
   channelHeading: document.getElementById("channelHeading"),
   categoryBackLink: document.getElementById("categoryBackLink"),
+  brandLink: document.getElementById("brandLink"),
   categoryBlurb: document.getElementById("categoryBlurb"),
   featuresGrid: document.getElementById("featuresGrid"),
   featuresEmptyNote: document.getElementById("featuresEmptyNote"),
@@ -2532,9 +2533,26 @@ function restoreGridFocus(fromId) {
 // Close synchronously. location.hash updates immediately but hashchange
 // fires later, so waiting on it let a rapid click -> Esc -> Esc leave the
 // article open (the second Esc saw a not-yet-rendered view and did nothing).
+// Home is ALWAYS "" (never "#/") so there's one canonical home URL, not
+// two — the logo and the category-page back link both route through this
+// instead of navigating their href directly.
+function goHome() {
+  if (location.hash !== "") location.hash = "";
+  else renderRoute();
+}
+
+// "Back to live coverage" / Escape while reading an article returns to
+// THAT ARTICLE'S OWN category page — derived from the article itself, not
+// "wherever you happened to click from" (works the same for a direct deep
+// link into the article). Escape while on a category page, with no article
+// open, is a separate, shallower step handled by the caller: that one goes
+// Home (see the Escape handler in init()).
 function goBackToGrid() {
-  if (location.hash) location.hash = "";
-  renderRoute();
+  const articleId = getRouteId();
+  const source = articleId && findArticleSource(articleId);
+  const target = source && source.category ? `#/category/${source.category}` : "";
+  if (location.hash !== target) location.hash = target;
+  else renderRoute();
 }
 
 function renderRoute(opts) {
@@ -2594,10 +2612,19 @@ function init() {
     input.addEventListener("change", (e) => onCategoryChange(e.target.value));
   });
   els.categoryBackLink.addEventListener("click", (e) => {
-    // Same-page hash change; goBackToGrid() renders synchronously so the
+    // Same-page hash change; goHome() renders synchronously so the
     // heading/focus updates immediately rather than waiting on hashchange.
+    // Always Home — unlike goBackToGrid(), this link's job is unconditional.
     e.preventDefault();
-    goBackToGrid();
+    goHome();
+  });
+  // The logo/wordmark: same reasoning — intercepted so it always lands on
+  // the one canonical home URL ("") instead of native-navigating to its
+  // literal href ("#/"), which used to leave two different "home" URLs in
+  // the history stack depending on which control the reader used.
+  els.brandLink.addEventListener("click", (e) => {
+    e.preventDefault();
+    goHome();
   });
 
   // klaxon toggle
@@ -2674,8 +2701,11 @@ function init() {
   document.addEventListener("keydown", (e) => {
     if (e.key !== "Escape") return;
     if (!els.adminPanel.hidden) { setAdminOpen(false); return; }
-    // Route intent, not the DOM: the article may be requested but not yet rendered.
-    if (getRouteId() || !els.articleView.hidden || getCategoryRoute()) { goBackToGrid(); return; }
+    // Route intent, not the DOM: the article may be requested but not yet
+    // rendered. One layer at a time, same depth order as the UI itself:
+    // article -> its own category page -> Home -> (nothing left to close).
+    if (getRouteId() || !els.articleView.hidden) { goBackToGrid(); return; }
+    if (getCategoryRoute()) { goHome(); return; }
     if (state.breaking) { setBreaking(false); els.klaxonBtn.focus(); return; }
   });
 

← 0466ef4 Slow the breaking-news ticker to a constant readable ~55-70  ·  back to Crazy News Channel  ·  5x sweep 5: route every home link through goHome() via one d 2472ae0 →