@webspire/mcp 0.7.1 → 0.8.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 (2) hide show
  1. package/data/registry.json +1946 -56
  2. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "1.2.0",
3
- "generated": "2026-03-21T18:18:27.871Z",
3
+ "generated": "2026-03-21T23:26:59.284Z",
4
4
  "snippets": [
5
5
  {
6
6
  "id": "animations/blur-in",
@@ -675,6 +675,60 @@
675
675
  },
676
676
  "css": "@property --breathe-hue {\n syntax: \"<number>\";\n initial-value: 280;\n inherits: false;\n}\n\n.color-breathe {\n --breathe-hue-start: 280;\n --breathe-hue-end: 180;\n --breathe-chroma: 0.2;\n --breathe-lightness: 0.6;\n --breathe-speed: 8s;\n --breathe-hue: var(--breathe-hue-start);\n background: oklch(var(--breathe-lightness) var(--breathe-chroma) var(--breathe-hue));\n animation: color-breathe-shift var(--breathe-speed) ease-in-out infinite alternate;\n}\n\n@keyframes color-breathe-shift {\n to {\n --breathe-hue: var(--breathe-hue-end);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .color-breathe {\n animation: none;\n }\n}\n"
677
677
  },
678
+ {
679
+ "id": "decorative/frame-corners",
680
+ "title": "Frame Corners",
681
+ "description": "Minimal corner-frame accent for cards, images, and promo blocks using only pseudo-elements.",
682
+ "category": "decorative",
683
+ "tags": [
684
+ "frame",
685
+ "corners",
686
+ "accent",
687
+ "card",
688
+ "overlay"
689
+ ],
690
+ "responsive": false,
691
+ "darkMode": false,
692
+ "dependencies": [],
693
+ "variants": [],
694
+ "updatedAt": "2026-03-22",
695
+ "meta": {
696
+ "lines": 30,
697
+ "bytes": 753,
698
+ "tailwind": "4.x",
699
+ "browser": "baseline-2024",
700
+ "accessibility": {
701
+ "prefersReducedMotion": false,
702
+ "prefersColorScheme": false,
703
+ "supportsCheck": false
704
+ },
705
+ "customProperties": [
706
+ "--frame-corner-color",
707
+ "--frame-corner-size",
708
+ "--frame-corner-thickness"
709
+ ],
710
+ "classes": [
711
+ ".frame-corners"
712
+ ],
713
+ "useCases": [
714
+ "editorial promo cards with a more designed perimeter",
715
+ "image blocks or hero media frames",
716
+ "category tiles that need a subtle graphic accent"
717
+ ],
718
+ "solves": [
719
+ "bordered cards feel too generic",
720
+ "need a graphic frame treatment without extra markup",
721
+ "want a pseudo-element accent that works inside Tailwind cards"
722
+ ],
723
+ "usageExample": "<article class=\"frame-corners relative rounded-3xl border border-white/10 bg-slate-950/80 p-6 text-white\">...</article>",
724
+ "defaultValues": {
725
+ "--frame-corner-color": "oklch(0.74 0.16 260 / 0.9)",
726
+ "--frame-corner-size": "22px",
727
+ "--frame-corner-thickness": "2px"
728
+ }
729
+ },
730
+ "css": ".frame-corners {\n --frame-corner-color: oklch(0.74 0.16 260 / 0.9);\n --frame-corner-size: 22px;\n --frame-corner-thickness: 2px;\n position: relative;\n}\n\n.frame-corners::before,\n.frame-corners::after {\n content: \"\";\n position: absolute;\n width: var(--frame-corner-size);\n height: var(--frame-corner-size);\n pointer-events: none;\n}\n\n.frame-corners::before {\n top: 0;\n left: 0;\n border-top: var(--frame-corner-thickness) solid var(--frame-corner-color);\n border-left: var(--frame-corner-thickness) solid var(--frame-corner-color);\n}\n\n.frame-corners::after {\n right: 0;\n bottom: 0;\n border-right: var(--frame-corner-thickness) solid var(--frame-corner-color);\n border-bottom: var(--frame-corner-thickness) solid var(--frame-corner-color);\n}\n"
731
+ },
678
732
  {
679
733
  "id": "decorative/gradient-border",
680
734
  "title": "Gradient Border",
@@ -792,6 +846,65 @@
792
846
  },
793
847
  "css": ".gradient-mesh {\n --mesh-color-1: oklch(0.6 0.25 280);\n --mesh-color-2: oklch(0.55 0.2 330);\n --mesh-color-3: oklch(0.5 0.2 200);\n --mesh-color-4: oklch(0.45 0.15 150);\n background:\n conic-gradient(\n from 45deg at 30% 40%,\n var(--mesh-color-1),\n var(--mesh-color-2),\n var(--mesh-color-3)\n ),\n conic-gradient(\n from 200deg at 70% 60%,\n var(--mesh-color-2),\n var(--mesh-color-4),\n var(--mesh-color-1)\n );\n background-blend-mode: overlay;\n filter: blur(40px) saturate(1.5);\n}\n"
794
848
  },
849
+ {
850
+ "id": "decorative/gradient-progress-line",
851
+ "title": "Gradient Progress Line",
852
+ "description": "A left-to-right progress line with configurable gradient stops. Use it for process progress, status semantics, or to sync a visual line with active steps.",
853
+ "category": "decorative",
854
+ "tags": [
855
+ "gradient",
856
+ "progress",
857
+ "line",
858
+ "status",
859
+ "steps",
860
+ "decorative"
861
+ ],
862
+ "responsive": false,
863
+ "darkMode": false,
864
+ "dependencies": [],
865
+ "variants": [],
866
+ "updatedAt": "2026-03-21",
867
+ "meta": {
868
+ "lines": 30,
869
+ "bytes": 890,
870
+ "tailwind": "4.x",
871
+ "browser": "baseline-2024",
872
+ "accessibility": {
873
+ "prefersReducedMotion": true,
874
+ "prefersColorScheme": false,
875
+ "supportsCheck": false
876
+ },
877
+ "customProperties": [
878
+ "--progress-from",
879
+ "--progress-via",
880
+ "--progress-to",
881
+ "--progress-height",
882
+ "--progress-width"
883
+ ],
884
+ "classes": [
885
+ ".gradient-progress-line"
886
+ ],
887
+ "useCases": [
888
+ "process progress with semantic color progression",
889
+ "highlight current completion state in step sections",
890
+ "decorative status line under cards or timelines"
891
+ ],
892
+ "solves": [
893
+ "need more expressive progress feedback than a flat color bar",
894
+ "want progress width controlled from CSS or JS",
895
+ "need one reusable line that can sync with step activation"
896
+ ],
897
+ "usageExample": "<div class=\"gradient-progress-line\" style=\"--progress-width: 66%\"></div>",
898
+ "defaultValues": {
899
+ "--progress-from": "oklch(0.68 0.22 28)",
900
+ "--progress-via": "oklch(0.79 0.2 85)",
901
+ "--progress-to": "oklch(0.73 0.18 150)",
902
+ "--progress-height": "0.35rem",
903
+ "--progress-width": "0%"
904
+ }
905
+ },
906
+ "css": ".gradient-progress-line {\n --progress-from: oklch(0.68 0.22 28);\n --progress-via: oklch(0.79 0.2 85);\n --progress-to: oklch(0.73 0.18 150);\n --progress-height: 0.35rem;\n --progress-width: 0%;\n position: relative;\n width: 100%;\n height: var(--progress-height);\n border-radius: 9999px;\n overflow: hidden;\n background: color-mix(in oklch, currentColor 14%, transparent);\n}\n\n.gradient-progress-line::after {\n content: \"\";\n position: absolute;\n inset: 0 auto 0 0;\n width: var(--progress-width);\n border-radius: inherit;\n background: linear-gradient(90deg, var(--progress-from), var(--progress-via), var(--progress-to));\n box-shadow: 0 0 18px color-mix(in oklch, var(--progress-via) 32%, transparent);\n transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .gradient-progress-line::after {\n transition-duration: 0.01ms;\n }\n}\n"
907
+ },
795
908
  {
796
909
  "id": "decorative/grid-pattern",
797
910
  "title": "Grid Pattern",
@@ -849,6 +962,58 @@
849
962
  },
850
963
  "css": ".grid-pattern {\n --grid-size: 3rem;\n --grid-color: oklch(1 0 0 / 0.06);\n --grid-thickness: 1px;\n background-image:\n repeating-linear-gradient(\n 0deg,\n var(--grid-color) 0 var(--grid-thickness),\n transparent var(--grid-thickness) var(--grid-size)\n ),\n repeating-linear-gradient(\n 90deg,\n var(--grid-color) 0 var(--grid-thickness),\n transparent var(--grid-thickness) var(--grid-size)\n );\n}\n\n.grid-pattern-dots {\n --grid-size: 2rem;\n --grid-color: oklch(1 0 0 / 0.15);\n --grid-dot-size: 1px;\n background-image: radial-gradient(\n circle,\n var(--grid-color) var(--grid-dot-size),\n transparent var(--grid-dot-size)\n );\n background-size: var(--grid-size) var(--grid-size);\n}\n"
851
964
  },
965
+ {
966
+ "id": "decorative/label-rail",
967
+ "title": "Label Rail",
968
+ "description": "Vertical rail accent for small label groups, metadata blocks, and editorial side notes.",
969
+ "category": "decorative",
970
+ "tags": [
971
+ "label",
972
+ "rail",
973
+ "accent",
974
+ "metadata",
975
+ "editorial"
976
+ ],
977
+ "responsive": false,
978
+ "darkMode": false,
979
+ "dependencies": [],
980
+ "variants": [],
981
+ "updatedAt": "2026-03-22",
982
+ "meta": {
983
+ "lines": 17,
984
+ "bytes": 382,
985
+ "tailwind": "4.x",
986
+ "browser": "baseline-2024",
987
+ "accessibility": {
988
+ "prefersReducedMotion": false,
989
+ "prefersColorScheme": false,
990
+ "supportsCheck": false
991
+ },
992
+ "customProperties": [
993
+ "--label-rail-color",
994
+ "--label-rail-width"
995
+ ],
996
+ "classes": [
997
+ ".label-rail"
998
+ ],
999
+ "useCases": [
1000
+ "metadata callouts in Tailwind cards",
1001
+ "side labels or annotations in editorial layouts",
1002
+ "small descriptive blocks that need more visual structure"
1003
+ ],
1004
+ "solves": [
1005
+ "tiny content blocks need hierarchy without using a full border card",
1006
+ "badges alone are too weak for side metadata",
1007
+ "want a slim editorial accent that fits inside normal Tailwind markup"
1008
+ ],
1009
+ "usageExample": "<div class=\"label-rail text-sm text-slate-600\"><p class=\"font-semibold text-slate-900\">Research</p><p>Updated 2 days ago</p></div>",
1010
+ "defaultValues": {
1011
+ "--label-rail-color": "oklch(0.74 0.16 250 / 0.22)",
1012
+ "--label-rail-width": "3px"
1013
+ }
1014
+ },
1015
+ "css": ".label-rail {\n --label-rail-color: oklch(0.74 0.16 250 / 0.22);\n --label-rail-width: 3px;\n position: relative;\n padding-left: 1rem;\n}\n\n.label-rail::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0.2rem;\n bottom: 0.2rem;\n width: var(--label-rail-width);\n border-radius: 9999px;\n background: linear-gradient(180deg, var(--label-rail-color), transparent);\n}\n"
1016
+ },
852
1017
  {
853
1018
  "id": "decorative/morph-blob",
854
1019
  "title": "Morph Blob",
@@ -1175,6 +1340,116 @@
1175
1340
  },
1176
1341
  "css": ".shimmer {\n --shimmer-color: oklch(0.85 0 0 / 0.6);\n --shimmer-bg: oklch(0.92 0 0);\n --shimmer-speed: 1.5s;\n position: relative;\n overflow: hidden;\n background: var(--shimmer-bg);\n border-radius: 0.5rem;\n}\n\n.shimmer::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: linear-gradient(90deg, transparent 0%, var(--shimmer-color) 50%, transparent 100%);\n animation: shimmer-sweep var(--shimmer-speed) ease-in-out infinite;\n transform: translateX(-100%);\n}\n\n@keyframes shimmer-sweep {\n to {\n transform: translateX(100%);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .shimmer::after {\n animation: none;\n opacity: 0;\n }\n}\n"
1177
1342
  },
1343
+ {
1344
+ "id": "decorative/stripe-reveal",
1345
+ "title": "Stripe Reveal",
1346
+ "description": "Hover overlay with animated repeating stripes for buttons, cards, and highlighted surfaces.",
1347
+ "category": "decorative",
1348
+ "tags": [
1349
+ "stripe",
1350
+ "hover",
1351
+ "overlay",
1352
+ "button",
1353
+ "card"
1354
+ ],
1355
+ "responsive": false,
1356
+ "darkMode": false,
1357
+ "dependencies": [],
1358
+ "variants": [],
1359
+ "updatedAt": "2026-03-22",
1360
+ "meta": {
1361
+ "lines": 35,
1362
+ "bytes": 971,
1363
+ "tailwind": "4.x",
1364
+ "browser": "baseline-2024",
1365
+ "accessibility": {
1366
+ "prefersReducedMotion": true,
1367
+ "prefersColorScheme": false,
1368
+ "supportsCheck": false
1369
+ },
1370
+ "customProperties": [
1371
+ "--stripe-color",
1372
+ "--stripe-width",
1373
+ "--stripe-gap",
1374
+ "--stripe-angle",
1375
+ "--stripe-duration"
1376
+ ],
1377
+ "classes": [
1378
+ ".stripe-reveal"
1379
+ ],
1380
+ "useCases": [
1381
+ "Tailwind CTA buttons with more graphic hover treatment",
1382
+ "editorial callout cards or promo tiles",
1383
+ "featured links that need a stronger visual pass on hover"
1384
+ ],
1385
+ "solves": [
1386
+ "flat hover overlays feel too bland",
1387
+ "need a more graphic interaction without images or JS",
1388
+ "want a stripe-based reveal that works on both buttons and cards"
1389
+ ],
1390
+ "usageExample": "<button class=\"stripe-reveal relative rounded-full border border-white/10 px-5 py-3 font-semibold text-white\">Upgrade</button>",
1391
+ "defaultValues": {
1392
+ "--stripe-color": "oklch(0.82 0.12 90 / 0.34)",
1393
+ "--stripe-width": "14px",
1394
+ "--stripe-gap": "14px",
1395
+ "--stripe-angle": "90deg",
1396
+ "--stripe-duration": "0.42s"
1397
+ }
1398
+ },
1399
+ "css": ".stripe-reveal {\n --stripe-color: oklch(0.82 0.12 90 / 0.34);\n --stripe-width: 14px;\n --stripe-gap: 14px;\n --stripe-angle: 90deg;\n --stripe-duration: 0.42s;\n position: relative;\n isolation: isolate;\n overflow: hidden;\n}\n\n.stripe-reveal::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background: repeating-linear-gradient(\n var(--stripe-angle),\n var(--stripe-color) 0 var(--stripe-width),\n transparent var(--stripe-width) calc(var(--stripe-width) + var(--stripe-gap))\n );\n opacity: 0;\n transform: translateX(-18%);\n transition:\n transform var(--stripe-duration) cubic-bezier(0.16, 1, 0.3, 1),\n opacity var(--stripe-duration) cubic-bezier(0.16, 1, 0.3, 1);\n pointer-events: none;\n z-index: -1;\n}\n\n.stripe-reveal:hover::before,\n.stripe-reveal:focus-visible::before {\n opacity: 1;\n transform: translateX(0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .stripe-reveal::before {\n transition: none;\n }\n}\n"
1400
+ },
1401
+ {
1402
+ "id": "decorative/topographic-lines",
1403
+ "title": "Topographic Lines",
1404
+ "description": "Soft contour-line background accent for editorial cards, hero panels, and diagram-like surfaces.",
1405
+ "category": "decorative",
1406
+ "tags": [
1407
+ "decorative",
1408
+ "lines",
1409
+ "topographic",
1410
+ "background",
1411
+ "contour"
1412
+ ],
1413
+ "responsive": false,
1414
+ "darkMode": false,
1415
+ "dependencies": [],
1416
+ "variants": [],
1417
+ "updatedAt": "2026-03-22",
1418
+ "meta": {
1419
+ "lines": 17,
1420
+ "bytes": 628,
1421
+ "tailwind": "4.x",
1422
+ "browser": "baseline-2024",
1423
+ "accessibility": {
1424
+ "prefersReducedMotion": false,
1425
+ "prefersColorScheme": false,
1426
+ "supportsCheck": false
1427
+ },
1428
+ "customProperties": [
1429
+ "--topographic-line-color",
1430
+ "--topographic-line-gap"
1431
+ ],
1432
+ "classes": [
1433
+ ".topographic-lines"
1434
+ ],
1435
+ "useCases": [
1436
+ "hero or promo backgrounds in Tailwind landing pages",
1437
+ "editorial callouts with a technical or map-like accent",
1438
+ "subtle diagrammatic texture on cards and empty states"
1439
+ ],
1440
+ "solves": [
1441
+ "flat surfaces need more atmosphere than a plain gradient",
1442
+ "grid and dot patterns can feel too mechanical",
1443
+ "want a softer graphic background treatment without images"
1444
+ ],
1445
+ "usageExample": "<section class=\"topographic-lines relative overflow-hidden rounded-[2rem] border border-white/10 bg-slate-950/80 p-8 text-white\">...</section>",
1446
+ "defaultValues": {
1447
+ "--topographic-line-color": "oklch(0.74 0.08 240 / 0.18)",
1448
+ "--topographic-line-gap": "14px"
1449
+ }
1450
+ },
1451
+ "css": ".topographic-lines {\n --topographic-line-color: oklch(0.74 0.08 240 / 0.18);\n --topographic-line-gap: 14px;\n position: relative;\n overflow: hidden;\n}\n\n.topographic-lines::before {\n content: \"\";\n position: absolute;\n inset: -10%;\n background:\n radial-gradient(\n circle at 20% 25%,\n transparent 0 16%,\n var(--topographic-line-color) 16.2% 17.2%,\n transparent 17.4% 24%\n ),\n radial-gradient(\n circle at 58% 52%,\n transparent 0 14%,\n var(--topographic-line-color) 14.2% 15.2%,\n transparent 15.4% 22%\n ),\n radial-gradient(\n circle at 80% 28%,\n transparent 0 10%,\n var(--topographic-line-color) 10.2% 11.2%,\n transparent 11.4% 17%\n );\n pointer-events: none;\n z-index: -1;\n}\n"
1452
+ },
1178
1453
  {
1179
1454
  "id": "depth/floating-stack",
1180
1455
  "title": "Floating Stack",
@@ -1753,6 +2028,59 @@
1753
2028
  },
1754
2029
  "css": ".border-draw {\n --border-draw-color: oklch(0.65 0.25 280);\n --border-draw-width: 2px;\n --border-draw-speed: 0.4s;\n position: relative;\n}\n\n.border-draw::before,\n.border-draw::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border: var(--border-draw-width) solid var(--border-draw-color);\n pointer-events: none;\n transition: clip-path var(--border-draw-speed) ease-in-out;\n}\n\n.border-draw::before {\n clip-path: inset(0 100% 100% 0);\n}\n\n.border-draw::after {\n clip-path: inset(100% 0 0 100%);\n}\n\n.border-draw:hover::before {\n clip-path: inset(0 0 0 0);\n}\n\n.border-draw:hover::after {\n clip-path: inset(0 0 0 0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .border-draw::before,\n .border-draw::after {\n transition: none;\n }\n}\n"
1755
2030
  },
2031
+ {
2032
+ "id": "interactions/caption-slide-card",
2033
+ "title": "Caption Slide Card",
2034
+ "description": "Media card overlay where the caption block lifts into place on hover, useful for galleries, featured posts, and promo tiles.",
2035
+ "category": "interactions",
2036
+ "tags": [
2037
+ "card",
2038
+ "caption",
2039
+ "hover",
2040
+ "media",
2041
+ "overlay"
2042
+ ],
2043
+ "responsive": false,
2044
+ "darkMode": false,
2045
+ "dependencies": [],
2046
+ "variants": [],
2047
+ "updatedAt": "2026-03-22",
2048
+ "meta": {
2049
+ "lines": 28,
2050
+ "bytes": 710,
2051
+ "tailwind": "4.x",
2052
+ "browser": "baseline-2024",
2053
+ "accessibility": {
2054
+ "prefersReducedMotion": true,
2055
+ "prefersColorScheme": false,
2056
+ "supportsCheck": false
2057
+ },
2058
+ "customProperties": [
2059
+ "--caption-slide-distance",
2060
+ "--caption-slide-duration"
2061
+ ],
2062
+ "classes": [
2063
+ ".caption-slide-card",
2064
+ ".caption-slide-body"
2065
+ ],
2066
+ "useCases": [
2067
+ "Tailwind media cards with hoverable caption overlays",
2068
+ "blog or case-study teasers with image-first presentation",
2069
+ "gallery and promo tiles with a clearer hover state"
2070
+ ],
2071
+ "solves": [
2072
+ "plain image cards feel too inert",
2073
+ "need a hover caption without complex 3D transforms",
2074
+ "want a card reveal pattern that still fits normal Tailwind card markup"
2075
+ ],
2076
+ "usageExample": "<article class=\"caption-slide-card relative overflow-hidden rounded-3xl\"><div class=\"caption-slide-body p-6 text-white\">...</div></article>",
2077
+ "defaultValues": {
2078
+ "--caption-slide-distance": "18px",
2079
+ "--caption-slide-duration": "0.38s"
2080
+ }
2081
+ },
2082
+ "css": ".caption-slide-card {\n --caption-slide-distance: 18px;\n --caption-slide-duration: 0.38s;\n position: relative;\n isolation: isolate;\n overflow: hidden;\n}\n\n.caption-slide-card::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background: linear-gradient(180deg, transparent 28%, rgb(15 23 42 / 0.82));\n opacity: 0.92;\n z-index: -1;\n}\n\n.caption-slide-body {\n transform: translateY(var(--caption-slide-distance));\n transition: transform var(--caption-slide-duration) cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.caption-slide-card:hover .caption-slide-body,\n.caption-slide-card:focus-visible .caption-slide-body {\n transform: translateY(0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .caption-slide-body {\n transition: none;\n }\n}\n"
2083
+ },
1756
2084
  {
1757
2085
  "id": "interactions/expand-cards",
1758
2086
  "title": "Expand Cards",
@@ -1926,6 +2254,61 @@
1926
2254
  },
1927
2255
  "css": ".focus-ring:focus-visible {\n --focus-color: oklch(0.55 0.2 250);\n --focus-offset: 2px;\n --focus-ring-width: 2px;\n outline: var(--focus-ring-width) solid var(--focus-color);\n outline-offset: var(--focus-offset);\n box-shadow: 0 0 0 calc(var(--focus-offset) + var(--focus-ring-width) + 2px) oklch(1 0 0);\n}\n\n@media (prefers-color-scheme: dark) {\n .focus-ring:focus-visible {\n box-shadow: 0 0 0 calc(var(--focus-offset) + var(--focus-ring-width) + 2px) oklch(0.15 0 0);\n }\n}\n\n@supports not selector(:focus-visible) {\n .focus-ring:focus {\n outline: 2px solid oklch(0.55 0.2 250);\n outline-offset: 2px;\n }\n}\n"
1928
2256
  },
