@whykusanagi/corrupted-theme 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +6 -0
  3. package/docs/CAPABILITIES.md +209 -0
  4. package/docs/CHARACTER_LEVEL_CORRUPTION.md +264 -0
  5. package/docs/CORRUPTION_PHRASES.md +529 -0
  6. package/docs/FUTURE_WORK.md +189 -0
  7. package/docs/IMPLEMENTATION_VALIDATION.md +401 -0
  8. package/docs/LLM_PROVIDERS.md +345 -0
  9. package/docs/PERSONALITY.md +128 -0
  10. package/docs/ROADMAP.md +266 -0
  11. package/docs/ROUTING.md +324 -0
  12. package/docs/STYLE_GUIDE.md +605 -0
  13. package/docs/brand/BRAND_OVERVIEW.md +413 -0
  14. package/docs/brand/COLOR_SYSTEM.md +583 -0
  15. package/docs/brand/DESIGN_TOKENS.md +1009 -0
  16. package/docs/brand/TRANSLATION_FAILURE_AESTHETIC.md +525 -0
  17. package/docs/brand/TYPOGRAPHY.md +624 -0
  18. package/docs/components/ANIMATION_GUIDELINES.md +901 -0
  19. package/docs/components/COMPONENT_LIBRARY.md +1061 -0
  20. package/docs/components/GLASSMORPHISM.md +602 -0
  21. package/docs/components/INTERACTIVE_STATES.md +766 -0
  22. package/docs/governance/CONTRIBUTION_GUIDELINES.md +593 -0
  23. package/docs/governance/DESIGN_SYSTEM_GOVERNANCE.md +451 -0
  24. package/docs/governance/VERSION_MANAGEMENT.md +447 -0
  25. package/docs/governance/VERSION_REFERENCES.md +229 -0
  26. package/docs/platforms/CLI_IMPLEMENTATION.md +1025 -0
  27. package/docs/platforms/COMPONENT_MAPPING.md +579 -0
  28. package/docs/platforms/NPM_PACKAGE.md +854 -0
  29. package/docs/platforms/WEB_IMPLEMENTATION.md +1221 -0
  30. package/docs/standards/ACCESSIBILITY.md +715 -0
  31. package/docs/standards/ANTI_PATTERNS.md +554 -0
  32. package/docs/standards/SPACING_SYSTEM.md +549 -0
  33. package/examples/button.html +1 -1
  34. package/examples/card.html +1 -1
  35. package/examples/form.html +1 -1
  36. package/examples/index.html +2 -2
  37. package/examples/layout.html +1 -1
  38. package/examples/nikke-team-builder.html +1 -1
  39. package/examples/showcase-complete.html +840 -15
  40. package/examples/showcase.html +1 -1
  41. package/package.json +4 -2
  42. package/src/css/components.css +676 -0
  43. package/src/lib/character-corruption.js +563 -0
  44. package/src/lib/components.js +283 -0
