Files
roa2web-service-auto/docs/CSS_PATTERNS.md
Claude Agent fdec2ae81d feat(unified-mobile-material-design): Complete US-115 - Actualizare CSS_PATTERNS.md cu Mobile Material Design
Implemented by Ralph autonomous loop.
Iteration: 4

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-12 11:17:28 +00:00

26 KiB
Raw Permalink Blame History

ROA2WEB CSS Patterns Library

Version: 2.0.0 Last Updated: 2025-11-19 Status: Complete


Table of Contents

  1. Card Patterns
  2. Form Patterns
  3. Button Patterns
  4. Table Patterns
  5. Dashboard Patterns
  6. Interactive Patterns
  7. Layout Patterns
  8. Utility Classes
  9. Mobile Material Design
  10. Quick Reference

Overview

This document provides a comprehensive reference to all CSS patterns available in the ROA2WEB frontend application. All patterns are production-ready, tested, and follow our design system.

Key Principles

  • Use global patterns first - Check this library before writing custom CSS
  • Design tokens - Use CSS variables (var(--color-primary)) not hardcoded values
  • Responsive by default - All patterns work on mobile
  • Accessibility - WCAG 2.1 AA compliant
  • No duplication - Never recreate existing patterns

Card Patterns

Basic Card

Standard card with optional header, body, and footer sections.

<div class="card">
  <div class="card-header">
    <h3>Card Title</h3>
  </div>
  <div class="card-body">
    <p>Card content goes here</p>
  </div>
  <div class="card-footer">
    <button class="btn btn-primary">Action</button>
  </div>
</div>

Variants:

  • .card-compact - Reduced padding
  • .card-minimal - No border/shadow
  • .card-elevated - Higher shadow with hover lift
  • .card-hover - Hover effect with border color change

Use Cases:

  • Content containers
  • Form wrappers
  • Information blocks

Metric Card

Dashboard metric display with icon, value, and label.

<div class="metric-card card-hover">
  <div class="metric-header">
    <div class="metric-icon bg-primary-light text-primary">
      <i class="pi pi-chart-bar"></i>
    </div>
    <div class="metric-label">Total Sales</div>
  </div>
  <div class="metric-value">$125,430</div>
  <div class="trend trend-up">
    <i class="pi pi-arrow-up trend-icon"></i>
    +12.5% vs last month
  </div>
</div>

Structure:

  • .metric-card - Base container
  • .metric-header - Icon + label section
  • .metric-icon - 40x40px icon container
  • .metric-value - Large numeric display
  • .metric-label - Uppercase description

Modifiers:

  • .metric-value-lg - Larger font size (2.5rem)

Use Cases:

  • KPI displays
  • Financial metrics
  • Statistics cards

Stats Card

Centered statistics display for key metrics.

<div class="stats-card">
  <span class="stats-value">1,234</span>
  <span class="stats-label">Active Users</span>
  <span class="stats-change positive">
    <i class="pi pi-arrow-up"></i> +5.2%
  </span>
</div>

Variants:

  • .stats-card-mini - Compact size, left-aligned
  • .stats-card-large - Extra padding
  • .stats-value-large - Larger number display

Use Cases:

  • Dashboard summaries
  • Quick stats
  • Report headers

KPI Card

Horizontal card with icon and key performance indicator.

<div class="kpi-card">
  <div class="kpi-icon bg-primary">
    <i class="pi pi-dollar"></i>
  </div>
  <div class="kpi-content">
    <div class="kpi-value">$45,231</div>
    <div class="kpi-label">Monthly Revenue</div>
  </div>
</div>

Use Cases:

  • Performance indicators
  • Business metrics
  • Dashboard sidebar stats

Action Card

Interactive card that functions as a clickable button.

<div class="action-card">
  <div class="action-icon">
    <i class="pi pi-file-excel"></i>
  </div>
  <div class="action-title">Export Data</div>
  <div class="action-description">Download as Excel file</div>
</div>

Use Cases:

  • Quick actions
  • Navigation tiles
  • Feature shortcuts

Status Card

Card with colored left border indicating status.

<div class="status-card success">
  <strong>Success!</strong> Your payment was processed.
</div>

<div class="status-card error">
  <strong>Error:</strong> Payment failed, please try again.
</div>