2257
+ {
2258
+ "id": "interactions/focus-within-panel",
2259
+ "title": "Focus Within Panel",
2260
+ "description": "Panel-level focus treatment that highlights a whole grouped UI block whenever one of its inner controls receives keyboard focus.",
2261
+ "category": "interactions",
2262
+ "tags": [
2263
+ "focus",
2264
+ "accessibility",
2265
+ "panel",
2266
+ "keyboard",
2267
+ "form"
2268
+ ],
2269
+ "responsive": false,
2270
+ "darkMode": false,
2271
+ "dependencies": [],
2272
+ "variants": [],
2273
+ "updatedAt": "2026-03-22",
2274
+ "meta": {
2275
+ "lines": 15,
2276
+ "bytes": 403,
2277
+ "tailwind": "4.x",
2278
+ "browser": "baseline-2024",
2279
+ "accessibility": {
2280
+ "prefersReducedMotion": true,
2281
+ "prefersColorScheme": false,
2282
+ "supportsCheck": true,
2283
+ "ariaNotes": [
2284
+ "Useful for grouped form controls and keyboard navigation"
2285
+ ]
2286
+ },
2287
+ "customProperties": [
2288
+ "--focus-within-accent",
2289
+ "--focus-within-shadow"
2290
+ ],
2291
+ "classes": [
2292
+ ".focus-within-panel"
2293
+ ],
2294
+ "useCases": [
2295
+ "grouped Tailwind form fields",
2296
+ "settings cards with multiple controls",
2297
+ "search bars or prompt panels with several focusable children"
2298
+ ],
2299
+ "solves": [
2300
+ "keyboard focus is visible on the input but not on the containing surface",
2301
+ "grouped panels feel disconnected during keyboard navigation",
2302
+ "need a single state for multi-control cards"
2303
+ ],
2304
+ "usageExample": "<div class=\"focus-within-panel rounded-3xl border border-white/10 bg-slate-950/80 p-4 text-white\">...</div>",
2305
+ "defaultValues": {
2306
+ "--focus-within-accent": "oklch(0.72 0.16 250 / 0.2)",
2307
+ "--focus-within-shadow": "0 0 0 1px color-mix(in oklab, white 18%, transparent), 0 0 0 6px var(--focus-within-accent)"
2308
+ }
2309
+ },
2310
+ "css": ".focus-within-panel {\n --focus-within-accent: oklch(0.72 0.16 250 / 0.2);\n --focus-within-shadow:\n 0 0 0 1px color-mix(in oklab, white 18%, transparent), 0 0 0 6px var(--focus-within-accent);\n transition: box-shadow 0.24s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.focus-within-panel:focus-within {\n box-shadow: var(--focus-within-shadow);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .focus-within-panel {\n transition: none;\n }\n}\n"
2311
+ },
1929
2312
  {
1930
2313
  "id": "interactions/glow",
1931
2314
  "title": "Glow",
@@ -2038,6 +2421,59 @@
2038
2421
  },
2039
2422
  "css": ".hover-lift {\n --lift-distance: -4px;\n --lift-shadow: 0 8px 24px oklch(0 0 0 / 0.2);\n --lift-duration: 0.25s;\n transition:\n transform var(--lift-duration) cubic-bezier(0.16, 1, 0.3, 1),\n box-shadow var(--lift-duration) cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.hover-lift:hover {\n transform: translateY(var(--lift-distance));\n box-shadow: var(--lift-shadow);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .hover-lift {\n transition: none;\n }\n}\n"
2040
2423
  },
2424
+ {
2425
+ "id": "interactions/icon-shift-link",
2426
+ "title": "Icon Shift Link",
2427
+ "description": "Inline link treatment where the trailing icon glides forward on hover, ideal for text actions, cards, and section CTAs.",
2428
+ "category": "interactions",
2429
+ "tags": [
2430
+ "link",
2431
+ "icon",
2432
+ "hover",
2433
+ "cta",
2434
+ "inline"
2435
+ ],
2436
+ "responsive": false,
2437
+ "darkMode": false,
2438
+ "dependencies": [],
2439
+ "variants": [],
2440
+ "updatedAt": "2026-03-22",
2441
+ "meta": {
2442
+ "lines": 19,
2443
+ "bytes": 472,
2444
+ "tailwind": "4.x",
2445
+ "browser": "baseline-2024",
2446
+ "accessibility": {
2447
+ "prefersReducedMotion": true,
2448
+ "prefersColorScheme": false,
2449
+ "supportsCheck": false
2450
+ },
2451
+ "customProperties": [
2452
+ "--icon-shift-distance",
2453
+ "--icon-shift-duration"
2454
+ ],
2455
+ "classes": [
2456
+ ".icon-shift-link",
2457
+ ".icon-shift-glyph"
2458
+ ],
2459
+ "useCases": [
2460
+ "Tailwind text links with a clearer CTA direction",
2461
+ "card footer actions or read-more links",
2462
+ "section links where underline-only feels too passive"
2463
+ ],
2464
+ "solves": [
2465
+ "text links need more direction without turning into buttons",
2466
+ "icon links often feel static",
2467
+ "want a tiny motion cue that fits normal Tailwind prose or cards"
2468
+ ],
2469
+ "usageExample": "<a class=\"icon-shift-link text-sm font-semibold text-slate-900\" href=\"#\"><span>Read more</span><span class=\"icon-shift-glyph\">→</span></a>",
2470
+ "defaultValues": {
2471
+ "--icon-shift-distance": "0.28rem",
2472
+ "--icon-shift-duration": "0.28s"
2473
+ }
2474
+ },
2475
+ "css": ".icon-shift-link {\n --icon-shift-distance: 0.28rem;\n --icon-shift-duration: 0.28s;\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n text-decoration: none;\n}\n\n.icon-shift-link .icon-shift-glyph {\n transition: transform var(--icon-shift-duration) cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.icon-shift-link:hover .icon-shift-glyph,\n.icon-shift-link:focus-visible .icon-shift-glyph {\n transform: translateX(var(--icon-shift-distance));\n}\n\n@media (prefers-reduced-motion: reduce) {\n .icon-shift-link .icon-shift-glyph {\n transition: none;\n }\n}\n"
2476
+ },
2041
2477
  {
2042
2478
  "id": "interactions/magnetic",
2043
2479
  "title": "Magnetic",
@@ -2259,6 +2695,180 @@
2259
2695
  },
2260
2696
  "css": ".shine-sweep {\n --shine-color: oklch(1 0 0 / 0.15);\n --shine-speed: 0.6s;\n position: relative;\n overflow: hidden;\n isolation: isolate;\n}\n\n.shine-sweep::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: linear-gradient(120deg, transparent 30%, var(--shine-color) 50%, transparent 70%);\n transform: translateX(-100%);\n transition: none;\n pointer-events: none;\n z-index: 1;\n}\n\n.shine-sweep:hover::after {\n animation: shine-sweep-move var(--shine-speed) ease-out;\n}\n\n@keyframes shine-sweep-move {\n to {\n transform: translateX(100%);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .shine-sweep::after {\n display: none;\n }\n}\n"
2261
2697
  },
2698
+ {
2699
+ "id": "interactions/stack-peek-card",
2700
+ "title": "Stack Peek Card",
2701
+ "description": "Card hover effect that reveals a two-layer stack behind the surface for a more editorial, dimensional hover state.",
2702
+ "category": "interactions",
2703
+ "tags": [
2704
+ "hover",
2705
+ "stack",
2706
+ "cards",
2707
+ "depth",
2708
+ "editorial"
2709
+ ],
2710
+ "responsive": false,
2711
+ "darkMode": false,
2712
+ "dependencies": [],
2713
+ "variants": [],
2714
+ "updatedAt": "2026-03-22",
2715
+ "meta": {
2716
+ "lines": 61,
2717
+ "bytes": 1887,
2718
+ "tailwind": "4.x",
2719
+ "browser": "baseline-2024",
2720
+ "accessibility": {
2721
+ "prefersReducedMotion": true,
2722
+ "prefersColorScheme": false,
2723
+ "supportsCheck": false
2724
+ },
2725
+ "customProperties": [
2726
+ "--stack-offset-x",
2727
+ "--stack-offset-y",
2728
+ "--stack-rotate-a",
2729
+ "--stack-rotate-b",
2730
+ "--stack-accent-a",
2731
+ "--stack-accent-b",
2732
+ "--stack-shadow"
2733
+ ],
2734
+ "classes": [
2735
+ ".stack-peek-card"
2736
+ ],
2737
+ "useCases": [
2738
+ "premium feature cards in Tailwind landing pages",
2739
+ "editorial article teasers with more layered hover feedback",
2740
+ "product cards that need more personality than a simple lift"
2741
+ ],
2742
+ "solves": [
2743
+ "basic hover-lift feels too generic for hero cards",
2744
+ "cards need depth without a full 3D tilt effect",
2745
+ "want a stack reveal that still works in static Tailwind layouts"
2746
+ ],
2747
+ "usageExample": "<article class=\"stack-peek-card relative rounded-3xl border border-white/10 bg-slate-950/80 p-6 text-white\">...</article>",
2748
+ "defaultValues": {
2749
+ "--stack-offset-x": "14px",
2750
+ "--stack-offset-y": "12px",
2751
+ "--stack-rotate-a": "-4deg",
2752
+ "--stack-rotate-b": "4deg",
2753
+ "--stack-accent-a": "oklch(0.68 0.16 285 / 0.3)",
2754
+ "--stack-accent-b": "oklch(0.78 0.12 220 / 0.24)",
2755
+ "--stack-shadow": "0 22px 48px oklch(0.18 0.03 280 / 0.18)"
2756
+ }
2757
+ },
2758
+ "css": ".stack-peek-card {\n --stack-offset-x: 14px;\n --stack-offset-y: 12px;\n --stack-rotate-a: -4deg;\n --stack-rotate-b: 4deg;\n --stack-accent-a: oklch(0.68 0.16 285 / 0.3);\n --stack-accent-b: oklch(0.78 0.12 220 / 0.24);\n --stack-shadow: 0 22px 48px oklch(0.18 0.03 280 / 0.18);\n position: relative;\n isolation: isolate;\n transition:\n transform 0.42s cubic-bezier(0.16, 1, 0.3, 1),\n box-shadow 0.42s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.stack-peek-card::before,\n.stack-peek-card::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n border: 1px solid color-mix(in oklab, white 16%, transparent);\n pointer-events: none;\n z-index: -1;\n transition:\n transform 0.42s cubic-bezier(0.16, 1, 0.3, 1),\n opacity 0.42s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.stack-peek-card::before {\n background: linear-gradient(135deg, var(--stack-accent-a), transparent 70%);\n opacity: 0.75;\n}\n\n.stack-peek-card::after {\n background: linear-gradient(135deg, transparent 10%, var(--stack-accent-b));\n opacity: 0.6;\n}\n\n.stack-peek-card:hover,\n.stack-peek-card:focus-visible {\n transform: translateY(-6px);\n box-shadow: var(--stack-shadow);\n}\n\n.stack-peek-card:hover::before,\n.stack-peek-card:focus-visible::before {\n transform: translate3d(calc(var(--stack-offset-x) * -1), var(--stack-offset-y), 0)\n rotate(var(--stack-rotate-a));\n}\n\n.stack-peek-card:hover::after,\n.stack-peek-card:focus-visible::after {\n transform: translate3d(var(--stack-offset-x), calc(var(--stack-offset-y) + 6px), 0)\n rotate(var(--stack-rotate-b));\n}\n\n@media (prefers-reduced-motion: reduce) {\n .stack-peek-card,\n .stack-peek-card::before,\n .stack-peek-card::after {\n transition: none;\n }\n}\n"
2759
+ },
2760
+ {
2761
+ "id": "interactions/thumb-reveal-link",
2762
+ "title": "Thumb Reveal Link",
2763
+ "description": "Link hover that reveals a small thumbnail beside the label, useful for editorial lists, menus, and featured link groups.",
2764
+ "category": "interactions",
2765
+ "tags": [
2766
+ "link",
2767
+ "hover",
2768
+ "thumbnail",
2769
+ "menu",
2770
+ "editorial"
2771
+ ],
2772
+ "responsive": false,
2773
+ "darkMode": false,
2774
+ "dependencies": [],
2775
+ "variants": [],
2776
+ "updatedAt": "2026-03-22",
2777
+ "meta": {
2778
+ "lines": 57,
2779
+ "bytes": 1715,
2780
+ "tailwind": "4.x",
2781
+ "browser": "baseline-2024",
2782
+ "accessibility": {
2783
+ "prefersReducedMotion": true,
2784
+ "prefersColorScheme": false,
2785
+ "supportsCheck": false
2786
+ },
2787
+ "customProperties": [
2788
+ "--thumb-reveal-scale",
2789
+ "--thumb-reveal-rotate",
2790
+ "--thumb-reveal-shift-x",
2791
+ "--thumb-reveal-shift-y",
2792
+ "--thumb-reveal-duration"
2793
+ ],
2794
+ "classes": [
2795
+ ".thumb-reveal-link",
2796
+ ".thumb-reveal-media"
2797
+ ],
2798
+ "useCases": [
2799
+ "Tailwind navs with media-backed hover states",
2800
+ "editorial article lists or featured links",
2801
+ "portfolio and category menus that need more than a text hover"
2802
+ ],
2803
+ "solves": [
2804
+ "text links alone feel too flat in featured lists",
2805
+ "need a lightweight image-reveal hover without JS",
2806
+ "want a thumbnail hover pattern that still works in Tailwind markup"
2807
+ ],
2808
+ "usageExample": "<a class=\"thumb-reveal-link relative text-xl font-semibold text-slate-950\" href=\"#\"><span>Research notes</span><img class=\"thumb-reveal-media\" src=\"/image.jpg\" alt=\"\" /></a>",
2809
+ "defaultValues": {
2810
+ "--thumb-reveal-scale": "0.88",
2811
+ "--thumb-reveal-rotate": "-5deg",
2812
+ "--thumb-reveal-shift-x": "14px",
2813
+ "--thumb-reveal-shift-y": "-10px",
2814
+ "--thumb-reveal-duration": "0.36s"
2815
+ }
2816
+ },
2817
+ "css": ".thumb-reveal-link {\n --thumb-reveal-scale: 0.88;\n --thumb-reveal-rotate: -5deg;\n --thumb-reveal-shift-x: 14px;\n --thumb-reveal-shift-y: -10px;\n --thumb-reveal-duration: 0.36s;\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n text-decoration: none;\n}\n\n.thumb-reveal-media {\n position: absolute;\n left: calc(100% + 1rem);\n top: 50%;\n width: min(10rem, 36vw);\n aspect-ratio: 1;\n object-fit: cover;\n border-radius: 1rem;\n border: 1px solid color-mix(in oklab, white 18%, transparent);\n box-shadow: 0 24px 48px oklch(0.18 0.03 260 / 0.2);\n opacity: 0;\n pointer-events: none;\n transform: translate3d(\n calc(var(--thumb-reveal-shift-x) * -1),\n calc(-50% - var(--thumb-reveal-shift-y)),\n 0\n )\n scale(var(--thumb-reveal-scale)) rotate(var(--thumb-reveal-rotate));\n transition:\n transform var(--thumb-reveal-duration) cubic-bezier(0.16, 1, 0.3, 1),\n opacity var(--thumb-reveal-duration) cubic-bezier(0.16, 1, 0.3, 1);\n z-index: 10;\n}\n\n.thumb-reveal-link:hover .thumb-reveal-media,\n.thumb-reveal-link:focus-visible .thumb-reveal-media {\n opacity: 1;\n transform: translate3d(var(--thumb-reveal-shift-x), -50%, 0) scale(1) rotate(0deg);\n}\n\n@media (max-width: 767px) {\n .thumb-reveal-media {\n left: auto;\n right: 0;\n top: calc(100% + 0.75rem);\n width: min(12rem, 64vw);\n transform: translate3d(0, calc(var(--thumb-reveal-shift-y) * -1), 0)\n scale(var(--thumb-reveal-scale)) rotate(var(--thumb-reveal-rotate));\n }\n\n .thumb-reveal-link:hover .thumb-reveal-media,\n .thumb-reveal-link:focus-visible .thumb-reveal-media {\n transform: translate3d(0, 0, 0) scale(1) rotate(0deg);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .thumb-reveal-media {\n transition: none;\n }\n}\n"
2818
+ },
2819
+ {
2820
+ "id": "interactions/thumb-stack-link",
2821
+ "title": "Thumb Stack Link",
2822
+ "description": "Link hover that reveals a small stack of thumbnails, useful for menus, portfolios, and featured editorial lists.",
2823
+ "category": "interactions",
2824
+ "tags": [
2825
+ "link",
2826
+ "hover",
2827
+ "thumbnails",
2828
+ "stack",
2829
+ "menu"
2830
+ ],
2831
+ "responsive": false,
2832
+ "darkMode": false,
2833
+ "dependencies": [],
2834
+ "variants": [],
2835
+ "updatedAt": "2026-03-22",
2836
+ "meta": {
2837
+ "lines": 71,
2838
+ "bytes": 2259,
2839
+ "tailwind": "4.x",
2840
+ "browser": "baseline-2024",
2841
+ "accessibility": {
2842
+ "prefersReducedMotion": true,
2843
+ "prefersColorScheme": false,
2844
+ "supportsCheck": false
2845
+ },
2846
+ "customProperties": [
2847
+ "--thumb-stack-shift",
2848
+ "--thumb-stack-duration"
2849
+ ],
2850
+ "classes": [
2851
+ ".thumb-stack-link",
2852
+ ".thumb-stack-media"
2853
+ ],
2854
+ "useCases": [
2855
+ "Tailwind menus with richer hover states",
2856
+ "portfolio category links or featured lists",
2857
+ "editorial navigation that needs more visual presence than plain text"
2858
+ ],
2859
+ "solves": [
2860
+ "single thumbnail reveal can feel too flat for premium menus",
2861
+ "need a stacked media hover without JavaScript",
2862
+ "want a more visual menu effect that still pastes cleanly into Tailwind layouts"
2863
+ ],
2864
+ "usageExample": "<a class=\"thumb-stack-link relative text-xl font-semibold text-slate-950\" href=\"#\"><span>Cases</span><img class=\"thumb-stack-media\" src=\"/a.jpg\" alt=\"\" /><img class=\"thumb-stack-media\" src=\"/b.jpg\" alt=\"\" /></a>",
2865
+ "defaultValues": {
2866
+ "--thumb-stack-shift": "14px",
2867
+ "--thumb-stack-duration": "0.38s"
2868
+ }
2869
+ },
2870
+ "css": ".thumb-stack-link {\n --thumb-stack-shift: 14px;\n --thumb-stack-duration: 0.38s;\n position: relative;\n display: inline-flex;\n align-items: center;\n text-decoration: none;\n}\n\n.thumb-stack-link .thumb-stack-media {\n position: absolute;\n left: calc(100% + 1rem);\n top: 50%;\n width: min(8.5rem, 30vw);\n aspect-ratio: 1;\n object-fit: cover;\n border-radius: 1rem;\n border: 1px solid color-mix(in oklab, white 18%, transparent);\n box-shadow: 0 24px 48px oklch(0.18 0.03 260 / 0.18);\n opacity: 0;\n pointer-events: none;\n transition:\n transform var(--thumb-stack-duration) cubic-bezier(0.16, 1, 0.3, 1),\n opacity var(--thumb-stack-duration) cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.thumb-stack-link .thumb-stack-media:nth-of-type(1) {\n transform: translate3d(calc(var(--thumb-stack-shift) * -1), calc(-50% - 12px), 0) rotate(-7deg)\n scale(0.92);\n}\n\n.thumb-stack-link .thumb-stack-media:nth-of-type(2) {\n transform: translate3d(calc(var(--thumb-stack-shift) * -0.35), calc(-50% + 10px), 0) rotate(5deg)\n scale(0.96);\n}\n\n.thumb-stack-link:hover .thumb-stack-media:nth-of-type(1),\n.thumb-stack-link:focus-visible .thumb-stack-media:nth-of-type(1) {\n opacity: 1;\n transform: translate3d(var(--thumb-stack-shift), calc(-50% - 16px), 0) rotate(-5deg) scale(1);\n}\n\n.thumb-stack-link:hover .thumb-stack-media:nth-of-type(2),\n.thumb-stack-link:focus-visible .thumb-stack-media:nth-of-type(2) {\n opacity: 1;\n transform: translate3d(calc(var(--thumb-stack-shift) + 18px), calc(-50% + 14px), 0) rotate(4deg)\n scale(1);\n}\n\n@media (max-width: 767px) {\n .thumb-stack-link .thumb-stack-media {\n left: auto;\n right: 0;\n top: calc(100% + 0.75rem);\n width: min(10rem, 56vw);\n }\n\n .thumb-stack-link .thumb-stack-media:nth-of-type(1) {\n transform: translate3d(0, 0, 0) rotate(-7deg) scale(0.92);\n }\n\n .thumb-stack-link .thumb-stack-media:nth-of-type(2) {\n transform: translate3d(18px, 18px, 0) rotate(5deg) scale(0.96);\n }\n\n .thumb-stack-link:hover .thumb-stack-media:nth-of-type(1),\n .thumb-stack-link:focus-visible .thumb-stack-media:nth-of-type(1) {\n transform: translate3d(0, 0, 0) rotate(-5deg) scale(1);\n }\n\n .thumb-stack-link:hover .thumb-stack-media:nth-of-type(2),\n .thumb-stack-link:focus-visible .thumb-stack-media:nth-of-type(2) {\n transform: translate3d(20px, 20px, 0) rotate(4deg) scale(1);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .thumb-stack-link .thumb-stack-media {\n transition: none;\n }\n}\n"
2871
+ },
2262
2872
  {
2263
2873
  "id": "interactions/tilt",
2264
2874
  "title": "Tilt",
@@ -2441,8 +3051,8 @@
2441
3051
  "variants": [],
2442
3052
  "updatedAt": "2026-03-21",
2443
3053
  "meta": {
2444
- "lines": 31,
2445
- "bytes": 1098,
3054
+ "lines": 42,
3055
+ "bytes": 1554,
2446
3056
  "tailwind": "4.x",
2447
3057
  "browser": "baseline-2024",
2448
3058
  "accessibility": {
@@ -2471,7 +3081,7 @@
2471
3081
  "need premium lighting without canvas or JS libraries",
2472
3082
  "want cursor-driven highlights on cards"
2473
3083
  ],
2474
- "usageExample": "<article class=\"spotlight-card rounded-3xl p-8\" onmousemove=\"const r=this.getBoundingClientRect();this.style.setProperty(`--spotlight-x`,`${event.clientX-r.left}px`);this.style.setProperty(`--spotlight-y`,`${event.clientY-r.top}px`)\"></article>",
3084
+ "usageExample": "<article class=\"spotlight-card rounded-3xl p-8\" onmousemove=\"const r=this.getBoundingClientRect();this.style.setProperty(`--spotlight-x`,`${event.clientX-r.left}px`);this.style.setProperty(`--spotlight-y`,`${event.clientY-r.top}px`)\" onmouseleave=\"this.style.setProperty(`--spotlight-x`,`50%`);this.style.setProperty(`--spotlight-y`,`50%`)\"></article>",
2475
3085
  "defaultValues": {
2476
3086
  "--spotlight-x": "50%",
2477
3087
  "--spotlight-y": "50%",
@@ -2481,7 +3091,113 @@
2481
3091
  "--spotlight-border": "rgb(255 255 255 / 0.12"
2482
3092
  }
2483
3093
  },
2484
- "css": ".spotlight-card {\n position: relative;\n overflow: hidden;\n isolation: isolate;\n background:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), rgb(255 255 255 / 0.02)),\n var(--spotlight-surface, oklch(24% 0.02 255));\n border: 1px solid var(--spotlight-border, rgb(255 255 255 / 0.12));\n}\n\n.spotlight-card::before {\n content: \"\";\n position: absolute;\n inset: -30%;\n background:\n radial-gradient(\n circle at var(--spotlight-x, 50%) var(--spotlight-y, 50%),\n var(--spotlight-color, rgb(125 211 252 / 0.42)),\n transparent 24%\n ),\n radial-gradient(\n circle at var(--spotlight-x, 50%) var(--spotlight-y, 50%),\n rgb(255 255 255 / 0.26),\n transparent 12%\n );\n opacity: 0;\n transition: opacity var(--spotlight-duration, 220ms ease);\n pointer-events: none;\n}\n\n.spotlight-card::after {\n content: \"\";\n position: absolute;\n inset: 1px;\n border-radius: inherit;\n border: 1px solid rgb(255 255 255 / 0.14);\n mask: linear-gradient(180deg, black, transparent 40%);\n pointer-events: none;\n}\n\n.spotlight-card:hover::before,\n.spotlight-card:focus-visible::before {\n opacity: 1;\n}\n"
3094
+ "css": ".spotlight-card {\n position: relative;\n overflow: hidden;\n isolation: isolate;\n background:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), rgb(255 255 255 / 0.02)),\n var(--spotlight-surface, oklch(24% 0.02 255));\n border: 1px solid var(--spotlight-border, rgb(255 255 255 / 0.12));\n box-shadow:\n inset 0 1px 0 rgb(255 255 255 / 0.08),\n 0 22px 50px rgb(0 0 0 / 0.28);\n transition:\n border-color 220ms ease,\n background-color 220ms ease,\n box-shadow 220ms ease;\n}\n\n.spotlight-card::before {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background:\n radial-gradient(\n 18rem circle at var(--spotlight-x, 50%) var(--spotlight-y, 50%),\n var(--spotlight-color, rgb(125 211 252 / 0.42)),\n transparent 38%\n ),\n radial-gradient(\n 7rem circle at var(--spotlight-x, 50%) var(--spotlight-y, 50%),\n rgb(255 255 255 / 0.24),\n transparent 18%\n ),\n radial-gradient(circle at top, rgb(255 255 255 / 0.1), transparent 42%);\n opacity: 0;\n mix-blend-mode: screen;\n transition: opacity var(--spotlight-duration, 220ms ease);\n pointer-events: none;\n}\n\n.spotlight-card::after {\n content: \"\";\n position: absolute;\n inset: 1px;\n border-radius: inherit;\n border: 1px solid rgb(255 255 255 / 0.14);\n mask: linear-gradient(180deg, black, transparent 40%);\n pointer-events: none;\n}\n\n.spotlight-card:hover,\n.spotlight-card:focus-visible {\n border-color: rgb(255 255 255 / 0.18);\n box-shadow:\n inset 0 1px 0 rgb(255 255 255 / 0.12),\n 0 28px 65px rgb(0 0 0 / 0.35);\n}\n\n.spotlight-card:hover::before,\n.spotlight-card:focus-visible::before {\n opacity: 1;\n}\n"
3095
+ },
3096
+ {
3097
+ "id": "masks/box-unreveal",
3098
+ "title": "Box Unreveal",
3099
+ "description": "Full overlay panel that slides away on hover, revealing the base card beneath it.",
3100
+ "category": "masks",
3101
+ "tags": [
3102
+ "mask",
3103
+ "reveal",
3104
+ "overlay",
3105
+ "panel",
3106
+ "card"
3107
+ ],
3108
+ "responsive": false,
3109
+ "darkMode": false,
3110
+ "dependencies": [],
3111
+ "variants": [],
3112
+ "updatedAt": "2026-03-22",
3113
+ "meta": {
3114
+ "lines": 24,
3115
+ "bytes": 611,
3116
+ "tailwind": "4.x",
3117
+ "browser": "baseline-2024",
3118
+ "accessibility": {
3119
+ "prefersReducedMotion": true,
3120
+ "prefersColorScheme": false,
3121
+ "supportsCheck": false
3122
+ },
3123
+ "customProperties": [
3124
+ "--box-unreveal-duration",
3125
+ "--box-unreveal-bg"
3126
+ ],
3127
+ "classes": [
3128
+ ".box-unreveal"
3129
+ ],
3130
+ "useCases": [
3131
+ "promo cards and CTAs with a stronger first-state cover",
3132
+ "category tiles where hover reveals more neutral content beneath",
3133
+ "Tailwind surfaces that need a clean unreveal motion"
3134
+ ],
3135
+ "solves": [
3136
+ "ordinary overlays fade in but do not create a real before-and-after state",
3137
+ "need a directional panel reveal without complex markup",
3138
+ "want a boxy reveal inspired by menu unreveal motion but practical for cards"
3139
+ ],
3140
+ "usageExample": "<article class=\"box-unreveal relative rounded-[1.25rem] border border-white/10 bg-slate-950/80 p-6 text-white\">...</article>",
3141
+ "defaultValues": {
3142
+ "--box-unreveal-duration": "0.42s",
3143
+ "--box-unreveal-bg": "linear-gradient(\n 135deg,\n oklch(0.74 0.18 280 / 0.9),\n oklch(0.66 0.18 220 / 0.9)\n )"
3144
+ }
3145
+ },
3146
+ "css": ".box-unreveal {\n --box-unreveal-duration: 0.42s;\n --box-unreveal-bg: linear-gradient(\n 135deg,\n oklch(0.74 0.18 280 / 0.9),\n oklch(0.66 0.18 220 / 0.9)\n );\n position: relative;\n isolation: isolate;\n overflow: hidden;\n}\n\n.box-unreveal::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background: var(--box-unreveal-bg);\n transform: scaleX(1);\n transform-origin: right;\n transition: transform var(--box-unreveal-duration) cubic-bezier(0.16, 1, 0.3, 1);\n z-index: -1;\n}\n\n.box-unreveal:hover::before,\n.box-unreveal:focus-visible::before {\n transform: scaleX(0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .box-unreveal::before {\n transition: none;\n }\n}\n"
3147
+ },
3148
+ {
3149
+ "id": "masks/clip-slice-reveal",
3150
+ "title": "Clip Slice Reveal",
3151
+ "description": "Hover reveal that opens a clipped overlay across a card, useful for promo surfaces, category cards, and highlighted links.",
3152
+ "category": "masks",
3153
+ "tags": [
3154
+ "mask",
3155
+ "clip-path",
3156
+ "reveal",
3157
+ "card",
3158
+ "promo"
3159
+ ],
3160
+ "responsive": false,
3161
+ "darkMode": false,
3162
+ "dependencies": [],
3163
+ "variants": [],
3164
+ "updatedAt": "2026-03-22",
3165
+ "meta": {
3166
+ "lines": 27,
3167
+ "bytes": 786,
3168
+ "tailwind": "4.x",
3169
+ "browser": "baseline-2024",
3170
+ "accessibility": {
3171
+ "prefersReducedMotion": true,
3172
+ "prefersColorScheme": false,
3173
+ "supportsCheck": false
3174
+ },
3175
+ "customProperties": [
3176
+ "--clip-slice-from",
3177
+ "--clip-slice-to",
3178
+ "--clip-slice-duration"
3179
+ ],
3180
+ "classes": [
3181
+ ".clip-slice-reveal"
3182
+ ],
3183
+ "useCases": [
3184
+ "Tailwind promo cards with a stronger hover reveal",
3185
+ "category surfaces that need more motion than a simple background shift",
3186
+ "callout boxes or featured links with directional energy"
3187
+ ],
3188
+ "solves": [
3189
+ "flat hover overlays lack shape and direction",
3190
+ "diagonal and radial reveals are too specific for everyday cards",
3191
+ "want a clip-path based reveal that stays easy to paste into Tailwind markup"
3192
+ ],
3193
+ "usageExample": "<article class=\"clip-slice-reveal relative rounded-[1.25rem] border border-white/10 bg-slate-950/80 p-6 text-white\">...</article>",
3194
+ "defaultValues": {
3195
+ "--clip-slice-from": "inset(0 100% 0 0 round 1.25rem)",
3196
+ "--clip-slice-to": "inset(0 0 0 0 round 1.25rem)",
3197
+ "--clip-slice-duration": "0.42s"
3198
+ }
3199
+ },
3200
+ "css": ".clip-slice-reveal {\n --clip-slice-from: inset(0 100% 0 0 round 1.25rem);\n --clip-slice-to: inset(0 0 0 0 round 1.25rem);\n --clip-slice-duration: 0.42s;\n position: relative;\n isolation: isolate;\n overflow: hidden;\n}\n\n.clip-slice-reveal::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background:\n linear-gradient(140deg, oklch(0.74 0.16 280 / 0.92), oklch(0.66 0.18 220 / 0.9)),\n linear-gradient(180deg, rgb(255 255 255 / 0.18), transparent 42%);\n clip-path: var(--clip-slice-from);\n transition: clip-path var(--clip-slice-duration) cubic-bezier(0.16, 1, 0.3, 1);\n z-index: -1;\n}\n\n.clip-slice-reveal:hover::before,\n.clip-slice-reveal:focus-visible::before {\n clip-path: var(--clip-slice-to);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .clip-slice-reveal::before {\n transition: none;\n }\n}\n"
2485
3201
  },
