Files
CompanySite/.agents/documentation-writer/COMPONENT_LIBRARY.md
T
Clintchiz 0614ae6f85
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
Deploy to Production / Build & Verify (push) Failing after 13s
Ping Search Engines / Notify Search Engines (push) Successful in 3s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 1s
E2E Test Suite / Smoke Tests (P0) (push) Failing after 9m36s
E2E Test Suite / Form Interaction Tests (push) Failing after 12m6s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 11m46s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 9m31s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 11m5s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 15m24s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 6s
E2E Test Suite / Mobile Device Tests (push) Failing after 3h12m28s
Uptime Monitor / Health & Response Time (push) Successful in 5s
Uptime Monitor / SSL Certificate (push) Successful in 3s
Uptime Monitor / Send Alerts (push) Has been skipped
Uptime Monitor / Record Uptime Success (push) Successful in 2s
Latest Updated Pages
2026-03-22 14:37:17 +05:30

8.6 KiB

WorkRoot Component Library

A reference for all reusable UI components. Every component listed here fully supports dark/light theme switching via Tailwind's dark: variant prefix — the dark class is toggled on <html> by ThemeToggle.astro.


Theme Architecture

Mechanism Detail
Strategy Tailwind class dark mode (darkMode: 'class' in tailwind.config.mjs)
Toggle <ThemeToggle /> writes dark / light to localStorage and toggles html.dark
FOUC prevention Inline <script is:inline> in BaseLayout.astro <head> reads localStorage synchronously before CSS renders
CSS tokens src/styles/design-tokens.css + legacy aliases in global.css under html.dark {}

Components

Badge

File: src/components/ui/Badge.astro

Eyebrow labels used above section headings.

<Badge label="Why Choose Us" variant="primary" />
<Badge label="New Feature" variant="accent" />
<Badge label="Category" variant="secondary" />
Variant Light Dark
primary (default) bg-primary-50 text-primary-700 bg-primary-900/40 text-primary-300
primary-dark bg-primary-400/20 text-primary-300 same (designed for dark sections)
accent bg-accent-50 text-accent-700 bg-accent-900/40 text-accent-300
secondary bg-secondary-100 text-secondary-700 bg-secondary-800 text-secondary-300

Usage note: Use primary or accent on light/surface sections. Use primary-dark on hero/CTA sections that have dark gradient backgrounds (these sections are dark in both themes).


Card

File: src/components/ui/Card.astro

Versatile content container with predefined style variants.

<Card variant="feature">...</Card>
<Card variant="service" padding="p-8">...</Card>
<Card variant="surface">...</Card>
<Card variant="dark">...</Card>  <!-- for use on dark gradient sections -->
<Card variant="plain">...</Card> <!-- no styles applied -->
Variant Light Dark
feature from-secondary-50 to-white, border secondary-100 from-secondary-800 to-secondary-900, border secondary-700
service bg-white, border secondary-100 bg-secondary-800, border secondary-700
surface bg-secondary-50, border secondary-200 bg-secondary-800, border secondary-700
dark bg-white/5 glassmorphism (static) same — designed for dark gradient backgrounds only

SectionHeader

File: src/components/ui/SectionHeader.astro

Standard eyebrow + heading + description pattern used in every section.

<!-- On light/surface sections -->
<SectionHeader
  badge="Our Services"
  title="What We Build"
  description="From concept to production."
  theme="light"
  badgeColor="primary"
/>

<!-- On dark/hero sections -->
<SectionHeader
  badge="How It Works"
  title="Simple Process"
  theme="dark"
  badgeColor="accent"
/>
Prop Type Default Notes
badge string required Eyebrow label text
title string required <h2> heading
description string Optional paragraph below heading
theme 'light' | 'dark' 'light' Controls text/badge colors
badgeColor 'primary' | 'accent' 'primary' Badge hue
maxWidth string 'max-w-3xl' Tailwind width class

Theme behavior:

  • theme="light" — heading text-secondary-900 dark:text-secondary-50, description text-secondary-600 dark:text-secondary-400
  • theme="dark" — heading text-white, description text-secondary-300 (used on dark gradient backgrounds that look the same in both themes)

ThemeToggle

File: src/components/ThemeToggle.astro

Sun/moon icon button that toggles between dark and light mode.