Variants:

  • .success - Green border, success background
  • .warning - Yellow border, warning background
  • .error - Red border, error background
  • .info - Blue border, info background

Use Cases:

  • Alerts
  • Notifications
  • Status messages

Form Patterns

Standard Form

Complete form structure with validation.

<form @submit.prevent="handleSubmit" class="form">

  <!-- Single Field -->
  <div class="form-group">
    <label for="username" class="form-label required">Username</label>
    <input
      id="username"
      v-model="formData.username"
      type="text"
      class="form-input"
      :class="{ 'invalid': errors.username }"
      placeholder="Enter username"
    />
    <span v-if="errors.username" class="form-error">
      <i class="pi pi-exclamation-circle"></i>
      {{ errors.username }}
    </span>
    <span v-else class="form-help">
      Minimum 3 characters
    </span>
  </div>

  <!-- Horizontal Fields -->
  <div class="form-row">
    <div class="form-col">
      <div class="form-group">
        <label class="form-label">First Name</label>
        <input type="text" class="form-input" />
      </div>
    </div>
    <div class="form-col">
      <div class="form-group">
        <label class="form-label">Last Name</label>
        <input type="text" class="form-input" />
      </div>
    </div>
  </div>

  <!-- Actions -->
  <div class="form-actions">
    <button type="button" class="btn btn-secondary">Cancel</button>
    <button type="submit" class="btn btn-primary" :disabled="isSubmitting">
      <i v-if="isSubmitting" class="pi pi-spin pi-spinner"></i>
      Submit
    </button>
  </div>
</form>

Key Classes:

  • .form - Base form container
  • .form-group - Field wrapper
  • .form-row - Horizontal field container
  • .form-col - Column within row
  • .form-label - Label text
  • .form-label.required - Adds red asterisk
  • .form-input - Text input
  • .form-select - Select dropdown
  • .form-textarea - Multi-line text
  • .form-error - Error message (red)
  • .form-help - Help text (gray)
  • .form-actions - Button container

Validation States:

  • .valid - Green border with checkmark icon
  • .invalid - Red border with X icon

Input Sizes

<!-- Small -->
<input type="text" class="form-input form-input-sm" />

<!-- Default -->
<input type="text" class="form-input" />

<!-- Large -->
<input type="text" class="form-input form-input-lg" />

Input Group

Input with prefix/suffix addons.

<div class="input-group">
  <span class="input-group-addon">https://</span>
  <input type="text" class="form-input" placeholder="example.com" />
  <span class="input-group-addon">.com</span>
</div>

Search Form

Dedicated search input with icon.

<div class="search-form">
  <div class="search-input">
    <input type="search" class="form-input" placeholder="Search..." />
    <i class="pi pi-search search-icon"></i>
  </div>
  <button class="btn btn-primary">Search</button>
</div>

File Upload

Drag-and-drop file upload area.

<div class="file-upload">
  <input type="file" class="file-upload-input" />
  <label class="file-upload-label">
    <i class="pi pi-cloud-upload"></i>
    <span>Click to upload or drag and drop</span>
  </label>
</div>

Button Patterns

Button Variants

<!-- Primary (filled blue) -->
<button class="btn btn-primary">Primary</button>

<!-- Secondary (outlined gray) -->
<button class="btn btn-secondary">Secondary</button>

<!-- Outline (outlined blue) -->
<button class="btn btn-outline">Outline</button>

<!-- Ghost (transparent) -->
<button class="btn btn-ghost">Ghost</button>

<!-- Status variants -->
<button class="btn btn-success">Success</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-error">Danger</button>

Button Sizes

<button class="btn btn-xs btn-primary">Extra Small</button>
<button class="btn btn-sm btn-primary">Small</button>
<button class="btn btn-md btn-primary">Medium (Default)</button>
<button class="btn btn-lg btn-primary">Large</button>
<button class="btn btn-xl btn-primary">Extra Large</button>

Icon Buttons

<!-- Button with icon + text -->
<button class="btn btn-primary">
  <i class="pi pi-plus"></i>
  Add Item
</button>

<!-- Icon-only button -->
<button class="btn btn-icon btn-primary">
  <i class="pi pi-pencil"></i>
</button>

<!-- Circle icon button -->
<button class="btn btn-circle btn-primary">
  <i class="pi pi-search"></i>
</button>