2486
3202
  {
2487
3203
  "id": "masks/diagonal-reveal",
@@ -2952,6 +3668,62 @@
2952
3668
  },
2953
3669
  "css": ".scroll-unmask {\n animation: scroll-unmask-reveal linear both;\n animation-timeline: view();\n animation-range: entry 0% cover 40%;\n}\n\n.scroll-unmask-left {\n animation: scroll-unmask-left-reveal linear both;\n animation-timeline: view();\n animation-range: entry 0% cover 40%;\n}\n\n@keyframes scroll-unmask-reveal {\n from {\n clip-path: inset(0 0 100% 0);\n opacity: 0.3;\n }\n to {\n clip-path: inset(0);\n opacity: 1;\n }\n}\n\n@keyframes scroll-unmask-left-reveal {\n from {\n clip-path: inset(0 100% 0 0);\n opacity: 0.3;\n }\n to {\n clip-path: inset(0);\n opacity: 1;\n }\n}\n\n@supports not (animation-timeline: view()) {\n .scroll-unmask,\n .scroll-unmask-left {\n clip-path: none;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .scroll-unmask,\n .scroll-unmask-left {\n animation: none;\n clip-path: none;\n }\n}\n"
2954
3670
  },
3671
+ {
3672
+ "id": "scroll/sequential-steps",
3673
+ "title": "Sequential Steps",
3674
+ "description": "Steps enter one after another with a configurable pause once the group becomes visible. Useful for horizontal process rows where regular viewport triggers fire all items at once.",
3675
+ "category": "scroll",
3676
+ "tags": [
3677
+ "scroll",
3678
+ "steps",
3679
+ "sequence",
3680
+ "onboarding",
3681
+ "process",
3682
+ "timeline"
3683
+ ],
3684
+ "responsive": false,
3685
+ "darkMode": false,
3686
+ "dependencies": [],
3687
+ "variants": [],
3688
+ "updatedAt": "2026-03-21",
3689
+ "meta": {
3690
+ "lines": 36,
3691
+ "bytes": 1145,
3692
+ "tailwind": "4.x",
3693
+ "browser": "baseline-2024",
3694
+ "accessibility": {
3695
+ "prefersReducedMotion": true,
3696
+ "prefersColorScheme": false,
3697
+ "supportsCheck": false
3698
+ },
3699
+ "customProperties": [
3700
+ "--step-delay",
3701
+ "--step-duration",
3702
+ "--step-offset"
3703
+ ],
3704
+ "classes": [
3705
+ ".sequential-steps",
3706
+ ".sequential-step"
3707
+ ],
3708
+ "useCases": [
3709
+ "onboarding or process rows with horizontal steps",
3710
+ "timeline sections that should play once in sequence",
3711
+ "how it works layouts with staged reveal timing"
3712
+ ],
3713
+ "solves": [
3714
+ "all step items trigger at the same time in one viewport band",
3715
+ "need configurable pause between cards or milestones",
3716
+ "want a once-only sequence without per-item observers"
3717
+ ],
3718
+ "usageExample": "<div class=\"sequential-steps is-visible\"><article class=\"sequential-step\">Step</article><article class=\"sequential-step\">Step</article></div>",
3719
+ "defaultValues": {
3720
+ "--step-delay": "600ms",
3721
+ "--step-duration": "0.5s",
3722
+ "--step-offset": "18px"
3723
+ }
3724
+ },
3725
+ "css": ".sequential-steps {\n --step-delay: 600ms;\n --step-duration: 0.5s;\n --step-offset: 18px;\n}\n\n.sequential-step {\n opacity: 0;\n transform: translateY(var(--step-offset)) scale(0.98);\n}\n\n.sequential-steps.is-visible .sequential-step {\n animation: sequential-step-in var(--step-duration) cubic-bezier(0.22, 1, 0.36, 1) forwards;\n}\n\n.sequential-steps.is-visible .sequential-step:nth-child(2) {\n animation-delay: var(--step-delay);\n}\n.sequential-steps.is-visible .sequential-step:nth-child(3) {\n animation-delay: calc(var(--step-delay) * 2);\n}\n.sequential-steps.is-visible .sequential-step:nth-child(4) {\n animation-delay: calc(var(--step-delay) * 3);\n}\n.sequential-steps.is-visible .sequential-step:nth-child(5) {\n animation-delay: calc(var(--step-delay) * 4);\n}\n.sequential-steps.is-visible .sequential-step:nth-child(6) {\n animation-delay: calc(var(--step-delay) * 5);\n}\n\n@keyframes sequential-step-in {\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sequential-step,\n .sequential-steps.is-visible .sequential-step {\n opacity: 1;\n transform: none;\n animation: none;\n }\n}\n"
3726
+ },
2955
3727
  {
2956
3728
  "id": "scroll/snap-sections",
2957
3729
  "title": "Snap Sections",
@@ -3162,6 +3934,58 @@
3162
3934
  },
3163
3935
  "css": ".holographic-foil {\n position: relative;\n overflow: hidden;\n isolation: isolate;\n background:\n linear-gradient(135deg, rgb(255 255 255 / 0.08), rgb(255 255 255 / 0.02)),\n var(--foil-base, oklch(18% 0.01 265));\n border: 1px solid var(--foil-border, rgb(255 255 255 / 0.14));\n}\n\n.holographic-foil::before,\n.holographic-foil::after {\n content: \"\";\n position: absolute;\n inset: -40%;\n pointer-events: none;\n}\n\n.holographic-foil::before {\n background: conic-gradient(\n from 180deg at 50% 50%,\n rgb(34 211 238 / 0.42),\n rgb(192 132 252 / 0.42),\n rgb(244 114 182 / 0.35),\n rgb(34 211 238 / 0.42)\n );\n mix-blend-mode: screen;\n filter: blur(24px) saturate(1.25);\n animation: foil-shift var(--foil-speed, 10s) linear infinite;\n}\n\n.holographic-foil::after {\n background: linear-gradient(120deg, transparent 20%, rgb(255 255 255 / 0.4) 48%, transparent 75%);\n transform: translateX(-35%) rotate(12deg);\n opacity: 0.55;\n}\n\n@keyframes foil-shift {\n to {\n transform: rotate(1turn);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .holographic-foil::before {\n animation: none;\n }\n}\n"
3164
3936
  },
3937
+ {
3938
+ "id": "surfaces/rim-highlight-panel",
3939
+ "title": "Rim Highlight Panel",
3940
+ "description": "Card or panel surface with a subtle perimeter highlight and low ambient glow, suited for premium settings panels and featured surfaces.",
3941
+ "category": "surfaces",
3942
+ "tags": [
3943
+ "surface",
3944
+ "panel",
3945
+ "border",
3946
+ "glow",
3947
+ "premium"
3948
+ ],
3949
+ "responsive": false,
3950
+ "darkMode": false,
3951
+ "dependencies": [],
3952
+ "variants": [],
3953
+ "updatedAt": "2026-03-22",
3954
+ "meta": {
3955
+ "lines": 37,
3956
+ "bytes": 1161,
3957
+ "tailwind": "4.x",
3958
+ "browser": "baseline-2024",
3959
+ "accessibility": {
3960
+ "prefersReducedMotion": false,
3961
+ "prefersColorScheme": false,
3962
+ "supportsCheck": false
3963
+ },
3964
+ "customProperties": [
3965
+ "--rim-highlight-color",
3966
+ "--rim-highlight-shadow"
3967
+ ],
3968
+ "classes": [
3969
+ ".rim-highlight-panel"
3970
+ ],
3971
+ "useCases": [
3972
+ "premium Tailwind cards and settings panels",
3973
+ "feature callouts with a more elevated material edge",
3974
+ "dashboard or marketing panels that need a refined perimeter"
3975
+ ],
3976
+ "solves": [
3977
+ "flat cards need more material definition",
3978
+ "simple borders look too generic on premium surfaces",
3979
+ "want a subtle highlight edge without a heavy neon treatment"
3980
+ ],
3981
+ "usageExample": "<article class=\"rim-highlight-panel relative rounded-[1.5rem] bg-slate-950/80 p-6 text-white\">...</article>",
3982
+ "defaultValues": {
3983
+ "--rim-highlight-color": "oklch(0.78 0.12 230 / 0.22)",
3984
+ "--rim-highlight-shadow": "0 24px 48px oklch(0.18 0.03 260 / 0.18)"
3985
+ }
3986
+ },
3987
+ "css": ".rim-highlight-panel {\n --rim-highlight-color: oklch(0.78 0.12 230 / 0.22);\n --rim-highlight-shadow: 0 24px 48px oklch(0.18 0.03 260 / 0.18);\n position: relative;\n isolation: isolate;\n}\n\n.rim-highlight-panel::before {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n padding: 1px;\n background: linear-gradient(\n 145deg,\n color-mix(in oklab, white 24%, transparent),\n var(--rim-highlight-color),\n transparent 62%\n );\n -webkit-mask:\n linear-gradient(#000 0 0) content-box,\n linear-gradient(#000 0 0);\n -webkit-mask-composite: xor;\n mask-composite: exclude;\n pointer-events: none;\n z-index: -1;\n}\n\n.rim-highlight-panel::after {\n content: \"\";\n position: absolute;\n inset: auto 12% -18% 12%;\n height: 36%;\n border-radius: 9999px;\n background: radial-gradient(\n circle,\n color-mix(in oklab, var(--rim-highlight-color) 48%, transparent),\n transparent 70%\n );\n filter: blur(28px);\n opacity: 0.9;\n pointer-events: none;\n z-index: -2;\n}\n\n.rim-highlight-panel:hover,\n.rim-highlight-panel:focus-visible {\n box-shadow: var(--rim-highlight-shadow);\n}\n"
3988
+ },
3165
3989
  {
3166
3990
  "id": "surfaces/soft-emboss",
3167
3991
  "title": "Soft Emboss",
@@ -3216,6 +4040,56 @@
3216
4040
  },
3217
4041
  "css": ".soft-emboss {\n background: var(--emboss-bg, oklch(95% 0.01 250));\n box-shadow:\n var(--emboss-light, -10px -10px 20px rgb(255 255 255 / 0.9)),\n var(--emboss-dark, 10px 10px 20px rgb(148 163 184 / 0.18)),\n inset 0 1px 0 rgb(255 255 255 / 0.85);\n}\n\n.soft-emboss[data-pressed=\"true\"] {\n box-shadow:\n inset 8px 8px 16px rgb(148 163 184 / 0.18),\n inset -8px -8px 16px rgb(255 255 255 / 0.9);\n}\n"
3218
4042
  },
4043
+ {
4044
+ "id": "surfaces/top-light-panel",
4045
+ "title": "Top Light Panel",
4046
+ "description": "Surface accent with a soft top-light gradient that makes cards and panels feel more dimensional without a full glow treatment.",
4047
+ "category": "surfaces",
4048
+ "tags": [
4049
+ "surface",
4050
+ "panel",
4051
+ "gradient",
4052
+ "light",
4053
+ "card"
4054
+ ],
4055
+ "responsive": false,
4056
+ "darkMode": false,
4057
+ "dependencies": [],
4058
+ "variants": [],
4059
+ "updatedAt": "2026-03-22",
4060
+ "meta": {
4061
+ "lines": 13,
4062
+ "bytes": 309,
4063
+ "tailwind": "4.x",
4064
+ "browser": "baseline-2024",
4065
+ "accessibility": {
4066
+ "prefersReducedMotion": false,
4067
+ "prefersColorScheme": false,
4068
+ "supportsCheck": false
4069
+ },
4070
+ "customProperties": [
4071
+ "--top-light-strength"
4072
+ ],
4073
+ "classes": [
4074
+ ".top-light-panel"
4075
+ ],
4076
+ "useCases": [
4077
+ "premium settings or pricing panels",
4078
+ "hero cards and promo surfaces",
4079
+ "dashboard cards that need a quieter surface accent"
4080
+ ],
4081
+ "solves": [
4082
+ "surfaces look too flat with only border and shadow",
4083
+ "full glow or foil effects are too loud",
4084
+ "need a subtle lighting cue that fits Tailwind card stacks"
4085
+ ],
4086
+ "usageExample": "<article class=\"top-light-panel relative rounded-3xl border border-white/10 bg-slate-950/80 p-6 text-white\">...</article>",
4087
+ "defaultValues": {
4088
+ "--top-light-strength": "oklch(0.98 0.01 250 / 0.1)"
4089
+ }
4090
+ },
4091
+ "css": ".top-light-panel {\n --top-light-strength: oklch(0.98 0.01 250 / 0.1);\n position: relative;\n isolation: isolate;\n}\n\n.top-light-panel::before {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: linear-gradient(180deg, var(--top-light-strength), transparent 28%);\n pointer-events: none;\n z-index: -1;\n}\n"
4092
+ },
3219
4093
  {
3220
4094
  "id": "text/balance",
3221
4095
  "title": "Text Balance",
@@ -3367,6 +4241,60 @@
3367
4241
  },
3368
4242
  "css": ".text-gradient {\n --text-gradient-from: oklch(0.7 0.25 280);\n --text-gradient-to: oklch(0.65 0.2 330);\n --text-gradient-angle: 135deg;\n background: linear-gradient(\n var(--text-gradient-angle),\n var(--text-gradient-from),\n var(--text-gradient-to)\n );\n background-clip: text;\n -webkit-background-clip: text;\n color: transparent;\n}\n"
3369
4243
  },
