Colors
+Brand palette, semantic aliases, and text hierarchy. Click any swatch to copy the CSS variable.
+ +Code snippet
/* Brand */
+--violet: #9B5DE5;
+--cyan: #06D6E0;
+--green: #06D664;
+--pink: #F15BB5;
+--amber: #FFB347;
+
+/* Semantic */
+--success: var(--green);
+--warning: var(--amber);
+--danger: var(--pink);
+--info: var(--cyan);Typography
+Type scale, font families, and weight ladder. Unbounded: display/headings/KPI numbers. Manrope: everything else.
+ +Code snippet
--text-xs: 0.72rem; /* 11.5px */
+--text-sm: 0.82rem; /* 13px */
+--text-base: 0.92rem; /* 14.7px */
+--text-md: 1.02rem; /* 16.3px */
+--text-lg: 1.18rem; /* 18.9px */
+--text-xl: 1.5rem; /* 24px */
+--text-2xl: 2rem; /* 32px */
+--text-3xl: 2.6rem; /* 41.6px */
+
+--fw-regular: 400;
+--fw-medium: 500;
+--fw-semibold: 600;
+--fw-bold: 700;
+--fw-extrabold: 800;Spacing
+4px base scale. Use tokens instead of hardcoded values for consistent rhythm.
+Code snippet
--space-1: 4px;
+--space-2: 8px;
+--space-3: 12px;
+--space-4: 16px;
+--space-5: 20px;
+--space-6: 24px;
+--space-8: 32px;
+--space-10: 40px;
+--space-12: 48px;
+--space-16: 64px;Radii
+Border-radius ladder from sharp to pill. Click to copy.
+Code snippet
--r-xs: 4px;
+--r-sm: 8px;
+--r-md: 12px;
+--r-lg: 20px;
+--r-xl: 24px;
+--r-pill: 999px;Shadows
+Two-layer shadows: crisp ambient + lifted. Use --shadow-h on hover.
Code snippet
--shadow: 0 2px 8px rgba(15,23,42,0.08), 0 8px 40px rgba(15,23,42,0.10);
+--shadow-h: 0 4px 16px rgba(15,23,42,0.12), 0 16px 56px rgba(15,23,42,0.13);Blur
+--blur: blur(20px) — used with a semi-transparent background for glass surfaces.
Code snippet
--blur: blur(20px);
+
+/* Usage */
+.glass-panel {
+ background: rgba(238,242,255,0.55);
+ backdrop-filter: var(--blur);
+ border: 1.5px solid rgba(255,255,255,0.4);
+}Buttons
+All buttons meet WCAG 2.5.5 44px touch target. Primary has shimmer on hover.
+ +Code snippet
<button class="btn-primary">Primary</button>
+<button class="btn-ghost">Ghost</button>
+<button class="btn-danger">Danger</button>
+<button class="icon-btn" aria-label="Settings">
+ <i data-lucide="settings"></i>
+</button>Form Inputs
+All inputs use .form-input. Focus ring uses violet at 15% opacity.
Code snippet
<input class="form-input" type="text" placeholder="Enter value...">
+<input class="form-input error" type="text">
+<select class="form-input">...</select>
+<textarea class="form-input" rows="3"></textarea>Badges
+5 brand-color variants, pill-shaped, suitable for status labels.
+Code snippet
<span class="badge badge-violet">Учитель</span>
+<span class="badge badge-cyan">Активен</span>
+<span class="badge badge-green">Завершено</span>
+<span class="badge badge-pink">Новый</span>
+<span class="badge badge-amber">Ученик</span>Chips
+Interactive filter chips, KPI chips, and status chips.
+Code snippet
<button class="chip active">All subjects</button>
+<button class="chip">Mathematics
+ <span class="chip-x" aria-label="Remove">...</span>
+</button>Cards
+Surface, glass, top-bar, and hero card variants.
+var(--surface) background with shadow.Code snippet
<div class="ds-surface-card">...</div>
+
+<!-- glass: wrap in gradient div, then -->
+<div style="backdrop-filter:var(--blur);background:rgba(255,255,255,0.35)">...</div>
+
+<!-- top-bar: ::before height:3px; background: gradient -->Modal
+Uses LS.modal() from api.js. Focus-trapped, dismissible via Escape or overlay click.
Code snippet
const m = LS.modal({
+ title: 'Modal title',
+ content: '<p>Body content here</p>',
+ size: 'md', // 'sm' | 'md' | 'lg'
+ actions: [
+ { label: 'Cancel', onClick: () => m.close() },
+ { label: 'Confirm', primary: true, onClick: async () => { ... } },
+ ],
+});Toast
+4 variants via LS.toast(message, type). Auto-dismiss in 3.5s.
Code snippet
LS.toast('Action completed!', 'success');
+LS.toast('Review your input.', 'warn');
+LS.toast('An error occurred.', 'error');
+LS.toast('Session saved.', 'info');Skeleton
+Shimmer placeholders for loading states. Use .ls-skeleton as base.
Code snippet
<!-- Neutral shimmer -->
+<div class="ls-skeleton ls-skeleton-line"></div>
+
+<!-- Violet shimmer (existing) -->
+<div class="ls-sk" style="height:36px"></div>Empty State
+Zero-data, error, and no-results variants using .rich-empty.
Code snippet
<div class="rich-empty">
+ <div class="rich-empty-svg"><!-- Lucide icon --></div>
+ <div class="rich-empty-title">No data yet</div>
+ <div class="rich-empty-sub">Description text</div>
+ <button class="rich-empty-btn">Action</button>
+</div>Avatar
+Initials-based pills with HSL color derived from name hash. Role-colored variants.
+Code snippet
function avatarColor(name) {
+ let h = 0;
+ for (const c of name) h = (h * 31 + c.charCodeAt(0)) % 360;
+ return `hsl(${h}, 60%, 48%)`;
+}
+// initials
+const initials = name.split(' ').slice(0,2).map(w=>w[0]).join('').toUpperCase();Stat Card
+KPI cards with colored top bar and optional delta indicator.
+Code snippet
<div class="stat-card vc">
+ <div class="stat-label">Total sessions</div>
+ <div class="stat-val">1,248</div>
+ <div class="stat-delta">+12% this week</div>
+</div>
+/* .vc = violet-cyan bar, .gc = green-cyan, .ac = amber-pink */Data Table
+Sticky header, hover highlight, row actions revealed on hover.
+| Student | Subject | Score | Date | Status | + |
|---|---|---|---|---|---|
| Anna K. | Mathematics | 92% | May 20 | +Passed | ++ |
| Dmitri P. | Physics | 74% | May 19 | +Review | ++ |
| Maria S. | Chemistry | 88% | May 18 | +Graded | ++ |
| Ivan B. | History | 61% | May 17 | +Failed | ++ |
| Elena V. | Biology | 95% | May 16 | +Top score | ++ |
Code snippet
<div class="ds-table-wrap">
+ <table class="ds-table">
+ <thead><tr><th>Name</th>...</tr></thead>
+ <tbody>
+ <tr>
+ <td>Anna K.</td>...
+ <td><div class="row-actions">...</div></td>
+ </tr>
+ </tbody>
+ </table>
+</div>Search + Filter Bar
+Search input paired with filter chips pattern.
+Code snippet
<div class="search-bar">
+ <div class="search-wrap">
+ <!-- Lucide search icon -->
+ <input class="form-input" type="search" placeholder="Search...">
+ </div>
+ <button class="chip active">All</button>
+ <button class="chip">Active</button>
+</div>Tabs
+Pill-tabs with white active indicator. Wraps in a muted violet track.
+Code snippet
<div class="ds-tabs">
+ <button class="ds-tab active">Overview</button>
+ <button class="ds-tab">Sessions</button>
+ <button class="ds-tab">Students</button>
+</div>Hero Header
+Greeting + KPI chip row used at the top of dashboard pages.
+Bento Grid
+3-column masonry-like grid with spanning cells for dashboard layouts.
+Code snippet
<div class="bento">
+ <div class="bento-cell wide">Span 2 cols</div>
+ <div class="bento-cell tall">Span 2 rows</div>
+ <div class="bento-cell">Normal</div>
+ <div class="bento-cell">Normal</div>
+</div>Hover Row Actions
+Action buttons hidden by default, revealed on row hover via display:flex toggle.
| Name | Role | Last active | |
|---|---|---|---|
| Anna K. | Teacher | 2 min ago | |
| Dmitri P. | Student | 1 hour ago | |
| Maria S. | Admin | Just now |
Hover a row to see action buttons.
+Motion
+Spring and ease-out transitions. Hover cards to see. Toggle prefers-reduced-motion simulation.
+0.22s
0.22s
0.40s
Code snippet
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
+--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
+--duration-fast: 0.12s;
+--duration-base: 0.22s;
+--duration-slow: 0.40s;
+
+/* Usage */
+.card { transition: transform var(--duration-base) var(--ease-spring); }
+.card:hover { transform: translateY(-6px) scale(1.02); }
+
+/* Respect user preference */
+@media (prefers-reduced-motion: reduce) {
+ .card { transition: none; }
+}Accessibility
+Focus rings use :focus-visible. All interactive elements meet 44px touch target (WCAG 2.5.5).
Contrast Checker
+Compute WCAG 2.1 contrast ratio live. AA requires 4.5:1 (normal text), 3:1 (large text).
+Icons (Lucide)
+Top 50 Lucide icons used in LearnSpace. Click to copy <i data-lucide="..."> tag.
Code snippet
<!-- Include once in <head> -->
+<script src="https://cdn.jsdelivr.net/npm/lucide@0.469.0/dist/umd/lucide.min.js"></script>
+
+<!-- Use icon -->
+<i data-lucide="users" style="width:18px;height:18px"></i>
+
+<!-- Initialize (call once after DOM) -->
+<script>lucide.createIcons();</script>Anti-Patterns
+Common mistakes and their correct counterparts in LearnSpace.
+color: #9B5DE5;
+ color: var(--violet);
+ style="display:none"
+ class="hidden"
+ style="background:#9B5DE5;color:#fff;border-radius:999px;..."
+ <button class="btn-primary">
+ style="padding:12px"
+ class="p-3"
+