@lancar/lxui 1.0.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/LICENSE +21 -0
  3. package/README.md +5072 -0
  4. package/css/base/reset.css +91 -0
  5. package/css/base/tokens-extended.css +119 -0
  6. package/css/base/tokens.css +105 -0
  7. package/css/base/typography.css +35 -0
  8. package/css/base/utils.css +26 -0
  9. package/css/components/accordion.css +25 -0
  10. package/css/components/alert.css +22 -0
  11. package/css/components/animations.css +26 -0
  12. package/css/components/avatar.css +38 -0
  13. package/css/components/back-top.css +32 -0
  14. package/css/components/badge.css +37 -0
  15. package/css/components/breadcrumb.css +13 -0
  16. package/css/components/button.css +103 -0
  17. package/css/components/callout.css +20 -0
  18. package/css/components/card.css +42 -0
  19. package/css/components/carousel.css +31 -0
  20. package/css/components/chip.css +52 -0
  21. package/css/components/code-block.css +22 -0
  22. package/css/components/collapse.css +6 -0
  23. package/css/components/compat.css +27 -0
  24. package/css/components/dark-mode.css +35 -0
  25. package/css/components/divider.css +36 -0
  26. package/css/components/dropdown.css +39 -0
  27. package/css/components/empty.css +34 -0
  28. package/css/components/fab.css +28 -0
  29. package/css/components/file-drop.css +47 -0
  30. package/css/components/forms.css +107 -0
  31. package/css/components/kbd.css +5 -0
  32. package/css/components/list-group.css +17 -0
  33. package/css/components/modal.css +50 -0
  34. package/css/components/nav.css +25 -0
  35. package/css/components/navbar.css +44 -0
  36. package/css/components/number-input.css +52 -0
  37. package/css/components/offcanvas.css +25 -0
  38. package/css/components/pagination.css +17 -0
  39. package/css/components/popover.css +12 -0
  40. package/css/components/progress.css +26 -0
  41. package/css/components/rating.css +28 -0
  42. package/css/components/section.css +18 -0
  43. package/css/components/skeleton.css +19 -0
  44. package/css/components/spinner.css +38 -0
  45. package/css/components/stat.css +58 -0
  46. package/css/components/steps.css +76 -0
  47. package/css/components/table.css +29 -0
  48. package/css/components/tag.css +29 -0
  49. package/css/components/timeline.css +11 -0
  50. package/css/components/toast.css +14 -0
  51. package/css/components/toggler.css +20 -0
  52. package/css/components/tooltip.css +10 -0
  53. package/css/index.css +59 -0
  54. package/css/layout/grid.css +71 -0
  55. package/css/layout/utilities.css +257 -0
  56. package/js/breakpoint.js +13 -0
  57. package/js/carousel.js +62 -0
  58. package/js/clipboard.js +28 -0
  59. package/js/collapse.js +36 -0
  60. package/js/counter.js +38 -0
  61. package/js/dropdown.js +27 -0
  62. package/js/index.js +19 -0
  63. package/js/init.js +89 -0
  64. package/js/modal.js +44 -0
  65. package/js/number-input.js +44 -0
  66. package/js/offcanvas.js +28 -0
  67. package/js/popover.js +39 -0
  68. package/js/rating.js +39 -0
  69. package/js/scrollspy.js +24 -0
  70. package/js/tab.js +18 -0
  71. package/js/theme.js +9 -0
  72. package/js/toast.js +73 -0
  73. package/js/tooltip.js +39 -0
  74. package/js/utils.js +20 -0
  75. package/lx-grid.min.css +2 -0
  76. package/lx-utilities.min.css +2 -0
  77. package/lxeditor.min.css +2 -0
  78. package/lxfonts.min.css +2 -0
  79. package/lxicons.min.css +2 -0
  80. package/lxmarked.js +276 -0
  81. package/lxthemes.min.css +2 -0
  82. package/lxui.bundle.js +540 -0
  83. package/lxui.bundle.min.js +13 -0
  84. package/lxui.css +2163 -0
  85. package/lxui.esm.js +669 -0
  86. package/lxui.esm.min.js +8 -0
  87. package/lxui.js +859 -0
  88. package/lxui.min.css +2 -0
  89. package/lxui.min.js +7 -0
  90. package/lxui.rtl.css +2466 -0
  91. package/lxui.rtl.min.css +2 -0
  92. package/marked.min.js +69 -0
  93. package/package.json +183 -0
  94. package/types/index.d.ts +284 -0