4244
+ {
4245
+ "id": "text/link-swap",
4246
+ "title": "Link Swap",
4247
+ "description": "Typographic link hover that swaps the visible label with a second colored layer using pseudo-elements and data-hover.",
4248
+ "category": "text",
4249
+ "tags": [
4250
+ "text",
4251
+ "link",
4252
+ "hover",
4253
+ "nav",
4254
+ "typography"
4255
+ ],
4256
+ "responsive": false,
4257
+ "darkMode": false,
4258
+ "dependencies": [],
4259
+ "variants": [],
4260
+ "updatedAt": "2026-03-22",
4261
+ "meta": {
4262
+ "lines": 45,
4263
+ "bytes": 1027,
4264
+ "tailwind": "4.x",
4265
+ "browser": "baseline-2024",
4266
+ "accessibility": {
4267
+ "prefersReducedMotion": true,
4268
+ "prefersColorScheme": false,
4269
+ "supportsCheck": false
4270
+ },
4271
+ "customProperties": [
4272
+ "--link-swap-from",
4273
+ "--link-swap-to",
4274
+ "--link-swap-duration"
4275
+ ],
4276
+ "classes": [
4277
+ ".link-swap"
4278
+ ],
4279
+ "useCases": [
4280
+ "Tailwind nav links with more refined hover motion",
4281
+ "editorial link lists and inline text actions",
4282
+ "category or menu labels that need motion without underline tricks"
4283
+ ],
4284
+ "solves": [
4285
+ "basic color-change hovers feel too plain",
4286
+ "border-draw is too structural for text-first navigation",
4287
+ "need a pseudo-element based link effect that stays lightweight"
4288
+ ],
4289
+ "usageExample": "<a class=\"link-swap text-lg font-semibold\" data-hover=\"Patterns\" href=\"#\">Patterns</a>",
4290
+ "defaultValues": {
4291
+ "--link-swap-from": "currentColor",
4292
+ "--link-swap-to": "oklch(0.72 0.18 265)",
4293
+ "--link-swap-duration": "0.32s"
4294
+ }
4295
+ },
4296
+ "css": ".link-swap {\n --link-swap-from: currentColor;\n --link-swap-to: oklch(0.72 0.18 265);\n --link-swap-duration: 0.32s;\n position: relative;\n display: inline-grid;\n place-items: center;\n overflow: hidden;\n color: var(--link-swap-from);\n text-decoration: none;\n vertical-align: top;\n}\n\n.link-swap::before,\n.link-swap::after {\n content: attr(data-hover);\n grid-area: 1 / 1;\n transition:\n transform var(--link-swap-duration) cubic-bezier(0.16, 1, 0.3, 1),\n opacity var(--link-swap-duration) cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.link-swap::before {\n color: var(--link-swap-from);\n transform: translateY(0);\n opacity: 1;\n}\n\n.link-swap::after {\n color: var(--link-swap-to);\n transform: translateY(115%);\n opacity: 0;\n}\n\n.link-swap:hover::before,\n.link-swap:focus-visible::before {\n transform: translateY(-115%);\n opacity: 0;\n}\n\n.link-swap:hover::after,\n.link-swap:focus-visible::after {\n transform: translateY(0);\n opacity: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .link-swap::before,\n .link-swap::after {\n transition: none;\n }\n}\n"
4297
+ },
3370
4298
  {
3371
4299
  "id": "text/text-stroke-reveal",
3372
4300
  "title": "Text Stroke Reveal",
@@ -3524,6 +4452,60 @@
3524
4452
  }
3525
4453
  },
3526
4454
  "css": ".animate-typewriter {\n --typewriter-duration: 1.2s;\n --typewriter-delay: 0s;\n clip-path: inset(0 100% 0 0);\n animation: typewriter-reveal var(--typewriter-duration) var(--typewriter-delay)\n cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;\n}\n\n@keyframes typewriter-reveal {\n to {\n clip-path: inset(0 0 0 0);\n }\n}\n\n@supports not (clip-path: inset(0)) {\n .animate-typewriter {\n animation: none;\n clip-path: none;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .animate-typewriter {\n animation: none;\n clip-path: none;\n }\n}\n"
4455
+ },
4456
+ {
4457
+ "id": "text/underline-swipe",
4458
+ "title": "Underline Swipe",
4459
+ "description": "Inline link effect where the underline draws in with a directional swipe, suited for navs, article links, and text actions.",
4460
+ "category": "text",
4461
+ "tags": [
4462
+ "text",
4463
+ "link",
4464
+ "underline",
4465
+ "hover",
4466
+ "nav"
4467
+ ],
4468
+ "responsive": false,
4469
+ "darkMode": false,
4470
+ "dependencies": [],
4471
+ "variants": [],
4472
+ "updatedAt": "2026-03-22",
4473
+ "meta": {
4474
+ "lines": 28,
4475
+ "bytes": 623,
4476
+ "tailwind": "4.x",
4477
+ "browser": "baseline-2024",
4478
+ "accessibility": {
4479
+ "prefersReducedMotion": true,
4480
+ "prefersColorScheme": false,
4481
+ "supportsCheck": false
4482
+ },
4483
+ "customProperties": [
4484
+ "--underline-swipe-color",
4485
+ "--underline-swipe-thickness",
4486
+ "--underline-swipe-duration"
4487
+ ],
4488
+ "classes": [
4489
+ ".underline-swipe"
4490
+ ],
4491
+ "useCases": [
4492
+ "Tailwind nav links that need a cleaner underline treatment",
4493
+ "article links or section actions inside editorial layouts",
4494
+ "secondary CTAs where border-draw would feel too heavy"
4495
+ ],
4496
+ "solves": [
4497
+ "color-only hover is too weak for important text links",
4498
+ "border-draw is too structural for inline navigation",
4499
+ "need a small text-first effect that pastes into Tailwind markup easily"
4500
+ ],
4501
+ "usageExample": "<a class=\"underline-swipe text-lg font-semibold text-slate-900\" href=\"#\">Read the article</a>",
4502
+ "defaultValues": {
4503
+ "--underline-swipe-color": "currentColor",
4504
+ "--underline-swipe-thickness": "2px",
4505
+ "--underline-swipe-duration": "0.32s"
4506
+ }
4507
+ },
4508
+ "css": ".underline-swipe {\n --underline-swipe-color: currentColor;\n --underline-swipe-thickness: 2px;\n --underline-swipe-duration: 0.32s;\n position: relative;\n display: inline-block;\n text-decoration: none;\n}\n\n.underline-swipe::after {\n content: \"\";\n position: absolute;\n left: 0;\n bottom: -0.12em;\n width: 100%;\n height: var(--underline-swipe-thickness);\n background: var(--underline-swipe-color);\n transform: scaleX(0);\n transform-origin: left;\n transition: transform var(--underline-swipe-duration) cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.underline-swipe:hover::after,\n.underline-swipe:focus-visible::after {\n transform: scaleX(1);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .underline-swipe::after {\n transition: none;\n }\n}\n"
3527
4509
  }
3528
4510
  ],
3529
4511
  "patterns": [
@@ -8485,6 +9467,207 @@
8485
9467
  "css": null,
8486
9468
  "js": null
8487
9469
  },
9470
+ {
9471
+ "id": "blog/carousel",
9472
+ "title": "Blog Scroll Carousel",
9473
+ "summary": "Horizontal scroll-snap blog rail for featured articles with square thumbnails and compact metadata.",
9474
+ "family": "blog",
9475
+ "kind": "section",
9476
+ "tier": "enhanced",
9477
+ "extends": "blog/base",
9478
+ "tags": [
9479
+ "blog",
9480
+ "carousel",
9481
+ "scroll-snap",
9482
+ "featured",
9483
+ "rail"
9484
+ ],
9485
+ "search": {
9486
+ "intent": [
9487
+ "featured article carousel without JavaScript",
9488
+ "horizontally scrolling blog cards"
9489
+ ],
9490
+ "keywords": [
9491
+ "blog",
9492
+ "carousel",
9493
+ "scroll-snap",
9494
+ "featured",
9495
+ "rail",
9496
+ "horizontal",
9497
+ "articles"
9498
+ ],
9499
+ "useCases": [
9500
+ "featured articles rail",
9501
+ "newest posts strip",
9502
+ "homepage highlight",
9503
+ "category teaser"
9504
+ ]
9505
+ },
9506
+ "frameworks": {
9507
+ "html": true,
9508
+ "astro": true,
9509
+ "webComponent": false
9510
+ },
9511
+ "tokens": {
9512
+ "color": "neutral",
9513
+ "radius": "xl",
9514
+ "shadow": "none",
9515
+ "spacing": "section-default",
9516
+ "typography": "marketing-default"
9517
+ },
9518
+ "capabilities": {
9519
+ "responsive": true,
9520
+ "darkMode": true,
9521
+ "animated": false,
9522
+ "interactive": true,
9523
+ "dependencies": [],
9524
+ "animationPreset": "none"
9525
+ },
9526
+ "slots": [
9527
+ {
9528
+ "name": "heading",
9529
+ "required": false,
9530
+ "description": "Optional heading and intro."
9531
+ },
9532
+ {
9533
+ "name": "posts",
9534
+ "required": true,
9535
+ "description": "Featured cards rendered in a horizontal scroll-snap row."
9536
+ }
9537
+ ],
9538
+ "props": [],
9539
+ "files": {
9540
+ "html": "./carousel.html",
9541
+ "css": null,
9542
+ "js": null
9543
+ },
9544
+ "install": {
9545
+ "copyPasteReady": true,
9546
+ "ssrSafe": true,
9547
+ "tailwindOnly": true,
9548
+ "notes": [
9549
+ "Native CSS scroll snap keeps this fast and low-complexity.",
9550
+ "Best for 5-10 highlighted stories, not full archives."
9551
+ ]
9552
+ },
9553
+ "ai": {
9554
+ "prompts": [
9555
+ "Create a horizontal featured article rail with CSS scroll snap.",
9556
+ "Build a no-JS blog carousel for highlighted posts."
9557
+ ],
9558
+ "compositionRole": "supporting"
9559
+ },
9560
+ "governance": {
9561
+ "status": "published",
9562
+ "quality": "stable",
9563
+ "owner": "design-system",
9564
+ "updatedAt": "2026-03-21"
9565
+ },
9566
+ "html": "<section class=\"ws-blog bg-[var(--ws-blog-bg)] py-20\">\n <div class=\"mx-auto max-w-7xl px-6\">\n <div class=\"flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between\">\n <div class=\"max-w-2xl\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-blog-accent)]\">Featured Rail</p>\n <h2 class=\"mt-3 text-3xl font-bold tracking-tight text-[var(--ws-blog-text)] sm:text-4xl\">Highlighted reads</h2>\n <p class=\"mt-3 text-base text-[var(--ws-blog-text-soft)]\">A horizontal rail for curated stories, powered by native CSS scroll snap.</p>\n </div>\n <div class=\"text-sm text-[var(--ws-blog-text-muted)]\">Swipe or trackpad-scroll</div>\n </div>\n\n <div class=\"-mx-6 mt-10 overflow-x-auto px-6 pb-2 [scrollbar-width:none] [-ms-overflow-style:none]\">\n <div class=\"flex gap-5 snap-x snap-mandatory [&::-webkit-scrollbar]:hidden\">\n <article class=\"group w-[min(320px,82vw)] flex-none snap-start\">\n <a href=\"#\" class=\"block\">\n <div class=\"aspect-square overflow-hidden rounded-[1.35rem] bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-indigo-100 to-purple-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Registry</span>\n <h3 class=\"mt-2 text-xl font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Wie eine Registry fuer Menschen und Agents gleichermassen lesbar wird</h3>\n <div class=\"mt-2 text-sm text-[var(--ws-blog-text-muted)]\">21. Maerz 2026 · 9 Min</div>\n </div>\n </a>\n </article>\n\n <article class=\"group w-[min(320px,82vw)] flex-none snap-start\">\n <a href=\"#\" class=\"block\">\n <div class=\"aspect-square overflow-hidden rounded-[1.35rem] bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-emerald-100 to-teal-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Effects</span>\n <h3 class=\"mt-2 text-xl font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Scroll-, Hover- und Lighting-Demos richtig visualisieren</h3>\n <div class=\"mt-2 text-sm text-[var(--ws-blog-text-muted)]\">18. Maerz 2026 · 6 Min</div>\n </div>\n </a>\n </article>\n\n <article class=\"group w-[min(320px,82vw)] flex-none snap-start\">\n <a href=\"#\" class=\"block\">\n <div class=\"aspect-square overflow-hidden rounded-[1.35rem] bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-amber-100 to-orange-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Content</span>\n <h3 class=\"mt-2 text-xl font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Startseiten so schreiben, dass die Anwendung sofort verstanden wird</h3>\n <div class=\"mt-2 text-sm text-[var(--ws-blog-text-muted)]\">13. Maerz 2026 · 7 Min</div>\n </div>\n </a>\n </article>\n\n <article class=\"group w-[min(320px,82vw)] flex-none snap-start\">\n <a href=\"#\" class=\"block\">\n <div class=\"aspect-square overflow-hidden rounded-[1.35rem] bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-sky-100 to-cyan-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Workflow</span>\n <h3 class=\"mt-2 text-xl font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Wie man aus einem TODO echte Registry-Inhalte macht</h3>\n <div class=\"mt-2 text-sm text-[var(--ws-blog-text-muted)]\">9. Maerz 2026 · 5 Min</div>\n </div>\n </a>\n </article>\n </div>\n </div>\n </div>\n</section>\n",
9567
+ "css": null,
9568
+ "js": null
9569
+ },
9570
+ {
9571
+ "id": "blog/compact-list",
9572
+ "title": "Blog Compact List",
9573
+ "summary": "Dense blog list with small square thumbnails, strong title focus, and lightweight metadata for scanning many posts quickly.",
9574
+ "family": "blog",
9575
+ "kind": "section",
9576
+ "tier": "enhanced",
9577
+ "extends": "blog/base",
9578
+ "tags": [
9579
+ "blog",
9580
+ "compact",
9581
+ "list",
9582
+ "thumbnails",
9583
+ "editorial",
9584
+ "feed"
9585
+ ],
9586
+ "search": {
9587
+ "intent": [
9588
+ "compact blog listing for many articles",
9589
+ "dense article feed with thumbnails"
9590
+ ],
9591
+ "keywords": [
9592
+ "blog",
9593
+ "compact",
9594
+ "list",
9595
+ "feed",
9596
+ "thumbnails",
9597
+ "articles",
9598
+ "editorial"
9599
+ ],
9600
+ "useCases": [
9601
+ "large content archive",
9602
+ "editorial feed",
9603
+ "knowledge base",
9604
+ "company insights"
9605
+ ]
9606
+ },
9607
+ "frameworks": {
9608
+ "html": true,
9609
+ "astro": true,
9610
+ "webComponent": false
9611
+ },
9612
+ "tokens": {
9613
+ "color": "neutral",
9614
+ "radius": "lg",
9615
+ "shadow": "none",
9616
+ "spacing": "section-default",
9617
+ "typography": "marketing-default"
9618
+ },
9619
+ "capabilities": {
9620
+ "responsive": true,
9621
+ "darkMode": true,
9622
+ "animated": false,
9623
+ "interactive": false,
9624
+ "dependencies": [],
9625
+ "animationPreset": "none"
9626
+ },
9627
+ "slots": [
9628
+ {
9629
+ "name": "heading",
9630
+ "required": false,
9631
+ "description": "List heading and optional intro copy."
9632
+ },
9633
+ {
9634
+ "name": "posts",
9635
+ "required": true,
9636
+ "description": "Dense list of posts with thumbnail, title, subtitle, and meta row."
9637
+ }
9638
+ ],
9639
+ "props": [],
9640
+ "files": {
9641
+ "html": "./compact-list.html",
9642
+ "css": null,
9643
+ "js": null
9644
+ },
9645
+ "install": {
9646
+ "copyPasteReady": true,
9647
+ "ssrSafe": true,
9648
+ "tailwindOnly": true,
9649
+ "notes": [
9650
+ "Works especially well for long German titles because text gets most of the horizontal space.",
9651
+ "Keep thumbnails small and lazy-loaded for large archives."
9652
+ ]
9653
+ },
9654
+ "ai": {
9655
+ "prompts": [
9656
+ "Create a dense blog listing for hundreds of articles.",
9657
+ "Build a compact editorial feed with square thumbnails."
9658
+ ],
9659
+ "compositionRole": "supporting"
9660
+ },
9661
+ "governance": {
9662
+ "status": "published",
9663
+ "quality": "stable",
9664
+ "owner": "design-system",
9665
+ "updatedAt": "2026-03-21"
9666
+ },
9667
+ "html": "<section class=\"ws-blog bg-[var(--ws-blog-bg)] py-20\">\n <div class=\"mx-auto max-w-5xl px-6\">\n <div class=\"max-w-2xl\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-blog-accent)]\">Insights Feed</p>\n <h2 class=\"mt-3 text-3xl font-bold tracking-tight text-[var(--ws-blog-text)] sm:text-4xl\">Recent articles and deep dives</h2>\n <p class=\"mt-3 text-base text-[var(--ws-blog-text-soft)]\">A compact listing built for fast scanning across a large editorial archive.</p>\n </div>\n\n <div class=\"mt-10 divide-y divide-[var(--ws-blog-border)] border-y border-[var(--ws-blog-border)]\">\n <article class=\"group py-5\">\n <a href=\"#\" class=\"flex gap-4\">\n <div class=\"h-16 w-16 shrink-0 overflow-hidden rounded-xl bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-indigo-100 to-purple-100\"></div>\n </div>\n <div class=\"min-w-0 flex-1\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Patterns</span>\n <h3 class=\"mt-1 text-lg font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Wie man eine skalierbare Pattern-Registry fuer Marketing, Produkt und Docs gleichzeitig baut</h3>\n <p class=\"mt-1 line-clamp-2 text-sm text-[var(--ws-blog-text-soft)]\">Von Namensgebung bis Registry-Struktur: welche Entscheidungen sich bei vielen Komponenten wirklich auszahlen.</p>\n <div class=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--ws-blog-text-muted)]\">\n <span>21. Maerz 2026</span>\n <span>8 Min</span>\n <span>Registry</span>\n </div>\n </div>\n </a>\n </article>\n\n <article class=\"group py-5\">\n <a href=\"#\" class=\"flex gap-4\">\n <div class=\"h-16 w-16 shrink-0 overflow-hidden rounded-xl bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-emerald-100 to-teal-100\"></div>\n </div>\n <div class=\"min-w-0 flex-1\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">CSS Effects</span>\n <h3 class=\"mt-1 text-lg font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Scroll-getriebene Animationen ohne JavaScript sauber fuer Produktseiten einsetzen</h3>\n <p class=\"mt-1 line-clamp-2 text-sm text-[var(--ws-blog-text-soft)]\">Welche Scroll-Mechaniken sich fuer Storytelling lohnen und wo sie schnell zu laut oder ornamental werden.</p>\n <div class=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--ws-blog-text-muted)]\">\n <span>18. Maerz 2026</span>\n <span>6 Min</span>\n <span>Scroll</span>\n </div>\n </div>\n </a>\n </article>\n\n <article class=\"group py-5\">\n <a href=\"#\" class=\"flex gap-4\">\n <div class=\"h-16 w-16 shrink-0 overflow-hidden rounded-xl bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-amber-100 to-orange-100\"></div>\n </div>\n <div class=\"min-w-0 flex-1\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Workflow</span>\n <h3 class=\"mt-1 text-lg font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Agentische Workflows fuer Landingpages: Was man wirklich standardisieren sollte</h3>\n <p class=\"mt-1 line-clamp-2 text-sm text-[var(--ws-blog-text-soft)]\">Snippets, Patterns und Templates greifen nur dann sauber ineinander, wenn die Registry semantisch gepflegt ist.</p>\n <div class=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--ws-blog-text-muted)]\">\n <span>14. Maerz 2026</span>\n <span>7 Min</span>\n <span>AI</span>\n </div>\n </div>\n </a>\n </article>\n </div>\n </div>\n</section>\n",
9668
+ "css": null,
9669
+ "js": null
9670
+ },
8488
9671
  {
8489
9672
  "id": "blog/featured",
8490
9673
  "title": "Blog Featured",
@@ -8590,39 +9773,39 @@
8590
9773
  "js": null
8591
9774
  },
8592
9775
  {
8593
- "id": "blog/minimal",
8594
- "title": "Blog Minimal",
8595
- "summary": "Clean text-only blog listing with date, category, title, and excerpt in a single-column list.",
9776
+ "id": "blog/magazine-grid",
9777
+ "title": "Blog Magazine Grid",
9778
+ "summary": "Asymmetric magazine-style blog grid with one large lead story and a supporting grid of smaller article cards.",
8596
9779
  "family": "blog",
8597
9780
  "kind": "section",
8598
9781
  "tier": "enhanced",
8599
9782
  "extends": "blog/base",
8600
9783
  "tags": [
8601
9784
  "blog",
8602
- "minimal",
8603
- "list",
8604
- "text-only",
8605
- "editorial"
9785
+ "magazine",
9786
+ "editorial",
9787
+ "asymmetric-grid",
9788
+ "featured"
8606
9789
  ],
8607
9790
  "search": {
8608
9791
  "intent": [
8609
- "minimal blog post list",
8610
- "text-only article listing"
9792
+ "magazine style blog layout",
9793
+ "asymmetric article grid with hero story"
8611
9794
  ],
8612
9795
  "keywords": [
8613
9796
  "blog",
8614
- "minimal",
8615
- "list",
8616
- "simple",
8617
- "text",
8618
- "articles",
8619
- "editorial"
9797
+ "magazine",
9798
+ "grid",
9799
+ "editorial",
9800
+ "hero",
9801
+ "featured",
9802
+ "articles"
8620
9803
  ],
8621
9804
  "useCases": [
8622
- "engineering blog",
8623
- "personal site",
8624
- "changelog",
8625
- "company updates"
9805
+ "editorial landing page",
9806
+ "featured content hub",
9807
+ "category overview",
9808
+ "homepage"
8626
9809
  ]
8627
9810
  },
8628
9811
  "frameworks": {
@@ -8632,7 +9815,7 @@
8632
9815
  },
8633
9816
  "tokens": {
8634
9817
  "color": "neutral",
8635
- "radius": "none",
9818
+ "radius": "2xl",
8636
9819
  "shadow": "none",
8637
9820
  "spacing": "section-default",
8638
9821
  "typography": "marketing-default"
@@ -8649,17 +9832,22 @@
8649
9832
  {
8650
9833
  "name": "heading",
8651
9834
  "required": false,
8652
- "description": "Blog title and description."
9835
+ "description": "Editorial heading block."
9836
+ },
9837
+ {
9838
+ "name": "featured",
9839
+ "required": true,
9840
+ "description": "Large lead article."
8653
9841
  },
8654
9842
  {
8655
9843
  "name": "posts",
8656
9844
  "required": true,
8657
- "description": "List of posts with date, category, title, excerpt."
9845
+ "description": "Smaller supporting stories arranged around the lead story."
8658
9846
  }
8659
9847
  ],
8660
9848
  "props": [],
8661
9849
  "files": {
8662
- "html": "./minimal.html",
9850
+ "html": "./magazine-grid.html",
8663
9851
  "css": null,
8664
9852
  "js": null
8665
9853
  },
@@ -8667,60 +9855,261 @@
8667
9855
  "copyPasteReady": true,
8668
9856
  "ssrSafe": true,
8669
9857
  "tailwindOnly": true,
8670
- "notes": []
9858
+ "notes": [
9859
+ "Best used for a curated top area, not a full archive of hundreds of posts.",
9860
+ "Keep only a handful of cards in this layout to preserve hierarchy."
9861
+ ]
8671
9862
  },
8672
9863
  "ai": {
8673
9864
  "prompts": [
8674
- "Add a minimal text-only blog listing.",
8675
- "Create a clean single-column article list."
9865
+ "Create a magazine-style blog section with one lead story and smaller supporting cards.",
9866
+ "Build an asymmetric editorial grid for featured articles."
8676
9867
  ],
8677
- "compositionRole": "supporting"
9868
+ "compositionRole": "entry"
8678
9869
  },
