@morphika/andami 0.5.0 → 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 (122) hide show
  1. package/README.md +151 -36
  2. package/app/admin/assets/page.tsx +6 -6
  3. package/app/admin/database/page.tsx +302 -302
  4. package/app/admin/error.tsx +53 -53
  5. package/app/admin/layout.tsx +320 -327
  6. package/app/admin/navigation/page.tsx +255 -255
  7. package/app/admin/pages/[slug]/page.tsx +6 -6
  8. package/app/admin/pages/page.tsx +11 -11
  9. package/app/admin/projects/page.tsx +14 -14
  10. package/app/admin/setup/page.tsx +1 -1
  11. package/app/admin/styles/page.tsx +1 -1
  12. package/components/admin/MetadataEditor.tsx +6 -6
  13. package/components/admin/nav-builder/NavBuilder.tsx +1 -1
  14. package/components/admin/nav-builder/NavBuilderGrid.tsx +3 -3
  15. package/components/admin/nav-builder/NavGridCell.tsx +48 -48
  16. package/components/admin/nav-builder/NavGridItem.tsx +4 -4
  17. package/components/admin/nav-builder/NavItemSettings.tsx +331 -331
  18. package/components/admin/nav-builder/NavItemTypePicker.tsx +102 -102
  19. package/components/admin/nav-builder/NavLivePreview.tsx +1 -1
  20. package/components/admin/nav-builder/NavMobileLivePreview.tsx +226 -226
  21. package/components/admin/nav-builder/NavMobileSettings.tsx +242 -242
  22. package/components/admin/nav-builder/NavSettingsFields.tsx +514 -514
  23. package/components/admin/setup-wizard/BrandingStep.tsx +3 -3
  24. package/components/admin/setup-wizard/DatabaseStep.tsx +2 -2
  25. package/components/admin/setup-wizard/DoneStep.tsx +1 -1
  26. package/components/admin/setup-wizard/SetupWizard.tsx +4 -4
  27. package/components/admin/setup-wizard/StorageStep.tsx +2 -2
  28. package/components/admin/setup-wizard/WelcomeStep.tsx +2 -2
  29. package/components/admin/styles/ColorsEditor.tsx +2 -2
  30. package/components/admin/styles/FontsEditor.tsx +6 -6
  31. package/components/admin/styles/GridLayoutEditor.tsx +9 -9
  32. package/components/admin/styles/LinksButtonsEditor.tsx +5 -5
  33. package/components/admin/styles/TypographyEditor.tsx +6 -6
  34. package/components/admin/styles/shared.tsx +68 -68
  35. package/components/blocks/AudioBlockRenderer.tsx +286 -0
  36. package/components/blocks/BeforeAfterBlockRenderer.tsx +274 -0
  37. package/components/blocks/MarqueeBlockRenderer.tsx +316 -0
  38. package/components/blocks/ProjectCarouselBlockRenderer.tsx +1 -1
  39. package/components/builder/BlockCardIcons.tsx +316 -227
  40. package/components/builder/BlockTypePicker.tsx +3 -1
  41. package/components/builder/BubbleIcons.tsx +90 -0
  42. package/components/builder/BuilderCanvas.tsx +2 -0
  43. package/components/builder/CanvasMinimap.tsx +2 -2
  44. package/components/builder/CoverSectionCanvas.tsx +363 -275
  45. package/components/builder/DeviceFrame.tsx +1 -1
  46. package/components/builder/DndWrapper.tsx +3 -3
  47. package/components/builder/InsertionLines.tsx +1 -1
  48. package/components/builder/SectionCardIcons.tsx +421 -320
  49. package/components/builder/SectionEditorBar.tsx +1 -1
  50. package/components/builder/SectionTypePicker.tsx +4 -4
  51. package/components/builder/SectionV2Canvas.tsx +20 -4
  52. package/components/builder/SectionV2Column.tsx +74 -68
  53. package/components/builder/SortableBlock.tsx +93 -73
  54. package/components/builder/SortableRow.tsx +27 -26
  55. package/components/builder/VirtualAssetGrid.tsx +2 -2
  56. package/components/builder/asset-browser/R2BrowserContent.tsx +34 -17
  57. package/components/builder/asset-browser/helpers.ts +4 -0
  58. package/components/builder/asset-browser/types.ts +2 -1
  59. package/components/builder/blockStyles.tsx +192 -173
  60. package/components/builder/color-picker/AlphaSlider.tsx +141 -141
  61. package/components/builder/color-picker/ColorInputs.tsx +105 -105
  62. package/components/builder/color-picker/EyedropperButton.tsx +74 -74
  63. package/components/builder/color-picker/HueSlider.tsx +124 -124
  64. package/components/builder/color-picker/SaturationCanvas.tsx +142 -142
  65. package/components/builder/color-picker/SwatchBar.tsx +93 -93
  66. package/components/builder/editors/AudioBlockEditor.tsx +242 -0
  67. package/components/builder/editors/BeforeAfterBlockEditor.tsx +360 -0
  68. package/components/builder/editors/ButtonBlockEditor.tsx +4 -4
  69. package/components/builder/editors/EnterAnimationPicker.tsx +2 -2
  70. package/components/builder/editors/HoverEffectPicker.tsx +2 -2
  71. package/components/builder/editors/ImageBlockEditor.tsx +2 -2
  72. package/components/builder/editors/ImageGridBlockEditor.tsx +4 -4
  73. package/components/builder/editors/MarqueeBlockEditor.tsx +621 -0
  74. package/components/builder/editors/ProjectCarouselBlockEditor.tsx +443 -443
  75. package/components/builder/editors/ProjectGridEditor.tsx +9 -9
  76. package/components/builder/editors/SpacerBlockEditor.tsx +5 -5
  77. package/components/builder/editors/StaggerSettings.tsx +109 -109
  78. package/components/builder/editors/TextBlockEditor.tsx +3 -3
  79. package/components/builder/editors/TextStylePicker.tsx +1 -1
  80. package/components/builder/editors/VideoBlockEditor.tsx +2 -2
  81. package/components/builder/editors/index.ts +11 -10
  82. package/components/builder/editors/shared.tsx +7 -7
  83. package/components/builder/live-preview/LiveAudioPreview.tsx +120 -0
  84. package/components/builder/live-preview/LiveBeforeAfterPreview.tsx +176 -0
  85. package/components/builder/live-preview/LiveImageGridPreview.tsx +10 -2
  86. package/components/builder/live-preview/LiveImagePreview.tsx +1 -1
  87. package/components/builder/live-preview/LiveMarqueePreview.tsx +39 -0
  88. package/components/builder/live-preview/LiveProjectCarouselPreview.tsx +1 -1
  89. package/components/builder/live-preview/LiveVideoPreview.tsx +1 -1
  90. package/components/builder/live-preview/ProjectCardWrapper.tsx +291 -291
  91. package/components/builder/settings-panel/AnimationTab.tsx +138 -138
  92. package/components/builder/settings-panel/BlockLayoutTab.tsx +7 -7
  93. package/components/builder/settings-panel/CardEntranceSection.tsx +114 -114
  94. package/components/builder/settings-panel/ColumnV2Settings.tsx +5 -5
  95. package/components/builder/settings-panel/CoverSectionLayoutTab.tsx +71 -71
  96. package/components/builder/settings-panel/CoverSectionSettings.tsx +335 -335
  97. package/components/builder/settings-panel/PageSettings.tsx +3 -3
  98. package/components/builder/settings-panel/ParallaxSlideSettings.tsx +2 -2
  99. package/components/builder/settings-panel/SectionV2AnimationTab.tsx +4 -4
  100. package/components/builder/settings-panel/SectionV2LayoutTab.tsx +356 -356
  101. package/components/builder/settings-panel/SectionV2Settings.tsx +14 -14
  102. package/components/builder/settings-panel/TRBLInputs.tsx +1 -1
  103. package/lib/animation/enter-types.ts +3 -0
  104. package/lib/animation/hover-effect-presets.ts +210 -210
  105. package/lib/animation/hover-effect-types.ts +3 -0
  106. package/lib/builder/block-registrations.ts +468 -335
  107. package/lib/builder/constants.ts +111 -111
  108. package/lib/builder/store-sections.ts +2 -2
  109. package/lib/builder/types-slices.ts +414 -414
  110. package/lib/builder/types.ts +6 -1
  111. package/lib/config/index.ts +27 -27
  112. package/lib/sanity/types.ts +156 -1
  113. package/lib/version.ts +1 -1
  114. package/package.json +1 -1
  115. package/sanity/schemas/blocks/audioBlock.ts +69 -0
  116. package/sanity/schemas/blocks/beforeAfterBlock.ts +121 -0
  117. package/sanity/schemas/blocks/index.ts +12 -9
  118. package/sanity/schemas/blocks/marqueeBlock.ts +292 -0
  119. package/sanity/schemas/index.ts +120 -111
  120. package/styles/admin.css +85 -85
  121. package/styles/animations.css +237 -237
  122. package/styles/base.css +114 -114
