@whykusanagi/corrupted-theme 0.1.0

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.
package/README.md ADDED
@@ -0,0 +1,399 @@
1
+ # Corrupted Theme
2
+
3
+ A production-ready glassmorphic design system for cinematic, cyberpunk-inspired applications. Built as a drop-in CSS framework with JS enhancements, Docker showcase, and npm distribution standards on par with Meta/Google/Netflix internal libraries.
4
+
5
+ ## Table of Contents
6
+ 1. [Overview](#overview)
7
+ 2. [Installation](#installation)
8
+ 3. [Project Architecture](#project-architecture)
9
+ 4. [Base Layout & Background](#base-layout--background)
10
+ 5. [CSS & JS Imports](#css--js-imports)
11
+ 6. [Component Quick Reference](#component-quick-reference)
12
+ 7. [Animations & Experience Layer](#animations--experience-layer)
13
+ 8. [Nikke Utilities](#nikke-utilities)
14
+ 9. [Customization & Tokens](#customization--tokens)
15
+ 10. [Coding Standards](#coding-standards)
16
+ 11. [Development Workflow](#development-workflow)
17
+ 12. [Testing & QA Expectations](#testing--qa-expectations)
18
+ 13. [Support](#support)
19
+ 14. [Celeste Widget Integration](#celeste-widget-integration-optional)
20
+ 15. [License](#license)
21
+
22
+ ## Overview
23
+ - **Glassmorphism-first** visual language with layered depth, gradients, and scanlines.
24
+ - **Systemized tokens** (`src/css/variables.css`) for colors, typography, spacing, motion, and elevation.
25
+ - **Bootstrap-scale coverage** of components (navigation, forms, data display, API docs, Nikke-specific UI).
26
+ - **First-visit cinematic experiences** via `corrupted-text.js` and `corruption-loading.js`.
27
+ - **WCAG AA** compliance, motion safety, and keyboard support baked in.
28
+ - **Dockerized showcase** at `examples/showcase-complete.html` for instant QA.
29
+
30
+ ## Installation
31
+ ### npm (public registry)
32
+ ```bash
33
+ npm install @whykusanagi/corrupted-theme
34
+ ```
35
+ ```css
36
+ @import '@whykusanagi/corrupted-theme';
37
+ /* or scoped imports */
38
+ @import '@whykusanagi/corrupted-theme/variables';
39
+ @import '@whykusanagi/corrupted-theme/components';
40
+ ```
41
+ > Tip: make sure you are logged in with `npm login` if the package is private. No `.npmrc` token is needed for the public release.
42
+
43
+ ### CDN (when mirrored)
44
+ ```html
45
+ <link rel="stylesheet" href="https://s3.whykusanagi.xyz/corrupted-theme/theme.css">
46
+ ```
47
+
48
+ ### Manual Copy
49
+ Copy `src/css` into your project (or use `dist/theme.min.css`) and import it locally.
50
+
51
+ ## Project Architecture
52
+ ```
53
+ .
54
+ ├── src/
55
+ │ ├── css/
56
+ │ │ ├── variables.css # design tokens
57
+ │ │ ├── typography.css # font stack + hierarchy
58
+ │ │ ├── glassmorphism.css # shared glass utilities
59
+ │ │ ├── animations.css # motion + corruption keyframes
60
+ │ │ ├── components.css # UI primitives + layouts
61
+ │ │ ├── utilities.css # spacing, flex, layout utilities
62
+ │ │ └── theme.css # entry point (imports all modules)
63
+ │ └── lib/
64
+ │ ├── corrupted-text.js # multi-language glitch animation
65
+ │ └── corruption-loading.js# cinematic loading curtain
66
+ ├── dist/theme.min.css # postcss + cssnano build output
67
+ ├── examples/showcase-complete.html
68
+ ├── scripts/static-server.js # ESM static server (Docker)
69
+ └── docs/COMPONENTS_REFERENCE.md # exhaustive snippets
70
+ ```
71
+
72
+ **npm scripts**
73
+ - `npm run build` – compiles `dist/theme.min.css`
74
+ - `npm run watch` – rebuilds on change (dev use)
75
+ - `npm run dev:static` – serves `/examples` (port 8000)
76
+ - `npm run dev:proxy` – Celeste proxy (port 5000)
77
+
78
+ ## Base Layout & Background
79
+ ```html
80
+ <body>
81
+ <video class="background-media" autoplay muted loop playsinline>
82
+ <source src="/media/corruption-loop.mp4" type="video/mp4" />
83
+ </video>
84
+ <div class="glass-backdrop"></div>
85
+ <main class="app-shell"><!-- your glass UI --></main>
86
+ </body>
87
+ ```
88
+ ```css
89
+ html, body { min-height: 100vh; background: var(--bg); margin: 0; }
90
+ .background-media { position: fixed; inset: 0; object-fit: cover; z-index: -2; }
91
+ .glass-backdrop { position: fixed; inset: 0; background: linear-gradient(180deg, rgba(5,0,16,.85), rgba(10,10,10,.9)); z-index: -1; }
92
+ .app-shell { position: relative; z-index: 1; padding: clamp(1.5rem, 3vw, 3rem); backdrop-filter: blur(0); }
93
+ ```
94
+ Use `.app-shell` as the only stacking context above the backdrop so containers never block the video/image layer.
95
+
96
+ ## CSS & JS Imports
97
+ ```html
98
+ <link rel="stylesheet" href="@whykusanagi/corrupted-theme/dist/theme.min.css">
99
+ <script type="module" src="@whykusanagi/corrupted-theme/src/lib/corrupted-text.js"></script>
100
+ <script type="module" src="@whykusanagi/corrupted-theme/src/lib/corruption-loading.js"></script>
101
+ ```
102
+ ```js
103
+ import { initCorruptedText } from '@whykusanagi/corrupted-theme/src/lib/corrupted-text.js';
104
+ import { showCorruptionLoading } from '@whykusanagi/corrupted-theme/src/lib/corruption-loading.js';
105
+
106
+ document.addEventListener('DOMContentLoaded', () => {
107
+ initCorruptedText(); // re-init if you stream new DOM
108
+ // showCorruptionLoading({ force: true }); // force-run outside 72h cadence
109
+ });
110
+ ```
111
+
112
+ ## Component Quick Reference
113
+ The snippets below mirror the canonical showcase. For the full catalog (tabs, modals, tables, API docs, Nikke cards, etc.) keep `docs/COMPONENTS_REFERENCE.md` open beside this README.
114
+
115
+ ### Glass Kit
116
+ ```html
117
+ <div class="glass-card p-xl">
118
+ <h3>Glass Card</h3>
119
+ <p>Enhanced glass depth layer.</p>
120
+ <input class="glass-input" placeholder="glass input" />
121
+ <button class="glass-button">Primary Action</button>
122
+ <pre class="glass-code">const example = 'Hello';</pre>
123
+ </div>
124
+ ```
125
+
126
+ ### Buttons & Utilities
127
+ ```html
128
+ <div class="flex-center gap-md">
129
+ <button class="btn">Primary</button>
130
+ <button class="btn secondary">Secondary</button>
131
+ <button class="btn ghost">Ghost</button>
132
+ <button class="btn sm">Compact</button>
133
+ <button class="btn lg block">Full Width</button>
134
+ </div>
135
+ ```
136
+
137
+ ### Forms
138
+ ```html
139
+ <form class="glass-card p-xl">
140
+ <label>Name</label>
141
+ <input type="text" class="glass-input" required>
142
+ <label>Message</label>
143
+ <textarea class="glass-input" rows="3"></textarea>
144
+ <button class="glass-button">Send</button>
145
+ </form>
146
+ ```
147
+
148
+ ### Navigation
149
+ ```html
150
+ <nav class="navbar">
151
+ <div class="navbar-content">
152
+ <a class="navbar-logo" href="/">whyku</a>
153
+ <ul class="navbar-links">
154
+ <li><a href="#glass" class="active">Glass</a></li>
155
+ <li><a href="#components">Components</a></li>
156
+ <li class="has-submenu">
157
+ <a href="#products">Products <i class="fas fa-chevron-down"></i></a>
158
+ <div class="submenu">
159
+ <a href="#one">Product 1</a>
160
+ <a href="#two">Product 2</a>
161
+ </div>
162
+ </li>
163
+ </ul>
164
+ </div>
165
+ </nav>
166
+ <button class="navbar-toggle" onclick="toggleNavbar(this)">
167
+ <span class="icon"><span></span><span></span><span></span></span>
168
+ </button>
169
+ <ul class="navbar-links"><!-- mobile nav --></ul>
170
+ ```
171
+ ```js
172
+ function toggleNavbar(button) {
173
+ const menu = document.querySelector('.navbar-links');
174
+ menu.classList.toggle('active');
175
+ button.classList.toggle('active');
176
+ }
177
+ ```
178
+
179
+ ### Dropdown
180
+ ```html
181
+ <div class="dropdown">
182
+ <button class="dropdown-toggle" onclick="toggleDropdown(this)">Menu <i class="fas fa-chevron-down"></i></button>
183
+ <div class="dropdown-menu">
184
+ <a class="dropdown-item">Action</a>
185
+ <a class="dropdown-item">Settings</a>
186
+ <div class="dropdown-divider"></div>
187
+ <a class="dropdown-item">Logout</a>
188
+ </div>
189
+ </div>
190
+ ```
191
+ ```js
192
+ function toggleDropdown(button) {
193
+ const menu = button.nextElementSibling;
194
+ const open = menu.classList.contains('active');
195
+ document.querySelectorAll('.dropdown-menu').forEach(m => m.classList.remove('active'));
196
+ document.querySelectorAll('.dropdown-toggle').forEach(b => b.classList.remove('active'));
197
+ if (!open) {
198
+ menu.classList.add('active');
199
+ button.classList.add('active');
200
+ }
201
+ }
202
+ document.addEventListener('click', e => {
203
+ if (!e.target.closest('.dropdown')) {
204
+ document.querySelectorAll('.dropdown-menu').forEach(m => m.classList.remove('active'));
205
+ document.querySelectorAll('.dropdown-toggle').forEach(b => b.classList.remove('active'));
206
+ }
207
+ });
208
+ ```
209
+
210
+ ### Data & API
211
+ ```html
212
+ <table class="table table-striped">
213
+ <thead><tr><th>Name</th><th>Email</th><th>Status</th></tr></thead>
214
+ <tbody>
215
+ <tr><td>Eve</td><td>eve@demo.com</td><td><span class="badge success">Active</span></td></tr>
216
+ <tr><td>Dan</td><td>dan@demo.com</td><td><span class="badge warning">Pending</span></td></tr>
217
+ </tbody>
218
+ </table>
219
+
220
+ <div class="api-endpoint">
221
+ <div class="flex items-center gap-md">
222
+ <span class="api-method get">GET</span>
223
+ <code class="api-path">/api/v1/units</code>
224
+ </div>
225
+ <p class="api-description">Retrieve a list of units.</p>
226
+ <div class="api-param">
227
+ <span class="api-param-name">element</span>
228
+ <span class="api-param-type">string</span>
229
+ <span class="api-param-required">optional</span>
230
+ <p class="api-param-description">Filter by element type.</p>
231
+ </div>
232
+ <div class="api-response">
233
+ <div class="api-response-title">200 OK</div>
234
+ <pre class="api-response-code">{"data": []}</pre>
235
+ </div>
236
+ </div>
237
+ ```
238
+
239
+ ### Corrupted Text & Loader
240
+ ```html
241
+ <span class="corrupted-text" data-text="CORRUPTED">CORRUPTED</span>
242
+ <span class="glitch-kanji">
243
+ <span class="glitch-word" data-text="CORRUPTED TEXT">CORRUPTED TEXT</span>
244
+ </span>
245
+ ```
246
+ ```html
247
+ <video class="background-media" autoplay muted loop playsinline>
248
+ <source src="/media/corruption-loop.mp4" type="video/mp4" />
249
+ </video>
250
+ <script type="module" src="@whykusanagi/corrupted-theme/src/lib/corruption-loading.js"></script>
251
+ <script>
252
+ showCorruptionLoading(); // auto once every 72h
253
+ // showCorruptionLoading({ force: true });
254
+ </script>
255
+ ```
256
+ Japanese overlay text is sourced from the lewd phrase array inside `examples/showcase-complete.html`; supply your own by updating the data attribute or reusing the script snippet.
257
+
258
+ ## Animations & Experience Layer
259
+ Class | Behavior
260
+ --- | ---
261
+ `.fade-in`, `.fade-up`, `.slide-in-left/right`, `.scale-in` | Standard entrance motions synchronized to `var(--transition)`
262
+ `.glitch-word`, `.glitch-kanji` | Fragmented glitch with horizontal scanlines + JP overlays
263
+ `.corrupted-text`, `.corrupted-strong` | Brute-force corruption effect for headings and pills
264
+ `.scanlines`, `.tear`, `.data-corrupt` | Utility effects inspired by whykusanagi.xyz hero
265
+ `.spinner`, `.loading-bar`, `.progress-bar` | Loading indicators with shimmer + accent variants
266
+ `.corruption-loading` (JS) | Full-screen loader with 72h replay timer
267
+ `.corrupted-multilang` (JS) | First-visit Japanese/English/Romaji cycling text
268
+
269
+ ## Nikke Utilities
270
+ ```html
271
+ <div class="element-pills">
272
+ <button class="element-pill water">Water</button>
273
+ <button class="element-pill wind active">Wind</button>
274
+ <button class="element-pill iron">Iron</button>
275
+ <button class="element-pill electric">Electric</button>
276
+ <button class="element-pill fire">Fire</button>
277
+ </div>
278
+ <div class="team-position-cards">
279
+ <div class="position-card filled">
280
+ <div class="position-header">
281
+ <span class="position-number">1</span>
282
+ <span class="position-label">Front Left</span>
283
+ </div>
284
+ <div class="position-content">
285
+ <div class="unit-display">
286
+ <div class="unit-name">Scarlet Priest Abe</div>
287
+ </div>
288
+ <button class="remove-unit" aria-label="Remove unit">×</button>
289
+ </div>
290
+ </div>
291
+ </div>
292
+ ```
293
+ All Nikke-specific helpers live alongside the main utilities (`src/css/nikke-utilities.css`) and observe the same token set, so there are no visual disconnects between game-specific and general UI.
294
+
295
+ ## Customization & Tokens
296
+ Override only the tokens you need. The defaults intentionally mirror the showcase.
297
+ ```css
298
+ :root {
299
+ --accent: #ff5fb0;
300
+ --accent-light: #ff8cd0;
301
+ --accent-dark: #c71c7d;
302
+ --glass: rgba(15, 10, 25, 0.65);
303
+ --glass-light: rgba(24, 14, 42, 0.45);
304
+ --glass-darker: rgba(10, 5, 20, 0.65);
305
+ --text: #f4e9ff;
306
+ --text-secondary: #b8afc8;
307
+ --transition-normal: 0.3s ease;
308
+ --transition-fast: 0.15s ease;
309
+ }
310
+ ```
311
+ Utilities (`src/css/utilities.css`) provide spacing (`.p-xl`, `.gap-md`), layout (`.flex`, `.grid`), and elevation helpers so you rarely write bespoke CSS.
312
+
313
+ ## Coding Standards
314
+ These guidelines keep contributions aligned with enterprise frameworks:
315
+ - **CSS architecture**: component classes are flat (`.btn.secondary`), tokens live in `variables.css`, and utilities never override component styles.
316
+ - **Naming**: prefer descriptive nouns (e.g., `.api-endpoint`, `.glass-card`) and suffix modifiers with dot notation (`.btn.secondary`). Avoid chained hyphen variants unless the base class does not apply (`.badge-method`).
317
+ - **JavaScript**: all helper scripts are ES modules, side-effect-free, and expose initialization functions. Never mutate global scope outside a guarded `DOMContentLoaded` block.
318
+ - **Accessibility**: every interactive component includes focus styles, ARIA labels where relevant, and respects `prefers-reduced-motion` fallbacks.
319
+ - **Performance**: animations use `transform`/`opacity`, heavy filters are scoped to small elements, and layout thrashers are avoided.
320
+ - **Documentation**: README + `docs/COMPONENTS_REFERENCE.md` are the single sources of truth. Additions must include runnable snippets and token usage notes.
321
+ - **Versioning**: update `CHANGELOG.md` with semantic sections (`Added`, `Changed`, `Fixed`) before publishing.
322
+
323
+ ## Development Workflow
324
+ ```bash
325
+ npm install # install dependencies
326
+ npm run build # compile CSS bundle
327
+ npm run watch # dev rebuild loop
328
+ npm run dev:static # serve /examples on :8000
329
+ npm run dev:proxy # optional Celeste proxy on :5000
330
+
331
+ # Docker showcase
332
+ docker build -t corrupted-theme:latest .
333
+ docker run -d -p 8000:8000 --name corrupted-theme corrupted-theme:latest
334
+ ```
335
+ - The Docker container automatically serves `examples/showcase-complete.html`.
336
+ - Provide `CELESTE_*` env vars to exercise the widget proxy inside the same container.
337
+
338
+ ## Testing & QA Expectations
339
+ - **Visual regression**: validate against `examples/showcase-complete.html` in latest Chrome, Firefox, Safari, and a mobile viewport.
340
+ - **Accessibility**: run `tab` sweeps, screen reader spot checks, and `prefers-reduced-motion` toggles.
341
+ - **Performance**: Lighthouse performance budget ≥ 90, no long-running animations on background threads.
342
+ - **Animation review**: ensure the first-visit corrupted text + loader remain opt-in via JS flags for SPA integrations.
343
+
344
+ ## Support
345
+ - GitHub Issues: [corrupted-theme/issues](https://github.com/whykusanagi/corrupted-theme/issues)
346
+ - Email: contact@whykusanagi.xyz
347
+
348
+ ## Celeste Widget Integration (Secure Proxy)
349
+ The theme ships with an optional Celeste AI widget that **never exposes credentials to the browser**. It relies on the hardened proxy bundle located in `celeste_widget_pack/`.
350
+
351
+ ### Environment Variables (required)
352
+ | Variable | Purpose |
353
+ |----------|---------|
354
+ | `CELESTE_AGENT_KEY` | Bearer token for the Celeste API |
355
+ | `CELESTE_AGENT_ID` | Agent identifier (UUID) |
356
+ | `CELESTE_AGENT_BASE_URL` | API endpoint root |
357
+
358
+ > Store these via your platform’s secret manager (Vault, Doppler, AWS Secrets Manager, etc.). Never commit them or inject them into client-side code.
359
+
360
+ ### Docker Workflow
361
+ ```bash
362
+ docker build -t corrupted-theme:latest .
363
+
364
+ docker run -d \
365
+ -p 8000:8000 \ # static showcase
366
+ -p 5001:5000 \ # exposes proxy externally
367
+ -e CELESTE_AGENT_KEY="$CELESTE_AGENT_KEY" \
368
+ -e CELESTE_AGENT_ID="$CELESTE_AGENT_ID" \
369
+ -e CELESTE_AGENT_BASE_URL="https://api.your-domain.com" \
370
+ corrupted-theme:latest
371
+
372
+ # Visit http://localhost:8000 (UI) and http://localhost:5001/api/health (proxy)
373
+ ```
374
+
375
+ ### Local Development (split processes)
376
+ ```bash
377
+ # Terminal 1 – proxy server (port defaults to 5000 inside container)
378
+ CELESTE_AGENT_KEY="..." \
379
+ CELESTE_AGENT_ID="..." \
380
+ CELESTE_AGENT_BASE_URL="..." \
381
+ PROXY_PORT=5000 node scripts/celeste-proxy-server.js
382
+
383
+ # Terminal 2 – static showcase
384
+ STATIC_PORT=8000 node scripts/static-server.js
385
+ ```
386
+
387
+ ### Security Guarantees
388
+ - Browser never receives `CELESTE_*` variables (verified via DevTools/HTML scans)
389
+ - All outbound API calls originate from the proxy (`/api/chat`, `/api/health`)
390
+ - Health endpoint surfaces status without leaking secrets
391
+ - Ready for Cloudflare Worker / Pages deployment (see secure pack doc)
392
+
393
+ For the full hardening guide—including architecture diagrams, Cloudflare steps, and troubleshooting—see `celeste_widget_pack/docs/CELESTE_WIDGET_SECURE_SETUP.md`.
394
+
395
+ ## License
396
+ MIT © whykusanagi
397
+
398
+ ---
399
+ Made with 💎 by [whykusanagi](https://whykusanagi.xyz)
@@ -0,0 +1,48 @@
1
+ #!/bin/bash
2
+ # Docker entrypoint script for whykusanagi.xyz
3
+ # Starts the Celeste API proxy and static file server (both in Node.js)
4
+
5
+ set -e
6
+
7
+ echo "[Docker] Starting whykusanagi.xyz site"
8
+
9
+ # Check if Celeste environment variables are provided
10
+ if [ -z "$CELESTE_AGENT_KEY" ] || [ -z "$CELESTE_AGENT_ID" ] || [ -z "$CELESTE_AGENT_BASE_URL" ]; then
11
+ echo "[Celeste] ⚠️ Warning: One or more required environment variables are missing!"
12
+ echo "[Celeste] Required: CELESTE_AGENT_KEY, CELESTE_AGENT_ID, CELESTE_AGENT_BASE_URL"
13
+ echo "[Celeste] The Celeste widget API proxy will not start, but static site will serve."
14
+ echo "[Celeste] To enable the widget, provide these environment variables."
15
+
16
+ # Start only HTTP server (no widget API)
17
+ echo "[Docker] Starting static file server on http://0.0.0.0:8000"
18
+ exec node scripts/static-server.js
19
+ else
20
+ echo "[Celeste] ✅ Configuration validated"
21
+ echo "[Celeste] Agent ID: ${CELESTE_AGENT_ID:0:8}..."
22
+ echo "[Celeste] Base URL: ${CELESTE_AGENT_BASE_URL}"
23
+
24
+ # Start the API proxy in the background
25
+ echo "[Docker] Starting Celeste API proxy on http://0.0.0.0:5000"
26
+ PROXY_PORT=5000 STATIC_PORT=8000 node scripts/celeste-proxy-server.js &
27
+ PROXY_PID=$!
28
+
29
+ # Give proxy time to start
30
+ sleep 2
31
+
32
+ # Check if proxy started successfully
33
+ if ! kill -0 $PROXY_PID 2>/dev/null; then
34
+ echo "[Docker] ❌ Failed to start Celeste API proxy"
35
+ exit 1
36
+ fi
37
+
38
+ echo "[Docker] ✅ Celeste API proxy started (PID: $PROXY_PID)"
39
+
40
+ # Start the static file server in foreground
41
+ echo "[Docker] Starting static file server on http://0.0.0.0:8000"
42
+
43
+ # Trap signals to clean up proxy when container stops
44
+ trap "kill $PROXY_PID 2>/dev/null || true" EXIT INT TERM
45
+
46
+ # Serve static files
47
+ exec node scripts/static-server.js
48
+ fi