Sizes:

  • .btn-icon-sm - 32x32px
  • .btn-icon - 40x40px
  • .btn-icon-lg - 48x48px

Button Groups

<div class="btn-group">
  <button class="btn btn-secondary">Left</button>
  <button class="btn btn-secondary">Middle</button>
  <button class="btn btn-secondary">Right</button>
</div>

Loading State

<button class="btn btn-primary btn-loading">
  Loading...
</button>

<!-- Or manually with spinner -->
<button class="btn btn-primary" disabled>
  <i class="pi pi-spin pi-spinner"></i>
  Processing...
</button>

Table Patterns

Note: Table styles are centralized in tables.css. Always use PrimeVue DataTable component with global styling.

Basic Table

<DataTable
  :value="data"
  class="p-datatable-sm"
  stripedRows
  :paginator="true"
>
  <Column field="name" header="Name" sortable></Column>
  <Column field="email" header="Email"></Column>
  <Column field="status" header="Status">
    <template #body="slotProps">
      <span :class="getStatusClass(slotProps.data.status)">
        {{ slotProps.data.status }}
      </span>
    </template>
  </Column>
</DataTable>

Global Row Classes (App.vue):

  • .bank-row - Blue background for bank rows
  • .cash-row - Green background for cash rows
  • .invoice-paid - Light green for paid invoices
  • .invoice-overdue - Light red for overdue invoices

⚠️ Important: Unified Table Column Structure

All tables in the application MUST follow this structure for consistency:

DO: One value per column

<!-- CORRECT: Separate columns for related data -->
<DataTable :value="data">
  <Column field="account" header="Account" sortable></Column>
  <Column field="debit" header="Debit" sortable>
    <template #body="slotProps">
      {{ formatCurrency(slotProps.data.debit) }}
    </template>
  </Column>
  <Column field="credit" header="Credit" sortable>
    <template #body="slotProps">
      {{ formatCurrency(slotProps.data.credit) }}
    </template>
  </Column>
</DataTable>

DON'T: Multiple values stacked vertically in single column

<!-- WRONG: Grouping debit/credit in one column -->
<Column header="Balance">
  <template #body="slotProps">
    <div class="balance-group">
      <div>D: {{ slotProps.data.debit }}</div>
      <div>C: {{ slotProps.data.credit }}</div>
    </div>
  </template>
</Column>

Rationale:

  • Maintains visual consistency across all views
  • Improves scannability and data comparison
  • Better for sorting and filtering
  • Follows established patterns (see InvoicesView, MaturityAndDetailsCard)

Table Filter and Action Buttons

Standard pattern: PrimeVue buttons with icon + label, separate row below filters

All filter-related buttons (clear filters, export, refresh) MUST be:

  • PrimeVue Button components (not HTML <button>)
  • Icon + label (both icon and text visible)
  • Separate row below filters (not on same row with inputs)
  • Standard PrimeVue styling (outlined buttons with contextual colors)
<div class="form">
  <div class="form-row">
    <!-- Filter inputs -->
    <div class="form-col">
      <div class="form-group">
        <label class="form-label">Filter Name</label>
        <InputText v-model="filter" placeholder="Filter..." class="w-full" />
      </div>
    </div>
    <!-- More filter inputs... -->
  </div>

  <!-- Action Buttons (separate row below filters!) -->
  <div class="filters-actions">
    <Button
      icon="pi pi-filter-slash"
      label="Resetează Filtre"
      class="p-button-outlined p-button-secondary"
      @click="clearFilters"
    />
    <Button
      icon="pi pi-file-excel"
      label="Export Excel"
      class="p-button-outlined p-button-success"
      @click="exportExcel"
      :disabled="!hasData"
    />
    <Button
      icon="pi pi-file-pdf"
      label="Export PDF"
      class="p-button-outlined p-button-danger"
      @click="exportPDF"
      :disabled="!hasData"
    />
    <Button
      icon="pi pi-refresh"
      label="Actualizează"
      :loading="isLoading"
      @click="refresh"
    />
  </div>
</div>

CSS Styles:

.filters-actions {
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
  padding-top: 1rem;
  border-top: 1px solid var(--surface-border);
}

/* Responsive */
@media (max-width: 768px) {
  .filters-actions {
    flex-direction: column;
  }
}

CRITICAL: Export ALL Data, Not Just Current Page

