@transcodes/ui-components 0.3.0 → 0.3.1

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 (46) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +124 -79
  3. package/dist/controllers/animation.controller.js +32 -0
  4. package/dist/controllers/base.controller.js +8 -0
  5. package/dist/controllers/form-validation.controller.js +49 -0
  6. package/dist/controllers/history.controller.js +26 -0
  7. package/dist/controllers/loading.controller.js +27 -0
  8. package/dist/controllers/match-media.controller.js +20 -0
  9. package/dist/controllers/message-bus.controller.js +45 -0
  10. package/dist/controllers/storage.controller.js +40 -0
  11. package/dist/index.js +80 -0
  12. package/dist/primitives/tc-box.js +38 -0
  13. package/dist/primitives/tc-button.js +167 -0
  14. package/dist/primitives/tc-callout.js +86 -0
  15. package/dist/primitives/tc-card.js +76 -0
  16. package/dist/primitives/tc-chip.js +79 -0
  17. package/dist/primitives/tc-container.js +62 -0
  18. package/dist/primitives/tc-divider.js +76 -0
  19. package/dist/primitives/tc-error-message.js +74 -0
  20. package/dist/primitives/tc-form-header.js +120 -0
  21. package/dist/primitives/tc-icon.js +95 -0
  22. package/dist/primitives/tc-input-with-chip.js +242 -0
  23. package/dist/primitives/tc-input.js +262 -0
  24. package/dist/primitives/tc-item-button.js +168 -0
  25. package/dist/primitives/tc-item.js +93 -0
  26. package/dist/primitives/tc-otp-input.js +230 -0
  27. package/dist/primitives/tc-section.js +48 -0
  28. package/dist/primitives/tc-spinner.js +87 -0
  29. package/dist/primitives/tc-symbol.js +56 -0
  30. package/dist/primitives/tc-text.js +145 -0
  31. package/dist/primitives/tc-toast.js +189 -0
  32. package/dist/screens/tc-error-screen.js +119 -0
  33. package/dist/screens/tc-loading-screen.js +77 -0
  34. package/dist/screens/tc-success-screen.js +192 -0
  35. package/dist/styles/shared.js +7 -0
  36. package/dist/widgets/tc-authenticator-card.js +213 -0
  37. package/dist/widgets/tc-floating-button.js +132 -0
  38. package/dist/widgets/tc-iframe-modal.js +263 -0
  39. package/dist/widgets/tc-installation-banner.js +234 -0
  40. package/dist/widgets/tc-ios-installation-guide.js +240 -0
  41. package/dist/widgets/tc-notification-modal.js +230 -0
  42. package/dist/widgets/tc-offline-modal.js +202 -0
  43. package/dist/widgets/tc-page-decoration.js +126 -0
  44. package/package.json +25 -7
  45. package/dist/ui-components.css +0 -1
  46. package/dist/ui-components.js +0 -4981
