@ox-content/vite-plugin 2.90.0 → 3.0.0-alpha.10

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.
@@ -0,0 +1,526 @@
1
+ /* ox-content Social Embeds - Twitter/X, Bluesky, WebContainer, media iframes */
2
+
3
+ /* Static link cards (<Tweet>/<XPost>/<Bluesky> without build-time fetch) */
4
+ .ox-tweet,
5
+ .ox-bluesky {
6
+ display: block;
7
+ margin: 1.5rem 0;
8
+ border-top: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
9
+ border-bottom: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
10
+ }
11
+
12
+ .ox-tweet > a,
13
+ .ox-bluesky > a {
14
+ display: block;
15
+ padding: 1rem 0;
16
+ text-decoration: none;
17
+ color: var(--octc-color-text);
18
+ }
19
+
20
+ .ox-tweet > a:hover,
21
+ .ox-bluesky > a:hover {
22
+ text-decoration: none;
23
+ }
24
+
25
+ .ox-tweet > a > span,
26
+ .ox-bluesky > a > span {
27
+ display: block;
28
+ font-size: 0.6875rem;
29
+ font-weight: 600;
30
+ letter-spacing: 0.08em;
31
+ text-transform: uppercase;
32
+ color: var(--octc-color-text-muted);
33
+ margin-bottom: 0.375rem;
34
+ }
35
+
36
+ .ox-tweet > a > strong,
37
+ .ox-bluesky > a > strong {
38
+ display: block;
39
+ font-weight: 600;
40
+ font-size: 0.9375rem;
41
+ color: var(--octc-color-primary);
42
+ overflow: hidden;
43
+ text-overflow: ellipsis;
44
+ white-space: nowrap;
45
+ }
46
+
47
+ .ox-tweet > a:hover > strong,
48
+ .ox-bluesky > a:hover > strong {
49
+ text-decoration: underline;
50
+ }
51
+
52
+ .ox-tweet > a > p,
53
+ .ox-bluesky > a > p {
54
+ margin: 0.5rem 0 0;
55
+ font-size: 0.875rem;
56
+ line-height: 1.5;
57
+ color: var(--octc-color-text-muted);
58
+ }
59
+
60
+ .ox-bluesky__header {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 0.75rem;
64
+ min-width: 0;
65
+ }
66
+
67
+ .ox-bluesky__avatar-wrap {
68
+ flex: 0 0 auto;
69
+ }
70
+
71
+ .ox-bluesky__avatar,
72
+ .ox-bluesky__avatar-fallback {
73
+ display: grid;
74
+ place-items: center;
75
+ width: 42px;
76
+ height: 42px;
77
+ border-radius: 50%;
78
+ background: color-mix(in srgb, var(--octc-color-primary) 16%, var(--octc-color-bg-alt));
79
+ color: var(--octc-color-primary);
80
+ font-weight: 700;
81
+ }
82
+
83
+ .ox-bluesky__avatar {
84
+ object-fit: cover;
85
+ }
86
+
87
+ .ox-bluesky__identity {
88
+ display: grid;
89
+ min-width: 0;
90
+ gap: 0.125rem;
91
+ }
92
+
93
+ .ox-bluesky__author-name,
94
+ .ox-bluesky__handle {
95
+ overflow: hidden;
96
+ text-overflow: ellipsis;
97
+ white-space: nowrap;
98
+ }
99
+
100
+ .ox-bluesky__author-name {
101
+ font-size: 0.95rem;
102
+ line-height: 1.2;
103
+ color: var(--octc-color-text);
104
+ }
105
+
106
+ .ox-bluesky__handle,
107
+ .ox-bluesky__network,
108
+ .ox-bluesky__meta {
109
+ color: var(--octc-color-text-muted);
110
+ }
111
+
112
+ .ox-bluesky__network {
113
+ margin-left: auto;
114
+ flex: 0 0 auto;
115
+ font-size: 0.75rem;
116
+ font-weight: 600;
117
+ }
118
+
119
+ .ox-bluesky__body {
120
+ margin: 0.875rem 0 0;
121
+ font-size: 0.95rem;
122
+ line-height: 1.55;
123
+ color: var(--octc-color-text);
124
+ }
125
+
126
+ .ox-bluesky__meta {
127
+ display: flex;
128
+ flex-wrap: wrap;
129
+ gap: 0.45rem 0.8rem;
130
+ margin-top: 0.875rem;
131
+ font-size: 0.75rem;
132
+ }
133
+
134
+ .ox-bluesky__source {
135
+ color: var(--octc-color-primary);
136
+ font-weight: 600;
137
+ }
138
+
139
+ /* Fetched tweet cards (<Tweet> with `twitter: { fetch: true }`) */
140
+ .ox-tweet--fetched > a {
141
+ padding: 1rem 0;
142
+ }
143
+
144
+ .ox-tweet__header {
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: space-between;
148
+ gap: 0.5rem;
149
+ margin-bottom: 0.625rem;
150
+ }
151
+
152
+ .ox-tweet__profile {
153
+ display: flex;
154
+ align-items: center;
155
+ gap: 0.625rem;
156
+ min-width: 0;
157
+ }
158
+
159
+ .ox-tweet__avatar {
160
+ width: 40px;
161
+ height: 40px;
162
+ border-radius: 9999px;
163
+ background: var(--octc-color-bg-alt);
164
+ }
165
+
166
+ .ox-tweet__author-name {
167
+ display: block;
168
+ font-weight: 600;
169
+ font-size: 0.9375rem;
170
+ color: var(--octc-color-text);
171
+ }
172
+
173
+ .ox-tweet__author-handle {
174
+ display: block;
175
+ font-size: 0.8125rem;
176
+ color: var(--octc-color-text-muted);
177
+ }
178
+
179
+ .ox-tweet__body {
180
+ margin: 0 0 0.625rem;
181
+ font-size: 0.9375rem;
182
+ line-height: 1.55;
183
+ color: var(--octc-color-text);
184
+ white-space: pre-wrap;
185
+ }
186
+
187
+ .ox-tweet__media {
188
+ display: grid;
189
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
190
+ gap: 0.5rem;
191
+ margin-bottom: 0.625rem;
192
+ }
193
+
194
+ .ox-tweet__media-item {
195
+ width: 100%;
196
+ height: auto;
197
+ border-radius: 8px;
198
+ border: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
199
+ background: var(--octc-color-bg-alt);
200
+ }
201
+
202
+ .ox-tweet__media-fallback {
203
+ display: flex;
204
+ flex-direction: column;
205
+ min-width: 0;
206
+ }
207
+
208
+ .ox-tweet__media-fallback > img {
209
+ width: 100%;
210
+ height: auto;
211
+ border-radius: inherit;
212
+ }
213
+
214
+ .ox-tweet__watch {
215
+ margin-top: 0.375rem;
216
+ font-size: 0.8125rem;
217
+ }
218
+
219
+ .ox-tweet__footer {
220
+ display: flex;
221
+ align-items: center;
222
+ gap: 0.5rem;
223
+ font-size: 0.75rem;
224
+ color: var(--octc-color-text-muted);
225
+ }
226
+
227
+ .ox-tweet__permalink {
228
+ overflow: hidden;
229
+ text-overflow: ellipsis;
230
+ white-space: nowrap;
231
+ }
232
+
233
+ .ox-tweet__source {
234
+ color: var(--octc-color-primary);
235
+ font-weight: 600;
236
+ }
237
+
238
+ .ox-tweet__metrics {
239
+ display: flex;
240
+ flex-wrap: wrap;
241
+ gap: 0.4rem 0.75rem;
242
+ margin: 0.5rem 0 0;
243
+ font-size: 0.75rem;
244
+ color: var(--octc-color-text-muted);
245
+ }
246
+
247
+ .ox-tweet__metric strong {
248
+ color: var(--octc-color-text);
249
+ }
250
+
251
+ .ox-tweet__reply {
252
+ margin: 0 0 0.5rem;
253
+ font-size: 0.8125rem;
254
+ }
255
+
256
+ .ox-tweet__reply-link {
257
+ color: var(--octc-color-text-muted);
258
+ text-decoration: none;
259
+ }
260
+
261
+ .ox-tweet__reply-link:hover {
262
+ text-decoration: underline;
263
+ }
264
+
265
+ .ox-tweet__quote {
266
+ margin: 0 0 0.625rem;
267
+ padding: 0.75rem;
268
+ border: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
269
+ border-radius: 8px;
270
+ }
271
+
272
+ .ox-tweet__quote-header {
273
+ display: flex;
274
+ align-items: center;
275
+ gap: 0.5rem;
276
+ margin-bottom: 0.5rem;
277
+ }
278
+
279
+ .ox-tweet__quote .ox-tweet__avatar {
280
+ width: 28px;
281
+ height: 28px;
282
+ }
283
+
284
+ .ox-tweet__quote-body {
285
+ margin: 0 0 0.5rem;
286
+ font-size: 0.875rem;
287
+ line-height: 1.5;
288
+ color: var(--octc-color-text);
289
+ white-space: pre-wrap;
290
+ }
291
+
292
+ .ox-tweet__quote .ox-tweet__media {
293
+ margin-bottom: 0;
294
+ }
295
+
296
+ /* WebContainer lazy placeholder */
297
+ .ox-webcontainer {
298
+ margin: 1.5rem 0;
299
+ border: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
300
+ border-radius: 8px;
301
+ overflow: hidden;
302
+ }
303
+
304
+ .ox-webcontainer__header {
305
+ display: flex;
306
+ align-items: center;
307
+ justify-content: space-between;
308
+ gap: 0.75rem;
309
+ padding: 0.625rem 1rem;
310
+ border-bottom: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
311
+ background: var(--octc-color-bg-alt);
312
+ }
313
+
314
+ .ox-webcontainer__header strong {
315
+ font-size: 0.875rem;
316
+ color: var(--octc-color-text);
317
+ }
318
+
319
+ .ox-webcontainer__header span {
320
+ font-size: 0.75rem;
321
+ color: var(--octc-color-text-muted);
322
+ white-space: nowrap;
323
+ }
324
+
325
+ .ox-webcontainer pre {
326
+ margin: 0;
327
+ border: 0;
328
+ border-radius: 0;
329
+ }
330
+
331
+ /* Media iframes */
332
+ .ox-spotify,
333
+ .ox-apple-music,
334
+ .ox-speaker-deck,
335
+ .ox-stackblitz,
336
+ .ox-audio,
337
+ .ox-video {
338
+ display: block;
339
+ width: 100%;
340
+ margin: 1.5rem 0;
341
+ border: 0;
342
+ border-radius: 12px;
343
+ }
344
+
345
+ .ox-stackblitz {
346
+ border: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
347
+ border-radius: 8px;
348
+ }
349
+ .ox-tweet--rich .ox-tweet__card {
350
+ display: block;
351
+ padding: 1rem 0;
352
+ color: var(--octc-color-text);
353
+ text-decoration: none;
354
+ }
355
+
356
+ .ox-tweet--rich .ox-tweet__profile {
357
+ display: flex;
358
+ align-items: center;
359
+ gap: 0.625rem;
360
+ min-width: 0;
361
+ }
362
+
363
+ .ox-tweet--rich .ox-tweet__avatar-wrap {
364
+ flex: 0 0 auto;
365
+ }
366
+
367
+ .ox-tweet--rich .ox-tweet__avatar,
368
+ .ox-tweet--rich .ox-tweet__avatar-fallback {
369
+ display: grid;
370
+ place-items: center;
371
+ width: 42px;
372
+ height: 42px;
373
+ border-radius: 50%;
374
+ background: color-mix(in srgb, var(--octc-color-text) 10%, var(--octc-color-bg-alt));
375
+ color: var(--octc-color-text);
376
+ font-weight: 800;
377
+ }
378
+
379
+ .ox-tweet--rich .ox-tweet__avatar {
380
+ object-fit: cover;
381
+ }
382
+
383
+ .ox-tweet--rich .ox-tweet__identity {
384
+ display: grid;
385
+ min-width: 0;
386
+ gap: 0.125rem;
387
+ }
388
+
389
+ .ox-tweet--rich .ox-tweet__author-name,
390
+ .ox-tweet--rich .ox-tweet__author-handle {
391
+ overflow: hidden;
392
+ text-overflow: ellipsis;
393
+ white-space: nowrap;
394
+ }
395
+
396
+ .ox-tweet--rich .ox-tweet__network {
397
+ margin-left: auto;
398
+ flex: 0 0 auto;
399
+ font-size: 0.75rem;
400
+ font-weight: 700;
401
+ color: var(--octc-color-text-muted);
402
+ }
403
+
404
+ .ox-tweet--rich .ox-tweet__meta {
405
+ display: flex;
406
+ flex-wrap: wrap;
407
+ gap: 0.45rem 0.8rem;
408
+ margin-top: 0.875rem;
409
+ font-size: 0.75rem;
410
+ color: var(--octc-color-text-muted);
411
+ }
412
+
413
+ .ox-tweet--rich .ox-tweet__source {
414
+ color: var(--octc-color-primary);
415
+ font-weight: 600;
416
+ }
417
+ /* Reddit post cards */
418
+ .ox-reddit-card {
419
+ display: block;
420
+ margin: 1.5rem 0;
421
+ border: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
422
+ border-radius: 8px;
423
+ overflow: hidden;
424
+ background: var(--octc-color-bg);
425
+ }
426
+
427
+ .ox-reddit-card__main,
428
+ .ox-reddit-card__original {
429
+ display: block;
430
+ color: var(--octc-color-text);
431
+ text-decoration: none;
432
+ }
433
+
434
+ .ox-reddit-card__main {
435
+ padding: 1rem;
436
+ }
437
+
438
+ .ox-reddit-card__main:hover,
439
+ .ox-reddit-card__original:hover {
440
+ text-decoration: none;
441
+ }
442
+
443
+ .ox-reddit-card__header,
444
+ .ox-reddit-card__meta {
445
+ display: flex;
446
+ flex-wrap: wrap;
447
+ align-items: center;
448
+ gap: 0.35rem 0.75rem;
449
+ color: var(--octc-color-text-muted);
450
+ }
451
+
452
+ .ox-reddit-card__header {
453
+ margin-bottom: 0.625rem;
454
+ font-size: 0.75rem;
455
+ }
456
+
457
+ .ox-reddit-card__network,
458
+ .ox-reddit-card__subreddit,
459
+ .ox-reddit-card__source,
460
+ .ox-reddit-card__original {
461
+ font-weight: 600;
462
+ }
463
+
464
+ .ox-reddit-card__network {
465
+ color: #ff4500;
466
+ letter-spacing: 0.08em;
467
+ text-transform: uppercase;
468
+ }
469
+
470
+ .ox-reddit-card__subreddit,
471
+ .ox-reddit-card__source,
472
+ .ox-reddit-card__original {
473
+ color: var(--octc-color-primary);
474
+ }
475
+
476
+ .ox-reddit-card__author,
477
+ .ox-reddit-card__time {
478
+ color: var(--octc-color-text-muted);
479
+ }
480
+
481
+ .ox-reddit-card__title {
482
+ margin: 0;
483
+ font-size: 1rem;
484
+ line-height: 1.35;
485
+ color: var(--octc-color-text);
486
+ }
487
+
488
+ .ox-reddit-card__body {
489
+ margin: 0.625rem 0 0;
490
+ font-size: 0.875rem;
491
+ line-height: 1.55;
492
+ color: var(--octc-color-text-muted);
493
+ }
494
+
495
+ .ox-reddit-card__image {
496
+ display: block;
497
+ width: 100%;
498
+ height: auto;
499
+ max-height: 420px;
500
+ margin-top: 0.875rem;
501
+ border: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
502
+ border-radius: 8px;
503
+ object-fit: cover;
504
+ background: var(--octc-color-bg-alt);
505
+ }
506
+
507
+ .ox-reddit-card__meta {
508
+ margin-top: 0.875rem;
509
+ font-size: 0.75rem;
510
+ }
511
+
512
+ .ox-reddit-card__metric strong {
513
+ color: var(--octc-color-text);
514
+ }
515
+
516
+ .ox-reddit-card__original {
517
+ padding: 0.625rem 1rem;
518
+ border-top: 1px solid color-mix(in srgb, var(--octc-color-border) 74%, transparent);
519
+ background: var(--octc-color-bg-alt);
520
+ font-size: 0.8125rem;
521
+ }
522
+
523
+ .ox-reddit-card--fallback,
524
+ .ox-reddit-card.error {
525
+ border-style: dashed;
526
+ }
@@ -0,0 +1,202 @@
1
+ /* ox-content Tabs Plugin - Pure CSS, No JS */
2
+
3
+ .ox-tabs {
4
+ margin: 1.5rem 0;
5
+ border: 1px solid var(--octc-color-border);
6
+ border-radius: 4px;
7
+ overflow: hidden;
8
+ background: var(--octc-color-bg);
9
+ }
10
+
11
+ .ox-tabs-header {
12
+ display: flex;
13
+ align-items: end;
14
+ gap: 0.125rem;
15
+ padding: 0.35rem 0.35rem 0;
16
+ background: var(--octc-color-bg-alt);
17
+ border-bottom: 1px solid var(--octc-color-border);
18
+ overflow-x: auto;
19
+ -webkit-overflow-scrolling: touch;
20
+ scrollbar-width: none;
21
+ }
22
+
23
+ .ox-tabs-header::-webkit-scrollbar {
24
+ display: none;
25
+ }
26
+
27
+ /* Hidden radio inputs for tab selection */
28
+ .ox-tabs input[type="radio"] {
29
+ position: absolute;
30
+ width: 1px;
31
+ height: 1px;
32
+ padding: 0;
33
+ margin: -1px;
34
+ overflow: hidden;
35
+ clip: rect(0, 0, 0, 0);
36
+ white-space: nowrap;
37
+ border: 0;
38
+ }
39
+
40
+ /* Tab labels */
41
+ .ox-tabs label {
42
+ display: inline-flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ flex: 1 0 max-content;
46
+ min-width: 3.5rem;
47
+ padding: 0.65rem 0.85rem;
48
+ cursor: pointer;
49
+ font-size: 0.875rem;
50
+ font-weight: 500;
51
+ color: var(--octc-color-text-muted);
52
+ border: 1px solid transparent;
53
+ border-bottom: 2px solid transparent;
54
+ margin-bottom: -1px;
55
+ border-radius: 4px 4px 0 0;
56
+ white-space: nowrap;
57
+ transition:
58
+ background-color 0.2s ease,
59
+ color 0.2s ease,
60
+ border-color 0.2s ease;
61
+ }
62
+
63
+ .ox-tabs label:hover {
64
+ color: var(--octc-color-text);
65
+ background: color-mix(in srgb, var(--octc-color-bg) 72%, transparent);
66
+ }
67
+
68
+ /* Checked tab label */
69
+ .ox-tabs input[type="radio"]:checked + label {
70
+ color: var(--octc-color-primary);
71
+ background: var(--octc-color-bg);
72
+ border-color: var(--octc-color-border);
73
+ border-bottom-color: var(--octc-color-primary);
74
+ }
75
+
76
+ /* Focus styles for accessibility */
77
+ .ox-tabs input[type="radio"]:focus-visible + label {
78
+ outline: var(--octc-focus-ring);
79
+ outline-offset: -2px;
80
+ }
81
+
82
+ /* Tab content panels */
83
+ .ox-tab-panel {
84
+ display: none;
85
+ padding: 1rem;
86
+ background: var(--octc-color-bg);
87
+ }
88
+
89
+ /* Reset margins for first/last children in panels */
90
+ .ox-tab-panel > :first-child {
91
+ margin-top: 0;
92
+ }
93
+
94
+ .ox-tab-panel > :last-child {
95
+ margin-bottom: 0;
96
+ }
97
+
98
+ /* Panel visibility via :has(). Radio ids are `ox-tab-{group}-{index}`. */
99
+ @supports selector(:has(*)) {
100
+ .ox-tabs:has(input[id$="-0"]:checked) .ox-tab-panel[data-tab="0"] {
101
+ display: block;
102
+ }
103
+ .ox-tabs:has(input[id$="-1"]:checked) .ox-tab-panel[data-tab="1"] {
104
+ display: block;
105
+ }
106
+ .ox-tabs:has(input[id$="-2"]:checked) .ox-tab-panel[data-tab="2"] {
107
+ display: block;
108
+ }
109
+ .ox-tabs:has(input[id$="-3"]:checked) .ox-tab-panel[data-tab="3"] {
110
+ display: block;
111
+ }
112
+ .ox-tabs:has(input[id$="-4"]:checked) .ox-tab-panel[data-tab="4"] {
113
+ display: block;
114
+ }
115
+ .ox-tabs:has(input[id$="-5"]:checked) .ox-tab-panel[data-tab="5"] {
116
+ display: block;
117
+ }
118
+ .ox-tabs:has(input[id$="-6"]:checked) .ox-tab-panel[data-tab="6"] {
119
+ display: block;
120
+ }
121
+ .ox-tabs:has(input[id$="-7"]:checked) .ox-tab-panel[data-tab="7"] {
122
+ display: block;
123
+ }
124
+
125
+ .ox-tab-panel:has(> pre:only-child),
126
+ .ox-tabs-fallback .ox-tabs-fallback-content:has(> pre:only-child) {
127
+ padding: 0;
128
+ background: var(--octc-color-code-bg);
129
+ }
130
+
131
+ .ox-tab-panel:has(> pre:only-child) > pre,
132
+ .ox-tabs-fallback .ox-tabs-fallback-content:has(> pre:only-child) > pre {
133
+ margin: 0;
134
+ border: 0;
135
+ border-radius: 0;
136
+ }
137
+ }
138
+
139
+ /* Code blocks inside tabs */
140
+ .ox-tab-panel pre {
141
+ margin: 0.5rem 0;
142
+ }
143
+
144
+ .ox-tab-panel pre:first-child {
145
+ margin-top: 0;
146
+ }
147
+
148
+ .ox-tab-panel pre:last-child {
149
+ margin-bottom: 0;
150
+ }
151
+
152
+ .ox-tab-panel > .ox-code {
153
+ margin: 0;
154
+ }
155
+
156
+ /* Fallback for older browsers using <details> */
157
+ .ox-tabs-fallback {
158
+ margin: 1.5rem 0;
159
+ }
160
+
161
+ .ox-tabs-fallback details {
162
+ border: 1px solid var(--octc-color-border);
163
+ border-radius: 4px;
164
+ margin-bottom: 0.5rem;
165
+ }
166
+
167
+ .ox-tabs-fallback details:last-child {
168
+ margin-bottom: 0;
169
+ }
170
+
171
+ .ox-tabs-fallback summary {
172
+ padding: 0.75rem 1rem;
173
+ cursor: pointer;
174
+ font-weight: 500;
175
+ background: var(--octc-color-bg-alt);
176
+ border-radius: 4px;
177
+ list-style: none;
178
+ }
179
+
180
+ .ox-tabs-fallback summary::-webkit-details-marker {
181
+ display: none;
182
+ }
183
+
184
+ .ox-tabs-fallback summary::before {
185
+ content: "▸ ";
186
+ display: inline-block;
187
+ margin-right: 0.5rem;
188
+ transition: transform 0.2s ease;
189
+ }
190
+
191
+ .ox-tabs-fallback details[open] summary::before {
192
+ transform: rotate(90deg);
193
+ }
194
+
195
+ .ox-tabs-fallback details[open] summary {
196
+ border-radius: 4px 4px 0 0;
197
+ border-bottom: 1px solid var(--octc-color-border);
198
+ }
199
+
200
+ .ox-tabs-fallback .ox-tabs-fallback-content {
201
+ padding: 1rem;
202
+ }