Export functions MUST fetch ALL data from the backend, not just the current page:

// ❌ WRONG: Only exports current page
const exportExcel = () => {
  const data = store.currentPageData; // Only current page!
  exportToExcel(data, 'filename');
};

// ✅ CORRECT: Exports ALL data
const exportExcel = async () => {
  // Fetch ALL data with large page_size or no pagination
  const params = {
    ...filters,
    page: 1,
    page_size: 999999 // Get all data
  };

  const response = await apiService.get('/endpoint', { params });
  const allData = response.data.items;

  exportToExcel(allData, 'filename');

  toast.add({
    summary: "Export reușit",
    detail: `${allData.length} înregistrări exportate`
  });
};

Use Cases:

  • Financial reports (invoices, trial balance, etc.)
  • Detailed data tables with multiple columns
  • Any table with filters and pagination

Dashboard Patterns

Page Header

Standard page title with subtitle.

<header class="page-header">
  <h1 class="page-title">
    <i class="pi pi-chart-line"></i>
    Dashboard
  </h1>
  <p class="page-subtitle">
    Financial overview for {{ companyName }}
  </p>
</header>

Section Header

Section title with actions.

<div class="section-header">
  <h2 class="section-title">Recent Transactions</h2>
  <div class="section-controls">
    <button class="btn btn-secondary btn-sm">Filter</button>
    <button class="btn btn-primary btn-sm">Export</button>
  </div>
</div>

Metrics Row

Responsive grid for metric cards.

<div class="metrics-row">
  <div class="metric-card">...</div>
  <div class="metric-card">...</div>
</div>

Responsive:

  • Desktop: 2 columns
  • Tablet/Mobile: 1 column

Breakdown Pattern

Collapsible data breakdown.

<div class="breakdown-section">
  <div class="breakdown-header" @click="toggleBreakdown">
    <div class="breakdown-header-left">
      <i class="pi pi-angle-right breakdown-toggle" :class="{ expanded: isExpanded }"></i>
      <span class="breakdown-label">Details</span>
    </div>
    <span class="breakdown-value">$10,500</span>
  </div>

  <div v-if="isExpanded" class="breakdown-subitems">
    <div class="breakdown-subitem">
      <span class="breakdown-sublabel">Item 1</span>
      <span class="breakdown-subvalue">$5,000</span>
    </div>
    <div class="breakdown-subitem">
      <span class="breakdown-sublabel">Item 2</span>
      <span class="breakdown-subvalue">$5,500</span>
    </div>
  </div>
</div>

Interactive Patterns

Loading Spinner

Animated loading indicator.

<!-- Default (40px) -->
<div class="loading-spinner"></div>

<!-- Small (24px) -->
<div class="loading-spinner loading-spinner-sm"></div>

<!-- Large (56px) -->
<div class="loading-spinner loading-spinner-lg"></div>

Trend Indicator

Shows increase/decrease with icon.

<!-- Positive trend -->
<div class="trend trend-up">
  <i class="pi pi-arrow-up trend-icon"></i>
  +12.5%
</div>

<!-- Negative trend -->
<div class="trend trend-down">
  <i class="pi pi-arrow-down trend-icon"></i>
  -3.2%
</div>

<!-- Neutral trend -->
<div class="trend trend-neutral">
  <i class="pi pi-minus trend-icon"></i>
  0.0%
</div>

Collapsible Section

Expandable/collapsible content.

<div class="collapsible-header" @click="toggle">
  <span>Section Title</span>
  <i class="pi pi-angle-right collapse-icon" :class="{ expanded: isOpen }"></i>
</div>
<div v-if="isOpen">
  Content goes here
</div>

Sparkline Chart

Mini line chart for trends.

<div class="metric-sparkline">
  <div class="sparkline-header">
    <span class="sparkline-title">Last 7 Days</span>
    <span class="sparkline-value">$12,345</span>
  </div>
  <div class="sparkline-container">
    <canvas ref="sparklineCanvas" class="sparkline-canvas"></canvas>
  </div>
</div>

Sizes:

  • Default: 60px height
  • .sparkline-chart-lg: 150px height

Layout Patterns

Container

Page-level content container.

<div class="container">
  <!-- Content -->
</div>

Variants:

  • .container-sm - Max-width 640px
  • .container-md - Max-width 768px
  • .container-lg - Max-width 1024px
  • .container-xl - Max-width 1280px
  • .container-full - Full width

