plans
2026-05-06
2026 05 06 Design System

Design System Showcase Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Create /design-system page showcasing Premium UI (Aurora) design system with colors, typography, spacing, animation, and all UI components.

Architecture: Single-page client component at apps/frontend/app/[locale]/design-system/page.tsx. Sticky navigation with anchor links, scrollable sections. Aurora background for visual consistency. No MONO references.

Tech Stack: Next.js 16 (App Router), Tailwind CSS v4, Radix UI shadcn/ui components, tailwindcss-animate.


File Structure

apps/frontend/app/[locale]/design-system/
└── page.tsx                    # Main design system page (client component)

Helper components (optional, can inline for simplicity):

  • Section wrapper with anchor ID and title
  • Component showcase card with label and code snippet
  • Color swatch component

Tasks

Task 1: Create Design System Page

Files:

  • Create: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Create the design-system directory and page file

// apps/frontend/app/[locale]/design-system/page.tsx
/**
 * Design System Showcase — Premium UI (Aurora)
 * Route: /en/design-system and /vi/design-system
 */
"use client";
 
import { AuroraBackground } from "~/components/ui/aurora-background";
 
export default function DesignSystemPage() {
  return (
    <div className="min-h-screen bg-background">
      <AuroraBackground />
      {/* Content will be added in subsequent steps */}
    </div>
  );
}
  • Step 2: Add basic page structure with navigation
"use client";
 
import { useState, useEffect } from "react";
import { AuroraBackground } from "~/components/ui/aurora-background";
import { cn } from "~/lib/utils";
 
const sections = [
  { id: "colors", label: "Colors" },
  { id: "typography", label: "Typography" },
  { id: "spacing", label: "Spacing & Radius" },
  { id: "animation", label: "Animation" },
  { id: "components", label: "Components" },
  { id: "icons", label: "Icons" },
] as const;
 
export default function DesignSystemPage() {
  const [activeSection, setActiveSection] = useState<string>("colors");
 
  return (
    <div className="min-h-screen bg-background text-foreground">
      <AuroraBackground />
 
      {/* Sticky Navigation */}
      <nav className="sticky top-0 z-50 bg-background/80 backdrop-blur-md border-b border-border">
        <div className="max-w-5xl mx-auto px-4">
          <div className="flex items-center gap-1 overflow-x-auto py-3">
            {sections.map((section) => (
              <a
                key={section.id}
                href={`#${section.id}`}
                className={cn(
                  "px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap border-b-2",
                  activeSection === section.id
                    ? "text-gold border-gold"
                    : "text-muted-foreground border-transparent hover:text-foreground",
                )}
              >
                {section.label}
              </a>
            ))}
          </div>
        </div>
      </nav>
 
      {/* Main Content */}
      <main className="max-w-5xl mx-auto px-4 py-12 space-y-16">
        {/* Sections will be added in Tasks 2-7 */}
      </main>
    </div>
  );
}
  • Step 3: Commit
git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): scaffold design system page with navigation"

Task 2: Add Colors Section

Files:

  • Modify: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Add color data and section component

Add this after the imports:

const colors = [
  {
    name: "Gold",
    token: "--color-gold",
    hex: "#c5a059",
    usage: "Brand accent",
  },
  {
    name: "Gold Light",
    token: "--color-gold-light",
    hex: "#dec89e",
    usage: "Gold hover/highlight",
  },
  {
    name: "Background",
    token: "--color-background",
    hex: "#0a0a0f",
    usage: "Deep void",
  },
  {
    name: "Foreground",
    token: "--color-foreground",
    hex: "#ededed",
    usage: "Body text",
  },
  {
    name: "Muted Foreground",
    token: "--color-muted-foreground",
    hex: "#8b8b9b",
    usage: "Secondary text",
  },
  {
    name: "Surface",
    token: "--color-surface",
    hex: "#1a1a1f",
    usage: "Card surfaces",
  },
  {
    name: "Border",
    token: "--color-border",
    hex: "#2a2a35",
    usage: "Subtle borders",
  },
  {
    name: "Primary",
    token: "--color-primary",
    hex: "#ffd933",
    usage: "Interactive gold",
  },
  {
    name: "Destructive",
    token: "--color-destructive",
    hex: "#ef4444",
    usage: "Error/danger",
  },
] as const;
  • Step 2: Add Colors section to the page

