@morphika/andami 0.5.1 → 0.5.2

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 (117) hide show
  1. package/app/admin/assets/page.tsx +6 -6
  2. package/app/admin/database/page.tsx +302 -302
  3. package/app/admin/error.tsx +53 -53
  4. package/app/admin/layout.tsx +320 -320
  5. package/app/admin/navigation/page.tsx +255 -255
  6. package/app/admin/pages/[slug]/page.tsx +6 -6
  7. package/app/admin/pages/page.tsx +11 -11
  8. package/app/admin/projects/page.tsx +14 -14
  9. package/app/admin/setup/page.tsx +1 -1
  10. package/app/admin/styles/page.tsx +1 -1
  11. package/components/admin/MetadataEditor.tsx +6 -6
  12. package/components/admin/nav-builder/NavBuilder.tsx +1 -1
  13. package/components/admin/nav-builder/NavBuilderGrid.tsx +3 -3
  14. package/components/admin/nav-builder/NavGridCell.tsx +48 -48
  15. package/components/admin/nav-builder/NavGridItem.tsx +4 -4
  16. package/components/admin/nav-builder/NavItemSettings.tsx +331 -331
  17. package/components/admin/nav-builder/NavItemTypePicker.tsx +102 -102
  18. package/components/admin/nav-builder/NavLivePreview.tsx +1 -1
  19. package/components/admin/nav-builder/NavMobileLivePreview.tsx +226 -226
  20. package/components/admin/nav-builder/NavMobileSettings.tsx +242 -242
  21. package/components/admin/nav-builder/NavSettingsFields.tsx +514 -514
  22. package/components/admin/setup-wizard/BrandingStep.tsx +3 -3
  23. package/components/admin/setup-wizard/DatabaseStep.tsx +2 -2
  24. package/components/admin/setup-wizard/DoneStep.tsx +1 -1
  25. package/components/admin/setup-wizard/SetupWizard.tsx +4 -4
  26. package/components/admin/setup-wizard/StorageStep.tsx +2 -2
  27. package/components/admin/setup-wizard/WelcomeStep.tsx +2 -2
  28. package/components/admin/styles/ColorsEditor.tsx +2 -2
  29. package/components/admin/styles/FontsEditor.tsx +6 -6
  30. package/components/admin/styles/GridLayoutEditor.tsx +9 -9
  31. package/components/admin/styles/LinksButtonsEditor.tsx +5 -5
  32. package/components/admin/styles/TypographyEditor.tsx +6 -6
  33. package/components/admin/styles/shared.tsx +68 -68
  34. package/components/blocks/AudioBlockRenderer.tsx +286 -286
  35. package/components/blocks/MarqueeBlockRenderer.tsx +316 -0
  36. package/components/blocks/ProjectCarouselBlockRenderer.tsx +1 -1
  37. package/components/builder/BlockCardIcons.tsx +316 -316
  38. package/components/builder/BlockTypePicker.tsx +1 -1
  39. package/components/builder/BubbleIcons.tsx +90 -0
  40. package/components/builder/BuilderCanvas.tsx +2 -0
  41. package/components/builder/CanvasMinimap.tsx +2 -2
  42. package/components/builder/CoverSectionCanvas.tsx +363 -363
  43. package/components/builder/DeviceFrame.tsx +1 -1
  44. package/components/builder/DndWrapper.tsx +3 -3
  45. package/components/builder/InsertionLines.tsx +1 -1
  46. package/components/builder/SectionCardIcons.tsx +421 -320
  47. package/components/builder/SectionEditorBar.tsx +1 -1
  48. package/components/builder/SectionTypePicker.tsx +4 -4
  49. package/components/builder/SectionV2Canvas.tsx +1 -1
  50. package/components/builder/SectionV2Column.tsx +69 -67
  51. package/components/builder/SortableBlock.tsx +93 -73
  52. package/components/builder/SortableRow.tsx +27 -26
  53. package/components/builder/VirtualAssetGrid.tsx +2 -2
  54. package/components/builder/asset-browser/R2BrowserContent.tsx +11 -11
  55. package/components/builder/blockStyles.tsx +192 -185
  56. package/components/builder/color-picker/AlphaSlider.tsx +141 -141
  57. package/components/builder/color-picker/ColorInputs.tsx +105 -105
  58. package/components/builder/color-picker/EyedropperButton.tsx +74 -74
  59. package/components/builder/color-picker/HueSlider.tsx +124 -124
  60. package/components/builder/color-picker/SaturationCanvas.tsx +142 -142
  61. package/components/builder/color-picker/SwatchBar.tsx +93 -93
  62. package/components/builder/editors/AudioBlockEditor.tsx +242 -242
  63. package/components/builder/editors/BeforeAfterBlockEditor.tsx +360 -360
  64. package/components/builder/editors/ButtonBlockEditor.tsx +4 -4
  65. package/components/builder/editors/EnterAnimationPicker.tsx +2 -2
  66. package/components/builder/editors/HoverEffectPicker.tsx +2 -2
  67. package/components/builder/editors/ImageBlockEditor.tsx +2 -2
  68. package/components/builder/editors/ImageGridBlockEditor.tsx +4 -4
  69. package/components/builder/editors/MarqueeBlockEditor.tsx +621 -0
  70. package/components/builder/editors/ProjectCarouselBlockEditor.tsx +443 -443
  71. package/components/builder/editors/ProjectGridEditor.tsx +9 -9
  72. package/components/builder/editors/SpacerBlockEditor.tsx +5 -5
  73. package/components/builder/editors/StaggerSettings.tsx +109 -109
  74. package/components/builder/editors/TextBlockEditor.tsx +3 -3
  75. package/components/builder/editors/TextStylePicker.tsx +1 -1
  76. package/components/builder/editors/VideoBlockEditor.tsx +2 -2
  77. package/components/builder/editors/index.ts +11 -10
  78. package/components/builder/editors/shared.tsx +6 -6
  79. package/components/builder/live-preview/LiveAudioPreview.tsx +120 -120
  80. package/components/builder/live-preview/LiveBeforeAfterPreview.tsx +1 -1
  81. package/components/builder/live-preview/LiveImageGridPreview.tsx +10 -2
  82. package/components/builder/live-preview/LiveImagePreview.tsx +1 -1
  83. package/components/builder/live-preview/LiveMarqueePreview.tsx +39 -0
  84. package/components/builder/live-preview/LiveProjectCarouselPreview.tsx +1 -1
  85. package/components/builder/live-preview/LiveVideoPreview.tsx +1 -1
  86. package/components/builder/live-preview/ProjectCardWrapper.tsx +291 -291
  87. package/components/builder/settings-panel/AnimationTab.tsx +138 -138
  88. package/components/builder/settings-panel/BlockLayoutTab.tsx +7 -7
  89. package/components/builder/settings-panel/CardEntranceSection.tsx +114 -114
  90. package/components/builder/settings-panel/ColumnV2Settings.tsx +5 -5
  91. package/components/builder/settings-panel/CoverSectionLayoutTab.tsx +71 -71
  92. package/components/builder/settings-panel/CoverSectionSettings.tsx +335 -335
  93. package/components/builder/settings-panel/PageSettings.tsx +3 -3
  94. package/components/builder/settings-panel/ParallaxSlideSettings.tsx +2 -2
  95. package/components/builder/settings-panel/SectionV2AnimationTab.tsx +4 -4
  96. package/components/builder/settings-panel/SectionV2LayoutTab.tsx +356 -356
  97. package/components/builder/settings-panel/SectionV2Settings.tsx +14 -14
  98. package/components/builder/settings-panel/TRBLInputs.tsx +1 -1
  99. package/lib/animation/enter-types.ts +1 -0
  100. package/lib/animation/hover-effect-presets.ts +210 -210
  101. package/lib/animation/hover-effect-types.ts +1 -0
  102. package/lib/builder/block-registrations.ts +468 -417
  103. package/lib/builder/constants.ts +111 -111
  104. package/lib/builder/store-sections.ts +2 -2
  105. package/lib/builder/types-slices.ts +414 -414
  106. package/lib/builder/types.ts +4 -1
  107. package/lib/config/index.ts +27 -27
  108. package/lib/sanity/types.ts +98 -1
  109. package/lib/version.ts +1 -1
  110. package/package.json +1 -1
  111. package/sanity/schemas/blocks/audioBlock.ts +69 -69
  112. package/sanity/schemas/blocks/index.ts +12 -11
  113. package/sanity/schemas/blocks/marqueeBlock.ts +292 -0
  114. package/sanity/schemas/index.ts +120 -117
  115. package/styles/admin.css +85 -85
  116. package/styles/animations.css +237 -237
  117. package/styles/base.css +114 -114