8679
9870
  "governance": {
8680
9871
  "status": "published",
8681
9872
  "quality": "stable",
8682
9873
  "owner": "design-system",
8683
- "updatedAt": "2026-03-10"
9874
+ "updatedAt": "2026-03-21"
8684
9875
  },
8685
- "html": "<section class=\"ws-blog bg-[var(--ws-blog-bg)] py-20\">\n <div class=\"mx-auto max-w-3xl px-6\">\n <div class=\"mb-12\">\n <h2 class=\"text-3xl font-bold tracking-tight text-[var(--ws-blog-text)] sm:text-4xl\">Blog</h2>\n <p class=\"mt-2 text-lg text-[var(--ws-blog-text-soft)]\">Thoughts on design systems, CSS, and modern web development.</p>\n </div>\n\n <div class=\"divide-y divide-[var(--ws-blog-border)] border-y border-[var(--ws-blog-border)]\">\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-03-08\">Mar 8, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Patterns</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">The complete guide to building a pattern registry</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">From CSS snippets to full page sections how we built a searchable, AI-native component library.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-28\">Feb 28, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">CSS</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Scroll-driven animations without JavaScript</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">Modern CSS scroll timelines replace Intersection Observer for reveal, parallax, and progress bar effects.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-20\">Feb 20, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Workflow</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Using the CLI to scaffold landing pages</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">Combine the Webspire CLI with AI agents to compose full landing pages from registry patterns.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-14\">Feb 14, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Deep dive</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Glass effects with OKLCH and fallbacks</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">A complete guide to building accessible glassmorphism with modern color spaces and progressive enhancement.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-06\">Feb 6, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Architecture</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Why we chose Astro v6 for a pattern registry</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">Static-first, content-collections, and zero client JS — how Astro's architecture perfectly fits a documentation site.</p>\n </a>\n </article>\n </div>\n </div>\n</section>\n",
9876
+ "html": "<section class=\"ws-blog bg-[var(--ws-blog-bg)] py-20\">\n <div class=\"mx-auto max-w-7xl px-6\">\n <div class=\"max-w-2xl\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-blog-accent)]\">Featured Stories</p>\n <h2 class=\"mt-3 text-3xl font-bold tracking-tight text-[var(--ws-blog-text)] sm:text-4xl\">Editorial picks this month</h2>\n <p class=\"mt-3 text-base text-[var(--ws-blog-text-soft)]\">A magazine-style top area with one lead story and a tighter supporting grid.</p>\n </div>\n\n <div class=\"mt-12 grid grid-cols-1 gap-6 md:grid-cols-3\">\n <article class=\"group md:col-span-2 md:row-span-2\">\n <a href=\"#\" class=\"block h-full rounded-[1.75rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4 md:p-5\">\n <div class=\"aspect-square overflow-hidden rounded-[1.4rem]\">\n <div class=\"h-full w-full bg-gradient-to-br from-indigo-100 via-purple-100 to-fuchsia-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-5\">\n <span class=\"inline-flex rounded-full bg-indigo-100 px-3 py-1 text-xs font-semibold uppercase tracking-[0.14em] text-indigo-700\">Lead Story</span>\n <h3 class=\"mt-3 text-2xl font-semibold leading-tight text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)] sm:text-3xl\">Wie moderne Registry-Systeme Design, Entwicklung und agentische Workflows auf dieselbe Inhaltsbasis stellen</h3>\n <p class=\"mt-3 max-w-2xl text-sm leading-7 text-[var(--ws-blog-text-soft)]\">Eine praxisnahe Einordnung, warum Snippets, Patterns und Templates nur dann wirklich skalieren, wenn ihre Inhalte und Vorschauen dieselbe Sprache sprechen.</p>\n <div class=\"mt-5 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--ws-blog-text-muted)]\">\n <span>21. Maerz 2026</span>\n <span>10 Min</span>\n <span>Registry Strategy</span>\n </div>\n </div>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block rounded-[1.5rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4\">\n <div class=\"aspect-square overflow-hidden rounded-[1.15rem]\">\n <div class=\"h-full w-full bg-gradient-to-br from-emerald-100 to-teal-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">CSS</span>\n <h3 class=\"mt-2 text-lg font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Scroll-Timelines als Layout-Werkzeug</h3>\n </div>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block rounded-[1.5rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4\">\n <div class=\"aspect-square overflow-hidden rounded-[1.15rem]\">\n <div class=\"h-full w-full bg-gradient-to-br from-amber-100 to-orange-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Workflow</span>\n <h3 class=\"mt-2 text-lg font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Was gute Demo-Inhalte leisten muessen</h3>\n </div>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block rounded-[1.5rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4\">\n <div class=\"aspect-square overflow-hidden rounded-[1.15rem]\">\n <div class=\"h-full w-full bg-gradient-to-br from-sky-100 to-cyan-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Design</span>\n <h3 class=\"mt-2 text-lg font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Materialsysteme fuer Premium-Surfaces</h3>\n </div>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block rounded-[1.5rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4\">\n <div class=\"aspect-square overflow-hidden rounded-[1.15rem]\">\n <div class=\"h-full w-full bg-gradient-to-br from-rose-100 to-pink-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <div class=\"mt-4\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Content</span>\n <h3 class=\"mt-2 text-lg font-semibold leading-snug text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Warum Startseiten semantisch klar sein muessen</h3>\n </div>\n </a>\n </article>\n </div>\n </div>\n</section>\n",
8686
9877
  "css": null,
8687
9878
  "js": null
8688
9879
  },