Add this section component inside <main>:

<section id="colors" className="scroll-mt-20">
  <h2 className="font-display text-3xl text-gold mb-8">Colors</h2>
  <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
    {colors.map((color) => (
      <div
        key={color.token}
        className="border border-border rounded-lg overflow-hidden"
      >
        <div
          className="h-24 border-b border-border"
          style={{ backgroundColor: color.hex }}
        />
        <div className="p-3 space-y-1">
          <p className="font-medium text-sm">{color.name}</p>
          <p className="font-mono text-xs text-muted-foreground">{color.hex}</p>
          <p className="text-xs text-muted-foreground">{color.usage}</p>
        </div>
      </div>
    ))}
  </div>
</section>
  • Step 3: Commit
git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): add colors section with swatches"

Task 3: Add Typography Section

Files:

  • Modify: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Add typography data

const fonts = [
  {
    name: "Decophile",
    token: "--font-display",
    usage: "Headings, display text",
    sample: "The Magic Begins",
  },
  {
    name: "Mulish",
    token: "--font-sans",
    usage: "Body text",
    sample: "Experience the magic of Vietnamese theater",
  },
  {
    name: "Philosopher",
    token: "--font-serif",
    usage: "Numbers, elegant text",
    sample: "0123456789",
  },
  {
    name: "Noto Sans",
    token: "--font-noto-sans",
    usage: "Current body font",
    sample: "Welcome to House of Legends",
  },
] as const;
 
const typeScale = [
  { name: "caption", size: "12px", className: "text-xs" },
  { name: "body-sm", size: "14px", className: "text-sm" },
  { name: "body", size: "16px", className: "text-base" },
  { name: "subheading", size: "18px", className: "text-lg" },
  { name: "heading", size: "25px", className: "text-2xl" },
  { name: "heading-lg", size: "32px", className: "text-3xl" },
  { name: "display-sm", size: "40px", className: "text-4xl" },
  { name: "display", size: "48-64px", className: "text-5xl md:text-6xl" },
] as const;
  • Step 2: Add Typography section
<section id="typography" className="scroll-mt-20">
  <h2 className="font-display text-3xl text-gold mb-8">Typography</h2>
 
  {/* Font Families */}
  <div className="mb-8">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Font Families
    </h3>
    <div className="space-y-4">
      {fonts.map((font) => (
        <div key={font.name} className="border border-border rounded-lg p-4">
          <div className="flex items-center justify-between mb-2">
            <span className="font-medium">{font.name}</span>
            <code className="text-xs text-muted-foreground bg-surface px-2 py-1 rounded">
              {font.token}
            </code>
          </div>
          <p className="text-sm text-muted-foreground mb-3">{font.usage}</p>
          <p
            className={
              font.name === "Decophile"
                ? "font-display text-2xl"
                : font.name === "Philosopher"
                  ? "font-serif text-2xl"
                  : "text-2xl"
            }
          >
            {font.sample}
          </p>
        </div>
      ))}
    </div>
  </div>
 
  {/* Type Scale */}
  <div>
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Type Scale
    </h3>
    <div className="space-y-3 border border-border rounded-lg p-4">
      {typeScale.map((scale) => (
        <div key={scale.name} className="flex items-center gap-4">
          <code className="text-xs text-muted-foreground w-24 shrink-0">
            {scale.name}
          </code>
          <code className="text-xs text-muted-foreground w-20 shrink-0">
            {scale.size}
          </code>
          <p className={scale.className}>{scale.name} text sample</p>
        </div>
      ))}
    </div>
  </div>
</section>
  • Step 3: Commit
git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): add typography section with fonts and scale"

Task 4: Add Spacing & Radius Section

Files:

  • Modify: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Add spacing and radius data

