@aigne/afs-ui 1.11.0-beta.12

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 (196) hide show
  1. package/LICENSE.md +26 -0
  2. package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
  4. package/dist/aup-protocol.cjs +235 -0
  5. package/dist/aup-protocol.d.cts +78 -0
  6. package/dist/aup-protocol.d.cts.map +1 -0
  7. package/dist/aup-protocol.d.mts +78 -0
  8. package/dist/aup-protocol.d.mts.map +1 -0
  9. package/dist/aup-protocol.mjs +235 -0
  10. package/dist/aup-protocol.mjs.map +1 -0
  11. package/dist/aup-registry.cjs +2489 -0
  12. package/dist/aup-registry.mjs +2487 -0
  13. package/dist/aup-registry.mjs.map +1 -0
  14. package/dist/aup-spec.cjs +1467 -0
  15. package/dist/aup-spec.mjs +1466 -0
  16. package/dist/aup-spec.mjs.map +1 -0
  17. package/dist/aup-types.cjs +165 -0
  18. package/dist/aup-types.d.cts +157 -0
  19. package/dist/aup-types.d.cts.map +1 -0
  20. package/dist/aup-types.d.mts +157 -0
  21. package/dist/aup-types.d.mts.map +1 -0
  22. package/dist/aup-types.mjs +157 -0
  23. package/dist/aup-types.mjs.map +1 -0
  24. package/dist/backend.cjs +14 -0
  25. package/dist/backend.d.cts +104 -0
  26. package/dist/backend.d.cts.map +1 -0
  27. package/dist/backend.d.mts +104 -0
  28. package/dist/backend.d.mts.map +1 -0
  29. package/dist/backend.mjs +13 -0
  30. package/dist/backend.mjs.map +1 -0
  31. package/dist/degradation.cjs +85 -0
  32. package/dist/degradation.d.cts +17 -0
  33. package/dist/degradation.d.cts.map +1 -0
  34. package/dist/degradation.d.mts +17 -0
  35. package/dist/degradation.d.mts.map +1 -0
  36. package/dist/degradation.mjs +84 -0
  37. package/dist/degradation.mjs.map +1 -0
  38. package/dist/index.cjs +36 -0
  39. package/dist/index.d.cts +12 -0
  40. package/dist/index.d.mts +12 -0
  41. package/dist/index.mjs +13 -0
  42. package/dist/runtime.cjs +117 -0
  43. package/dist/runtime.d.cts +59 -0
  44. package/dist/runtime.d.cts.map +1 -0
  45. package/dist/runtime.d.mts +59 -0
  46. package/dist/runtime.d.mts.map +1 -0
  47. package/dist/runtime.mjs +118 -0
  48. package/dist/runtime.mjs.map +1 -0
  49. package/dist/session.cjs +159 -0
  50. package/dist/session.d.cts +80 -0
  51. package/dist/session.d.cts.map +1 -0
  52. package/dist/session.d.mts +80 -0
  53. package/dist/session.d.mts.map +1 -0
  54. package/dist/session.mjs +159 -0
  55. package/dist/session.mjs.map +1 -0
  56. package/dist/snapshot.cjs +162 -0
  57. package/dist/snapshot.mjs +163 -0
  58. package/dist/snapshot.mjs.map +1 -0
  59. package/dist/term-page.cjs +264 -0
  60. package/dist/term-page.mjs +264 -0
  61. package/dist/term-page.mjs.map +1 -0
  62. package/dist/term.cjs +295 -0
  63. package/dist/term.d.cts +84 -0
  64. package/dist/term.d.cts.map +1 -0
  65. package/dist/term.d.mts +84 -0
  66. package/dist/term.d.mts.map +1 -0
  67. package/dist/term.mjs +296 -0
  68. package/dist/term.mjs.map +1 -0
  69. package/dist/tty.cjs +136 -0
  70. package/dist/tty.d.cts +53 -0
  71. package/dist/tty.d.cts.map +1 -0
  72. package/dist/tty.d.mts +53 -0
  73. package/dist/tty.d.mts.map +1 -0
  74. package/dist/tty.mjs +135 -0
  75. package/dist/tty.mjs.map +1 -0
  76. package/dist/ui-provider.cjs +4615 -0
  77. package/dist/ui-provider.d.cts +307 -0
  78. package/dist/ui-provider.d.cts.map +1 -0
  79. package/dist/ui-provider.d.mts +307 -0
  80. package/dist/ui-provider.d.mts.map +1 -0
  81. package/dist/ui-provider.mjs +4616 -0
  82. package/dist/ui-provider.mjs.map +1 -0
  83. package/dist/web-page/core.cjs +1388 -0
  84. package/dist/web-page/core.mjs +1387 -0
  85. package/dist/web-page/core.mjs.map +1 -0
  86. package/dist/web-page/css.cjs +1699 -0
  87. package/dist/web-page/css.mjs +1698 -0
  88. package/dist/web-page/css.mjs.map +1 -0
  89. package/dist/web-page/icons.cjs +248 -0
  90. package/dist/web-page/icons.mjs +248 -0
  91. package/dist/web-page/icons.mjs.map +1 -0
  92. package/dist/web-page/overlay-themes.cjs +514 -0
  93. package/dist/web-page/overlay-themes.mjs +513 -0
  94. package/dist/web-page/overlay-themes.mjs.map +1 -0
  95. package/dist/web-page/renderers/action.cjs +72 -0
  96. package/dist/web-page/renderers/action.mjs +72 -0
  97. package/dist/web-page/renderers/action.mjs.map +1 -0
  98. package/dist/web-page/renderers/broadcast.cjs +160 -0
  99. package/dist/web-page/renderers/broadcast.mjs +160 -0
  100. package/dist/web-page/renderers/broadcast.mjs.map +1 -0
  101. package/dist/web-page/renderers/calendar.cjs +137 -0
  102. package/dist/web-page/renderers/calendar.mjs +137 -0
  103. package/dist/web-page/renderers/calendar.mjs.map +1 -0
  104. package/dist/web-page/renderers/canvas.cjs +173 -0
  105. package/dist/web-page/renderers/canvas.mjs +173 -0
  106. package/dist/web-page/renderers/canvas.mjs.map +1 -0
  107. package/dist/web-page/renderers/cdn-loader.cjs +25 -0
  108. package/dist/web-page/renderers/cdn-loader.mjs +25 -0
  109. package/dist/web-page/renderers/cdn-loader.mjs.map +1 -0
  110. package/dist/web-page/renderers/chart.cjs +101 -0
  111. package/dist/web-page/renderers/chart.mjs +101 -0
  112. package/dist/web-page/renderers/chart.mjs.map +1 -0
  113. package/dist/web-page/renderers/deck.cjs +390 -0
  114. package/dist/web-page/renderers/deck.mjs +390 -0
  115. package/dist/web-page/renderers/deck.mjs.map +1 -0
  116. package/dist/web-page/renderers/device.cjs +1015 -0
  117. package/dist/web-page/renderers/device.mjs +1015 -0
  118. package/dist/web-page/renderers/device.mjs.map +1 -0
  119. package/dist/web-page/renderers/editor.cjs +127 -0
  120. package/dist/web-page/renderers/editor.mjs +127 -0
  121. package/dist/web-page/renderers/editor.mjs.map +1 -0
  122. package/dist/web-page/renderers/finance-chart.cjs +178 -0
  123. package/dist/web-page/renderers/finance-chart.mjs +178 -0
  124. package/dist/web-page/renderers/finance-chart.mjs.map +1 -0
  125. package/dist/web-page/renderers/frame.cjs +274 -0
  126. package/dist/web-page/renderers/frame.mjs +274 -0
  127. package/dist/web-page/renderers/frame.mjs.map +1 -0
  128. package/dist/web-page/renderers/globe.cjs +119 -0
  129. package/dist/web-page/renderers/globe.mjs +119 -0
  130. package/dist/web-page/renderers/globe.mjs.map +1 -0
  131. package/dist/web-page/renderers/input.cjs +137 -0
  132. package/dist/web-page/renderers/input.mjs +137 -0
  133. package/dist/web-page/renderers/input.mjs.map +1 -0
  134. package/dist/web-page/renderers/list.cjs +1243 -0
  135. package/dist/web-page/renderers/list.mjs +1243 -0
  136. package/dist/web-page/renderers/list.mjs.map +1 -0
  137. package/dist/web-page/renderers/map.cjs +126 -0
  138. package/dist/web-page/renderers/map.mjs +126 -0
  139. package/dist/web-page/renderers/map.mjs.map +1 -0
  140. package/dist/web-page/renderers/media.cjs +106 -0
  141. package/dist/web-page/renderers/media.mjs +106 -0
  142. package/dist/web-page/renderers/media.mjs.map +1 -0
  143. package/dist/web-page/renderers/moonphase.cjs +105 -0
  144. package/dist/web-page/renderers/moonphase.mjs +105 -0
  145. package/dist/web-page/renderers/moonphase.mjs.map +1 -0
  146. package/dist/web-page/renderers/natal-chart.cjs +222 -0
  147. package/dist/web-page/renderers/natal-chart.mjs +222 -0
  148. package/dist/web-page/renderers/natal-chart.mjs.map +1 -0
  149. package/dist/web-page/renderers/overlay.cjs +531 -0
  150. package/dist/web-page/renderers/overlay.mjs +531 -0
  151. package/dist/web-page/renderers/overlay.mjs.map +1 -0
  152. package/dist/web-page/renderers/table.cjs +74 -0
  153. package/dist/web-page/renderers/table.mjs +74 -0
  154. package/dist/web-page/renderers/table.mjs.map +1 -0
  155. package/dist/web-page/renderers/terminal.cjs +30 -0
  156. package/dist/web-page/renderers/terminal.mjs +30 -0
  157. package/dist/web-page/renderers/terminal.mjs.map +1 -0
  158. package/dist/web-page/renderers/text.cjs +109 -0
  159. package/dist/web-page/renderers/text.mjs +109 -0
  160. package/dist/web-page/renderers/text.mjs.map +1 -0
  161. package/dist/web-page/renderers/ticker.cjs +133 -0
  162. package/dist/web-page/renderers/ticker.mjs +133 -0
  163. package/dist/web-page/renderers/ticker.mjs.map +1 -0
  164. package/dist/web-page/renderers/time.cjs +69 -0
  165. package/dist/web-page/renderers/time.mjs +69 -0
  166. package/dist/web-page/renderers/time.mjs.map +1 -0
  167. package/dist/web-page/renderers/unknown.cjs +20 -0
  168. package/dist/web-page/renderers/unknown.mjs +20 -0
  169. package/dist/web-page/renderers/unknown.mjs.map +1 -0
  170. package/dist/web-page/renderers/view.cjs +161 -0
  171. package/dist/web-page/renderers/view.mjs +161 -0
  172. package/dist/web-page/renderers/view.mjs.map +1 -0
  173. package/dist/web-page/renderers/wm.cjs +669 -0
  174. package/dist/web-page/renderers/wm.mjs +669 -0
  175. package/dist/web-page/renderers/wm.mjs.map +1 -0
  176. package/dist/web-page/skeleton.cjs +103 -0
  177. package/dist/web-page/skeleton.mjs +103 -0
  178. package/dist/web-page/skeleton.mjs.map +1 -0
  179. package/dist/web-page.cjs +114 -0
  180. package/dist/web-page.d.cts +19 -0
  181. package/dist/web-page.d.cts.map +1 -0
  182. package/dist/web-page.d.mts +19 -0
  183. package/dist/web-page.d.mts.map +1 -0
  184. package/dist/web-page.mjs +115 -0
  185. package/dist/web-page.mjs.map +1 -0
  186. package/dist/web.cjs +827 -0
  187. package/dist/web.d.cts +144 -0
  188. package/dist/web.d.cts.map +1 -0
  189. package/dist/web.d.mts +144 -0
  190. package/dist/web.d.mts.map +1 -0
  191. package/dist/web.mjs +828 -0
  192. package/dist/web.mjs.map +1 -0
  193. package/dist/wm-state.cjs +172 -0
  194. package/dist/wm-state.mjs +171 -0
  195. package/dist/wm-state.mjs.map +1 -0
  196. package/package.json +59 -0
