@birdycom/omniaui-blocks 0.0.0-stage → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -2
  3. package/blocks/about-timeline.html +23 -0
  4. package/blocks/app-header.html +32 -0
  5. package/blocks/app-shell.html +84 -0
  6. package/blocks/auth-split.html +45 -0
  7. package/blocks/auth.html +21 -0
  8. package/blocks/contact-grid.html +38 -0
  9. package/blocks/cta.html +8 -0
  10. package/blocks/data-table.html +111 -0
  11. package/blocks/faq.html +33 -0
  12. package/blocks/features.html +18 -0
  13. package/blocks/footer.html +41 -0
  14. package/blocks/forgot-password.html +34 -0
  15. package/blocks/form-page.html +28 -0
  16. package/blocks/hero-code.html +27 -0
  17. package/blocks/hero-orbit.html +38 -0
  18. package/blocks/hero-split.html +12 -0
  19. package/blocks/hero.html +10 -0
  20. package/blocks/login-01.html +41 -0
  21. package/blocks/login-02.html +55 -0
  22. package/blocks/login-03.html +47 -0
  23. package/blocks/module-header.html +24 -0
  24. package/blocks/otp-01.html +36 -0
  25. package/blocks/otp-02.html +46 -0
  26. package/blocks/page-hero.html +10 -0
  27. package/blocks/portfolio-grid.html +31 -0
  28. package/blocks/pricing.html +42 -0
  29. package/blocks/process.html +19 -0
  30. package/blocks/product-grid.html +37 -0
  31. package/blocks/profile-header.html +27 -0
  32. package/blocks/reset-password.html +45 -0
  33. package/blocks/showcase.html +27 -0
  34. package/blocks/sidebar-01.html +56 -0
  35. package/blocks/sidebar-02.html +55 -0
  36. package/blocks/sidebar-03.html +53 -0
  37. package/blocks/sidebar-04.html +56 -0
  38. package/blocks/sidebar-05.html +68 -0
  39. package/blocks/signup-01.html +53 -0
  40. package/blocks/signup-02.html +56 -0
  41. package/blocks/site-footer.html +39 -0
  42. package/blocks/site-header.html +14 -0
  43. package/blocks/spotlight.html +22 -0
  44. package/blocks/stats-counter.html +15 -0
  45. package/blocks/stats.html +19 -0
  46. package/blocks/team-list.html +30 -0
  47. package/blocks/two-factor.html +33 -0
  48. package/blocks/wizard-dialog.html +36 -0
  49. package/dist/blocks.css +1431 -0
  50. package/dist/blocks.min.css +1 -0
  51. package/dist/parts/.gitkeep +0 -0
  52. package/dist/parts/site-about-timeline.css +61 -0
  53. package/dist/parts/site-contact-grid.css +58 -0
  54. package/dist/parts/site-faq.css +52 -0
  55. package/dist/parts/site-hero-orbit.css +62 -0
  56. package/dist/parts/site-portfolio-grid.css +23 -0
  57. package/dist/parts/site-profile-header.css +77 -0
  58. package/manifest.json +418 -0
  59. package/package.json +53 -4
  60. package/pro.json +140 -0