8689
9880
  {
8690
- "id": "blog/sidebar",
8691
- "title": "Blog Sidebar",
8692
- "summary": "Two-column blog layout with article list on the left and sidebar with categories and recent posts on the right.",
9881
+ "id": "blog/media-list",
9882
+ "title": "Blog Media List",
9883
+ "summary": "Text-dominant blog list with the content on the left and a compact square image on the right, inspired by editorial feeds like Medium.",
8693
9884
  "family": "blog",
8694
9885
  "kind": "section",
8695
9886
  "tier": "enhanced",
8696
9887
  "extends": "blog/base",
8697
9888
  "tags": [
8698
9889
  "blog",
8699
- "sidebar",
8700
- "two-column",
8701
- "categories",
8702
- "recent-posts"
9890
+ "editorial",
9891
+ "media",
9892
+ "list",
9893
+ "text-first",
9894
+ "feed"
8703
9895
  ],
8704
9896
  "search": {
8705
9897
  "intent": [
8706
- "blog layout with sidebar",
8707
- "two-column blog page"
9898
+ "medium style blog listing",
9899
+ "text first article feed with image on the right"
8708
9900
  ],
8709
9901
  "keywords": [
8710
9902
  "blog",
8711
- "sidebar",
8712
- "two-column",
8713
- "categories",
8714
- "recent",
8715
- "posts",
8716
- "articles",
8717
- "layout"
9903
+ "medium",
9904
+ "editorial",
9905
+ "list",
9906
+ "image-right",
9907
+ "text-first",
9908
+ "articles"
8718
9909
  ],
8719
9910
  "useCases": [
8720
- "content blog",
8721
- "news site",
8722
- "knowledge base",
8723
- "company blog"
9911
+ "editorial blog",
9912
+ "content marketing",
9913
+ "company insights",
9914
+ "thought leadership"
9915
+ ]
9916
+ },
9917
+ "frameworks": {
9918
+ "html": true,
9919
+ "astro": true,
9920
+ "webComponent": false
9921
+ },
9922
+ "tokens": {
9923
+ "color": "neutral",
9924
+ "radius": "xl",
9925
+ "shadow": "none",
9926
+ "spacing": "section-default",
9927
+ "typography": "marketing-default"
9928
+ },
9929
+ "capabilities": {
9930
+ "responsive": true,
9931
+ "darkMode": true,
9932
+ "animated": false,
9933
+ "interactive": false,
9934
+ "dependencies": [],
9935
+ "animationPreset": "none"
9936
+ },
9937
+ "slots": [
9938
+ {
9939
+ "name": "heading",
9940
+ "required": false,
9941
+ "description": "Optional heading block for the list."
9942
+ },
9943
+ {
9944
+ "name": "posts",
9945
+ "required": true,
9946
+ "description": "Editorial rows with dominant text and compact images."
9947
+ }
9948
+ ],
9949
+ "props": [],
9950
+ "files": {
9951
+ "html": "./media-list.html",
9952
+ "css": null,
9953
+ "js": null
9954
+ },
9955
+ "install": {
9956
+ "copyPasteReady": true,
9957
+ "ssrSafe": true,
9958
+ "tailwindOnly": true,
9959
+ "notes": [
9960
+ "Good replacement for wide horizontal cards when titles are long.",
9961
+ "Keep images secondary so the text remains the entry point."
9962
+ ]
9963
+ },
9964
+ "ai": {
9965
+ "prompts": [
9966
+ "Create a Medium-style blog feed with text on the left and image on the right.",
9967
+ "Build a text-first article list for long headlines."
9968
+ ],
9969
+ "compositionRole": "supporting"
9970
+ },
9971
+ "governance": {
9972
+ "status": "published",
9973
+ "quality": "stable",
9974
+ "owner": "design-system",
9975
+ "updatedAt": "2026-03-21"
9976
+ },
9977
+ "html": "<section class=\"ws-blog bg-[var(--ws-blog-bg)] py-20\">\n <div class=\"mx-auto max-w-5xl px-6\">\n <div class=\"max-w-2xl\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-blog-accent)]\">Editorial Feed</p>\n <h2 class=\"mt-3 text-3xl font-bold tracking-tight text-[var(--ws-blog-text)] sm:text-4xl\">Thoughtful writing, text first</h2>\n <p class=\"mt-3 text-base text-[var(--ws-blog-text-soft)]\">A text-dominant listing where the image acts as an anchor, not as the main story.</p>\n </div>\n\n <div class=\"mt-12 space-y-8\">\n <article class=\"group border-b border-[var(--ws-blog-border)] pb-8\">\n <a href=\"#\" class=\"flex flex-col-reverse gap-4 md:flex-row md:items-start md:gap-8\">\n <div class=\"min-w-0 flex-1\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Design Systems</span>\n <h3 class=\"mt-2 text-2xl font-semibold leading-tight text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Wie man aus fragmentierten UI-Bausteinen eine konsistente Registry fuer Teams und Agents baut</h3>\n <p class=\"mt-3 line-clamp-2 text-base text-[var(--ws-blog-text-soft)]\">Ein pragmischer Blick auf Benennung, Inhaltsqualitaet, Vorschau-Logik und die Frage, wann ein Snippet zu einem Pattern werden sollte.</p>\n <div class=\"mt-4 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-[var(--ws-blog-text-muted)]\">\n <span>21. Maerz 2026</span>\n <span>9 Min Lesezeit</span>\n <span>Registry</span>\n </div>\n </div>\n <div class=\"w-full shrink-0 md:w-32 lg:w-40\">\n <div class=\"aspect-square overflow-hidden rounded-2xl bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-indigo-100 to-purple-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n </div>\n </a>\n </article>\n\n <article class=\"group border-b border-[var(--ws-blog-border)] pb-8\">\n <a href=\"#\" class=\"flex flex-col-reverse gap-4 md:flex-row md:items-start md:gap-8\">\n <div class=\"min-w-0 flex-1\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">CSS Effects</span>\n <h3 class=\"mt-2 text-2xl font-semibold leading-tight text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Warum gute Effekt-Demos die Mechanik zeigen muessen und nicht nur visuell beeindrucken sollen</h3>\n <p class=\"mt-3 line-clamp-2 text-base text-[var(--ws-blog-text-soft)]\">Parallax, reveal, hover und glow wirken erst dann hochwertig, wenn der Einsatzzweck in der Vorschau unmittelbar lesbar wird.</p>\n <div class=\"mt-4 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-[var(--ws-blog-text-muted)]\">\n <span>17. Maerz 2026</span>\n <span>6 Min Lesezeit</span>\n <span>Preview Design</span>\n </div>\n </div>\n <div class=\"w-full shrink-0 md:w-32 lg:w-40\">\n <div class=\"aspect-square overflow-hidden rounded-2xl bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-emerald-100 to-teal-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n </div>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"flex flex-col-reverse gap-4 md:flex-row md:items-start md:gap-8\">\n <div class=\"min-w-0 flex-1\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Workflow</span>\n <h3 class=\"mt-2 text-2xl font-semibold leading-tight text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Welche Inhalte auf Startseiten gehoeren, wenn eine Registry nicht wie eine generische Tailwind-Sammlung wirken soll</h3>\n <p class=\"mt-3 line-clamp-2 text-base text-[var(--ws-blog-text-soft)]\">Messaging, Kategorielogik und Featured-Content muessen dieselbe semantische Schicht abbilden wie die eigentliche Anwendung.</p>\n <div class=\"mt-4 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-[var(--ws-blog-text-muted)]\">\n <span>12. Maerz 2026</span>\n <span>7 Min Lesezeit</span>\n <span>Content Strategy</span>\n </div>\n </div>\n <div class=\"w-full shrink-0 md:w-32 lg:w-40\">\n <div class=\"aspect-square overflow-hidden rounded-2xl bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-amber-100 to-orange-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n </div>\n </a>\n </article>\n </div>\n </div>\n</section>\n",
9978
+ "css": null,
9979
+ "js": null
9980
+ },
9981
+ {
9982
+ "id": "blog/minimal",
9983
+ "title": "Blog Minimal",
9984
+ "summary": "Clean text-only blog listing with date, category, title, and excerpt in a single-column list.",
9985
+ "family": "blog",
9986
+ "kind": "section",
9987
+ "tier": "enhanced",
9988
+ "extends": "blog/base",
9989
+ "tags": [
9990
+ "blog",
9991
+ "minimal",
9992
+ "list",
9993
+ "text-only",
9994
+ "editorial"
9995
+ ],
9996
+ "search": {
9997
+ "intent": [
9998
+ "minimal blog post list",
9999
+ "text-only article listing"
10000
+ ],
10001
+ "keywords": [
10002
+ "blog",
10003
+ "minimal",
10004
+ "list",
10005
+ "simple",
10006
+ "text",
10007
+ "articles",
10008
+ "editorial"
10009
+ ],
10010
+ "useCases": [
10011
+ "engineering blog",
10012
+ "personal site",
10013
+ "changelog",
10014
+ "company updates"
10015
+ ]
10016
+ },
10017
+ "frameworks": {
10018
+ "html": true,
10019
+ "astro": true,
10020
+ "webComponent": false
10021
+ },
10022
+ "tokens": {
10023
+ "color": "neutral",
10024
+ "radius": "none",
10025
+ "shadow": "none",
10026
+ "spacing": "section-default",
10027
+ "typography": "marketing-default"
10028
+ },
10029
+ "capabilities": {
10030
+ "responsive": true,
10031
+ "darkMode": true,
10032
+ "animated": false,
10033
+ "interactive": false,
10034
+ "dependencies": [],
10035
+ "animationPreset": "none"
10036
+ },
10037
+ "slots": [
10038
+ {
10039
+ "name": "heading",
10040
+ "required": false,
10041
+ "description": "Blog title and description."
10042
+ },
10043
+ {
10044
+ "name": "posts",
10045
+ "required": true,
10046
+ "description": "List of posts with date, category, title, excerpt."
10047
+ }
10048
+ ],
10049
+ "props": [],
10050
+ "files": {
10051
+ "html": "./minimal.html",
10052
+ "css": null,
10053
+ "js": null
10054
+ },
10055
+ "install": {
10056
+ "copyPasteReady": true,
10057
+ "ssrSafe": true,
10058
+ "tailwindOnly": true,
10059
+ "notes": []
10060
+ },
10061
+ "ai": {
10062
+ "prompts": [
10063
+ "Add a minimal text-only blog listing.",
10064
+ "Create a clean single-column article list."
10065
+ ],
10066
+ "compositionRole": "supporting"
10067
+ },
10068
+ "governance": {
10069
+ "status": "published",
10070
+ "quality": "stable",
10071
+ "owner": "design-system",
10072
+ "updatedAt": "2026-03-10"
10073
+ },
10074
+ "html": "<section class=\"ws-blog bg-[var(--ws-blog-bg)] py-20\">\n <div class=\"mx-auto max-w-3xl px-6\">\n <div class=\"mb-12\">\n <h2 class=\"text-3xl font-bold tracking-tight text-[var(--ws-blog-text)] sm:text-4xl\">Blog</h2>\n <p class=\"mt-2 text-lg text-[var(--ws-blog-text-soft)]\">Thoughts on design systems, CSS, and modern web development.</p>\n </div>\n\n <div class=\"divide-y divide-[var(--ws-blog-border)] border-y border-[var(--ws-blog-border)]\">\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-03-08\">Mar 8, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Patterns</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">The complete guide to building a pattern registry</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">From CSS snippets to full page sections — how we built a searchable, AI-native component library.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-28\">Feb 28, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">CSS</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Scroll-driven animations without JavaScript</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">Modern CSS scroll timelines replace Intersection Observer for reveal, parallax, and progress bar effects.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-20\">Feb 20, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Workflow</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Using the CLI to scaffold landing pages</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">Combine the Webspire CLI with AI agents to compose full landing pages from registry patterns.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-14\">Feb 14, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Deep dive</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Glass effects with OKLCH and fallbacks</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">A complete guide to building accessible glassmorphism with modern color spaces and progressive enhancement.</p>\n </a>\n </article>\n\n <article class=\"group py-6\">\n <a href=\"#\" class=\"block\">\n <div class=\"flex items-center gap-3 text-sm text-[var(--ws-blog-text-muted)]\">\n <time datetime=\"2026-02-06\">Feb 6, 2026</time>\n <span aria-hidden=\"true\">&middot;</span>\n <span class=\"text-[var(--ws-blog-accent)]\">Architecture</span>\n </div>\n <h3 class=\"mt-2 text-lg font-semibold text-[var(--ws-blog-text)] transition group-hover:text-[var(--ws-blog-accent)]\">Why we chose Astro v6 for a pattern registry</h3>\n <p class=\"mt-1 text-sm text-[var(--ws-blog-text-soft)]\">Static-first, content-collections, and zero client JS — how Astro's architecture perfectly fits a documentation site.</p>\n </a>\n </article>\n </div>\n </div>\n</section>\n",
10075
+ "css": null,
10076
+ "js": null
10077
+ },
10078
+ {
10079
+ "id": "blog/sidebar",
10080
+ "title": "Blog Sidebar",
10081
+ "summary": "Two-column blog layout with article list on the left and sidebar with categories and recent posts on the right.",
10082
+ "family": "blog",
10083
+ "kind": "section",
10084
+ "tier": "enhanced",
10085
+ "extends": "blog/base",
10086
+ "tags": [
10087
+ "blog",
10088
+ "sidebar",
10089
+ "two-column",
10090
+ "categories",
10091
+ "recent-posts"
10092
+ ],
10093
+ "search": {
10094
+ "intent": [
10095
+ "blog layout with sidebar",
10096
+ "two-column blog page"
10097
+ ],
10098
+ "keywords": [
10099
+ "blog",
10100
+ "sidebar",
10101
+ "two-column",
10102
+ "categories",
10103
+ "recent",
10104
+ "posts",
10105
+ "articles",
10106
+ "layout"
10107
+ ],
10108
+ "useCases": [
10109
+ "content blog",
10110
+ "news site",
10111
+ "knowledge base",
10112
+ "company blog"
8724
10113
  ]
8725
10114
  },
8726
10115
  "frameworks": {
@@ -8786,6 +10175,106 @@
8786
10175
  "css": null,
8787
10176
  "js": null
8788
10177
  },
10178
+ {
10179
+ "id": "blog/timeline",
10180
+ "title": "Blog Timeline",
10181
+ "summary": "Chronological blog archive laid out as a vertical timeline with alternating article cards and month markers.",
10182
+ "family": "blog",
10183
+ "kind": "section",
10184
+ "tier": "enhanced",
10185
+ "extends": "blog/base",
10186
+ "tags": [
10187
+ "blog",
10188
+ "timeline",
10189
+ "archive",
10190
+ "chronology",
10191
+ "editorial"
10192
+ ],
10193
+ "search": {
10194
+ "intent": [
10195
+ "blog archive timeline",
10196
+ "chronological article layout with timeline"
10197
+ ],
10198
+ "keywords": [
10199
+ "blog",
10200
+ "timeline",
10201
+ "archive",
10202
+ "chronology",
10203
+ "editorial",
10204
+ "articles",
10205
+ "history"
10206
+ ],
10207
+ "useCases": [
10208
+ "archive page",
10209
+ "company history",
10210
+ "editorial timeline",
10211
+ "release chronology"
10212
+ ]
10213
+ },
10214
+ "frameworks": {
10215
+ "html": true,
10216
+ "astro": true,
10217
+ "webComponent": false
10218
+ },
10219
+ "tokens": {
10220
+ "color": "neutral",
10221
+ "radius": "xl",
10222
+ "shadow": "none",
10223
+ "spacing": "section-default",
10224
+ "typography": "marketing-default"
10225
+ },
10226
+ "capabilities": {
10227
+ "responsive": true,
10228
+ "darkMode": true,
10229
+ "animated": false,
10230
+ "interactive": false,
10231
+ "dependencies": [],
10232
+ "animationPreset": "none"
10233
+ },
10234
+ "slots": [
10235
+ {
10236
+ "name": "heading",
10237
+ "required": false,
10238
+ "description": "Archive heading and intro copy."
10239
+ },
10240
+ {
10241
+ "name": "entries",
10242
+ "required": true,
10243
+ "description": "Timeline entries with month markers, post cards, and chronological metadata."
10244
+ }
10245
+ ],
10246
+ "props": [],
10247
+ "files": {
10248
+ "html": "./timeline.html",
10249
+ "css": null,
10250
+ "js": null
10251
+ },
10252
+ "install": {
10253
+ "copyPasteReady": true,
10254
+ "ssrSafe": true,
10255
+ "tailwindOnly": true,
10256
+ "notes": [
10257
+ "Best for chronological storytelling or archive browsing, not for dense high-volume feeds.",
10258
+ "On mobile, collapse to a single-column left-aligned timeline."
10259
+ ]
10260
+ },
10261
+ "ai": {
10262
+ "prompts": [
10263
+ "Create a chronological blog archive as a vertical timeline.",
10264
+ "Build an editorial timeline with alternating article cards and month markers."
10265
+ ],
10266
+ "compositionRole": "supporting"
10267
+ },
10268
+ "governance": {
10269
+ "status": "published",
10270
+ "quality": "stable",
10271
+ "owner": "design-system",
10272
+ "updatedAt": "2026-03-21"
10273
+ },
10274
+ "html": "<section class=\"ws-blog bg-[var(--ws-blog-bg)] py-20\">\n <div class=\"mx-auto max-w-6xl px-6\">\n <div class=\"max-w-2xl\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-blog-accent)]\">Archive Timeline</p>\n <h2 class=\"mt-3 text-3xl font-bold tracking-tight text-[var(--ws-blog-text)] sm:text-4xl\">Articles along a chronology</h2>\n <p class=\"mt-3 text-base text-[var(--ws-blog-text-soft)]\">A narrative archive layout for release histories, company stories, retrospectives, or editorial timelines.</p>\n </div>\n\n <div class=\"relative mt-14 max-w-5xl md:mx-auto\">\n <div class=\"absolute bottom-0 left-4 top-0 w-px bg-[var(--ws-blog-border)] md:left-1/2 md:-translate-x-1/2\"></div>\n\n <div class=\"relative mb-10 pl-12 md:pl-0\">\n <div class=\"absolute left-4 top-1.5 h-3 w-3 -translate-x-1/2 rounded-full border-4 border-[var(--ws-blog-bg)] bg-[var(--ws-blog-accent)] md:left-1/2\"></div>\n <div class=\"text-sm font-semibold uppercase tracking-[0.16em] text-[var(--ws-blog-accent)] md:text-center\">Maerz 2026</div>\n </div>\n\n <article class=\"relative mb-8 pl-12 md:flex md:justify-end md:pl-0 md:pr-[54%]\">\n <div class=\"absolute left-4 top-6 h-3 w-3 -translate-x-1/2 rounded-full border-4 border-[var(--ws-blog-bg)] bg-[var(--ws-blog-text)] md:left-1/2\"></div>\n <a href=\"#\" class=\"group block rounded-[1.4rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4 transition hover:border-[var(--ws-blog-accent)]\">\n <div class=\"mb-4 aspect-square overflow-hidden rounded-[1rem] bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-indigo-100 to-purple-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Registry</span>\n <h3 class=\"mt-2 text-xl font-semibold leading-snug text-[var(--ws-blog-text)]\">Wie Registry-Inhalte ueber Snippets, Patterns und Templates hinweg konsistent bleiben</h3>\n <p class=\"mt-2 text-sm leading-6 text-[var(--ws-blog-text-soft)]\">Eine Einordnung, wie Vorschauen, Metadaten und Inhaltsstruktur zusammenspielen muessen, damit die Anwendung verstanden wird.</p>\n <div class=\"mt-4 text-xs text-[var(--ws-blog-text-muted)]\">21. Maerz 2026 · 9 Min</div>\n </a>\n </article>\n\n <article class=\"relative mb-8 pl-12 md:flex md:justify-start md:pl-[54%]\">\n <div class=\"absolute left-4 top-6 h-3 w-3 -translate-x-1/2 rounded-full border-4 border-[var(--ws-blog-bg)] bg-[var(--ws-blog-text)] md:left-1/2\"></div>\n <a href=\"#\" class=\"group block rounded-[1.4rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4 transition hover:border-[var(--ws-blog-accent)]\">\n <div class=\"mb-4 aspect-square overflow-hidden rounded-[1rem] bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-emerald-100 to-teal-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">CSS Effects</span>\n <h3 class=\"mt-2 text-xl font-semibold leading-snug text-[var(--ws-blog-text)]\">Warum gute Effekt-Demos die Mechanik sichtbar machen muessen</h3>\n <p class=\"mt-2 text-sm leading-6 text-[var(--ws-blog-text-soft)]\">Von Scroll bis Hover: Demos sollten den Einsatzzweck lesbar machen, nicht nur dekorativ beeindrucken.</p>\n <div class=\"mt-4 text-xs text-[var(--ws-blog-text-muted)]\">17. Maerz 2026 · 6 Min</div>\n </a>\n </article>\n\n <div class=\"relative mb-10 pl-12 md:pl-0\">\n <div class=\"absolute left-4 top-1.5 h-3 w-3 -translate-x-1/2 rounded-full border-4 border-[var(--ws-blog-bg)] bg-[var(--ws-blog-accent)] md:left-1/2\"></div>\n <div class=\"text-sm font-semibold uppercase tracking-[0.16em] text-[var(--ws-blog-accent)] md:text-center\">Februar 2026</div>\n </div>\n\n <article class=\"relative mb-8 pl-12 md:flex md:justify-end md:pl-0 md:pr-[54%]\">\n <div class=\"absolute left-4 top-6 h-3 w-3 -translate-x-1/2 rounded-full border-4 border-[var(--ws-blog-bg)] bg-[var(--ws-blog-text)] md:left-1/2\"></div>\n <a href=\"#\" class=\"group block rounded-[1.4rem] border border-[var(--ws-blog-border)] bg-[var(--ws-blog-card-bg)] p-4 transition hover:border-[var(--ws-blog-accent)]\">\n <div class=\"mb-4 aspect-square overflow-hidden rounded-[1rem] bg-[var(--ws-blog-card-bg)]\">\n <div class=\"h-full w-full bg-gradient-to-br from-amber-100 to-orange-100 transition duration-300 group-hover:scale-105\"></div>\n </div>\n <span class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--ws-blog-accent)]\">Workflow</span>\n <h3 class=\"mt-2 text-xl font-semibold leading-snug text-[var(--ws-blog-text)]\">Welche TODOs sich direkt in Registry-Inhalte uebersetzen lassen</h3>\n <p class=\"mt-2 text-sm leading-6 text-[var(--ws-blog-text-soft)]\">Nicht jede Idee wird ein Pattern. Manche Wuensche muessen erst als Snippet, Preview oder Messaging-Schicht geloest werden.</p>\n <div class=\"mt-4 text-xs text-[var(--ws-blog-text-muted)]\">28. Februar 2026 · 7 Min</div>\n </a>\n </article>\n </div>\n </div>\n</section>\n",
10275
+ "css": null,
10276
+ "js": null
10277
+ },
8789
10278
  {
8790
10279
  "id": "breadcrumb/base",
8791
10280
  "title": "Breadcrumb Base",
@@ -13244,6 +14733,208 @@
13244
14733
  "css": null,
13245
14734
  "js": null
13246
14735
  },
14736
+ {
14737
+ "id": "comparison/cards",
14738
+ "title": "Comparison Cards",
14739
+ "summary": "Two separate comparison cards with unequal visual weight, useful for before-after framing or directional decisions without pricing semantics.",
14740
+ "family": "comparison",
14741
+ "kind": "section",
14742
+ "tier": "enhanced",
14743
+ "extends": "comparison/checklist",
14744
+ "tags": [
14745
+ "comparison",
14746
+ "cards",
14747
+ "side-by-side",
14748
+ "directional",
14749
+ "editorial"
14750
+ ],
14751
+ "search": {
14752
+ "intent": [
14753
+ "comparison as two separate cards",
14754
+ "before after comparison cards"
14755
+ ],
14756
+ "keywords": [
14757
+ "comparison",
14758
+ "cards",
14759
+ "before after",
14760
+ "side by side",
14761
+ "weighted"
14762
+ ],
14763
+ "useCases": [
14764
+ "before and after",
14765
+ "current vs target",
14766
+ "requirements framing",
14767
+ "editorial comparison"
14768
+ ]
14769
+ },
14770
+ "frameworks": {
14771
+ "html": true,
14772
+ "astro": true,
14773
+ "webComponent": false
14774
+ },
14775
+ "tokens": {
14776
+ "color": "neutral",
14777
+ "radius": "2xl",
14778
+ "shadow": "lg",
14779
+ "spacing": "section-default",
14780
+ "typography": "marketing-default"
14781
+ },
14782
+ "capabilities": {
14783
+ "responsive": true,
14784
+ "darkMode": true,
14785
+ "animated": false,
14786
+ "interactive": false,
14787
+ "dependencies": [],
14788
+ "animationPreset": "none"
14789
+ },
14790
+ "slots": [
14791
+ {
14792
+ "name": "heading",
14793
+ "required": true,
14794
+ "description": "Section heading and setup copy."
14795
+ },
14796
+ {
14797
+ "name": "cards",
14798
+ "required": true,
14799
+ "description": "Two comparison cards with distinct weight and messaging."
14800
+ }
14801
+ ],
14802
+ "props": [],
14803
+ "files": {
14804
+ "html": "./cards.html",
14805
+ "css": null,
14806
+ "js": null
14807
+ },
14808
+ "install": {
14809
+ "copyPasteReady": true,
14810
+ "ssrSafe": true,
14811
+ "tailwindOnly": true,
14812
+ "notes": [
14813
+ "Uses separate cards instead of one shared shell.",
14814
+ "The emphasized card uses stronger border, shadow and CTA."
14815
+ ]
14816
+ },
14817
+ "ai": {
14818
+ "prompts": [
14819
+ "Create a two card comparison for before vs after.",
14820
+ "Add a weighted side by side comparison without pricing UI."
14821
+ ],
14822
+ "compositionRole": "supporting"
14823
+ },
14824
+ "governance": {
14825
+ "status": "published",
14826
+ "quality": "stable",
14827
+ "owner": "design-system",
14828
+ "updatedAt": "2026-03-21"
14829
+ },
14830
+ "html": "<section class=\"ws-comparison bg-[var(--ws-comparison-bg)] py-20\">\n <div class=\"mx-auto max-w-5xl px-6\">\n <div class=\"mx-auto max-w-2xl text-center\">\n <h2 class=\"text-3xl font-bold tracking-tight text-[var(--ws-comparison-text)] sm:text-4xl\">Current state vs target state</h2>\n <p class=\"mt-4 text-lg text-[var(--ws-comparison-text-soft)]\">A card-based comparison for directional decisions where one side should feel clearly stronger.</p>\n </div>\n\n <div class=\"mt-12 grid gap-6 lg:grid-cols-2\">\n <article class=\"rounded-3xl border border-[var(--ws-comparison-border)] bg-[var(--ws-comparison-bg)] p-8 shadow-sm\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-comparison-text-soft)]\">Current</p>\n <h3 class=\"mt-3 text-2xl font-semibold text-[var(--ws-comparison-text)]\">Too many parallel priorities</h3>\n <p class=\"mt-4 text-sm leading-6 text-[var(--ws-comparison-text-soft)]\">Everything competes for attention, which makes the whole proposition feel less decisive.</p>\n <ul class=\"mt-8 space-y-3 text-sm text-[var(--ws-comparison-text-soft)]\">\n <li>Mixed messaging across product, design and rollout</li>\n <li>Harder to explain in a short sales conversation</li>\n <li>More moving parts before launch even happens</li>\n </ul>\n </article>\n\n <article class=\"rounded-3xl border-2 border-[var(--ws-comparison-highlight)] bg-[var(--ws-comparison-highlight)]/6 p-8 shadow-lg\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-comparison-highlight)]\">Target</p>\n <h3 class=\"mt-3 text-2xl font-semibold text-[var(--ws-comparison-text)]\">One strong path to ship</h3>\n <p class=\"mt-4 text-sm leading-6 text-[var(--ws-comparison-text-soft)]\">The preferred card gets more weight, so the recommendation is obvious even before reading every bullet.</p>\n <ul class=\"mt-8 space-y-3 text-sm text-[var(--ws-comparison-text)]\">\n <li>Clear hierarchy between must-have and optional scope</li>\n <li>Faster rollout with fewer decision branches</li>\n <li>Better internal alignment around what success means first</li>\n </ul>\n <a href=\"#\" class=\"mt-8 inline-flex rounded-xl bg-[var(--ws-comparison-highlight)] px-5 py-3 text-sm font-semibold text-white transition hover:opacity-90\">Choose this direction</a>\n </article>\n </div>\n </div>\n</section>\n",
14831
+ "css": null,
14832
+ "js": null
14833
+ },
14834
+ {
14835
+ "id": "comparison/checklist",
14836
+ "title": "Comparison Checklist",
14837
+ "summary": "Two-column comparison with a vertical divider on desktop, stacked sections on mobile, and differently weighted checklists for primary vs secondary options.",
14838
+ "family": "comparison",
14839
+ "kind": "section",
14840
+ "tier": "base",
14841
+ "extends": "comparison/side-by-side",
14842
+ "tags": [
14843
+ "comparison",
14844
+ "checklist",
14845
+ "side-by-side",
14846
+ "before-after",
14847
+ "requirements"
14848
+ ],
14849
+ "search": {
14850
+ "intent": [
14851
+ "side by side checklist comparison",
14852
+ "what we need vs nice to have layout"
14853
+ ],
14854
+ "keywords": [
14855
+ "comparison",
14856
+ "checklist",
14857
+ "two column",
14858
+ "requirements",
14859
+ "before after",
14860
+ "pros cons"
14861
+ ],
14862
+ "useCases": [
14863
+ "what we need vs nice to have",
14864
+ "before vs after",
14865
+ "left right comparison",
14866
+ "weighted options"
14867
+ ]
14868
+ },
14869
+ "frameworks": {
14870
+ "html": true,
14871
+ "astro": true,
14872
+ "webComponent": false
14873
+ },
14874
+ "tokens": {
14875
+ "color": "neutral",
14876
+ "radius": "2xl",
14877
+ "shadow": "md",
14878
+ "spacing": "section-default",
14879
+ "typography": "marketing-default"
14880
+ },
14881
+ "capabilities": {
14882
+ "responsive": true,
14883
+ "darkMode": true,
14884
+ "animated": false,
14885
+ "interactive": false,
14886
+ "dependencies": [],
14887
+ "animationPreset": "none"
14888
+ },
14889
+ "slots": [
14890
+ {
14891
+ "name": "heading",
14892
+ "required": true,
14893
+ "description": "Intro text for the comparison section."
14894
+ },
14895
+ {
14896
+ "name": "left",
14897
+ "required": true,
14898
+ "description": "Muted checklist column for the lower-priority or current state."
14899
+ },
14900
+ {
14901
+ "name": "right",
14902
+ "required": true,
14903
+ "description": "Emphasized checklist column for the preferred target state."
14904
+ }
14905
+ ],
14906
+ "props": [],
14907
+ "files": {
14908
+ "html": "./checklist.html",
14909
+ "css": null,
14910
+ "js": null
14911
+ },
14912
+ "install": {
14913
+ "copyPasteReady": true,
14914
+ "ssrSafe": true,
14915
+ "tailwindOnly": true,
14916
+ "notes": [
14917
+ "Uses a border between columns on desktop and a border between stacked blocks on mobile.",
14918
+ "Right column is intentionally more visually weighted."
14919
+ ]
14920
+ },
14921
+ "ai": {
14922
+ "prompts": [
14923
+ "Add a side by side checklist comparison for what we need vs nice to have.",
14924
+ "Create a two column comparison with one muted side and one emphasized side."
14925
+ ],
14926
+ "compositionRole": "supporting"
14927
+ },
14928
+ "governance": {
14929
+ "status": "published",
14930
+ "quality": "stable",
14931
+ "owner": "design-system",
14932
+ "updatedAt": "2026-03-21"
14933
+ },
14934
+ "html": "<section class=\"ws-comparison bg-[var(--ws-comparison-bg)] py-20\">\n <div class=\"mx-auto max-w-5xl px-6\">\n <div class=\"mx-auto max-w-2xl text-center\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.2em] text-[var(--ws-comparison-highlight)]\">Comparison</p>\n <h2 class=\"mt-4 text-3xl font-bold tracking-tight text-[var(--ws-comparison-text)] sm:text-4xl\">What we actually need</h2>\n <p class=\"mt-4 text-lg text-[var(--ws-comparison-text-soft)]\">A simple side-by-side frame for current assumptions versus the stronger target state.</p>\n </div>\n\n <div class=\"mt-12 grid overflow-hidden rounded-3xl border border-[var(--ws-comparison-border)] bg-[var(--ws-comparison-bg)] shadow-sm md:grid-cols-2\">\n <div class=\"p-8 md:border-r md:border-[var(--ws-comparison-border)]\">\n <div class=\"max-w-md\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-comparison-text-soft)]\">Nice to have</p>\n <h3 class=\"mt-3 text-2xl font-semibold text-[var(--ws-comparison-text)]\">Looks good on paper</h3>\n <p class=\"mt-3 text-sm leading-6 text-[var(--ws-comparison-text-soft)]\">Useful additions when budget, complexity and rollout speed are secondary concerns.</p>\n </div>\n <ul class=\"mt-8 space-y-4\">\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text-soft)]\"><span class=\"mt-0.5 text-base\">+</span><span>Extra polish layers and advanced integrations</span></li>\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text-soft)]\"><span class=\"mt-0.5 text-base\">+</span><span>More flexible content controls for edge cases</span></li>\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text-soft)]\"><span class=\"mt-0.5 text-base\">+</span><span>Optional storytelling sections for later expansion</span></li>\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text-soft)]\"><span class=\"mt-0.5 text-base\">+</span><span>Additional automation once the core workflow is stable</span></li>\n </ul>\n </div>\n\n <div class=\"bg-[var(--ws-comparison-highlight)]/5 p-8\">\n <div class=\"max-w-md\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-comparison-highlight)]\">What we need</p>\n <h3 class=\"mt-3 text-2xl font-semibold text-[var(--ws-comparison-text)]\">Clear, shippable essentials</h3>\n <p class=\"mt-3 text-sm leading-6 text-[var(--ws-comparison-text-soft)]\">The preferred side gets stronger contrast and clearer priority because it represents the actual decision path.</p>\n </div>\n <ul class=\"mt-8 space-y-4\">\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text)]\"><span class=\"mt-0.5 text-emerald-600\">✓</span><span>Fast to understand in one pass</span></li>\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text)]\"><span class=\"mt-0.5 text-emerald-600\">✓</span><span>Easy to explain to internal and external stakeholders</span></li>\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text)]\"><span class=\"mt-0.5 text-emerald-600\">✓</span><span>Prioritized around rollout speed and clarity</span></li>\n <li class=\"flex items-start gap-3 text-[var(--ws-comparison-text)]\"><span class=\"mt-0.5 text-emerald-600\">✓</span><span>Leaves room for iteration after launch</span></li>\n </ul>\n </div>\n </div>\n </div>\n</section>\n",
14935
+ "css": null,
14936
+ "js": null
14937
+ },
13247
14938
  {
13248
14939
  "id": "comparison/code",
13249
14940
  "title": "Code Comparison",
@@ -17441,6 +19132,99 @@
17441
19132
  "css": null,
17442
19133
  "js": null
17443
19134
  },
19135
+ {
19136
+ "id": "divider/statement",
19137
+ "title": "Statement Divider",
19138
+ "summary": "Centered statement text between top and bottom borders, designed as a rhetorical transition between larger sections.",
19139
+ "family": "divider",
19140
+ "kind": "component",
19141
+ "tier": "base",
19142
+ "extends": "divider/base",
19143
+ "tags": [
19144
+ "divider",
19145
+ "statement",
19146
+ "transition",
19147
+ "editorial",
19148
+ "quote"
19149
+ ],
19150
+ "search": {
19151
+ "intent": [
19152
+ "section transition statement",
19153
+ "centered divider text between sections"
19154
+ ],
19155
+ "keywords": [
19156
+ "divider",
19157
+ "statement",
19158
+ "rhetorical question",
19159
+ "transition",
19160
+ "editorial",
19161
+ "separator"
19162
+ ],
19163
+ "useCases": [
19164
+ "section transition",
19165
+ "rhetorical question",
19166
+ "chapter break",
19167
+ "summary statement"
19168
+ ]
19169
+ },
19170
+ "frameworks": {
19171
+ "html": true,
19172
+ "astro": true,
19173
+ "webComponent": false
19174
+ },
19175
+ "tokens": {
19176
+ "color": "neutral",
19177
+ "radius": "none",
19178
+ "shadow": "none",
19179
+ "spacing": "section-default",
19180
+ "typography": "marketing-default"
19181
+ },
19182
+ "capabilities": {
19183
+ "responsive": true,
19184
+ "darkMode": true,
19185
+ "animated": false,
19186
+ "interactive": false,
19187
+ "dependencies": [],
19188
+ "animationPreset": "none"
19189
+ },
19190
+ "slots": [
19191
+ {
19192
+ "name": "statement",
19193
+ "required": true,
19194
+ "description": "Centered line of text, optionally with one emphasized word or phrase."
19195
+ }
19196
+ ],
19197
+ "props": [],
19198
+ "files": {
19199
+ "html": "./statement.html",
19200
+ "css": null,
19201
+ "js": null
19202
+ },
19203
+ "install": {
19204
+ "copyPasteReady": true,
19205
+ "ssrSafe": true,
19206
+ "tailwindOnly": true,
19207
+ "notes": [
19208
+ "Works best between larger section blocks with enough vertical rhythm."
19209
+ ]
19210
+ },
19211
+ "ai": {
19212
+ "prompts": [
19213
+ "Insert a centered statement divider between sections.",
19214
+ "Add a rhetorical transition with subtle borders above and below."
19215
+ ],
19216
+ "compositionRole": "supporting"
19217
+ },
19218
+ "governance": {
19219
+ "status": "published",
19220
+ "quality": "stable",
19221
+ "owner": "design-system",
19222
+ "updatedAt": "2026-03-21"
19223
+ },
19224
+ "html": "<section class=\"ws-divider py-16\">\n <div class=\"mx-auto max-w-4xl px-6\">\n <div class=\"border-y border-[var(--ws-divider-color)] py-10 text-center\">\n <p class=\"mx-auto max-w-2xl text-2xl font-light tracking-tight text-[var(--ws-divider-text)] sm:text-3xl\">\n What matters is not more surface area, but a <span class=\"font-semibold text-[var(--ws-divider-accent)]\">clearer signal</span>.\n </p>\n </div>\n </div>\n</section>\n",
19225
+ "css": null,
19226
+ "js": null
19227
+ },
17444
19228
  {
17445
19229
  "id": "divider/with-icon",
17446
19230
  "title": "Divider with Icon",
@@ -36834,6 +38618,112 @@
36834
38618
  "css": null,
36835
38619
  "js": null
36836
38620
  },
38621
+ {
38622
+ "id": "steps/sequential",
38623
+ "title": "Steps Sequential",
38624
+ "summary": "Horizontal step section with sequential reveal timing and a gradient progress line, built for process or onboarding flows where items should enter one after another.",
38625
+ "family": "steps",
38626
+ "kind": "section",
38627
+ "tier": "enhanced",
38628
+ "extends": "steps/horizontal",
38629
+ "tags": [
38630
+ "steps",
38631
+ "sequential",
38632
+ "process",
38633
+ "onboarding",
38634
+ "progress",
38635
+ "timeline"
38636
+ ],
38637
+ "search": {
38638
+ "intent": [
38639
+ "sequential process steps section",
38640
+ "onboarding steps with progress line"
38641
+ ],
38642
+ "keywords": [
38643
+ "steps",
38644
+ "sequential",
38645
+ "process",
38646
+ "onboarding",
38647
+ "progress",
38648
+ "timeline",
38649
+ "stagger"
38650
+ ],
38651
+ "useCases": [
38652
+ "how it works",
38653
+ "onboarding sequence",
38654
+ "process explainer",
38655
+ "horizontal timeline"
38656
+ ]
38657
+ },
38658
+ "frameworks": {
38659
+ "html": true,
38660
+ "astro": true,
38661
+ "webComponent": false
38662
+ },
38663
+ "tokens": {
38664
+ "color": "neutral",
38665
+ "radius": "2xl",
38666
+ "shadow": "md",
38667
+ "spacing": "section-default",
38668
+ "typography": "marketing-default"
38669
+ },
38670
+ "capabilities": {
38671
+ "responsive": true,
38672
+ "darkMode": true,
38673
+ "animated": true,
38674
+ "interactive": false,
38675
+ "dependencies": [],
38676
+ "animationPreset": "stagger-children"
38677
+ },
38678
+ "slots": [
38679
+ {
38680
+ "name": "heading",
38681
+ "required": true,
38682
+ "description": "Section title and supporting copy."
38683
+ },
38684
+ {
38685
+ "name": "progress",
38686
+ "required": true,
38687
+ "description": "Gradient progress line showing current rollout stage."
38688
+ },
38689
+ {
38690
+ "name": "steps",
38691
+ "required": true,
38692
+ "description": "Sequentially revealed step cards with timing offsets."
38693
+ }
38694
+ ],
38695
+ "props": [],
38696
+ "files": {
38697
+ "html": "./sequential.html",
38698
+ "css": null,
38699
+ "js": null
38700
+ },
38701
+ "install": {
38702
+ "copyPasteReady": true,
38703
+ "ssrSafe": true,
38704
+ "tailwindOnly": true,
38705
+ "notes": [
38706
+ "The demo ships with the section already visible so the sequence plays immediately.",
38707
+ "To trigger on viewport entry, add the visibility class with your own observer when integrating."
38708
+ ]
38709
+ },
38710
+ "ai": {
38711
+ "prompts": [
38712
+ "Add a sequential steps section with a gradient progress line.",
38713
+ "Create a process section where cards reveal one after another."
38714
+ ],
38715
+ "compositionRole": "supporting"
38716
+ },
38717
+ "governance": {
38718
+ "status": "published",
38719
+ "quality": "stable",
38720
+ "owner": "design-system",
38721
+ "updatedAt": "2026-03-21"
38722
+ },
38723
+ "html": "<section class=\"ws-steps bg-[var(--ws-steps-bg)] py-20\">\n <style>\n .ws-steps-sequential {\n --step-delay: 220ms;\n --step-duration: 0.55s;\n --step-offset: 18px;\n --progress-from: oklch(0.68 0.22 28);\n --progress-via: oklch(0.79 0.2 85);\n --progress-to: oklch(0.73 0.18 150);\n --progress-width: 74%;\n }\n\n .ws-steps-sequential .ws-step-card {\n opacity: 0;\n transform: translateY(var(--step-offset)) scale(0.985);\n }\n\n .ws-steps-sequential.is-visible .ws-step-card {\n animation: ws-step-in var(--step-duration) cubic-bezier(0.22, 1, 0.36, 1) forwards;\n }\n\n .ws-steps-sequential.is-visible .ws-step-card:nth-child(2) { animation-delay: var(--step-delay); }\n .ws-steps-sequential.is-visible .ws-step-card:nth-child(3) { animation-delay: calc(var(--step-delay) * 2); }\n .ws-steps-sequential.is-visible .ws-step-card:nth-child(4) { animation-delay: calc(var(--step-delay) * 3); }\n\n .ws-steps-sequential .ws-progress-line {\n position: relative;\n height: 0.4rem;\n width: 100%;\n overflow: hidden;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--ws-steps-line) 70%, transparent);\n }\n\n .ws-steps-sequential .ws-progress-line::after {\n content: \"\";\n position: absolute;\n inset: 0 auto 0 0;\n width: var(--progress-width);\n border-radius: inherit;\n background: linear-gradient(90deg, var(--progress-from), var(--progress-via), var(--progress-to));\n box-shadow: 0 0 18px color-mix(in oklch, var(--progress-via) 30%, transparent);\n }\n\n @keyframes ws-step-in {\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .ws-steps-sequential .ws-step-card,\n .ws-steps-sequential.is-visible .ws-step-card {\n opacity: 1;\n transform: none;\n animation: none;\n }\n }\n </style>\n\n <div class=\"ws-steps-sequential is-visible mx-auto max-w-6xl px-6\">\n <div class=\"mx-auto max-w-2xl text-center\">\n <p class=\"text-sm font-semibold uppercase tracking-[0.2em] text-[var(--ws-steps-accent)]\">Process</p>\n <h2 class=\"mt-4 text-3xl font-bold tracking-tight text-[var(--ws-steps-text)] sm:text-4xl\">Roll out in clear phases</h2>\n <p class=\"mt-4 text-lg text-[var(--ws-steps-text-soft)]\">Instead of revealing every card at once, this section guides attention from left to right with fixed pauses.</p>\n </div>\n\n <div class=\"mx-auto mt-10 max-w-4xl\">\n <div class=\"flex items-center justify-between text-[0.72rem] font-semibold uppercase tracking-[0.16em] text-[var(--ws-steps-text-soft)]\">\n <span>Briefing</span>\n <span>Launch</span>\n </div>\n <div class=\"ws-progress-line mt-3\"></div>\n </div>\n\n <div class=\"mt-12 grid gap-5 lg:grid-cols-4\">\n <article class=\"ws-step-card rounded-2xl border border-[var(--ws-steps-line)] bg-[var(--ws-steps-bg)] p-6 shadow-sm\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.18em] text-[var(--ws-steps-text-soft)]\">01</span>\n <h3 class=\"mt-4 text-lg font-semibold text-[var(--ws-steps-text)]\">Frame the scope</h3>\n <p class=\"mt-3 text-sm leading-6 text-[var(--ws-steps-text-soft)]\">Align on the essentials first, so the sequence starts with a clear decision boundary.</p>\n </article>\n\n <article class=\"ws-step-card rounded-2xl border border-[var(--ws-steps-line)] bg-[var(--ws-steps-bg)] p-6 shadow-sm\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.18em] text-[var(--ws-steps-text-soft)]\">02</span>\n <h3 class=\"mt-4 text-lg font-semibold text-[var(--ws-steps-text)]\">Build the flow</h3>\n <p class=\"mt-3 text-sm leading-6 text-[var(--ws-steps-text-soft)]\">Turn the structure into a usable sequence instead of a flat list of equally loud steps.</p>\n </article>\n\n <article class=\"ws-step-card rounded-2xl border border-[var(--ws-steps-line)] bg-[var(--ws-steps-bg)] p-6 shadow-sm\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.18em] text-[var(--ws-steps-text-soft)]\">03</span>\n <h3 class=\"mt-4 text-lg font-semibold text-[var(--ws-steps-text)]\">Refine the cues</h3>\n <p class=\"mt-3 text-sm leading-6 text-[var(--ws-steps-text-soft)]\">Use the progress line and the staged reveal to make the reading order feel obvious.</p>\n </article>\n\n <article class=\"ws-step-card rounded-2xl border border-[var(--ws-steps-line)] bg-[var(--ws-steps-bg)] p-6 shadow-sm\">\n <span class=\"text-xs font-semibold uppercase tracking-[0.18em] text-[var(--ws-steps-text-soft)]\">04</span>\n <h3 class=\"mt-4 text-lg font-semibold text-[var(--ws-steps-text)]\">Ship the section</h3>\n <p class=\"mt-3 text-sm leading-6 text-[var(--ws-steps-text-soft)]\">Keep the interaction small, readable and easy to wire to a single viewport trigger.</p>\n </article>\n </div>\n </div>\n</section>\n",
38724
+ "css": null,
38725
+ "js": null
38726
+ },
36837
38727
  {
36838
38728
  "id": "steps/timeline",
36839
38729
  "title": "Timeline",
@@ -40822,7 +42712,7 @@
40822
42712
  "owner": "design-system",
40823
42713
  "updatedAt": "2026-03-21"
40824
42714
  },
40825
- "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>The Verge Weekly — Tech, Design &amp; Culture</title>\n <meta name=\"description\" content=\"Magazine-style blog with featured articles, category navigation, and newsletter signup.\" />\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap\" rel=\"stylesheet\" />\n <style>\n body { font-family: 'Inter', sans-serif; }\n </style>\n</head>\n<body class=\"bg-white text-gray-900 antialiased\">\n\n <!-- Navbar -->\n <nav class=\"sticky top-0 z-50 bg-white/90 backdrop-blur-lg border-b border-gray-100\" aria-label=\"Main navigation\">\n <div class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between h-16\">\n <a href=\"#\" class=\"text-xl font-extrabold text-gray-900\">The Verge Weekly</a>\n <div class=\"hidden md:flex items-center gap-6 text-sm font-medium text-gray-600\">\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Technology</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Design</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Culture</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Startups</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Opinion</a>\n </div>\n <div class=\"flex items-center gap-3\">\n <button class=\"p-2 text-gray-400 hover:text-gray-600 rounded-lg\" aria-label=\"Search\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path stroke-linecap=\"round\" d=\"M21 21l-4.35-4.35\"/></svg>\n </button>\n <a href=\"#\" class=\"hidden sm:block text-sm font-semibold px-4 py-2 rounded-lg bg-gray-900 text-white hover:bg-gray-800\">Subscribe</a>\n </div>\n </div>\n </nav>\n\n <main class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10\">\n\n <!-- Featured Article Hero -->\n <section class=\"mb-12\">\n <a href=\"#\" class=\"group block relative rounded-2xl overflow-hidden bg-gray-100 aspect-[2/1] md:aspect-[3/1]\">\n <div class=\"absolute inset-0 bg-gradient-to-t from-gray-900/80 via-gray-900/30 to-transparent\"></div>\n <img src=\"https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1200&h=500&fit=crop\" alt=\"Featured article cover\" class=\"w-full h-full object-cover\" />\n <div class=\"absolute bottom-0 left-0 right-0 p-6 md:p-10\">\n <span class=\"inline-block px-2.5 py-0.5 text-xs font-semibold bg-indigo-600 text-white rounded-full mb-3\">Technology</span>\n <h2 class=\"text-2xl md:text-4xl font-bold text-white leading-tight group-hover:underline decoration-2 underline-offset-4\">The Future of Computing: How Quantum Will Change Everything</h2>\n <p class=\"mt-2 text-sm md:text-base text-gray-300 max-w-2xl\">From drug discovery to cryptography, quantum computing promises to solve problems that classical computers never could. Here's what you need to know.</p>\n <div class=\"mt-4 flex items-center gap-3 text-sm text-gray-400\">\n <span>By Sarah Mitchell</span>\n <span>&middot;</span>\n <span>March 21, 2026</span>\n <span>&middot;</span>\n <span>12 min read</span>\n </div>\n </div>\n </a>\n </section>\n\n <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-10\">\n\n <!-- Article Grid -->\n <div class=\"lg:col-span-2\">\n <h3 class=\"text-lg font-bold text-gray-900 mb-6\">Latest Stories</h3>\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-6\">\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1555949963-aa79dcee981c?w=400&h=300&fit=crop\" alt=\"Article cover\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <span class=\"text-xs font-semibold text-indigo-600\">Design</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Why Every Designer Should Learn to Code in 2026</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">The line between design and development continues to blur. Here's why crossing it will make you irreplaceable.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 20 &middot; 6 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=400&h=300&fit=crop\" alt=\"Article cover\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <span class=\"text-xs font-semibold text-emerald-600\">Startups</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">The Rise of AI-Native Startups: What VCs Are Betting On</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">Venture capital is pouring billions into AI-first companies. We mapped the biggest bets of Q1 2026.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 19 &middot; 8 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1558618666-fcd25c85f82e?w=400&h=300&fit=crop\" alt=\"Article cover\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <span class=\"text-xs font-semibold text-amber-600\">Culture</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Digital Minimalism: Reclaiming Focus in an Age of Distraction</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">A growing movement of professionals are deliberately reducing their digital footprint. Here's what they've learned.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 18 &middot; 5 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=400&h=300&fit=crop\" alt=\"Article cover\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <span class=\"text-xs font-semibold text-indigo-600\">Technology</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Web Components in 2026: The Standard That Finally Won</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">After years of framework dominance, native Web Components are seeing real adoption. Here's what changed.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 17 &middot; 7 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1504384308090-c894fdcc538d?w=400&h=300&fit=crop\" alt=\"Article cover\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <span class=\"text-xs font-semibold text-rose-600\">Opinion</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Why Remote Work Isn't Going Away (Despite What CEOs Say)</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">The data is clear: return-to-office mandates are backfiring. Here's the evidence corporate leaders are ignoring.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 16 &middot; 9 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?w=400&h=300&fit=crop\" alt=\"Article cover\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <span class=\"text-xs font-semibold text-emerald-600\">Startups</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Open Source in the AI Era: New Business Models Emerge</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">The traditional open-core model is evolving. We explore how AI companies are building sustainable businesses around open code.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 15 &middot; 10 min read</p>\n </a>\n </article>\n\n </div>\n </div>\n\n <!-- Sidebar -->\n <aside class=\"space-y-8\">\n <!-- Categories -->\n <div class=\"bg-gray-50 rounded-2xl p-6\">\n <h3 class=\"text-sm font-bold text-gray-900 uppercase tracking-wider mb-4\">Categories</h3>\n <div class=\"space-y-2\">\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Technology</span><span class=\"text-xs text-gray-400\">42</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Design</span><span class=\"text-xs text-gray-400\">28</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Culture</span><span class=\"text-xs text-gray-400\">19</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Startups</span><span class=\"text-xs text-gray-400\">35</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Opinion</span><span class=\"text-xs text-gray-400\">14</span>\n </a>\n </div>\n </div>\n\n <!-- Newsletter -->\n <div class=\"bg-indigo-50 rounded-2xl p-6\">\n <h3 class=\"text-sm font-bold text-gray-900 uppercase tracking-wider mb-2\">Newsletter</h3>\n <p class=\"text-sm text-gray-600 mb-4\">Get the best stories delivered to your inbox every week.</p>\n <form class=\"space-y-3\">\n <input type=\"email\" placeholder=\"your@email.com\" class=\"w-full px-4 py-2.5 text-sm border border-indigo-200 rounded-lg bg-white focus:outline-none focus:ring-2 focus:ring-indigo-500\" />\n <button type=\"submit\" class=\"w-full px-4 py-2.5 text-sm font-semibold bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors\">Subscribe</button>\n </form>\n <p class=\"mt-3 text-xs text-gray-500\">No spam. Unsubscribe anytime.</p>\n </div>\n\n <!-- Trending -->\n <div>\n <h3 class=\"text-sm font-bold text-gray-900 uppercase tracking-wider mb-4\">Trending</h3>\n <div class=\"space-y-4\">\n <a href=\"#\" class=\"flex items-start gap-3 group\">\n <span class=\"text-2xl font-bold text-gray-200 group-hover:text-indigo-300 transition-colors\">01</span>\n <div>\n <p class=\"text-sm font-medium text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Apple's Vision Pro 2 Changes Everything About Spatial Computing</p>\n <p class=\"text-xs text-gray-400 mt-1\">Mar 20 &middot; 5 min</p>\n </div>\n </a>\n <a href=\"#\" class=\"flex items-start gap-3 group\">\n <span class=\"text-2xl font-bold text-gray-200 group-hover:text-indigo-300 transition-colors\">02</span>\n <div>\n <p class=\"text-sm font-medium text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">The CSS Revolution: What Tailwind v4 Means for Developers</p>\n <p class=\"text-xs text-gray-400 mt-1\">Mar 19 &middot; 7 min</p>\n </div>\n </a>\n <a href=\"#\" class=\"flex items-start gap-3 group\">\n <span class=\"text-2xl font-bold text-gray-200 group-hover:text-indigo-300 transition-colors\">03</span>\n <div>\n <p class=\"text-sm font-medium text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">GitHub Copilot Workspace: Coding Without Writing Code</p>\n <p class=\"text-xs text-gray-400 mt-1\">Mar 18 &middot; 4 min</p>\n </div>\n </a>\n </div>\n </div>\n </aside>\n\n </div>\n </main>\n\n <!-- Footer -->\n <footer class=\"border-t border-gray-200 mt-16\">\n <div class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12\">\n <div class=\"flex flex-col md:flex-row md:items-center md:justify-between gap-6\">\n <p class=\"text-sm font-bold text-gray-900\">The Verge Weekly</p>\n <div class=\"flex flex-wrap gap-6 text-sm text-gray-500\">\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">About</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Advertise</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Careers</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Privacy</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">RSS</a>\n </div>\n </div>\n <p class=\"mt-6 text-xs text-gray-400\">&copy; 2026 The Verge Weekly. All rights reserved.</p>\n </div>\n </footer>\n\n</body>\n</html>\n"
42715
+ "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>The Verge Weekly — Tech, Design &amp; Culture</title>\n <meta name=\"description\" content=\"Magazine-style blog with featured articles, category navigation, and newsletter signup.\" />\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap\" rel=\"stylesheet\" />\n <style>\n body { font-family: 'Inter', sans-serif; }\n </style>\n</head>\n<body class=\"bg-white text-gray-900 antialiased\">\n\n <!-- Navbar -->\n <nav class=\"sticky top-0 z-50 bg-white/90 backdrop-blur-lg border-b border-gray-100\" aria-label=\"Main navigation\">\n <div class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between h-16\">\n <a href=\"#\" class=\"text-xl font-extrabold text-gray-900\">The Verge Weekly</a>\n <div class=\"hidden md:flex items-center gap-6 text-sm font-medium text-gray-600\">\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Technology</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Design</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Culture</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Startups</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Opinion</a>\n </div>\n <div class=\"flex items-center gap-3\">\n <button class=\"p-2 text-gray-400 hover:text-gray-600 rounded-lg\" aria-label=\"Search\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path stroke-linecap=\"round\" d=\"M21 21l-4.35-4.35\"/></svg>\n </button>\n <a href=\"#\" class=\"hidden sm:block text-sm font-semibold px-4 py-2 rounded-lg bg-gray-900 text-white hover:bg-gray-800\">Subscribe</a>\n </div>\n </div>\n </nav>\n\n <main class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10\">\n\n <!-- Featured Article Hero -->\n <section class=\"mb-12\">\n <a href=\"#\" class=\"group block relative rounded-2xl overflow-hidden bg-gray-100 aspect-[2/1] md:aspect-[3/1]\">\n <div class=\"absolute inset-0 bg-gradient-to-br from-indigo-600 via-violet-500 to-purple-700\"></div>\n <div class=\"absolute inset-0 bg-gradient-to-t from-gray-900/80 via-gray-900/30 to-transparent\"></div>\n <div class=\"absolute bottom-0 left-0 right-0 p-6 md:p-10\">\n <span class=\"inline-block px-2.5 py-0.5 text-xs font-semibold bg-indigo-600 text-white rounded-full mb-3\">Technology</span>\n <h2 class=\"text-2xl md:text-4xl font-bold text-white leading-tight group-hover:underline decoration-2 underline-offset-4\">The Future of Computing: How Quantum Will Change Everything</h2>\n <p class=\"mt-2 text-sm md:text-base text-gray-300 max-w-2xl\">From drug discovery to cryptography, quantum computing promises to solve problems that classical computers never could. Here's what you need to know.</p>\n <div class=\"mt-4 flex items-center gap-3 text-sm text-gray-400\">\n <span>By Sarah Mitchell</span>\n <span>&middot;</span>\n <span>March 21, 2026</span>\n <span>&middot;</span>\n <span>12 min read</span>\n </div>\n </div>\n </a>\n </section>\n\n <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-10\">\n\n <!-- Article Grid -->\n <div class=\"lg:col-span-2\">\n <h3 class=\"text-lg font-bold text-gray-900 mb-6\">Latest Stories</h3>\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-6\">\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-indigo-400 to-blue-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.53 16.122a3 3 0 0 0-5.78 1.128 2.25 2.25 0 0 1-2.4 2.245 4.5 4.5 0 0 0 8.4-2.245c0-.399-.078-.78-.22-1.128Zm0 0a15.998 15.998 0 0 0 3.388-1.62m-5.043-.025a15.994 15.994 0 0 1 1.622-3.395m3.42 3.42a15.995 15.995 0 0 0 4.764-4.648l3.876-5.814a1.151 1.151 0 0 0-1.597-1.597L14.146 6.32a15.996 15.996 0 0 0-4.649 4.763m3.42 3.42a6.776 6.776 0 0 0-3.42-3.42\" /></svg>\n </div>\n <span class=\"text-xs font-semibold text-indigo-600\">Design</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Why Every Designer Should Learn to Code in 2026</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">The line between design and development continues to blur. Here's why crossing it will make you irreplaceable.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 20 &middot; 6 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-emerald-400 to-teal-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z\" /></svg>\n </div>\n <span class=\"text-xs font-semibold text-emerald-600\">Startups</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">The Rise of AI-Native Startups: What VCs Are Betting On</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">Venture capital is pouring billions into AI-first companies. We mapped the biggest bets of Q1 2026.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 19 &middot; 8 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-amber-400 to-orange-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25\" /></svg>\n </div>\n <span class=\"text-xs font-semibold text-amber-600\">Culture</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Digital Minimalism: Reclaiming Focus in an Age of Distraction</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">A growing movement of professionals are deliberately reducing their digital footprint. Here's what they've learned.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 18 &middot; 5 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-violet-400 to-purple-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5\" /></svg>\n </div>\n <span class=\"text-xs font-semibold text-indigo-600\">Technology</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Web Components in 2026: The Standard That Finally Won</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">After years of framework dominance, native Web Components are seeing real adoption. Here's what changed.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 17 &middot; 7 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-rose-400 to-red-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z\" /></svg>\n </div>\n <span class=\"text-xs font-semibold text-rose-600\">Opinion</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Why Remote Work Isn't Going Away (Despite What CEOs Say)</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">The data is clear: return-to-office mandates are backfiring. Here's the evidence corporate leaders are ignoring.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 16 &middot; 9 min read</p>\n </a>\n </article>\n\n <article class=\"group\">\n <a href=\"#\" class=\"block\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-cyan-400 to-blue-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125\" /></svg>\n </div>\n <span class=\"text-xs font-semibold text-emerald-600\">Startups</span>\n <h4 class=\"mt-1 text-base font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Open Source in the AI Era: New Business Models Emerge</h4>\n <p class=\"mt-1 text-sm text-gray-500 line-clamp-2\">The traditional open-core model is evolving. We explore how AI companies are building sustainable businesses around open code.</p>\n <p class=\"mt-2 text-xs text-gray-400\">Mar 15 &middot; 10 min read</p>\n </a>\n </article>\n\n </div>\n </div>\n\n <!-- Sidebar -->\n <aside class=\"space-y-8\">\n <!-- Categories -->\n <div class=\"bg-gray-50 rounded-2xl p-6\">\n <h3 class=\"text-sm font-bold text-gray-900 uppercase tracking-wider mb-4\">Categories</h3>\n <div class=\"space-y-2\">\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Technology</span><span class=\"text-xs text-gray-400\">42</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Design</span><span class=\"text-xs text-gray-400\">28</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Culture</span><span class=\"text-xs text-gray-400\">19</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Startups</span><span class=\"text-xs text-gray-400\">35</span>\n </a>\n <a href=\"#\" class=\"flex items-center justify-between py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors\">\n <span>Opinion</span><span class=\"text-xs text-gray-400\">14</span>\n </a>\n </div>\n </div>\n\n <!-- Newsletter -->\n <div class=\"bg-indigo-50 rounded-2xl p-6\">\n <h3 class=\"text-sm font-bold text-gray-900 uppercase tracking-wider mb-2\">Newsletter</h3>\n <p class=\"text-sm text-gray-600 mb-4\">Get the best stories delivered to your inbox every week.</p>\n <form class=\"space-y-3\">\n <input type=\"email\" placeholder=\"your@email.com\" class=\"w-full px-4 py-2.5 text-sm border border-indigo-200 rounded-lg bg-white focus:outline-none focus:ring-2 focus:ring-indigo-500\" />\n <button type=\"submit\" class=\"w-full px-4 py-2.5 text-sm font-semibold bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors\">Subscribe</button>\n </form>\n <p class=\"mt-3 text-xs text-gray-500\">No spam. Unsubscribe anytime.</p>\n </div>\n\n <!-- Trending -->\n <div>\n <h3 class=\"text-sm font-bold text-gray-900 uppercase tracking-wider mb-4\">Trending</h3>\n <div class=\"space-y-4\">\n <a href=\"#\" class=\"flex items-start gap-3 group\">\n <span class=\"text-2xl font-bold text-gray-200 group-hover:text-indigo-300 transition-colors\">01</span>\n <div>\n <p class=\"text-sm font-medium text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">Apple's Vision Pro 2 Changes Everything About Spatial Computing</p>\n <p class=\"text-xs text-gray-400 mt-1\">Mar 20 &middot; 5 min</p>\n </div>\n </a>\n <a href=\"#\" class=\"flex items-start gap-3 group\">\n <span class=\"text-2xl font-bold text-gray-200 group-hover:text-indigo-300 transition-colors\">02</span>\n <div>\n <p class=\"text-sm font-medium text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">The CSS Revolution: What Tailwind v4 Means for Developers</p>\n <p class=\"text-xs text-gray-400 mt-1\">Mar 19 &middot; 7 min</p>\n </div>\n </a>\n <a href=\"#\" class=\"flex items-start gap-3 group\">\n <span class=\"text-2xl font-bold text-gray-200 group-hover:text-indigo-300 transition-colors\">03</span>\n <div>\n <p class=\"text-sm font-medium text-gray-900 group-hover:text-indigo-600 transition-colors leading-snug\">GitHub Copilot Workspace: Coding Without Writing Code</p>\n <p class=\"text-xs text-gray-400 mt-1\">Mar 18 &middot; 4 min</p>\n </div>\n </a>\n </div>\n </div>\n </aside>\n\n </div>\n </main>\n\n <!-- Footer -->\n <footer class=\"border-t border-gray-200 mt-16\">\n <div class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12\">\n <div class=\"flex flex-col md:flex-row md:items-center md:justify-between gap-6\">\n <p class=\"text-sm font-bold text-gray-900\">The Verge Weekly</p>\n <div class=\"flex flex-wrap gap-6 text-sm text-gray-500\">\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">About</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Advertise</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Careers</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Privacy</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">RSS</a>\n </div>\n </div>\n <p class=\"mt-6 text-xs text-gray-400\">&copy; 2026 The Verge Weekly. All rights reserved.</p>\n </div>\n </footer>\n\n</body>\n</html>\n"
40826
42716
  },