@@ -0,0 +1,234 @@
1
+ import { LitElement as d, html as p, css as m } from "lit";
2
+ import { property as r, state as h, customElement as u } from "lit/decorators.js";
3
+ import { AnimationController as v } from "../controllers/animation.controller.js";
4
+ import { StorageController as b } from "../controllers/storage.controller.js";
5
+ import { sharedStyles as y } from "../styles/shared.js";
6
+ var g = Object.defineProperty, f = Object.getOwnPropertyDescriptor, s = (i, a, o, n) => {
7
+ for (var e = n > 1 ? void 0 : n ? f(a, o) : a, l = i.length - 1, c; l >= 0; l--)
8
+ (c = i[l]) && (e = (n ? c(a, o, e) : c(e)) || e);
9
+ return n && e && g(a, o, e), e;
10
+ };
11
+ let t = class extends d {
12
+ constructor() {
13
+ super(...arguments), this.title = "Install App", this.description = "Add to your home screen for quick access", this.installLabel = "Install", this.storageKey = "tc-install-banner-dismissed", this.dismissDays = 7, this.isDismissed = !1, this.animation = new v(this, {
14
+ showDuration: 400,
15
+ hideDuration: 300
16
+ }), this.storage = new b(
17
+ this,
18
+ this.storageKey
19
+ );
20
+ }
21
+ connectedCallback() {
22
+ super.connectedCallback(), this.updateDataState(), this.checkDismissState();
23
+ }
24
+ checkDismissState() {
25
+ const i = this.storage.value;
26
+ i?.dismissedAt && ((Date.now() - i.dismissedAt) / 864e5 < this.dismissDays ? this.isDismissed = !0 : this.storage.remove());
27
+ }
28
+ updateDataState() {
29
+ this.dataset.state = this.animation.state;
30
+ }
31
+ async show() {
32
+ this.isDismissed || (await this.animation.show(), this.updateDataState());
33
+ }
34
+ async dismiss() {
35
+ this.storage.set({ dismissedAt: Date.now() }), await this.animation.hide(), this.updateDataState(), this.dispatchEvent(
36
+ new CustomEvent("tc-dismiss", {
37
+ bubbles: !0,
38
+ composed: !0
39
+ })
40
+ );
41
+ }
42
+ handleInstall() {
43
+ this.dispatchEvent(
44
+ new CustomEvent("tc-install", {
45
+ bubbles: !0,
46
+ composed: !0
47
+ })
48
+ );
49
+ }
50
+ handleClose() {
51
+ this.dismiss();
52
+ }
53
+ render() {
54
+ return p`
55
+ <div part="banner" class="banner" role="banner">
56
+ <div part="icon" class="icon">
57
+ <tc-icon name="download" size="1.5rem"></tc-icon>
58
+ </div>
59
+ <div part="content" class="content">
60
+ <tc-text part="title" class="title" size="base" weight="600">
61
+ ${this.title}
62
+ </tc-text>
63
+ <tc-text part="description" class="description" size="sm" color="tertiary">
64
+ ${this.description}
65
+ </tc-text>
66
+ </div>
67
+ <div part="actions" class="actions">
68
+ <tc-button
69
+ part="install"
70
+ variant="primary"
71
+ size="small"
72
+ @tc-click=${this.handleInstall}
73
+ >
74
+ ${this.installLabel}
75
+ </tc-button>
76
+ <button part="close" class="close" @click=${this.handleClose} aria-label="Dismiss">
77
+ <svg
78
+ viewBox="0 0 24 24"
79
+ fill="none"
80
+ stroke="currentColor"
81
+ stroke-width="2"
82
+ stroke-linecap="round"
83
+ stroke-linejoin="round"
84
+ >
85
+ <line x1="18" y1="6" x2="6" y2="18"></line>
86
+ <line x1="6" y1="6" x2="18" y2="18"></line>
87
+ </svg>
88
+ </button>
89
+ </div>
90
+ </div>
91
+ `;
92
+ }
93
+ };
94
+ t.styles = [
95
+ y,
96
+ m`
97
+ :host {
98
+ display: block;
99
+ position: fixed;
100
+ bottom: 0;
101
+ left: 0;
102
+ right: 0;
103
+ z-index: 100;
104
+ padding: var(--space-md);
105
+ pointer-events: none;
106
+ }
107
+
108
+ .banner {
109
+ display: flex;
110
+ align-items: center;
111
+ gap: var(--space-md);
112
+ padding: var(--space-md) var(--space-lg);
113
+ background: var(--paper-white);
114
+ border-radius: var(--radius-lg);
115
+ box-shadow: 0 -4px 20px var(--overlay-shadow-light);
116
+ pointer-events: auto;
117
+ opacity: 0;
118
+ transform: translateY(100%);
119
+ transition: opacity var(--transition-smooth), transform var(--transition-smooth);
120
+ }
121
+
122
+ :host([data-state='showing']) .banner,
123
+ :host([data-state='visible']) .banner {
124
+ opacity: 1;
125
+ transform: translateY(0);
126
+ }
127
+
128
+ :host([data-state='hiding']) .banner {
129
+ opacity: 0;
130
+ transform: translateY(100%);
131
+ }
132
+
133
+ :host([data-state='hidden']) {
134
+ display: none;
135
+ }
136
+
137
+ .icon {
138
+ flex-shrink: 0;
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ width: 3rem;
143
+ height: 3rem;
144
+ background: linear-gradient(135deg, var(--accent-primary), var(--accent-primary-hover));
145
+ border-radius: var(--radius-md);
146
+ color: white;
147
+ }
148
+
149
+ .content {
150
+ flex: 1;
151
+ min-width: 0;
152
+ }
153
+
154
+ .title {
155
+ font-weight: 600;
156
+ color: var(--ink-dark);
157
+ }
158
+
159
+ .description {
160
+ color: var(--ink-medium);
161
+ margin-top: 2px;
162
+ }
163
+
164
+ .actions {
165
+ display: flex;
166
+ align-items: center;
167
+ gap: var(--space-sm);
168
+ }
169
+
170
+ .close {
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: center;
174
+ width: var(--size-close-button);
175
+ height: var(--size-close-button);
176
+ padding: 0;
177
+ border: none;
178
+ background: transparent;
179
+ color: var(--ink-light);
180
+ cursor: pointer;
181
+ border-radius: var(--radius-sm);
182
+ transition: var(--transition-fast);
183
+ }
184
+
185
+ .close:hover {
186
+ background: var(--paper-warm);
187
+ color: var(--ink-medium);
188
+ }
189
+
190
+ .close svg {
191
+ width: 1.25rem;
192
+ height: 1.25rem;
193
+ }
194
+
195
+ @media (max-width: 480px) {
196
+ .banner {
197
+ flex-wrap: wrap;
198
+ }
199
+
200
+ .content {
201
+ flex-basis: calc(100% - 4rem);
202
+ }
203
+
204
+ .actions {
205
+ flex-basis: 100%;
206
+ justify-content: flex-end;
207
+ }
208
+ }
209
+ `
210
+ ];
211
+ s([
212
+ r({ type: String })
213
+ ], t.prototype, "title", 2);
214
+ s([
215
+ r({ type: String })
216
+ ], t.prototype, "description", 2);
217
+ s([
218
+ r({ type: String, attribute: "install-label" })
219
+ ], t.prototype, "installLabel", 2);
220
+ s([
221
+ r({ type: String, attribute: "storage-key" })
222
+ ], t.prototype, "storageKey", 2);
223
+ s([
224
+ r({ type: Number, attribute: "dismiss-days" })
225
+ ], t.prototype, "dismissDays", 2);
226
+ s([
227
+ h()
228
+ ], t.prototype, "isDismissed", 2);
229
+ t = s([
230
+ u("tc-installation-banner")
231
+ ], t);
232
+ export {
233
+ t as TcInstallationBanner
234
+ };
@@ -0,0 +1,240 @@
1
+ import { LitElement as p, html as l, css as h } from "lit";
2
+ import { property as c, customElement as v } from "lit/decorators.js";
3
+ import { AnimationController as m } from "../controllers/animation.controller.js";
4
+ import { sharedStyles as u } from "../styles/shared.js";
5
+ var y = Object.defineProperty, g = Object.getOwnPropertyDescriptor, d = (t, e, a, s) => {
6
+ for (var i = s > 1 ? void 0 : s ? g(e, a) : e, o = t.length - 1, n; o >= 0; o--)
7
+ (n = t[o]) && (i = (s ? n(e, a, i) : n(i)) || i);
8
+ return s && i && y(e, a, i), i;
9
+ };
10
+ let r = class extends p {
11
+ constructor() {
12
+ super(...arguments), this.title = "Install on iOS", this.steps = [
13
+ "Tap the Share button in Safari",
14
+ 'Scroll down and tap "Add to Home Screen"',
15
+ 'Tap "Add" in the top right corner'
16
+ ], this.animation = new m(this, {
17
+ showDuration: 300,
18
+ hideDuration: 200
19
+ });
20
+ }
21
+ connectedCallback() {
22
+ super.connectedCallback(), this.updateDataState();
23
+ }
24
+ updateDataState() {
25
+ this.dataset.state = this.animation.state;
26
+ }
27
+ async show() {
28
+ await this.animation.show(), this.updateDataState();
29
+ }
30
+ async close() {
31
+ await this.animation.hide(), this.updateDataState(), this.dispatchEvent(
32
+ new CustomEvent("tc-close", {
33
+ bubbles: !0,
34
+ composed: !0
35
+ })
36
+ );
37
+ }
38
+ handleOverlayClick(t) {
39
+ t.target === t.currentTarget && this.close();
40
+ }
41
+ renderStep(t, e) {
42
+ const a = t.split("[share]"), s = a.length > 1 ? l`${a[0]}<svg class="share-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
43
+ <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"></path>
44
+ <polyline points="16 6 12 2 8 6"></polyline>
45
+ <line x1="12" y1="2" x2="12" y2="15"></line>
46
+ </svg>${a[1]}` : t;
47
+ return l`
48
+ <div part="step" class="step">
49
+ <span part="step-number" class="step-number">${e + 1}</span>
50
+ <tc-text part="step-text" class="step-text" size="base">${s}</tc-text>
51
+ </div>
52
+ `;
53
+ }
54
+ render() {
55
+ return l`
56
+ <div part="overlay" class="overlay" @click=${this.handleOverlayClick}>
57
+ <div part="modal" class="modal" role="dialog" aria-modal="true" aria-labelledby="guide-title">
58
+ <div part="header" class="header">
59
+ <h2 id="guide-title" class="title">${this.title}</h2>
60
+ <button part="close" class="close" @click=${this.close} aria-label="Close">
61
+ <svg
62
+ viewBox="0 0 24 24"
63
+ fill="none"
64
+ stroke="currentColor"
65
+ stroke-width="2"
66
+ stroke-linecap="round"
67
+ stroke-linejoin="round"
68
+ >
69
+ <line x1="18" y1="6" x2="6" y2="18"></line>
70
+ <line x1="6" y1="6" x2="18" y2="18"></line>
71
+ </svg>
72
+ </button>
73
+ </div>
74
+ <div part="content" class="content">
75
+ <div part="steps" class="steps">
76
+ ${this.steps.map((t, e) => this.renderStep(t, e))}
77
+ </div>
78
+ </div>
79
+ <div part="action" class="action">
80
+ <tc-button variant="primary" @tc-click=${this.close}>Got it</tc-button>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ `;
85
+ }
86
+ };
87
+ r.styles = [
88
+ u,
89
+ h`
90
+ :host {
91
+ display: contents;
92
+ }
93
+
94
+ .overlay {
95
+ position: fixed;
96
+ inset: 0;
97
+ z-index: 1000;
98
+ display: flex;
99
+ align-items: flex-end;
100
+ justify-content: center;
101
+ background: var(--overlay-dim);
102
+ opacity: 0;
103
+ visibility: hidden;
104
+ transition: opacity var(--transition-smooth), visibility var(--transition-smooth);
105
+ }
106
+
107
+ :host([data-state='showing']) .overlay,
108
+ :host([data-state='visible']) .overlay {
109
+ opacity: 1;
110
+ visibility: visible;
111
+ }
112
+
113
+ :host([data-state='hiding']) .overlay {
114
+ opacity: 0;
115
+ }
116
+
117
+ :host([data-state='hidden']) .overlay {
118
+ visibility: hidden;
119
+ }
120
+
121
+ .modal {
122
+ width: 100%;
123
+ max-width: 400px;
124
+ margin: var(--space-md);
125
+ padding: var(--space-lg);
126
+ background: var(--paper-white);
127
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
128
+ transform: translateY(100%);
129
+ transition: transform var(--transition-smooth);
130
+ }
131
+
132
+ :host([data-state='showing']) .modal,
133
+ :host([data-state='visible']) .modal {
134
+ transform: translateY(0);
135
+ }
136
+
137
+ :host([data-state='hiding']) .modal {
138
+ transform: translateY(100%);
139
+ }
140
+
141
+ .header {
142
+ display: flex;
143
+ align-items: center;
144
+ justify-content: space-between;
145
+ margin-bottom: var(--space-lg);
146
+ }
147
+
148
+ .title {
149
+ font-family: var(--font-body);
150
+ font-size: var(--font-size-lg);
151
+ font-weight: 600;
152
+ color: var(--ink-dark);
153
+ margin: 0;
154
+ }
155
+
156
+ .close {
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ width: var(--size-close-button);
161
+ height: var(--size-close-button);
162
+ padding: 0;
163
+ border: none;
164
+ background: transparent;
165
+ color: var(--ink-medium);
166
+ cursor: pointer;
167
+ border-radius: var(--radius-sm);
168
+ transition: var(--transition-fast);
169
+ }
170
+
171
+ .close:hover {
172
+ background: var(--paper-warm);
173
+ color: var(--ink-dark);
174
+ }
175
+
176
+ .close svg {
177
+ width: 1.25rem;
178
+ height: 1.25rem;
179
+ }
180
+
181
+ .steps {
182
+ display: flex;
183
+ flex-direction: column;
184
+ gap: var(--space-md);
185
+ }
186
+
187
+ .step {
188
+ display: flex;
189
+ align-items: flex-start;
190
+ gap: var(--space-md);
191
+ }
192
+
193
+ .step-number {
194
+ flex-shrink: 0;
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ width: 1.75rem;
199
+ height: 1.75rem;
200
+ background: var(--accent-primary);
201
+ color: white;
202
+ font-family: var(--font-body);
203
+ font-size: var(--font-size-sm);
204
+ font-weight: 600;
205
+ border-radius: var(--radius-full);
206
+ }
207
+
208
+ .step-text {
209
+ flex: 1;
210
+ padding-top: 2px;
211
+ color: var(--ink-dark);
212
+ line-height: 1.5;
213
+ }
214
+
215
+ .share-icon {
216
+ display: inline-flex;
217
+ vertical-align: middle;
218
+ width: 1.25rem;
219
+ height: 1.25rem;
220
+ margin: 0 2px;
221
+ color: var(--accent-primary);
222
+ }
223
+
224
+ .action {
225
+ margin-top: var(--space-xl);
226
+ }
227
+ `
228
+ ];
229
+ d([
230
+ c({ type: String })
231
+ ], r.prototype, "title", 2);
232
+ d([
233
+ c({ type: Array })
234
+ ], r.prototype, "steps", 2);
235
+ r = d([
236
+ v("tc-ios-installation-guide")
237
+ ], r);
238
+ export {
239
+ r as TcIosInstallationGuide
240
+ };
@@ -0,0 +1,230 @@
1
+ import { LitElement as d, html as p, css as h } from "lit";
2
+ import { property as o, customElement as m } from "lit/decorators.js";
3
+ import { AnimationController as y } from "../controllers/animation.controller.js";
4
+ import { StorageController as u } from "../controllers/storage.controller.js";
5
+ import { sharedStyles as v } from "../styles/shared.js";
6
+ var b = Object.defineProperty, g = Object.getOwnPropertyDescriptor, i = (t, s, n, r) => {
7
+ for (var a = r > 1 ? void 0 : r ? g(s, n) : s, l = t.length - 1, c; l >= 0; l--)
8
+ (c = t[l]) && (a = (r ? c(s, n, a) : c(a)) || a);
9
+ return r && a && b(s, n, a), a;
10
+ };
11
+ let e = class extends d {
12
+ constructor() {
13
+ super(...arguments), this.title = "Enable Notifications", this.description = "Stay updated with important alerts and messages.", this.allowLabel = "Allow", this.denyLabel = "Not Now", this.storageKey = "tc-notification-modal-state", this.animation = new y(this, {
14
+ showDuration: 300,
15
+ hideDuration: 200
16
+ }), this.storage = new u(this, this.storageKey);
17
+ }
18
+ connectedCallback() {
19
+ super.connectedCallback(), this.updateDataState();
20
+ }
21
+ updateDataState() {
22
+ this.dataset.state = this.animation.state;
23
+ }
24
+ /**
25
+ * Check if the modal should be shown based on stored state.
26
+ */
27
+ shouldShow() {
28
+ const t = this.storage.value;
29
+ return !(t?.dismissed || t?.permission === "granted");
30
+ }
31
+ async show() {
32
+ this.shouldShow() && (await this.animation.show(), this.updateDataState());
33
+ }
34
+ async close() {
35
+ await this.animation.hide(), this.updateDataState(), this.dispatchEvent(
36
+ new CustomEvent("tc-close", {
37
+ bubbles: !0,
38
+ composed: !0
39
+ })
40
+ );
41
+ }
42
+ handleOverlayClick(t) {
43
+ t.target === t.currentTarget && this.handleDeny();
44
+ }
45
+ handleAllow() {
46
+ this.storage.set({ dismissed: !0, permission: "granted" }), this.close(), this.dispatchEvent(
47
+ new CustomEvent("tc-allow", {
48
+ bubbles: !0,
49
+ composed: !0
50
+ })
51
+ );
52
+ }
53
+ handleDeny() {
54
+ this.storage.set({ dismissed: !0, permission: "denied" }), this.close(), this.dispatchEvent(
55
+ new CustomEvent("tc-deny", {
56
+ bubbles: !0,
57
+ composed: !0
58
+ })
59
+ );
60
+ }
61
+ render() {
62
+ return p`
63
+ <div part="overlay" class="overlay" @click=${this.handleOverlayClick}>
64
+ <div
65
+ part="modal"
66
+ class="modal"
67
+ role="dialog"
68
+ aria-modal="true"
69
+ aria-labelledby="notification-title"
70
+ aria-describedby="notification-description"
71
+ >
72
+ <div part="icon" class="icon-container">
73
+ <tc-icon name="bell" size="2rem"></tc-icon>
74
+ </div>
75
+ <tc-section part="content" class="content" gap="var(--space-sm)">
76
+ <tc-text
77
+ id="notification-title"
78
+ part="title"
79
+ class="title"
80
+ tag="h2"
81
+ size="lg"
82
+ weight="600"
83
+ >
84
+ ${this.title}
85
+ </tc-text>
86
+ <tc-text
87
+ id="notification-description"
88
+ part="description"
89
+ size="base"
90
+ color="tertiary"
91
+ >
92
+ ${this.description}
93
+ </tc-text>
94
+ </tc-section>
95
+ <div part="actions" class="actions">
96
+ <tc-button variant="primary" @tc-click=${this.handleAllow}>
97
+ ${this.allowLabel}
98
+ </tc-button>
99
+ <button class="deny-button" @click=${this.handleDeny}>
100
+ ${this.denyLabel}
101
+ </button>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ `;
106
+ }
107
+ };
108
+ e.styles = [
109
+ v,
110
+ h`
111
+ :host {
112
+ display: contents;
113
+ }
114
+
115
+ .overlay {
116
+ position: fixed;
117
+ inset: 0;
118
+ z-index: 1000;
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ padding: var(--space-lg);
123
+ background: var(--overlay-dim);
124
+ opacity: 0;
125
+ visibility: hidden;
126
+ transition: opacity var(--transition-smooth), visibility var(--transition-smooth);
127
+ }
128
+
129
+ :host([data-state='showing']) .overlay,
130
+ :host([data-state='visible']) .overlay {
131
+ opacity: 1;
132
+ visibility: visible;
133
+ }
134
+
135
+ :host([data-state='hiding']) .overlay {
136
+ opacity: 0;
137
+ }
138
+
139
+ :host([data-state='hidden']) .overlay {
140
+ visibility: hidden;
141
+ }
142
+
143
+ .modal {
144
+ display: flex;
145
+ flex-direction: column;
146
+ align-items: center;
147
+ width: 100%;
148
+ max-width: 320px;
149
+ padding: var(--space-xl);
150
+ background: var(--paper-white);
151
+ border-radius: var(--radius-lg);
152
+ box-shadow: 0 20px 60px var(--overlay-shadow-strong);
153
+ text-align: center;
154
+ transform: scale(0.95);
155
+ transition: transform var(--transition-smooth);
156
+ }
157
+
158
+ :host([data-state='showing']) .modal,
159
+ :host([data-state='visible']) .modal {
160
+ transform: scale(1);
161
+ }
162
+
163
+ :host([data-state='hiding']) .modal {
164
+ transform: scale(0.95);
165
+ }
166
+
167
+ .icon-container {
168
+ display: flex;
169
+ align-items: center;
170
+ justify-content: center;
171
+ width: 4rem;
172
+ height: 4rem;
173
+ margin-bottom: var(--space-lg);
174
+ background: var(--alpha-primary10);
175
+ border-radius: var(--radius-full);
176
+ color: var(--accent-primary);
177
+ }
178
+
179
+ .content {
180
+ margin-bottom: var(--space-xl);
181
+ }
182
+
183
+ .title {
184
+ margin-bottom: var(--space-sm);
185
+ }
186
+
187
+ .actions {
188
+ display: flex;
189
+ flex-direction: column;
190
+ gap: var(--space-sm);
191
+ width: 100%;
192
+ }
193
+
194
+ .deny-button {
195
+ background: transparent;
196
+ border: none;
197
+ padding: var(--space-sm);
198
+ font-family: var(--font-body);
199
+ font-size: var(--font-size-sm);
200
+ color: var(--ink-medium);
201
+ cursor: pointer;
202
+ transition: color var(--transition-fast);
203
+ }
204
+
205
+ .deny-button:hover {
206
+ color: var(--ink-dark);
207
+ }
208
+ `
209
+ ];
210
+ i([
211
+ o({ type: String })
212
+ ], e.prototype, "title", 2);
213
+ i([
214
+ o({ type: String })
215
+ ], e.prototype, "description", 2);
216
+ i([
217
+ o({ type: String, attribute: "allow-label" })
218
+ ], e.prototype, "allowLabel", 2);
219
+ i([
220
+ o({ type: String, attribute: "deny-label" })
221
+ ], e.prototype, "denyLabel", 2);
222
+ i([
223
+ o({ type: String, attribute: "storage-key" })
224
+ ], e.prototype, "storageKey", 2);
225
+ e = i([
226
+ m("tc-notification-modal")
227
+ ], e);
228
+ export {
229
+ e as TcNotificationModal
230
+ };