@whykusanagi/corrupted-theme 0.1.6 → 0.1.8

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/CHANGELOG.md CHANGED
@@ -14,6 +14,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
 
15
15
  ---
16
16
 
17
+ ## [0.1.7] - 2026-02-07
18
+
19
+ ### Security
20
+ - **XSS hardening in celeste-widget.js** - `addMessage()` now uses `textContent` via safe DOM construction instead of `innerHTML` interpolation
21
+ - **HTML injection fix in countdown-widget.js** - `config.popup.message` now rendered with `textContent` instead of `innerHTML`
22
+ - **XSS hardening in components.js** - `showToast()` rebuilt with safe DOM methods (`createElement`/`textContent`) instead of `innerHTML` template
23
+
24
+ ### Added
25
+ - **Lifecycle utilities** - New `TimerRegistry` and `EventTracker` classes (`src/core/`) for consistent timer/listener cleanup across all components
26
+ - **Modal JS** - `ModalManager` with open/close, overlay click-to-close, Escape key, body scroll lock, and `modal:open`/`modal:close` custom events
27
+ - **Dropdown JS** - `DropdownManager` with toggle behavior and click-outside-to-close
28
+ - **Tab JS** - `TabManager` with panel switching via `data-ct-target` attributes
29
+ - **Collapse auto-init** - Existing `toggleCollapse()` wired to `data-ct-toggle="collapse"` data attributes
30
+ - **Carousel component** - New `src/lib/carousel.js` with autoplay, prev/next controls, dot indicators, touch/swipe, keyboard navigation, and pause on hover. CSS added to `components.css`
31
+ - **Unified auto-init** - All interactive components auto-initialize via `data-ct-*` attributes on DOMContentLoaded
32
+ - **`destroyComponents()`** - Tears down all component managers (modal, dropdown, tab, toast) at once
33
+ - **`destroyAllAutoCorruption()`** - Stops all active character corruption intervals
34
+ - **Multi-gallery example** - `examples/basic/multi-gallery.html` demonstrates two independent galleries
35
+ - **Interactive components example** - `examples/interactive-components.html` demonstrates Modal, Dropdown, Tabs, Collapse, Accordion, Carousel, and Toast
36
+ - **`"./carousel"` package export** - Carousel available via `@whykusanagi/corrupted-theme/carousel`
37
+
38
+ ### Fixed
39
+ - **Memory leak: celeste-widget.js** - Added `destroy()` method, tracked all event listeners, popstate handler now calls `updateContext()` instead of re-initializing
40
+ - **Memory leak: gallery.js** - Refactored from singleton to `Gallery` class with per-instance `EventTracker` and `TimerRegistry`. Each instance gets a unique lightbox. `destroy()` removes all listeners and DOM
41
+ - **Memory leak: corruption-loading.js** - All `setTimeout`/`setInterval` calls tracked; added `cancelLoading()` to stop mid-animation
42
+ - **Memory leak: corrupted-text.js** - Tracked `_startDelayId`, `_animateTimeoutId`, `_corruptTimeoutId`; added `destroy()` method
43
+ - **Memory leak: components.js** - Toast auto-dismiss timeout stored on element, cleared on early dismiss; added `destroy()` to `ToastManager`
44
+ - **Memory leak: character-corruption.js** - Replaced unreliable `dataset` string storage with `WeakMap` for interval ID tracking
45
+ - **Memory leak: countdown-widget.js** - Popup `setTimeout` calls tracked in state, cleared in `destroyCountdown()`
46
+
47
+ ### Changed
48
+ - **Dev dependency updates** - Updated `cssnano` ^6 to ^7, `postcss-cli` ^10 to ^11
49
+ - **Node.js engine requirement** - Bumped minimum from >=14.0.0 to >=18.0.0
50
+ - **Gallery multi-instance** - `initGallery()` now returns a `Gallery` instance; backward-compatible `destroyGallery()` still works for default instance
51
+ - **COMPONENTS_REFERENCE.md** - Updated Interactive Components section with `data-ct-*` usage, added Carousel and Lifecycle Management sections
52
+
53
+ ---
54
+
17
55
  ## [0.1.6] - 2026-01-16
18
56
 
19
57
  ### Changed