@@ -1,237 +1,237 @@
1
- /* ============================================
2
- Animations — Core keyframes and animation systems
3
- Imported by globals.css (monolith) or instance CSS
4
- ============================================ */
5
-
6
- @keyframes marquee {
7
- from {
8
- transform: translateX(0);
9
- }
10
- to {
11
- transform: translateX(-50%);
12
- }
13
- }
14
-
15
- /* V2 Grid snapping guide pulse */
16
- @keyframes pulse {
17
- 0%, 100% { opacity: 0.4; }
18
- 50% { opacity: 1; }
19
- }
20
-
21
- /* ============================================
22
- View Transitions — DISABLED (Session 112)
23
- Removed to eliminate black flash conflicts with
24
- "On Enter" element animations. Page exit animations
25
- (PageExitContext) handle the transition feel instead.
26
- ============================================ */
27
-
28
- /* ============================================
29
- Enter Animation Keyframes (Session 120)
30
- Used by EnterAnimationWrapper via inline styles.
31
- animation-name, duration, delay, easing, and fill-mode
32
- are set via inline styles — no CSS rules needed here.
33
- ============================================ */
34
-
35
- @keyframes enter-fade {
36
- from { opacity: 0; }
37
- to { opacity: 1; }
38
- }
39
-
40
- @keyframes enter-slide-up {
41
- from { opacity: 0; transform: translateY(30px); }
42
- to { opacity: 1; transform: translateY(0); }
43
- }
44
-
45
- @keyframes enter-slide-down {
46
- from { opacity: 0; transform: translateY(-30px); }
47
- to { opacity: 1; transform: translateY(0); }
48
- }
49
-
50
- @keyframes enter-scale {
51
- from { opacity: 0; transform: scale(0.85); }
52
- to { opacity: 1; transform: scale(1); }
53
- }
54
-
55
- @keyframes enter-reveal {
56
- from { opacity: 0; clip-path: inset(0 100% 0 0); }
57
- to { opacity: 1; clip-path: inset(0 0% 0 0); }
58
- }
59
-
60
- @keyframes enter-blur {
61
- from { opacity: 0; filter: blur(10px); }
62
- to { opacity: 1; filter: blur(0px); }
63
- }
64
-
65
- @keyframes enter-blur-in {
66
- from { opacity: 0; filter: blur(6px); }
67
- to { opacity: 1; filter: blur(0px); }
68
- }
69
-
70
- /* Prefers reduced motion — neutralize ALL enter animations */
71
- @media (prefers-reduced-motion: reduce) {
72
- [data-enter-animation] {
73
- animation: none !important;
74
- opacity: 1 !important;
75
- transform: none !important;
76
- filter: none !important;
77
- clip-path: none !important;
78
- }
79
- }
80
-
81
- /* Suppress hover transitions while enter animation is still playing.
82
- Prevents visual conflict between CSS animation (enter) and CSS transition (hover). */
83
- [data-enter-animation]:not([data-entered]) [data-hover-effect] {
84
- transition: none !important;
85
- pointer-events: none;
86
- }
87
-
88
- /* ============================================
89
- Hover Effect System (Sessions 60, 120)
90
- ============================================
91
- Most hover styling is applied via inline styles in HoverAnimationWrapper.
92
- The :hover pseudo-class cannot be set inline, so we use data attributes. */
93
-
94
- /* Scale Up */
95
- [data-hover-effect="scale-up"]:hover {
96
- transform: scale(1.05) !important;
97
- }
98
-
99
- /* Scale Down */
100
- [data-hover-effect="scale-down"]:hover {
101
- transform: scale(0.95) !important;
102
- }
103
-
104
- /* Lift — uses inline custom properties for intensity-dependent values */
105
- [data-hover-effect="lift"] {
106
- --hover-lift-y: -4px;
107
- --hover-lift-shadow: 0 8px 20px rgba(0,0,0,0.15);
108
- }
109
- [data-hover-effect="lift"]:hover {
110
- transform: translateY(var(--hover-lift-y)) !important;
111
- box-shadow: var(--hover-lift-shadow) !important;
112
- }
113
-
114
- /* Tilt 3D — transform is handled by JS mousemove, but we ensure base state */
115
- [data-hover-effect="tilt-3d"] {
116
- transform-style: preserve-3d;
117
- }
118
-
119
- /* Color Shift */
120
- [data-hover-effect="color-shift"] {
121
- --hover-brightness: 1.1;
122
- --hover-saturate: 1.2;
123
- }
124
- [data-hover-effect="color-shift"]:hover {
125
- filter: brightness(var(--hover-brightness)) saturate(var(--hover-saturate)) !important;
126
- }
127
-
128
- /* Blur Reveal */
129
- [data-hover-effect="blur-reveal"] {
130
- --hover-blur-base: 3px;
131
- --hover-opacity-base: 0.85;
132
- }
133
- [data-hover-effect="blur-reveal"]:hover {
134
- filter: blur(0px) !important;
135
- opacity: 1 !important;
136
- }
137
-
138
- /* Border Glow */
139
- [data-hover-effect="border-glow"] {
140
- --hover-glow-spread: 4px;
141
- --hover-glow-color: rgba(7,107,255,0.4);
142
- }
143
- [data-hover-effect="border-glow"]:hover {
144
- box-shadow: 0 0 calc(var(--hover-glow-spread) * 2) var(--hover-glow-spread) var(--hover-glow-color) !important;
145
- }
146
-
147
- /* Prefers reduced motion — disable hover animations */
148
- @media (prefers-reduced-motion: reduce) {
149
- [data-hover-effect] {
150
- transition: none !important;
151
- }
152
- [data-hover-effect]:hover {
153
- transform: none !important;
154
- filter: none !important;
155
- box-shadow: none !important;
156
- opacity: 1 !important;
157
- }
158
- }
159
-
160
- /* ============================================
161
- Text Animation Presets (Parallax Showcase)
162
- CSS-only presets for title/subtitle entrance.
163
- Triggered via IntersectionObserver (enter mode).
164
- ============================================ */
165
-
166
- /* ============================================
167
- Nav Entrance Animations
168
- Applied to the entire nav or individual items
169
- when stagger is enabled. Triggered on page load.
170
- ============================================ */
171
-
172
- @keyframes nav-fade-in {
173
- from { opacity: 0; }
174
- to { opacity: 1; }
175
- }
176
-
177
- @keyframes nav-slide-down {
178
- from { opacity: 0; transform: translateY(-100%); }
179
- to { opacity: 1; transform: translateY(0); }
180
- }
181
-
182
- @keyframes nav-blur-in {
183
- from { opacity: 0; filter: blur(12px); }
184
- to { opacity: 1; filter: blur(0px); }
185
- }
186
-
187
- /* Nav entrance: initial hidden state */
188
- [data-nav-entrance] {
189
- opacity: 0;
190
- }
191
-
192
- /* Nav entrance: play once the attribute is set */
193
- [data-nav-entrance="fade-in"][data-nav-entered] {
194
- animation: nav-fade-in var(--nav-entrance-duration, 600ms) var(--nav-entrance-delay, 0ms) ease-out forwards;
195
- }
196
-
197
- [data-nav-entrance="slide-down"][data-nav-entered] {
198
- animation: nav-slide-down var(--nav-entrance-duration, 600ms) var(--nav-entrance-delay, 0ms) ease-out forwards;
199
- }
200
-
201
- [data-nav-entrance="blur-in"][data-nav-entered] {
202
- animation: nav-blur-in var(--nav-entrance-duration, 700ms) var(--nav-entrance-delay, 0ms) ease-out forwards;
203
- }
204
-
205
- /* Staggered items: each item animates independently */
206
- [data-nav-item-entrance] {
207
- opacity: 0;
208
- }
209
-
210
- [data-nav-item-entrance="fade-in"][data-nav-entered] {
211
- animation: nav-fade-in var(--nav-item-duration, 400ms) var(--nav-item-delay, 0ms) ease-out forwards;
212
- }
213
-
214
- [data-nav-item-entrance="slide-down"][data-nav-entered] {
215
- animation: nav-slide-down var(--nav-item-duration, 400ms) var(--nav-item-delay, 0ms) ease-out forwards;
216
- }
217
-
218
- [data-nav-item-entrance="blur-in"][data-nav-entered] {
219
- animation: nav-blur-in var(--nav-item-duration, 400ms) var(--nav-item-delay, 0ms) ease-out forwards;
220
- }
221
-
222
- /* Prefers reduced motion — disable nav animations */
223
- @media (prefers-reduced-motion: reduce) {
224
- [data-nav-entrance],
225
- [data-nav-item-entrance] {
226
- animation: none !important;
227
- opacity: 1 !important;
228
- transform: none !important;
229
- filter: none !important;
230
- }
231
- }
232
-
233
- /* Typewriter cursor blink */
234
- @keyframes typewriter-cursor-blink {
235
- 0%, 100% { opacity: 1; }
236
- 50% { opacity: 0; }
237
- }
1
+ /* ============================================
2
+ Animations — Core keyframes and animation systems
3
+ Imported by globals.css (monolith) or instance CSS
4
+ ============================================ */
5
+
6
+ @keyframes marquee {
7
+ from {
8
+ transform: translateX(0);
9
+ }
10
+ to {
11
+ transform: translateX(-50%);
12
+ }
13
+ }
14
+
15
+ /* V2 Grid snapping guide pulse */
16
+ @keyframes pulse {
17
+ 0%, 100% { opacity: 0.4; }
18
+ 50% { opacity: 1; }
19
+ }
20
+
21
+ /* ============================================
22
+ View Transitions — DISABLED (Session 112)
23
+ Removed to eliminate black flash conflicts with
24
+ "On Enter" element animations. Page exit animations
25
+ (PageExitContext) handle the transition feel instead.
26
+ ============================================ */
27
+
28
+ /* ============================================
29
+ Enter Animation Keyframes (Session 120)
30
+ Used by EnterAnimationWrapper via inline styles.
31
+ animation-name, duration, delay, easing, and fill-mode
32
+ are set via inline styles — no CSS rules needed here.
33
+ ============================================ */
34
+
35
+ @keyframes enter-fade {
36
+ from { opacity: 0; }
37
+ to { opacity: 1; }
38
+ }
39
+
40
+ @keyframes enter-slide-up {
41
+ from { opacity: 0; transform: translateY(30px); }
42
+ to { opacity: 1; transform: translateY(0); }
43
+ }
44
+
45
+ @keyframes enter-slide-down {
46
+ from { opacity: 0; transform: translateY(-30px); }
47
+ to { opacity: 1; transform: translateY(0); }
48
+ }
49
+
50
+ @keyframes enter-scale {
51
+ from { opacity: 0; transform: scale(0.85); }
52
+ to { opacity: 1; transform: scale(1); }
53
+ }
54
+
55
+ @keyframes enter-reveal {
56
+ from { opacity: 0; clip-path: inset(0 100% 0 0); }
57
+ to { opacity: 1; clip-path: inset(0 0% 0 0); }
58
+ }
59
+
60
+ @keyframes enter-blur {
61
+ from { opacity: 0; filter: blur(10px); }
62
+ to { opacity: 1; filter: blur(0px); }
63
+ }
64
+
65
+ @keyframes enter-blur-in {
66
+ from { opacity: 0; filter: blur(6px); }
67
+ to { opacity: 1; filter: blur(0px); }
68
+ }
69
+
70
+ /* Prefers reduced motion — neutralize ALL enter animations */
71
+ @media (prefers-reduced-motion: reduce) {
72
+ [data-enter-animation] {
73
+ animation: none !important;
74
+ opacity: 1 !important;
75
+ transform: none !important;
76
+ filter: none !important;
77
+ clip-path: none !important;
78
+ }
79
+ }
80
+
81
+ /* Suppress hover transitions while enter animation is still playing.
82
+ Prevents visual conflict between CSS animation (enter) and CSS transition (hover). */
83
+ [data-enter-animation]:not([data-entered]) [data-hover-effect] {
84
+ transition: none !important;
85
+ pointer-events: none;
86
+ }
87
+
88
+ /* ============================================
89
+ Hover Effect System (Sessions 60, 120)
90
+ ============================================
91
+ Most hover styling is applied via inline styles in HoverAnimationWrapper.
92
+ The :hover pseudo-class cannot be set inline, so we use data attributes. */
93
+
94
+ /* Scale Up */
95
+ [data-hover-effect="scale-up"]:hover {
96
+ transform: scale(1.05) !important;
97
+ }
98
+
99
+ /* Scale Down */
100
+ [data-hover-effect="scale-down"]:hover {
101
+ transform: scale(0.95) !important;
102
+ }
103
+
104
+ /* Lift — uses inline custom properties for intensity-dependent values */
105
+ [data-hover-effect="lift"] {
106
+ --hover-lift-y: -4px;
107
+ --hover-lift-shadow: 0 8px 20px rgba(0,0,0,0.15);
108
+ }
109
+ [data-hover-effect="lift"]:hover {
110
+ transform: translateY(var(--hover-lift-y)) !important;
111
+ box-shadow: var(--hover-lift-shadow) !important;
112
+ }
113
+
114
+ /* Tilt 3D — transform is handled by JS mousemove, but we ensure base state */
115
+ [data-hover-effect="tilt-3d"] {
116
+ transform-style: preserve-3d;
117
+ }
118
+
119
+ /* Color Shift */
120
+ [data-hover-effect="color-shift"] {
121
+ --hover-brightness: 1.1;
122
+ --hover-saturate: 1.2;
123
+ }
124
+ [data-hover-effect="color-shift"]:hover {
125
+ filter: brightness(var(--hover-brightness)) saturate(var(--hover-saturate)) !important;
126
+ }
127
+
128
+ /* Blur Reveal */
129
+ [data-hover-effect="blur-reveal"] {
130
+ --hover-blur-base: 3px;
131
+ --hover-opacity-base: 0.85;
132
+ }
133
+ [data-hover-effect="blur-reveal"]:hover {
134
+ filter: blur(0px) !important;
135
+ opacity: 1 !important;
136
+ }
137
+
138
+ /* Border Glow */
139
+ [data-hover-effect="border-glow"] {
140
+ --hover-glow-spread: 4px;
141
+ --hover-glow-color: rgba(53, 128, 249,0.4);
142
+ }
143
+ [data-hover-effect="border-glow"]:hover {
144
+ box-shadow: 0 0 calc(var(--hover-glow-spread) * 2) var(--hover-glow-spread) var(--hover-glow-color) !important;
145
+ }
146
+
147
+ /* Prefers reduced motion — disable hover animations */
148
+ @media (prefers-reduced-motion: reduce) {
149
+ [data-hover-effect] {
150
+ transition: none !important;
151
+ }
152
+ [data-hover-effect]:hover {
153
+ transform: none !important;
154
+ filter: none !important;
155
+ box-shadow: none !important;
156
+ opacity: 1 !important;
157
+ }
158
+ }
159
+
160
+ /* ============================================
161
+ Text Animation Presets (Parallax Showcase)
162
+ CSS-only presets for title/subtitle entrance.
163
+ Triggered via IntersectionObserver (enter mode).
164
+ ============================================ */
165
+
166
+ /* ============================================
167
+ Nav Entrance Animations
168
+ Applied to the entire nav or individual items
169
+ when stagger is enabled. Triggered on page load.
170
+ ============================================ */
171
+
172
+ @keyframes nav-fade-in {
173
+ from { opacity: 0; }
174
+ to { opacity: 1; }
175
+ }
176
+
177
+ @keyframes nav-slide-down {
178
+ from { opacity: 0; transform: translateY(-100%); }
179
+ to { opacity: 1; transform: translateY(0); }
180
+ }
181
+
182
+ @keyframes nav-blur-in {
183
+ from { opacity: 0; filter: blur(12px); }
184
+ to { opacity: 1; filter: blur(0px); }
185
+ }
186
+
187
+ /* Nav entrance: initial hidden state */
188
+ [data-nav-entrance] {
189
+ opacity: 0;
190
+ }
191
+
192
+ /* Nav entrance: play once the attribute is set */
193
+ [data-nav-entrance="fade-in"][data-nav-entered] {
194
+ animation: nav-fade-in var(--nav-entrance-duration, 600ms) var(--nav-entrance-delay, 0ms) ease-out forwards;
195
+ }
196
+
197
+ [data-nav-entrance="slide-down"][data-nav-entered] {
198
+ animation: nav-slide-down var(--nav-entrance-duration, 600ms) var(--nav-entrance-delay, 0ms) ease-out forwards;
199
+ }
200
+
201
+ [data-nav-entrance="blur-in"][data-nav-entered] {
202
+ animation: nav-blur-in var(--nav-entrance-duration, 700ms) var(--nav-entrance-delay, 0ms) ease-out forwards;
203
+ }
204
+
205
+ /* Staggered items: each item animates independently */
206
+ [data-nav-item-entrance] {
207
+ opacity: 0;
208
+ }
209
+
210
+ [data-nav-item-entrance="fade-in"][data-nav-entered] {
211
+ animation: nav-fade-in var(--nav-item-duration, 400ms) var(--nav-item-delay, 0ms) ease-out forwards;
212
+ }
213
+
214
+ [data-nav-item-entrance="slide-down"][data-nav-entered] {
215
+ animation: nav-slide-down var(--nav-item-duration, 400ms) var(--nav-item-delay, 0ms) ease-out forwards;
216
+ }
217
+
218
+ [data-nav-item-entrance="blur-in"][data-nav-entered] {
219
+ animation: nav-blur-in var(--nav-item-duration, 400ms) var(--nav-item-delay, 0ms) ease-out forwards;
220
+ }
221
+
222
+ /* Prefers reduced motion — disable nav animations */
223
+ @media (prefers-reduced-motion: reduce) {
224
+ [data-nav-entrance],
225
+ [data-nav-item-entrance] {
226
+ animation: none !important;
227
+ opacity: 1 !important;
228
+ transform: none !important;
229
+ filter: none !important;
230
+ }
231
+ }
232
+
233
+ /* Typewriter cursor blink */
234
+ @keyframes typewriter-cursor-blink {
235
+ 0%, 100% { opacity: 1; }
236
+ 50% { opacity: 0; }
237
+ }