| name | web-components |
| description | Use when building or restyling the strike-cli-web marketing site — page sections, UI primitives, design tokens, motion, demos, install CTA, or layout work under `src/`. Covers the component catalog, `src/index.css` `@theme` tokens, and composition in `src/App.tsx`. Do not use for the strike-cli Go/TUI product codebase. |
Web components (strike-cli-web)
Marketing and information site for strike-cli — “agentic coding in your terminal.” Live: strike.jonathanung.ca.
Stack: React 19 + Vite 7 + TypeScript 5.9 + Tailwind CSS v4 + framer-motion + lucide-react.
Composition lives in src/App.tsx (react-router) + SiteLayout:
SiteLayout(BackgroundEffects, Header, Outlet, Footer)
HomePage → Hero, HappyPath, Quickstart, Demos, Features, …
Docs / Changelog / 404 pages share the same tokens + ui kit
Design tokens live in src/index.css under @theme, aligned with strike-cli TUI theme.Default() dark roles. Prefer Tailwind theme classes (bg-bg, text-accent, border-border-muted, font-mono, …) over raw hex. Dark is default (color-scheme: dark). Prefer solid surfaces over heavy glows/borders.
Boundaries
- This repo only — marketing/info website. Do not implement the Go CLI, Bubble Tea TUI, or
internal/* packages here.
- CLI/TUI terms in copy only — product claims (install command, “TUI”, agent features) are marketing text, not implementation targets.
- Prefer existing primitives:
Section, Card, Button, CodeBlock, INSTALL_COMMAND from InstallCommand.tsx, copyToClipboard from src/lib/copy.ts.
- Theme tokens, not raw hex — extend
@theme in src/index.css when a new color/font is needed; do not scatter #b39dff in components.
- Motion: honor
useReducedMotion() from framer-motion; CSS already disables .animate-orb / .animate-curve-dash under prefers-reduced-motion.
- Router —
react-router-dom for /, /docs, /docs/:slug, /changelog; homepage section ids still use header hash links (scroll-mt-20 via Section).
- Static assets under
public/ (e.g. public/demos/*.gif); reference as /demos/....
- nginx / Docker / CI — only edit when the issue is about deploy,
/install proxy, or infra. Otherwise leave them alone.
Component catalog
| Piece | Path | Role |
|---|
| App | src/App.tsx | Router + lazy docs/changelog routes |
| SiteLayout | src/components/SiteLayout.tsx | Shared chrome: effects, header, outlet, footer |
| BackgroundEffects | src/components/BackgroundEffects.tsx | Ambient orbs / grid / decorative motion behind content |
| Header | src/components/Header.tsx | Sticky nav, section anchors, branding |
| Hero | src/components/Hero.tsx | Above-the-fold headline, value prop, primary CTA |
| HeroCarousel | src/components/HeroCarousel.tsx | TUI-chrome frame + product still carousel |
| InstallCommand | src/components/InstallCommand.tsx | Copyable install CTA; exports INSTALL_COMMAND |
| HappyPath | src/components/HappyPath.tsx | Animated install → launch → upgrade walkthrough; imports INSTALL_COMMAND |
| Demos | src/components/Demos.tsx | Demo media (data-demo-slot); wire public/demos/ here |
| Features | src/components/Features.tsx | Feature grid / product highlights |
| ComingSoon | src/components/ComingSoon.tsx | Roadmap / upcoming items |
| Footer | src/components/Footer.tsx | Trust strip, footer links and credits |
| Section | src/components/ui/Section.tsx | Page section shell: padding, max-width, optional id + scroll-mt-20 |
| Card | src/components/ui/Card.tsx | Solid surface panel (homepage + docs) |
| Button | src/components/ui/Button.tsx | Primary / secondary / ghost / soft CTAs (button or ) |
Section API
Section({ id?, children, className?, narrow? })
- Default content width:
max-w-6xl
narrow: max-w-3xl
- When
id is set: scroll-mt-20 for sticky-header anchors
Card API
Card({ children, className?, elevated?, interactive?, as? })
Solid bg-surface (or elevated) + border-border-muted. Prefer over ad-hoc rounded-2xl glass cards.
Button API
Button({ variant?: 'primary' | 'secondary' | 'ghost' | 'soft', to?, children, ... })
to renders a react-router Link; otherwise a <button>.
CodeBlock API
CodeBlock({ children, className?, label?, action? })
Solid terminal chrome (bg-terminal-bg, muted border, accent status dot + label; optional action for copy controls).
Install command (single source)
export const INSTALL_COMMAND =
'curl -fsSL https://strike.jonathanung.ca/install | bash'
HappyPath and any other surface that shows the install string must import INSTALL_COMMAND — do not duplicate the curl string.
Design tokens
From src/index.css @theme (aligned with TUI theme.Default() dark):
| Token | Value | Typical Tailwind |
|---|
--color-bg | #1c1b22 | bg-bg |
--color-bg-elevated | #21202a | bg-bg-elevated |
--color-surface | #252430 | bg-surface |
--color-surface-focus | #2f2c3c | bg-surface-focus |
--color-border | #4a4858 | border-border |
--color-border-muted | #323040 | border-border-muted |
--color-text | #eceaf4 | text-text |
--color-text-muted | #a09eb0 | text-text-muted |
--color-accent | #b39dff | text-accent / bg-accent |
--color-accent-soft | #2f2c3c | bg-accent-soft |
--color-accent-glow | #6d43d6 | soft ambient only |
--color-sky | #5cd0e8 | text-sky (AccentAlt) |
--color-bolt | #f5c451 | text-bolt (Warning) |
--color-success | #5edb92 | text-success (copy OK) |
--color-danger | #ff8087 |
Utility classes (@layer utilities)
| Class | Purpose |
|---|
.bg-grid | Faded grid background with radial mask |
.animate-orb | Ambient orb drift (--orb-duration, default 22s) |
.animate-curve-dash | SVG stroke dash animation (--curve-duration, default 50s) |
.text-gradient-accent | Text gradient: text → accent → sky |
.surface-solid / .surface-elevated / .surface-terminal | Solid cockpit fills |
Extending tokens
- Add or change values only in
src/index.css @theme (or shared utilities there).
- Use the new token via Tailwind class names generated from the theme.
- Keep contrast readable on dark
bg / surface; accent is violet — sky/bolt/success are accents, not body text defaults.
- Do not introduce a second design system or CSS-in-JS theme. Prefer solid surfaces over decorative glow borders.
Recipes
New page section
- Create
src/components/MySection.tsx.
- Wrap content in
<Section id="my-section" className="…">.
- Import and place it in
src/App.tsx in the intended order inside <main>.
- Add a Header nav link to
#my-section if it should be reachable from the sticky nav.
- Match existing spacing rhythm (
pb-20 sm:pb-28, etc.) and typography patterns from neighboring sections.
Reuse install command
import { INSTALL_COMMAND } from './InstallCommand'
import { InstallCommand } from './InstallCommand'
Never hardcode a second curl URL.
Code / terminal snippet
import { CodeBlock } from './ui/CodeBlock'
<CodeBlock label="terminal">
{`strike --continue`}
</CodeBlock>
Wire a demo GIF
- Drop the file in
public/demos/ (e.g. launch.gif).
- In
Demos.tsx, set img: '/demos/launch.gif' (or replace the placeholder with <img src="..." alt="..." className="h-full w-full object-cover" />).
- Keep
data-demo-slot attributes for findability.
- Optionally surface the same asset in
HeroCarousel if the hero should showcase it.
Icons
import { Copy, Check, Github } from 'lucide-react'
Use lucide-react consistently; mark decorative icons aria-hidden and put accessible names on controls (aria-label on icon-only buttons/links).
Touch / focus patterns
- Interactive controls: prefer
min-h-11 (or equivalent) for touch targets.
- Focus:
focus-visible:ring-2 focus-visible:ring-accent with appropriate ring-offset-* against the local background (bg, terminal-bg, …).
- Global
:focus-visible outline is already set in index.css; do not remove it.
- Copy feedback: use
aria-live="polite" for status text (see InstallCommand).
Motion
import { motion, useReducedMotion } from 'framer-motion'
const reduceMotion = useReducedMotion()
Extending and verification
- New shared UI chrome → prefer
src/components/ui/ and document it in this catalog in the same change.
- New colors/fonts/utilities →
src/index.css only.
- After UI work, verify with
test-and-validate:
npm run build
npm run preview
Docker / /install smoke only when infra or install proxy is in scope (see test-and-validate).
Do not
- Implement or edit the strike-cli Go/TUI product in this repo.
- Duplicate
INSTALL_COMMAND string literals across files.
- Use raw hex colors when a
@theme token exists.
- Add react-router or multi-page routing without an explicit product decision.
- Ignore
prefers-reduced-motion / useReducedMotion.
- Edit
nginx.conf, Dockerfile, or .github/workflows/ci-cd.yml for pure visual polish.
- Leave broken TypeScript —
npm run build runs tsc -b && vite build.