Design system
Internal audit. Everything we use to render 1ar.io, one page. Snapshot taken 2026-04-17.
Not listed in nav. Public. Built to reduce hotfixes. Every "raw pattern" below is a place where pages inline Tailwind instead of using a component — these are the duplication hotspots worth fixing first.
Button
Badge
Tag
Card
default
opaque base-200 card
Content.glass
frosted glass-card
Content.flat
no class, no padding
Content.ArrowCard
With arrow
Click through card. Used on /tools and homepage FeaturedTools.
No href
Renders as div when no href given.
Input
This field is required.
FormattedDate · Icon
Pagination
MinimalCodeBlock
import Button from "@/components/ui/Button.astro";
<Button variant="default">hello</Button>
CalloutBox · CTAButton
49 components across 10 folders. Each lists its props, variants, which CSS classes it applies, and whether it hydrates as an island.
layout · 6
BaseLayout
layouts/BaseLayout.astro default page shell: header, footer, fonts, analytics, breadcrumb
props: title, description, image, type
AdminLayout
layouts/AdminLayout.astro standalone admin shell (always-dark sidebar), does NOT extend BaseLayout
props: title, user
Header
components/layout/Header.astro fixed top nav, desktop dropdowns + mobile pill layout
css: mobile-pill, mobile-dropdown-panel, header-glass
Footer
components/layout/Footer.astro site footer with brand + links + contact
css: layout-container, section-title
NavDropdown
components/layout/NavDropdown.astro hover-open dropdown for desktop nav
props: item, currentPath
css: nav-dropdown-*
UpdatesSidebar
components/layout/UpdatesSidebar.astro taxonomy filters for /updates (kind, status, tags, categories, archive)
props: entries
css: section-title, tag, filter-chip
ui · 22
Button
components/ui/Button.astro polymorphic button/link
props: variant, size, href, class
variants: default, secondary, outline, ghost, neutral, light · sizes: sm, default, lg
css: glass-btn, glass-btn-secondary, btn-light, liquid-border
Card
components/ui/Card.astro generic container with header/title/description/content/footer slots
props: variant, padding, class, hover
variants: default (card), glass, layered, flat
css: card, glass-card
ArrowCard
components/ui/ArrowCard.astro card with optional arrow icon, renders as anchor or div
props: href, ariaLabel, showArrow, arrowHref
css: glass-card
Badge
components/ui/Badge.astro small pill label
props: variant, class
variants: default, secondary, outline
Tag
components/ui/Tag.astro rounded mono pill; span or anchor
props: href, class
css: tag
TagCloud
components/ui/TagCloud.astro tag list with counts for sidebar
props: tags
css: section-title, tag
ArchiveList
components/ui/ArchiveList.astro year archive link list for sidebar
props: archives
css: section-title
Container
components/ui/Container.astro max-width content wrapper
props: size, class
css: layout-container
Section
components/ui/Section.astro full-width section wrapper with vertical padding (NOT used much; most pages inline section tags)
props: variant, size, class
variants: default, muted · sizes: sm, default, lg
SectionHeading
components/ui/SectionHeading.astro anchor-linked heading used across homepage sections
props: label, id, centered
css: section-title
PageHeader
components/ui/PageHeader.astro standardized h1 + subtitle for page tops (UNDERUSED: see raw-pattern list below)
props: title, description, titleClasses, descriptionClasses, containerClasses
Breadcrumb
components/ui/Breadcrumb.astro back-link with optional active filter chip for second-level pages
css: breadcrumb, breadcrumb-link, filter-chip
Pagination
components/ui/Pagination.astro prev/next pagination nav
props: prevUrl, nextUrl, currentPage, totalPages
Input
components/ui/Input.astro labeled text input with validation state
props: label, error, ...native input attrs
css: app-input, app-input-invalid
FormattedDate
components/ui/FormattedDate.astro time element with en-US locale formatting
props: date
Icon
components/ui/Icon.astro RemixIcon renderer with shorthand alias map
props: name, size, class
Lightbox
components/ui/Lightbox.astro full-screen image zoom overlay, activates on [data-lightbox]
CodeBlock
components/ui/CodeBlock.astro canonical code block — Shiki+vesper, copy button, identical look on .astro pages and inside markdown content
props: code, lang, class
MinimalCodeBlock
components/ui/MinimalCodeBlock.astro plain pre/code block with copy-to-clipboard button (no syntax highlighting)
props: text, id, class
ScrollableText
components/ui/ScrollableText.astro scrollable container with styled thin scrollbar
props: class, maxHeight, trackMargin
AwardsMarquee
components/ui/AwardsMarquee.astro auto-scrolling horizontal awards strip
props: awards, href, class
ClickToCopyEmail
components/ui/ClickToCopyEmail.astro obfuscated email button that copies on click
props: userPart, domainPart, buttonText, trackLocation
sections · 8
Hero
components/sections/Hero.astro page hero with optional rotating tagline and CTA
props: title, subtitle, taglines[], cta
CTASection
components/sections/CTASection.astro reusable CTA block with 1-2 buttons
props: title, description, primaryCta, secondaryCta, variant
variants: default, glass, flat
FeaturedProjects
components/sections/FeaturedProjects.astro homepage 3-up project grid from featured entries
props: count
FeaturedTools
components/sections/FeaturedTools.astro homepage tools teaser (single ArrowCard currently)
RecentUpdates
components/sections/RecentUpdates.astro homepage list of 4 recent update/article/event entries
Services
components/sections/Services.astro services/offerings grid
css: glass-card, section-title
Testimonials island
components/sections/Testimonials.astro testimonials section wrapper
props: title
AiNews
components/sections/AiNews.astro homepage briefing: tech news + Polymarket tabs (fetches cached blobs)
css: app-tablist, app-tab-active, market-pill, liquid-border, hover-glow, sumr-nav
cards · 2
ProjectCard
components/cards/ProjectCard.astro linked card for a project entry (icon + status badge)
props: project
css: glass-card
UpdateCardSlim
components/cards/UpdateCardSlim.astro compact horizontal row for timeline entry
props: entry
css: glass-card, tag
updates · 1
TimelineCard
components/updates/TimelineCard.astro full timeline card for /updates page
props: entry
css: glass-card, tag, tag-event-*
content · 4
CalloutBox
components/content/CalloutBox.astro MDX callout block with icon and colored border
props: variant
variants: info, warning, success
css: glass-card
CTAButton
components/content/CTAButton.astro inline CTA link for use inside MDX prose
props: text, href, variant
variants: primary, light
css: glass-btn
ImageGrid
components/content/ImageGrid.astro responsive image grid wrapper for MDX
props: columns (1-4)
VideoEmbed
components/content/VideoEmbed.astro aspect-ratio iframe embed for YouTube/Vimeo
props: url, title
css: glass-card
blog · 1
TableOfContents
components/blog/TableOfContents.astro nested on-page anchor nav for h2-h4
props: headings
email · 1
EmailSignup
components/email/EmailSignup.astro double opt-in email signup form with already-subscribed state
props: source, title, description, blurb, class
css: card, email-signup-btn
search · 1
CommandPalette island
components/search/CommandPalette.tsx Fuse.js-powered fuzzy search palette; blurs layout-main+footer on open for iOS keyboard gap
props: baseUrl
css: liquid-border
testimonials · 1
TestimonialsCarousel island
components/testimonials/TestimonialsCarousel.tsx Embla carousel of testimonial cards with highlight text
css: liquid-border, testimonial-scrollbar
theme · 2
ThemeScript
components/theme/ThemeScript.astro FOUC-prevention: sets theme from localStorage/system, exposes window.toggleTheme()
ThemeToggle
components/theme/ThemeToggle.astro sun/moon toggle button; syncs via theme-changed event
Defined in src/styles/global.css. Tailwind utilities beat @layer components in specificity — keep transition/hover properties owned by whoever defines the variant.
@layer components · 10
glass-card semi-transparent frosted card, blur, liquid border via ::after
used by: ProjectCard, ArrowCard, UpdateCardSlim, CalloutBox, VideoEmbed, TimelineCard, CTASection(glass), Card(glass/layered), Services
card opaque base-200 card, shadow, liquid border via ::after
used by: EmailSignup, Card(default), unsubscribe.astro
glass-btn primary CTA button, metallic gradient, blur, liquid border, dark-mode muted amber
used by: Button(default), admin/login submit (raw)
glass-btn-secondary subdued glass button, shadow deepens on hover
used by: Button(secondary)
btn-light inverted contrast button (near-black light / near-white dark)
used by: Button(light)
app-input styled text input with focus ring and autofill override
used by: Input, admin/login forms (raw)
app-input-invalid error state border + red glow ring
used by: Input
app-tablist / app-tab-active / app-tab-idle pill-style tab container with inset shadow
used by: AiNews
market-pill tiny mono pill for market data
used by: AiNews
mobile-pill / mobile-dropdown-panel / mobile-menu-backdrop opaque mobile header pill (no backdrop-filter) + floating dropdown (display:none when hidden to avoid Safari tinting)
used by: Header
@layer utilities · 4
liquid-border gradient border via ::after pseudo-element, works with semi-transparent fills
used by: Button(neutral), TestimonialsCarousel, CommandPalette, AiNews tablist
hover-glow on hover sets --color-base-content to accent
used by: AiNews sumr button
hide-scrollbar hides scrollbar (webkit + Firefox)
used by: any scrollable container
no-spinner removes number input spinner arrows
used by: utility
global-scope classes · 15
layout-container max-width centered content wrapper with responsive padding
layout-main / layout-main-fullwidth padding-top for fixed header; target for page-glow
layout-content-with-sidebar / layout-sidebar / layout-primary sidebar flex layout primitives for /updates
breadcrumb / breadcrumb-link back-link navigation row
section-title uppercase mono small-caps label
tag rounded mono pill
filter-chip / filter-chip-x active filter tag with dismiss button
tag-event-upcoming / tag-event-live / tag-event-past colored status pills for events
email-signup-btn submit button for email signup (armed state flips to amber accent)
testimonial-scrollbar thin primary-colored scrollbar for quote area
page-glow when set on html, applies dual radial-gradient to layout-main (matches autaxy app shell)
sumr-nav mono flex link list for Sumr sub-nav and bottom-of-article nav
animate / animate.show fade+slide-up entrance animation with staggered nth-child delays
prose rich text typography for MDX article pages
astro-code / code-block-wrapper / code-copy-btn shiki+vesper syntax highlight block + copy button. shared by markdown blocks and the CodeBlock component on .astro pages — identical bg (#101010), border, padding, font
Ancillary stylesheets
src/styles/admin.css— admin dashboard ("1ar orbit") styles; always-dark sidebar, tables, auth forms. Scoped to /admin/*.src/styles/autaxy.css— autaxy embed overrides scoped under.autaxy-wrapper. Contains .app-shell gradient matching page-glow.
Places where pages inline Tailwind instead of using an existing component, or should have a new component. Sorted roughly by impact (count of occurrences).
01 Page header block
25+×<div class="mb-8">
<h1 class="text-4xl md:text-5xl font-serif leading-tight mb-4 text-[var(--color-base-content)]">Title</h1>
<p class="text-lg text-[var(--color-neutral-content)]">Subtitle</p>
</div> - projects/index.astro + 7 project subpages
- tools/cin, finder-file-actions, graft, raycast-bridges
- sumr/index, contact, manual, pricing, privacy, terms (6 pages)
- updates/index + archive/[year] + category/[category] + status/[status] + tag/[tag] + type/[kind] (6 filter pages)
- privacy.astro, terms.astro
fix use <PageHeader title=... description=... />
02 CTA button row (project/tool detail top)
13+×<div class="flex flex-wrap gap-3 mb-8">
<Button ...>...</Button>
<Button ...>...</Button>
</div> - all 8 project detail pages
- tools/cin, finder-file-actions, graft, raycast-bridges
- publications.astro
fix extract <ButtonRow> wrapper OR add a `ctaRow` slot to PageHeader
03 Bottom breadcrumb nav (sumr-nav)
19+×<nav class="not-prose sumr-nav my-6"><a href="/">home</a> / <a href="/parent">parent</a> / title</nav> - all 8 project detail pages
- tools/autaxy, cin, finder-file-actions, graft, raycast-bridges
- sumr/* (11 occurrences across 6 pages)
fix extract <DetailNav crumbs=[...] /> component (renames sumr-nav to detail-nav)
04 Inline external link style
10+×<a class="text-[var(--color-link)] hover:text-[var(--color-link-hover)] transition-colors duration-300" href="...">...</a> - publications.astro (6x)
- admin/index.astro
- admin/subscribers.astro
- sumr-trace.astro
- workshops.astro (complex [&_a]: variant inside blockquote)
fix either a <Link /> component OR a global `.prose a` rule + global `a` default that matches this
05 Badge pill (accent variant)
2×<span class="inline-block text-xs font-mono uppercase tracking-wider px-2 py-0.5 rounded-md bg-[var(--color-accent)]/15 text-[var(--color-accent)]">Coming soon</span> - sumr-trace.astro
- workshops.astro
fix add an `accent` variant to <Badge>; it currently lacks this exact look
06 Filter-page header (section-title + h1 + count)
6 files×<div class="mb-8">
<p class="section-title">Archive</p>
<h1 class="text-2xl font-bold text-[var(--color-base-content)]">2026</h1>
<p class="text-sm mt-1 text-[var(--color-neutral-content)]">N entries</p>
</div> - updates/index
- archive/[year]
- category/[category]
- status/[status]
- tag/[tag]
- type/[kind]
fix extract <FilterPageHeader kicker=.. title=.. count=.. /> — distinct from PageHeader (smaller h1, kicker label)
07 App Store badge
2 (verbatim)×<a href="https://apps.apple.com/..."><img src="..." style="border-radius:10px;width:160px"/></a> - sumr/index.astro
- sumr/pricing.astro
fix extract <AppStoreBadge variant='apple|google' href=... />
08 Admin login form field (label + app-input)
4×<label class="block text-sm font-medium">Email</label>
<input class="w-full h-10 px-4 app-input" type="email" required /> - admin/login.astro (4x across signin + signup)
fix use <Input label='Email' /> (component already exists)
09 Admin login submit button
2×<button class="w-full h-10 glass-btn text-[var(--color-primary-content)] rounded-[var(--radius-box)] font-medium text-sm mt-2">Sign in</button> - admin/login.astro (2x)
fix use <Button variant='default' class='w-full'>Sign in</Button>
10 Achievements / feature card grid (about)
6 items, 1 page×<div class="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-8">
<div><i class="ri-rocket-line..."></i><h3>...</h3><p>...</p></div>
...
</div> - about.astro
fix extract <FeatureCard icon=.. title=.. description=.. /> + <FeatureGrid>
11 Publications citation block
N per paper×<div class="text-xs font-mono text-[var(--color-neutral-content)]/60 bg-[var(--color-base-200)]/50 rounded px-3 py-2 mb-3">Journal · Year · DOI</div> - publications.astro
fix extract <CitationBlock />
12 Screenshot gallery
1 but should be shared×<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-10">{imgs.map(i => <img class="rounded-lg border border-[var(--color-base-300)]" ... />)}</div> - tools/finder-file-actions.astro
fix ImageGrid component exists (content/ImageGrid.astro) but is not used; align its API and adopt
13 Event status banner
2 variants inline×<div class="card p-4 mb-4 border-l-4 border-[var(--color-accent)]">...</div> - updates/[...slug].astro (2 variants: accent, neutral)
fix extract <EventBanner status='upcoming|past|live' />
14 Tag list footer
1 page×<footer class="mt-8 pt-6 border-t border-[var(--color-separator)]"><div class="flex flex-wrap gap-2">{tags.map(t => <a class="tag" href=...>{t}</a>)}</div></footer> - updates/[...slug].astro
fix extract <TagList tags=[...] /> (shares <Tag> component)
15 Article meta row
1×<div class="flex flex-wrap items-center gap-4 text-sm text-[var(--color-neutral-content)]"><Icon name='calendar'/><FormattedDate.../>...</div> - updates/[...slug].astro
fix extract <ArticleMeta entry=... />
16 Group section header (Upcoming/Past)
2 versions of same pattern×<header class="mb-4 flex items-baseline gap-3"><h2 class="text-lg font-semibold ...">Upcoming</h2><span class="text-xs font-mono ...">N</span></header> - updates/index.astro (via JS)
- updates/type/[kind].astro (SSR)
fix extract <GroupHeading label=... count=... />
17 Two-col text + image grid
2×<div class="grid grid-cols-1 md:grid-cols-2 gap-8 items-center">...</div> - about.astro
- contact.astro
fix either a <TwoColumn> layout primitive OR accept as a common inline pattern
18 Admin head block duplication
2 near-copies×<head>Google Fonts + RemixIcon CDN + ThemeScript</head> - AdminLayout.astro
- admin/login.astro
fix login.astro should extend AdminLayout, or extract <AdminHead /> partial
19 page-glow activation script
6×<script>document.documentElement.classList.add('page-glow');</script> - sumr/index, contact, manual, pricing, privacy, terms
fix add a `pageGlow?: boolean` prop on BaseLayout that emits this script
20 Portfolio / format cards (workshops)
2 patterns on 1 page×<div class='glass-card'><div class='flex items-center justify-between mb-2'><h3>...</h3><span class='tag tag-event-upcoming'>...</span></div>...</div> - workshops.astro
fix align with ProjectCard / ArrowCard slot API or add a UpcomingEventCard component
21 404 primary-button anchor
1×<a class="inline-flex items-center gap-2 px-6 py-3 rounded-lg bg-[var(--color-primary)] text-white font-medium hover:opacity-90 transition-opacity">back home</a> - 404.astro
fix use <Button href='/' variant='default'>back home</Button>
Page header block
The strongest finding. Same h1 + subtitle markup copy-pasted on ~25 pages (every project detail, every tool detail, every filter page, every sumr page, privacy, terms). PageHeader already exists and is used on about, contact, awards, publications, tools/index, sumr-trace, workshops. The rest should migrate.
Bottom detail nav (sumr-nav)
~19 occurrences of <nav class="not-prose sumr-nav my-6"> across project pages, tool pages, and sumr pages. Name is misleading — it's used far beyond sumr. Should be renamed (detail-nav) and componentized.
CTA button row
flex flex-wrap gap-3 mb-8 wrapping Button components — 13+ pages. Candidate for a PageHeader slot or a dedicated ButtonRow primitive.
Inline external link style
text-[var(--color-link)] hover:text-[var(--color-link-hover)] transition-colors repeated 10+ times on loose anchors in publications, admin, workshops, sumr-trace. Either a Link component or a global a default rule.
Mixed button discipline
404.astro uses a raw primary-button anchor, admin/login uses raw glass-btn submit buttons, EmailSignup has its own email-signup-btn class. Three different button paths doing similar work. Button component should be the only button path.
Admin head duplication
admin/login.astro bypasses both BaseLayout and AdminLayout, rendering its own doctype/head. Google Fonts + RemixIcon CDN links are duplicated between the two files.
page-glow activation
6 sumr/* pages each ship the same inline <script>document.documentElement.classList.add('page-glow')</script>. BaseLayout should expose pageGlow?: boolean.
Audit-only summary. No code was modified in this pass. Suggested ordering for a cleanup sweep:
- Enforce PageHeader across all 25+ pages. Delete the raw h1 + subtitle blocks. Verify the existing default classes match what those pages had.
- Extract DetailNav from sumr-nav. Rename the CSS class, migrate all 19+ call sites, update CLAUDE.md.
- Add pageGlow prop to BaseLayout, drop the 6 inline scripts. Sumr pages also reach
layout-main-fullwidth— consider one prop that handles both. - Unify buttons. Replace admin/login raw glass-btn + 404 raw primary anchor with
<Button>. Port EmailSignup to use Button + override viaclassprop. - Add Badge accent variant (or a
Pillcomponent) for the uppercase-mono tiny label used in sumr-trace and workshops. - Global a-tag styling. Decide: either a
<Link>component for external anchors OR a globaladefault that matches the inline pattern. Pick one. - Filter-page header. Extract
<FilterPageHeader>— it's a distinct pattern from PageHeader (smaller h1, kicker label, count line). 6 updates pages. - Article detail bits: ArticleMeta, TagList, EventBanner, GroupHeading. All live only in
updates/[...slug].astro+ one filter page — low risk extractions. - Admin login: extend AdminLayout or extract AdminHead partial. Use Input + Button for the form.
- Pricing/feature cards: sumr/pricing currently has zero cards — two pricing options inside
.prose. Workshops has glass-card blocks with raw interior. A shared FeatureCard + PricingCard would cover both.
src/pages/** and src/components/**. No component was modified. Not linked from nav; discoverable only via direct URL. If a pattern here looks wrong, the page is stale — regenerate the audit before trusting it.