<ThemeToggle />
  • Persists preference in localStorage under key theme ('dark' | 'light')
  • Falls back to prefers-color-scheme when no stored preference
  • Updates meta[name="theme-color"] for browser chrome color
  • Fully keyboard accessible — ARIA label updates dynamically
  • Respects prefers-reduced-motion

Header

File: src/components/Header.astro

Fixed top navigation with desktop menu, mobile slide-out panel, and theme toggle.

<Header />  <!-- used in BaseLayout, no props needed -->

Dark mode classes:

Element Light Dark
Header bar bg-white/95 border-secondary-100 bg-secondary-900/95 border-secondary-800
Active nav link text-primary bg-primary-50 text-primary-400 bg-primary-900/30
Inactive nav link hover hover:bg-secondary-50 dark:hover:bg-secondary-800
Mobile panel bg-white bg-secondary-900
Mobile nav items same pattern as desktop same dark variants

File: src/components/Footer.astro

Always dark (bg-secondary-900) — no light/dark switching needed as the footer is intentionally dark in both modes.


LazyImage

File: src/components/LazyImage.astro

Lightweight image wrapper with native lazy loading and fade-in animation.

<LazyImage
  src="/images/hero.jpg"
  alt="Team working"
  width={1200}
  height={630}
  loading="eager"
  fetchpriority="high"
/>
Prop Default Notes
loading 'lazy' Use 'eager' for above-the-fold images
fetchpriority 'auto' Use 'high' for LCP images
placeholder var(--color-surface-alt) Adapts to theme via CSS custom property

The placeholder color uses --color-surface-alt from global.css, which is #f1f5f9 in light mode and #1e293b in dark mode.


Global CSS Component Classes

Classes defined in src/styles/global.css under @layer components. All support dark mode via dark: variants.

Buttons

<button class="btn-primary">Primary Action</button>
<button class="btn-primary-lg">Large CTA</button>
<button class="btn-secondary">Secondary</button>
<button class="btn-accent">Accent</button>
<button class="btn-ghost">Ghost (for dark sections)</button>
<button class="btn-inverse-lg">Inverse Large (for dark sections)</button>
Class Theme behavior
btn-primary Cyan background — same in both modes (brand color)
btn-secondary border-secondary in light / border-secondary-400 text-secondary-300 in dark
btn-ghost bg-white/5 — designed for dark sections only

Badges (global classes)

<span class="badge-primary">Label</span>
<span class="badge-accent">Label</span>
<span class="badge-secondary">Label</span>
<span class="badge-primary-dark">Label</span>

Cards (global classes)

<div class="card">...</div>
<div class="card-hover">...</div>
<div class="card-service">...</div>
<div class="card-surface">...</div>

Forms

<label class="form-label">Email</label>
<input class="form-input" type="email" />
<p class="form-error">Required field</p>
Class Dark mode
form-input bg-secondary-800 border-secondary-600 text-secondary-100
form-label text-secondary-300
form-error text-red-400

Section Typography

<h2 class="section-title">Heading</h2>
<p class="section-description">Supporting text</p>

<!-- On dark gradient sections -->
<h2 class="section-title-inverse">Heading</h2>
<p class="section-description-inverse">Supporting text</p>

Design Tokens Quick Reference

Defined in src/styles/design-tokens.css and aliased in global.css.

Token Light value Dark value
--color-surface #f8fafc #0f172a
--color-surface-alt #f1f5f9 #1e293b
--color-border #e2e8f0 #334155
--color-text-primary #1e293b #f1f5f9
--color-text-secondary #475569 #cbd5e1
--color-text-muted #94a3b8 #94a3b8
--color-primary #0891b2 (cyan-600) #22d3ee (cyan-400)
--color-accent #f59e0b (amber-500) #fbbf24 (amber-400)

Adding a New Component

  1. Use dark: prefixed Tailwind classes for all color utilities
  2. For surface backgrounds: bg-white dark:bg-secondary-800 or bg-secondary-50 dark:bg-secondary-800
  3. For borders: border-secondary-100 dark:border-secondary-700
  4. For text: text-secondary-900 dark:text-secondary-50 (headings), text-secondary-600 dark:text-secondary-400 (body)
  5. Do NOT use html.dark CSS overrides — prefer Tailwind dark: variants for colocation
  6. Use CSS custom properties (var(--color-surface)) only when Tailwind classes won't work (e.g. dynamic inline styles)