Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit dda46eb4db9fda0e3c8a450c36094c7f0f1ad36d
parent da102eab935821d0e19695a72c31bb1dfa83de36
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sun, 13 Sep 2026 11:20:02 -0400

channels: one primary in the header, and the caveat beside the title

Four dark pills of equal weight shared the header: three that sweep the
WHOLE channel pool and are used rarely, and one that creates a channel and
is the actual call to action. The three become outlines under an "Every
channel" eyebrow that says what they act on; New channel is the only fill.

The freshness note moves from the very bottom of the page - 11px type under
a floating bar, ~6,000px below the numbers it is a caveat about - to the
subtitle slot beside the h1, prefixed with the channel count. It is the same
element with the same data-testid and the same text; it was written before
and it is said now.

On md+ the page root becomes a viewport-height flex column so the rack
scrolls inside its own region and the chrome around it stays put.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Meditor/app/channels/page.tsx | 148++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 86 insertions(+), 62 deletions(-)

diff --git a/editor/app/channels/page.tsx b/editor/app/channels/page.tsx @@ -259,20 +259,78 @@ export default async function ChannelsPage({ briefs.filter((b) => shown.has(b.slug)), ); return ( - <div className="flex flex-col gap-4"> - <div className="flex items-center justify-between"> - <h1 className="text-2xl font-semibold">Channels</h1> - <div className="flex items-center gap-2"> - <SyncAllChannelsButton /> - <RefreshAllReportsButton /> - <Link - href="/channels/new" - className="px-3 py-2 rounded-md bg-primary text-primary-foreground text-sm font-medium hover:opacity-90" - > - New channel - </Link> + // ON md+ THE DOCUMENT STOPS SCROLLING. The page is a flex column exactly + // the height of the viewport (main carries py-6, hence -3rem) so that the + // header, the focus line, the instrument bar and the selection deck are + // fixed chrome and the rack between them is the only thing that moves. + // Below md there is no height and the document scrolls as it always has. + <div className="flex flex-col gap-3 md:h-[calc(100vh-3rem)] md:min-h-0"> + <header className="flex flex-wrap items-start justify-between gap-x-4 gap-y-2 shrink-0"> + <div className="min-w-0"> + <h1 className="text-2xl font-semibold">Channels</h1> + {/* THE FRESHNESS NOTE IS THE PAGE'S CAVEAT, so it sits with the + page's title. It used to be the last thing on the page, in 11px + type under a floating bar, ~6,000px below the numbers it is a + caveat ABOUT — which is to say it was written but not said. */} + {channels.length > 0 && ( + <p + className="max-w-3xl text-xs text-muted-foreground" + data-testid="channels-freshness" + > + <span className="tabular-nums">{channels.length}</span>{" "} + {channels.length === 1 ? "channel" : "channels"} &middot;{" "} + {freshness.oldest ? ( + <> + Every pipeline on this page &mdash; downloads, transcripts, + digests and the speaker lanes &mdash; is read from each + channel&rsquo;s last report; the oldest on this page was + generated{" "} + <time dateTime={freshness.oldest}> + {new Date(freshness.oldest).toLocaleString()} + </time> + . A just-finished job can take a moment to show up here. + </> + ) : ( + <> + No channel on this page has a generated report yet, so every + pipeline reads empty. Run <em>Refresh report</em> from a row + here, or <em>Update all reports</em> above, to populate them. + </> + )} + {freshness.missing.length > 0 && freshness.oldest && ( + <> + {" "} + No report yet for {freshness.missing.join(", ")} — those rows + read zero + {sections + ? ", and a group figure that counts one of them is marked with a trailing + to say it is a floor rather than a total." + : "."} + </> + )} + </p> + )} </div> - </div> + {/* FOUR DARK PILLS OF EQUAL WEIGHT was four things shouting. Three of + these sweep the WHOLE pool and are used rarely; one creates a + channel and is the page's actual call to action. So the three are + outlines under an eyebrow that says what they act on, and only + "New channel" is filled. */} + <div className="flex shrink-0 flex-col items-end gap-1"> + <span className="font-mono text-[10px] uppercase tracking-[0.16em] text-muted-foreground"> + Every channel + </span> + <div className="flex flex-wrap items-center justify-end gap-2"> + <SyncAllChannelsButton /> + <RefreshAllReportsButton /> + <Link + href="/channels/new" + className="inline-flex h-8 items-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground hover:opacity-90" + > + New channel + </Link> + </div> + </div> + </header> {channels.length === 0 ? ( <p className="text-sm text-muted-foreground border border-dashed border-border rounded p-4"> {active.siteId && !active.isAll @@ -280,55 +338,21 @@ export default async function ChannelsPage({ : "No channels yet."} </p> ) : ( - <> - <ChannelsTable - channels={channels} - columns={columns} - sections={sections} - siteId={activeSite?.siteId} - // The configured cold root, for the bulk bar's box. Read here, not - // in the client component — the settings page is its one writer. - defaultMediaRoot={getSettings().storage.mediaRoot} - sites={sites.map((s) => ({ - siteId: s.siteId, - title: s.siteTitle || s.siteId, - }))} - focusLabel={focusLabel} - /> - <p - className="text-xs text-muted-foreground" - data-testid="channels-freshness" - > - {freshness.oldest ? ( - <> - Every pipeline on this page &mdash; downloads, transcripts, - digests and the speaker lanes &mdash; is read from each - channel&rsquo;s last report; the oldest on this page was - generated{" "} - <time dateTime={freshness.oldest}> - {new Date(freshness.oldest).toLocaleString()} - </time> - . A just-finished job can take a moment to show up here. - </> - ) : ( - <> - No channel on this page has a generated report yet, so every - pipeline reads empty. Run <em>Refresh report</em> from a row - here, or <em>Update all reports</em> above, to populate them. - </> - )} - {freshness.missing.length > 0 && freshness.oldest && ( - <> - {" "} - No report yet for {freshness.missing.join(", ")} — those rows - read zero - {sections - ? ", and a group figure that counts one of them is marked with a trailing + to say it is a floor rather than a total." - : "."} - </> - )} - </p> - </> + <ChannelsTable + channels={channels} + columns={columns} + sections={sections} + siteId={activeSite?.siteId} + // The configured cold root, for the selection deck's root box. Read + // here, not in the client component — the settings page is its one + // writer. + defaultMediaRoot={getSettings().storage.mediaRoot} + sites={sites.map((s) => ({ + siteId: s.siteId, + title: s.siteTitle || s.siteId, + }))} + focusLabel={focusLabel} + /> )} </div> );