40827
42717
  {
40828
42718
  "id": "blog/minimal",
@@ -40929,7 +42819,7 @@
40929
42819
  "owner": "design-system",
40930
42820
  "updatedAt": "2026-03-21"
40931
42821
  },
40932
- "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>The Architecture of Modern Web Applications — Insight Journal</title>\n <meta name=\"description\" content=\"A deep dive into the architecture patterns shaping modern web development in 2026.\" />\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap\" rel=\"stylesheet\" />\n <style>\n body { font-family: 'Inter', sans-serif; }\n .prose h2 { margin-top: 2.5rem; margin-bottom: 1rem; font-size: 1.5rem; font-weight: 700; color: #111827; }\n .prose h3 { margin-top: 2rem; margin-bottom: 0.75rem; font-size: 1.25rem; font-weight: 600; color: #111827; }\n .prose p { margin-bottom: 1.25rem; line-height: 1.8; color: #4b5563; }\n .prose ul { list-style-type: disc; padding-left: 1.5rem; margin-bottom: 1.25rem; color: #4b5563; }\n .prose ul li { margin-bottom: 0.5rem; line-height: 1.7; }\n .prose blockquote { border-left: 3px solid #6366f1; padding-left: 1.25rem; margin: 2rem 0; font-style: italic; color: #6b7280; }\n .prose code { background: #f3f4f6; padding: 0.15rem 0.4rem; border-radius: 0.25rem; font-size: 0.875rem; color: #1f2937; }\n .prose pre { background: #1f2937; color: #e5e7eb; padding: 1.25rem; border-radius: 0.75rem; overflow-x: auto; margin: 1.5rem 0; font-size: 0.875rem; line-height: 1.6; }\n .prose pre code { background: transparent; padding: 0; color: inherit; }\n </style>\n</head>\n<body class=\"bg-white text-gray-900 antialiased\">\n\n <!-- Header -->\n <header class=\"sticky top-0 z-50 bg-white/90 backdrop-blur-lg border-b border-gray-100\">\n <div class=\"max-w-4xl mx-auto px-4 sm:px-6 flex items-center justify-between h-14\">\n <a href=\"#\" class=\"text-base font-bold text-gray-900\">Insight Journal</a>\n <nav class=\"flex items-center gap-6 text-sm font-medium text-gray-500\" aria-label=\"Main navigation\">\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Blog</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">About</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Subscribe</a>\n </nav>\n </div>\n </header>\n\n <main class=\"max-w-3xl mx-auto px-4 sm:px-6\">\n\n <!-- Hero Image -->\n <div class=\"mt-10 rounded-2xl overflow-hidden bg-gray-100 aspect-[2/1]\">\n <img src=\"https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=900&h=450&fit=crop\" alt=\"Code on a laptop screen\" class=\"w-full h-full object-cover\" />\n </div>\n\n <!-- Article Header -->\n <div class=\"mt-8 mb-10\">\n <span class=\"inline-block px-2.5 py-0.5 text-xs font-semibold text-indigo-600 bg-indigo-50 rounded-full\">Architecture</span>\n <h1 class=\"mt-4 text-3xl sm:text-4xl font-extrabold text-gray-900 leading-tight\">The Architecture of Modern Web Applications</h1>\n <p class=\"mt-4 text-lg text-gray-500\">A deep dive into the patterns, trade-offs, and frameworks shaping how we build for the web in 2026.</p>\n <div class=\"mt-6 flex items-center gap-4\">\n <div class=\"w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center text-sm font-bold text-indigo-700\">DH</div>\n <div>\n <p class=\"text-sm font-medium text-gray-900\">Daniel Harper</p>\n <p class=\"text-xs text-gray-500\">March 21, 2026 &middot; 14 min read</p>\n </div>\n </div>\n </div>\n\n <!-- Article Body -->\n <article class=\"prose max-w-none\">\n\n <p>The web platform has evolved dramatically over the past few years. What was once a simple document delivery system has become the foundation for complex, interactive applications that rival native software. But with this power comes architectural complexity.</p>\n\n <h2>The Shift to Server-First</h2>\n\n <p>The pendulum has swung. After a decade of client-side rendering dominance, the industry is rediscovering the power of the server. Frameworks like Astro, Next.js, and SvelteKit have made server-side rendering the default, not an afterthought.</p>\n\n <p>This isn't your grandfather's server rendering, though. Modern SSR is paired with selective hydration, islands architecture, and edge computing to deliver the best of both worlds: fast initial loads and rich interactivity where it matters.</p>\n\n <blockquote>\n \"The best architecture is one where you only pay for the interactivity you actually need.\" — Ryan Carniato, SolidJS creator\n </blockquote>\n\n <h2>Islands Architecture</h2>\n\n <p>The islands architecture pattern, popularized by Astro, treats interactive components as isolated \"islands\" in a sea of static HTML. Each island hydrates independently, meaning the majority of your page ships zero JavaScript.</p>\n\n <ul>\n <li><strong>Static by default</strong> — HTML is rendered at build time with zero JS overhead</li>\n <li><strong>Interactive on demand</strong> — Only interactive components ship client-side JavaScript</li>\n <li><strong>Framework agnostic</strong> — Mix React, Svelte, and Vue on the same page</li>\n <li><strong>Progressive enhancement</strong> — Pages work before JavaScript loads</li>\n </ul>\n\n <h3>A Practical Example</h3>\n\n <p>Consider a typical marketing page. The hero, features section, and footer are entirely static. Only the pricing calculator and contact form need interactivity. With islands, you ship JavaScript only for those two components.</p>\n\n <pre><code>&lt;!-- Static Astro page with interactive islands --&gt;\n&lt;Layout&gt;\n &lt;Hero /&gt; &lt;!-- Zero JS --&gt;\n &lt;Features /&gt; &lt;!-- Zero JS --&gt;\n &lt;Calculator client:visible /&gt; &lt;!-- Hydrates when visible --&gt;\n &lt;ContactForm client:idle /&gt; &lt;!-- Hydrates when idle --&gt;\n &lt;Footer /&gt; &lt;!-- Zero JS --&gt;\n&lt;/Layout&gt;</code></pre>\n\n <h2>The Edge Changes Everything</h2>\n\n <p>Edge computing has shifted the conversation from \"where do we render?\" to \"how close can we render?\" With platforms like Cloudflare Workers and Deno Deploy, your server-side code runs in data centers worldwide, often within 50ms of the user.</p>\n\n <p>This means server-rendered pages can be as fast as statically served files, while remaining fully dynamic. Personalization, A/B testing, and geo-specific content no longer require client-side JavaScript or complex CDN configurations.</p>\n\n <h2>Choosing the Right Architecture</h2>\n\n <p>There's no one-size-fits-all answer. The right architecture depends on your use case, team, and performance requirements. But here's a framework for thinking about it:</p>\n\n <ul>\n <li><strong>Content sites</strong> (blogs, docs, marketing) — Static generation with islands</li>\n <li><strong>E-commerce</strong> — Hybrid static + server rendering at the edge</li>\n <li><strong>Dashboards</strong> — SPA with server-side data fetching</li>\n <li><strong>Real-time apps</strong> — WebSocket-powered with minimal SSR</li>\n </ul>\n\n <p>The key insight is that most applications are a mix of these categories. The best frameworks let you make per-page or per-component decisions about rendering strategy.</p>\n\n </article>\n\n <!-- Author Bio -->\n <div class=\"mt-14 mb-10 p-6 bg-gray-50 rounded-2xl flex flex-col sm:flex-row items-start gap-5\">\n <div class=\"w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center text-xl font-bold text-indigo-700 shrink-0\">DH</div>\n <div>\n <h3 class=\"text-base font-semibold text-gray-900\">Daniel Harper</h3>\n <p class=\"text-sm text-gray-500 mt-1\">Staff Engineer at Vercel. Building tools for the modern web. Previously at Stripe and Cloudflare. Writing about architecture, performance, and developer experience.</p>\n <div class=\"mt-3 flex items-center gap-4\">\n <a href=\"#\" class=\"text-sm font-medium text-indigo-600 hover:text-indigo-700 transition-colors\">Twitter</a>\n <a href=\"#\" class=\"text-sm font-medium text-indigo-600 hover:text-indigo-700 transition-colors\">GitHub</a>\n <a href=\"#\" class=\"text-sm font-medium text-indigo-600 hover:text-indigo-700 transition-colors\">Website</a>\n </div>\n </div>\n </div>\n\n <!-- Related Posts -->\n <section class=\"mb-16\">\n <h3 class=\"text-lg font-bold text-gray-900 mb-6\">Related Articles</h3>\n <div class=\"grid grid-cols-1 sm:grid-cols-3 gap-6\">\n <a href=\"#\" class=\"group\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1555949963-aa79dcee981c?w=300&h=225&fit=crop\" alt=\"Related article\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <h4 class=\"text-sm font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors\">Understanding Hydration: A Visual Guide</h4>\n <p class=\"mt-1 text-xs text-gray-400\">Mar 15 &middot; 8 min</p>\n </a>\n <a href=\"#\" class=\"group\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=300&h=225&fit=crop\" alt=\"Related article\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <h4 class=\"text-sm font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors\">Edge Computing for Frontend Developers</h4>\n <p class=\"mt-1 text-xs text-gray-400\">Mar 12 &middot; 6 min</p>\n </a>\n <a href=\"#\" class=\"group\">\n <div class=\"rounded-xl overflow-hidden bg-gray-100 aspect-[4/3] mb-3\">\n <img src=\"https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?w=300&h=225&fit=crop\" alt=\"Related article\" class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\" />\n </div>\n <h4 class=\"text-sm font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors\">Astro vs Next.js: Choosing in 2026</h4>\n <p class=\"mt-1 text-xs text-gray-400\">Mar 8 &middot; 10 min</p>\n </a>\n </div>\n </section>\n\n </main>\n\n <!-- Footer -->\n <footer class=\"border-t border-gray-100\">\n <div class=\"max-w-4xl mx-auto px-4 sm:px-6 py-8\">\n <div class=\"flex items-center justify-between\">\n <p class=\"text-sm font-bold text-gray-900\">Insight Journal</p>\n <div class=\"flex items-center gap-4 text-xs text-gray-400\">\n <a href=\"#\" class=\"hover:text-gray-700 transition-colors\">Twitter</a>\n <a href=\"#\" class=\"hover:text-gray-700 transition-colors\">RSS</a>\n <a href=\"#\" class=\"hover:text-gray-700 transition-colors\">Privacy</a>\n </div>\n </div>\n <p class=\"mt-4 text-xs text-gray-400\">&copy; 2026 Insight Journal. All rights reserved.</p>\n </div>\n </footer>\n\n</body>\n</html>\n"
42822
+ "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>The Architecture of Modern Web Applications — Insight Journal</title>\n <meta name=\"description\" content=\"A deep dive into the architecture patterns shaping modern web development in 2026.\" />\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap\" rel=\"stylesheet\" />\n <style>\n body { font-family: 'Inter', sans-serif; }\n .prose h2 { margin-top: 2.5rem; margin-bottom: 1rem; font-size: 1.5rem; font-weight: 700; color: #111827; }\n .prose h3 { margin-top: 2rem; margin-bottom: 0.75rem; font-size: 1.25rem; font-weight: 600; color: #111827; }\n .prose p { margin-bottom: 1.25rem; line-height: 1.8; color: #4b5563; }\n .prose ul { list-style-type: disc; padding-left: 1.5rem; margin-bottom: 1.25rem; color: #4b5563; }\n .prose ul li { margin-bottom: 0.5rem; line-height: 1.7; }\n .prose blockquote { border-left: 3px solid #6366f1; padding-left: 1.25rem; margin: 2rem 0; font-style: italic; color: #6b7280; }\n .prose code { background: #f3f4f6; padding: 0.15rem 0.4rem; border-radius: 0.25rem; font-size: 0.875rem; color: #1f2937; }\n .prose pre { background: #1f2937; color: #e5e7eb; padding: 1.25rem; border-radius: 0.75rem; overflow-x: auto; margin: 1.5rem 0; font-size: 0.875rem; line-height: 1.6; }\n .prose pre code { background: transparent; padding: 0; color: inherit; }\n </style>\n</head>\n<body class=\"bg-white text-gray-900 antialiased\">\n\n <!-- Header -->\n <header class=\"sticky top-0 z-50 bg-white/90 backdrop-blur-lg border-b border-gray-100\">\n <div class=\"max-w-4xl mx-auto px-4 sm:px-6 flex items-center justify-between h-14\">\n <a href=\"#\" class=\"text-base font-bold text-gray-900\">Insight Journal</a>\n <nav class=\"flex items-center gap-6 text-sm font-medium text-gray-500\" aria-label=\"Main navigation\">\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Blog</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">About</a>\n <a href=\"#\" class=\"hover:text-gray-900 transition-colors\">Subscribe</a>\n </nav>\n </div>\n </header>\n\n <main class=\"max-w-3xl mx-auto px-4 sm:px-6\">\n\n <!-- Hero Image -->\n <div class=\"mt-10 rounded-2xl overflow-hidden aspect-[2/1] bg-gradient-to-br from-indigo-500 via-purple-500 to-pink-500 flex items-center justify-center\">\n <svg class=\"w-16 h-16 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5\" /></svg>\n </div>\n\n <!-- Article Header -->\n <div class=\"mt-8 mb-10\">\n <span class=\"inline-block px-2.5 py-0.5 text-xs font-semibold text-indigo-600 bg-indigo-50 rounded-full\">Architecture</span>\n <h1 class=\"mt-4 text-3xl sm:text-4xl font-extrabold text-gray-900 leading-tight\">The Architecture of Modern Web Applications</h1>\n <p class=\"mt-4 text-lg text-gray-500\">A deep dive into the patterns, trade-offs, and frameworks shaping how we build for the web in 2026.</p>\n <div class=\"mt-6 flex items-center gap-4\">\n <div class=\"w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center text-sm font-bold text-indigo-700\">DH</div>\n <div>\n <p class=\"text-sm font-medium text-gray-900\">Daniel Harper</p>\n <p class=\"text-xs text-gray-500\">March 21, 2026 &middot; 14 min read</p>\n </div>\n </div>\n </div>\n\n <!-- Article Body -->\n <article class=\"prose max-w-none\">\n\n <p>The web platform has evolved dramatically over the past few years. What was once a simple document delivery system has become the foundation for complex, interactive applications that rival native software. But with this power comes architectural complexity.</p>\n\n <h2>The Shift to Server-First</h2>\n\n <p>The pendulum has swung. After a decade of client-side rendering dominance, the industry is rediscovering the power of the server. Frameworks like Astro, Next.js, and SvelteKit have made server-side rendering the default, not an afterthought.</p>\n\n <p>This isn't your grandfather's server rendering, though. Modern SSR is paired with selective hydration, islands architecture, and edge computing to deliver the best of both worlds: fast initial loads and rich interactivity where it matters.</p>\n\n <blockquote>\n \"The best architecture is one where you only pay for the interactivity you actually need.\" — Ryan Carniato, SolidJS creator\n </blockquote>\n\n <h2>Islands Architecture</h2>\n\n <p>The islands architecture pattern, popularized by Astro, treats interactive components as isolated \"islands\" in a sea of static HTML. Each island hydrates independently, meaning the majority of your page ships zero JavaScript.</p>\n\n <ul>\n <li><strong>Static by default</strong> — HTML is rendered at build time with zero JS overhead</li>\n <li><strong>Interactive on demand</strong> — Only interactive components ship client-side JavaScript</li>\n <li><strong>Framework agnostic</strong> — Mix React, Svelte, and Vue on the same page</li>\n <li><strong>Progressive enhancement</strong> — Pages work before JavaScript loads</li>\n </ul>\n\n <h3>A Practical Example</h3>\n\n <p>Consider a typical marketing page. The hero, features section, and footer are entirely static. Only the pricing calculator and contact form need interactivity. With islands, you ship JavaScript only for those two components.</p>\n\n <pre><code>&lt;!-- Static Astro page with interactive islands --&gt;\n&lt;Layout&gt;\n &lt;Hero /&gt; &lt;!-- Zero JS --&gt;\n &lt;Features /&gt; &lt;!-- Zero JS --&gt;\n &lt;Calculator client:visible /&gt; &lt;!-- Hydrates when visible --&gt;\n &lt;ContactForm client:idle /&gt; &lt;!-- Hydrates when idle --&gt;\n &lt;Footer /&gt; &lt;!-- Zero JS --&gt;\n&lt;/Layout&gt;</code></pre>\n\n <h2>The Edge Changes Everything</h2>\n\n <p>Edge computing has shifted the conversation from \"where do we render?\" to \"how close can we render?\" With platforms like Cloudflare Workers and Deno Deploy, your server-side code runs in data centers worldwide, often within 50ms of the user.</p>\n\n <p>This means server-rendered pages can be as fast as statically served files, while remaining fully dynamic. Personalization, A/B testing, and geo-specific content no longer require client-side JavaScript or complex CDN configurations.</p>\n\n <h2>Choosing the Right Architecture</h2>\n\n <p>There's no one-size-fits-all answer. The right architecture depends on your use case, team, and performance requirements. But here's a framework for thinking about it:</p>\n\n <ul>\n <li><strong>Content sites</strong> (blogs, docs, marketing) — Static generation with islands</li>\n <li><strong>E-commerce</strong> — Hybrid static + server rendering at the edge</li>\n <li><strong>Dashboards</strong> — SPA with server-side data fetching</li>\n <li><strong>Real-time apps</strong> — WebSocket-powered with minimal SSR</li>\n </ul>\n\n <p>The key insight is that most applications are a mix of these categories. The best frameworks let you make per-page or per-component decisions about rendering strategy.</p>\n\n </article>\n\n <!-- Author Bio -->\n <div class=\"mt-14 mb-10 p-6 bg-gray-50 rounded-2xl flex flex-col sm:flex-row items-start gap-5\">\n <div class=\"w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center text-xl font-bold text-indigo-700 shrink-0\">DH</div>\n <div>\n <h3 class=\"text-base font-semibold text-gray-900\">Daniel Harper</h3>\n <p class=\"text-sm text-gray-500 mt-1\">Staff Engineer at Vercel. Building tools for the modern web. Previously at Stripe and Cloudflare. Writing about architecture, performance, and developer experience.</p>\n <div class=\"mt-3 flex items-center gap-4\">\n <a href=\"#\" class=\"text-sm font-medium text-indigo-600 hover:text-indigo-700 transition-colors\">Twitter</a>\n <a href=\"#\" class=\"text-sm font-medium text-indigo-600 hover:text-indigo-700 transition-colors\">GitHub</a>\n <a href=\"#\" class=\"text-sm font-medium text-indigo-600 hover:text-indigo-700 transition-colors\">Website</a>\n </div>\n </div>\n </div>\n\n <!-- Related Posts -->\n <section class=\"mb-16\">\n <h3 class=\"text-lg font-bold text-gray-900 mb-6\">Related Articles</h3>\n <div class=\"grid grid-cols-1 sm:grid-cols-3 gap-6\">\n <a href=\"#\" class=\"group\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-indigo-400 to-blue-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.75 3.104v5.714a2.25 2.25 0 0 1-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 0 1 4.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0 1 12 15a9.065 9.065 0 0 0-6.23.693L5 14.5m14.8.8 1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0 1 12 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5\" /></svg>\n </div>\n <h4 class=\"text-sm font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors\">Understanding Hydration: A Visual Guide</h4>\n <p class=\"mt-1 text-xs text-gray-400\">Mar 15 &middot; 8 min</p>\n </a>\n <a href=\"#\" class=\"group\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-emerald-400 to-teal-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M2.25 15a4.5 4.5 0 0 0 4.5 4.5H18a3.75 3.75 0 0 0 1.332-7.257 3 3 0 0 0-3.758-3.848 5.25 5.25 0 0 0-10.233 2.33A4.502 4.502 0 0 0 2.25 15Z\" /></svg>\n </div>\n <h4 class=\"text-sm font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors\">Edge Computing for Frontend Developers</h4>\n <p class=\"mt-1 text-xs text-gray-400\">Mar 12 &middot; 6 min</p>\n </a>\n <a href=\"#\" class=\"group\">\n <div class=\"rounded-xl overflow-hidden aspect-[4/3] mb-3 bg-gradient-to-br from-violet-400 to-purple-600 flex items-center justify-center\">\n <svg class=\"w-10 h-10 text-white/30\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z\" /></svg>\n </div>\n <h4 class=\"text-sm font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors\">Astro vs Next.js: Choosing in 2026</h4>\n <p class=\"mt-1 text-xs text-gray-400\">Mar 8 &middot; 10 min</p>\n </a>\n </div>\n </section>\n\n </main>\n\n <!-- Footer -->\n <footer class=\"border-t border-gray-100\">\n <div class=\"max-w-4xl mx-auto px-4 sm:px-6 py-8\">\n <div class=\"flex items-center justify-between\">\n <p class=\"text-sm font-bold text-gray-900\">Insight Journal</p>\n <div class=\"flex items-center gap-4 text-xs text-gray-400\">\n <a href=\"#\" class=\"hover:text-gray-700 transition-colors\">Twitter</a>\n <a href=\"#\" class=\"hover:text-gray-700 transition-colors\">RSS</a>\n <a href=\"#\" class=\"hover:text-gray-700 transition-colors\">Privacy</a>\n </div>\n </div>\n <p class=\"mt-4 text-xs text-gray-400\">&copy; 2026 Insight Journal. All rights reserved.</p>\n </div>\n </footer>\n\n</body>\n</html>\n"
40933
42823
  },
40934
42824
  {
40935
42825
  "id": "coming-soon/countdown",