package/README.md CHANGED
@@ -9,16 +9,18 @@ A production-ready glassmorphic design system for cinematic, cyberpunk-inspired
9
9
  4. [Base Layout & Background](#base-layout--background)
10
10
  5. [CSS & JS Imports](#css--js-imports)
11
11
  6. [Component Quick Reference](#component-quick-reference)
12
- 7. [Animations & Experience Layer](#animations--experience-layer)
13
- 8. [Nikke Utilities](#nikke-utilities)
14
- 9. [Extension Components](#extension-components)
15
- 10. [Customization & Tokens](#customization--tokens)
16
- 11. [Coding Standards](#coding-standards)
17
- 12. [Development Workflow](#development-workflow)
18
- 13. [Testing & QA Expectations](#testing--qa-expectations)
19
- 14. [Support](#support)
20
- 15. [Celeste Widget Integration](#celeste-widget-integration-optional)
21
- 16. [License](#license)
12
+ 7. [Interactive Components](#interactive-components)
13
+ 8. [Animations & Experience Layer](#animations--experience-layer)
14
+ 9. [Lifecycle Management](#lifecycle-management)
15
+ 10. [Nikke Utilities](#nikke-utilities)
16
+ 11. [Extension Components](#extension-components)
17
+ 12. [Customization & Tokens](#customization--tokens)
18
+ 13. [Coding Standards](#coding-standards)
19
+ 14. [Development Workflow](#development-workflow)
20
+ 15. [Testing & QA Expectations](#testing--qa-expectations)
21
+ 16. [Support](#support)
22
+ 17. [Celeste Widget Integration](#celeste-widget-integration-optional)
23
+ 18. [License](#license)
22
24
 
23
25
  <div align="center" style="margin: 2rem 0;">
24
26
 
@@ -82,20 +84,30 @@ Copy `src/css` into your project (or use `dist/theme.min.css`) and import it loc
82
84
  .
83
85
  ├── src/
84
86
  │ ├── css/
85
- │ │ ├── variables.css # design tokens
86
- │ │ ├── typography.css # font stack + hierarchy
87
- │ │ ├── glassmorphism.css # shared glass utilities
88
- │ │ ├── animations.css # motion + corruption keyframes
89
- │ │ ├── components.css # UI primitives + layouts
90
- │ │ ├── utilities.css # spacing, flex, layout utilities
91
- │ │ └── theme.css # entry point (imports all modules)
87
+ │ │ ├── variables.css # design tokens
88
+ │ │ ├── typography.css # font stack + hierarchy
89
+ │ │ ├── glassmorphism.css # shared glass utilities
90
+ │ │ ├── animations.css # motion + corruption keyframes
91
+ │ │ ├── components.css # UI primitives + layouts (incl. carousel)
92
+ │ │ ├── utilities.css # spacing, flex, layout utilities
93
+ │ │ └── theme.css # entry point (imports all modules)
94
+ │ ├── core/
95
+ │ │ ├── timer-registry.js # lifecycle: tracked setTimeout/setInterval/rAF
96
+ │ │ └── event-tracker.js # lifecycle: tracked addEventListener
92
97
  │ └── lib/
93
- │ ├── corrupted-text.js # multi-language glitch animation
94
- └── corruption-loading.js# cinematic loading curtain
95
- ├── dist/theme.min.css # postcss + cssnano build output
96
- ├── examples/showcase-complete.html
97
- ├── scripts/static-server.js # ESM static server (Docker)
98
- └── docs/COMPONENTS_REFERENCE.md # exhaustive snippets
98
+ │ ├── carousel.js # carousel/slideshow with autoplay + swipe
99
+ ├── character-corruption.js# auto-corruption for individual characters
100
+ ├── components.js # modal, dropdown, tabs, collapse, accordion, toast
101
+ ├── corrupted-text.js # multi-language glitch animation
102
+ ├── corruption-loading.js # cinematic loading curtain
103
+ │ ├── countdown-widget.js # event countdown with shapes
104
+ │ └── gallery.js # gallery grid with filtering + lightbox
105
+ ├── dist/theme.min.css # postcss + cssnano build output
106
+ ├── examples/
107
+ │ ├── showcase-complete.html # full design system demo
108
+ │ └── interactive-components.html # modal, dropdown, tabs, carousel demo
109
+ ├── scripts/static-server.js # ESM static server (Docker)
110
+ └── docs/COMPONENTS_REFERENCE.md # exhaustive snippets
99
111
  ```
100
112
 
101
113
  **npm scripts**
@@ -232,21 +244,25 @@ Import only the modules you need for smaller bundle sizes.
232
244
 
233
245
  ### JavaScript Imports
234
246
 
235
- ```html
236
- <!-- HTML -->
237
- <script type="module" src="@whykusanagi/corrupted-theme/src/lib/corrupted-text.js"></script>
238
- <script type="module" src="@whykusanagi/corrupted-theme/src/lib/corruption-loading.js"></script>
247
+ ```js
248
+ // Interactive components (modal, dropdown, tabs, collapse, accordion, toast)
249
+ import { initComponents, destroyComponents, showToast, toast }
250
+ from '@whykusanagi/corrupted-theme/components-js';
251
+
252
+ // Carousel (separate module)
253
+ import { initCarousel } from '@whykusanagi/corrupted-theme/carousel';
254
+
255
+ // Corruption effects
256
+ import { initCorruptedText } from '@whykusanagi/corrupted-theme/corrupted-text';
257
+ import { initGallery, destroyGallery } from '@whykusanagi/corrupted-theme/gallery';
258
+ import { initCountdown } from '@whykusanagi/corrupted-theme/countdown';
239
259
  ```
240
260
 
241
- ```js
242
- // ES Modules
243
- import { initCorruptedText } from '@whykusanagi/corrupted-theme/src/lib/corrupted-text.js';
244
- import { showCorruptionLoading } from '@whykusanagi/corrupted-theme/src/lib/corruption-loading.js';
261
+ Components auto-initialize on `DOMContentLoaded` when imported. For manual control:
245
262
 
246
- document.addEventListener('DOMContentLoaded', () => {
247
- initCorruptedText(); // Initialize glitch text effects
248
- // showCorruptionLoading({ force: true }); // Force loader outside 72h cadence
249
- });
263
+ ```js
264
+ initComponents(); // scan DOM for data-ct-* attributes
265
+ destroyComponents(); // tear down all managers and tracked listeners
250
266
  ```
251
267
 
252
268
  ## Component Quick Reference
@@ -317,9 +333,11 @@ function toggleNavbar(button) {
317
333
  ```
318
334
 
319
335
  ### Dropdown
336
+
337
+ **Zero-JS (data attributes):**
320
338
  ```html
321
339
  <div class="dropdown">
322
- <button class="dropdown-toggle" onclick="toggleDropdown(this)">Menu <i class="fas fa-chevron-down"></i></button>
340
+ <button class="dropdown-toggle" data-ct-toggle="dropdown">Menu</button>
323
341
  <div class="dropdown-menu">
324
342
  <a class="dropdown-item">Action</a>
325
343
  <a class="dropdown-item">Settings</a>
@@ -328,16 +346,23 @@ function toggleNavbar(button) {
328
346
  </div>
329
347
  </div>
330
348
  ```
349
+
350
+ **Manual JS (legacy):**
351
+ ```html
352
+ <div class="dropdown">
353
+ <button class="dropdown-toggle" onclick="toggleDropdown(this)">Menu</button>
354
+ <div class="dropdown-menu">
355
+ <a class="dropdown-item">Action</a>
356
+ </div>
357
+ </div>
358
+ ```
331
359
  ```js
332
360
  function toggleDropdown(button) {
333
361
  const menu = button.nextElementSibling;
334
362
  const open = menu.classList.contains('active');
335
363
  document.querySelectorAll('.dropdown-menu').forEach(m => m.classList.remove('active'));
336
364
  document.querySelectorAll('.dropdown-toggle').forEach(b => b.classList.remove('active'));
337
- if (!open) {
338
- menu.classList.add('active');
339
- button.classList.add('active');
340
- }
365
+ if (!open) { menu.classList.add('active'); button.classList.add('active'); }
341
366
  }
342
367
  document.addEventListener('click', e => {
343
368
  if (!e.target.closest('.dropdown')) {
@@ -416,6 +441,105 @@ typing.start('Neural corruption detected... System Online');
416
441
 
417
442
  See `examples/basic/` for SFW examples and `examples/advanced/nsfw-corruption.html` for NSFW demo.
418
443
 
444
+ ## Interactive Components
445
+
446
+ v0.1.8 adds JS-driven interactive components that self-initialize via `data-ct-*` attributes. Import the components module and everything wires up automatically on `DOMContentLoaded`.
447
+
448
+ ```html
449
+ <script type="module">
450
+ import '@whykusanagi/corrupted-theme/components-js';
451
+ import { initCarousel } from '@whykusanagi/corrupted-theme/carousel';
452
+ </script>
453
+ ```
454
+
455
+ ### Modal
456
+
457
+ ```html
458
+ <button class="btn" data-ct-toggle="modal" data-ct-target="#my-modal">Open</button>
459
+
460
+ <div class="modal-overlay" id="my-modal">
461
+ <div class="modal">
462
+ <div class="modal-header">
463
+ <h3 class="modal-title">Title</h3>
464
+ <button class="modal-close">&times;</button>
465
+ </div>
466
+ <div class="modal-body"><p>Content here.</p></div>
467
+ <div class="modal-footer">
468
+ <button class="btn secondary" data-ct-toggle="modal" data-ct-target="#my-modal">Cancel</button>
469
+ <button class="btn" data-ct-toggle="modal" data-ct-target="#my-modal">Confirm</button>
470
+ </div>
471
+ </div>
472
+ </div>
473
+ ```
474
+
475
+ Closes via X button, overlay click, or Escape key. Dispatches `modal:open` / `modal:close` custom events.
476
+
477
+ ### Tabs
478
+
479
+ ```html
480
+ <div class="tabs">
481
+ <button class="tab active" data-ct-target="#panel-1">Tab 1</button>
482
+ <button class="tab" data-ct-target="#panel-2">Tab 2</button>
483
+ </div>
484
+ <div class="tab-content active" id="panel-1">Panel 1 content</div>
485
+ <div class="tab-content" id="panel-2">Panel 2 content</div>
486
+ ```
487
+
488
+ ### Collapse
489
+
490
+ ```html
491
+ <button class="btn" data-ct-toggle="collapse" data-ct-target="#details">Toggle</button>
492
+ <div class="collapse" id="details">
493
+ <p>Collapsible content.</p>
494
+ </div>
495
+ ```
496
+
497
+ ### Carousel
498
+
499
+ ```html
500
+ <div class="carousel" data-ct-autoplay data-ct-interval="4000">
501
+ <div class="carousel-inner">
502
+ <div class="carousel-slide active">Slide 1</div>
503
+ <div class="carousel-slide">Slide 2</div>
504
+ <div class="carousel-slide">Slide 3</div>
505
+ </div>
506
+ </div>
507
+ ```
508
+
509
+ Features: autoplay, prev/next controls, dot indicators, touch/swipe, keyboard navigation (ArrowLeft/Right). Import separately:
510
+
511
+ ```js
512
+ import { initCarousel } from '@whykusanagi/corrupted-theme/carousel';
513
+ ```
514
+
515
+ ### Accordion
516
+
517
+ ```html
518
+ <div class="accordion">
519
+ <div class="accordion-item active">
520
+ <div class="accordion-header">Question 1</div>
521
+ <div class="accordion-body"><p>Answer 1</p></div>
522
+ </div>
523
+ <div class="accordion-item">
524
+ <div class="accordion-header">Question 2</div>
525
+ <div class="accordion-body"><p>Answer 2</p></div>
526
+ </div>
527
+ </div>
528
+ ```
529
+
530
+ ### Toast Notifications
531
+
532
+ ```js
533
+ import { toast } from '@whykusanagi/corrupted-theme/components-js';
534
+
535
+ toast.success('Operation completed.');
536
+ toast.warning('Check your input.');
537
+ toast.error('Something went wrong.');
538
+ toast.info('FYI: update available.');
539
+ ```
540
+
541
+ See `examples/interactive-components.html` for a live demo of all interactive components.
542
+
419
543
  ## Animations & Experience Layer
420
544
 
421
545
  ### Standard CSS Animations
@@ -448,6 +572,46 @@ Class | Behavior
448
572
  - Helper functions for random phrase selection
449
573
  - Module: `src/core/corruption-phrases.js`
450
574
 
575
+ ## Lifecycle Management
576
+
577
+ All JS components follow a consistent init/destroy pattern to prevent memory leaks in SPAs and dynamic UIs.
578
+
579
+ ### Destroying Components
580
+
581
+ ```js
582
+ import { destroyComponents } from '@whykusanagi/corrupted-theme/components-js';
583
+ import { destroyGallery } from '@whykusanagi/corrupted-theme/gallery';
584
+
585
+ // Tear down all interactive components (modal, dropdown, tabs, accordion, toast)
586
+ destroyComponents();
587
+
588
+ // Destroy default gallery instance
589
+ destroyGallery();
590
+ ```
591
+
592
+ ### Multi-Instance Gallery
593
+
594
+ ```js
595
+ import { initGallery } from '@whykusanagi/corrupted-theme/gallery';
596
+
597
+ const g1 = initGallery('#gallery-1', { enableLightbox: true });
598
+ const g2 = initGallery('#gallery-2', { enableLightbox: true });
599
+
600
+ // Each instance has independent filters, lightbox, and state
601
+ g1.destroy(); // only tears down gallery-1
602
+ ```
603
+
604
+ See `examples/basic/multi-gallery.html` for a working multi-instance demo.
605
+
606
+ ### Core Utilities
607
+
608
+ The `src/core/` directory provides lifecycle primitives used by all components:
609
+
610
+ - **TimerRegistry** (`timer-registry.js`) — wraps `setTimeout`, `setInterval`, and `requestAnimationFrame` with bulk `clearAll()`
611
+ - **EventTracker** (`event-tracker.js`) — wraps `addEventListener` with bulk `removeAll()`
612
+
613
+ These ensure no orphaned timers or listeners remain after `destroy()`.
614
+
451
615
  ## Nikke Utilities
452
616
  ```html
453
617
  <div class="element-pills">
@@ -480,7 +644,7 @@ Production-tested components from whykusanagi.xyz for galleries, social links, c
480
644
 
481
645
  ### Gallery System
482
646
 
483
- Responsive gallery grid with filtering, lightbox, and NSFW content support.
647
+ Responsive gallery grid with filtering, lightbox, and NSFW content support. Supports multiple independent instances on the same page.
484
648
 
485
649
  ```html
486
650
  <div class="filter-bar">
@@ -497,7 +661,7 @@ Responsive gallery grid with filtering, lightbox, and NSFW content support.
497
661
  ```
498
662
 
499
663
  ```javascript
500
- import { initGallery } from '@whykusanagi/corrupted-theme/gallery';
664
+ import { initGallery, destroyGallery } from '@whykusanagi/corrupted-theme/gallery';
501
665
 
502
666
  const gallery = initGallery('#my-gallery', {
503
667
  enableLightbox: true,
@@ -507,6 +671,7 @@ const gallery = initGallery('#my-gallery', {
507
671
 
508
672
  gallery.filter('photos'); // Filter by category
509
673
  gallery.openLightbox(0); // Open first image
674
+ gallery.destroy(); // Clean up (removes lightbox, listeners, timers)
510
675
  ```
511
676
 
512
677
  ### Social Links List
@@ -12,17 +12,19 @@ This document provides a comprehensive reference for all components available in
12
12
  1. [Glass Components](#glass-components)
13
13
  2. [Standard Components](#standard-components)
14
14
  3. [Interactive Components](#interactive-components)
15
- 4. [Data Display](#data-display)
16
- 5. [Navigation](#navigation)
17
- 6. [API Documentation](#api-documentation)
18
- 7. [Nikke Components](#nikke-components)
19
- 8. [Background & Images](#background--images)
20
- 9. [Extension Components](#extension-components)
21
- - [Gallery System](#gallery-system)
22
- - [Lightbox](#lightbox)
23
- - [NSFW Content Blur](#nsfw-content-blur)
24
- - [Social Links List](#social-links-list)
25
- - [Countdown Widget](#countdown-widget)
15
+ - [Modals](#modals) | [Tooltips](#tooltips) | [Dropdowns](#dropdowns) | [Tabs](#tabs) | [Collapse](#collapse) | [Carousel](#carousel)
16
+ 4. [Lifecycle Management](#lifecycle-management)
17
+ 5. [Data Display](#data-display)
18
+ 6. [Navigation](#navigation)
19
+ 7. [API Documentation](#api-documentation)
20
+ 8. [Nikke Components](#nikke-components)
21
+ 9. [Background & Images](#background--images)
22
+ 10. [Extension Components](#extension-components)
23
+ - [Gallery System](#gallery-system)
24
+ - [Lightbox](#lightbox)
25
+ - [NSFW Content Blur](#nsfw-content-blur)
26
+ - [Social Links List](#social-links-list)
27
+ - [Countdown Widget](#countdown-widget)
26
28
 
27
29
  ---
28
30
 
@@ -155,41 +157,47 @@ Code block display component.
155
157
 
156
158
  ## Interactive Components
157
159
 
160
+ All interactive components support **data-attribute initialization** via `data-ct-*` attributes and **programmatic control** via JS imports. Import the components module:
161
+
162
+ ```javascript
163
+ import { openModal, closeModal, destroyComponents } from '@whykusanagi/corrupted-theme/components-js';
164
+ ```
165
+
158
166
  ### Modals
159
167
 
160
168
  ```html
161
- <!-- Trigger Button -->
162
- <button class="btn" onclick="openModal('my-modal')">Open Modal</button>
169
+ <!-- Trigger via data attribute -->
170
+ <button class="btn" data-ct-toggle="modal" data-ct-target="#my-modal">Open Modal</button>
163
171
 
164
- <!-- Modal -->
172
+ <!-- Modal overlay -->
165
173
  <div class="modal-overlay" id="my-modal">
166
174
  <div class="modal">
167
175
  <div class="modal-header">
168
176
  <h3 class="modal-title">Modal Title</h3>
169
- <button class="modal-close" onclick="closeModal('my-modal')">&times;</button>
177
+ <button class="modal-close">&times;</button>
170
178
  </div>
171
179
  <div class="modal-body">
172
180
  <p>Modal content goes here</p>
173
181
  </div>
174
182
  <div class="modal-footer">
175
- <button class="btn secondary" onclick="closeModal('my-modal')">Cancel</button>
176
- <button class="btn" onclick="closeModal('my-modal')">Confirm</button>
183
+ <button class="btn secondary" data-ct-toggle="modal" data-ct-target="#my-modal">Cancel</button>
184
+ <button class="btn">Confirm</button>
177
185
  </div>
178
186
  </div>
179
187
  </div>
180
188
  ```
181
189
 
182
- **JavaScript:**
183
- ```javascript
184
- function openModal(id) {
185
- document.getElementById(id).classList.add('active');
186
- document.body.style.overflow = 'hidden';
187
- }
190
+ **Features:**
191
+ - Close button (`.modal-close`) auto-wired
192
+ - Click overlay background to close
193
+ - Escape key closes active modals
194
+ - Body scroll lock while open
195
+ - Custom events: `modal:open`, `modal:close`
188
196
 
189
- function closeModal(id) {
190
- document.getElementById(id).classList.remove('active');
191
- document.body.style.overflow = '';
192
- }
197
+ **Programmatic API:**
198
+ ```javascript
199
+ openModal('#my-modal');
200
+ closeModal('#my-modal');
193
201
  ```
194
202
 
195
203
  ### Tooltips
@@ -210,8 +218,8 @@ function closeModal(id) {
210
218
 
211
219
  ```html
212
220
  <div class="dropdown">
213
- <button class="dropdown-toggle" onclick="toggleDropdown(this)">
214
- Dropdown <i class="fas fa-chevron-down"></i>
221
+ <button class="dropdown-toggle" data-ct-toggle="dropdown">
222
+ Dropdown
215
223
  </button>
216
224
  <div class="dropdown-menu">
217
225
  <a href="#" class="dropdown-item">Action 1</a>
@@ -222,16 +230,115 @@ function closeModal(id) {
222
230
  </div>
223
231
  ```
224
232
 
233
+ **Features:**
234
+ - Click toggle to open/close
235
+ - Click outside to close
236
+ - Multiple dropdowns don't conflict
237
+
225
238
  ### Tabs
226
239
 
227
240
  ```html
228
241
  <div class="tabs">
229
- <button class="tab active" onclick="switchTab(this, 'tab-1')">Tab 1</button>
230
- <button class="tab" onclick="switchTab(this, 'tab-2')">Tab 2</button>
242
+ <button class="tab active" data-ct-target="#panel-1">Tab 1</button>
243
+ <button class="tab" data-ct-target="#panel-2">Tab 2</button>
244
+ </div>
245
+
246
+ <div id="panel-1" class="tab-content active">Tab 1 content</div>
247
+ <div id="panel-2" class="tab-content">Tab 2 content</div>
248
+ ```
249
+
250
+ ### Collapse
251
+
252
+ ```html
253
+ <button class="btn" data-ct-toggle="collapse" data-ct-target="#details">
254
+ Toggle Details
255
+ </button>
256
+ <div class="collapse" id="details">
257
+ <p>Collapsible content here.</p>
231
258
  </div>
259
+ ```
260
+
261
+ ### Carousel
262
+
263
+ ```html
264
+ <div class="carousel" data-ct-autoplay data-ct-interval="5000">
265
+ <div class="carousel-inner">
266
+ <div class="carousel-slide active">
267
+ <img src="slide1.jpg" alt="Slide 1">
268
+ </div>
269
+ <div class="carousel-slide">
270
+ <img src="slide2.jpg" alt="Slide 2">
271
+ </div>
272
+ <div class="carousel-slide">
273
+ <img src="slide3.jpg" alt="Slide 3">
274
+ </div>
275
+ </div>
276
+ </div>
277
+ ```
278
+
279
+ **Programmatic API:**
280
+ ```javascript
281
+ import { initCarousel } from '@whykusanagi/corrupted-theme/carousel';
282
+
283
+ const carousel = initCarousel('.carousel', {
284
+ autoplay: true,
285
+ interval: 5000,
286
+ indicators: true,
287
+ controls: true,
288
+ keyboard: true,
289
+ touch: true,
290
+ pauseOnHover: true
291
+ });
292
+
293
+ carousel.next();
294
+ carousel.prev();
295
+ carousel.goTo(2);
296
+ carousel.destroy();
297
+ ```
298
+
299
+ **Features:**
300
+ - Autoplay with pause on hover
301
+ - Prev/next controls (glassmorphic)
302
+ - Dot indicators
303
+ - Touch/swipe support
304
+ - Keyboard navigation (arrow keys)
305
+
306
+ ---
307
+
308
+ ## Lifecycle Management
309
+
310
+ All JS-driven components support proper initialization and teardown.
311
+
312
+ ### Init / Destroy Pattern
313
+
314
+ ```javascript
315
+ import { initGallery, destroyGallery } from '@whykusanagi/corrupted-theme/gallery';
316
+ import { initCarousel, destroyCarousel } from '@whykusanagi/corrupted-theme/carousel';
317
+ import { destroyComponents } from '@whykusanagi/corrupted-theme/components-js';
318
+
319
+ // Components auto-initialize on DOMContentLoaded when data-ct-* attributes
320
+ // are present. For manual control:
321
+ const gallery = initGallery('#my-gallery');
322
+ const carousel = initCarousel('.my-carousel', { autoplay: true });
323
+
324
+ // Tear down individual components
325
+ gallery.destroy();
326
+ carousel.destroy();
327
+
328
+ // Or tear down all component managers at once
329
+ destroyComponents();
330
+ ```
331
+
332
+ ### Multi-Instance Support
333
+
334
+ Gallery and Carousel support multiple independent instances on the same page:
335
+
336
+ ```javascript
337
+ const gallery1 = initGallery('#gallery-1');
338
+ const gallery2 = initGallery('#gallery-2');
339
+ // Each has independent filters, lightbox, and state
232
340
 
233
- <div id="tab-1" class="tab-content active">Tab 1 content</div>
234
- <div id="tab-2" class="tab-content">Tab 2 content</div>
341
+ gallery1.destroy(); // Only destroys gallery1
235
342
  ```
236
343
 
237
344
  ---
@@ -940,7 +1047,7 @@ initCountdown();
940
1047
 
941
1048
  ---
942
1049
 
943
- **Last Updated:** 2025-11-26
944
- **Version:** 1.1
1050
+ **Last Updated:** 2026-02-07
1051
+ **Version:** 2.0
945
1052
  **Status:** Complete and Production Ready
946
1053
 
@@ -104,7 +104,7 @@ Increment when you make **backward-compatible bug fixes**:
104
104
  - **Public API**: Not stable yet
105
105
  - **Use case**: Early adopters, experimentation
106
106
 
107
- **Current Celeste version**: `0.1.2` (pre-1.0.0)
107
+ **Current Celeste version**: `0.1.8` (pre-1.0.0)
108
108
 
109
109
  ### Post-1.0.0 (Stable)
110
110
 
@@ -441,7 +441,7 @@ npm view @whykusanagi/corrupted-theme version
441
441
 
442
442
  **Last Updated**: 2025-12-13
443
443
  **Version**: 1.0.0
444
- **Current Celeste Version**: 0.1.2
444
+ **Current Celeste Version**: 0.1.8
445
445
  **Versioning Spec**: Semantic Versioning 2.0.0
446
446
  **Maintainer**: Celeste Brand System
447
447
  **Status**: ✅ Active Policy