Grid System

Responsive column layout.

<div class="grid grid-cols-3 gap-lg">
  <div class="col">Column 1</div>
  <div class="col">Column 2</div>
  <div class="col">Column 3</div>
</div>

Grid Columns:

  • .grid-cols-1 to .grid-cols-12
  • Responsive: .sm:grid-cols-2, .md:grid-cols-3, .lg:grid-cols-4

Utility Classes

Spacing

<!-- Margin -->
<div class="m-0">No margin</div>
<div class="m-sm">Small margin (0.5rem)</div>
<div class="m-md">Medium margin (1rem)</div>
<div class="m-lg">Large margin (1.5rem)</div>
<div class="m-xl">Extra large margin (2rem)</div>

<!-- Padding -->
<div class="p-0">No padding</div>
<div class="p-sm">Small padding</div>
<div class="p-md">Medium padding</div>
<div class="p-lg">Large padding</div>

<!-- Directional -->
<div class="mt-lg">Margin top</div>
<div class="mb-md">Margin bottom</div>
<div class="ml-sm">Margin left</div>
<div class="mr-xl">Margin right</div>
<div class="mx-auto">Horizontal center</div>
<div class="my-lg">Vertical margin</div>

Text Utilities

<!-- Sizes -->
<p class="text-xs">Extra small (0.75rem)</p>
<p class="text-sm">Small (0.875rem)</p>
<p class="text-base">Base (1rem)</p>
<p class="text-lg">Large (1.125rem)</p>
<p class="text-xl">Extra large (1.25rem)</p>
<p class="text-2xl">2X large (1.5rem)</p>
<p class="text-3xl">3X large (1.875rem)</p>
<p class="text-4xl">4X large (2.25rem)</p>

<!-- Alignment -->
<p class="text-left">Left aligned</p>
<p class="text-center">Center aligned</p>
<p class="text-right">Right aligned</p>

<!-- Weight -->
<p class="font-normal">Normal (400)</p>
<p class="font-medium">Medium (500)</p>
<p class="font-semibold">Semibold (600)</p>
<p class="font-bold">Bold (700)</p>

<!-- Transform -->
<p class="uppercase">UPPERCASE TEXT</p>
<p class="lowercase">lowercase text</p>
<p class="capitalize">Capitalized Text</p>

Color Utilities

<!-- Text Colors -->
<p class="text-primary">Primary color</p>
<p class="text-success">Success (green)</p>
<p class="text-warning">Warning (yellow)</p>
<p class="text-error">Error (red)</p>
<p class="text-info">Info (blue)</p>
<p class="text-muted">Muted (gray)</p>
<p class="text-secondary">Secondary (light gray)</p>

<!-- Background Colors -->
<div class="bg-primary">Primary background</div>
<div class="bg-success">Success background</div>
<div class="bg-warning">Warning background</div>
<div class="bg-error">Error background</div>

<!-- Light Backgrounds (10% opacity) -->
<div class="bg-primary-light">Light primary</div>
<div class="bg-success-light">Light success</div>
<div class="bg-warning-light">Light warning</div>
<div class="bg-error-light">Light error</div>

Flexbox Utilities

<!-- Flex Container -->
<div class="flex">Flex container</div>
<div class="inline-flex">Inline flex</div>

<!-- Direction -->
<div class="flex flex-row">Row (default)</div>
<div class="flex flex-col">Column</div>
<div class="flex flex-row-reverse">Row reverse</div>
<div class="flex flex-col-reverse">Column reverse</div>

<!-- Justify Content -->
<div class="flex justify-start">Start</div>
<div class="flex justify-center">Center</div>
<div class="flex justify-end">End</div>
<div class="flex justify-between">Space between</div>
<div class="flex justify-around">Space around</div>

<!-- Align Items -->
<div class="flex items-start">Start</div>
<div class="flex items-center">Center</div>
<div class="flex items-end">End</div>
<div class="flex items-stretch">Stretch</div>

<!-- Gap -->
<div class="flex gap-sm">Small gap</div>
<div class="flex gap-md">Medium gap</div>
<div class="flex gap-lg">Large gap</div>

Display Utilities

<div class="block">Block</div>
<div class="inline-block">Inline block</div>
<div class="inline">Inline</div>
<div class="hidden">Hidden</div>

