Archilyzer · Source

archilyzer

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

commit 0ebdb1a6b3247eb856d297eb7b4effc702ae2f22
parent d8c9f227f216e98be545f100f549192a764798cb
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Fri, 25 Sep 2026 20:08:42 -0400

hub, homepage: Title Case headings, no subtitle under Official Instances, no description on the official cards

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

Diffstat:
Mexport/app/components/hub/AddArchive.tsx | 2+-
Mexport/app/components/hub/ArchiveShelf.tsx | 72+++++++++++++++++++++++++++++++-----------------------------------------
Mhomepage/app/components/ArchiveCards.tsx | 33++++++++++++++-------------------
Mhomepage/app/page.tsx | 16+++++++---------
4 files changed, 53 insertions(+), 70 deletions(-)

diff --git a/export/app/components/hub/AddArchive.tsx b/export/app/components/hub/AddArchive.tsx @@ -1,7 +1,7 @@ "use client"; // The add-an-archive control: paste an archive URL, it validates against the -// federation contract, and on success the archive joins "Archives you added". +// federation contract, and on success the archive joins "Archives You Added". // Written as direction — validating → success, or a plain reason it couldn't // be read. Self-contained: owns its input + status and commits to the shared // registry. The button is the family's CTA — ink on ground, not a coloured diff --git a/export/app/components/hub/ArchiveShelf.tsx b/export/app/components/hub/ArchiveShelf.tsx @@ -3,8 +3,9 @@ // The hub's front: what it is, the official instances it searches, the // archives a visitor added, and the form to add another — in the homepage's // register (homepage/app/page.tsx): short declarative sentences, no eyebrow -// over a band, no subtitle under a heading, and each heading after the H1 -// names what is under it. +// over a band, no subtitle under a heading (nor under a card's title: the +// site's description is not shown), Title Case headings, and each heading +// after the H1 names what is under it. // // Two kinds of number, deliberately kept apart. An official card shows the // homepage's own figures for that archive, composed at hub build time @@ -67,7 +68,6 @@ function ArchiveCard({ }) { const accent = site.accent || figures?.accent || fallbackAccent; const href = site.siteUrl || site.origin; - const description = figures?.siteDescription; const channels = figures === undefined ? site.channelCount : figures?.channels; const anyFigure = @@ -86,38 +86,31 @@ function ArchiveCard({ className="absolute inset-y-0 left-0 w-[3px]" style={{ background: accent }} /> - <div className="flex flex-col gap-1.5"> - <div className="flex items-start justify-between gap-2"> - <h3 className="font-display text-lg font-semibold text-foreground"> - <a - href={href} - target="_blank" - rel="noopener noreferrer" - className="underline decoration-transparent underline-offset-4 transition-colors hover:decoration-border-strong" - > - {site.siteTitle} - <span aria-hidden="true" className="ml-1.5 text-sm text-faint"> - ↗ - </span> - </a> - </h3> - {onRemove && ( - <button - type="button" - onClick={() => onRemove(site.origin)} - aria-label={`Remove ${site.siteTitle}`} - // Reveal-on-hover is not an affordance on a touch screen: a device - // with no hover shows it always. `hover:` never gates a function. - className="-mr-1 mt-0.5 rounded p-0.5 text-muted-foreground/60 opacity-0 transition-opacity pointer-coarse:opacity-100 hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100" - > - <X className="size-3.5" aria-hidden="true" /> - </button> - )} - </div> - {description && ( - <p className="text-sm leading-relaxed text-muted-foreground"> - {description} - </p> + <div className="flex items-start justify-between gap-2"> + <h3 className="font-display text-lg font-semibold text-foreground"> + <a + href={href} + target="_blank" + rel="noopener noreferrer" + className="underline decoration-transparent underline-offset-4 transition-colors hover:decoration-border-strong" + > + {site.siteTitle} + <span aria-hidden="true" className="ml-1.5 text-sm text-faint"> + ↗ + </span> + </a> + </h3> + {onRemove && ( + <button + type="button" + onClick={() => onRemove(site.origin)} + aria-label={`Remove ${site.siteTitle}`} + // Reveal-on-hover is not an affordance on a touch screen: a device + // with no hover shows it always. `hover:` never gates a function. + className="-mr-1 mt-0.5 rounded p-0.5 text-muted-foreground/60 opacity-0 transition-opacity pointer-coarse:opacity-100 hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100" + > + <X className="size-3.5" aria-hidden="true" /> + </button> )} </div> <div className="mt-auto flex flex-col gap-3"> @@ -177,12 +170,9 @@ export default function ArchiveShelf() { {official.length > 0 ? ( <div> - <h2 className="font-display text-2xl font-semibold text-foreground"> - Official instances + <h2 className="mb-6 font-display text-2xl font-semibold text-foreground"> + Official Instances </h2> - <p className="mt-2 mb-6 max-w-xl leading-relaxed text-muted-foreground"> - The archives I run. Anyone can run their own. - </p> <ul className={GRID}> {official.map((site, i) => { const figures = hubSummarySiteFor(summary, site); @@ -209,7 +199,7 @@ export default function ArchiveShelf() { {added.length > 0 && ( <> <h2 className="font-display text-2xl font-semibold text-foreground"> - Archives you added + Archives You Added </h2> <ul className={`${GRID} mt-6 mb-6`}> {added.map((site, i) => ( diff --git a/homepage/app/components/ArchiveCards.tsx b/homepage/app/components/ArchiveCards.tsx @@ -2,7 +2,9 @@ import type { HomepageSummarySite } from "yt-dlp-transcript-common/lib/homepageS import { seriesColor } from "yt-dlp-transcript-common/lib/homepageChart"; // The official instances: one card per public archive, its title linking out, -// its own numbers underneath. The stripe is seriesColor(i), the same index the +// its own numbers underneath. No description line under the title — the +// page's copy rule is no subtitles unless needed, and the name plus the +// numbers say what the archive is. The stripe is seriesColor(i), the same index the // growth chart colours that instance's layer with, so a card is its own legend. // // A site's `accent` is deliberately NOT used here any more: the chart cannot @@ -38,24 +40,17 @@ export function ArchiveCards({ sites }: { sites: HomepageSummarySite[] }) { className="absolute left-0 top-0 h-full w-[3px]" style={{ backgroundColor: seriesColor(i) }} /> - <div className="flex flex-col gap-1.5"> - <h3 className="font-display text-lg font-semibold text-[var(--foreground)]"> - <a - href={site.siteUrl} - target="_blank" - rel="noopener noreferrer" - className="underline decoration-transparent underline-offset-4 transition-colors hover:decoration-[var(--border-strong)]" - > - {site.siteTitle} - <span aria-hidden="true" className="ml-1.5 text-sm text-[var(--faint)]">↗</span> - </a> - </h3> - {site.siteDescription && ( - <p className="text-sm leading-relaxed text-[var(--muted-foreground)]"> - {site.siteDescription} - </p> - )} - </div> + <h3 className="font-display text-lg font-semibold text-[var(--foreground)]"> + <a + href={site.siteUrl} + target="_blank" + rel="noopener noreferrer" + className="underline decoration-transparent underline-offset-4 transition-colors hover:decoration-[var(--border-strong)]" + > + {site.siteTitle} + <span aria-hidden="true" className="ml-1.5 text-sm text-[var(--faint)]">↗</span> + </a> + </h3> <dl className="mt-auto grid grid-cols-4 gap-3"> <Figure value={site.channels} unit="channels" /> <Figure value={site.recordings} unit="recordings" /> diff --git a/homepage/app/page.tsx b/homepage/app/page.tsx @@ -13,7 +13,8 @@ import { currentHomepage } from "./lib/homepage"; // loadSummary(). A build with no data renders the words and the links only. // // Copy rules, kept deliberately: short declarative sentences, no eyebrow over -// every band, no subtitles under the headings. The page has two headings after +// every band, no subtitles under the headings or the cards, headings in Title +// Case (the hub shelf matches). The page has two headings after // the H1 and both name what is under them. const CONTAINER = "w-full max-w-6xl mx-auto px-5 sm:px-6"; @@ -106,28 +107,25 @@ export default function Home() { </section> )} - {/* ── Official instances ───────────────────────────────────────────── */} + {/* ── Official Instances ───────────────────────────────────────────── */} {sites.length > 0 && ( <section className="border-t border-[var(--border)]"> <div className={`${CONTAINER} py-14 sm:py-20`}> - <h2 className="font-display text-2xl font-semibold text-[var(--foreground)]"> - Official instances + <h2 className="mb-8 font-display text-2xl font-semibold text-[var(--foreground)]"> + Official Instances </h2> - <p className="mt-2 mb-8 max-w-xl text-[var(--muted-foreground)] leading-relaxed"> - The archives I run. Anyone can run their own. - </p> <ArchiveCards sites={sites} /> </div> </section> )} - {/* ── What it does ─────────────────────────────────────────────────── */} + {/* ── What It Does ─────────────────────────────────────────────────── */} {/* Three short paragraphs, not three titled panels: without titles, three one-sentence items read as prose, not as a feature grid. */} <section className="border-t border-[var(--border)]"> <div className={`${CONTAINER} py-14 sm:py-20`}> <h2 className="font-display text-2xl font-semibold text-[var(--foreground)]"> - What it does + What It Does </h2> <div className="mt-6 flex max-w-2xl flex-col gap-4 text-[1.0625rem] leading-relaxed text-[var(--muted-foreground)]"> <p>