package/styles/admin.css CHANGED
@@ -1,85 +1,85 @@
1
- /* ============================================
2
- Admin Panel — Clean UI Override
3
- Uses Inter (sans-serif) for admin, white bg,
4
- clean hierarchy. Mono reserved for public site.
5
- ============================================ */
6
-
7
- /* Admin shell: override dark defaults */
8
- [data-admin] {
9
- font-family: var(--font-sans);
10
- background: #ffffff;
11
- color: #1a1a1a;
12
- }
13
-
14
- [data-admin] * {
15
- cursor: auto;
16
- }
17
-
18
- /* Admin typography scale */
19
- [data-admin] h1 { font-size: 1.5rem; font-weight: 600; letter-spacing: -0.01em; color: #111; }
20
- [data-admin] h2 { font-size: 1.125rem; font-weight: 600; letter-spacing: -0.01em; color: #222; }
21
- [data-admin] h3 { font-size: 0.9375rem; font-weight: 500; color: #333; }
22
-
23
- /* Admin inputs */
24
- [data-admin] input[type="text"],
25
- [data-admin] input[type="password"],
26
- [data-admin] input[type="email"],
27
- [data-admin] input[type="url"],
28
- [data-admin] input[type="number"],
29
- [data-admin] textarea,
30
- [data-admin] select {
31
- font-family: var(--font-sans);
32
- font-size: 0.8125rem;
33
- border-radius: 0.5rem;
34
- border: 1px solid #e5e5e5;
35
- padding: 0.5rem 0.75rem;
36
- transition: border-color 0.15s;
37
- }
38
-
39
- [data-admin] input:focus,
40
- [data-admin] textarea:focus,
41
- [data-admin] select:focus {
42
- border-color: #076bff;
43
- outline: none;
44
- box-shadow: 0 0 0 3px rgba(7, 107, 255, 0.08);
45
- }
46
-
47
- /* Admin buttons base */
48
- [data-admin] .btn-primary {
49
- background: #076bff;
50
- color: white;
51
- font-weight: 500;
52
- font-size: 0.8125rem;
53
- padding: 0.5rem 1.25rem;
54
- border-radius: 0.5rem;
55
- transition: all 0.15s;
56
- }
57
- [data-admin] .btn-primary:hover { background: #0559d4; }
58
- [data-admin] .btn-primary:disabled { opacity: 0.4; }
59
-
60
- [data-admin] .btn-secondary {
61
- background: white;
62
- color: #555;
63
- font-weight: 500;
64
- font-size: 0.8125rem;
65
- padding: 0.5rem 1.25rem;
66
- border-radius: 0.5rem;
67
- border: 1px solid #e5e5e5;
68
- transition: all 0.15s;
69
- }
70
- [data-admin] .btn-secondary:hover { border-color: #ccc; color: #111; }
71
-
72
- /* Admin card base */
73
- [data-admin] .admin-card {
74
- background: white;
75
- border: 1px solid #f0f0f0;
76
- border-radius: 0.75rem;
77
- padding: 1.5rem;
78
- box-shadow: 0 1px 3px rgba(0,0,0,0.04);
79
- }
80
-
81
- /* Scrollbar for admin */
82
- [data-admin] ::-webkit-scrollbar { width: 6px; }
83
- [data-admin] ::-webkit-scrollbar-track { background: transparent; }
84
- [data-admin] ::-webkit-scrollbar-thumb { background: #ddd; border-radius: 3px; }
85
- [data-admin] ::-webkit-scrollbar-thumb:hover { background: #bbb; }
1
+ /* ============================================
2
+ Admin Panel — Clean UI Override
3
+ Uses Inter (sans-serif) for admin, white bg,
4
+ clean hierarchy. Mono reserved for public site.
5
+ ============================================ */
6
+
7
+ /* Admin shell: override dark defaults */
8
+ [data-admin] {
9
+ font-family: var(--font-sans);
10
+ background: #ffffff;
11
+ color: #1a1a1a;
12
+ }
13
+
14
+ [data-admin] * {
15
+ cursor: auto;
16
+ }
17
+
18
+ /* Admin typography scale */
19
+ [data-admin] h1 { font-size: 1.5rem; font-weight: 600; letter-spacing: -0.01em; color: #111; }
20
+ [data-admin] h2 { font-size: 1.125rem; font-weight: 600; letter-spacing: -0.01em; color: #222; }
21
+ [data-admin] h3 { font-size: 0.9375rem; font-weight: 500; color: #333; }
22
+
23
+ /* Admin inputs */
24
+ [data-admin] input[type="text"],
25
+ [data-admin] input[type="password"],
26
+ [data-admin] input[type="email"],
27
+ [data-admin] input[type="url"],
28
+ [data-admin] input[type="number"],
29
+ [data-admin] textarea,
30
+ [data-admin] select {
31
+ font-family: var(--font-sans);
32
+ font-size: 0.8125rem;
33
+ border-radius: 0.5rem;
34
+ border: 1px solid #e5e5e5;
35
+ padding: 0.5rem 0.75rem;
36
+ transition: border-color 0.15s;
37
+ }
38
+
39
+ [data-admin] input:focus,
40
+ [data-admin] textarea:focus,
41
+ [data-admin] select:focus {
42
+ border-color: #3580f9;
43
+ outline: none;
44
+ box-shadow: 0 0 0 3px rgba(53, 128, 249, 0.08);
45
+ }
46
+
47
+ /* Admin buttons base */
48
+ [data-admin] .btn-primary {
49
+ background: #3580f9;
50
+ color: white;
51
+ font-weight: 500;
52
+ font-size: 0.8125rem;
53
+ padding: 0.5rem 1.25rem;
54
+ border-radius: 0.5rem;
55
+ transition: all 0.15s;
56
+ }
57
+ [data-admin] .btn-primary:hover { background: #2d6dd4; }
58
+ [data-admin] .btn-primary:disabled { opacity: 0.4; }
59
+
60
+ [data-admin] .btn-secondary {
61
+ background: white;
62
+ color: #555;
63
+ font-weight: 500;
64
+ font-size: 0.8125rem;
65
+ padding: 0.5rem 1.25rem;
66
+ border-radius: 0.5rem;
67
+ border: 1px solid #e5e5e5;
68
+ transition: all 0.15s;
69
+ }
70
+ [data-admin] .btn-secondary:hover { border-color: #ccc; color: #111; }
71
+
72
+ /* Admin card base */
73
+ [data-admin] .admin-card {
74
+ background: white;
75
+ border: 1px solid #f0f0f0;
76
+ border-radius: 0.75rem;
77
+ padding: 1.5rem;
78
+ box-shadow: 0 1px 3px rgba(0,0,0,0.04);
79
+ }
80
+
81
+ /* Scrollbar for admin */
82
+ [data-admin] ::-webkit-scrollbar { width: 6px; }
83
+ [data-admin] ::-webkit-scrollbar-track { background: transparent; }
84
+ [data-admin] ::-webkit-scrollbar-thumb { background: #ddd; border-radius: 3px; }
85
+ [data-admin] ::-webkit-scrollbar-thumb:hover { background: #bbb; }
@@ -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
+ }