const spacingScale = [4, 8, 12, 16, 20, 24, 32, 40, 48, 64] as const;
 
const radiusScale = [
  { name: "none", value: "0px" },
  { name: "xs", value: "0.125rem" },
  { name: "sm", value: "0.25rem" },
  { name: "md", value: "0.375rem" },
  { name: "lg", value: "0.5rem" },
  { name: "xl", value: "0.75rem" },
  { name: "2xl", value: "1rem" },
  { name: "3xl", value: "1.5rem" },
] as const;
  • Step 2: Add Spacing & Radius section
<section id="spacing" className="scroll-mt-20">
  <h2 className="font-display text-3xl text-gold mb-8">Spacing & Radius</h2>
 
  {/* Spacing Scale */}
  <div className="mb-8">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Spacing (4px base grid)
    </h3>
    <div className="space-y-2">
      {spacingScale.map((value) => (
        <div key={value} className="flex items-center gap-4">
          <code className="text-xs text-muted-foreground w-16">{value}px</code>
          <div
            className="h-4 bg-gold/30 border border-gold rounded-sm"
            style={{ width: `${value * 2}px`, minWidth: `${value}px` }}
          />
          <code className="text-xs text-muted-foreground">gap-{value / 4}</code>
        </div>
      ))}
    </div>
  </div>
 
  {/* Border Radius */}
  <div>
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Border Radius
    </h3>
    <div className="flex flex-wrap gap-4">
      {radiusScale.map((radius) => (
        <div key={radius.name} className="text-center">
          <div
            className="w-16 h-16 bg-gold/20 border-2 border-gold mx-auto mb-2"
            style={{ borderRadius: radius.value }}
          />
          <code className="text-xs text-muted-foreground">{radius.name}</code>
          <p className="text-xs text-muted-foreground">{radius.value}</p>
        </div>
      ))}
    </div>
  </div>
</section>
  • Step 3: Commit
git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): add spacing and radius section"

Task 5: Add Animation Section

Files:

  • Modify: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Add animation data

const animations = [
  {
    name: "animate-fade-in",
    description: "Opacity 0→1",
    className: "animate-fade-in",
  },
  {
    name: "animate-slide-in-from-bottom-4",
    description: "Translate Y -16px → 0",
    className: "animate-slide-in-from-bottom-4",
  },
  {
    name: "animate-slide-in-from-top-8",
    description: "Translate Y 32px → 0",
    className: "animate-slide-in-from-top-8",
  },
  {
    name: "animate-slide-in-from-left-4",
    description: "Translate X -16px → 0",
    className: "animate-slide-in-from-left-4",
  },
  {
    name: "animate-slide-in-from-right-4",
    description: "Translate X 16px → 0",
    className: "animate-slide-in-from-right-4",
  },
  {
    name: "animate-zoom-in-95",
    description: "Scale 0.95 → 1",
    className: "animate-zoom-in-95",
  },
] as const;
 
const durations = [75, 100, 150, 200, 300, 500, 700, 1000] as const;
 
const delays = [0, 75, 100, 150, 200, 300, 500, 700, 1000] as const;
  • Step 2: Add Animation section
<section id="animation" className="scroll-mt-20">
  <h2 className="font-display text-3xl text-gold mb-8">Animation</h2>
 
  {/* Entrance Animations */}
  <div className="mb-8">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Entrance Animations (tailwindcss-animate)
    </h3>
    <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
      {animations.map((anim) => (
        <div key={anim.name} className="border border-border rounded-lg p-4">
          <div className="h-24 bg-surface rounded-lg mb-3 flex items-center justify-center overflow-hidden">
            <div
              className={cn(
                "w-12 h-12 bg-gold rounded-lg",
                anim.className,
                "animate-duration-700",
              )}
            />
          </div>
          <p className="font-medium text-sm mb-1">{anim.name}</p>
          <p className="text-xs text-muted-foreground">{anim.description}</p>
        </div>
      ))}
    </div>
  </div>
 
  {/* Duration Classes */}
  <div className="mb-8">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Duration Classes
    </h3>
    <div className="flex flex-wrap gap-2">
      {durations.map((ms) => (
        <code
          key={ms}
          className="text-xs bg-surface px-3 py-2 rounded border border-border"
        >
          animate-duration-{ms}
          <span className="text-muted-foreground ml-2">{ms}ms</span>
        </code>
      ))}
    </div>
  </div>
 
  {/* Delay Classes */}
  <div>
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Delay Classes
    </h3>
    <div className="flex flex-wrap gap-2">
      {delays.map((ms) => (
        <code
          key={ms}
          className="text-xs bg-surface px-3 py-2 rounded border border-border"
        >
          animation-delay-{ms}
          <span className="text-muted-foreground ml-2">{ms}ms</span>
        </code>
      ))}
    </div>
  </div>