package/js/init.js ADDED
@@ -0,0 +1,89 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { Modal } from './modal.js';
3
+ import { Toast } from './toast.js';
4
+ import { Collapse } from './collapse.js';
5
+ import { Dropdown } from './dropdown.js';
6
+ import { Offcanvas } from './offcanvas.js';
7
+ import { Tooltip } from './tooltip.js';
8
+ import { Tab } from './tab.js';
9
+ import { Carousel } from './carousel.js';
10
+ import { Scrollspy } from './scrollspy.js';
11
+ import { NumberInput } from './number-input.js';
12
+ import { Rating } from './rating.js';
13
+ import { theme } from './theme.js';
14
+ import { on, qs, qsa } from './utils.js';
15
+
16
+ export function init() {
17
+ // Data-attribute bridge
18
+ on(document, 'click', e => {
19
+ const el = e.target.closest('[data-lx-toggle],[data-lx-dismiss],[data-lx-slide],[data-lx-slide-to]');
20
+ if (!el) return;
21
+ const toggle = el.dataset.lxToggle, dismiss = el.dataset.lxDismiss;
22
+ const target = el.dataset.lxTarget ? qs(el.dataset.lxTarget) : null;
23
+ if (dismiss === 'modal') { const m = el.closest('.lx-modal'); if (m) new Modal(m).hide(); }
24
+ if (dismiss === 'offcanvas'){ const o = el.closest('.lx-offcanvas');if (o) new Offcanvas(o).hide(); }
25
+ if (dismiss === 'alert') { const a = el.closest('.lx-alert'); if (a) { a.style.opacity='0'; a.style.transition='opacity .15s'; setTimeout(()=>a.remove(),150); } }
26
+ if (dismiss === 'toast') { const t = el.closest('.lx-toast'); if (t) { t.style.opacity='0'; t.style.transition='opacity .15s'; setTimeout(()=>t.remove(),150); } }
27
+ if (toggle === 'modal' && target) { e.preventDefault(); new Modal(target).toggle(); }
28
+ else if (toggle === 'collapse' && target) { e.preventDefault(); new Collapse(target).toggle(); el.setAttribute('aria-expanded', (!target.classList.contains('lx-show')).toString()); }
29
+ else if (toggle === 'accordion' && target) {
30
+ e.preventDefault();
31
+ const isOpen = target.classList.contains('lx-show'), accordion = el.closest('.lx-accordion');
32
+ if (accordion) {
33
+ qsa('.lx-accordion-body.lx-show', accordion).forEach(b => { if (b !== target) new Collapse(b).hide(); });
34
+ qsa('.lx-accordion-trigger', accordion).forEach(t => { if (t !== el) { t.classList.remove('lx-active'); t.setAttribute('aria-expanded','false'); } });
35
+ }
36
+ new Collapse(target)[isOpen ? 'hide' : 'show']();
37
+ el.classList.toggle('lx-active', !isOpen); el.setAttribute('aria-expanded', (!isOpen).toString());
38
+ }
39
+ else if (toggle === 'dropdown') { e.preventDefault(); e.stopPropagation(); new Dropdown(el).toggle(); }
40
+ else if (toggle === 'offcanvas' && target) { e.preventDefault(); new Offcanvas(target).toggle(); }
41
+ else if (toggle === 'tab' && target) { e.preventDefault(); new Tab(el).show(); }
42
+ const slideTo = el.dataset.lxSlideTo, slideDir = el.dataset.lxSlide;
43
+ if (slideTo !== undefined || slideDir) {
44
+ const c = (qs(el.dataset.lxTarget) || el.closest('.lx-carousel'))?._lxCarousel;
45
+ if (c) { if (slideDir === 'next') c.next(); else if (slideDir === 'prev') c.prev(); else if (slideTo !== undefined) c.to(parseInt(slideTo)); }
46
+ }
47
+ });
48
+ // Scrollspy
49
+ qsa('[data-lx-spy="scroll"]').forEach(el => new Scrollspy(el));
50
+ // Tooltips
51
+ qsa('[data-lx-toggle="tooltip"]').forEach(el => new Tooltip(el, { placement: el.dataset.lxPlacement || 'top', trigger: 'hover focus', delay: { show: 100, hide: 0 } }));
52
+ // Carousels
53
+ qsa('.lx-carousel').forEach(el => { const c = new Carousel(el, { interval: parseInt(el.dataset.lxInterval) || 5000 }); el._lxCarousel = c; });
54
+ // Number inputs
55
+ qsa('.lx-number-input').forEach(el => new NumberInput(el));
56
+ // Ratings
57
+ qsa('.lx-rating').forEach(el => new Rating(el));
58
+ // Back to top
59
+ const btns = qsa('.lx-back-top');
60
+ if (btns.length) {
61
+ const toggle = () => btns.forEach(b => b.classList.toggle('lx-show', window.scrollY > 300));
62
+ on(window, 'scroll', toggle, { passive: true });
63
+ btns.forEach(btn => on(btn, 'click', e => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }));
64
+ toggle();
65
+ }
66
+ // Lazy load
67
+ if ('IntersectionObserver' in window) {
68
+ const io = new IntersectionObserver(entries => {
69
+ entries.forEach(e => {
70
+ if (!e.isIntersecting) return;
71
+ const el = e.target;
72
+ if (el.dataset.lxSrc) el.src = el.dataset.lxSrc;
73
+ if (el.dataset.lxBg) el.style.backgroundImage = 'url(' + el.dataset.lxBg + ')';
74
+ el.classList.add('lx-lazy-loaded'); io.unobserve(el);
75
+ });
76
+ }, { rootMargin: '200px' });
77
+ qsa('[data-lx-lazy]').forEach(el => io.observe(el));
78
+ }
79
+ // File drops
80
+ qsa('.lx-file-drop').forEach(zone => {
81
+ const input = qs('input[type="file"]', zone);
82
+ ['dragenter','dragover'].forEach(ev => on(zone, ev, e => { e.preventDefault(); zone.classList.add('lx-drag-over'); }));
83
+ ['dragleave','drop'].forEach(ev => on(zone, ev, e => { e.preventDefault(); zone.classList.remove('lx-drag-over'); }));
84
+ on(zone, 'drop', e => { const files = e.dataTransfer.files; if (input) { try { input.files = files; } catch(x){} } emit(zone, 'file.drop', { files }); });
85
+ on(zone, 'click', () => input && input.click());
86
+ if (input) on(input, 'change', () => emit(zone, 'file.select', { files: input.files }));
87
+ });
88
+ theme.restore();
89
+ }
package/js/modal.js ADDED
@@ -0,0 +1,44 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class Modal {
5
+ constructor(sel, opts = {}) {
6
+ this.el = typeof sel === 'string' ? qs(sel) : sel;
7
+ if (!this.el) return;
8
+ this.opts = Object.assign({ backdrop: true, keyboard: true, focus: true }, opts);
9
+ this._backdrop = null;
10
+ this._prevFocus = null;
11
+ }
12
+ show() {
13
+ if (!this.el) return;
14
+ emit(this.el, 'modal.show');
15
+ this._prevFocus = document.activeElement;
16
+ this._backdrop = document.createElement('div');
17
+ this._backdrop.className = 'lx-modal-backdrop lx-fade lx-show';
18
+ document.body.appendChild(this._backdrop);
19
+ document.body.classList.add('lx-modal-open');
20
+ this.el.classList.add('lx-show');
21
+ this.el.style.display = 'flex';
22
+ this.el.removeAttribute('aria-hidden');
23
+ if (this.opts.focus) trap(this.el);
24
+ if (this.opts.keyboard) {
25
+ this._keyHandler = e => { if (e.key === 'Escape') this.hide(); };
26
+ on(document, 'keydown', this._keyHandler);
27
+ }
28
+ if (this.opts.backdrop) on(this._backdrop, 'click', () => this.hide());
29
+ requestAnimationFrame(() => emit(this.el, 'modal.shown'));
30
+ }
31
+ hide() {
32
+ if (!this.el) return;
33
+ emit(this.el, 'modal.hide');
34
+ this.el.classList.remove('lx-show');
35
+ this.el.style.display = '';
36
+ this.el.setAttribute('aria-hidden', 'true');
37
+ if (this._backdrop) { this._backdrop.remove(); this._backdrop = null; }
38
+ document.body.classList.remove('lx-modal-open');
39
+ if (this._keyHandler) off(document, 'keydown', this._keyHandler);
40
+ if (this._prevFocus) this._prevFocus.focus();
41
+ emit(this.el, 'modal.hidden');
42
+ }
43
+ toggle() { this.el.classList.contains('lx-show') ? this.hide() : this.show(); }
44
+ }
@@ -0,0 +1,44 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class NumberInput {
5
+ constructor(el, opts = {}) {
6
+ this.wrap = typeof el === 'string' ? qs(el) : el;
7
+ if (!this.wrap) return;
8
+ this.input = qs('input', this.wrap);
9
+ if (!this.input) return;
10
+ this.opts = Object.assign({ step: 1, min: -Infinity, max: Infinity }, opts);
11
+ this.opts.min = parseFloat(this.input.min || this.opts.min);
12
+ this.opts.max = parseFloat(this.input.max || this.opts.max);
13
+ this.opts.step = parseFloat(this.input.step || this.opts.step) || 1;
14
+ this._attach();
15
+ }
16
+ _val() { return parseFloat(this.input.value) || 0; }
17
+ _set(v) {
18
+ const clamped = Math.min(this.opts.max, Math.max(this.opts.min, v));
19
+ this.input.value = clamped;
20
+ emit(this.input, 'change', { value: clamped });
21
+ this._updateBtns();
22
+ }
23
+ _updateBtns() {
24
+ const v = this._val();
25
+ const dec = qs('.lx-number-btn[data-lx-dec]', this.wrap) || qs('.lx-number-dec', this.wrap);
26
+ const inc = qs('.lx-number-btn[data-lx-inc]', this.wrap) || qs('.lx-number-inc', this.wrap);
27
+ if (dec) dec.disabled = v <= this.opts.min;
28
+ if (inc) inc.disabled = v >= this.opts.max;
29
+ }
30
+ _attach() {
31
+ on(this.wrap, 'click', e => {
32
+ const btn = e.target.closest('[data-lx-dec],[data-lx-inc],.lx-number-dec,.lx-number-inc');
33
+ if (!btn) return;
34
+ if (btn.matches('[data-lx-dec],.lx-number-dec')) this._set(this._val() - this.opts.step);
35
+ if (btn.matches('[data-lx-inc],.lx-number-inc')) this._set(this._val() + this.opts.step);
36
+ });
37
+ on(this.input, 'change', () => this._set(this._val()));
38
+ on(this.input, 'keydown', e => {
39
+ if (e.key === 'ArrowUp') { e.preventDefault(); this._set(this._val() + this.opts.step); }
40
+ if (e.key === 'ArrowDown') { e.preventDefault(); this._set(this._val() - this.opts.step); }
41
+ });
42
+ this._updateBtns();
43
+ }
44
+ }
@@ -0,0 +1,28 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class Offcanvas {
5
+ constructor(sel) { this.el = typeof sel === 'string' ? qs(sel) : sel; this._backdrop = null; }
6
+ show() {
7
+ if (!this.el) return;
8
+ this._backdrop = document.createElement('div');
9
+ this._backdrop.className = 'lx-offcanvas-backdrop';
10
+ this._backdrop.style.cssText = 'position:fixed;inset:0;z-index:1039;background:rgba(0,0,0,.5)';
11
+ document.body.appendChild(this._backdrop);
12
+ document.body.style.overflow = 'hidden';
13
+ this.el.classList.add('lx-show');
14
+ this.el.removeAttribute('aria-hidden');
15
+ trap(this.el);
16
+ on(this._backdrop, 'click', () => this.hide());
17
+ on(document, 'keydown', this._esc = e => { if (e.key === 'Escape') this.hide(); });
18
+ }
19
+ hide() {
20
+ if (!this.el) return;
21
+ this.el.classList.remove('lx-show');
22
+ this.el.setAttribute('aria-hidden', 'true');
23
+ if (this._backdrop) { this._backdrop.remove(); this._backdrop = null; }
24
+ document.body.style.overflow = '';
25
+ off(document, 'keydown', this._esc);
26
+ }
27
+ toggle() { this.el && this.el.classList.contains('lx-show') ? this.hide() : this.show(); }
28
+ }
package/js/popover.js ADDED
@@ -0,0 +1,39 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class Popover {
5
+ constructor(el, opts = {}) {
6
+ this.el = typeof el === 'string' ? qs(el) : el;
7
+ if (!this.el) return;
8
+ this.opts = Object.assign({ placement: 'top', trigger: 'click' }, opts);
9
+ this._pop = null;
10
+ const toggle = () => this._pop ? this._hide() : this._show();
11
+ if (this.opts.trigger.includes('click')) on(this.el, 'click', toggle);
12
+ }
13
+ _show() {
14
+ const title = this.el.dataset.lxTitle || '';
15
+ const content = this.el.dataset.lxContent || '';
16
+ this._pop = document.createElement('div');
17
+ this._pop.className = 'lx-popover';
18
+ this._pop.setAttribute('role', 'tooltip');
19
+ this._pop.style.cssText = 'position:absolute;z-index:1070;background:var(--surface,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.12);padding:.75rem 1rem;min-width:200px;max-width:300px';
20
+ if (title) {
21
+ const h = document.createElement('strong');
22
+ h.style.cssText = 'display:block;margin-bottom:.5rem;font-size:.875rem';
23
+ h.textContent = title;
24
+ this._pop.appendChild(h);
25
+ }
26
+ const pb = document.createElement('p');
27
+ pb.style.cssText = 'margin:0;font-size:.875rem;color:var(--text-secondary,#6b7280)';
28
+ pb.textContent = content;
29
+ this._pop.appendChild(pb);
30
+ document.body.appendChild(this._pop);
31
+ const r = this.el.getBoundingClientRect(), s = window.scrollY;
32
+ this._pop.style.top = (r.bottom + s + 8) + 'px';
33
+ this._pop.style.left = r.left + 'px';
34
+ setTimeout(() => on(document, 'click', this._outside = e => {
35
+ if (!this.el.contains(e.target) && !this._pop?.contains(e.target)) this._hide();
36
+ }), 0);
37
+ }
38
+ _hide() { if (this._pop) { this._pop.remove(); this._pop = null; off(document, 'click', this._outside); } }
39
+ }
package/js/rating.js ADDED
@@ -0,0 +1,39 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class Rating {
5
+ constructor(el, opts = {}) {
6
+ this.el = typeof el === 'string' ? qs(el) : el;
7
+ if (!this.el) return;
8
+ this.opts = Object.assign({ stars: 5, value: 0, readonly: this.el.dataset.lxReadonly !== undefined }, opts);
9
+ this.value = parseFloat(this.el.dataset.lxValue || this.opts.value) || 0;
10
+ this._render();
11
+ }
12
+ _render() {
13
+ this.el.innerHTML = '';
14
+ this.el.setAttribute('role', 'radiogroup');
15
+ for (let i = 1; i <= this.opts.stars; i++) {
16
+ const s = document.createElement('span');
17
+ s.className = 'lx-rating-star' + (i <= this.value ? ' lx-filled' : '');
18
+ s.setAttribute('role', 'radio');
19
+ s.setAttribute('aria-label', i + ' star' + (i !== 1 ? 's' : ''));
20
+ s.setAttribute('aria-checked', i <= this.value ? 'true' : 'false');
21
+ s.dataset.value = i;
22
+ this.el.appendChild(s);
23
+ }
24
+ if (this.opts.readonly) { this.el.dataset.readonly = ''; return; }
25
+ on(this.el, 'click', e => {
26
+ const s = e.target.closest('.lx-rating-star');
27
+ if (!s) return;
28
+ this.value = parseInt(s.dataset.value);
29
+ qsa('.lx-rating-star', this.el).forEach((st, i) => {
30
+ const filled = i + 1 <= this.value;
31
+ st.classList.toggle('lx-filled', filled);
32
+ st.setAttribute('aria-checked', filled ? 'true' : 'false');
33
+ });
34
+ emit(this.el, 'rating.change', { value: this.value });
35
+ });
36
+ }
37
+ setValue(v) { this.value = v; this._render(); }
38
+ getValue() { return this.value; }
39
+ }
@@ -0,0 +1,24 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class Scrollspy {
5
+ constructor(el, opts = {}) {
6
+ this.el = typeof el === 'string' ? qs(el) : el;
7
+ if (!this.el) return;
8
+ this.opts = Object.assign({ offset: 70 }, opts);
9
+ const targetSel = this.el.dataset.lxTarget;
10
+ this.nav = targetSel ? qs(targetSel) : null;
11
+ this._update = this._update.bind(this);
12
+ on(this.el === document.body ? window : this.el, 'scroll', this._update);
13
+ this._update();
14
+ }
15
+ _update() {
16
+ if (!this.nav) return;
17
+ const links = qsa('a[href^="#"]', this.nav);
18
+ const scrollTop = (this.el === document.body ? window.scrollY : this.el.scrollTop) + this.opts.offset;
19
+ let active = null;
20
+ links.forEach(a => { const t = qs(a.getAttribute('href')); if (t && t.offsetTop <= scrollTop) active = a; });
21
+ links.forEach(a => a.classList.remove('lx-active'));
22
+ if (active) active.classList.add('lx-active');
23
+ }
24
+ }
package/js/tab.js ADDED
@@ -0,0 +1,18 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class Tab {
5
+ constructor(trigger) { this.trigger = typeof trigger === 'string' ? qs(trigger) : trigger; }
6
+ show() {
7
+ if (!this.trigger) return;
8
+ const targetSel = this.trigger.dataset.lxTarget;
9
+ const target = targetSel ? qs(targetSel) : null;
10
+ if (!target) return;
11
+ const tablist = this.trigger.closest('[role="tablist"]') || this.trigger.parentElement.parentElement;
12
+ qsa('.lx-nav-link, .lx-tab-item', tablist).forEach(t => { t.classList.remove('lx-active'); t.setAttribute('aria-selected', 'false'); });
13
+ qsa('.lx-tab-pane', target.parentElement).forEach(p => p.classList.remove('lx-active', 'lx-show'));
14
+ this.trigger.classList.add('lx-active');
15
+ this.trigger.setAttribute('aria-selected', 'true');
16
+ target.classList.add('lx-active', 'lx-show');
17
+ }
18
+ }
package/js/theme.js ADDED
@@ -0,0 +1,9 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ export const theme = {
3
+ set(t, mode) { document.documentElement.dataset.theme = t; if (mode) document.documentElement.dataset.mode = mode; },
4
+ setMode(mode) { document.documentElement.dataset.mode = mode; },
5
+ toggle() { const cur = document.documentElement.dataset.mode || 'light'; this.setMode(cur === 'dark' ? 'light' : 'dark'); },
6
+ current() { return { theme: document.documentElement.dataset.theme, mode: document.documentElement.dataset.mode }; },
7
+ save(t, mode) { this.set(t, mode); localStorage.setItem('lx-theme', t); if (mode) localStorage.setItem('lx-mode', mode); },
8
+ restore() { const t = localStorage.getItem('lx-theme'), m = localStorage.getItem('lx-mode'); if (t) this.set(t, m || undefined); }
9
+ };
package/js/toast.js ADDED
@@ -0,0 +1,73 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export const Toast = {
5
+ _container(pos) {
6
+ const id = 'lx-toast-' + pos;
7
+ let c = document.getElementById(id);
8
+ if (!c) {
9
+ c = document.createElement('div');
10
+ c.id = id;
11
+ const posMap = {
12
+ 'top-right': 'top:1rem;right:1rem',
13
+ 'top-left': 'top:1rem;left:1rem',
14
+ 'bottom-right': 'bottom:1rem;right:1rem',
15
+ 'bottom-left': 'bottom:1rem;left:1rem',
16
+ 'top-center': 'top:1rem;left:50%;transform:translateX(-50%)',
17
+ 'bottom-center':'bottom:1rem;left:50%;transform:translateX(-50%)'
18
+ };
19
+ c.setAttribute('style', `position:fixed;z-index:1090;display:flex;flex-direction:column;gap:.5rem;${posMap[pos] || posMap['top-right']}`);
20
+ document.body.appendChild(c);
21
+ }
22
+ return c;
23
+ },
24
+ show(opts = {}) {
25
+ const { message = '', type = 'default', duration = 4000, position = 'top-right', title = '' } = opts;
26
+ const colors = { success: '#22c55e', warning: '#f59e0b', danger: '#ef4444', info: '#06b6d4', default: '#3b82f6' };
27
+ const t = document.createElement('div');
28
+ t.setAttribute('role', 'alert');
29
+ t.setAttribute('aria-live', 'assertive');
30
+ t.setAttribute('aria-atomic', 'true');
31
+ t.style.cssText = 'background:var(--surface,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.12);padding:.875rem 1rem;min-width:280px;max-width:380px;display:flex;align-items:flex-start;gap:.75rem;animation:lxSlideIn .2s ease';
32
+ const dot = document.createElement('span');
33
+ dot.style.cssText = 'width:8px;height:8px;border-radius:50%;background:' + (colors[type] || colors.default) + ';flex-shrink:0;margin-top:4px';
34
+ t.appendChild(dot);
35
+ if (title) {
36
+ const wrap = document.createElement('div');
37
+ const strong = document.createElement('strong');
38
+ strong.style.cssText = 'display:block;margin-bottom:2px;font-size:.875rem';
39
+ strong.textContent = title;
40
+ const span = document.createElement('span');
41
+ span.style.cssText = 'font-size:.875rem;color:var(--text-secondary,#6b7280)';
42
+ span.textContent = message;
43
+ wrap.appendChild(strong); wrap.appendChild(span);
44
+ t.appendChild(wrap);
45
+ } else {
46
+ const span = document.createElement('span');
47
+ span.style.cssText = 'font-size:.875rem;color:var(--text-primary,#111827);flex:1';
48
+ span.textContent = message;
49
+ t.appendChild(span);
50
+ }
51
+ const close = document.createElement('button');
52
+ close.style.cssText = 'background:none;border:none;cursor:pointer;padding:0;color:var(--text-muted,#9ca3af);font-size:1.125rem;line-height:1;margin-left:auto';
53
+ close.setAttribute('aria-label', 'Close');
54
+ close.textContent = '×';
55
+ close.addEventListener('click', () => t.remove());
56
+ t.appendChild(close);
57
+ this._container(position).appendChild(t);
58
+ if (!document.getElementById('lx-toast-style')) {
59
+ const s = document.createElement('style');
60
+ s.id = 'lx-toast-style';
61
+ s.textContent = '@keyframes lxSlideIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}';
62
+ document.head.appendChild(s);
63
+ }
64
+ if (duration > 0) setTimeout(() => {
65
+ t.style.opacity = '0'; t.style.transition = 'opacity .2s';
66
+ setTimeout(() => t.remove(), 200);
67
+ }, duration);
68
+ },
69
+ success(msg, opts = {}) { this.show({ ...opts, message: msg, type: 'success' }); },
70
+ error(msg, opts = {}) { this.show({ ...opts, message: msg, type: 'danger' }); },
71
+ warning(msg, opts = {}) { this.show({ ...opts, message: msg, type: 'warning' }); },
72
+ info(msg, opts = {}) { this.show({ ...opts, message: msg, type: 'info' }); },
73
+ };
package/js/tooltip.js ADDED
@@ -0,0 +1,39 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ import { qs, qsa, on, off, emit, trap } from './utils.js';
3
+
4
+ export class Tooltip {
5
+ constructor(el, opts = {}) {
6
+ this.el = typeof el === 'string' ? qs(el) : el;
7
+ if (!this.el) return;
8
+ this.opts = Object.assign({ placement: 'top', trigger: 'hover', delay: { show: 0, hide: 0 } }, opts);
9
+ this._tip = null;
10
+ this._attach();
11
+ }
12
+ _attach() {
13
+ const show = () => { clearTimeout(this._hideTimer); this._showTimer = setTimeout(() => this._show(), this.opts.delay.show); };
14
+ const hide = () => { clearTimeout(this._showTimer); this._hideTimer = setTimeout(() => this._hide(), this.opts.delay.hide); };
15
+ if (this.opts.trigger.includes('hover')) { on(this.el, 'mouseenter', show); on(this.el, 'mouseleave', hide); }
16
+ if (this.opts.trigger.includes('focus')) { on(this.el, 'focusin', show); on(this.el, 'focusout', hide); }
17
+ }
18
+ _show() {
19
+ const text = this.el.getAttribute('title') || this.el.dataset.lxOrigTitle || '';
20
+ if (!text) return;
21
+ if (this.el.getAttribute('title')) { this.el.dataset.lxOrigTitle = text; this.el.removeAttribute('title'); }
22
+ this._tip = document.createElement('div');
23
+ this._tip.className = 'lx-tooltip lx-tooltip-' + this.opts.placement;
24
+ this._tip.setAttribute('role', 'tooltip');
25
+ this._tip.style.cssText = 'position:absolute;z-index:1080;padding:4px 8px;background:rgba(0,0,0,.85);color:#fff;border-radius:4px;font-size:.75rem;white-space:nowrap;pointer-events:none';
26
+ this._tip.textContent = text;
27
+ document.body.appendChild(this._tip);
28
+ const r = this.el.getBoundingClientRect(), t = this._tip.getBoundingClientRect(), s = window.scrollY;
29
+ const p = this.opts.placement;
30
+ let top = 0, left = 0;
31
+ if (p === 'top') { top = r.top + s - t.height - 6; left = r.left + (r.width - t.width) / 2; }
32
+ else if (p === 'bottom') { top = r.bottom + s + 6; left = r.left + (r.width - t.width) / 2; }
33
+ else if (p === 'left') { top = r.top + s + (r.height - t.height) / 2; left = r.left - t.width - 6; }
34
+ else { top = r.top + s + (r.height - t.height) / 2; left = r.right + 6; }
35
+ this._tip.style.top = top + 'px';
36
+ this._tip.style.left = left + 'px';
37
+ }
38
+ _hide() { if (this._tip) { this._tip.remove(); this._tip = null; } }
39
+ }
package/js/utils.js ADDED
@@ -0,0 +1,20 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ // Shared DOM helpers — used by all LxUI components
3
+ export function qs(sel, ctx) { return (ctx || document).querySelector(sel); }
4
+ export function qsa(sel, ctx) { return Array.from((ctx || document).querySelectorAll(sel)); }
5
+ export function on(el, ev, fn, opts) { el && el.addEventListener(ev, fn, opts); }
6
+ export function off(el, ev, fn) { el && el.removeEventListener(ev, fn); }
7
+ export function emit(el, name, detail) {
8
+ el.dispatchEvent(new CustomEvent('lx.' + name, { bubbles: true, cancelable: true, detail }));
9
+ }
10
+ export function trap(el) {
11
+ const focusable = qsa('button,a,[href],[tabindex]:not([tabindex="-1"]),input,select,textarea', el)
12
+ .filter(e => !e.disabled && e.offsetParent !== null);
13
+ if (!focusable.length) return;
14
+ const [first, last] = [focusable[0], focusable[focusable.length - 1]];
15
+ on(el, 'keydown', e => {
16
+ if (e.key !== 'Tab') return;
17
+ if (e.shiftKey) { if (document.activeElement === first) { e.preventDefault(); last.focus(); } }
18
+ else { if (document.activeElement === last) { e.preventDefault(); first.focus(); } }
19
+ });
20
+ }
@@ -0,0 +1,2 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */:root{--lx-gap:1rem;--lx-container-padding-x:1rem;--lx-grid-cols:12}*,::after,::before{box-sizing:border-box}.lx-container{width:100%;margin-inline:auto;padding-inline:var(--lx-container-padding-x)}.lx-container-fluid{width:100%;padding-inline:var(--lx-container-padding-x)}.lx-container-sm{max-width:640px;margin-inline:auto;padding-inline:var(--lx-container-padding-x)}.lx-container-md{max-width:768px;margin-inline:auto;padding-inline:var(--lx-container-padding-x)}.lx-container-lg{max-width:1024px;margin-inline:auto;padding-inline:var(--lx-container-padding-x)}.lx-container-xl{max-width:1280px;margin-inline:auto;padding-inline:var(--lx-container-padding-x)}.lx-container-2xl{max-width:1536px;margin-inline:auto;padding-inline:var(--lx-container-padding-x)}@media(min-width:640px){.lx-container{max-width:640px}}@media(min-width:768px){.lx-container{max-width:768px}:root{--lx-container-padding-x:1.5rem}}@media(min-width:1024px){.lx-container{max-width:1024px}}@media(min-width:1280px){.lx-container{max-width:1280px}}@media(min-width:1536px){.lx-container{max-width:1536px}}.lx-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--lx-gap)}.lx-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lx-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lx-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lx-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lx-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lx-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lx-cols-auto{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}.lx-col-1{grid-column:span 1/span 1}.lx-col-2{grid-column:span 2/span 2}.lx-col-3{grid-column:span 3/span 3}.lx-col-4{grid-column:span 4/span 4}.lx-col-5{grid-column:span 5/span 5}.lx-col-6{grid-column:span 6/span 6}.lx-col-7{grid-column:span 7/span 7}.lx-col-8{grid-column:span 8/span 8}.lx-col-9{grid-column:span 9/span 9}.lx-col-10{grid-column:span 10/span 10}.lx-col-11{grid-column:span 11/span 11}.lx-col-12{grid-column:span 12/span 12}.lx-col-offset-1{margin-inline-start:calc(100%/12*1)}.lx-col-offset-2{margin-inline-start:calc(100%/12*2)}.lx-col-offset-3{margin-inline-start:calc(100%/12*3)}.lx-col-offset-4{margin-inline-start:calc(100%/12*4)}.lx-col-offset-5{margin-inline-start:calc(100%/12*5)}.lx-col-offset-6{margin-inline-start:calc(100%/12*6)}.lx-order-first{order:-9999}.lx-order-last{order:9999}.lx-order-1{order:1}.lx-order-2{order:2}.lx-order-3{order:3}.lx-order-4{order:4}.lx-order-5{order:5}.lx-order-6{order:6}.lx-gap-0{gap:0}.lx-gap-1{gap:.25rem}.lx-gap-2{gap:.5rem}.lx-gap-3{gap:.75rem}.lx-gap-4{gap:1rem}.lx-gap-5{gap:1.25rem}.lx-gap-6{gap:1.5rem}.lx-gap-8{gap:2rem}.lx-gap-10{gap:2.5rem}.lx-gap-12{gap:3rem}.lx-gap-x-0{column-gap:0}.lx-gap-x-2{column-gap:.5rem}.lx-gap-x-4{column-gap:1rem}.lx-gap-x-6{column-gap:1.5rem}.lx-gap-x-8{column-gap:2rem}.lx-gap-y-0{row-gap:0}.lx-gap-y-2{row-gap:.5rem}.lx-gap-y-4{row-gap:1rem}.lx-gap-y-6{row-gap:1.5rem}.lx-gap-y-8{row-gap:2rem}@media(min-width:640px){.lx-sm-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lx-sm-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lx-sm-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lx-sm-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lx-sm-col-1{grid-column:span 1/span 1}.lx-sm-col-2{grid-column:span 2/span 2}.lx-sm-col-3{grid-column:span 3/span 3}.lx-sm-col-4{grid-column:span 4/span 4}.lx-sm-col-6{grid-column:span 6/span 6}.lx-sm-col-12{grid-column:span 12/span 12}.lx-sm-gap-2{gap:.5rem}.lx-sm-gap-4{gap:1rem}.lx-sm-gap-6{gap:1.5rem}}@media(min-width:768px){.lx-md-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lx-md-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lx-md-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lx-md-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lx-md-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lx-md-col-1{grid-column:span 1/span 1}.lx-md-col-2{grid-column:span 2/span 2}.lx-md-col-3{grid-column:span 3/span 3}.lx-md-col-4{grid-column:span 4/span 4}.lx-md-col-5{grid-column:span 5/span 5}.lx-md-col-6{grid-column:span 6/span 6}.lx-md-col-7{grid-column:span 7/span 7}.lx-md-col-8{grid-column:span 8/span 8}.lx-md-col-9{grid-column:span 9/span 9}.lx-md-col-10{grid-column:span 10/span 10}.lx-md-col-12{grid-column:span 12/span 12}.lx-md-col-offset-3{margin-inline-start:25%}.lx-md-col-offset-4{margin-inline-start:33.333%}.lx-md-gap-2{gap:.5rem}.lx-md-gap-4{gap:1rem}.lx-md-gap-6{gap:1.5rem}.lx-md-gap-8{gap:2rem}}@media(min-width:1024px){.lx-lg-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lx-lg-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lx-lg-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lx-lg-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lx-lg-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lx-lg-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lx-lg-col-1{grid-column:span 1/span 1}.lx-lg-col-2{grid-column:span 2/span 2}.lx-lg-col-3{grid-column:span 3/span 3}.lx-lg-col-4{grid-column:span 4/span 4}.lx-lg-col-5{grid-column:span 5/span 5}.lx-lg-col-6{grid-column:span 6/span 6}.lx-lg-col-8{grid-column:span 8/span 8}.lx-lg-col-9{grid-column:span 9/span 9}.lx-lg-col-12{grid-column:span 12/span 12}.lx-lg-gap-4{gap:1rem}.lx-lg-gap-6{gap:1.5rem}.lx-lg-gap-8{gap:2rem}}@media(min-width:1280px){.lx-xl-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lx-xl-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lx-xl-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lx-xl-col-3{grid-column:span 3/span 3}.lx-xl-col-4{grid-column:span 4/span 4}.lx-xl-col-6{grid-column:span 6/span 6}}
@@ -0,0 +1,2 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */.lx-block{display:block}.lx-inline{display:inline}.lx-inline-block{display:inline-block}.lx-flex{display:flex}.lx-inline-flex{display:inline-flex}.lx-grid{display:grid}.lx-inline-grid{display:inline-grid}.lx-table{display:table}.lx-table-row{display:table-row}.lx-table-cell{display:table-cell}.lx-contents{display:contents}.lx-hidden{display:none}@media print{.lx-print-hidden{display:none!important}.lx-print-block{display:block!important}}.lx-flex-row{flex-direction:row}.lx-flex-row-reverse{flex-direction:row-reverse}.lx-flex-col{flex-direction:column}.lx-flex-col-reverse{flex-direction:column-reverse}.lx-flex-wrap{flex-wrap:wrap}.lx-flex-nowrap{flex-wrap:nowrap}.lx-flex-wrap-reverse{flex-wrap:wrap-reverse}.lx-justify-start{justify-content:flex-start}.lx-justify-end{justify-content:flex-end}.lx-justify-center{justify-content:center}.lx-justify-between{justify-content:space-between}.lx-justify-around{justify-content:space-around}.lx-justify-evenly{justify-content:space-evenly}.lx-items-start{align-items:flex-start}.lx-items-end{align-items:flex-end}.lx-items-center{align-items:center}.lx-items-baseline{align-items:baseline}.lx-items-stretch{align-items:stretch}.lx-self-start{align-self:flex-start}.lx-self-end{align-self:flex-end}.lx-self-center{align-self:center}.lx-self-stretch{align-self:stretch}.lx-self-auto{align-self:auto}.lx-content-start{align-content:flex-start}.lx-content-end{align-content:flex-end}.lx-content-center{align-content:center}.lx-content-between{align-content:space-between}.lx-flex-1{flex:1 1 0%}.lx-flex-auto{flex:1 1 auto}.lx-flex-none{flex:none}.lx-flex-shrink-0{flex-shrink:0}.lx-flex-shrink{flex-shrink:1}.lx-grow{flex-grow:1}.lx-grow-0{flex-grow:0}.lx-order-first{order:-9999}.lx-order-last{order:9999}.lx-order-1{order:1}.lx-order-2{order:2}.lx-order-3{order:3}.lx-order-4{order:4}.lx-stack>*+*{margin-block-start:var(--lx-stack-gap,1rem)}.lx-hstack{display:flex;align-items:center}.lx-m-0{margin:0}.lx-m-1{margin:.25rem}.lx-m-2{margin:.5rem}.lx-m-3{margin:.75rem}.lx-m-4{margin:1rem}.lx-m-5{margin:1.25rem}.lx-m-6{margin:1.5rem}.lx-m-8{margin:2rem}.lx-m-10{margin:2.5rem}.lx-m-12{margin:3rem}.lx-m-16{margin:4rem}.lx-m-auto{margin:auto}.lx-mt-0{margin-top:0}.lx-mt-1{margin-top:.25rem}.lx-mt-2{margin-top:.5rem}.lx-mt-3{margin-top:.75rem}.lx-mt-4{margin-top:1rem}.lx-mt-5{margin-top:1.25rem}.lx-mt-6{margin-top:1.5rem}.lx-mt-8{margin-top:2rem}.lx-mt-10{margin-top:2.5rem}.lx-mt-12{margin-top:3rem}.lx-mt-16{margin-top:4rem}.lx-mt-auto{margin-top:auto}.lx-mb-0{margin-bottom:0}.lx-mb-1{margin-bottom:.25rem}.lx-mb-2{margin-bottom:.5rem}.lx-mb-3{margin-bottom:.75rem}.lx-mb-4{margin-bottom:1rem}.lx-mb-5{margin-bottom:1.25rem}.lx-mb-6{margin-bottom:1.5rem}.lx-mb-8{margin-bottom:2rem}.lx-mb-10{margin-bottom:2.5rem}.lx-mb-12{margin-bottom:3rem}.lx-mb-16{margin-bottom:4rem}.lx-mb-auto{margin-bottom:auto}.lx-ms-0{margin-inline-start:0}.lx-ms-1{margin-inline-start:.25rem}.lx-ms-2{margin-inline-start:.5rem}.lx-ms-3{margin-inline-start:.75rem}.lx-ms-4{margin-inline-start:1rem}.lx-ms-5{margin-inline-start:1.25rem}.lx-ms-6{margin-inline-start:1.5rem}.lx-ms-8{margin-inline-start:2rem}.lx-ms-auto{margin-inline-start:auto}.lx-me-0{margin-inline-end:0}.lx-me-1{margin-inline-end:.25rem}.lx-me-2{margin-inline-end:.5rem}.lx-me-3{margin-inline-end:.75rem}.lx-me-4{margin-inline-end:1rem}.lx-me-5{margin-inline-end:1.25rem}.lx-me-6{margin-inline-end:1.5rem}.lx-me-8{margin-inline-end:2rem}.lx-me-auto{margin-inline-end:auto}.lx-mx-0{margin-inline:0}.lx-mx-1{margin-inline:.25rem}.lx-mx-2{margin-inline:.5rem}.lx-mx-3{margin-inline:.75rem}.lx-mx-4{margin-inline:1rem}.lx-mx-6{margin-inline:1.5rem}.lx-mx-8{margin-inline:2rem}.lx-mx-auto{margin-inline:auto}.lx-my-0{margin-block:0}.lx-my-1{margin-block:.25rem}.lx-my-2{margin-block:.5rem}.lx-my-3{margin-block:.75rem}.lx-my-4{margin-block:1rem}.lx-my-6{margin-block:1.5rem}.lx-my-8{margin-block:2rem}.lx-my-auto{margin-block:auto}.lx-p-0{padding:0}.lx-p-1{padding:.25rem}.lx-p-2{padding:.5rem}.lx-p-3{padding:.75rem}.lx-p-4{padding:1rem}.lx-p-5{padding:1.25rem}.lx-p-6{padding:1.5rem}.lx-p-8{padding:2rem}.lx-p-10{padding:2.5rem}.lx-p-12{padding:3rem}.lx-p-16{padding:4rem}.lx-pt-0{padding-top:0}.lx-pt-1{padding-top:.25rem}.lx-pt-2{padding-top:.5rem}.lx-pt-3{padding-top:.75rem}.lx-pt-4{padding-top:1rem}.lx-pt-6{padding-top:1.5rem}.lx-pt-8{padding-top:2rem}.lx-pt-12{padding-top:3rem}.lx-pt-16{padding-top:4rem}.lx-pb-0{padding-bottom:0}.lx-pb-1{padding-bottom:.25rem}.lx-pb-2{padding-bottom:.5rem}.lx-pb-3{padding-bottom:.75rem}.lx-pb-4{padding-bottom:1rem}.lx-pb-6{padding-bottom:1.5rem}.lx-pb-8{padding-bottom:2rem}.lx-pb-12{padding-bottom:3rem}.lx-pb-16{padding-bottom:4rem}.lx-ps-0{padding-inline-start:0}.lx-ps-1{padding-inline-start:.25rem}.lx-ps-2{padding-inline-start:.5rem}.lx-ps-3{padding-inline-start:.75rem}.lx-ps-4{padding-inline-start:1rem}.lx-ps-5{padding-inline-start:1.25rem}.lx-ps-6{padding-inline-start:1.5rem}.lx-ps-8{padding-inline-start:2rem}.lx-pe-0{padding-inline-end:0}.lx-pe-1{padding-inline-end:.25rem}.lx-pe-2{padding-inline-end:.5rem}.lx-pe-3{padding-inline-end:.75rem}.lx-pe-4{padding-inline-end:1rem}.lx-pe-5{padding-inline-end:1.25rem}.lx-pe-6{padding-inline-end:1.5rem}.lx-pe-8{padding-inline-end:2rem}.lx-px-0{padding-inline:0}.lx-px-1{padding-inline:.25rem}.lx-px-2{padding-inline:.5rem}.lx-px-3{padding-inline:.75rem}.lx-px-4{padding-inline:1rem}.lx-px-5{padding-inline:1.25rem}.lx-px-6{padding-inline:1.5rem}.lx-px-8{padding-inline:2rem}.lx-py-0{padding-block:0}.lx-py-1{padding-block:.25rem}.lx-py-2{padding-block:.5rem}.lx-py-3{padding-block:.75rem}.lx-py-4{padding-block:1rem}.lx-py-5{padding-block:1.25rem}.lx-py-6{padding-block:1.5rem}.lx-py-8{padding-block:2rem}.lx-text-xs{font-size:.75rem}.lx-text-sm{font-size:.875rem}.lx-text-base{font-size:1rem}.lx-text-lg{font-size:1.125rem}.lx-text-xl{font-size:1.25rem}.lx-text-2xl{font-size:1.5rem}.lx-text-3xl{font-size:1.875rem}.lx-text-4xl{font-size:2.25rem}.lx-text-5xl{font-size:3rem}.lx-text-left{text-align:left}.lx-text-center{text-align:center}.lx-text-right{text-align:right}.lx-text-justify{text-align:justify}.lx-text-start{text-align:start}.lx-text-end{text-align:end}.lx-font-thin{font-weight:100}.lx-font-extralight{font-weight:200}.lx-font-light{font-weight:300}.lx-font-normal{font-weight:400}.lx-font-medium{font-weight:500}.lx-font-semibold{font-weight:600}.lx-font-bold{font-weight:700}.lx-font-extrabold{font-weight:800}.lx-font-black{font-weight:900}.lx-italic{font-style:italic}.lx-not-italic{font-style:normal}.lx-uppercase{text-transform:uppercase}.lx-lowercase{text-transform:lowercase}.lx-capitalize{text-transform:capitalize}.lx-normal-case{text-transform:none}.lx-underline{text-decoration-line:underline}.lx-overline{text-decoration-line:overline}.lx-line-through{text-decoration-line:line-through}.lx-no-underline{text-decoration:none}.lx-tracking-tighter{letter-spacing:-.05em}.lx-tracking-tight{letter-spacing:-.025em}.lx-tracking-normal{letter-spacing:0}.lx-tracking-wide{letter-spacing:.025em}.lx-tracking-wider{letter-spacing:.05em}.lx-tracking-widest{letter-spacing:.1em}.lx-leading-none{line-height:1}.lx-leading-tight{line-height:1.25}.lx-leading-snug{line-height:1.375}.lx-leading-normal{line-height:1.6}.lx-leading-relaxed{line-height:1.75}.lx-leading-loose{line-height:2}.lx-text-truncate,.lx-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lx-line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.lx-line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.lx-line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.lx-line-clamp-4{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4}.lx-whitespace-nowrap{white-space:nowrap}.lx-whitespace-pre{white-space:pre}.lx-whitespace-pre-wrap{white-space:pre-wrap}.lx-whitespace-normal{white-space:normal}.lx-break-all{word-break:break-all}.lx-break-words{overflow-wrap:break-word}.lx-word-break{word-break:break-all}.lx-text-primary{color:var(--lx-primary,#3b82f6)}.lx-text-secondary{color:var(--lx-secondary,#6b7280)}.lx-text-success{color:var(--lx-success,#22c55e)}.lx-text-warning{color:var(--lx-warning,#f59e0b)}.lx-text-danger{color:var(--lx-danger,#ef4444)}.lx-text-info{color:var(--lx-info,#06b6d4)}.lx-text-dark{color:var(--lx-dark,#1f2937)}.lx-text-light{color:var(--lx-light,#f9fafb)}.lx-text-white{color:#fff}.lx-text-black{color:#000}.lx-text-muted{color:var(--text-muted,#9ca3af)}.lx-text-body{color:var(--text-primary,#111827)}.lx-text-opacity-75{opacity:.75;color:color-mix(in srgb,currentColor 75%,transparent)!important}.lx-text-opacity-50{opacity:.5;color:color-mix(in srgb,currentColor 50%,transparent)!important}.lx-text-opacity-25{opacity:.25;color:color-mix(in srgb,currentColor 25%,transparent)!important}.lx-bg-primary{background-color:var(--lx-primary,#3b82f6)}.lx-bg-secondary{background-color:var(--lx-secondary,#6b7280)}.lx-bg-success{background-color:var(--lx-success,#22c55e)}.lx-bg-warning{background-color:var(--lx-warning,#f59e0b)}.lx-bg-danger{background-color:var(--lx-danger,#ef4444)}.lx-bg-info{background-color:var(--lx-info,#06b6d4)}.lx-bg-dark{background-color:var(--lx-dark,#1f2937)}.lx-bg-light{background-color:var(--lx-light,#f9fafb)}.lx-bg-white{background-color:#fff}.lx-bg-transparent{background-color:transparent}.lx-bg-primary-soft{background-color:color-mix(in srgb,var(--lx-primary,#3b82f6) 12%,#fff)}.lx-bg-success-soft{background-color:color-mix(in srgb,var(--lx-success,#22c55e) 12%,#fff)}.lx-bg-warning-soft{background-color:color-mix(in srgb,var(--lx-warning,#f59e0b) 12%,#fff)}.lx-bg-danger-soft{background-color:color-mix(in srgb,var(--lx-danger,#ef4444) 12%,#fff)}.lx-bg-opacity-75{opacity:.75}.lx-bg-opacity-50{opacity:.5}.lx-bg-opacity-25{opacity:.25}.lx-bg-opacity-10{opacity:.1}.lx-w-auto{width:auto}.lx-w-full{width:100%}.lx-w-screen{width:100vw}.lx-w-fit{width:fit-content}.lx-w-1\/2{width:50%}.lx-w-1\/3{width:33.333%}.lx-w-2\/3{width:66.666%}.lx-w-1\/4{width:25%}.lx-w-3\/4{width:75%}.lx-w-1\/5{width:20%}.lx-w-4\/5{width:80%}.lx-w-4{width:1rem}.lx-w-6{width:1.5rem}.lx-w-8{width:2rem}.lx-w-12{width:3rem}.lx-w-16{width:4rem}.lx-w-24{width:6rem}.lx-w-32{width:8rem}.lx-w-48{width:12rem}.lx-w-64{width:16rem}.lx-h-auto{height:auto}.lx-h-full{height:100%}.lx-h-screen{height:100vh}.lx-h-fit{height:fit-content}.lx-h-4{height:1rem}.lx-h-6{height:1.5rem}.lx-h-8{height:2rem}.lx-h-12{height:3rem}.lx-h-16{height:4rem}.lx-h-24{height:6rem}.lx-h-32{height:8rem}.lx-min-w-0{min-width:0}.lx-max-w-full{max-width:100%}.lx-max-w-screen-sm{max-width:640px}.lx-max-w-screen-md{max-width:768px}.lx-max-w-screen-lg{max-width:1024px}.lx-max-w-screen-xl{max-width:1280px}.lx-min-h-screen{min-height:100vh}.lx-max-h-screen{max-height:100vh}.lx-max-h-64{max-height:16rem}.lx-size-4{width:1rem;height:1rem}.lx-size-6{width:1.5rem;height:1.5rem}.lx-size-8{width:2rem;height:2rem}.lx-size-12{width:3rem;height:3rem}.lx-size-16{width:4rem;height:4rem}.lx-static{position:static}.lx-relative{position:relative}.lx-absolute{position:absolute}.lx-fixed{position:fixed}.lx-sticky{position:sticky}.lx-top-0{top:0}.lx-top-50{top:50%}.lx-top-100{top:100%}.lx-top-auto{top:auto}.lx-bottom-0{bottom:0}.lx-bottom-50{bottom:50%}.lx-bottom-auto{bottom:auto}.lx-start-0{inset-inline-start:0}.lx-start-50{inset-inline-start:50%}.lx-start-auto{inset-inline-start:auto}.lx-end-0{inset-inline-end:0}.lx-end-50{inset-inline-end:50%}.lx-end-auto{inset-inline-end:auto}.lx-inset-0{inset:0}.lx-translate-middle{transform:translate(-50%,-50%)}.lx-translate-middle-x{transform:translateX(-50%)}.lx-translate-middle-y{transform:translateY(-50%)}.lx-sticky-top{position:sticky;top:0;z-index:var(--lx-z-sticky,1020)}.lx-border{border:1px solid var(--border-default,#e5e7eb)}.lx-border-0{border:0!important}.lx-border-2{border-width:2px}.lx-border-3{border-width:3px}.lx-border-t{border-top:1px solid var(--border-default,#e5e7eb)}.lx-border-b{border-bottom:1px solid var(--border-default,#e5e7eb)}.lx-border-s{border-inline-start:1px solid var(--border-default,#e5e7eb)}.lx-border-e{border-inline-end:1px solid var(--border-default,#e5e7eb)}.lx-border-t-0{border-top:0}.lx-border-b-0{border-bottom:0}.lx-border-primary{border-color:var(--lx-primary,#3b82f6)!important}.lx-border-success{border-color:var(--lx-success,#22c55e)!important}.lx-border-danger{border-color:var(--lx-danger,#ef4444)!important}.lx-border-warning{border-color:var(--lx-warning,#f59e0b)!important}.lx-border-white{border-color:#fff!important}.lx-border-opacity-50{border-color:color-mix(in srgb,currentColor 50%,transparent)!important}.lx-rounded-none{border-radius:0}.lx-rounded-sm{border-radius:4px}.lx-rounded{border-radius:8px}.lx-rounded-md{border-radius:12px}.lx-rounded-lg{border-radius:16px}.lx-rounded-xl{border-radius:24px}.lx-rounded-2xl{border-radius:32px}.lx-rounded-full{border-radius:9999px}.lx-rounded-t{border-top-left-radius:8px;border-top-right-radius:8px}.lx-rounded-b{border-bottom-left-radius:8px;border-bottom-right-radius:8px}.lx-rounded-s{border-top-left-radius:8px;border-bottom-left-radius:8px}.lx-rounded-e{border-top-right-radius:8px;border-bottom-right-radius:8px}.lx-shadow-none{box-shadow:none!important}.lx-shadow-xs{box-shadow:0 1px 2px rgba(0,0,0,.04)}.lx-shadow-sm{box-shadow:0 1px 3px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.04)}.lx-shadow{box-shadow:0 4px 6px -1px rgba(0,0,0,.07),0 2px 4px -2px rgba(0,0,0,.05)}.lx-shadow-md{box-shadow:0 8px 12px -3px rgba(0,0,0,.08),0 4px 6px -4px rgba(0,0,0,.05)}.lx-shadow-lg{box-shadow:0 16px 24px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.05)}.lx-shadow-xl{box-shadow:0 24px 40px -8px rgba(0,0,0,.12),0 12px 16px -8px rgba(0,0,0,.06)}.lx-shadow-2xl{box-shadow:0 40px 60px -12px rgba(0,0,0,.18)}.lx-shadow-inner{box-shadow:inset 0 2px 4px rgba(0,0,0,.06)}.lx-overflow-auto{overflow:auto}.lx-overflow-hidden{overflow:hidden}.lx-overflow-visible{overflow:visible}.lx-overflow-scroll{overflow:scroll}.lx-overflow-x-auto{overflow-x:auto}.lx-overflow-y-auto{overflow-y:auto}.lx-overflow-x-hidden{overflow-x:hidden}.lx-overflow-y-hidden{overflow-y:hidden}.lx-overflow-x-scroll{overflow-x:scroll}.lx-overflow-y-scroll{overflow-y:scroll}.lx-visible{visibility:visible}.lx-invisible{visibility:hidden}.lx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.lx-sr-only-focusable:focus,.lx-sr-only-focusable:focus-within{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.lx-pointer-events-none{pointer-events:none}.lx-pointer-events-auto{pointer-events:auto}.lx-select-none{user-select:none}.lx-select-all{user-select:all}.lx-select-text{user-select:text}.lx-cursor-pointer{cursor:pointer}.lx-cursor-default{cursor:default}.lx-cursor-auto{cursor:auto}.lx-cursor-not-allowed{cursor:not-allowed}.lx-cursor-wait{cursor:wait}.lx-cursor-move{cursor:move}.lx-cursor-grab{cursor:grab}.lx-cursor-text{cursor:text}.lx-float-start{float:inline-start}.lx-float-end{float:inline-end}.lx-float-none{float:none}.lx-clearfix::after{content:"";display:table;clear:both}.lx-align-baseline{vertical-align:baseline}.lx-align-top{vertical-align:top}.lx-align-middle{vertical-align:middle}.lx-align-bottom{vertical-align:bottom}.lx-align-text-top{vertical-align:text-top}.lx-align-text-bottom{vertical-align:text-bottom}.lx-align-sub{vertical-align:sub}.lx-align-super{vertical-align:super}.lx-object-cover{object-fit:cover}.lx-object-contain{object-fit:contain}.lx-object-fill{object-fit:fill}.lx-object-none{object-fit:none}.lx-object-center{object-position:center}.lx-object-top{object-position:top}.lx-opacity-0{opacity:0}.lx-opacity-25{opacity:.25}.lx-opacity-50{opacity:.5}.lx-opacity-75{opacity:.75}.lx-opacity-100{opacity:1}.lx-text-opacity-80{color:color-mix(in srgb,currentColor 80%,transparent)!important}.lx-z-n1{z-index:-1}.lx-z-0{z-index:0}.lx-z-10{z-index:10}.lx-z-20{z-index:20}.lx-z-50{z-index:50}.lx-z-dropdown{z-index:1000}.lx-z-sticky{z-index:1020}.lx-z-fixed{z-index:1030}.lx-z-offcanvas{z-index:1040}.lx-z-modal-bg{z-index:1050}.lx-z-modal{z-index:1060}.lx-z-popover{z-index:1070}.lx-z-tooltip{z-index:1080}.lx-z-toast{z-index:1090}.lx-ratio{position:relative;width:100%}.lx-ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.lx-ratio::before{display:block;content:"";padding-top:calc(var(--lx-aspect-ratio) * 100%)}.lx-ratio-1x1{--lx-aspect-ratio:1}.lx-ratio-4x3{--lx-aspect-ratio:calc(3/4)}.lx-ratio-16x9{--lx-aspect-ratio:calc(9/16)}.lx-ratio-21x9{--lx-aspect-ratio:calc(9/21)}.lx-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}@media(min-width:640px){.lx-sm-block{display:block}.lx-sm-flex{display:flex}.lx-sm-grid{display:grid}.lx-sm-hidden{display:none}.lx-sm-text-center{text-align:center}.lx-sm-text-left{text-align:left}.lx-sm-w-full{width:100%}.lx-sm-w-auto{width:auto}}@media(min-width:768px){.lx-md-block{display:block}.lx-md-flex{display:flex}.lx-md-grid{display:grid}.lx-md-hidden{display:none}.lx-md-inline-flex{display:inline-flex}.lx-md-inline-block{display:inline-block}.lx-md-flex-row{flex-direction:row}.lx-md-flex-col{flex-direction:column}.lx-md-justify-center{justify-content:center}.lx-md-justify-between{justify-content:space-between}.lx-md-items-center{align-items:center}.lx-md-items-start{align-items:flex-start}.lx-md-text-center{text-align:center}.lx-md-text-left{text-align:left}.lx-md-text-right{text-align:right}.lx-md-text-sm{font-size:.875rem}.lx-md-text-base{font-size:1rem}.lx-md-text-lg{font-size:1.125rem}.lx-md-text-xl{font-size:1.25rem}.lx-md-text-2xl{font-size:1.5rem}.lx-md-text-3xl{font-size:1.875rem}.lx-md-p-0{padding:0}.lx-md-p-2{padding:.5rem}.lx-md-p-4{padding:1rem}.lx-md-p-6{padding:1.5rem}.lx-md-p-8{padding:2rem}.lx-md-px-4{padding-inline:1rem}.lx-md-px-6{padding-inline:1.5rem}.lx-md-px-8{padding-inline:2rem}.lx-md-py-4{padding-block:1rem}.lx-md-py-6{padding-block:1.5rem}.lx-md-py-8{padding-block:2rem}.lx-md-mt-0{margin-top:0}.lx-md-mt-4{margin-top:1rem}.lx-md-mt-8{margin-top:2rem}.lx-md-w-full{width:100%}.lx-md-w-auto{width:auto}.lx-md-w-1\/2{width:50%}.lx-md-float-start{float:inline-start}.lx-md-float-end{float:inline-end}.lx-md-float-none{float:none}}@media(min-width:1024px){.lx-lg-block{display:block}.lx-lg-flex{display:flex}.lx-lg-grid{display:grid}.lx-lg-hidden{display:none}.lx-lg-inline-flex{display:inline-flex}.lx-lg-inline-block{display:inline-block}.lx-lg-flex-row{flex-direction:row}.lx-lg-flex-col{flex-direction:column}.lx-lg-justify-center{justify-content:center}.lx-lg-justify-between{justify-content:space-between}.lx-lg-items-center{align-items:center}.lx-lg-text-base{font-size:1rem}.lx-lg-text-lg{font-size:1.125rem}.lx-lg-text-xl{font-size:1.25rem}.lx-lg-text-2xl{font-size:1.5rem}.lx-lg-text-3xl{font-size:1.875rem}.lx-lg-text-4xl{font-size:2.25rem}.lx-lg-p-4{padding:1rem}.lx-lg-p-6{padding:1.5rem}.lx-lg-p-8{padding:2rem}.lx-lg-p-12{padding:3rem}.lx-lg-px-6{padding-inline:1.5rem}.lx-lg-px-8{padding-inline:2rem}.lx-lg-px-12{padding-inline:3rem}.lx-lg-py-4{padding-block:1rem}.lx-lg-py-6{padding-block:1.5rem}.lx-lg-py-8{padding-block:2rem}.lx-lg-w-auto{width:auto}.lx-lg-w-full{width:100%}}@media(min-width:1280px){.lx-xl-block{display:block}.lx-xl-flex{display:flex}.lx-xl-grid{display:grid}.lx-xl-hidden{display:none}}
@@ -0,0 +1,2 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */[data-editor-theme=github-dark],[data-editor-theme]{--bg:#0d1117;--bg2:#161b22;--bg3:#21262d;--surface:#2d333b;--text:#e6edf3;--muted:#7d8590;--dim:#484f58;--accent:#58a6ff;--accent-bg:rgba(88,166,255,.1);--success:#3fb950;--success-bg:rgba(63,185,80,.1);--warn:#d29922;--warn-bg:rgba(210,153,34,.12);--danger:#f85149;--danger-bg:rgba(248,81,73,.12);--info:#79c0ff;--info-bg:rgba(121,192,255,.1);--syntax-string:#a5d6ff;--syntax-number:#79c0ff;--syntax-keyword:#ff7b72;--syntax-function:#d2a8ff;--syntax-comment:#8b949e;--syntax-attr:#79c0ff;--syntax-tag:#7ee787;--syntax-variable:#ffa657}[data-editor-theme=github-light]{--bg:#fff;--bg2:#f6f8fa;--bg3:#eaeef2;--surface:#f0f2f5;--text:#1f2328;--muted:#656d76;--dim:#9198a1;--accent:#0969da;--accent-bg:rgba(9,105,218,.08);--success:#1a7f37;--success-bg:rgba(26,127,55,.1);--warn:#9a6700;--warn-bg:rgba(154,103,0,.1);--danger:#d1242f;--danger-bg:rgba(209,36,47,.1);--info:#0969da;--info-bg:rgba(9,105,218,.08);--syntax-string:#0a3069;--syntax-number:#033b8b;--syntax-keyword:#d1242f;--syntax-function:#6f42c1;--syntax-comment:#79a8be;--syntax-attr:#0969da;--syntax-tag:#116329;--syntax-variable:#bf8700}[data-editor-theme=dracula]{--bg:#282a36;--bg2:#1e1f2b;--bg3:#44475a;--surface:#383a47;--text:#f8f8f2;--muted:#6272a4;--dim:#44475a;--accent:#bd93f9;--accent-bg:rgba(189,147,249,.12);--success:#50fa7b;--success-bg:rgba(80,250,123,.1);--warn:#f1fa8c;--warn-bg:rgba(241,250,140,.1);--danger:#ff5555;--danger-bg:rgba(255,85,85,.12);--info:#8be9fd;--info-bg:rgba(139,233,253,.1);--syntax-string:#f1fa8c;--syntax-number:#bd93f9;--syntax-keyword:#ff79c6;--syntax-function:#50fa7b;--syntax-comment:#6272a4;--syntax-attr:#8be9fd;--syntax-tag:#ff79c6;--syntax-variable:#ffb86c}[data-editor-theme=nord]{--bg:#2e3440;--bg2:#3b4252;--bg3:#434c5e;--surface:#4c566a;--text:#eceff4;--muted:#d8dee9;--dim:#4c566a;--accent:#88c0d0;--accent-bg:rgba(136,192,208,.12);--success:#a3be8c;--success-bg:rgba(163,190,140,.12);--warn:#ebcb8b;--warn-bg:rgba(235,203,139,.12);--danger:#bf616a;--danger-bg:rgba(191,97,106,.12);--info:#81a1c1;--info-bg:rgba(129,161,193,.1);--syntax-string:#a3be8c;--syntax-number:#b48ead;--syntax-keyword:#81a1c1;--syntax-function:#88c0d0;--syntax-comment:#616e88;--syntax-attr:#8fbcbb;--syntax-tag:#81a1c1;--syntax-variable:#d08770}[data-editor-theme=monokai]{--bg:#272822;--bg2:#1e1f1c;--bg3:#3e3d32;--surface:#49483e;--text:#f8f8f2;--muted:#75715e;--dim:#49483e;--accent:#66d9e8;--accent-bg:rgba(102,217,232,.12);--success:#a6e22e;--success-bg:rgba(166,226,46,.1);--warn:#e6db74;--warn-bg:rgba(230,219,116,.1);--danger:#f92672;--danger-bg:rgba(249,38,114,.12);--info:#a1efe4;--info-bg:rgba(161,239,228,.1);--syntax-string:#e6db74;--syntax-number:#ae81ff;--syntax-keyword:#f92672;--syntax-function:#a6e22e;--syntax-comment:#75715e;--syntax-attr:#66d9e8;--syntax-tag:#f92672;--syntax-variable:#fd971f}[data-editor-theme=solarized-dark]{--bg:#002b36;--bg2:#073642;--bg3:#0d3f4e;--surface:#586e75;--text:#93a1a1;--muted:#657b83;--dim:#586e75;--accent:#268bd2;--accent-bg:rgba(38,139,210,.12);--success:#859900;--success-bg:rgba(133,153,0,.12);--warn:#b58900;--warn-bg:rgba(181,137,0,.12);--danger:#dc322f;--danger-bg:rgba(220,50,47,.12);--info:#2aa198;--info-bg:rgba(42,161,152,.1);--syntax-string:#2aa198;--syntax-number:#d33682;--syntax-keyword:#859900;--syntax-function:#268bd2;--syntax-comment:#586e75;--syntax-attr:#268bd2;--syntax-tag:#859900;--syntax-variable:#b58900}[data-editor-theme=solarized-light]{--bg:#fdf6e3;--bg2:#eee8d5;--bg3:#e3ddc8;--surface:#d5cfc0;--text:#657b83;--muted:#839496;--dim:#93a1a1;--accent:#268bd2;--accent-bg:rgba(38,139,210,.1);--success:#859900;--success-bg:rgba(133,153,0,.1);--warn:#b58900;--warn-bg:rgba(181,137,0,.1);--danger:#dc322f;--danger-bg:rgba(220,50,47,.1);--info:#2aa198;--info-bg:rgba(42,161,152,.1);--syntax-string:#2aa198;--syntax-number:#d33682;--syntax-keyword:#859900;--syntax-function:#268bd2;--syntax-comment:#93a1a1;--syntax-attr:#268bd2;--syntax-tag:#859900;--syntax-variable:#b58900}[data-editor-theme=tokyo-night]{--bg:#1a1b26;--bg2:#16161e;--bg3:#292e42;--surface:#3b4261;--text:#c0caf5;--muted:#7aa2f7;--dim:#565f89;--accent:#7aa2f7;--accent-bg:rgba(122,162,247,.12);--success:#9ece6a;--success-bg:rgba(158,206,106,.1);--warn:#e0af68;--warn-bg:rgba(224,175,104,.1);--danger:#f7768e;--danger-bg:rgba(247,118,142,.12);--info:#7aa2f7;--info-bg:rgba(122,162,247,.12);--syntax-string:#9ece6a;--syntax-number:#ff9e64;--syntax-keyword:#bb9af7;--syntax-function:#7aa2f7;--syntax-comment:#565f89;--syntax-attr:#7aa2f7;--syntax-tag:#f7768e;--syntax-variable:#e0af68}[data-editor-theme=catppuccin]{--bg:#1e1e2e;--bg2:#313244;--bg3:#45475a;--surface:#585b70;--text:#cdd6f4;--muted:#a6adc8;--dim:#6c7086;--accent:#89b4fa;--accent-bg:rgba(137,180,250,.12);--success:#a6e3a1;--success-bg:rgba(166,227,161,.1);--warn:#f9e2af;--warn-bg:rgba(249,226,175,.1);--danger:#f38ba8;--danger-bg:rgba(243,139,168,.12);--info:#89dceb;--info-bg:rgba(137,220,235,.1);--syntax-string:#a6e3a1;--syntax-number:#fab387;--syntax-keyword:#cba6f7;--syntax-function:#89b4fa;--syntax-comment:#6c7086;--syntax-attr:#89dceb;--syntax-tag:#f38ba8;--syntax-variable:#f9e2af}[data-editor-theme=gruvbox-dark]{--bg:#282828;--bg2:#1d2021;--bg3:#3c3836;--surface:#504945;--text:#fbf1c7;--muted:#928374;--dim:#665c54;--accent:#83a598;--accent-bg:rgba(131,165,152,.12);--success:#b8bb26;--success-bg:rgba(184,187,38,.1);--warn:#fabd2f;--warn-bg:rgba(250,189,47,.1);--danger:#fb4934;--danger-bg:rgba(251,73,52,.12);--info:#8ec07c;--info-bg:rgba(142,192,124,.1);--syntax-string:#b8bb26;--syntax-number:#d3869b;--syntax-keyword:#fb4934;--syntax-function:#8ec07c;--syntax-comment:#928374;--syntax-attr:#83a598;--syntax-tag:#fb4934;--syntax-variable:#fabd2f}[data-editor-theme=gruvbox-light]{--bg:#f9f5d5;--bg2:#fbf1c7;--bg3:#eee6d9;--surface:#d5c4a1;--text:#3c3735;--muted:#7c6f64;--dim:#928374;--accent:#076678;--accent-bg:rgba(7,102,120,.1);--success:#79740e;--success-bg:rgba(121,116,14,.1);--warn:#b57614;--warn-bg:rgba(181,118,20,.1);--danger:#9d0006;--danger-bg:rgba(157,0,6,.1);--info:#427b58;--info-bg:rgba(66,123,88,.1);--syntax-string:#79740e;--syntax-number:#8f3f71;--syntax-keyword:#9d0006;--syntax-function:#427b58;--syntax-comment:#a89984;--syntax-attr:#076678;--syntax-tag:#9d0006;--syntax-variable:#b57614}[data-editor-theme=one-light]{--bg:#fafafa;--bg2:#f0f0f0;--bg3:#e5e5e6;--surface:#d0d0d0;--text:#383a42;--muted:#696c77;--dim:#a0a1a7;--accent:#4078f2;--accent-bg:rgba(64,120,242,.1);--success:#50a14f;--success-bg:rgba(80,161,79,.1);--warn:#c18401;--warn-bg:rgba(193,132,1,.1);--danger:#e45649;--danger-bg:rgba(228,86,73,.1);--info:#0184bc;--info-bg:rgba(1,132,188,.1);--syntax-string:#50a14f;--syntax-number:#986801;--syntax-keyword:#a626a4;--syntax-function:#4078f2;--syntax-comment:#a0a1a7;--syntax-attr:#0184bc;--syntax-tag:#e45649;--syntax-variable:#c18401}/* Utilities */ [data-editor-theme]{background-color:var(--bg);color:var(--text);font-family:SFMono-Regular,"JetBrains Mono",Consolas,"Liberation Mono",Menlo,"Courier New",monospace}[data-editor-theme] code,[data-editor-theme] pre{background-color:var(--bg2);color:var(--text)}[data-editor-theme] .success{color:var(--success);background-color:var(--success-bg)}[data-editor-theme] .warn,[data-editor-theme] .warning{color:var(--warn);background-color:var(--warn-bg)}[data-editor-theme] .danger,[data-editor-theme] .error{color:var(--danger);background-color:var(--danger-bg)}[data-editor-theme] .info{color:var(--info);background-color:var(--info-bg)}[data-editor-theme] .accent{color:var(--accent);background-color:var(--accent-bg)}[data-editor-theme] .text-muted{color:var(--muted)}[data-editor-theme] .text-dim{color:var(--dim)}.str{color:var(--syntax-string)}.num{color:var(--syntax-number)}.kwd{color:var(--syntax-keyword)}.fn{color:var(--syntax-function)}.cmt{color:var(--syntax-comment);font-style:italic}.tag{color:var(--syntax-tag)}.var{color:var(--syntax-variable)}.attr{color:var(--syntax-attr)}
@@ -0,0 +1,2 @@
1
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */
2
+ /*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id *//*! LxUI v1.0.0 | MIT License | https://ui.lancar.id */:root{--font-system:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-default:"Plus Jakarta Sans","Inter","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--font-modern:"Inter","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--font-smooth:"Manrope","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--font-tech:"IBM Plex Sans","Menlo","Consolas","Courier New",monospace;--font-accessibility:"Atkinson Hyperlegible","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--font-classic:"Literata","Georgia","Times New Roman",serif;--font-serif:"Source Serif 4","Source Serif Pro","Georgia","Times New Roman",serif;--font-editorial:"Merriweather","Georgia","Times New Roman",serif;--font-mono:"SFMono-Regular","JetBrains Mono","Fira Code",Consolas,"Liberation Mono",Menlo,"Courier New",monospace}body,html{font-family:var(--font-default);font-size:16px;line-height:1.6;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-family:var(--font-default);font-weight:700;letter-spacing:-.02em;margin-top:1.5em;margin-bottom:.5em}h1{font-size:clamp(1.75rem,4vw + 1rem,2.5rem);line-height:1.2}h2{font-size:clamp(1.5rem,3vw + .8rem,2rem);line-height:1.3}h3{font-size:clamp(1.25rem,2.5vw + .6rem,1.75rem);line-height:1.3}h4{font-size:clamp(1.125rem,2vw + .5rem,1.5rem);line-height:1.4}h5{font-size:clamp(1rem,1.5vw + .4rem,1.25rem);line-height:1.4}h6{font-size:1rem;line-height:1.5;font-weight:600}.lx-display-1{font-size:clamp(3rem,6vw+1rem,5rem);font-weight:700;line-height:1.1;letter-spacing:-.03em}.lx-display-2{font-size:clamp(2.5rem,5vw+1rem,4.5rem);font-weight:700;line-height:1.1;letter-spacing:-.03em}.lx-display-3{font-size:clamp(2rem,4vw+1rem,4rem);font-weight:700;line-height:1.2;letter-spacing:-.02em}.lx-display-4{font-size:clamp(1.75rem,3.5vw+.8rem,3.5rem);font-weight:700;line-height:1.2;letter-spacing:-.02em}.lx-lead{font-size:clamp(1.125rem,1.5vw+.5rem,1.25rem);font-weight:400;line-height:1.7}p{margin-top:0;margin-bottom:1em}a{color:var(--accent,#3b82f6);text-decoration:none;transition:color .2s}a:hover{color:var(--accent-hover,#2563eb);text-decoration:underline}a:focus-visible{outline:2px solid var(--accent,#3b82f6);outline-offset:2px;border-radius:3px}code,pre{font-family:var(--font-mono);font-size:.9em;border-radius:4px}code{padding:2px 6px;background:var(--bg-secondary,#f3f4f6);border:1px solid var(--border-subtle,#e5e7eb)}pre{padding:1rem;overflow-x:auto;line-height:1.6;background:var(--bg-secondary,#f3f4f6);border:1px solid var(--border-subtle,#e5e7eb)}pre code{background:0 0;border:none;padding:0}kbd{font-family:var(--font-mono);font-size:.875em;padding:.125rem .375rem;background:var(--bg-tertiary,#e5e7eb);border:1px solid var(--border-default,#d1d5db);border-radius:4px}mark{background:#fef08a;color:inherit;padding:.1em .2em;border-radius:2px}.lx-blockquote,blockquote{border-inline-start:4px solid var(--accent,#3b82f6);padding:.75rem 1.25rem;margin:1.5rem 0;background:var(--bg-secondary,#f9fafb);border-radius:0 var(--lx-radius,8px) var(--lx-radius,8px) 0}.lx-blockquote-footer{color:var(--text-muted,#6b7280);font-size:.875em;margin-top:.5rem}.lx-blockquote-footer::before{content:"— "}.lx-small,small{font-size:.875em;color:var(--text-secondary,#6b7280)}b,strong{font-weight:700}em,i{font-style:italic}.lx-hr,hr{border:none;border-top:1px solid var(--border-subtle,#e5e7eb);margin:1.5rem 0}::selection{background:var(--accent-subtle,#dbeafe);color:var(--accent,#1d4ed8)}.font-system{font-family:var(--font-system)!important}.font-default{font-family:var(--font-default)!important}.font-modern{font-family:var(--font-modern)!important}.font-smooth{font-family:var(--font-smooth)!important}.font-tech{font-family:var(--font-tech)!important}.font-classic{font-family:var(--font-classic)!important}.font-serif{font-family:var(--font-serif)!important}.font-editorial{font-family:var(--font-editorial)!important}.font-accessibility{font-family:var(--font-accessibility)!important}.font-mono{font-family:var(--font-mono)!important}