@@ -0,0 +1,513 @@
1
+ //#region src/web-page/overlay-themes.ts
2
+ /**
3
+ * Overlay Theme System — broadcast "graphics packages" for overlay-grid.
4
+ *
5
+ * Three built-in themes: minimal (default), cnn (hard-edge news), apple (frosted glass).
6
+ * Theme CSS is injected on-demand when _applyOverlayTheme is called.
7
+ * Font loading is lazy — Google Fonts <link> injected only when a theme activates.
8
+ *
9
+ * 12 broadcast roles styled per theme:
10
+ * live-badge, clock, viewer-count, speaker-bar, hashtag, logo,
11
+ * data-widget, alert, featured-comment, score-bug, lower-third, ticker-item
12
+ *
13
+ * Specificity strategy:
14
+ * - Role selectors use [data-overlay-theme][data-overlay-theme] double-attr
15
+ * to reach (0,3,0), beating primitive defaults like .aup-text[data-mode] (0,2,0).
16
+ * - Color inheritance is forced on all children inside themed overlay-grid
17
+ * so primitive default `color: var(--text)` doesn't override theme colors.
18
+ * - Ticker gets a dedicated override for .aup-ticker color.
19
+ */
20
+ const OVERLAY_THEMES_CSS = `
21
+ /* ── Overlay Theme: minimal ── */
22
+ [data-overlay-theme="minimal"] {
23
+ --overlay-badge-bg: rgba(0,0,0,0.6);
24
+ --overlay-badge-color: #fff;
25
+ --overlay-badge-radius: 6px;
26
+ --overlay-badge-font: inherit;
27
+ --overlay-badge-size: 0.85rem;
28
+ --overlay-badge-weight: 600;
29
+ --overlay-card-bg: rgba(0,0,0,0.5);
30
+ --overlay-card-color: #fff;
31
+ --overlay-card-border: 1px solid rgba(255,255,255,0.1);
32
+ --overlay-card-radius: 8px;
33
+ --overlay-glass-blur: 8px;
34
+ --overlay-lower-bg: rgba(0,0,0,0.5);
35
+ --overlay-lower-color: #fff;
36
+ --overlay-lower-accent: rgba(255,255,255,0.3);
37
+ --overlay-lower-radius: 8px;
38
+ --overlay-lower-size: 1rem;
39
+ --overlay-ticker-bg: rgba(0,0,0,0.6);
40
+ --overlay-ticker-color: #fff;
41
+ --overlay-ticker-size: 0.85rem;
42
+ --overlay-alert-bg: rgba(220,38,38,0.85);
43
+ --overlay-alert-color: #fff;
44
+ --overlay-alert-size: 0.9rem;
45
+ --overlay-score-bg: rgba(0,0,0,0.7);
46
+ --overlay-score-color: #fff;
47
+ --overlay-score-radius: 6px;
48
+ --overlay-viewer-bg: rgba(0,0,0,0.4);
49
+ --overlay-viewer-color: #fff;
50
+ }
51
+
52
+ /* ── Overlay Theme: cnn ── */
53
+ [data-overlay-theme="cnn"] {
54
+ --overlay-badge-bg: #cc0000;
55
+ --overlay-badge-color: #fff;
56
+ --overlay-badge-radius: 2px;
57
+ --overlay-badge-font: "Barlow Condensed", "Arial Narrow", sans-serif;
58
+ --overlay-badge-size: 1rem;
59
+ --overlay-badge-weight: 700;
60
+ --overlay-card-bg: rgba(0,0,0,0.9);
61
+ --overlay-card-color: #fff;
62
+ --overlay-card-border: 4px solid #cc0000;
63
+ --overlay-card-radius: 0;
64
+ --overlay-glass-blur: 0;
65
+ --overlay-lower-bg: rgba(0,0,0,0.9);
66
+ --overlay-lower-color: #fff;
67
+ --overlay-lower-accent: #cc0000;
68
+ --overlay-lower-radius: 0;
69
+ --overlay-lower-size: 1.15rem;
70
+ --overlay-ticker-bg: #111;
71
+ --overlay-ticker-color: #fff;
72
+ --overlay-ticker-size: 0.95rem;
73
+ --overlay-alert-bg: #fbbf24;
74
+ --overlay-alert-color: #111;
75
+ --overlay-alert-size: 1.05rem;
76
+ --overlay-score-bg: #1a1a1a;
77
+ --overlay-score-color: #fff;
78
+ --overlay-score-radius: 0;
79
+ --overlay-viewer-bg: rgba(0,0,0,0.6);
80
+ --overlay-viewer-color: rgba(255,255,255,0.9);
81
+ }
82
+
83
+ /* ── Overlay Theme: apple ── */
84
+ [data-overlay-theme="apple"] {
85
+ --overlay-badge-bg: rgba(0,0,0,0.4);
86
+ --overlay-badge-color: #fff;
87
+ --overlay-badge-radius: 20px;
88
+ --overlay-badge-font: "Inter", -apple-system, sans-serif;
89
+ --overlay-badge-size: 0.78rem;
90
+ --overlay-badge-weight: 500;
91
+ --overlay-card-bg: rgba(0,0,0,0.3);
92
+ --overlay-card-color: #fff;
93
+ --overlay-card-border: 1px solid rgba(255,255,255,0.18);
94
+ --overlay-card-radius: 16px;
95
+ --overlay-glass-blur: 20px;
96
+ --overlay-lower-bg: rgba(0,0,0,0.3);
97
+ --overlay-lower-color: #fff;
98
+ --overlay-lower-accent: rgba(255,255,255,0.2);
99
+ --overlay-lower-radius: 16px;
100
+ --overlay-lower-size: 0.95rem;
101
+ --overlay-ticker-bg: rgba(0,0,0,0.25);
102
+ --overlay-ticker-color: rgba(255,255,255,0.95);
103
+ --overlay-ticker-size: 0.82rem;
104
+ --overlay-alert-bg: rgba(220,38,38,0.8);
105
+ --overlay-alert-color: #fff;
106
+ --overlay-alert-size: 0.88rem;
107
+ --overlay-score-bg: rgba(0,0,0,0.3);
108
+ --overlay-score-color: #fff;
109
+ --overlay-score-radius: 12px;
110
+ --overlay-viewer-bg: rgba(0,0,0,0.3);
111
+ --overlay-viewer-color: rgba(255,255,255,0.9);
112
+ }
113
+
114
+ /* ══════════════════════════════════════════════════════════
115
+ Force color inheritance inside themed overlay-grid.
116
+ Primitives (.aup-text, .aup-ticker etc.) normally set
117
+ color: var(--text) which overrides theme colors.
118
+ This resets all children to inherit from their role/region container.
119
+ Double-attr [data-overlay-theme][data-overlay-theme] => (0,3,0)
120
+ beats .aup-text[data-mode="badge"][data-intent="info"] (0,3,1) — close but
121
+ we use * to catch all children.
122
+ ══════════════════════════════════════════════════════════ */
123
+
124
+ [data-overlay-theme] [data-role] *,
125
+ [data-overlay-theme] [data-role] {
126
+ color: inherit;
127
+ font-family: inherit;
128
+ }
129
+
130
+ /* Ticker: the .aup-ticker inside [data-region="ticker"] sets its own color.
131
+ Force it and all its children to inherit the region's color. */
132
+ [data-overlay-theme] > [data-region="ticker"],
133
+ [data-overlay-theme] > [data-region="ticker"] *,
134
+ [data-overlay-theme] > [data-region="ticker"] .aup-ticker {
135
+ color: var(--overlay-ticker-color) !important;
136
+ }
137
+
138
+ /* ── Role styles — doubled attribute for (0,3,0) specificity ── */
139
+
140
+ /* live-badge */
141
+ [data-overlay-theme] [data-role="live-badge"][data-role] {
142
+ display: inline-flex; align-items: center; gap: 6px;
143
+ background: var(--overlay-badge-bg); color: var(--overlay-badge-color);
144
+ padding: 6px 14px; border-radius: var(--overlay-badge-radius);
145
+ font-family: var(--overlay-badge-font); font-weight: var(--overlay-badge-weight);
146
+ font-size: var(--overlay-badge-size);
147
+ text-transform: uppercase; letter-spacing: 0.05em;
148
+ backdrop-filter: blur(var(--overlay-glass-blur));
149
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
150
+ border: none; box-shadow: none;
151
+ }
152
+
153
+ /* clock */
154
+ [data-overlay-theme] [data-role="clock"][data-role] {
155
+ display: inline-flex; align-items: center;
156
+ background: var(--overlay-badge-bg); color: var(--overlay-badge-color);
157
+ padding: 6px 14px; border-radius: var(--overlay-badge-radius);
158
+ font-family: var(--overlay-badge-font); font-variant-numeric: tabular-nums;
159
+ font-size: var(--overlay-badge-size); font-weight: var(--overlay-badge-weight);
160
+ backdrop-filter: blur(var(--overlay-glass-blur));
161
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
162
+ border: none; box-shadow: none;
163
+ }
164
+
165
+ /* viewer-count — lighter than badge, not same color */
166
+ [data-overlay-theme] [data-role="viewer-count"][data-role] {
167
+ display: inline-flex; align-items: center; gap: 4px;
168
+ background: var(--overlay-viewer-bg); color: var(--overlay-viewer-color);
169
+ padding: 6px 14px; border-radius: var(--overlay-badge-radius);
170
+ font-family: var(--overlay-badge-font); font-size: var(--overlay-badge-size);
171
+ backdrop-filter: blur(var(--overlay-glass-blur));
172
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
173
+ border: none; box-shadow: none;
174
+ }
175
+
176
+ /* speaker-bar */
177
+ [data-overlay-theme] [data-role="speaker-bar"][data-role] {
178
+ display: flex; flex-direction: column; gap: 4px;
179
+ background: var(--overlay-card-bg); color: var(--overlay-card-color);
180
+ padding: 14px 24px; border-radius: var(--overlay-card-radius);
181
+ border-left: var(--overlay-card-border);
182
+ backdrop-filter: blur(var(--overlay-glass-blur));
183
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
184
+ box-shadow: none;
185
+ }
186
+
187
+ /* hashtag */
188
+ [data-overlay-theme] [data-role="hashtag"][data-role] {
189
+ display: inline-flex; align-items: center;
190
+ background: var(--overlay-badge-bg); color: var(--overlay-badge-color);
191
+ padding: 6px 14px; border-radius: var(--overlay-badge-radius);
192
+ font-family: var(--overlay-badge-font); font-size: var(--overlay-badge-size);
193
+ backdrop-filter: blur(var(--overlay-glass-blur));
194
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
195
+ border: none; box-shadow: none;
196
+ }
197
+
198
+ /* logo */
199
+ [data-overlay-theme] [data-role="logo"][data-role] {
200
+ display: flex; align-items: center; justify-content: center;
201
+ backdrop-filter: blur(var(--overlay-glass-blur));
202
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
203
+ }
204
+
205
+ /* data-widget */
206
+ [data-overlay-theme] [data-role="data-widget"][data-role] {
207
+ background: var(--overlay-card-bg); color: var(--overlay-card-color);
208
+ padding: 14px 20px; border-radius: var(--overlay-card-radius);
209
+ border: var(--overlay-card-border);
210
+ backdrop-filter: blur(var(--overlay-glass-blur));
211
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
212
+ box-shadow: none;
213
+ }
214
+
215
+ /* alert — prominent bar */
216
+ [data-overlay-theme] [data-role="alert"][data-role] {
217
+ display: flex; align-items: center; justify-content: center; gap: 10px;
218
+ background: var(--overlay-alert-bg); color: var(--overlay-alert-color);
219
+ padding: 12px 32px; border-radius: var(--overlay-badge-radius);
220
+ font-family: var(--overlay-badge-font); font-weight: 700;
221
+ font-size: var(--overlay-alert-size);
222
+ text-transform: uppercase; letter-spacing: 0.06em;
223
+ backdrop-filter: blur(var(--overlay-glass-blur));
224
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
225
+ border: none; box-shadow: none;
226
+ }
227
+
228
+ /* featured-comment */
229
+ [data-overlay-theme] [data-role="featured-comment"][data-role] {
230
+ background: var(--overlay-card-bg); color: var(--overlay-card-color);
231
+ padding: 14px 24px; border-radius: var(--overlay-card-radius);
232
+ border: var(--overlay-card-border);
233
+ backdrop-filter: blur(var(--overlay-glass-blur));
234
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
235
+ max-width: 420px; box-shadow: none;
236
+ }
237
+
238
+ /* score-bug */
239
+ [data-overlay-theme] [data-role="score-bug"][data-role] {
240
+ display: inline-flex; align-items: center; gap: 0;
241
+ background: var(--overlay-score-bg); color: var(--overlay-score-color);
242
+ border-radius: var(--overlay-score-radius);
243
+ overflow: hidden; font-family: var(--overlay-badge-font);
244
+ font-weight: 700; font-variant-numeric: tabular-nums;
245
+ backdrop-filter: blur(var(--overlay-glass-blur));
246
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
247
+ border: none; box-shadow: none;
248
+ }
249
+
250
+ /* lower-third — wide bar, prominent */
251
+ [data-overlay-theme] [data-role="lower-third"][data-role] {
252
+ display: flex; flex-direction: column; gap: 4px;
253
+ background: var(--overlay-lower-bg); color: var(--overlay-lower-color);
254
+ padding: 16px 28px; border-radius: var(--overlay-lower-radius);
255
+ border-left: 4px solid var(--overlay-lower-accent);
256
+ backdrop-filter: blur(var(--overlay-glass-blur));
257
+ -webkit-backdrop-filter: blur(var(--overlay-glass-blur));
258
+ font-size: var(--overlay-lower-size);
259
+ min-width: 340px;
260
+ border-top: none; border-right: none; border-bottom: none;
261
+ box-shadow: none;
262
+ }
263
+
264
+ /* ticker region — background on the grid region container */
265
+ [data-overlay-theme] > [data-region="ticker"] {
266
+ background: var(--overlay-ticker-bg);
267
+ font-size: var(--overlay-ticker-size);
268
+ padding: 8px 0;
269
+ }
270
+
271
+ /* ticker-item */
272
+ [data-overlay-theme] [data-role="ticker-item"][data-role] {
273
+ display: inline-flex; align-items: center;
274
+ font-family: var(--overlay-badge-font);
275
+ font-size: var(--overlay-ticker-size);
276
+ }
277
+
278
+ /* ══════════════════════════════════════════════════════════
279
+ CNN theme-specific overrides
280
+ Real CNN: full-width bars, 0 gap, 0 radius, condensed bold,
281
+ huge text (2-3rem headlines), white-bg black-text headline bar,
282
+ red BREAKING NEWS bar, black ticker.
283
+ ══════════════════════════════════════════════════════════ */
284
+
285
+ /* CNN: zero gap between lower regions & ticker — tight bar stacking */
286
+ [data-overlay-theme="cnn"] {
287
+ gap: 8px 8px;
288
+ }
289
+ /* CNN broadcast: full-width bars for lower/ticker/bottom rows — break out of title-safe padding */
290
+ [data-overlay-theme="cnn"] > [data-region^="lower"],
291
+ [data-overlay-theme="cnn"] > [data-region="ticker"],
292
+ [data-overlay-theme="cnn"] > [data-region^="bottom"] {
293
+ margin-top: -8px;
294
+ margin-left: calc(-1 * var(--overlay-pad));
295
+ margin-right: calc(-1 * var(--overlay-pad));
296
+ padding-left: var(--overlay-pad);
297
+ padding-right: var(--overlay-pad);
298
+ }
299
+
300
+ [data-overlay-theme="cnn"] [data-role="live-badge"][data-role] {
301
+ font-size: 1.1rem; letter-spacing: 0.15em; padding: 10px 22px;
302
+ font-weight: 700;
303
+ }
304
+ [data-overlay-theme="cnn"] [data-role="clock"][data-role] {
305
+ font-size: 1rem; padding: 8px 16px;
306
+ }
307
+
308
+ /* CNN lower-third: name bar — dark bg, red left accent, bold white text */
309
+ [data-overlay-theme="cnn"] [data-role="lower-third"][data-role] {
310
+ border-left: 5px solid #cc0000;
311
+ background: rgba(0,0,0,0.95);
312
+ padding: 14px 24px; min-width: 280px;
313
+ font-size: 1rem; border-radius: 0;
314
+ }
315
+ [data-overlay-theme="cnn"] [data-role="lower-third"][data-role] .aup-text:first-child {
316
+ font-size: 1.2rem; font-weight: 700; text-transform: uppercase;
317
+ }
318
+ [data-overlay-theme="cnn"] [data-role="lower-third"][data-role] .aup-text:nth-child(2) {
319
+ font-size: 0.85rem; opacity: 0.7; font-weight: 400;
320
+ }
321
+
322
+ /* CNN alert (BREAKING NEWS): red bg, huge bold white text */
323
+ [data-overlay-theme="cnn"] [data-role="alert"][data-role] {
324
+ background: #cc0000; color: #fff;
325
+ font-size: 1.4rem; letter-spacing: 0.12em; font-weight: 700;
326
+ padding: 12px 28px; border-radius: 0;
327
+ text-transform: uppercase;
328
+ }
329
+
330
+ /* CNN headline: WHITE bg, BLACK text, enormous condensed bold, full-width bar */
331
+ [data-overlay-theme="cnn"] [data-role="headline"][data-role] {
332
+ background: rgba(255,255,255,0.97); color: #111;
333
+ font-size: 2.2rem; font-weight: 700; line-height: 1.15;
334
+ padding: 18px 28px; border-radius: 0;
335
+ text-transform: uppercase; letter-spacing: 0.02em;
336
+ border: none; box-shadow: none;
337
+ backdrop-filter: none; -webkit-backdrop-filter: none;
338
+ }
339
+
340
+ /* CNN speaker-bar (name card in lower-start) */
341
+ [data-overlay-theme="cnn"] [data-role="speaker-bar"][data-role] {
342
+ border-left: 5px solid #cc0000; border-radius: 0;
343
+ background: rgba(0,0,0,0.95); padding: 14px 24px;
344
+ }
345
+ [data-overlay-theme="cnn"] [data-role="speaker-bar"][data-role] .aup-text:first-child {
346
+ font-size: 1.15rem; font-weight: 700; text-transform: uppercase;
347
+ }
348
+ [data-overlay-theme="cnn"] [data-role="speaker-bar"][data-role] .aup-text:nth-child(2) {
349
+ font-size: 0.85rem; opacity: 0.7;
350
+ }
351
+
352
+ /* CNN logo system (vertical stack in lower-end) */
353
+ [data-overlay-theme="cnn"] [data-role="logo"][data-role] {
354
+ background: #fff; padding: 8px 16px; border-radius: 0;
355
+ }
356
+
357
+ /* CNN data-widget / hashtag — compact, 0 radius */
358
+ [data-overlay-theme="cnn"] [data-role="data-widget"][data-role] {
359
+ border-radius: 0; border: none; border-left: 4px solid #cc0000;
360
+ }
361
+ [data-overlay-theme="cnn"] [data-role="hashtag"][data-role] {
362
+ border-radius: 0; font-size: 0.9rem; padding: 8px 16px;
363
+ background: rgba(0,0,0,0.8);
364
+ }
365
+
366
+ /* CNN ticker: solid black, bold white, wider padding */
367
+ [data-overlay-theme="cnn"] > [data-region="ticker"] {
368
+ background: #111; font-weight: 600; padding: 10px 16px;
369
+ }
370
+ [data-overlay-theme="cnn"] > [data-region="ticker"] .aup-ticker-separator {
371
+ opacity: 0.4; padding: 0 16px;
372
+ }
373
+
374
+ /* ══════════════════════════════════════════════════════════
375
+ Apple theme-specific overrides
376
+ ══════════════════════════════════════════════════════════ */
377
+ [data-overlay-theme="apple"] [data-role="live-badge"][data-role] {
378
+ font-weight: 500; font-size: 0.78rem; letter-spacing: 0.08em;
379
+ padding: 7px 18px;
380
+ }
381
+ [data-overlay-theme="apple"] [data-role="lower-third"][data-role] {
382
+ border-left: none; padding: 20px 32px; min-width: 320px;
383
+ background: rgba(0,0,0,0.35);
384
+ backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
385
+ border: 1px solid rgba(255,255,255,0.15);
386
+ font-size: 0.95rem; font-weight: 400;
387
+ border-radius: 16px;
388
+ }
389
+ [data-overlay-theme="apple"] [data-role="speaker-bar"][data-role] {
390
+ border-left: none; padding: 18px 28px;
391
+ background: rgba(0,0,0,0.35);
392
+ backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
393
+ border: 1px solid rgba(255,255,255,0.15);
394
+ border-radius: 16px;
395
+ }
396
+ [data-overlay-theme="apple"] [data-role="alert"][data-role] {
397
+ border-radius: 24px; font-weight: 500;
398
+ text-transform: none; letter-spacing: 0;
399
+ background: rgba(220,38,38,0.8);
400
+ backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
401
+ padding: 10px 28px;
402
+ }
403
+ [data-overlay-theme="apple"] > [data-region="ticker"] {
404
+ background: rgba(0,0,0,0.25);
405
+ backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
406
+ padding: 6px 0;
407
+ }
408
+ `;
409
+ const OVERLAY_THEMES_JS = `
410
+ // ── Overlay Theme Presets ──
411
+ var _OVERLAY_THEMES = {
412
+ minimal: {
413
+ fonts: []
414
+ },
415
+ cnn: {
416
+ fonts: ["Barlow+Condensed:wght@400;600;700"]
417
+ },
418
+ apple: {
419
+ fonts: ["Inter:wght@300;400;500;600"]
420
+ }
421
+ };
422
+
423
+ // ── Font loader (lazy, deduplicated) ──
424
+ var _overlayLoadedFonts = {};
425
+
426
+ function _isSafeOverlayFontURL(url) {
427
+ return /^https:\\/\\/fonts\\.googleapis\\.com\\/css2/.test(url);
428
+ }
429
+
430
+ function _loadOverlayFonts(fonts) {
431
+ if (!fonts || !fonts.length) return;
432
+ for (var i = 0; i < fonts.length; i++) {
433
+ var f = fonts[i];
434
+ if (_overlayLoadedFonts[f]) continue;
435
+ var url = "https://fonts.googleapis.com/css2?family=" + f + "&display=swap";
436
+ if (!_isSafeOverlayFontURL(url)) continue;
437
+ var link = document.createElement("link");
438
+ link.rel = "stylesheet";
439
+ link.href = url;
440
+ document.head.appendChild(link);
441
+ _overlayLoadedFonts[f] = true;
442
+ }
443
+ }
444
+
445
+ // ── CSS injection (once) ──
446
+ var _overlayThemeCSSInjected = false;
447
+
448
+ function _injectOverlayThemeCSS() {
449
+ if (_overlayThemeCSSInjected) return;
450
+ _overlayThemeCSSInjected = true;
451
+ var style = document.createElement("style");
452
+ style.textContent = _OVERLAY_THEMES_CSS;
453
+ document.head.appendChild(style);
454
+ }
455
+
456
+ // ── Apply overlay theme to an element ──
457
+ function _applyOverlayTheme(el, theme) {
458
+ if (!theme) return;
459
+ _injectOverlayThemeCSS();
460
+
461
+ if (typeof theme === "string") {
462
+ // Named preset
463
+ var preset = _OVERLAY_THEMES[theme];
464
+ if (!preset) return;
465
+ el.setAttribute("data-overlay-theme", theme);
466
+ _loadOverlayFonts(preset.fonts);
467
+ } else if (typeof theme === "object") {
468
+ // Custom inline theme — apply as CSS variables
469
+ el.setAttribute("data-overlay-theme", "custom");
470
+ var keyMap = {
471
+ badgeBg: "--overlay-badge-bg",
472
+ badgeColor: "--overlay-badge-color",
473
+ badgeRadius: "--overlay-badge-radius",
474
+ badgeFont: "--overlay-badge-font",
475
+ badgeSize: "--overlay-badge-size",
476
+ badgeWeight: "--overlay-badge-weight",
477
+ cardBg: "--overlay-card-bg",
478
+ cardColor: "--overlay-card-color",
479
+ cardBorder: "--overlay-card-border",
480
+ cardRadius: "--overlay-card-radius",
481
+ glassBlur: "--overlay-glass-blur",
482
+ lowerBg: "--overlay-lower-bg",
483
+ lowerColor: "--overlay-lower-color",
484
+ lowerAccent: "--overlay-lower-accent",
485
+ lowerRadius: "--overlay-lower-radius",
486
+ lowerSize: "--overlay-lower-size",
487
+ tickerBg: "--overlay-ticker-bg",
488
+ tickerColor: "--overlay-ticker-color",
489
+ tickerSize: "--overlay-ticker-size",
490
+ alertBg: "--overlay-alert-bg",
491
+ alertColor: "--overlay-alert-color",
492
+ alertSize: "--overlay-alert-size",
493
+ scoreBg: "--overlay-score-bg",
494
+ scoreColor: "--overlay-score-color",
495
+ scoreRadius: "--overlay-score-radius",
496
+ viewerBg: "--overlay-viewer-bg",
497
+ viewerColor: "--overlay-viewer-color"
498
+ };
499
+ for (var k in theme) {
500
+ if (theme.hasOwnProperty(k)) {
501
+ var cssVar = keyMap[k] || ("--overlay-" + k.replace(/([A-Z])/g, "-$1").toLowerCase());
502
+ el.style.setProperty(cssVar, theme[k]);
503
+ }
504
+ }
505
+ // Load custom fonts if provided
506
+ if (theme.fonts) _loadOverlayFonts(theme.fonts);
507
+ }
508
+ }
509
+ `;
510
+
511
+ //#endregion
512
+ export { OVERLAY_THEMES_CSS, OVERLAY_THEMES_JS };
513
+ //# sourceMappingURL=overlay-themes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-themes.mjs","names":[],"sources":["../../src/web-page/overlay-themes.ts"],"sourcesContent":["/**\n * Overlay Theme System — broadcast \"graphics packages\" for overlay-grid.\n *\n * Three built-in themes: minimal (default), cnn (hard-edge news), apple (frosted glass).\n * Theme CSS is injected on-demand when _applyOverlayTheme is called.\n * Font loading is lazy — Google Fonts <link> injected only when a theme activates.\n *\n * 12 broadcast roles styled per theme:\n * live-badge, clock, viewer-count, speaker-bar, hashtag, logo,\n * data-widget, alert, featured-comment, score-bug, lower-third, ticker-item\n *\n * Specificity strategy:\n * - Role selectors use [data-overlay-theme][data-overlay-theme] double-attr\n * to reach (0,3,0), beating primitive defaults like .aup-text[data-mode] (0,2,0).\n * - Color inheritance is forced on all children inside themed overlay-grid\n * so primitive default `color: var(--text)` doesn't override theme colors.\n * - Ticker gets a dedicated override for .aup-ticker color.\n */\n\n// ── CSS injected as a JS string, applied on demand ──\n\nexport const OVERLAY_THEMES_CSS = `\n/* ── Overlay Theme: minimal ── */\n[data-overlay-theme=\"minimal\"] {\n --overlay-badge-bg: rgba(0,0,0,0.6);\n --overlay-badge-color: #fff;\n --overlay-badge-radius: 6px;\n --overlay-badge-font: inherit;\n --overlay-badge-size: 0.85rem;\n --overlay-badge-weight: 600;\n --overlay-card-bg: rgba(0,0,0,0.5);\n --overlay-card-color: #fff;\n --overlay-card-border: 1px solid rgba(255,255,255,0.1);\n --overlay-card-radius: 8px;\n --overlay-glass-blur: 8px;\n --overlay-lower-bg: rgba(0,0,0,0.5);\n --overlay-lower-color: #fff;\n --overlay-lower-accent: rgba(255,255,255,0.3);\n --overlay-lower-radius: 8px;\n --overlay-lower-size: 1rem;\n --overlay-ticker-bg: rgba(0,0,0,0.6);\n --overlay-ticker-color: #fff;\n --overlay-ticker-size: 0.85rem;\n --overlay-alert-bg: rgba(220,38,38,0.85);\n --overlay-alert-color: #fff;\n --overlay-alert-size: 0.9rem;\n --overlay-score-bg: rgba(0,0,0,0.7);\n --overlay-score-color: #fff;\n --overlay-score-radius: 6px;\n --overlay-viewer-bg: rgba(0,0,0,0.4);\n --overlay-viewer-color: #fff;\n}\n\n/* ── Overlay Theme: cnn ── */\n[data-overlay-theme=\"cnn\"] {\n --overlay-badge-bg: #cc0000;\n --overlay-badge-color: #fff;\n --overlay-badge-radius: 2px;\n --overlay-badge-font: \"Barlow Condensed\", \"Arial Narrow\", sans-serif;\n --overlay-badge-size: 1rem;\n --overlay-badge-weight: 700;\n --overlay-card-bg: rgba(0,0,0,0.9);\n --overlay-card-color: #fff;\n --overlay-card-border: 4px solid #cc0000;\n --overlay-card-radius: 0;\n --overlay-glass-blur: 0;\n --overlay-lower-bg: rgba(0,0,0,0.9);\n --overlay-lower-color: #fff;\n --overlay-lower-accent: #cc0000;\n --overlay-lower-radius: 0;\n --overlay-lower-size: 1.15rem;\n --overlay-ticker-bg: #111;\n --overlay-ticker-color: #fff;\n --overlay-ticker-size: 0.95rem;\n --overlay-alert-bg: #fbbf24;\n --overlay-alert-color: #111;\n --overlay-alert-size: 1.05rem;\n --overlay-score-bg: #1a1a1a;\n --overlay-score-color: #fff;\n --overlay-score-radius: 0;\n --overlay-viewer-bg: rgba(0,0,0,0.6);\n --overlay-viewer-color: rgba(255,255,255,0.9);\n}\n\n/* ── Overlay Theme: apple ── */\n[data-overlay-theme=\"apple\"] {\n --overlay-badge-bg: rgba(0,0,0,0.4);\n --overlay-badge-color: #fff;\n --overlay-badge-radius: 20px;\n --overlay-badge-font: \"Inter\", -apple-system, sans-serif;\n --overlay-badge-size: 0.78rem;\n --overlay-badge-weight: 500;\n --overlay-card-bg: rgba(0,0,0,0.3);\n --overlay-card-color: #fff;\n --overlay-card-border: 1px solid rgba(255,255,255,0.18);\n --overlay-card-radius: 16px;\n --overlay-glass-blur: 20px;\n --overlay-lower-bg: rgba(0,0,0,0.3);\n --overlay-lower-color: #fff;\n --overlay-lower-accent: rgba(255,255,255,0.2);\n --overlay-lower-radius: 16px;\n --overlay-lower-size: 0.95rem;\n --overlay-ticker-bg: rgba(0,0,0,0.25);\n --overlay-ticker-color: rgba(255,255,255,0.95);\n --overlay-ticker-size: 0.82rem;\n --overlay-alert-bg: rgba(220,38,38,0.8);\n --overlay-alert-color: #fff;\n --overlay-alert-size: 0.88rem;\n --overlay-score-bg: rgba(0,0,0,0.3);\n --overlay-score-color: #fff;\n --overlay-score-radius: 12px;\n --overlay-viewer-bg: rgba(0,0,0,0.3);\n --overlay-viewer-color: rgba(255,255,255,0.9);\n}\n\n/* ══════════════════════════════════════════════════════════\n Force color inheritance inside themed overlay-grid.\n Primitives (.aup-text, .aup-ticker etc.) normally set\n color: var(--text) which overrides theme colors.\n This resets all children to inherit from their role/region container.\n Double-attr [data-overlay-theme][data-overlay-theme] => (0,3,0)\n beats .aup-text[data-mode=\"badge\"][data-intent=\"info\"] (0,3,1) — close but\n we use * to catch all children.\n ══════════════════════════════════════════════════════════ */\n\n[data-overlay-theme] [data-role] *,\n[data-overlay-theme] [data-role] {\n color: inherit;\n font-family: inherit;\n}\n\n/* Ticker: the .aup-ticker inside [data-region=\"ticker\"] sets its own color.\n Force it and all its children to inherit the region's color. */\n[data-overlay-theme] > [data-region=\"ticker\"],\n[data-overlay-theme] > [data-region=\"ticker\"] *,\n[data-overlay-theme] > [data-region=\"ticker\"] .aup-ticker {\n color: var(--overlay-ticker-color) !important;\n}\n\n/* ── Role styles — doubled attribute for (0,3,0) specificity ── */\n\n/* live-badge */\n[data-overlay-theme] [data-role=\"live-badge\"][data-role] {\n display: inline-flex; align-items: center; gap: 6px;\n background: var(--overlay-badge-bg); color: var(--overlay-badge-color);\n padding: 6px 14px; border-radius: var(--overlay-badge-radius);\n font-family: var(--overlay-badge-font); font-weight: var(--overlay-badge-weight);\n font-size: var(--overlay-badge-size);\n text-transform: uppercase; letter-spacing: 0.05em;\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n border: none; box-shadow: none;\n}\n\n/* clock */\n[data-overlay-theme] [data-role=\"clock\"][data-role] {\n display: inline-flex; align-items: center;\n background: var(--overlay-badge-bg); color: var(--overlay-badge-color);\n padding: 6px 14px; border-radius: var(--overlay-badge-radius);\n font-family: var(--overlay-badge-font); font-variant-numeric: tabular-nums;\n font-size: var(--overlay-badge-size); font-weight: var(--overlay-badge-weight);\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n border: none; box-shadow: none;\n}\n\n/* viewer-count — lighter than badge, not same color */\n[data-overlay-theme] [data-role=\"viewer-count\"][data-role] {\n display: inline-flex; align-items: center; gap: 4px;\n background: var(--overlay-viewer-bg); color: var(--overlay-viewer-color);\n padding: 6px 14px; border-radius: var(--overlay-badge-radius);\n font-family: var(--overlay-badge-font); font-size: var(--overlay-badge-size);\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n border: none; box-shadow: none;\n}\n\n/* speaker-bar */\n[data-overlay-theme] [data-role=\"speaker-bar\"][data-role] {\n display: flex; flex-direction: column; gap: 4px;\n background: var(--overlay-card-bg); color: var(--overlay-card-color);\n padding: 14px 24px; border-radius: var(--overlay-card-radius);\n border-left: var(--overlay-card-border);\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n box-shadow: none;\n}\n\n/* hashtag */\n[data-overlay-theme] [data-role=\"hashtag\"][data-role] {\n display: inline-flex; align-items: center;\n background: var(--overlay-badge-bg); color: var(--overlay-badge-color);\n padding: 6px 14px; border-radius: var(--overlay-badge-radius);\n font-family: var(--overlay-badge-font); font-size: var(--overlay-badge-size);\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n border: none; box-shadow: none;\n}\n\n/* logo */\n[data-overlay-theme] [data-role=\"logo\"][data-role] {\n display: flex; align-items: center; justify-content: center;\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n}\n\n/* data-widget */\n[data-overlay-theme] [data-role=\"data-widget\"][data-role] {\n background: var(--overlay-card-bg); color: var(--overlay-card-color);\n padding: 14px 20px; border-radius: var(--overlay-card-radius);\n border: var(--overlay-card-border);\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n box-shadow: none;\n}\n\n/* alert — prominent bar */\n[data-overlay-theme] [data-role=\"alert\"][data-role] {\n display: flex; align-items: center; justify-content: center; gap: 10px;\n background: var(--overlay-alert-bg); color: var(--overlay-alert-color);\n padding: 12px 32px; border-radius: var(--overlay-badge-radius);\n font-family: var(--overlay-badge-font); font-weight: 700;\n font-size: var(--overlay-alert-size);\n text-transform: uppercase; letter-spacing: 0.06em;\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n border: none; box-shadow: none;\n}\n\n/* featured-comment */\n[data-overlay-theme] [data-role=\"featured-comment\"][data-role] {\n background: var(--overlay-card-bg); color: var(--overlay-card-color);\n padding: 14px 24px; border-radius: var(--overlay-card-radius);\n border: var(--overlay-card-border);\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n max-width: 420px; box-shadow: none;\n}\n\n/* score-bug */\n[data-overlay-theme] [data-role=\"score-bug\"][data-role] {\n display: inline-flex; align-items: center; gap: 0;\n background: var(--overlay-score-bg); color: var(--overlay-score-color);\n border-radius: var(--overlay-score-radius);\n overflow: hidden; font-family: var(--overlay-badge-font);\n font-weight: 700; font-variant-numeric: tabular-nums;\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n border: none; box-shadow: none;\n}\n\n/* lower-third — wide bar, prominent */\n[data-overlay-theme] [data-role=\"lower-third\"][data-role] {\n display: flex; flex-direction: column; gap: 4px;\n background: var(--overlay-lower-bg); color: var(--overlay-lower-color);\n padding: 16px 28px; border-radius: var(--overlay-lower-radius);\n border-left: 4px solid var(--overlay-lower-accent);\n backdrop-filter: blur(var(--overlay-glass-blur));\n -webkit-backdrop-filter: blur(var(--overlay-glass-blur));\n font-size: var(--overlay-lower-size);\n min-width: 340px;\n border-top: none; border-right: none; border-bottom: none;\n box-shadow: none;\n}\n\n/* ticker region — background on the grid region container */\n[data-overlay-theme] > [data-region=\"ticker\"] {\n background: var(--overlay-ticker-bg);\n font-size: var(--overlay-ticker-size);\n padding: 8px 0;\n}\n\n/* ticker-item */\n[data-overlay-theme] [data-role=\"ticker-item\"][data-role] {\n display: inline-flex; align-items: center;\n font-family: var(--overlay-badge-font);\n font-size: var(--overlay-ticker-size);\n}\n\n/* ══════════════════════════════════════════════════════════\n CNN theme-specific overrides\n Real CNN: full-width bars, 0 gap, 0 radius, condensed bold,\n huge text (2-3rem headlines), white-bg black-text headline bar,\n red BREAKING NEWS bar, black ticker.\n ══════════════════════════════════════════════════════════ */\n\n/* CNN: zero gap between lower regions & ticker — tight bar stacking */\n[data-overlay-theme=\"cnn\"] {\n gap: 8px 8px;\n}\n/* CNN broadcast: full-width bars for lower/ticker/bottom rows — break out of title-safe padding */\n[data-overlay-theme=\"cnn\"] > [data-region^=\"lower\"],\n[data-overlay-theme=\"cnn\"] > [data-region=\"ticker\"],\n[data-overlay-theme=\"cnn\"] > [data-region^=\"bottom\"] {\n margin-top: -8px;\n margin-left: calc(-1 * var(--overlay-pad));\n margin-right: calc(-1 * var(--overlay-pad));\n padding-left: var(--overlay-pad);\n padding-right: var(--overlay-pad);\n}\n\n[data-overlay-theme=\"cnn\"] [data-role=\"live-badge\"][data-role] {\n font-size: 1.1rem; letter-spacing: 0.15em; padding: 10px 22px;\n font-weight: 700;\n}\n[data-overlay-theme=\"cnn\"] [data-role=\"clock\"][data-role] {\n font-size: 1rem; padding: 8px 16px;\n}\n\n/* CNN lower-third: name bar — dark bg, red left accent, bold white text */\n[data-overlay-theme=\"cnn\"] [data-role=\"lower-third\"][data-role] {\n border-left: 5px solid #cc0000;\n background: rgba(0,0,0,0.95);\n padding: 14px 24px; min-width: 280px;\n font-size: 1rem; border-radius: 0;\n}\n[data-overlay-theme=\"cnn\"] [data-role=\"lower-third\"][data-role] .aup-text:first-child {\n font-size: 1.2rem; font-weight: 700; text-transform: uppercase;\n}\n[data-overlay-theme=\"cnn\"] [data-role=\"lower-third\"][data-role] .aup-text:nth-child(2) {\n font-size: 0.85rem; opacity: 0.7; font-weight: 400;\n}\n\n/* CNN alert (BREAKING NEWS): red bg, huge bold white text */\n[data-overlay-theme=\"cnn\"] [data-role=\"alert\"][data-role] {\n background: #cc0000; color: #fff;\n font-size: 1.4rem; letter-spacing: 0.12em; font-weight: 700;\n padding: 12px 28px; border-radius: 0;\n text-transform: uppercase;\n}\n\n/* CNN headline: WHITE bg, BLACK text, enormous condensed bold, full-width bar */\n[data-overlay-theme=\"cnn\"] [data-role=\"headline\"][data-role] {\n background: rgba(255,255,255,0.97); color: #111;\n font-size: 2.2rem; font-weight: 700; line-height: 1.15;\n padding: 18px 28px; border-radius: 0;\n text-transform: uppercase; letter-spacing: 0.02em;\n border: none; box-shadow: none;\n backdrop-filter: none; -webkit-backdrop-filter: none;\n}\n\n/* CNN speaker-bar (name card in lower-start) */\n[data-overlay-theme=\"cnn\"] [data-role=\"speaker-bar\"][data-role] {\n border-left: 5px solid #cc0000; border-radius: 0;\n background: rgba(0,0,0,0.95); padding: 14px 24px;\n}\n[data-overlay-theme=\"cnn\"] [data-role=\"speaker-bar\"][data-role] .aup-text:first-child {\n font-size: 1.15rem; font-weight: 700; text-transform: uppercase;\n}\n[data-overlay-theme=\"cnn\"] [data-role=\"speaker-bar\"][data-role] .aup-text:nth-child(2) {\n font-size: 0.85rem; opacity: 0.7;\n}\n\n/* CNN logo system (vertical stack in lower-end) */\n[data-overlay-theme=\"cnn\"] [data-role=\"logo\"][data-role] {\n background: #fff; padding: 8px 16px; border-radius: 0;\n}\n\n/* CNN data-widget / hashtag — compact, 0 radius */\n[data-overlay-theme=\"cnn\"] [data-role=\"data-widget\"][data-role] {\n border-radius: 0; border: none; border-left: 4px solid #cc0000;\n}\n[data-overlay-theme=\"cnn\"] [data-role=\"hashtag\"][data-role] {\n border-radius: 0; font-size: 0.9rem; padding: 8px 16px;\n background: rgba(0,0,0,0.8);\n}\n\n/* CNN ticker: solid black, bold white, wider padding */\n[data-overlay-theme=\"cnn\"] > [data-region=\"ticker\"] {\n background: #111; font-weight: 600; padding: 10px 16px;\n}\n[data-overlay-theme=\"cnn\"] > [data-region=\"ticker\"] .aup-ticker-separator {\n opacity: 0.4; padding: 0 16px;\n}\n\n/* ══════════════════════════════════════════════════════════\n Apple theme-specific overrides\n ══════════════════════════════════════════════════════════ */\n[data-overlay-theme=\"apple\"] [data-role=\"live-badge\"][data-role] {\n font-weight: 500; font-size: 0.78rem; letter-spacing: 0.08em;\n padding: 7px 18px;\n}\n[data-overlay-theme=\"apple\"] [data-role=\"lower-third\"][data-role] {\n border-left: none; padding: 20px 32px; min-width: 320px;\n background: rgba(0,0,0,0.35);\n backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);\n border: 1px solid rgba(255,255,255,0.15);\n font-size: 0.95rem; font-weight: 400;\n border-radius: 16px;\n}\n[data-overlay-theme=\"apple\"] [data-role=\"speaker-bar\"][data-role] {\n border-left: none; padding: 18px 28px;\n background: rgba(0,0,0,0.35);\n backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);\n border: 1px solid rgba(255,255,255,0.15);\n border-radius: 16px;\n}\n[data-overlay-theme=\"apple\"] [data-role=\"alert\"][data-role] {\n border-radius: 24px; font-weight: 500;\n text-transform: none; letter-spacing: 0;\n background: rgba(220,38,38,0.8);\n backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);\n padding: 10px 28px;\n}\n[data-overlay-theme=\"apple\"] > [data-region=\"ticker\"] {\n background: rgba(0,0,0,0.25);\n backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);\n padding: 6px 0;\n}\n`;\n\n// ── JS: theme presets, font loader, and _applyOverlayTheme function ──\n\nexport const OVERLAY_THEMES_JS = `\n // ── Overlay Theme Presets ──\n var _OVERLAY_THEMES = {\n minimal: {\n fonts: []\n },\n cnn: {\n fonts: [\"Barlow+Condensed:wght@400;600;700\"]\n },\n apple: {\n fonts: [\"Inter:wght@300;400;500;600\"]\n }\n };\n\n // ── Font loader (lazy, deduplicated) ──\n var _overlayLoadedFonts = {};\n\n function _isSafeOverlayFontURL(url) {\n return /^https:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css2/.test(url);\n }\n\n function _loadOverlayFonts(fonts) {\n if (!fonts || !fonts.length) return;\n for (var i = 0; i < fonts.length; i++) {\n var f = fonts[i];\n if (_overlayLoadedFonts[f]) continue;\n var url = \"https://fonts.googleapis.com/css2?family=\" + f + \"&display=swap\";\n if (!_isSafeOverlayFontURL(url)) continue;\n var link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = url;\n document.head.appendChild(link);\n _overlayLoadedFonts[f] = true;\n }\n }\n\n // ── CSS injection (once) ──\n var _overlayThemeCSSInjected = false;\n\n function _injectOverlayThemeCSS() {\n if (_overlayThemeCSSInjected) return;\n _overlayThemeCSSInjected = true;\n var style = document.createElement(\"style\");\n style.textContent = _OVERLAY_THEMES_CSS;\n document.head.appendChild(style);\n }\n\n // ── Apply overlay theme to an element ──\n function _applyOverlayTheme(el, theme) {\n if (!theme) return;\n _injectOverlayThemeCSS();\n\n if (typeof theme === \"string\") {\n // Named preset\n var preset = _OVERLAY_THEMES[theme];\n if (!preset) return;\n el.setAttribute(\"data-overlay-theme\", theme);\n _loadOverlayFonts(preset.fonts);\n } else if (typeof theme === \"object\") {\n // Custom inline theme — apply as CSS variables\n el.setAttribute(\"data-overlay-theme\", \"custom\");\n var keyMap = {\n badgeBg: \"--overlay-badge-bg\",\n badgeColor: \"--overlay-badge-color\",\n badgeRadius: \"--overlay-badge-radius\",\n badgeFont: \"--overlay-badge-font\",\n badgeSize: \"--overlay-badge-size\",\n badgeWeight: \"--overlay-badge-weight\",\n cardBg: \"--overlay-card-bg\",\n cardColor: \"--overlay-card-color\",\n cardBorder: \"--overlay-card-border\",\n cardRadius: \"--overlay-card-radius\",\n glassBlur: \"--overlay-glass-blur\",\n lowerBg: \"--overlay-lower-bg\",\n lowerColor: \"--overlay-lower-color\",\n lowerAccent: \"--overlay-lower-accent\",\n lowerRadius: \"--overlay-lower-radius\",\n lowerSize: \"--overlay-lower-size\",\n tickerBg: \"--overlay-ticker-bg\",\n tickerColor: \"--overlay-ticker-color\",\n tickerSize: \"--overlay-ticker-size\",\n alertBg: \"--overlay-alert-bg\",\n alertColor: \"--overlay-alert-color\",\n alertSize: \"--overlay-alert-size\",\n scoreBg: \"--overlay-score-bg\",\n scoreColor: \"--overlay-score-color\",\n scoreRadius: \"--overlay-score-radius\",\n viewerBg: \"--overlay-viewer-bg\",\n viewerColor: \"--overlay-viewer-color\"\n };\n for (var k in theme) {\n if (theme.hasOwnProperty(k)) {\n var cssVar = keyMap[k] || (\"--overlay-\" + k.replace(/([A-Z])/g, \"-$1\").toLowerCase());\n el.style.setProperty(cssVar, theme[k]);\n }\n }\n // Load custom fonts if provided\n if (theme.fonts) _loadOverlayFonts(theme.fonts);\n }\n }\n`;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,MAAa,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwYlC,MAAa,oBAAoB"}
@@ -0,0 +1,72 @@
1
+
2
+ //#region src/web-page/renderers/action.ts
3
+ const ACTION_JS = `
4
+ function _sanitizeActionHref(rawHref) {
5
+ if (typeof rawHref !== "string") return null;
6
+ var href = rawHref.trim();
7
+ if (!href) return null;
8
+ if (href.charAt(0) === "/" || href.charAt(0) === "#") return href;
9
+ try {
10
+ var parsed = new URL(href, location.href);
11
+ var protocol = parsed.protocol.toLowerCase();
12
+ if (
13
+ protocol === "http:" ||
14
+ protocol === "https:" ||
15
+ protocol === "mailto:" ||
16
+ protocol === "tel:"
17
+ ) {
18
+ return href;
19
+ }
20
+ } catch (_ex) {}
21
+ return null;
22
+ }
23
+
24
+ function renderAupAction(node) {
25
+ var p = node.props || {};
26
+ var safeHref = _sanitizeActionHref(p.href);
27
+ var el;
28
+ if (safeHref) {
29
+ el = document.createElement("a");
30
+ el.href = safeHref;
31
+ if (p.target) {
32
+ el.target = p.target;
33
+ if (String(p.target).toLowerCase() === "_blank") {
34
+ el.rel = "noopener noreferrer";
35
+ }
36
+ }
37
+ } else {
38
+ el = document.createElement("button");
39
+ }
40
+ el.className = "aup-action";
41
+ if (p.variant) el.setAttribute("data-variant", p.variant);
42
+ if (p.size) el.setAttribute("data-size", p.size);
43
+ // Icon before label
44
+ if (p.icon && _ICON_PATHS[p.icon]) {
45
+ var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
46
+ svg.setAttribute("viewBox", "0 0 24 24");
47
+ svg.setAttribute("fill", "none");
48
+ svg.setAttribute("stroke", "currentColor");
49
+ svg.setAttribute("stroke-width", "2");
50
+ svg.setAttribute("stroke-linecap", "round");
51
+ svg.setAttribute("stroke-linejoin", "round");
52
+ svg.classList.add("aup-icon-svg");
53
+ svg.innerHTML = _ICON_PATHS[p.icon];
54
+ el.appendChild(svg);
55
+ }
56
+ var span = document.createElement("span");
57
+ span.textContent = String(p.label || "Action");
58
+ el.appendChild(span);
59
+ // Wire click event — use _fireAupEvent for proper device WS routing
60
+ if (node.events && node.events.click) {
61
+ el.onclick = function(e) {
62
+ if (safeHref) e.preventDefault();
63
+ _fireAupEvent(node.id, "click", {});
64
+ };
65
+ }
66
+ return el;
67
+ }
68
+
69
+ `;
70
+
71
+ //#endregion
72
+ exports.ACTION_JS = ACTION_JS;