Skip to content
AstroCraft Docs
On this theme

Components Reference

A lookup table for the whole component tree. TVfolio has 33 sections outside the dev catalog, 40 UI primitives, and one icon component.

The layering is: pages compose sections; sections build on primitives and native elements; primitives are token-only and know nothing about the site. UI Components explains when to reach for which.

Global sections

The 21 sections in Sections/Global/, used by two or more pages — or, in the case of the television, by all of them.

The television

Section Draws
TvSet the whole set: room, table, cabinet, tube, and the two chrome slots. Every page renders inside it
TvControlPanel the bottom strip — speaker grille, brand badge, VOL knob, LIGHT/DARK switch, four social caps, power LED. A sub-part of TvSet
TvScreenBar the channel bar: channel number, page name, signal strength, clock. Goes in slot="screen-top"
FastextBar the six coloured keys. Goes in slot="screen-bottom"
PagesDropup the channel index the F6 key opens. Rendered by FastextBar, because a <summary> must be its <details>’s first child

Structure and headings

Section Draws
SectionHead the two-part heading every block shares — a tracked title left, a dimmer routing hint right
TitleBlock a page’s opening: region head, the name in lights, the standfirst. Animates on load, not scroll
PageIntro a detail page’s opening: the return-to-index row over its rule, then title and standfirst
SpecStrip a rule over a row of key/value specs. Drawn three times across About and Project
StatsStrip three bordered stat cells, each counting up when it scrolls into view
CurrentlyBlock the availability panel — where, when, which timezone
ContactRow the sign-off: a live mailto plus the fastext routing hint to the next page

Content blocks

Section Draws
TubeStill the framed, scroll-scaling capture. Use this for any image inside the tube
TubeFigure a full-width TubeStill plus its FIG caption row
CamTag the stamped-on camera identifier in a still’s corner
TestCard the EBU 75% colour-bar test card, framed and captioned
PullQuote the ruled-off pull quote — hairlines on both sides, unlike every other block
TransmissionList a numbered list of transmissions; also the 404’s channel lineup
CareerList the career log, one numbered posting per row
TubeSlab one slab from the action row — a tracked label over a sub-line
LinkButtons a row of TubeSlabs, side-by-side above the cabinet split

_fastext.ts sits alongside them: not a section, but the shared module holding the F-number opacity, because two components draw a key and the contrast check imports the value rather than guessing it.

Page sections

Folder Section Draws
Home/ Hero the home hero, in the CRT idiom
About/ ProfileBlock the portrait beside the long-form briefing
Work/ TransmissionGrid the six project cards CH 02 tunes to
ProjectBriefing the long-form column beside the highlights list
ProjectGallery the STILLS block, two-up on desktop
ProjectActions LAUNCH DEMO and VIEW SOURCE — each renders only if its URL exists
Blog/ BulletinIndex the log index: featured bulletin then the numbered archive
BulletinArticle the two-column post — prose left, aside blocks right
PostNav the sign-off row: the older bulletin, and this one’s position
SubscribeRow the feed’s printed address as a live link
Contact/ ContactForm the only block on the set that takes input
Legal/ LegalArticle the shared renderer for Terms and Privacy

UiCatalog/ holds nine more sections for the dev-only /examples/ui route. Delete the folder before launch.

UI primitives

All 40, in src/components/ui/<name>/. Each exports its component, a <Name>Variants object and a default.

Tier 1button · input · label · textarea · badge · card (Image, Header, Title, Description, Action, Content, Footer) · alert · separator · skeleton · avatar

Tier 2accordion (<details>) · tabs · tooltip (CSS-only) · breadcrumb · pagination · progress · spinner

Tier 3dialog (native <dialog>) · sheet (a Dialog pinned to an edge) · dropdown (Popover API) · select (native) · checkbox · radio · switch · table

Advanced form controlsslider (native range) · input-number · toggle-count · password (PasswordInput + PasswordStrength) · combobox · advanced-select · searchbox (⌘K palette)

Navigation & contentnav (Nav, NavItem, NavLink) · mega-menu · list

Content & motionsplit-text · count-up · marquee · reveal

Themetheme-toggle

The three the design uses

reveal, split-text and count-up. Plus two modules: _client.ts’s onReady, and theme-toggle/theme.ts, which the cabinet’s LIGHT/DARK switch imports without using the component.

The other thirty-seven exist so /examples/ui can render them. That is a decision, and UI Components explains the rule it gives you.

Shared internals

Not primitives — modules, prefixed accordingly:

Module Job
_client.ts onReady — the load + astro:after-swap re-init contract every scripted primitive shares
_dialog.ts the delegated Dialog/Sheet controller; binds once, survives view transitions
_popover.ts placement for Dropdown and MegaMenu, plus arrow-key roving
_field.ts the shared field look — size and validation state
_listbox.ts filterByText / nextIndex / createActiveDescendant for the filterable trio
_overlay.css Dialog and Sheet transitions, the backdrop scrim, the modal scroll-lock
_Chevron.astro the one disclosure/select chevron glyph
password/strength.ts the rule-based scorePassword

Icons

<Icon /> from @components/svg/icons — 572 icons, name typed as IconName, size in four steps, title for an accessible name. See Icons.

Layouts

File Job
BaseLayout.astro <html> + <head> + a chrome-free <body> with one slot
BaseHead.astro every meta, OG, Twitter and JSON-LD tag; the pre-paint theme script; <ClientRouter />

BaseLayout is deliberately chrome-free — no nav, no footer. Those are composed per page, which for this theme means composed inside TvSet.

Utilities

Module Exports
@js/blog getBulletins()
@js/work getWork()
@js/schema six JSON-LD builders, organizationId, serializeJsonLd, the SeoProps type
@js/cv cvRecord, renderCvText, renderCvPdf, toWinAnsi, pdfEscape
@js/rss buildRss
@js/contact parseContact, rateLimited, contactEmail, statusUrl, the limits and constants
@js/textUtils slugify, isoDate, pad2, readingTime, readableUrl, formatDate
@config/navData channelFor, fkeyFor, fkeyLabelFor, assertChannelLabels, channels, the keys
@config/siteData the site record plus availabilityLabels
NEXT STEPCommands & Testing