@@ -0,0 +1,1221 @@
1
+ # Web Implementation Guide
2
+
3
+ > **Celeste Brand System** | Platform Documentation
4
+ > **Document**: Web Implementation Guide
5
+ > **Version**: 1.0.0
6
+ > **Last Updated**: 2025-12-13
7
+
8
+ ---
9
+
10
+ ## Table of Contents
11
+
12
+ 1. [Overview](#overview)
13
+ 2. [Responsive Design System](#responsive-design-system)
14
+ 3. [CSS Integration](#css-integration)
15
+ 4. [Framework Integration](#framework-integration)
16
+ 5. [Performance Optimization](#performance-optimization)
17
+ 6. [Browser Support](#browser-support)
18
+ 7. [Accessibility](#accessibility)
19
+ 8. [Implementation Examples](#implementation-examples)
20
+ 9. [Common Patterns](#common-patterns)
21
+ 10. [Troubleshooting](#troubleshooting)
22
+
23
+ ---
24
+
25
+ ## Overview
26
+
27
+ This guide covers implementing the Celeste brand system on web platforms using the **@whykusanagi/corrupted-theme** npm package. The web implementation maintains the same translation-failure aesthetic as the CLI while adapting to responsive, interactive web interfaces.
28
+
29
+ ### Key Web Features
30
+
31
+ - **Responsive Design**: Mobile-first approach with 3 breakpoints
32
+ - **Glassmorphism**: CSS backdrop-filter effects for frosted glass aesthetic
33
+ - **Modular CSS**: Import only what you need (9 modular files)
34
+ - **Design Tokens**: CSS custom properties for easy theming
35
+ - **Framework Agnostic**: Works with React, Vue, Svelte, vanilla JS
36
+ - **Accessibility**: WCAG AA compliant with keyboard navigation
37
+ - **Performance**: GPU-accelerated animations, optimized glass effects
38
+
39
+ ### Quick Start
40
+
41
+ ```bash
42
+ # Install corrupted-theme
43
+ npm install @whykusanagi/corrupted-theme
44
+
45
+ # Or use from local development
46
+ npm link /path/to/corrupted-theme
47
+ ```
48
+
49
+ ```html
50
+ <!-- Import full theme -->
51
+ <link rel="stylesheet" href="node_modules/@whykusanagi/corrupted-theme/src/css/theme.css">
52
+
53
+ <!-- Or import modularly -->
54
+ <link rel="stylesheet" href="node_modules/@whykusanagi/corrupted-theme/src/css/variables.css">
55
+ <link rel="stylesheet" href="node_modules/@whykusanagi/corrupted-theme/src/css/glass.css">
56
+ <link rel="stylesheet" href="node_modules/@whykusanagi/corrupted-theme/src/css/components.css">
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Responsive Design System
62
+
63
+ ### Breakpoint Strategy
64
+
65
+ Celeste uses a **mobile-first** approach with 3 core breakpoints:
66
+
67
+ ```css
68
+ /* Mobile: 0-640px (default - no media query needed) */
69
+ .container {
70
+ padding: 1rem;
71
+ max-width: 100%;
72
+ }
73
+
74
+ /* Tablet: 641px-1024px */
75
+ @media (min-width: 641px) {
76
+ .container {
77
+ padding: 2rem;
78
+ max-width: 768px;
79
+ }
80
+ }
81
+
82
+ /* Desktop: 1025px+ */
83
+ @media (min-width: 1025px) {
84
+ .container {
85
+ padding: 3rem;
86
+ max-width: 1200px;
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Breakpoint Reference
92
+
93
+ | Breakpoint | Range | Target Devices | Container Width |
94
+ |------------|-------|----------------|-----------------|
95
+ | **Mobile** | 0-640px | Phones (portrait) | 100% (16px padding) |
96
+ | **Tablet** | 641px-1024px | Tablets, phones (landscape) | 768px (32px padding) |
97
+ | **Desktop** | 1025px+ | Laptops, desktops, large screens | 1200px (48px padding) |
98
+
99
+ ### Design Tokens for Breakpoints
100
+
101
+ ```css
102
+ :root {
103
+ /* Breakpoint values */
104
+ --breakpoint-mobile: 640px;
105
+ --breakpoint-tablet: 641px;
106
+ --breakpoint-desktop: 1025px;
107
+
108
+ /* Container widths */
109
+ --container-mobile: 100%;
110
+ --container-tablet: 768px;
111
+ --container-desktop: 1200px;
112
+
113
+ /* Spacing scale (responsive) */
114
+ --spacing-xs: 0.25rem; /* 4px */
115
+ --spacing-sm: 0.5rem; /* 8px */
116
+ --spacing-md: 1rem; /* 16px */
117
+ --spacing-lg: 1.5rem; /* 24px */
118
+ --spacing-xl: 2rem; /* 32px */
119
+ --spacing-2xl: 3rem; /* 48px */
120
+ }
121
+
122
+ /* Scale up spacing on larger screens */
123
+ @media (min-width: 1025px) {
124
+ :root {
125
+ --spacing-lg: 2rem; /* 32px on desktop */
126
+ --spacing-xl: 3rem; /* 48px on desktop */
127
+ --spacing-2xl: 4rem; /* 64px on desktop */
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Responsive Typography
133
+
134
+ Typography scales proportionally across breakpoints:
135
+
136
+ ```css
137
+ /* Mobile typography (base) */
138
+ :root {
139
+ --font-size-h1: 2rem; /* 32px */
140
+ --font-size-h2: 1.5rem; /* 24px */
141
+ --font-size-h3: 1.25rem; /* 20px */
142
+ --font-size-body: 1rem; /* 16px */
143
+ --font-size-small: 0.875rem; /* 14px */
144
+ }
145
+
146
+ /* Desktop typography (scaled up) */
147
+ @media (min-width: 1025px) {
148
+ :root {
149
+ --font-size-h1: 3.75rem; /* 60px */
150
+ --font-size-h2: 2.5rem; /* 40px */
151
+ --font-size-h3: 1.875rem; /* 30px */
152
+ --font-size-body: 1.125rem; /* 18px */
153
+ }
154
+ }
155
+
156
+ /* Usage */
157
+ h1 {
158
+ font-size: var(--font-size-h1);
159
+ line-height: 1.2;
160
+ }
161
+ ```
162
+
163
+ ### Grid System (Optional)
164
+
165
+ For complex layouts, use CSS Grid with responsive columns:
166
+
167
+ ```css
168
+ .grid {
169
+ display: grid;
170
+ gap: var(--spacing-md);
171
+
172
+ /* Mobile: 1 column */
173
+ grid-template-columns: 1fr;
174
+ }
175
+
176
+ @media (min-width: 641px) {
177
+ .grid {
178
+ /* Tablet: 2 columns */
179
+ grid-template-columns: repeat(2, 1fr);
180
+ }
181
+ }
182
+
183
+ @media (min-width: 1025px) {
184
+ .grid {
185
+ /* Desktop: 3-4 columns */
186
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
187
+ }
188
+ }
189
+ ```
190
+
191
+ ---
192
+
193
+ ## CSS Integration
194
+
195
+ ### Import Order (Critical)
196
+
197
+ CSS files must be imported in this **specific order** to ensure proper cascading:
198
+
199
+ ```html
200
+ <!-- 1. Variables (design tokens) - MUST be first -->
201
+ <link rel="stylesheet" href="css/variables.css">
202
+
203
+ <!-- 2. Base styles (resets, typography) -->
204
+ <link rel="stylesheet" href="css/base.css">
205
+
206
+ <!-- 3. Animations (keyframes used by components) -->
207
+ <link rel="stylesheet" href="css/animations.css">
208
+
209
+ <!-- 4. Glass effects (backdrop-filter) -->
210
+ <link rel="stylesheet" href="css/glass.css">
211
+
212
+ <!-- 5. Layout utilities -->
213
+ <link rel="stylesheet" href="css/layout.css">
214
+
215
+ <!-- 6. Components -->
216
+ <link rel="stylesheet" href="css/components.css">
217
+
218
+ <!-- 7. Interactive states (hover, focus, active) -->
219
+ <link rel="stylesheet" href="css/interactive.css">
220
+
221
+ <!-- 8. Utilities (last to override) -->
222
+ <link rel="stylesheet" href="css/utilities.css">
223
+
224
+ <!-- 9. Your custom styles -->
225
+ <link rel="stylesheet" href="css/custom.css">
226
+ ```
227
+
228
+ ### Single File Import (Easier)
229
+
230
+ For simpler projects, use the pre-bundled theme:
231
+
232
+ ```html
233
+ <!-- All styles included (8.2KB gzipped) -->
234
+ <link rel="stylesheet" href="node_modules/@whykusanagi/corrupted-theme/src/css/theme.css">
235
+ ```
236
+
237
+ ### CSS Custom Properties (Theming)
238
+
239
+ Override design tokens for custom theming:
240
+
241
+ ```css
242
+ /* Override defaults in your custom CSS */
243
+ :root {
244
+ /* Change accent color from pink to purple */
245
+ --color-accent: #8b5cf6;
246
+ --color-accent-light: #a78bfa;
247
+ --color-accent-dark: #7c3aed;
248
+
249
+ /* Adjust glass opacity */
250
+ --glass-opacity: 0.8; /* Default is 0.7 */
251
+
252
+ /* Change border radius */
253
+ --radius-md: 12px; /* Default is 8px */
254
+ }
255
+ ```
256
+
257
+ ### CSS Architecture
258
+
259
+ The corrupted-theme package follows **ITCSS (Inverted Triangle CSS)** architecture:
260
+
261
+ ```
262
+ Settings (variables.css) ← Most generic
263
+
264
+ Tools (mixins, not included)
265
+
266
+ Generic (base.css)
267
+
268
+ Elements (typography, links)
269
+
270
+ Objects (layout.css)
271
+
272
+ Components (components.css) ← Most specific
273
+
274
+ Utilities (utilities.css)
275
+ ```
276
+
277
+ ---
278
+
279
+ ## Framework Integration
280
+
281
+ ### Vanilla JavaScript
282
+
283
+ ```html
284
+ <!DOCTYPE html>
285
+ <html lang="en">
286
+ <head>
287
+ <meta charset="UTF-8">
288
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
289
+ <title>Celeste App</title>
290
+
291
+ <!-- Import theme -->
292
+ <link rel="stylesheet" href="node_modules/@whykusanagi/corrupted-theme/src/css/theme.css">
293
+ </head>
294
+ <body>
295
+ <div class="glass-card">
296
+ <h2 class="corrupted-text">使US狀ERAGEMENT</h2>
297
+ <p>Your content here</p>
298
+ </div>
299
+
300
+ <script>
301
+ // Add corruption animation
302
+ function corruptText(text, intensity = 0.3) {
303
+ const japaneseChars = ['ア', 'イ', 'ウ', '使', '統', '計', 'ー'];
304
+ return text.split('').map((char, i) => {
305
+ if (Math.random() < intensity && /[a-zA-Z]/.test(char)) {
306
+ return japaneseChars[Math.floor(Math.random() * japaneseChars.length)];
307
+ }
308
+ return char;
309
+ }).join('');
310
+ }
311
+
312
+ // Apply corruption on hover
313
+ document.querySelectorAll('.corrupted-text').forEach(el => {
314
+ const original = el.textContent;
315
+ el.addEventListener('mouseenter', () => {
316
+ el.textContent = corruptText(original);
317
+ });
318
+ el.addEventListener('mouseleave', () => {
319
+ el.textContent = original;
320
+ });
321
+ });
322
+ </script>
323
+ </body>
324
+ </html>
325
+ ```
326
+
327
+ ### React
328
+
329
+ ```jsx
330
+ // App.jsx
331
+ import '@whykusanagi/corrupted-theme/src/css/theme.css';
332
+ import { useState, useEffect } from 'react';
333
+
334
+ function GlassCard({ children }) {
335
+ return (
336
+ <div className="glass-card">
337
+ {children}
338
+ </div>
339
+ );
340
+ }
341
+
342
+ function CorruptedText({ text, intensity = 0.3 }) {
343
+ const [corrupted, setCorrupted] = useState(text);
344
+
345
+ const corruptText = (text) => {
346
+ const japaneseChars = ['ア', 'イ', 'ウ', '使', '統', '計'];
347
+ return text.split('').map((char) => {
348
+ if (Math.random() < intensity && /[a-zA-Z]/.test(char)) {
349
+ return japaneseChars[Math.floor(Math.random() * japaneseChars.length)];
350
+ }
351
+ return char;
352
+ }).join('');
353
+ };
354
+
355
+ useEffect(() => {
356
+ const interval = setInterval(() => {
357
+ setCorrupted(corruptText(text));
358
+ }, 3000);
359
+ return () => clearInterval(interval);
360
+ }, [text, intensity]);
361
+
362
+ return <span className="corrupted-text">{corrupted}</span>;
363
+ }
364
+
365
+ function App() {
366
+ return (
367
+ <div className="container">
368
+ <GlassCard>
369
+ <h2><CorruptedText text="USER MANAGEMENT" /></h2>
370
+ <p>Your content here</p>
371
+ </GlassCard>
372
+ </div>
373
+ );
374
+ }
375
+
376
+ export default App;
377
+ ```
378
+
379
+ ### Vue 3
380
+
381
+ ```vue
382
+ <!-- App.vue -->
383
+ <script setup>
384
+ import { ref, onMounted, onUnmounted } from 'vue';
385
+ import '@whykusanagi/corrupted-theme/src/css/theme.css';
386
+
387
+ const props = defineProps({
388
+ text: String,
389
+ intensity: { type: Number, default: 0.3 }
390
+ });
391
+
392
+ const corrupted = ref(props.text);
393
+
394
+ function corruptText(text) {
395
+ const japaneseChars = ['ア', 'イ', 'ウ', '使', '統', '計'];
396
+ return text.split('').map((char) => {
397
+ if (Math.random() < props.intensity && /[a-zA-Z]/.test(char)) {
398
+ return japaneseChars[Math.floor(Math.random() * japaneseChars.length)];
399
+ }
400
+ return char;
401
+ }).join('');
402
+ }
403
+
404
+ let interval;
405
+ onMounted(() => {
406
+ interval = setInterval(() => {
407
+ corrupted.value = corruptText(props.text);
408
+ }, 3000);
409
+ });
410
+
411
+ onUnmounted(() => clearInterval(interval));
412
+ </script>
413
+
414
+ <template>
415
+ <div class="glass-card">
416
+ <h2 class="corrupted-text">{{ corrupted }}</h2>
417
+ <slot />
418
+ </div>
419
+ </template>
420
+ ```
421
+
422
+ ### Next.js (App Router)
423
+
424
+ ```jsx
425
+ // app/layout.jsx
426
+ import '@whykusanagi/corrupted-theme/src/css/theme.css';
427
+
428
+ export const metadata = {
429
+ title: 'Celeste App',
430
+ description: 'Translation-failure aesthetic',
431
+ };
432
+
433
+ export default function RootLayout({ children }) {
434
+ return (
435
+ <html lang="en">
436
+ <body>{children}</body>
437
+ </html>
438
+ );
439
+ }
440
+
441
+ // app/page.jsx
442
+ 'use client';
443
+
444
+ import { useEffect, useState } from 'react';
445
+
446
+ export default function Home() {
447
+ const [mounted, setMounted] = useState(false);
448
+
449
+ useEffect(() => {
450
+ setMounted(true);
451
+ }, []);
452
+
453
+ if (!mounted) return null; // Prevent SSR hydration mismatch
454
+
455
+ return (
456
+ <main className="container">
457
+ <div className="glass-card">
458
+ <h1 className="corrupted-text">使WE統LCOME</h1>
459
+ <p>Premium corrupted AI aesthetic</p>
460
+ </div>
461
+ </main>
462
+ );
463
+ }
464
+ ```
465
+
466
+ ---
467
+
468
+ ## Performance Optimization
469
+
470
+ ### Critical Rendering Path
471
+
472
+ 1. **Inline critical CSS** for above-the-fold content:
473
+
474
+ ```html
475
+ <head>
476
+ <style>
477
+ /* Critical CSS (variables + glass-card only) */
478
+ :root {
479
+ --color-accent: #d94f90;
480
+ --glass-bg: rgba(20, 12, 40, 0.7);
481
+ }
482
+
483
+ .glass-card {
484
+ background: var(--glass-bg);
485
+ backdrop-filter: blur(15px);
486
+ border-radius: 8px;
487
+ padding: 2rem;
488
+ }
489
+ </style>
490
+
491
+ <!-- Defer non-critical CSS -->
492
+ <link rel="preload" href="theme.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
493
+ <noscript><link rel="stylesheet" href="theme.css"></noscript>
494
+ </head>
495
+ ```
496
+
497
+ ### Glass Effect Performance
498
+
499
+ Backdrop-filter is expensive. Follow these rules:
500
+
501
+ ```css
502
+ /* ✅ Good: Limited glass elements */
503
+ .hero-card {
504
+ backdrop-filter: blur(15px);
505
+ }
506
+
507
+ /* ❌ Bad: Too many glass elements */
508
+ .every-card {
509
+ backdrop-filter: blur(15px); /* 20+ cards = janky scroll */
510
+ }
511
+
512
+ /* ✅ Good: Disable glass on scroll (mobile) */
513
+ @media (max-width: 640px) {
514
+ .scrolling .glass-card {
515
+ backdrop-filter: none; /* Improve scroll performance */
516
+ background: rgba(20, 12, 40, 0.95); /* Solid fallback */
517
+ }
518
+ }
519
+ ```
520
+
521
+ ### Code Splitting (React)
522
+
523
+ ```jsx
524
+ import { lazy, Suspense } from 'react';
525
+
526
+ // Lazy load corrupted-theme for non-critical pages
527
+ const CorruptedDashboard = lazy(() => import('./CorruptedDashboard'));
528
+
529
+ function App() {
530
+ return (
531
+ <Suspense fallback={<div>Loading...</div>}>
532
+ <CorruptedDashboard />
533
+ </Suspense>
534
+ );
535
+ }
536
+ ```
537
+
538
+ ### Image Optimization
539
+
540
+ ```html
541
+ <!-- Use WebP with fallback -->
542
+ <picture>
543
+ <source srcset="hero.webp" type="image/webp">
544
+ <img src="hero.jpg" alt="Hero" loading="lazy">
545
+ </picture>
546
+
547
+ <!-- Add blur placeholder for glassmorphism effect -->
548
+ <div class="glass-image-wrapper">
549
+ <img src="hero.jpg" alt="Hero" style="filter: blur(2px);">
550
+ </div>
551
+ ```
552
+
553
+ ### Animation Performance
554
+
555
+ ```css
556
+ /* ✅ Good: GPU-accelerated properties only */
557
+ .btn {
558
+ transition: transform 0.15s ease, opacity 0.15s ease;
559
+ }
560
+
561
+ .btn:hover {
562
+ transform: scale(1.05);
563
+ opacity: 0.9;
564
+ }
565
+
566
+ /* ❌ Bad: CPU-bound properties */
567
+ .btn:hover {
568
+ width: 120px; /* Causes reflow */
569
+ margin-left: -10px; /* Causes reflow */
570
+ }
571
+ ```
572
+
573
+ ---
574
+
575
+ ## Browser Support
576
+
577
+ ### Target Browsers
578
+
579
+ Celeste supports **modern browsers** with graceful degradation:
580
+
581
+ | Browser | Minimum Version | Notes |
582
+ |---------|-----------------|-------|
583
+ | **Chrome** | 90+ | Full support (backdrop-filter) |
584
+ | **Firefox** | 88+ | Full support |
585
+ | **Safari** | 14+ | Full support (-webkit-backdrop-filter) |
586
+ | **Edge** | 90+ | Full support (Chromium-based) |
587
+ | **Mobile Safari** | iOS 14+ | Full support |
588
+ | **Chrome Android** | 90+ | Full support |
589
+
590
+ ### Feature Detection
591
+
592
+ Use `@supports` for progressive enhancement:
593
+
594
+ ```css
595
+ /* Fallback for browsers without backdrop-filter */
596
+ .glass-card {
597
+ background: rgba(20, 12, 40, 0.95); /* Solid fallback */
598
+ border: 1px solid rgba(217, 79, 144, 0.3);
599
+ }
600
+
601
+ /* Enhanced glass effect for modern browsers */
602
+ @supports (backdrop-filter: blur(15px)) or (-webkit-backdrop-filter: blur(15px)) {
603
+ .glass-card {
604
+ background: rgba(20, 12, 40, 0.7); /* More transparent */
605
+ backdrop-filter: blur(15px);
606
+ -webkit-backdrop-filter: blur(15px); /* Safari prefix */
607
+ }
608
+ }
609
+ ```
610
+
611
+ ### Vendor Prefixes
612
+
613
+ **Required prefixes** (already included in theme.css):
614
+
615
+ ```css
616
+ .glass-card {
617
+ backdrop-filter: blur(15px); /* Standard */
618
+ -webkit-backdrop-filter: blur(15px); /* Safari/iOS */
619
+ }
620
+
621
+ .gradient-text {
622
+ background-clip: text; /* Standard */
623
+ -webkit-background-clip: text; /* Safari/Chrome */
624
+ -webkit-text-fill-color: transparent; /* Safari/Chrome */
625
+ }
626
+ ```
627
+
628
+ ### Polyfills (Optional)
629
+
630
+ For IE11 support (not recommended), use polyfills:
631
+
632
+ ```html
633
+ <!-- CSS custom properties polyfill -->
634
+ <script src="https://cdn.jsdelivr.net/npm/css-vars-ponyfill@2"></script>
635
+ <script>
636
+ cssVars({
637
+ include: 'link[rel=stylesheet]',
638
+ onlyLegacy: true, // Only run for IE11
639
+ });
640
+ </script>
641
+ ```
642
+
643
+ ---
644
+
645
+ ## Accessibility
646
+
647
+ ### WCAG AA Compliance
648
+
649
+ All Celeste components meet **WCAG 2.1 Level AA** standards:
650
+
651
+ #### Color Contrast
652
+
653
+ ```css
654
+ /* ✅ All combinations tested */
655
+ --color-bg: #0a0612; /* Dark background */
656
+ --color-text: #ffffff; /* White text: 21:1 ratio (AAA) */
657
+ --color-accent: #d94f90; /* Pink accent: 7.2:1 ratio (AAA) */
658
+ --color-muted: #a0a0a0; /* Muted text: 10.5:1 ratio (AAA) */
659
+ ```
660
+
661
+ #### Keyboard Navigation
662
+
663
+ ```css
664
+ /* Focus indicators (WCAG 2.4.7) */
665
+ .btn:focus-visible {
666
+ outline: 2px solid rgba(217, 79, 144, 0.7);
667
+ outline-offset: 2px;
668
+ }
669
+
670
+ /* Skip to main content link */
671
+ .skip-link {
672
+ position: absolute;
673
+ top: -40px;
674
+ left: 0;
675
+ background: var(--color-accent);
676
+ color: white;
677
+ padding: 8px;
678
+ z-index: 100;
679
+ }
680
+
681
+ .skip-link:focus {
682
+ top: 0;
683
+ }
684
+ ```
685
+
686
+ #### Screen Reader Support
687
+
688
+ ```html
689
+ <!-- ARIA labels for interactive elements -->
690
+ <button class="btn" aria-label="Close dialog">
691
+ <span aria-hidden="true">×</span>
692
+ </button>
693
+
694
+ <!-- ARIA live regions for dynamic content -->
695
+ <div class="toast" role="alert" aria-live="polite">
696
+ Success! Data saved.
697
+ </div>
698
+
699
+ <!-- Hidden text for corrupted content -->
700
+ <h2 class="corrupted-text" aria-label="User Management">
701
+ 使US狀ERAGEMENT <!-- Visual corruption -->
702
+ </h2>
703
+ ```
704
+
705
+ #### Motion Reduction
706
+
707
+ ```css
708
+ /* Respect user preference (WCAG 2.3.3) */
709
+ @media (prefers-reduced-motion: reduce) {
710
+ * {
711
+ animation-duration: 0.01ms !important;
712
+ animation-iteration-count: 1 !important;
713
+ transition-duration: 0.01ms !important;
714
+ }
715
+
716
+ /* Disable decorative animations */
717
+ .corrupted-text,
718
+ .flicker,
719
+ .glitch-effect {
720
+ animation: none;
721
+ }
722
+ }
723
+ ```
724
+
725
+ #### Touch Targets (Mobile)
726
+
727
+ ```css
728
+ /* Minimum 44x44px touch targets (WCAG 2.5.5) */
729
+ .btn {
730
+ min-width: 44px;
731
+ min-height: 44px;
732
+ padding: 0.75rem 1.5rem;
733
+ }
734
+
735
+ /* Increase spacing between touch targets */
736
+ .btn + .btn {
737
+ margin-left: 0.5rem; /* 8px gap */
738
+ }
739
+ ```
740
+
741
+ ---
742
+
743
+ ## Implementation Examples
744
+
745
+ ### Example 1: Homepage Hero
746
+
747
+ ```html
748
+ <section class="hero">
749
+ <div class="container">
750
+ <div class="glass-card hero-card">
751
+ <h1 class="corrupted-text" aria-label="Welcome to Celeste">
752
+ 使WE統LCOME TO C理計E埋ESTE
753
+ </h1>
754
+ <p class="subtitle">
755
+ Premium corrupted AI aesthetic with translation-failure linguistics
756
+ </p>
757
+ <div class="btn-group">
758
+ <button class="btn btn-primary">Get Started</button>
759
+ <button class="btn btn-secondary">Learn More</button>
760
+ </div>
761
+ </div>
762
+ </div>
763
+ </section>
764
+
765
+ <style>
766
+ .hero {
767
+ min-height: 100vh;
768
+ display: flex;
769
+ align-items: center;
770
+ background: linear-gradient(135deg, #0a0612 0%, #1a0a2e 100%);
771
+ }
772
+
773
+ .hero-card {
774
+ text-align: center;
775
+ max-width: 600px;
776
+ margin: 0 auto;
777
+ }
778
+
779
+ .hero h1 {
780
+ font-size: clamp(2rem, 5vw, 3.75rem); /* Responsive font size */
781
+ margin-bottom: 1rem;
782
+ }
783
+
784
+ .subtitle {
785
+ font-size: 1.25rem;
786
+ color: rgba(255, 255, 255, 0.8);
787
+ margin-bottom: 2rem;
788
+ }
789
+
790
+ .btn-group {
791
+ display: flex;
792
+ gap: 1rem;
793
+ justify-content: center;
794
+ flex-wrap: wrap; /* Stack on mobile */
795
+ }
796
+ </style>
797
+ ```
798
+
799
+ ### Example 2: Dashboard Grid
800
+
801
+ ```html
802
+ <div class="dashboard">
803
+ <div class="grid">
804
+ <div class="glass-card stat-card">
805
+ <div class="stat-icon">📊</div>
806
+ <h3>US使AGE</h3>
807
+ <p class="stat-value">1,234</p>
808
+ </div>
809
+
810
+ <div class="glass-card stat-card">
811
+ <div class="stat-icon">👥</div>
812
+ <h3>US統ERS</h3>
813
+ <p class="stat-value">567</p>
814
+ </div>
815
+
816
+ <div class="glass-card stat-card">
817
+ <div class="stat-icon">⚡</div>
818
+ <h3>AC計IVE</h3>
819
+ <p class="stat-value">89</p>
820
+ </div>
821
+ </div>
822
+ </div>
823
+
824
+ <style>
825
+ .dashboard {
826
+ padding: 2rem;
827
+ }
828
+
829
+ .grid {
830
+ display: grid;
831
+ gap: 1.5rem;
832
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
833
+ }
834
+
835
+ .stat-card {
836
+ text-align: center;
837
+ padding: 2rem;
838
+ transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
839
+ }
840
+
841
+ .stat-card:hover {
842
+ transform: translateY(-4px) scale(1.02);
843
+ }
844
+
845
+ .stat-icon {
846
+ font-size: 3rem;
847
+ margin-bottom: 1rem;
848
+ }
849
+
850
+ .stat-value {
851
+ font-size: 2.5rem;
852
+ font-weight: 700;
853
+ color: var(--color-accent);
854
+ }
855
+ </style>
856
+ ```
857
+
858
+ ### Example 3: Form with Validation
859
+
860
+ ```html
861
+ <form class="glass-card form">
862
+ <h2>Sign計 US使UP</h2>
863
+
864
+ <div class="form-group">
865
+ <label for="email">Email</label>
866
+ <input
867
+ type="email"
868
+ id="email"
869
+ class="input"
870
+ placeholder="your@email.com"
871
+ required
872
+ >
873
+ <span class="error-message" role="alert"></span>
874
+ </div>
875
+
876
+ <div class="form-group">
877
+ <label for="password">Password</label>
878
+ <input
879
+ type="password"
880
+ id="password"
881
+ class="input"
882
+ placeholder="••••••••"
883
+ required
884
+ >
885
+ <span class="error-message" role="alert"></span>
886
+ </div>
887
+
888
+ <button type="submit" class="btn btn-primary">
889
+ Create Account
890
+ </button>
891
+ </form>
892
+
893
+ <style>
894
+ .form {
895
+ max-width: 400px;
896
+ margin: 2rem auto;
897
+ padding: 2rem;
898
+ }
899
+
900
+ .form-group {
901
+ margin-bottom: 1.5rem;
902
+ }
903
+
904
+ .form-group label {
905
+ display: block;
906
+ margin-bottom: 0.5rem;
907
+ font-weight: 500;
908
+ }
909
+
910
+ .input {
911
+ width: 100%;
912
+ padding: 0.75rem;
913
+ background: rgba(255, 255, 255, 0.05);
914
+ border: 1px solid rgba(217, 79, 144, 0.3);
915
+ border-radius: 8px;
916
+ color: white;
917
+ font-size: 1rem;
918
+ transition: border-color 0.15s ease;
919
+ }
920
+
921
+ .input:focus {
922
+ outline: none;
923
+ border-color: rgba(217, 79, 144, 0.7);
924
+ }
925
+
926
+ .input.error {
927
+ border-color: rgba(255, 68, 68, 0.7);
928
+ }
929
+
930
+ .error-message {
931
+ display: block;
932
+ color: rgba(255, 68, 68, 0.9);
933
+ font-size: 0.875rem;
934
+ margin-top: 0.25rem;
935
+ min-height: 1.25rem; /* Prevent layout shift */
936
+ }
937
+ </style>
938
+
939
+ <script>
940
+ // Client-side validation
941
+ document.querySelector('.form').addEventListener('submit', (e) => {
942
+ e.preventDefault();
943
+
944
+ const email = document.getElementById('email');
945
+ const password = document.getElementById('password');
946
+
947
+ // Validate email
948
+ if (!email.value.includes('@')) {
949
+ email.classList.add('error');
950
+ email.nextElementSibling.textContent = 'Invalid email address';
951
+ return;
952
+ }
953
+
954
+ // Validate password
955
+ if (password.value.length < 8) {
956
+ password.classList.add('error');
957
+ password.nextElementSibling.textContent = 'Password must be 8+ characters';
958
+ return;
959
+ }
960
+
961
+ // Success - submit form
962
+ console.log('Form submitted');
963
+ });
964
+ </script>
965
+ ```
966
+
967
+ ---
968
+
969
+ ## Common Patterns
970
+
971
+ ### Loading States
972
+
973
+ ```html
974
+ <div class="glass-card loading">
975
+ <div class="spinner"></div>
976
+ <p>Loading...</p>
977
+ </div>
978
+
979
+ <style>
980
+ .spinner {
981
+ width: 40px;
982
+ height: 40px;
983
+ border: 3px solid rgba(217, 79, 144, 0.2);
984
+ border-top-color: #d94f90;
985
+ border-radius: 50%;
986
+ animation: spin 1s linear infinite;
987
+ margin: 0 auto 1rem;
988
+ }
989
+
990
+ @keyframes spin {
991
+ to { transform: rotate(360deg); }
992
+ }
993
+ </style>
994
+ ```
995
+
996
+ ### Toast Notifications
997
+
998
+ ```html
999
+ <div class="toast toast-success" role="alert">
1000
+ ✓ Success! Data saved.
1001
+ </div>
1002
+
1003
+ <style>
1004
+ .toast {
1005
+ position: fixed;
1006
+ bottom: 2rem;
1007
+ right: 2rem;
1008
+ background: rgba(20, 12, 40, 0.95);
1009
+ backdrop-filter: blur(15px);
1010
+ border: 1px solid rgba(217, 79, 144, 0.3);
1011
+ border-radius: 8px;
1012
+ padding: 1rem 1.5rem;
1013
+ box-shadow: 0 4px 16px rgba(217, 79, 144, 0.25);
1014
+ animation: slideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
1015
+ }
1016
+
1017
+ @keyframes slideIn {
1018
+ from {
1019
+ transform: translateX(400px);
1020
+ opacity: 0;
1021
+ }
1022
+ to {
1023
+ transform: translateX(0);
1024
+ opacity: 1;
1025
+ }
1026
+ }
1027
+
1028
+ .toast-success {
1029
+ border-left: 4px solid #10b981; /* Green accent */
1030
+ }
1031
+ </style>
1032
+ ```
1033
+
1034
+ ### Modal Dialog
1035
+
1036
+ ```html
1037
+ <div class="modal-backdrop">
1038
+ <div class="modal glass-card" role="dialog" aria-modal="true">
1039
+ <button class="modal-close" aria-label="Close">×</button>
1040
+ <h2>Dialog計 使Title</h2>
1041
+ <p>Modal content here</p>
1042
+ <div class="modal-actions">
1043
+ <button class="btn btn-secondary">Cancel</button>
1044
+ <button class="btn btn-primary">Confirm</button>
1045
+ </div>
1046
+ </div>
1047
+ </div>
1048
+
1049
+ <style>
1050
+ .modal-backdrop {
1051
+ position: fixed;
1052
+ inset: 0;
1053
+ background: rgba(0, 0, 0, 0.8);
1054
+ backdrop-filter: blur(4px);
1055
+ display: flex;
1056
+ align-items: center;
1057
+ justify-content: center;
1058
+ z-index: 1000;
1059
+ }
1060
+
1061
+ .modal {
1062
+ max-width: 500px;
1063
+ width: 90%;
1064
+ max-height: 90vh;
1065
+ overflow-y: auto;
1066
+ animation: modalEnter 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
1067
+ }
1068
+
1069
+ @keyframes modalEnter {
1070
+ from {
1071
+ opacity: 0;
1072
+ transform: scale(0.9) translateY(-20px);
1073
+ }
1074
+ to {
1075
+ opacity: 1;
1076
+ transform: scale(1) translateY(0);
1077
+ }
1078
+ }
1079
+
1080
+ .modal-close {
1081
+ position: absolute;
1082
+ top: 1rem;
1083
+ right: 1rem;
1084
+ background: none;
1085
+ border: none;
1086
+ font-size: 2rem;
1087
+ color: white;
1088
+ cursor: pointer;
1089
+ }
1090
+
1091
+ .modal-actions {
1092
+ display: flex;
1093
+ gap: 1rem;
1094
+ justify-content: flex-end;
1095
+ margin-top: 2rem;
1096
+ }
1097
+ </style>
1098
+ ```
1099
+
1100
+ ---
1101
+
1102
+ ## Troubleshooting
1103
+
1104
+ ### Issue: Backdrop-filter Not Working
1105
+
1106
+ **Symptoms**: Glass effect appears solid instead of translucent blur
1107
+
1108
+ **Causes**:
1109
+ 1. Browser doesn't support backdrop-filter
1110
+ 2. Missing `-webkit-` prefix for Safari
1111
+ 3. Element has no positioned parent
1112
+
1113
+ **Solutions**:
1114
+ ```css
1115
+ /* Add vendor prefix */
1116
+ .glass-card {
1117
+ backdrop-filter: blur(15px);
1118
+ -webkit-backdrop-filter: blur(15px); /* Safari */
1119
+ }
1120
+
1121
+ /* Ensure parent creates stacking context */
1122
+ .parent {
1123
+ position: relative;
1124
+ z-index: 0;
1125
+ }
1126
+
1127
+ /* Fallback for unsupported browsers */
1128
+ @supports not (backdrop-filter: blur(15px)) {
1129
+ .glass-card {
1130
+ background: rgba(20, 12, 40, 0.95); /* More opaque */
1131
+ }
1132
+ }
1133
+ ```
1134
+
1135
+ ### Issue: Animations Janky on Mobile
1136
+
1137
+ **Symptoms**: Scrolling/animations drop frames on mobile devices
1138
+
1139
+ **Solutions**:
1140
+ ```css
1141
+ /* Disable expensive effects on mobile */
1142
+ @media (max-width: 640px) {
1143
+ .glass-card {
1144
+ backdrop-filter: none;
1145
+ background: rgba(20, 12, 40, 0.95);
1146
+ }
1147
+
1148
+ /* Simplify animations */
1149
+ * {
1150
+ animation-duration: 0.15s !important;
1151
+ }
1152
+ }
1153
+
1154
+ /* Use GPU acceleration */
1155
+ .animated-element {
1156
+ will-change: transform;
1157
+ transform: translateZ(0); /* Force GPU layer */
1158
+ }
1159
+ ```
1160
+
1161
+ ### Issue: Text Corruption Not Visible
1162
+
1163
+ **Symptoms**: Japanese characters not rendering or showing boxes
1164
+
1165
+ **Causes**:
1166
+ 1. Font doesn't support Japanese characters
1167
+ 2. Character encoding incorrect
1168
+
1169
+ **Solutions**:
1170
+ ```html
1171
+ <!-- Ensure UTF-8 encoding -->
1172
+ <meta charset="UTF-8">
1173
+
1174
+ <!-- Use system fonts with Japanese support -->
1175
+ <style>
1176
+ body {
1177
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
1178
+ 'Hiragino Sans', 'Yu Gothic', sans-serif;
1179
+ }
1180
+ </style>
1181
+ ```
1182
+
1183
+ ### Issue: CSS Custom Properties Not Working
1184
+
1185
+ **Symptoms**: Styles not applying, colors are wrong
1186
+
1187
+ **Causes**:
1188
+ 1. Variables.css not imported first
1189
+ 2. Typo in variable name
1190
+
1191
+ **Solutions**:
1192
+ ```html
1193
+ <!-- MUST import variables FIRST -->
1194
+ <link rel="stylesheet" href="css/variables.css">
1195
+ <link rel="stylesheet" href="css/components.css">
1196
+ ```
1197
+
1198
+ ```css
1199
+ /* Check variable name spelling */
1200
+ .btn {
1201
+ background: var(--color-accent); /* Correct */
1202
+ /* background: var(--accent-color); ← Wrong variable name */
1203
+ }
1204
+ ```
1205
+
1206
+ ---
1207
+
1208
+ ## Related Documentation
1209
+
1210
+ - [NPM_PACKAGE.md](./NPM_PACKAGE.md) - Package installation and configuration
1211
+ - [COMPONENT_MAPPING.md](./COMPONENT_MAPPING.md) - Web ↔ CLI component equivalents
1212
+ - [COMPONENT_LIBRARY.md](../components/COMPONENT_LIBRARY.md) - All available components
1213
+ - [ANIMATION_GUIDELINES.md](../components/ANIMATION_GUIDELINES.md) - Animation specifications
1214
+ - [ACCESSIBILITY.md](../standards/ACCESSIBILITY.md) - Full accessibility standards
1215
+
1216
+ ---
1217
+
1218
+ **Last Updated**: 2025-12-13
1219
+ **Version**: 1.0.0
1220
+ **Maintainer**: Celeste Brand System
1221
+ **Status**: ✅ Ready for Production