▍ humdrum codex / soft

Print: briefs flow inline as trailing column cards, no banner/page break

b0e950074f9ee73d760e7f705a996e3530e63980
humdrum-tiv <45084903+humdrum-tiv@users.noreply.github.com> · 2026-06-09 14:08

parent c4e5432d

Print: briefs flow inline as trailing column cards, no banner/page break

Drop the News Briefs band and the dedicated full-page spread. Each of
the four Screamer categories now renders as an ordinary left-accent
.paper-card appended after every personal section, so they flow down the
same two columns and onto later pages — briefs last, no balancing.
Brief cards get a .paper-flow variant (break-inside: auto) so a long
briefing can split across columns while individual stories stay whole.
Remove the now-unused .paper-news* / .paper-brief CSS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

2 files changed

app/globals.css +4 −24
@@ -223,6 +223,9 @@ .paper-card {
   border: 1px solid #ddd; border-left: 4px solid #111; border-radius: 7px;
   padding: 9px 12px 10px; margin-bottom: 11px; break-inside: avoid;
 }
+/* Brief cards may be taller than a column; let them split across columns/pages
+   (individual stories stay whole via .paper-story break-inside: avoid). */
+.paper-card.paper-flow { break-inside: auto; }
 .paper-card > h2 {
   font-family: var(--font-display); font-weight: 700; font-size: 16px;
   display: flex; align-items: baseline; gap: 7px;
@@ -243,30 +246,7 @@ .paper-empty { color: #777; font-style: italic; }
 .paper-item .yr { font-family: var(--font-mono); font-weight: 700; }
 .paper-todo.done { text-decoration: line-through; color: #777; }
 
-/* ── News briefs spread ── trailing full page, 2-column magazine flow ── */
-.paper-news { break-before: page; }
-.paper-news-band {
-  border-top: 2px solid #111; border-bottom: 2px solid #111;
-  padding: 5px 2px; margin-bottom: var(--space-3);
-  display: flex; justify-content: space-between; align-items: baseline;
-}
-.paper-news-band h1 { font-family: var(--font-display); font-weight: 700; font-size: 26px; margin: 0; }
-.paper-news-band .meta {
-  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
-  letter-spacing: 0.14em; color: #777;
-}
-.paper-news-flow { column-count: 2; column-gap: 22px; }
-.paper-brief { break-inside: avoid-column; margin-bottom: 15px; }
-.paper-brief > h2 {
-  font-family: var(--font-display); font-weight: 700; font-size: 19px;
-  display: flex; align-items: baseline; gap: 7px;
-  border-bottom: 2px solid #111; padding-bottom: 4px; margin: 0 0 8px;
-  break-after: avoid;
-}
-.paper-brief > h2 .kick {
-  margin-left: auto; font-family: var(--font-mono); font-weight: 500; font-size: 8px;
-  letter-spacing: 0.13em; text-transform: uppercase; color: #777;
-}
+/* ── Screamer brief stories (inside a .paper-card, flowing in the columns) ── */
 .paper-story { margin-bottom: 10px; break-inside: avoid; }
 .paper-story .t { font-weight: 700; font-size: 12.5px; line-height: 1.28; margin-bottom: 3px; }
 .paper-story .s { font-size: 11px; line-height: 1.4; color: #222; margin-bottom: 3px; }
app/print/page.tsx +28 −34
@@ -2,9 +2,10 @@ // /print — the newspaper edition. Server-rendered from current cached snapshots.
 // Puppeteer loads this route to produce the PDF (see /api/edition).
 //
 // Layout: masthead → full-width weather hero (double-wide, with today's day-part
-// strip) → personal sections in a classic two-column newspaper flow → a trailing
-// full-page news spread (the four Screamer briefs). Each kind has a small paper
-// renderer below; add a case to support a new kind.
+// strip) → personal sections, then the Screamer briefs, all in one classic
+// two-column newspaper flow (briefs come last and simply spill down the columns
+// and onto later pages). Each kind has a small paper renderer below; add a case
+// to support a new kind.
 
 import { gatherEdition, type EditionSection } from "@/lib/edition-data";
 import type { SourceKind } from "@/lib/schemas/source";
@@ -309,36 +310,25 @@     </section>
   );
 }
 
-// The trailing full-page news spread: the four Screamer briefs in a 2-column
-// magazine flow. Title (bold) → summary → source publications.
-function BriefsSpread({ section }: { section: EditionSection }) {
-  const p = section.payload as BriefsPayload;
-  const live = p.categories.filter((c) => c.stories.length > 0);
-  if (live.length === 0) return null;
+// One Screamer brief category as a flowing column card (title → summary →
+// source publications). These come last, after every personal section, and just
+// flow down the two columns and onto following pages — no balancing.
+function BriefCard({ category }: { category: BriefsPayload["categories"][number] }) {
+  if (category.stories.length === 0) return null;
   return (
-    <div className="paper-news">
-      <div className="paper-news-band">
-        <h1>News Briefs</h1>
-        <span className="meta">Screamer</span>
-      </div>
-      <div className="paper-news-flow">
-        {live.map((c) => (
-          <div className="paper-brief" key={c.key}>
-            <h2>
-              {c.name}
-              <span className="kick">Screamer</span>
-            </h2>
-            {c.stories.map((s, i) => (
-              <div className="paper-story" key={i}>
-                <div className="t">{s.title}</div>
-                {s.summary && <div className="s">{s.summary}</div>}
-                {s.sources.length > 0 && <div className="src">{s.sources.join(", ")}</div>}
-              </div>
-            ))}
-          </div>
-        ))}
-      </div>
-    </div>
+    <section className="paper-card paper-flow">
+      <h2>
+        {category.name}
+        <span className="kick">Screamer</span>
+      </h2>
+      {category.stories.map((s, i) => (
+        <div className="paper-story" key={i}>
+          <div className="t">{s.title}</div>
+          {s.summary && <div className="s">{s.summary}</div>}
+          {s.sources.length > 0 && <div className="src">{s.sources.join(", ")}</div>}
+        </div>
+      ))}
+    </section>
   );
 }
 
@@ -346,6 +336,9 @@ export default function PrintPage() {
   const d = gatherEdition();
   const briefs = d.sections.find((s) => s.kind === "briefs");
   const grid = d.sections.filter((s) => s.kind !== "briefs");
+  const briefCats = briefs
+    ? (briefs.payload as BriefsPayload).categories.filter((c) => c.stories.length > 0)
+    : [];
 
   return (
     <div className="paper">
@@ -363,9 +356,10 @@       <div className="paper-grid">
         {grid.map((s) => (
           <PaperCard key={s.id} section={s} />
         ))}
+        {briefCats.map((c) => (
+          <BriefCard key={c.key} category={c} />
+        ))}
       </div>
-
-      {briefs && <BriefsSpread section={briefs} />}
     </div>
   );
 }