<!-- Responsive -->
<div class="hidden md:block">Hidden mobile, visible tablet+</div>
<div class="block md:hidden">Visible mobile, hidden tablet+</div>

Mobile Material Design

Full Documentation: docs/MOBILE_PATTERNS.md

ROA2WEB includes a complete mobile component library following Material Design 3 principles. All mobile components are designed for touch interactions and support both light and dark themes.

Available Components

Component Location Description
MobileTopBar @shared/components/mobile/ Fixed top bar with title, back/menu buttons, and actions
MobileBottomNav @shared/components/mobile/ Fixed bottom navigation with router integration
MobileSelectionFooter @shared/components/mobile/ Slide-up action bar for batch operations
BottomSheet @shared/components/mobile/ Modal sheet for filters and forms
SwipeableCards @shared/components/mobile/ Touch carousel for KPI cards

Mobile Breakpoints

/* Mobile-first breakpoints */
@media (max-width: 768px) {
  /* Mobile styles - this is where mobile components activate */
}

@media (min-width: 769px) {
  /* Tablet and desktop styles */
}

@media (min-width: 1024px) {
  /* Desktop-only styles */
}

Key Mobile Layout Tokens

Token Value Use
--header-height 56px TopBar and BottomNav height
Touch target 48×48px Minimum button/tap area
--z-fixed 1030 Fixed navigation elements
--z-modal 1050 BottomSheet and overlays

Quick Example

<template>
  <div class="mobile-view">
    <MobileTopBar title="My View" :showMenu="true" />

    <main class="mobile-content">
      <!-- Content with padding for fixed bars -->
    </main>

    <MobileBottomNav />
  </div>
</template>

<style scoped>
.mobile-content {
  padding-top: 56px;    /* MobileTopBar */
  padding-bottom: 56px; /* MobileBottomNav */
  min-height: 100vh;
}
</style>

For complete documentation including all props, events, and usage patterns, see MOBILE_PATTERNS.md.


Quick Reference

Most Common Patterns

<!-- Card with content -->
<div class="card">
  <div class="card-body">Content</div>
</div>

<!-- Primary button -->
<button class="btn btn-primary">Action</button>

<!-- Form field -->
<div class="form-group">
  <label class="form-label">Label</label>
  <input type="text" class="form-input" />
</div>

<!-- Loading spinner -->
<div class="loading-spinner"></div>

<!-- Success text -->
<p class="text-success font-semibold">Success message</p>

<!-- Flex row with spacing -->
<div class="flex items-center gap-md">
  <span>Item 1</span>
  <span>Item 2</span>
</div>

Color Shortcuts

Purpose Class Color
Primary action .text-primary .bg-primary Blue (#2563eb)
Success/Positive .text-success .bg-success Green (#059669)
Warning/Caution .text-warning .bg-warning Yellow (#d97706)
Error/Danger .text-error .bg-error Red (#dc2626)
Info/Neutral .text-info .bg-info Cyan (#0891b2)

Spacing Scale

Token Size Use Case
var(--space-xs) 0.25rem (4px) Tight spacing
var(--space-sm) 0.5rem (8px) Default gaps
var(--space-md) 1rem (16px) Component padding
var(--space-lg) 1.5rem (24px) Section padding
var(--space-xl) 2rem (32px) Page margins
var(--space-2xl) 3rem (48px) Large separations
var(--space-3xl) 4rem (64px) Hero sections

Font Sizes

Class Size Use Case
.text-xs 0.75rem (12px) Tiny labels
.text-sm 0.875rem (14px) Small text
.text-base 1rem (16px) Body text
.text-lg 1.125rem (18px) Emphasized text
.text-xl 1.25rem (20px) Small headings
.text-2xl 1.5rem (24px) Headings
.text-3xl 1.875rem (30px) Large headings
.text-4xl 2.25rem (36px) Page titles

Browser Support

All patterns support:

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

Performance Notes

  • CSS bundle size: 366.42 kB (51.31 kB gzipped)
  • All patterns use design tokens for consistency
  • Animations use transform and opacity for GPU acceleration
  • No unused patterns in production build

Need Help?


Last Updated: 2026-01-12 Version: 2.1.0 (Added Mobile Material Design section) Maintained By: Frontend Team