@@ -0,0 +1,1431 @@
1
+ /* File: public/css/oc-blocks.css */
2
+
3
+ /* Map: block tokens -> hero blocks -> auth blocks -> pricing blocks -> feature blocks -> footer blocks */
4
+
5
+ /* Description: Pre-composed page blocks built from OmniaCSS utilities and components. Copy-paste ready. */
6
+
7
+ /* Version: 0.1.6 */
8
+
9
+ /* Depends on: oc-components.css (for primitives like oc-btn, oc-input) */
10
+
11
+ /* ===================================================================
12
+ BLOCK TOKENS (shared variables for blocks)
13
+ =================================================================== */
14
+
15
+ :root {
16
+ --oc-block-max-width: 1200px;
17
+ --oc-block-gap: 24px;
18
+ --oc-block-radius: 16px;
19
+ --oc-block-surface: var(--oc-card);
20
+ --oc-block-surface-soft: var(--oc-muted);
21
+ --oc-block-border: var(--oc-border);
22
+ --oc-block-text: var(--oc-foreground);
23
+ --oc-block-text-soft: var(--oc-muted-foreground);
24
+ --oc-block-accent: var(--oc-primary);
25
+ }
26
+
27
+ /* ===================================================================
28
+ HERO BLOCKS
29
+ Full-width hero sections for landing pages
30
+ =================================================================== */
31
+
32
+ /* Hero — centered with CTA */
33
+
34
+ .oc-block-hero {
35
+ text-align: center;
36
+ padding: 64px var(--oc-block-gap) 48px;
37
+ max-width: var(--oc-block-max-width);
38
+ margin: 0 auto;
39
+ }
40
+
41
+ .oc-block-hero-badge {
42
+ display: inline-block;
43
+ font-size: 0.78rem;
44
+ padding: 4px 12px;
45
+ border-radius: 999px;
46
+ border: 1px solid var(--oc-block-border);
47
+ color: var(--oc-block-accent);
48
+ background: oklch(from var(--color-vividblue-50) l c h / 0.08);
49
+ margin-bottom: 16px;
50
+ }
51
+
52
+ .oc-block-hero h1 {
53
+ font-size: clamp(2rem, 5vw, 3.5rem);
54
+ line-height: 1.15;
55
+ margin: 0 0 16px;
56
+ color: var(--oc-block-text);
57
+ font-weight: 700;
58
+ letter-spacing: -0.02em;
59
+ }
60
+
61
+ .oc-block-hero p {
62
+ font-size: 1.1rem;
63
+ line-height: 1.6;
64
+ color: var(--oc-block-text-soft);
65
+ max-width: 640px;
66
+ margin: 0 auto 28px;
67
+ }
68
+
69
+ .oc-block-hero-actions {
70
+ display: flex;
71
+ justify-content: center;
72
+ gap: 12px;
73
+ flex-wrap: wrap;
74
+ }
75
+
76
+ /* Hero — split (text left, image/visual right) */
77
+
78
+ .oc-block-hero-split {
79
+ display: grid;
80
+ grid-template-columns: 1fr 1fr;
81
+ gap: 40px;
82
+ align-items: center;
83
+ padding: 48px var(--oc-block-gap);
84
+ max-width: var(--oc-block-max-width);
85
+ margin: 0 auto;
86
+ }
87
+
88
+ .oc-block-hero-split h1 {
89
+ font-size: clamp(1.8rem, 4vw, 2.8rem);
90
+ line-height: 1.15;
91
+ margin: 0 0 14px;
92
+ color: var(--oc-block-text);
93
+ font-weight: 700;
94
+ }
95
+
96
+ .oc-block-hero-split p {
97
+ font-size: 1rem;
98
+ line-height: 1.6;
99
+ color: var(--oc-block-text-soft);
100
+ margin: 0 0 24px;
101
+ }
102
+
103
+ .oc-block-hero-visual {
104
+ background: var(--oc-block-surface);
105
+ border: 1px solid var(--oc-block-border);
106
+ border-radius: var(--oc-block-radius);
107
+ min-height: 280px;
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: center;
111
+ color: var(--oc-block-text-soft);
112
+ font-size: 0.9rem;
113
+ }
114
+
115
+ @media (max-width: 50rem) {
116
+ .oc-block-hero-split {
117
+ grid-template-columns: 1fr;
118
+ text-align: center;
119
+ }
120
+ }
121
+
122
+ /* ===================================================================
123
+ AUTH BLOCKS
124
+ Login / Register forms
125
+ =================================================================== */
126
+
127
+ .oc-block-auth {
128
+ max-width: 400px;
129
+ margin: 48px auto;
130
+ padding: 0 var(--oc-block-gap);
131
+ }
132
+
133
+ .oc-block-auth-card {
134
+ background: var(--oc-block-surface);
135
+ border: 1px solid var(--oc-block-border);
136
+ border-radius: var(--oc-block-radius);
137
+ padding: 32px 28px;
138
+ }
139
+
140
+ .oc-block-auth-card h2 {
141
+ margin: 0 0 6px;
142
+ font-size: 1.3rem;
143
+ color: var(--oc-block-text);
144
+ }
145
+
146
+ .oc-block-auth-card .oc-block-subtitle {
147
+ margin: 0 0 24px;
148
+ font-size: 0.88rem;
149
+ color: var(--oc-block-text-soft);
150
+ }
151
+
152
+ .oc-block-auth-footer {
153
+ text-align: center;
154
+ margin-top: 16px;
155
+ font-size: 0.85rem;
156
+ color: var(--oc-block-text-soft);
157
+ }
158
+
159
+ .oc-block-auth-footer a {
160
+ color: var(--oc-block-accent);
161
+ text-decoration: none;
162
+ }
163
+
164
+ .oc-block-auth-footer a:hover {
165
+ text-decoration: underline;
166
+ }
167
+
168
+ .oc-block-auth-divider {
169
+ display: flex;
170
+ align-items: center;
171
+ gap: 12px;
172
+ margin: 20px 0;
173
+ color: var(--oc-block-text-soft);
174
+ font-size: 0.82rem;
175
+ }
176
+
177
+ .oc-block-auth-divider::before,
178
+ .oc-block-auth-divider::after {
179
+ content: "";
180
+ flex: 1;
181
+ height: 1px;
182
+ background: var(--oc-block-border);
183
+ }
184
+
185
+ /* ===================================================================
186
+ PRICING BLOCKS
187
+ Pricing cards in a grid
188
+ =================================================================== */
189
+
190
+ .oc-block-pricing {
191
+ max-width: var(--oc-block-max-width);
192
+ margin: 48px auto;
193
+ padding: 0 var(--oc-block-gap);
194
+ text-align: center;
195
+ }
196
+
197
+ .oc-block-pricing h2 {
198
+ font-size: 1.8rem;
199
+ margin: 0 0 8px;
200
+ color: var(--oc-block-text);
201
+ }
202
+
203
+ .oc-block-pricing > p {
204
+ color: var(--oc-block-text-soft);
205
+ margin: 0 0 32px;
206
+ font-size: 1rem;
207
+ }
208
+
209
+ .oc-block-pricing-grid {
210
+ display: grid;
211
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
212
+ gap: 20px;
213
+ }
214
+
215
+ .oc-block-pricing-card {
216
+ background: var(--oc-block-surface);
217
+ border: 1px solid var(--oc-block-border);
218
+ border-radius: var(--oc-block-radius);
219
+ padding: 28px 24px;
220
+ text-align: left;
221
+ display: flex;
222
+ flex-direction: column;
223
+ }
224
+
225
+ .oc-block-pricing-card--featured {
226
+ border-color: var(--oc-block-accent);
227
+ box-shadow: 0 0 0 1px var(--oc-block-accent);
228
+ }
229
+
230
+ .oc-block-pricing-name {
231
+ font-size: 1rem;
232
+ font-weight: 600;
233
+ color: var(--oc-block-text);
234
+ margin: 0 0 4px;
235
+ }
236
+
237
+ .oc-block-pricing-desc {
238
+ font-size: 0.85rem;
239
+ color: var(--oc-block-text-soft);
240
+ margin: 0 0 16px;
241
+ }
242
+
243
+ .oc-block-pricing-price {
244
+ font-size: 2.2rem;
245
+ font-weight: 700;
246
+ color: var(--oc-block-text);
247
+ margin: 0 0 4px;
248
+ }
249
+
250
+ .oc-block-pricing-price span {
251
+ font-size: 0.9rem;
252
+ font-weight: 400;
253
+ color: var(--oc-block-text-soft);
254
+ }
255
+
256
+ .oc-block-pricing-features {
257
+ list-style: none;
258
+ margin: 16px 0 24px;
259
+ padding: 0;
260
+ flex: 1;
261
+ }
262
+
263
+ .oc-block-pricing-features li {
264
+ padding: 6px 0;
265
+ font-size: 0.88rem;
266
+ color: var(--oc-block-text-soft);
267
+ border-bottom: 1px solid var(--oc-border);
268
+ }
269
+
270
+ .oc-block-pricing-features li::before {
271
+ content: "✓ ";
272
+ color: var(--oc-block-accent);
273
+ font-weight: 600;
274
+ }
275
+
276
+ /* ===================================================================
277
+ FEATURE BLOCKS
278
+ Feature grid with icon + title + text
279
+ =================================================================== */
280
+
281
+ .oc-block-features {
282
+ max-width: var(--oc-block-max-width);
283
+ margin: 48px auto;
284
+ padding: 0 var(--oc-block-gap);
285
+ text-align: center;
286
+ }
287
+
288
+ .oc-block-features h2 {
289
+ font-size: 1.6rem;
290
+ margin: 0 0 8px;
291
+ color: var(--oc-block-text);
292
+ }
293
+
294
+ .oc-block-features > p {
295
+ color: var(--oc-block-text-soft);
296
+ margin: 0 0 32px;
297
+ }
298
+
299
+ .oc-block-features-grid {
300
+ display: grid;
301
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
302
+ gap: 20px;
303
+ text-align: left;
304
+ }
305
+
306
+ .oc-block-feature-card {
307
+ background: var(--oc-block-surface);
308
+ border: 1px solid var(--oc-block-border);
309
+ border-radius: var(--oc-block-radius);
310
+ padding: 24px;
311
+ }
312
+
313
+ .oc-block-feature-icon {
314
+ width: 40px;
315
+ height: 40px;
316
+ border-radius: 10px;
317
+ background: oklch(from var(--color-vividblue-50) l c h / 0.12);
318
+ display: flex;
319
+ align-items: center;
320
+ justify-content: center;
321
+ margin-bottom: 14px;
322
+ font-size: 1.2rem;
323
+ color: var(--oc-block-accent);
324
+ }
325
+
326
+ .oc-block-feature-card h3 {
327
+ margin: 0 0 8px;
328
+ font-size: 1rem;
329
+ color: var(--oc-block-text);
330
+ }
331
+
332
+ .oc-block-feature-card p {
333
+ margin: 0;
334
+ font-size: 0.88rem;
335
+ color: var(--oc-block-text-soft);
336
+ line-height: 1.55;
337
+ }
338
+
339
+ /* ===================================================================
340
+ TESTIMONIAL BLOCK
341
+ Quote cards in a grid
342
+ =================================================================== */
343
+
344
+ .oc-block-testimonials {
345
+ max-width: var(--oc-block-max-width);
346
+ margin: 48px auto;
347
+ padding: 0 var(--oc-block-gap);
348
+ }
349
+
350
+ .oc-block-testimonial-grid {
351
+ display: grid;
352
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
353
+ gap: 20px;
354
+ }
355
+
356
+ .oc-block-testimonial-card {
357
+ background: var(--oc-block-surface);
358
+ border: 1px solid var(--oc-block-border);
359
+ border-radius: var(--oc-block-radius);
360
+ padding: 24px;
361
+ }
362
+
363
+ .oc-block-testimonial-card blockquote {
364
+ margin: 0 0 16px;
365
+ font-size: 0.92rem;
366
+ color: var(--oc-block-text-soft);
367
+ line-height: 1.6;
368
+ font-style: italic;
369
+ }
370
+
371
+ .oc-block-testimonial-author {
372
+ display: flex;
373
+ align-items: center;
374
+ gap: 10px;
375
+ }
376
+
377
+ .oc-block-testimonial-author strong {
378
+ display: block;
379
+ font-size: 0.88rem;
380
+ color: var(--oc-block-text);
381
+ }
382
+
383
+ .oc-block-testimonial-author span {
384
+ font-size: 0.78rem;
385
+ color: var(--oc-block-text-soft);
386
+ }
387
+
388
+ /* ===================================================================
389
+ FOOTER BLOCK
390
+ Multi-column footer with links
391
+ =================================================================== */
392
+
393
+ .oc-block-footer {
394
+ inline-size: 100%;
395
+ border-top: 1px solid var(--oc-block-border);
396
+ padding: 40px var(--oc-block-gap) 24px;
397
+ max-width: var(--oc-block-max-width);
398
+ margin: 48px auto 0;
399
+ }
400
+
401
+ .oc-block-footer-grid {
402
+ display: grid;
403
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
404
+ gap: 32px;
405
+ margin-bottom: 32px;
406
+ }
407
+
408
+ .oc-block-footer-col h4 {
409
+ margin: 0 0 12px;
410
+ font-size: 0.85rem;
411
+ text-transform: uppercase;
412
+ letter-spacing: 0.06em;
413
+ color: var(--oc-block-text-soft);
414
+ }
415
+
416
+ .oc-block-footer-col ul {
417
+ list-style: none;
418
+ margin: 0;
419
+ padding: 0;
420
+ }
421
+
422
+ .oc-block-footer-col li {
423
+ margin-bottom: 8px;
424
+ }
425
+
426
+ .oc-block-footer-col a {
427
+ color: var(--oc-block-text-soft);
428
+ text-decoration: none;
429
+ font-size: 0.88rem;
430
+ }
431
+
432
+ .oc-block-footer-col a:hover {
433
+ color: var(--oc-block-text);
434
+ }
435
+
436
+ .oc-block-footer-bottom {
437
+ border-top: 1px solid var(--oc-block-border);
438
+ padding-top: 16px;
439
+ font-size: 0.82rem;
440
+ color: var(--oc-block-text-soft);
441
+ display: flex;
442
+ justify-content: space-between;
443
+ flex-wrap: wrap;
444
+ gap: 8px;
445
+ }
446
+
447
+ /* ===================================================================
448
+ CTA BLOCK
449
+ Call-to-action banner
450
+ =================================================================== */
451
+
452
+ .oc-block-cta {
453
+ background: linear-gradient(135deg, oklch(from var(--color-vividblue-50) l c h / 0.12), oklch(from var(--color-indigo-10) l c h / 0.08));
454
+ border: 1px solid var(--oc-block-border);
455
+ border-radius: var(--oc-block-radius);
456
+ padding: 40px;
457
+ text-align: center;
458
+ max-width: var(--oc-block-max-width);
459
+ margin: 48px auto;
460
+ }
461
+
462
+ .oc-block-cta h2 {
463
+ margin: 0 0 10px;
464
+ font-size: 1.5rem;
465
+ color: var(--oc-block-text);
466
+ }
467
+
468
+ .oc-block-cta p {
469
+ margin: 0 0 24px;
470
+ color: var(--oc-block-text-soft);
471
+ max-width: 520px;
472
+ margin-left: auto;
473
+ margin-right: auto;
474
+ }
475
+
476
+ /* ===================================================================
477
+ STATS BLOCK
478
+ Key metrics in a row
479
+ =================================================================== */
480
+
481
+ .oc-block-stats {
482
+ display: grid;
483
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
484
+ gap: 20px;
485
+ max-width: var(--oc-block-max-width);
486
+ margin: 48px auto;
487
+ padding: 0 var(--oc-block-gap);
488
+ text-align: center;
489
+ }
490
+
491
+ .oc-block-stat {
492
+ padding: 20px;
493
+ }
494
+
495
+ .oc-block-stat-value {
496
+ font-size: 2rem;
497
+ font-weight: 700;
498
+ color: var(--oc-block-accent);
499
+ margin-bottom: 4px;
500
+ }
501
+
502
+ .oc-block-stat-label {
503
+ font-size: 0.85rem;
504
+ color: var(--oc-block-text-soft);
505
+ }
506
+
507
+ /* ===================================================================
508
+ Swatch Grid Block — auto-fit grid for color swatch cards
509
+ =================================================================== */
510
+
511
+ .oc-block-swatch-grid {
512
+ display: grid;
513
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
514
+ gap: 10px;
515
+ margin-top: 10px;
516
+ }
517
+
518
+ /* RAL group card — accent highlight for color group headers */
519
+
520
+ .oc-block-swatch-grid .oc-swatch--ral-group {
521
+ border-color: var(--color-vividblue-70);
522
+ background: oklch(from var(--color-vividblue-70) l c h / 0.12);
523
+ min-height: 88px;
524
+ }
525
+
526
+ /* ===================================================================
527
+ APPLICATION BLOCKS (v0.2.0) — composed sections for app UIs
528
+ Built from @birdycom/omniaui (sidebar, sheet, table, stepper, …). Colors: --oc-* theme tokens only.
529
+ Index: shell · appbar · modulehead · kpis · datatable · authsplit · twofactor · settings · hub · onboarding · wizard · team · formpage
530
+ =================================================================== */
531
+
532
+ /* ---- App shell: sidebar + main column (appbar, breadcrumb strip, scrolling content) ---- */
533
+
534
+ .oc-block-shell {
535
+ --oc-block-shell-height: 100dvh;
536
+ display: grid;
537
+ grid-template-columns: auto minmax(0, 1fr);
538
+ block-size: var(--oc-block-shell-height);
539
+ background: var(--oc-background);
540
+ color: var(--oc-foreground);
541
+ overflow: hidden;
542
+ }
543
+
544
+ .oc-block-shell-toggle {
545
+ position: absolute;
546
+ opacity: 0;
547
+ pointer-events: none;
548
+ }
549
+
550
+ /* CSS-only collapse: <label for="toggle"> flips the checkbox, :has() collapses the sidebar */
551
+
552
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) .oc-sidebar {
553
+ inline-size: var(--oc-sidebar-width-icon);
554
+ }
555
+
556
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) .oc-sidebar-menu-label,
557
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) .oc-sidebar-menu-badge,
558
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) .oc-sidebar-menu-sub,
559
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) .oc-sidebar-group-label,
560
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) .oc-sidebar .oc-user-text,
561
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) details.oc-sidebar-collapsible > summary::after { display: none; }
562
+
563
+ .oc-block-shell:has(.oc-block-shell-toggle:checked) .oc-sidebar-menu-button { justify-content: center; padding-inline: 0; }
564
+
565
+ .oc-block-shell-main { display: flex; flex-direction: column; min-inline-size: 0; min-block-size: 0; }
566
+
567
+ .oc-block-shell-breadcrumbs {
568
+ flex-shrink: 0;
569
+ padding: 0.5rem 1rem;
570
+ background: var(--oc-background);
571
+ border-block-end: 1px solid var(--oc-border);
572
+ }
573
+
574
+ .oc-block-shell-content {
575
+ flex: 1;
576
+ min-block-size: 0;
577
+ min-inline-size: 0;
578
+ padding: 1rem;
579
+ overflow: auto;
580
+ overscroll-behavior-y: contain;
581
+ }
582
+
583
+ .oc-block-shell-menu-button { display: none; }
584
+
585
+ @media (max-width: 47.99rem) {
586
+ .oc-block-shell { grid-template-columns: minmax(0, 1fr); }
587
+ .oc-block-shell > .oc-sidebar { display: none; }
588
+ .oc-block-shell-menu-button { display: inline-flex; }
589
+ }
590
+
591
+ /* ---- App header bar ---- */
592
+
593
+ .oc-block-appbar {
594
+ display: flex;
595
+ align-items: center;
596
+ gap: 0.75rem;
597
+ min-block-size: 3.5rem;
598
+ padding: 0.5rem 1rem;
599
+ flex-shrink: 0;
600
+ background: var(--oc-background);
601
+ border-block-end: 1px solid var(--oc-border);
602
+ }
603
+
604
+ .oc-block-appbar-nav { flex: 1; min-inline-size: 0; overflow-x: auto; }
605
+
606
+ .oc-block-appbar-actions { display: flex; align-items: center; gap: 0.5rem; margin-inline-start: auto; }
607
+
608
+ .oc-block-appbar-title { font-size: 1rem; font-weight: 600; white-space: nowrap; }
609
+
610
+ /* ---- Module header: icon + title + intro + actions ---- */
611
+
612
+ .oc-block-modulehead { padding: 1.5rem 0 0.5rem; }
613
+
614
+ .oc-block-modulehead-band {
615
+ display: flex;
616
+ align-items: flex-start;
617
+ gap: 0.75rem;
618
+ padding: 1rem 1.25rem;
619
+ background: linear-gradient(100deg, oklch(from var(--oc-primary) l c h / 0.1), oklch(from var(--oc-primary) l c h / 0.02));
620
+ border: 1px solid oklch(from var(--oc-primary) l c h / 0.25);
621
+ border-radius: calc(var(--oc-radius) + 4px);
622
+ }
623
+
624
+ .oc-block-modulehead-icon {
625
+ display: grid;
626
+ place-items: center;
627
+ inline-size: 2.5rem;
628
+ block-size: 2.5rem;
629
+ flex-shrink: 0;
630
+ font-size: 1.25rem;
631
+ color: var(--oc-primary);
632
+ background: oklch(from var(--oc-primary) l c h / 0.12);
633
+ border-radius: calc(var(--oc-radius) + 2px);
634
+ }
635
+
636
+ .oc-block-modulehead-icon svg { inline-size: 1.25em; block-size: 1.25em; }
637
+
638
+ .oc-block-authsplit-logo svg { inline-size: 1.5rem; block-size: 1.5rem; }
639
+
640
+ .oc-block-modulehead-body { max-inline-size: 42rem; min-inline-size: 0; }
641
+
642
+ .oc-block-modulehead-title { margin: 0; font-size: 1.25rem; font-weight: 600; letter-spacing: -0.01em; color: var(--oc-foreground); }
643
+
644
+ .oc-block-modulehead-intro { margin: 0.25rem 0 0; font-size: 0.875rem; line-height: 1.55; color: var(--oc-muted-foreground); }
645
+
646
+ .oc-block-modulehead-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-block-start: 0.5rem; }
647
+
648
+ .oc-block-modulehead-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; padding-block: 1rem 0; }
649
+
650
+ /* ---- KPI / dashboard stats ---- */
651
+
652
+ /* ---- Data table card: header · toolbar · table · footer ---- */
653
+
654
+ .oc-block-datatable { padding: 0; }
655
+
656
+ .oc-block-datatable-head {
657
+ display: flex;
658
+ flex-wrap: wrap;
659
+ align-items: flex-start;
660
+ justify-content: space-between;
661
+ gap: 0.75rem;
662
+ padding: 1.25rem 1.5rem 0;
663
+ }
664
+
665
+ .oc-block-datatable-title { margin: 0; font-size: 1.1rem; font-weight: 600; color: var(--oc-foreground); }
666
+
667
+ .oc-block-datatable-description { margin: 0.125rem 0 0; font-size: 0.875rem; color: var(--oc-muted-foreground); }
668
+
669
+ .oc-block-datatable-body { padding: 1rem 1.5rem 1.25rem; }
670
+
671
+ .oc-block-datatable .oc-table-wrap { border: 1px solid var(--oc-border); }
672
+
673
+ .oc-block-datatable .oc-table { table-layout: auto; }
674
+
675
+ .oc-block-datatable .oc-table th,
676
+ .oc-block-datatable .oc-table td { border-inline: 0; }
677
+
678
+ .oc-block-datatable .oc-table tbody tr:last-child td { border-block-end: 0; }
679
+
680
+ .oc-block-datatable .oc-table-wrap > .oc-table { min-inline-size: 40rem; }
681
+
682
+ .oc-block-datatable-bulk {
683
+ display: flex;
684
+ align-items: center;
685
+ gap: 0.75rem;
686
+ padding: 0.5rem 0.75rem;
687
+ margin-block-end: 0.75rem;
688
+ font-size: 0.8125rem;
689
+ background: oklch(from var(--oc-primary) l c h / 0.08);
690
+ border: 1px solid oklch(from var(--oc-primary) l c h / 0.3);
691
+ border-radius: var(--oc-radius);
692
+ }
693
+
694
+ /* ---- Split auth layout: brand panel + form panel ---- */
695
+
696
+ .oc-block-authsplit {
697
+ display: grid;
698
+ min-block-size: 32rem;
699
+ background: var(--oc-background);
700
+ color: var(--oc-foreground);
701
+ }
702
+
703
+ @media (min-width: 62rem) { .oc-block-authsplit { grid-template-columns: 1fr 1fr; } }
704
+
705
+ .oc-block-authsplit-brand {
706
+ position: relative;
707
+ display: none;
708
+ flex-direction: column;
709
+ justify-content: space-between;
710
+ gap: 2rem;
711
+ padding: 2.5rem;
712
+ color: var(--oc-primary-foreground);
713
+ background:
714
+ radial-gradient(ellipse 80% 60% at 20% -10%, oklch(from var(--oc-brand-2) l c h / 0.35), transparent 55%),
715
+ var(--oc-primary);
716
+ border-inline-end: 1px solid var(--oc-border);
717
+ }
718
+
719
+ @media (min-width: 62rem) { .oc-block-authsplit-brand { display: flex; } }
720
+
721
+ .oc-block-authsplit-logo { display: inline-flex; align-items: center; gap: 0.75rem; font-size: 1.1rem; font-weight: 600; letter-spacing: -0.01em; color: inherit; text-decoration: none; }
722
+
723
+ .oc-block-authsplit-quote { margin: 0; max-inline-size: 28rem; padding-inline-start: 1.25rem; border-inline-start: 2px solid oklch(from var(--oc-primary-foreground) l c h / 0.55); }
724
+
725
+ .oc-block-authsplit-quote p { margin: 0 0 0.5rem; font-size: 1.1rem; line-height: 1.55; font-weight: 500; }
726
+
727
+ .oc-block-authsplit-quote footer { font-size: 0.875rem; opacity: 0.75; }
728
+
729
+ .oc-block-authsplit-form { display: flex; align-items: center; justify-content: center; padding: 2rem 1rem; }
730
+
731
+ .oc-block-authsplit-card { inline-size: 100%; max-inline-size: 26rem; }
732
+
733
+ .oc-block-authsplit-title { margin: 0 0 0.25rem; font-size: 1.5rem; font-weight: 600; letter-spacing: -0.01em; text-align: center; }
734
+
735
+ .oc-block-authsplit-subtitle { margin: 0 0 1.5rem; font-size: 0.875rem; text-align: center; color: var(--oc-muted-foreground); }
736
+
737
+ .oc-block-authsplit-fields { display: flex; flex-direction: column; gap: 1rem; }
738
+
739
+ .oc-block-authsplit-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-size: 0.8125rem; }
740
+
741
+ /* ---- Two-factor: OTP code + recovery codes ---- */
742
+
743
+ .oc-block-twofactor { display: grid; gap: 1.5rem; max-inline-size: 28rem; margin-inline: auto; }
744
+
745
+ .oc-block-twofactor-step { display: grid; gap: 0.75rem; }
746
+
747
+ .oc-block-twofactor-center { display: grid; justify-items: center; gap: 0.75rem; text-align: center; }
748
+
749
+ .oc-block-twofactor-qr {
750
+ display: grid;
751
+ place-items: center;
752
+ inline-size: 11rem;
753
+ block-size: 11rem;
754
+ font-size: 0.75rem;
755
+ color: var(--oc-muted-foreground);
756
+ background: var(--oc-surface-strong);
757
+ border: 1px dashed var(--oc-border-strong);
758
+ border-radius: var(--oc-radius);
759
+ }
760
+
761
+ /* ---- Settings page: section navigation + content sections ---- */
762
+
763
+ /* ---- Hub: grid of launcher cards ---- */
764
+
765
+ /* ---- Onboarding checklist card ---- */
766
+
767
+ /* ---- Wizard dialog: stepper rail + step content ---- */
768
+
769
+ .oc-block-wizard { display: flex; flex-direction: column; min-block-size: 0; }
770
+
771
+ @media (min-width: 48rem) { .oc-block-wizard { flex-direction: row; } }
772
+
773
+ .oc-block-wizard-rail { flex-shrink: 0; padding: 0.75rem; border-block-end: 1px solid var(--oc-border); overflow-x: auto; }
774
+
775
+ @media (min-width: 48rem) { .oc-block-wizard-rail { inline-size: 15rem; padding: 1rem; border-block-end: 0; border-inline-end: 1px solid var(--oc-border); overflow-y: auto; } }
776
+
777
+ .oc-block-wizard-main { display: flex; flex: 1; flex-direction: column; min-inline-size: 0; }
778
+
779
+ .oc-block-wizard-step { flex: 1; padding: 1.25rem 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
780
+
781
+ .oc-block-wizard-step[hidden] { display: none; }
782
+
783
+ /* ---- Team list: members with role and actions ---- */
784
+
785
+ .oc-block-team { display: flex; flex-direction: column; border: 1px solid var(--oc-border); border-radius: calc(var(--oc-radius) + 4px); background: var(--oc-card); overflow: hidden; }
786
+
787
+ .oc-block-team-row { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; }
788
+
789
+ .oc-block-team-row + .oc-block-team-row { border-block-start: 1px solid var(--oc-border); }
790
+
791
+ .oc-block-team-row .oc-user { flex: 1; }
792
+
793
+ .oc-block-team-meta { display: flex; align-items: center; gap: 0.5rem; }
794
+
795
+ /* ---- Form page: collapsible sections + sticky action bar ---- */
796
+
797
+ .oc-block-formpage { display: flex; flex-direction: column; gap: 1rem; max-inline-size: 56rem; }
798
+
799
+ .oc-block-formpage-grid { display: grid; gap: 1rem; }
800
+
801
+ @media (min-width: 40rem) { .oc-block-formpage-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
802
+
803
+ .oc-block-formpage-actions {
804
+ position: sticky;
805
+ inset-block-end: 0;
806
+ display: flex;
807
+ justify-content: flex-end;
808
+ gap: 0.5rem;
809
+ padding: 0.75rem 1rem;
810
+ background: var(--oc-background);
811
+ border: 1px solid var(--oc-border);
812
+ border-radius: calc(var(--oc-radius) + 2px);
813
+ box-shadow: 0 -4px 16px oklch(from var(--color-black-60) l c h / 0.08);
814
+ }
815
+
816
+ /* C-BLOCKS:begin */
817
+
818
+ /* ===================================================================
819
+ AUTH FAMILY (login-01..05, signup-01..03, otp-01..03, forgot-password, reset-password)
820
+ Index: authpage · authcard · authsocial · authduo (container-query split) · authmin
821
+ =================================================================== */
822
+
823
+ .oc-block-authpage {
824
+ display: grid;
825
+ place-items: center;
826
+ min-block-size: 30rem;
827
+ padding: 2rem 1rem;
828
+ color: var(--oc-foreground);
829
+ background: var(--oc-muted);
830
+ border-radius: calc(var(--oc-radius) + 4px);
831
+ }
832
+
833
+ .oc-block-authpage--plain { background: var(--oc-background); border: 1px solid var(--oc-border); }
834
+
835
+ .oc-block-authcard {
836
+ display: flex;
837
+ flex-direction: column;
838
+ gap: 1rem;
839
+ inline-size: 100%;
840
+ max-inline-size: 24rem;
841
+ padding: 1.5rem;
842
+ color: var(--oc-foreground);
843
+ background: var(--oc-card);
844
+ border: 1px solid var(--oc-border);
845
+ border-radius: calc(var(--oc-radius) + 4px);
846
+ box-shadow: 0 1px 2px oklch(from var(--color-black-60) l c h / 0.06);
847
+ }
848
+
849
+ .oc-block-authcard--flat { padding: 0; background: transparent; border: 0; box-shadow: none; }
850
+
851
+ .oc-block-authcard--wide { max-inline-size: 28rem; }
852
+
853
+ .oc-block-authcard-logo {
854
+ display: grid;
855
+ place-items: center;
856
+ inline-size: 2.5rem;
857
+ block-size: 2.5rem;
858
+ margin-inline: auto;
859
+ color: var(--oc-primary-foreground);
860
+ background: var(--oc-primary);
861
+ border-radius: var(--oc-radius);
862
+ }
863
+
864
+ .oc-block-authcard-logo svg { inline-size: 1.35rem; block-size: 1.35rem; }
865
+
866
+ .oc-block-authcard-head { display: flex; flex-direction: column; gap: 0.25rem; text-align: center; }
867
+
868
+ .oc-block-authcard-title { margin: 0; font-size: 1.375rem; font-weight: 600; letter-spacing: -0.01em; }
869
+
870
+ .oc-block-authcard-text { margin: 0; font-size: 0.875rem; color: var(--oc-muted-foreground); }
871
+
872
+ .oc-block-authcard-fields { display: flex; flex-direction: column; gap: 1rem; }
873
+
874
+ .oc-block-authcard-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-size: 0.8125rem; }
875
+
876
+ .oc-block-authcard-foot { margin: 0; font-size: 0.875rem; text-align: center; color: var(--oc-muted-foreground); }
877
+
878
+ .oc-block-authcard-foot a { color: var(--oc-foreground); font-weight: 500; text-decoration: underline; text-underline-offset: 3px; }
879
+
880
+ .oc-block-authcard-legal { margin: 0; font-size: 0.75rem; text-align: center; color: var(--oc-muted-foreground); }
881
+
882
+ .oc-block-authcard-legal a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
883
+
884
+ .oc-block-authcard-submit { inline-size: 100%; }
885
+
886
+ .oc-block-authcard-hint { margin: 0; font-size: 0.75rem; color: var(--oc-muted-foreground); }
887
+
888
+ .oc-block-authcard-center { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; }
889
+
890
+ .oc-block-authsocial { display: grid; grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr)); gap: 0.5rem; }
891
+
892
+ .oc-block-authsocial .oc-btn { inline-size: 100%; }
893
+
894
+ /* Split: panel + form, switches to two columns by container width */
895
+
896
+ .oc-block-authduo {
897
+ container: oc-authduo / inline-size;
898
+ color: var(--oc-foreground);
899
+ background: var(--oc-background);
900
+ border: 1px solid var(--oc-border);
901
+ border-radius: calc(var(--oc-radius) + 4px);
902
+ overflow: hidden;
903
+ }
904
+
905
+ .oc-block-authduo-grid { display: grid; min-block-size: 34rem; }
906
+
907
+ @container oc-authduo (min-width: 42rem) {
908
+ .oc-block-authduo-grid { grid-template-columns: 1fr 1fr; }
909
+ .oc-block-authduo-panel { display: flex; }
910
+ .oc-block-authduo--reverse .oc-block-authduo-panel { order: 2; }
911
+ }
912
+
913
+ .oc-block-authduo-panel {
914
+ position: relative;
915
+ display: none;
916
+ flex-direction: column;
917
+ justify-content: space-between;
918
+ gap: 2rem;
919
+ padding: 2rem;
920
+ color: var(--oc-primary-foreground);
921
+ background:
922
+ radial-gradient(ellipse 70% 55% at 85% 100%, oklch(from var(--oc-brand-2) l c h / 0.4), transparent 60%),
923
+ radial-gradient(ellipse 60% 50% at 10% 0%, oklch(from var(--oc-brand-3) l c h / 0.35), transparent 60%),
924
+ var(--oc-primary);
925
+ }
926
+
927
+ .oc-block-authduo-panel--image::before {
928
+ content: "";
929
+ position: absolute;
930
+ inset: 0;
931
+ background:
932
+ repeating-linear-gradient(135deg, oklch(from var(--oc-primary-foreground) l c h / 0.07) 0 1px, transparent 1px 14px),
933
+ linear-gradient(to top, oklch(from var(--oc-primary) l c h / 0.7), transparent 60%);
934
+ pointer-events: none;
935
+ }
936
+
937
+ .oc-block-authduo-panel--muted { color: var(--oc-foreground); background: var(--oc-muted); }
938
+
939
+ .oc-block-authduo-panel > * { position: relative; }
940
+
941
+ .oc-block-authduo-logo { display: inline-flex; align-items: center; gap: 0.6rem; font-weight: 600; color: inherit; text-decoration: none; }
942
+
943
+ .oc-block-authduo-logo svg { inline-size: 1.4rem; block-size: 1.4rem; }
944
+
945
+ .oc-block-authduo-quote { margin: 0; max-inline-size: 26rem; }
946
+
947
+ .oc-block-authduo-quote p { margin: 0 0 0.5rem; font-size: 1.05rem; line-height: 1.55; font-weight: 500; }
948
+
949
+ .oc-block-authduo-quote footer { font-size: 0.8125rem; opacity: 0.8; }
950
+
951
+ .oc-block-authduo-form { display: grid; place-items: center; padding: 2rem 1.25rem; }
952
+
953
+ /* Minimal: no card, one centered column */
954
+
955
+ .oc-block-authmin { display: grid; place-items: center; min-block-size: 26rem; padding: 2rem 1rem; color: var(--oc-foreground); background: var(--oc-background); border: 1px solid var(--oc-border); border-radius: calc(var(--oc-radius) + 4px); }
956
+
957
+ /* ===================================================================
958
+ SIDEBAR FAMILY (sidebar-01..16) — a demo frame around .oc-sidebar plus a page-shaped main area
959
+ Index: sb · sb-main · sb-bar · sb-body · sb-ph · sb-group (collapsible group) · sb-rail · sb-toggle (icon collapse)
960
+ =================================================================== */
961
+
962
+ .oc-block-sb {
963
+ --oc-block-sb-height: 26rem;
964
+ display: grid;
965
+ grid-template-columns: auto minmax(0, 1fr);
966
+ block-size: var(--oc-block-sb-height);
967
+ color: var(--oc-foreground);
968
+ background: var(--oc-background);
969
+ border: 1px solid var(--oc-border);
970
+ border-radius: calc(var(--oc-radius) + 4px);
971
+ overflow: hidden;
972
+ }
973
+
974
+ .oc-block-sb--floating { background: var(--oc-muted); }
975
+
976
+ .oc-block-sb-main { display: flex; flex-direction: column; min-inline-size: 0; min-block-size: 0; }
977
+
978
+ .oc-block-sb-bar {
979
+ display: flex;
980
+ align-items: center;
981
+ gap: 0.5rem;
982
+ flex-shrink: 0;
983
+ min-block-size: 3rem;
984
+ padding: 0.5rem 0.75rem;
985
+ background: var(--oc-background);
986
+ border-block-end: 1px solid var(--oc-border);
987
+ }
988
+
989
+ .oc-block-sb-sep { inline-size: 1px; block-size: 1rem; background: var(--oc-border-strong); }
990
+
991
+ .oc-block-sb-body {
992
+ flex: 1;
993
+ display: grid;
994
+ grid-template-columns: repeat(3, minmax(0, 1fr));
995
+ grid-auto-rows: 4.5rem;
996
+ gap: 0.75rem;
997
+ min-block-size: 0;
998
+ padding: 0.75rem;
999
+ overflow: auto;
1000
+ }
1001
+
1002
+ .oc-block-sb-ph { background: var(--oc-muted); border-radius: var(--oc-radius); }
1003
+
1004
+ .oc-block-sb-ph--wide { grid-column: 1 / -1; grid-row: span 3; }
1005
+
1006
+ .oc-block-sb-toggle { position: absolute; opacity: 0; pointer-events: none; }
1007
+
1008
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) .oc-sidebar { inline-size: var(--oc-sidebar-width-icon); }
1009
+
1010
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) .oc-sidebar-menu-label,
1011
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) .oc-sidebar-menu-badge,
1012
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) .oc-sidebar-menu-sub,
1013
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) .oc-sidebar-group-label,
1014
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) .oc-sidebar .oc-user-text,
1015
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) details.oc-sidebar-collapsible > summary::after { display: none; }
1016
+
1017
+ .oc-block-sb:has(.oc-block-sb-toggle:checked) .oc-sidebar-menu-button { justify-content: center; padding-inline: 0; }
1018
+
1019
+ .oc-block-sb-hint { margin: 0; padding: 0 0.75rem; font-size: 0.75rem; color: var(--oc-muted-foreground); }
1020
+
1021
+ /* Collapsible group: <details class="oc-block-sb-group"><summary>Label</summary><ul class="oc-sidebar-menu">… */
1022
+
1023
+ .oc-block-sb-group > summary {
1024
+ display: flex;
1025
+ align-items: center;
1026
+ justify-content: space-between;
1027
+ padding: 0.5rem 0.625rem 0.25rem;
1028
+ font-size: 0.7rem;
1029
+ font-weight: 600;
1030
+ letter-spacing: 0.04em;
1031
+ text-transform: uppercase;
1032
+ color: var(--oc-muted-foreground);
1033
+ list-style: none;
1034
+ cursor: pointer;
1035
+ border-radius: var(--oc-radius);
1036
+ }
1037
+
1038
+ .oc-block-sb-group > summary::-webkit-details-marker { display: none; }
1039
+
1040
+ .oc-block-sb-group > summary::after {
1041
+ content: "";
1042
+ inline-size: 0.4rem;
1043
+ block-size: 0.4rem;
1044
+ border-inline-end: 1.5px solid currentColor;
1045
+ border-block-end: 1.5px solid currentColor;
1046
+ rotate: -45deg;
1047
+ transition: rotate var(--oc-transition-fast);
1048
+ }
1049
+
1050
+ .oc-block-sb-group[open] > summary::after { rotate: 45deg; }
1051
+
1052
+ .oc-block-sb-group > summary:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: -2px; }
1053
+
1054
+ /* Icon rail for the double sidebar */
1055
+
1056
+ .oc-block-sb-rail {
1057
+ display: flex;
1058
+ flex-direction: column;
1059
+ align-items: center;
1060
+ gap: 0.5rem;
1061
+ inline-size: 3.5rem;
1062
+ padding: 0.75rem 0.5rem;
1063
+ background: var(--oc-muted);
1064
+ border-inline-end: 1px solid var(--oc-border);
1065
+ }
1066
+
1067
+ .oc-block-sb-rail .oc-sidebar-menu-button { justify-content: center; padding: 0.5rem; }
1068
+
1069
+ /* Team switcher + user menu buttons */
1070
+
1071
+ .oc-block-sb-switch { inline-size: 100%; border: 0; background: transparent; font: inherit; color: inherit; cursor: pointer; text-align: start; }
1072
+
1073
+ .oc-block-sb-tile { display: grid; place-items: center; inline-size: 2rem; block-size: 2rem; flex: none; color: var(--oc-primary-foreground); background: var(--oc-primary); border-radius: var(--oc-radius); }
1074
+
1075
+ .oc-block-sb-tile svg { inline-size: 1rem; block-size: 1rem; }
1076
+
1077
+ .oc-block-sb-sub { display: block; font-size: 0.75rem; font-weight: 400; color: var(--oc-muted-foreground); }
1078
+
1079
+ /* ===================================================================
1080
+ DASHBOARD-01 + CHARTS — charts are plain SVG/CSS on the --oc-chart-1..5 tokens
1081
+ Index: chart (card) · chart-svg · chart-line/-area/-grid · chart-months · donut · radial · hbars · spark
1082
+ =================================================================== */
1083
+
1084
+ .oc-block-dash-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); gap: 1rem; }
1085
+
1086
+ .oc-block-dash-table { inline-size: 100%; }
1087
+
1088
+ /* parts/site-about-timeline.css */
1089
+ /* File: packages/blocks/src/parts/site-about-timeline.css
1090
+ Map: section -> split grid -> media placeholder + badge -> copy -> timeline spacing -> reverse variant
1091
+ About block: a picture next to the story of the company, ending in the timeline component. */
1092
+
1093
+ .oc-block-about {
1094
+ container-type: inline-size;
1095
+ max-inline-size: var(--oc-block-max-width, 1200px);
1096
+ margin-inline: auto;
1097
+ padding: clamp(3rem, 7vw, 5rem) var(--oc-block-gap, 24px);
1098
+ }
1099
+
1100
+ .oc-block-about-inner { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: center; }
1101
+ @container (min-width: 52rem) {
1102
+ .oc-block-about-inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
1103
+ /* Reverse: picture on the right. */
1104
+ .oc-block-about--reverse .oc-block-about-media { order: 2; }
1105
+ }
1106
+
1107
+ /* Picture: an <img> inside, or the accent gradient placeholder when empty. */
1108
+ .oc-block-about-media {
1109
+ position: relative;
1110
+ margin: 0;
1111
+ aspect-ratio: 4 / 3;
1112
+ border: 1px solid var(--oc-border);
1113
+ border-radius: var(--oc-radius-lg, 1.25rem);
1114
+ background:
1115
+ radial-gradient(circle at 25% 20%, color-mix(in oklch, var(--color-white-50) 28%, transparent), transparent 40%),
1116
+ linear-gradient(140deg, var(--oc-accent-from), var(--oc-accent-to));
1117
+ overflow: hidden;
1118
+ }
1119
+ .oc-block-about-media > img { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
1120
+
1121
+ /* Floating badge on the picture ("Since 2012"). */
1122
+ .oc-block-about-badge {
1123
+ position: absolute;
1124
+ inset: auto auto 1rem 1rem;
1125
+ display: grid;
1126
+ padding: 0.75rem 1rem;
1127
+ border: 1px solid var(--oc-border);
1128
+ border-radius: var(--oc-radius-md, 0.75rem);
1129
+ background: color-mix(in oklch, var(--oc-background) 85%, transparent);
1130
+ backdrop-filter: blur(10px);
1131
+ color: var(--oc-muted-foreground);
1132
+ font-size: 0.85rem;
1133
+ }
1134
+ .oc-block-about-badge strong { color: var(--oc-foreground); font-size: 1.4rem; line-height: 1.1; }
1135
+
1136
+ .oc-block-about-title {
1137
+ margin: 0 0 1rem;
1138
+ font-size: clamp(1.75rem, 4vw, 2.6rem);
1139
+ font-weight: 700;
1140
+ line-height: 1.15;
1141
+ letter-spacing: -0.02em;
1142
+ text-wrap: balance;
1143
+ }
1144
+ .oc-block-about-copy > p:not([class]) {
1145
+ margin: 0 0 1rem;
1146
+ color: var(--oc-muted-foreground);
1147
+ line-height: 1.65;
1148
+ }
1149
+ .oc-block-about-copy .oc-timeline { margin-block-start: 1.75rem; }
1150
+
1151
+ /* parts/site-contact-grid.css */
1152
+ /* File: packages/blocks/src/parts/site-contact-grid.css
1153
+ Map: section -> head -> card grid -> card (mark, title, lines) -> plain variant
1154
+ Contact grid block: contact info cards (e-mail, phone, address, hours). */
1155
+
1156
+ .oc-block-contact {
1157
+ max-inline-size: var(--oc-block-max-width, 1200px);
1158
+ margin-inline: auto;
1159
+ padding: clamp(3rem, 7vw, 5rem) var(--oc-block-gap, 24px);
1160
+ }
1161
+
1162
+ .oc-block-contact-head { max-inline-size: 40rem; margin-block-end: 2rem; }
1163
+ .oc-block-contact-heading {
1164
+ margin: 0 0 0.75rem;
1165
+ font-size: clamp(1.75rem, 4vw, 2.5rem);
1166
+ font-weight: 700;
1167
+ letter-spacing: -0.02em;
1168
+ }
1169
+ .oc-block-contact-lead { margin: 0; color: var(--oc-muted-foreground); font-size: 1.05rem; line-height: 1.6; }
1170
+
1171
+ .oc-block-contact-grid {
1172
+ display: grid;
1173
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
1174
+ gap: 1.25rem;
1175
+ }
1176
+
1177
+ .oc-block-contact-card {
1178
+ display: grid;
1179
+ align-content: start;
1180
+ gap: 0.35rem;
1181
+ padding: 1.5rem;
1182
+ border: 1px solid var(--oc-border);
1183
+ border-radius: var(--oc-radius-lg, 1.25rem);
1184
+ background: var(--oc-surface);
1185
+ font-style: normal; /* the address card is an <address> */
1186
+ }
1187
+ .oc-block-contact-card > .oc-product-mark { margin-block-end: 0.75rem; }
1188
+ .oc-block-contact-title { margin: 0 0 0.25rem; font-size: 1.05rem; font-weight: 700; }
1189
+
1190
+ /* A line of info. As a link it turns to the foreground color on hover. */
1191
+ .oc-block-contact-line {
1192
+ margin: 0;
1193
+ color: var(--oc-muted-foreground);
1194
+ font-size: 0.95rem;
1195
+ line-height: 1.55;
1196
+ text-decoration: none;
1197
+ overflow-wrap: anywhere;
1198
+ }
1199
+ a.oc-block-contact-line { color: var(--oc-foreground); font-weight: 500; }
1200
+ a.oc-block-contact-line:hover { color: var(--oc-brand-1); }
1201
+
1202
+ /* Plain: no card frames, a thin accent line on top of each item. */
1203
+ .oc-block-contact--plain .oc-block-contact-card {
1204
+ padding: 1.25rem 0 0;
1205
+ border: 0;
1206
+ border-block-start: 2px solid var(--oc-border-strong);
1207
+ border-radius: 0;
1208
+ background: none;
1209
+ }
1210
+
1211
+ /* parts/site-faq.css */
1212
+ /* File: packages/blocks/src/parts/site-faq.css
1213
+ Map: section -> head (eyebrow, title, lead) -> accordion list -> "more" line -> split variant
1214
+ FAQ block: a title plus the accordion component on native <details name="…"> (one item open at a time). */
1215
+
1216
+ .oc-block-faq {
1217
+ container-type: inline-size;
1218
+ max-inline-size: var(--oc-block-max-width, 1200px);
1219
+ margin-inline: auto;
1220
+ padding: clamp(3rem, 7vw, 5rem) var(--oc-block-gap, 24px);
1221
+ }
1222
+
1223
+ .oc-block-faq-inner {
1224
+ display: grid;
1225
+ gap: 2rem;
1226
+ max-inline-size: 48rem;
1227
+ margin-inline: auto;
1228
+ }
1229
+
1230
+ .oc-block-faq-head { text-align: center; }
1231
+ .oc-block-faq-title {
1232
+ margin: 0 0 0.75rem;
1233
+ font-size: clamp(1.75rem, 4vw, 2.5rem);
1234
+ font-weight: 700;
1235
+ letter-spacing: -0.02em;
1236
+ text-wrap: balance;
1237
+ }
1238
+ .oc-block-faq-lead {
1239
+ margin: 0;
1240
+ color: var(--oc-block-text-soft, var(--oc-muted-foreground));
1241
+ font-size: 1.05rem;
1242
+ line-height: 1.6;
1243
+ }
1244
+
1245
+ /* The accordion fills the column (the component default is 46rem wide). */
1246
+ .oc-block-faq-list { --oc-accordion-width: 100%; background: var(--oc-block-surface, var(--oc-card)); }
1247
+
1248
+ .oc-block-faq-more {
1249
+ margin: 0;
1250
+ color: var(--oc-block-text-soft, var(--oc-muted-foreground));
1251
+ text-align: center;
1252
+ }
1253
+
1254
+ /* Split: head on the left, questions on the right (from 48rem container width). */
1255
+ @container (min-width: 48rem) {
1256
+ .oc-block-faq--split .oc-block-faq-inner {
1257
+ grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
1258
+ align-items: start;
1259
+ max-inline-size: none;
1260
+ }
1261
+ .oc-block-faq--split .oc-block-faq-head { text-align: start; position: sticky; inset-block-start: 1rem; }
1262
+ .oc-block-faq--split .oc-block-faq-more { grid-column: 2; text-align: start; }
1263
+ }
1264
+
1265
+ /* parts/site-hero-orbit.css */
1266
+ /* File: packages/blocks/src/parts/site-hero-orbit.css
1267
+ Map: visual (square, container) -> dashed ring that turns -> marks on the ring (stay upright) -> center window -> reduced motion
1268
+ Hero orbit block: hero-code layout where product marks orbit around the code window.
1269
+ Place a mark with style="--oc-orbit-angle: 60deg". The ring turns once per --oc-orbit-duration (default 60s). */
1270
+
1271
+ /* Square stage; container units (cqi) give the ring radius. */
1272
+ .oc-block-orbit-visual {
1273
+ position: relative;
1274
+ container-type: inline-size;
1275
+ display: grid;
1276
+ place-items: center;
1277
+ inline-size: 100%;
1278
+ max-inline-size: 32rem;
1279
+ aspect-ratio: 1;
1280
+ margin-inline: auto;
1281
+ }
1282
+
1283
+ /* The ring: a dashed circle that slowly turns and carries the marks. */
1284
+ .oc-block-orbit-ring {
1285
+ position: absolute;
1286
+ inset: 6%;
1287
+ border: 1px dashed color-mix(in oklch, var(--oc-border-strong) 80%, transparent);
1288
+ border-radius: 50%;
1289
+ animation: oc-orbit-spin var(--oc-orbit-duration, 60s) linear infinite;
1290
+ }
1291
+ /* Second, inner ring for depth (no marks). */
1292
+ .oc-block-orbit-ring::before {
1293
+ content: "";
1294
+ position: absolute;
1295
+ inset: 18%;
1296
+ border: 1px solid color-mix(in oklch, var(--oc-border) 70%, transparent);
1297
+ border-radius: 50%;
1298
+ }
1299
+
1300
+ /* A mark sits on the ring at its angle. Radius = half the ring = 44% of the stage width. */
1301
+ .oc-block-orbit-mark {
1302
+ position: absolute;
1303
+ inset-block-start: 50%;
1304
+ inset-inline-start: 50%;
1305
+ translate: -50% -50%;
1306
+ transform: rotate(var(--oc-orbit-angle, 0deg)) translateX(44cqi) rotate(calc(var(--oc-orbit-angle, 0deg) * -1));
1307
+ }
1308
+ /* The mark turns back as fast as the ring turns, so its glyph stays upright. */
1309
+ .oc-block-orbit-mark > * {
1310
+ display: grid;
1311
+ animation: oc-orbit-spin var(--oc-orbit-duration, 60s) linear infinite reverse;
1312
+ }
1313
+
1314
+ /* Center: the code window (or any visual) above the ring. */
1315
+ .oc-block-orbit-center {
1316
+ position: relative;
1317
+ z-index: 1;
1318
+ inline-size: min(100%, 72cqi);
1319
+ }
1320
+ .oc-block-orbit-center.oc-code-window .oc-code-window__body { font-size: clamp(0.7rem, 2.6cqi, 0.9rem); }
1321
+
1322
+ @keyframes oc-orbit-spin { to { rotate: 360deg; } }
1323
+
1324
+ @media (prefers-reduced-motion: reduce) {
1325
+ .oc-block-orbit-ring,
1326
+ .oc-block-orbit-mark > * { animation: none; }
1327
+ }
1328
+
1329
+ /* parts/site-portfolio-grid.css */
1330
+ /* File: packages/blocks/src/parts/site-portfolio-grid.css
1331
+ Map: section -> head (title left, "all projects" link right) -> card grid -> two-column variant
1332
+ Portfolio grid block: a heading and a grid of project-card components. */
1333
+
1334
+ .oc-block-portfolio-head {
1335
+ display: flex;
1336
+ flex-wrap: wrap;
1337
+ align-items: flex-end;
1338
+ justify-content: space-between;
1339
+ gap: 1rem 2rem;
1340
+ margin-block-end: 2rem;
1341
+ }
1342
+ .oc-block-portfolio-head .oc-display { margin-block-end: 0; }
1343
+ .oc-block-portfolio-lead { margin: 0.75rem 0 0; color: var(--oc-muted-foreground); max-inline-size: 36rem; }
1344
+
1345
+ .oc-block-portfolio-grid {
1346
+ display: grid;
1347
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--oc-portfolio-min, 18rem)), 1fr));
1348
+ gap: 1.5rem;
1349
+ }
1350
+
1351
+ /* Two columns: bigger cards (fewer, more important projects). */
1352
+ .oc-block-portfolio--two { --oc-portfolio-min: 26rem; }
1353
+
1354
+ /* parts/site-profile-header.css */
1355
+ /* File: packages/blocks/src/parts/site-profile-header.css
1356
+ Map: section -> banner -> bar (overhanging avatar, info, actions) -> tab bar -> compact variant
1357
+ Profile header block: banner, an avatar that overlaps the banner edge, name + meta, actions and link tabs.
1358
+ Banner image: style="--oc-profile-banner: url(...)" (default: an accent gradient). */
1359
+
1360
+ .oc-block-profile {
1361
+ container-type: inline-size;
1362
+ max-inline-size: var(--oc-block-max-width, 1200px);
1363
+ margin-inline: auto;
1364
+ }
1365
+
1366
+ .oc-block-profile-banner {
1367
+ aspect-ratio: 6 / 1;
1368
+ min-block-size: 7rem;
1369
+ border-radius: var(--oc-block-radius, 16px);
1370
+ background:
1371
+ var(--oc-profile-banner, radial-gradient(circle at 85% 30%, color-mix(in oklch, var(--color-white-50) 25%, transparent), transparent 40%)),
1372
+ linear-gradient(120deg, var(--oc-accent-from), var(--oc-accent-to));
1373
+ background-size: cover;
1374
+ background-position: center;
1375
+ }
1376
+
1377
+ .oc-block-profile-bar {
1378
+ display: flex;
1379
+ flex-wrap: wrap;
1380
+ align-items: flex-end;
1381
+ gap: 1rem 1.25rem;
1382
+ padding-inline: clamp(1rem, 3vw, 1.5rem);
1383
+ }
1384
+
1385
+ /* The avatar component, made bigger and pulled up over the banner edge. */
1386
+ .oc-block-profile-avatar.oc-avatar {
1387
+ width: 6.5rem;
1388
+ height: 6.5rem;
1389
+ margin-block-start: -3.25rem;
1390
+ border: 4px solid var(--oc-background);
1391
+ font-size: 2rem;
1392
+ }
1393
+
1394
+ .oc-block-profile-info { flex: 1 1 16rem; min-inline-size: 0; padding-block-start: 0.75rem; }
1395
+ .oc-block-profile-name { margin: 0; font-size: clamp(1.4rem, 3vw, 1.9rem); font-weight: 700; letter-spacing: -0.02em; }
1396
+ .oc-block-profile-meta { margin: 0.2rem 0 0; color: var(--oc-muted-foreground); font-size: 0.9rem; }
1397
+ .oc-block-profile-bio { margin: 0.5rem 0 0; color: var(--oc-muted-foreground); font-size: 0.95rem; max-inline-size: 44rem; }
1398
+ .oc-block-profile-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
1399
+
1400
+ /* Tab bar: links; the current one gets aria-current="page". Scrolls sideways on small screens. */
1401
+ .oc-block-profile-tabs {
1402
+ display: flex;
1403
+ gap: 0.25rem;
1404
+ margin-block-start: 1.25rem;
1405
+ padding-inline: clamp(1rem, 3vw, 1.5rem);
1406
+ border-block-end: 1px solid var(--oc-border);
1407
+ overflow-x: auto;
1408
+ scrollbar-width: none;
1409
+ }
1410
+ .oc-block-profile-tab {
1411
+ padding: 0.75rem 1rem;
1412
+ border-block-end: 2px solid transparent;
1413
+ color: var(--oc-muted-foreground);
1414
+ font-size: 0.92rem;
1415
+ font-weight: 500;
1416
+ text-decoration: none;
1417
+ white-space: nowrap;
1418
+ transition: color var(--oc-transition-fast, 150ms), border-color var(--oc-transition-fast, 150ms);
1419
+ }
1420
+ .oc-block-profile-tab:hover { color: var(--oc-foreground); }
1421
+ .oc-block-profile-tab[aria-current="page"] { border-block-end-color: var(--oc-brand-1); color: var(--oc-foreground); }
1422
+ .oc-block-profile-tab:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: -2px; }
1423
+
1424
+ /* Compact: low banner and a smaller avatar. */
1425
+ .oc-block-profile--compact .oc-block-profile-banner { aspect-ratio: 10 / 1; min-block-size: 4.5rem; }
1426
+ .oc-block-profile--compact .oc-block-profile-avatar.oc-avatar { width: 4.5rem; height: 4.5rem; margin-block-start: -2.25rem; font-size: 1.4rem; }
1427
+
1428
+ /* Narrow: the actions go below the info, full width. */
1429
+ @container (max-width: 34rem) {
1430
+ .oc-block-profile-actions { flex-basis: 100%; }
1431
+ }