</section>
  • Step 3: Commit
git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): add animation section with showcases"

Task 6: Add Components Section

Files:

  • Modify: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Import UI components

Update the imports at the top:

import { AuroraBackground } from "~/components/ui/aurora-background";
import { Button, buttonVariants } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Checkbox } from "~/components/ui/checkbox";
import { RadioGroup, RadioGroupItem } from "~/components/ui/radio-group";
import { Switch } from "~/components/ui/switch";
import { Slider } from "~/components/ui/slider";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "~/components/ui/accordion";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "~/components/ui/tooltip";
import { Progress } from "~/components/ui/progress";
import { Skeleton } from "~/components/ui/skeleton";
import { Badge } from "~/components/ui/badge";
import { Separator } from "~/components/ui/separator";
import { Toggle } from "~/components/ui/toggle";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "~/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "~/components/ui/dialog";
import { Label } from "~/components/ui/label";
  • Step 2: Add component showcase sub-sections
<section id="components" className="scroll-mt-20">
  <h2 className="font-display text-3xl text-gold mb-8">Components</h2>
 
  {/* Buttons */}
  <div className="mb-12">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">Buttons</h3>
    <div className="border border-border rounded-lg p-6 space-y-6">
      {/* Variants */}
      <div>
        <p className="text-sm text-muted-foreground mb-3">Variants</p>
        <div className="flex flex-wrap gap-3">
          <Button variant="primary">Primary</Button>
          <Button variant="gold">Gold</Button>
          <Button variant="outline">Outline</Button>
          <Button variant="outlineGold">Outline Gold</Button>
          <Button variant="ghost">Ghost</Button>
        </div>
      </div>
      {/* Sizes */}
      <div>
        <p className="text-sm text-muted-foreground mb-3">Sizes</p>
        <div className="flex flex-wrap items-center gap-3">
          <Button size="sm">Small</Button>
          <Button size="md">Medium</Button>
          <Button size="lg">Large</Button>
        </div>
      </div>
      {/* States */}
      <div>
        <p className="text-sm text-muted-foreground mb-3">States</p>
        <div className="flex flex-wrap gap-3">
          <Button>Default</Button>
          <Button disabled>Disabled</Button>
          <Button className="opacity-50 cursor-not-allowed">Loading</Button>
        </div>
      </div>
    </div>
  </div>
 
  {/* Form Controls */}
  <div className="mb-12">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Form Controls
    </h3>
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6 border border-border rounded-lg p-6">
      {/* Input */}
      <Input label="Email" type="email" placeholder="your@email.com" />
      <Input
        label="With Error"
        error="This field is required"
        placeholder="Type something"
      />
      <Input label="Disabled" disabled defaultValue="Cannot edit" />
      <div>
        <Label>Checkbox</Label>
        <div className="flex items-center gap-3 mt-2">
          <Checkbox id="ds-check-1" />
          <Label htmlFor="ds-check-1" className="text-sm font-normal">
            Accept terms and conditions
          </Label>
        </div>
      </div>
      <div>
        <Label>Radio Group</Label>
        <RadioGroup defaultValue="option-1" className="mt-2">
          <div className="flex items-center gap-2">
            <RadioGroupItem value="option-1" id="ds-rad-1" />
            <Label htmlFor="ds-rad-1" className="text-sm font-normal">
              Option 1
            </Label>
          </div>
          <div className="flex items-center gap-2">
            <RadioGroupItem value="option-2" id="ds-rad-2" />
            <Label htmlFor="ds-rad-2" className="text-sm font-normal">
              Option 2
            </Label>
          </div>
        </RadioGroup>
      </div>
      <div>
        <Label>Switch</Label>
        <div className="flex items-center gap-3 mt-2">
          <Switch id="ds-switch-1" />
          <Label htmlFor="ds-switch-1" className="text-sm font-normal">
            Enable notifications
          </Label>
        </div>
      </div>
      <div>
        <Label>Toggle</Label>
        <div className="flex items-center gap-3 mt-2">
          <Toggle pressed aria-label="Toggle bold">
            <strong>B</strong>
          </Toggle>
          <Toggle aria-label="Toggle italic">
            <em>I</em>
          </Toggle>
        </div>
      </div>
      <div>
        <Label>Slider</Label>
        <Slider defaultValue={[50]} max={100} step={1} className="mt-6" />
      </div>
      <div>
        <Label>Select</Label>
        <Select>
          <SelectTrigger className="mt-2">
            <SelectValue placeholder="Select option" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="opt-1">Option 1</SelectItem>
            <SelectItem value="opt-2">Option 2</SelectItem>
            <SelectItem value="opt-3">Option 3</SelectItem>
          </SelectContent>
        </Select>
      </div>
    </div>
  </div>
 
  {/* Navigation */}
  <div className="mb-12">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Navigation
    </h3>
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
      {/* Tabs */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Tabs</p>
        <Tabs defaultValue="tab-1">
          <TabsList>
            <TabsTrigger value="tab-1">Tab 1</TabsTrigger>
            <TabsTrigger value="tab-2">Tab 2</TabsTrigger>
            <TabsTrigger value="tab-3">Tab 3</TabsTrigger>
          </TabsList>
          <TabsContent value="tab-1">Tab 1 content</TabsContent>
          <TabsContent value="tab-2">Tab 2 content</TabsContent>
          <TabsContent value="tab-3">Tab 3 content</TabsContent>
        </Tabs>
      </div>
      {/* Accordion */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Accordion</p>
        <Accordion type="single" collapsible>
          <AccordionItem value="item-1">
            <AccordionTrigger>Section 1</AccordionTrigger>
            <AccordionContent>Content for section 1</AccordionContent>
          </AccordionItem>
          <AccordionItem value="item-2">
            <AccordionTrigger>Section 2</AccordionTrigger>
            <AccordionContent>Content for section 2</AccordionContent>
          </AccordionItem>
        </Accordion>
      </div>
    </div>
  </div>
 
  {/* Feedback */}
  <div className="mb-12">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">Feedback</h3>
    <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
      {/* Tooltip */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Tooltip</p>
        <TooltipProvider>
          <Tooltip>
            <TooltipTrigger asChild>
              <Button variant="ghost" size="sm">
                Hover
              </Button>
            </TooltipTrigger>
            <TooltipContent>
              <p>This is a tooltip</p>
            </TooltipContent>
          </Tooltip>
        </TooltipProvider>
      </div>
      {/* Progress */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Progress</p>
        <Progress value={65} />
      </div>
      {/* Skeleton */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Skeleton</p>
        <Skeleton className="h-4 w-full" />
        <Skeleton className="h-4 w-3/4 mt-2" />
      </div>
      {/* Badge */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Badge</p>
        <Badge variant="default">Badge</Badge>
      </div>
    </div>
  </div>
 
  {/* Containers */}
  <div className="mb-12">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Containers
    </h3>
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
      {/* Dialog */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Dialog</p>
        <Dialog>
          <DialogTrigger asChild>
            <Button variant="outline" size="sm">
              Open Dialog
            </Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Dialog Title</DialogTitle>
            </DialogHeader>
            <p className="text-sm text-muted-foreground">
              This is the dialog content.
            </p>
          </DialogContent>
        </Dialog>
      </div>
      {/* Separator */}
      <div className="border border-border rounded-lg p-4">
        <p className="text-sm text-muted-foreground mb-3">Separator</p>
        <div className="space-y-2">
          <p className="text-sm">Above separator</p>
          <Separator />
          <p className="text-sm">Below separator</p>
        </div>
      </div>
    </div>
  </div>
</section>
  • Step 3: Commit
git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): add components section with all UI showcases"

Task 7: Add Icons Section

Files:

  • Modify: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Add IconSymbol and icon data

import { IconSymbol } from "~/components/ui/icon-symbol";
 
const icons = [
  "house",
  "calendar",
  "ticket",
  "utensils",
  "wine",
  "music",
  "users",
  "clock",
  "map-pin",
  "phone",
  "mail",
  "chevron-right",
  "chevron-left",
  "x",
  "check",
  "star",
] as const;
  • Step 2: Add Icons section
<section id="icons" className="scroll-mt-20">
  <h2 className="font-display text-3xl text-gold mb-8">Icons</h2>
 
  {/* IconSymbol Showcase */}
  <div className="mb-8">
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      IconSymbol Component
    </h3>
    <div className="border border-border rounded-lg p-6">
      <p className="text-sm text-muted-foreground mb-4">
        SF Symbols on iOS, Material Icons on Android. Mapped via IconSymbol
        component.
      </p>
      <div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-4">
        {icons.map((name) => (
          <div key={name} className="text-center">
            <IconSymbol
              name={name}
              size={24}
              className="mx-auto mb-1 text-gold"
            />
            <code className="text-xs text-muted-foreground">{name}</code>
          </div>
        ))}
      </div>
    </div>
  </div>
 
  {/* Size Variations */}
  <div>
    <h3 className="text-lg font-medium mb-4 text-muted-foreground">
      Size Variations
    </h3>
    <div className="flex items-end gap-6 border border-border rounded-lg p-6">
      {[16, 20, 24, 32, 48].map((size) => (
        <div key={size} className="text-center">
          <IconSymbol
            name="star"
            size={size}
            className="mx-auto mb-2 text-gold"
          />
          <code className="text-xs text-muted-foreground">{size}px</code>
        </div>
      ))}
    </div>
  </div>
</section>
  • Step 3: Commit
git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): add icons section with IconSymbol showcase"

Task 8: Polish and Test

Files:

  • Modify: apps/frontend/app/[locale]/design-system/page.tsx

  • Step 1: Add smooth scroll behavior and active section tracking

useEffect(() => {
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          setActiveSection(entry.target.id);
        }
      });
    },
    { rootMargin: "-20% 0px -80% 0px" },
  );
 
  sections.forEach((section) => {
    const element = document.getElementById(section.id);
    if (element) observer.observe(element);
  });
 
  return () => observer.disconnect();
}, []);
  • Step 2: Add CSS for smooth scrolling

Add to the page or ensure Tailwind's scroll-smooth is active:

// Add to the body/html classes in RootLayout or in the page:
<div className="min-h-screen bg-background text-foreground scroll-smooth">
  • Step 3: Verify the page compiles and renders

Run: cd apps/frontend && npm run build 2>&1 | head -100 Expected: Build succeeds with no errors

  • Step 4: Verify page accessibility

Check that:

  • All sections have unique IDs

  • Navigation links point to valid anchors

  • Components have proper labels

  • Step 5: Final commit

git add apps/frontend/app/\[locale\]/design-system/page.tsx
git commit -m "feat(design-system): polish smooth scroll and active section tracking"

Verification Checklist

  • Page accessible at /en/design-system and /vi/design-system
  • Sticky navigation scrolls smoothly to sections
  • All color tokens visible with correct hex values
  • Typography samples show actual font rendering
  • Animation examples are animated (not static)
  • Each component shows multiple variants/states
  • No MONO references anywhere on the page
  • Responsive: works on mobile and desktop
  • Aurora background consistent with public pages