@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
@@ -1,320 +1,421 @@
1
- "use client";
2
-
3
- /**
4
- * Full-size section card icons (220×120) used in the Add Section modal.
5
- *
6
- * Same visual language as `BlockCardIcons.tsx` but violet-tinted to
7
- * differentiate sections from blocks:
8
- * - accent: #7500D5 (block equivalent: #4794E2)
9
- * - ghost fill: #E8DFF2 (block equivalent: #DDE6F5)
10
- * - neutral stroke:#D6C9E2 (block equivalent: #C9D3E4)
11
- * - bevel end: #EBEAEF (block equivalent: #E6ECF6)
12
- *
13
- * IDs are namespaced per icon (`seSec`, `scSec`, `spgSec`, `spSec`, `sccSec`,
14
- * `ssSec`) so multiple cards can render side by side without collisions.
15
- */
16
-
17
- import { Bg, BgDefs, ShadowFilter, VertBevel } from "./iconPrimitives";
18
-
19
- // Section-specific colour tokens
20
- const ACCENT = "#7500D5";
21
- const GHOST = "#E8DFF2";
22
- const NEUTRAL_STROKE = "#D6C9E2";
23
- const BEVEL_END = "#EBEAEF";
24
-
25
- // ─────────────────────────────────────────────────────────────────────
26
- // Empty Section — frame + 4 ghost columns
27
- // ─────────────────────────────────────────────────────────────────────
28
- export function EmptySectionV2CardIcon() {
29
- return (
30
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
31
- <defs>
32
- <BgDefs prefix="seSec" />
33
- <ShadowFilter id="shadSeSec" />
34
- <VertBevel id="bevelSeSec" endColor={BEVEL_END} />
35
- </defs>
36
- <Bg prefix="seSec" />
37
-
38
- <g filter="url(#shadSeSec)">
39
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
40
- fill="url(#bevelSeSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
41
- </g>
42
- <g fill={GHOST}>
43
- <path d="M51.3,24.9H33.4c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C53.8,26.1,52.6,24.9,51.3,24.9z" />
44
- <path d="M78.3,24.9H60.4c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C80.8,26.1,79.7,24.9,78.3,24.9z" />
45
- <path d="M105.1,24.9H87.2c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C107.6,26.1,106.5,24.9,105.1,24.9z" />
46
- <path d="M132.2,24.9h-17.9c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C134.7,26.1,133.6,24.9,132.2,24.9z" />
47
- </g>
48
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
49
- fill="none" stroke={ACCENT} strokeWidth="2" strokeDasharray="3,3" />
50
- </svg>
51
- );
52
- }
53
-
54
- // ─────────────────────────────────────────────────────────────────────
55
- // Cover Section — frame + vertical + horizontal dimension arrows
56
- // ─────────────────────────────────────────────────────────────────────
57
- export function CoverSectionCardIcon() {
58
- return (
59
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
60
- <defs>
61
- <BgDefs prefix="scSec" />
62
- <ShadowFilter id="shadScSec" />
63
- <VertBevel id="bevelScSec" endColor={BEVEL_END} />
64
- </defs>
65
- <Bg prefix="scSec" />
66
-
67
- <g filter="url(#shadScSec)">
68
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
69
- fill="url(#bevelScSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
70
- </g>
71
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
72
- fill="none" stroke={ACCENT} strokeWidth="2" strokeDasharray="3,3" />
73
-
74
- {/* Vertical height arrow */}
75
- <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
76
- <line x1="82.4" y1="30.1" x2="82.4" y2="88.8" />
77
- <polygon points="82.4,23 78.4,33 82.4,30.6 86.5,33" />
78
- <polygon points="82.4,95.9 78.4,85.9 82.4,88.3 86.5,85.9" />
79
- </g>
80
-
81
- {/* Horizontal width arrow */}
82
- <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
83
- <line x1="127.9" y1="59.4" x2="34.5" y2="59.4" />
84
- <polygon points="135.4,59.4 125.4,55.4 127.8,59.4 125.4,63.5" />
85
- <polygon points="29.4,59.4 39.4,55.4 37,59.4 39.4,63.5" />
86
- </g>
87
- </svg>
88
- );
89
- }
90
-
91
- // ─────────────────────────────────────────────────────────────────────
92
- // Project Grid — 5 masonry tiles
93
- // ─────────────────────────────────────────────────────────────────────
94
- export function ProjectGridCardIcon() {
95
- return (
96
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
97
- <defs>
98
- <BgDefs prefix="spgSec" />
99
- <ShadowFilter id="shadSpgSec" />
100
- <VertBevel id="tileBevelSpgSec" endColor={BEVEL_END} />
101
- </defs>
102
- <Bg prefix="spgSec" />
103
-
104
- {/* 5 masonry tiles with shadow */}
105
- <g filter="url(#shadSpgSec)">
106
- <path d="M25.8,19h30.8c1,0,1.8,0.8,1.8,1.8v76.9c0,1-0.8,1.8-1.8,1.8H25.8c-1,0-1.8-0.8-1.8-1.8V20.8C24,19.8,24.8,19,25.8,19z"
107
- fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
108
- <path d="M67.5,19h30.8c1,0,1.8,0.8,1.8,1.8v38.4c0,1-0.8,1.8-1.8,1.8H67.5c-1,0-1.8-0.8-1.8-1.8V20.8C65.6,19.8,66.5,19,67.5,19z"
109
- fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
110
- <path d="M109.1,19h30.8c1,0,1.8,0.8,1.8,1.8v53.1c0,1-0.8,1.8-1.8,1.8h-30.8c-1,0-1.8-0.8-1.8-1.8V20.8C107.3,19.8,108.1,19,109.1,19z"
111
- fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
112
- <path d="M66.8,67h30.8c1,0,1.8,0.8,1.8,1.8v29.3c0,1-0.8,1.8-1.8,1.8H66.8c-1,0-1.8-0.8-1.8-1.8V68.8C65,67.8,65.8,67,66.8,67z"
113
- fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
114
- <path d="M139.6,99.7h-30.3c-1.2,0-2.1-0.9-2.1-2.1V81.4c0-1.2,0.9-2.1,2.1-2.1h30.3c1.2,0,2.1,0.9,2.1,2.1v16.2C141.6,98.8,140.7,99.7,139.6,99.7z"
115
- fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
116
- </g>
117
-
118
- {/* Inner ghost content */}
119
- <g fill={GHOST}>
120
- <path d="M28.7,22.6h25c0.6,0,1.1,0.5,1.1,1.1v54.5c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V23.7C27.7,23.1,28.1,22.6,28.7,22.6z" />
121
- <path d="M70.4,22.6h25c0.6,0,1.1,0.5,1.1,1.1v23.4c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V23.7C69.3,23.1,69.7,22.6,70.4,22.6z" />
122
- <path d="M112,22.6h25c0.6,0,1.1,0.5,1.1,1.1v38.1c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V23.7C110.9,23.1,111.3,22.6,112,22.6z" />
123
- <path d="M69.7,70.7h25c0.6,0,1.1,0.5,1.1,1.1v17.9c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V71.8C68.6,71.2,69.2,70.7,69.7,70.7z" />
124
- <path d="M137.5,96.2h-25.7c-0.7,0-1.4-0.6-1.4-1.4V84c0-0.7,0.6-1.4,1.4-1.4h25.7c0.7,0,1.4,0.6,1.4,1.4v10.8C138.7,95.6,138.2,96.2,137.5,96.2z" />
125
- <path d="M28.6,83h18.1c0.5,0,0.9,0.4,0.9,0.9v0.9c0,0.5-0.4,0.9-0.9,0.9H28.6c-0.5,0-0.9-0.4-0.9-0.9v-0.9C27.7,83.4,28,83,28.6,83z" />
126
- <path d="M28.6,88.5h10.9c0.5,0,0.9,0.4,0.9,0.9v0.9c0,0.5-0.4,0.9-0.9,0.9H28.6c-0.5,0-0.9-0.4-0.9-0.9v-0.9C27.7,88.9,28,88.5,28.6,88.5z" />
127
- </g>
128
-
129
- {/* Dashed violet outlines on all tiles */}
130
- <g fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3">
131
- <path d="M25.8,19h30.8c1,0,1.8,0.8,1.8,1.8v76.9c0,1-0.8,1.8-1.8,1.8H25.8c-1,0-1.8-0.8-1.8-1.8V20.8C24,19.8,24.8,19,25.8,19z" />
132
- <path d="M67.5,19h30.8c1,0,1.8,0.8,1.8,1.8v38.4c0,1-0.8,1.8-1.8,1.8H67.5c-1,0-1.8-0.8-1.8-1.8V20.8C65.6,19.8,66.5,19,67.5,19z" />
133
- <path d="M109.1,19h30.8c1,0,1.8,0.8,1.8,1.8v53.1c0,1-0.8,1.8-1.8,1.8h-30.8c-1,0-1.8-0.8-1.8-1.8V20.8C107.3,19.8,108.1,19,109.1,19z" />
134
- <path d="M66.8,67h30.8c1,0,1.8,0.8,1.8,1.8v29.3c0,1-0.8,1.8-1.8,1.8H66.8c-1,0-1.8-0.8-1.8-1.8V68.8C65,67.8,65.8,67,66.8,67z" />
135
- <path d="M139.6,99.7h-30.3c-1.2,0-2.1-0.9-2.1-2.1V81.4c0-1.2,0.9-2.1,2.1-2.1h30.3c1.2,0,2.1,0.9,2.1,2.1v16.2C141.6,98.8,140.7,99.7,139.6,99.7z" />
136
- </g>
137
- </svg>
138
- );
139
- }
140
-
141
- // ─────────────────────────────────────────────────────────────────────
142
- // Parallax Group — 3 stacked slides with image content
143
- // ─────────────────────────────────────────────────────────────────────
144
- export function ParallaxGroupCardIcon() {
145
- return (
146
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
147
- <defs>
148
- <BgDefs prefix="spSec" />
149
- <ShadowFilter id="shadSpSec" />
150
- <VertBevel id="slideBevelSpSec" endColor={BEVEL_END} />
151
- </defs>
152
- <Bg prefix="spSec" />
153
-
154
- {/* Slide 1 (back/smallest) */}
155
- <g filter="url(#shadSpSec)">
156
- <path d="M62.1,18.7H105c0.5,0,0.9,0.3,0.9,0.7v19.5c0,0.4-0.4,0.7-0.9,0.7H62.1c-0.5,0-0.9-0.3-0.9-0.7V19.4C61.2,19,61.6,18.7,62.1,18.7z"
157
- fill="url(#slideBevelSpSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
158
- </g>
159
- <path d="M66.8,22.6h33.5c0.2,0,0.5,0.1,0.5,0.3v12.4c0,0.2-0.2,0.3-0.5,0.3H66.8c-0.2,0-0.5-0.1-0.5-0.3V22.9C66.3,22.7,66.5,22.6,66.8,22.6z"
160
- fill={GHOST} />
161
- <ellipse cx="95.2" cy="26.5" rx="1.5" ry="1.5" fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
162
- <path d="M69.1,32.7l3.9-4.2c0.3-0.3,0.7-0.3,1,0l2.2,2.1c0.3,0.3,0.7,0.3,1,0l2-1.9c0.2-0.2,0.6-0.3,0.9-0.1l6,3.9c0.6,0.3,0.3,1.2-0.4,1.2H69.6C69.1,33.8,68.7,33.1,69.1,32.7z"
163
- fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
164
- <path d="M62.6,18.7h41.8c0.5,0,0.9,0.3,0.9,0.7v19.5c0,0.4-0.4,0.7-0.9,0.7H62.6c-0.5,0-0.9-0.3-0.9-0.7V19.4C61.8,19,62.1,18.7,62.6,18.7z"
165
- fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
166
-
167
- {/* Slide 2 (middle) */}
168
- <g filter="url(#shadSpSec)">
169
- <path d="M49.6,34h67.9c0.8,0,1.4,0.5,1.4,1.1v30.8c0,0.6-0.7,1.1-1.4,1.1H49.6c-0.8,0-1.4-0.5-1.4-1.1V35.1C48.2,34.5,48.8,34,49.6,34z"
170
- fill="url(#slideBevelSpSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
171
- </g>
172
- <path d="M55.7,39.4h55.7c0.4,0,0.8,0.2,0.8,0.5v21.7c0,0.3-0.3,0.5-0.8,0.5H55.7c-0.4,0-0.8-0.2-0.8-0.5V39.9C55,39.6,55.3,39.4,55.7,39.4z"
173
- fill={GHOST} />
174
- <ellipse cx="102.2" cy="44.3" rx="2.4" ry="2.4" fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
175
- <path d="M60.3,56.6l8.7-9.8c0.6-0.6,1.6-0.7,2.2,0l5,5c0.6,0.6,1.5,0.6,2.1,0l4.4-4.4c0.5-0.5,1.3-0.6,1.9-0.2l13.3,9.2c1.2,0.8,0.6,2.8-0.9,2.8H61.4C60.1,59.1,59.4,57.5,60.3,56.6z"
176
- fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
177
- <path d="M50.4,34h66.3c0.8,0,1.4,0.5,1.4,1.1v30.8c0,0.6-0.6,1.1-1.4,1.1H50.4c-0.8,0-1.4-0.5-1.4-1.1V35.1C49.1,34.5,49.6,34,50.4,34z"
178
- fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
179
-
180
- {/* Slide 3 (front/largest) */}
181
- <g filter="url(#shadSpSec)">
182
- <path d="M34,51.6h99c1.1,0,2,0.7,2,1.6v45c0,0.9-1,1.6-2,1.6H34c-1.1-0.1-2-0.8-2-1.6v-45C32,52.3,32.9,51.6,34,51.6z"
183
- fill="url(#slideBevelSpSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
184
- </g>
185
- <path d="M41.3,58.1h84.5c0.6,0,1.1,0.4,1.1,0.8v33.5c0,0.5-0.5,0.8-1.1,0.8H41.3c-0.6,0-1.1-0.4-1.1-0.8V58.9C40.2,58.4,40.7,58.1,41.3,58.1z"
186
- fill={GHOST} />
187
- <ellipse cx="110.8" cy="66.7" rx="3.5" ry="3.5" fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
188
- <path d="M47.6,84.9l12.7-14.4c0.9-0.9,2.3-1,3.2-0.1l7.2,7.3c0.9,0.9,2.2,0.9,3.1,0l6.4-6.4c0.7-0.7,1.9-0.9,2.8-0.2l19.3,13.4c1.8,1.2,0.9,4.1-1.2,4.1h-52C47.4,88.6,46.4,86.3,47.6,84.9z"
189
- fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
190
- <path d="M35.2,51.6h96.6c1.1,0,2,0.7,2,1.6v45c0,0.9-0.9,1.6-2,1.6H35.2c-1.1-0.1-2-0.8-2-1.6v-45C33.2,52.3,34.1,51.6,35.2,51.6z"
191
- fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
192
-
193
- {/* Scroll arrow on the right */}
194
- <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
195
- <line x1="150.1" y1="17.6" x2="150.1" y2="88.3" />
196
- <polygon points="150.1,96.8 145.3,84.8 150.1,87.7 155,84.8" />
197
- </g>
198
- </svg>
199
- );
200
- }
201
-
202
- // ─────────────────────────────────────────────────────────────────────
203
- // Create Custom Section — frame + circle + plus
204
- // ─────────────────────────────────────────────────────────────────────
205
- export function CreateCustomSectionCardIcon() {
206
- return (
207
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
208
- <defs>
209
- <BgDefs prefix="sccSec" />
210
- <ShadowFilter id="shadSccSec" />
211
- <VertBevel id="bevelSccSec" endColor={BEVEL_END} />
212
- </defs>
213
- <Bg prefix="sccSec" />
214
-
215
- <g filter="url(#shadSccSec)">
216
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
217
- fill="url(#bevelSccSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
218
- </g>
219
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
220
- fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
221
-
222
- <circle cx="82.8" cy="59.2" r="16.9" fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
223
- <line x1="82.8" y1="50.2" x2="82.8" y2="67.7" fill="none" stroke={ACCENT} strokeWidth="3" strokeLinecap="round" strokeMiterlimit="10" />
224
- <line x1="74" y1="58.9" x2="91.5" y2="58.9" fill="none" stroke={ACCENT} strokeWidth="3" strokeLinecap="round" strokeMiterlimit="10" />
225
- </svg>
226
- );
227
- }
228
-
229
- // ─────────────────────────────────────────────────────────────────────
230
- // Saved Custom Section — frame + save/download icon
231
- // ─────────────────────────────────────────────────────────────────────
232
- export function SavedSectionCardIcon() {
233
- return (
234
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
235
- <defs>
236
- <BgDefs prefix="ssSec" />
237
- <ShadowFilter id="shadSsSec" />
238
- <VertBevel id="bevelSsSec" endColor={BEVEL_END} />
239
- </defs>
240
- <Bg prefix="ssSec" />
241
-
242
- <g filter="url(#shadSsSec)">
243
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
244
- fill="url(#bevelSsSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
245
- </g>
246
- <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
247
- fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
248
-
249
- {/* Save/download icon */}
250
- <path fill={ACCENT}
251
- d="M69.4,39.5c-0.7,0-1.2,0.5-1.2,1.2v34.2c0,0.7,0.5,1.2,1.2,1.2h28.5c0.7,0,1.2-0.5,1.2-1.2V49.7c0-0.3-0.1-0.6-0.4-0.8l-9.1-9.1h0c-0.2-0.2-0.5-0.3-0.8-0.3L69.4,39.5z M70.6,41.9h17.8l8.3,8.4v23.5H70.6V41.9z M83.7,47.6c-0.7,0-1.2,0.5-1.2,1.2v11.5l-2-2h0C80.3,58.1,80,58,79.6,58c-0.3,0-0.6,0.1-0.9,0.4c-0.5,0.5-0.5,1.2,0,1.7l4,4c0.2,0.2,0.4,0.3,0.8,0.3c0.3,0,0.6-0.1,0.8-0.3l4-4c0.5-0.5,0.5-1.2,0-1.7c-0.5-0.5-1.2-0.5-1.7,0l-2,2V48.8C84.9,48.2,84.3,47.6,83.7,47.6L83.7,47.6z M78.1,65.5c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2h11.2c0.7,0,1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2H78.1z" />
252
- </svg>
253
- );
254
- }
255
-
256
- // ─────────────────────────────────────────────────────────────────────
257
- // Project Carousel — 3 horizontal cards with navigation arrows
258
- // ─────────────────────────────────────────────────────────────────────
259
- export function ProjectCarouselCardIcon() {
260
- return (
261
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
262
- <defs>
263
- <BgDefs prefix="pcarSec" />
264
- <ShadowFilter id="shadPcarSec" />
265
- <VertBevel id="cardBevelPcarSec" endColor={BEVEL_END} />
266
- </defs>
267
- <Bg prefix="pcarSec" />
268
-
269
- {/* 3 cards with shadow — center one is taller (featured) */}
270
- <g filter="url(#shadPcarSec)">
271
- {/* Card 1 (left) */}
272
- <path d="M25.7,30.1h29c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3h-29c-0.3,0-0.6-0.6-0.6-1.3V31.4C25.1,30.7,25.3,30.1,25.7,30.1z"
273
- fill="url(#cardBevelPcarSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
274
- {/* Card 2 (center, featured) */}
275
- <path d="M62,24.7h39.5c0.5,0,0.8,0.8,0.8,1.8v50c0,1-0.4,1.8-0.8,1.8H62c-0.5-0.1-0.8-0.9-0.8-1.8v-50C61.2,25.5,61.6,24.7,62,24.7z"
276
- fill="url(#cardBevelPcarSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
277
- {/* Card 3 (right) */}
278
- <path d="M108.7,30.1h29c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3h-29c-0.3,0-0.6-0.6-0.6-1.3V31.4C108.1,30.7,108.3,30.1,108.7,30.1z"
279
- fill="url(#cardBevelPcarSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
280
- </g>
281
-
282
- {/* Ghost content areas (image placeholders inside each card) */}
283
- <g fill={GHOST}>
284
- <path d="M28.1,33.2h24.1c0.2,0,0.3,0.2,0.3,0.5v20.2c0,0.3-0.1,0.5-0.3,0.5H28.1c-0.2,0-0.3-0.2-0.3-0.5V33.7C27.8,33.4,27.9,33.2,28.1,33.2z" />
285
- <path d="M65.4,28.9h32.8c0.2,0,0.4,0.3,0.4,0.7V57c0,0.4-0.2,0.7-0.4,0.7H65.4c-0.2,0-0.4-0.3-0.4-0.7V29.5C65,29.1,65.1,28.9,65.4,28.9z" />
286
- <path d="M111.1,33.2h24.1c0.2,0,0.3,0.2,0.3,0.5v20.2c0,0.3-0.1,0.5-0.3,0.5h-24.1c-0.2,0-0.3-0.2-0.3-0.5V33.7C110.8,33.4,111,33.2,111.1,33.2z" />
287
- </g>
288
-
289
- {/* Dashed violet outlines on all 3 cards */}
290
- <g fill="none" stroke={ACCENT} strokeWidth="2" strokeDasharray="3,3">
291
- <path d="M25.7,30.1H55c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3H25.7c-0.3,0-0.6-0.6-0.6-1.3V31.4C25.1,30.7,25.3,30.1,25.7,30.1z" />
292
- <path d="M62,24.7h39.9c0.5,0,0.8,0.8,0.8,1.8v50c0,1-0.4,1.8-0.8,1.8H62c-0.5-0.1-0.8-0.9-0.8-1.8v-50C61.2,25.5,61.6,24.7,62,24.7z" />
293
- <path d="M108.7,30.1H138c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3h-29.3c-0.3,0-0.6-0.6-0.6-1.3V31.4C108.1,30.7,108.3,30.1,108.7,30.1z" />
294
- </g>
295
-
296
- {/* Navigation arrows at the bottom — hint at horizontal swipe */}
297
- <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
298
- {/* Right arrow (pointing right) */}
299
- <line x1="103" y1="88.8" x2="136" y2="88.8" />
300
- <polygon points="139.9,88.8 134.4,91 135.7,88.8 134.4,86.5" />
301
- {/* Left arrow (pointing left) */}
302
- <line x1="63.6" y1="88.8" x2="30.6" y2="88.8" />
303
- <polygon points="26.6,88.8 32.2,86.5 30.8,88.8 32.2,91" />
304
- </g>
305
- </svg>
306
- );
307
- }
308
-
309
- // ─────────────────────────────────────────────────────────────────────
310
- // Lookup map for the Add Section modal
311
- // ─────────────────────────────────────────────────────────────────────
312
- export const SECTION_CARD_ICONS: Record<string, React.FC> = {
313
- "empty-v2": EmptySectionV2CardIcon,
314
- coverSection: CoverSectionCardIcon,
315
- projectGridBlock: ProjectGridCardIcon,
316
- projectCarouselBlock: ProjectCarouselCardIcon,
317
- parallaxGroup: ParallaxGroupCardIcon,
318
- createCustom: CreateCustomSectionCardIcon,
319
- savedCustom: SavedSectionCardIcon,
320
- };
1
+ "use client";
2
+
3
+ /**
4
+ * Full-size section card icons (220×120) used in the Add Section modal.
5
+ *
6
+ * Same visual language as `BlockCardIcons.tsx` but violet-tinted to
7
+ * differentiate sections from blocks:
8
+ * - accent: #7500D5 (block equivalent: #3580f9)
9
+ * - ghost fill: #E8DFF2 (block equivalent: #DDE6F5)
10
+ * - neutral stroke:#D6C9E2 (block equivalent: #C9D3E4)
11
+ * - bevel end: #EBEAEF (block equivalent: #E6ECF6)
12
+ *
13
+ * IDs are namespaced per icon (`seSec`, `scSec`, `spgSec`, `spSec`, `sccSec`,
14
+ * `ssSec`) so multiple cards can render side by side without collisions.
15
+ */
16
+
17
+ import { Bg, BgDefs, ShadowFilter, VertBevel } from "./iconPrimitives";
18
+
19
+ // Section-specific colour tokens
20
+ const ACCENT = "#7500D5";
21
+ const GHOST = "#E8DFF2";
22
+ const NEUTRAL_STROKE = "#D6C9E2";
23
+ const BEVEL_END = "#EBEAEF";
24
+
25
+ // ─────────────────────────────────────────────────────────────────────
26
+ // Empty Section — frame + 4 ghost columns
27
+ // ─────────────────────────────────────────────────────────────────────
28
+ export function EmptySectionV2CardIcon() {
29
+ return (
30
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
31
+ <defs>
32
+ <BgDefs prefix="seSec" />
33
+ <ShadowFilter id="shadSeSec" />
34
+ <VertBevel id="bevelSeSec" endColor={BEVEL_END} />
35
+ </defs>
36
+ <Bg prefix="seSec" />
37
+
38
+ <g filter="url(#shadSeSec)">
39
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
40
+ fill="url(#bevelSeSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
41
+ </g>
42
+ <g fill={GHOST}>
43
+ <path d="M51.3,24.9H33.4c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C53.8,26.1,52.6,24.9,51.3,24.9z" />
44
+ <path d="M78.3,24.9H60.4c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C80.8,26.1,79.7,24.9,78.3,24.9z" />
45
+ <path d="M105.1,24.9H87.2c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C107.6,26.1,106.5,24.9,105.1,24.9z" />
46
+ <path d="M132.2,24.9h-17.9c-1.4,0-2.5,1.1-2.5,2.5v63.3c0,1.4,1.1,2.5,2.5,2.5h17.9c1.4,0,2.5-1.1,2.5-2.5V27.4C134.7,26.1,133.6,24.9,132.2,24.9z" />
47
+ </g>
48
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
49
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeDasharray="3,3" />
50
+ </svg>
51
+ );
52
+ }
53
+
54
+ // ─────────────────────────────────────────────────────────────────────
55
+ // Cover Section — frame + vertical + horizontal dimension arrows
56
+ // ─────────────────────────────────────────────────────────────────────
57
+ export function CoverSectionCardIcon() {
58
+ return (
59
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
60
+ <defs>
61
+ <BgDefs prefix="scSec" />
62
+ <ShadowFilter id="shadScSec" />
63
+ <VertBevel id="bevelScSec" endColor={BEVEL_END} />
64
+ </defs>
65
+ <Bg prefix="scSec" />
66
+
67
+ <g filter="url(#shadScSec)">
68
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
69
+ fill="url(#bevelScSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
70
+ </g>
71
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
72
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeDasharray="3,3" />
73
+
74
+ {/* Vertical height arrow */}
75
+ <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
76
+ <line x1="82.4" y1="30.1" x2="82.4" y2="88.8" />
77
+ <polygon points="82.4,23 78.4,33 82.4,30.6 86.5,33" />
78
+ <polygon points="82.4,95.9 78.4,85.9 82.4,88.3 86.5,85.9" />
79
+ </g>
80
+
81
+ {/* Horizontal width arrow */}
82
+ <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
83
+ <line x1="127.9" y1="59.4" x2="34.5" y2="59.4" />
84
+ <polygon points="135.4,59.4 125.4,55.4 127.8,59.4 125.4,63.5" />
85
+ <polygon points="29.4,59.4 39.4,55.4 37,59.4 39.4,63.5" />
86
+ </g>
87
+ </svg>
88
+ );
89
+ }
90
+
91
+ // ─────────────────────────────────────────────────────────────────────
92
+ // Project Grid — 5 masonry tiles
93
+ // ─────────────────────────────────────────────────────────────────────
94
+ export function ProjectGridCardIcon() {
95
+ return (
96
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
97
+ <defs>
98
+ <BgDefs prefix="spgSec" />
99
+ <ShadowFilter id="shadSpgSec" />
100
+ <VertBevel id="tileBevelSpgSec" endColor={BEVEL_END} />
101
+ </defs>
102
+ <Bg prefix="spgSec" />
103
+
104
+ {/* 5 masonry tiles with shadow */}
105
+ <g filter="url(#shadSpgSec)">
106
+ <path d="M25.8,19h30.8c1,0,1.8,0.8,1.8,1.8v76.9c0,1-0.8,1.8-1.8,1.8H25.8c-1,0-1.8-0.8-1.8-1.8V20.8C24,19.8,24.8,19,25.8,19z"
107
+ fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
108
+ <path d="M67.5,19h30.8c1,0,1.8,0.8,1.8,1.8v38.4c0,1-0.8,1.8-1.8,1.8H67.5c-1,0-1.8-0.8-1.8-1.8V20.8C65.6,19.8,66.5,19,67.5,19z"
109
+ fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
110
+ <path d="M109.1,19h30.8c1,0,1.8,0.8,1.8,1.8v53.1c0,1-0.8,1.8-1.8,1.8h-30.8c-1,0-1.8-0.8-1.8-1.8V20.8C107.3,19.8,108.1,19,109.1,19z"
111
+ fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
112
+ <path d="M66.8,67h30.8c1,0,1.8,0.8,1.8,1.8v29.3c0,1-0.8,1.8-1.8,1.8H66.8c-1,0-1.8-0.8-1.8-1.8V68.8C65,67.8,65.8,67,66.8,67z"
113
+ fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
114
+ <path d="M139.6,99.7h-30.3c-1.2,0-2.1-0.9-2.1-2.1V81.4c0-1.2,0.9-2.1,2.1-2.1h30.3c1.2,0,2.1,0.9,2.1,2.1v16.2C141.6,98.8,140.7,99.7,139.6,99.7z"
115
+ fill="url(#tileBevelSpgSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.6" />
116
+ </g>
117
+
118
+ {/* Inner ghost content */}
119
+ <g fill={GHOST}>
120
+ <path d="M28.7,22.6h25c0.6,0,1.1,0.5,1.1,1.1v54.5c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V23.7C27.7,23.1,28.1,22.6,28.7,22.6z" />
121
+ <path d="M70.4,22.6h25c0.6,0,1.1,0.5,1.1,1.1v23.4c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V23.7C69.3,23.1,69.7,22.6,70.4,22.6z" />
122
+ <path d="M112,22.6h25c0.6,0,1.1,0.5,1.1,1.1v38.1c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V23.7C110.9,23.1,111.3,22.6,112,22.6z" />
123
+ <path d="M69.7,70.7h25c0.6,0,1.1,0.5,1.1,1.1v17.9c0,0.6-0.5,1.1-1.1,1.1h-25c-0.6,0-1.1-0.5-1.1-1.1V71.8C68.6,71.2,69.2,70.7,69.7,70.7z" />
124
+ <path d="M137.5,96.2h-25.7c-0.7,0-1.4-0.6-1.4-1.4V84c0-0.7,0.6-1.4,1.4-1.4h25.7c0.7,0,1.4,0.6,1.4,1.4v10.8C138.7,95.6,138.2,96.2,137.5,96.2z" />
125
+ <path d="M28.6,83h18.1c0.5,0,0.9,0.4,0.9,0.9v0.9c0,0.5-0.4,0.9-0.9,0.9H28.6c-0.5,0-0.9-0.4-0.9-0.9v-0.9C27.7,83.4,28,83,28.6,83z" />
126
+ <path d="M28.6,88.5h10.9c0.5,0,0.9,0.4,0.9,0.9v0.9c0,0.5-0.4,0.9-0.9,0.9H28.6c-0.5,0-0.9-0.4-0.9-0.9v-0.9C27.7,88.9,28,88.5,28.6,88.5z" />
127
+ </g>
128
+
129
+ {/* Dashed violet outlines on all tiles */}
130
+ <g fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3">
131
+ <path d="M25.8,19h30.8c1,0,1.8,0.8,1.8,1.8v76.9c0,1-0.8,1.8-1.8,1.8H25.8c-1,0-1.8-0.8-1.8-1.8V20.8C24,19.8,24.8,19,25.8,19z" />
132
+ <path d="M67.5,19h30.8c1,0,1.8,0.8,1.8,1.8v38.4c0,1-0.8,1.8-1.8,1.8H67.5c-1,0-1.8-0.8-1.8-1.8V20.8C65.6,19.8,66.5,19,67.5,19z" />
133
+ <path d="M109.1,19h30.8c1,0,1.8,0.8,1.8,1.8v53.1c0,1-0.8,1.8-1.8,1.8h-30.8c-1,0-1.8-0.8-1.8-1.8V20.8C107.3,19.8,108.1,19,109.1,19z" />
134
+ <path d="M66.8,67h30.8c1,0,1.8,0.8,1.8,1.8v29.3c0,1-0.8,1.8-1.8,1.8H66.8c-1,0-1.8-0.8-1.8-1.8V68.8C65,67.8,65.8,67,66.8,67z" />
135
+ <path d="M139.6,99.7h-30.3c-1.2,0-2.1-0.9-2.1-2.1V81.4c0-1.2,0.9-2.1,2.1-2.1h30.3c1.2,0,2.1,0.9,2.1,2.1v16.2C141.6,98.8,140.7,99.7,139.6,99.7z" />
136
+ </g>
137
+ </svg>
138
+ );
139
+ }
140
+
141
+ // ─────────────────────────────────────────────────────────────────────
142
+ // Parallax Group — 3 stacked slides with image content
143
+ // ─────────────────────────────────────────────────────────────────────
144
+ export function ParallaxGroupCardIcon() {
145
+ return (
146
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
147
+ <defs>
148
+ <BgDefs prefix="spSec" />
149
+ <ShadowFilter id="shadSpSec" />
150
+ <VertBevel id="slideBevelSpSec" endColor={BEVEL_END} />
151
+ </defs>
152
+ <Bg prefix="spSec" />
153
+
154
+ {/* Slide 1 (back/smallest) */}
155
+ <g filter="url(#shadSpSec)">
156
+ <path d="M62.1,18.7H105c0.5,0,0.9,0.3,0.9,0.7v19.5c0,0.4-0.4,0.7-0.9,0.7H62.1c-0.5,0-0.9-0.3-0.9-0.7V19.4C61.2,19,61.6,18.7,62.1,18.7z"
157
+ fill="url(#slideBevelSpSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
158
+ </g>
159
+ <path d="M66.8,22.6h33.5c0.2,0,0.5,0.1,0.5,0.3v12.4c0,0.2-0.2,0.3-0.5,0.3H66.8c-0.2,0-0.5-0.1-0.5-0.3V22.9C66.3,22.7,66.5,22.6,66.8,22.6z"
160
+ fill={GHOST} />
161
+ <ellipse cx="95.2" cy="26.5" rx="1.5" ry="1.5" fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
162
+ <path d="M69.1,32.7l3.9-4.2c0.3-0.3,0.7-0.3,1,0l2.2,2.1c0.3,0.3,0.7,0.3,1,0l2-1.9c0.2-0.2,0.6-0.3,0.9-0.1l6,3.9c0.6,0.3,0.3,1.2-0.4,1.2H69.6C69.1,33.8,68.7,33.1,69.1,32.7z"
163
+ fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
164
+ <path d="M62.6,18.7h41.8c0.5,0,0.9,0.3,0.9,0.7v19.5c0,0.4-0.4,0.7-0.9,0.7H62.6c-0.5,0-0.9-0.3-0.9-0.7V19.4C61.8,19,62.1,18.7,62.6,18.7z"
165
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
166
+
167
+ {/* Slide 2 (middle) */}
168
+ <g filter="url(#shadSpSec)">
169
+ <path d="M49.6,34h67.9c0.8,0,1.4,0.5,1.4,1.1v30.8c0,0.6-0.7,1.1-1.4,1.1H49.6c-0.8,0-1.4-0.5-1.4-1.1V35.1C48.2,34.5,48.8,34,49.6,34z"
170
+ fill="url(#slideBevelSpSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
171
+ </g>
172
+ <path d="M55.7,39.4h55.7c0.4,0,0.8,0.2,0.8,0.5v21.7c0,0.3-0.3,0.5-0.8,0.5H55.7c-0.4,0-0.8-0.2-0.8-0.5V39.9C55,39.6,55.3,39.4,55.7,39.4z"
173
+ fill={GHOST} />
174
+ <ellipse cx="102.2" cy="44.3" rx="2.4" ry="2.4" fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
175
+ <path d="M60.3,56.6l8.7-9.8c0.6-0.6,1.6-0.7,2.2,0l5,5c0.6,0.6,1.5,0.6,2.1,0l4.4-4.4c0.5-0.5,1.3-0.6,1.9-0.2l13.3,9.2c1.2,0.8,0.6,2.8-0.9,2.8H61.4C60.1,59.1,59.4,57.5,60.3,56.6z"
176
+ fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
177
+ <path d="M50.4,34h66.3c0.8,0,1.4,0.5,1.4,1.1v30.8c0,0.6-0.6,1.1-1.4,1.1H50.4c-0.8,0-1.4-0.5-1.4-1.1V35.1C49.1,34.5,49.6,34,50.4,34z"
178
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
179
+
180
+ {/* Slide 3 (front/largest) */}
181
+ <g filter="url(#shadSpSec)">
182
+ <path d="M34,51.6h99c1.1,0,2,0.7,2,1.6v45c0,0.9-1,1.6-2,1.6H34c-1.1-0.1-2-0.8-2-1.6v-45C32,52.3,32.9,51.6,34,51.6z"
183
+ fill="url(#slideBevelSpSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
184
+ </g>
185
+ <path d="M41.3,58.1h84.5c0.6,0,1.1,0.4,1.1,0.8v33.5c0,0.5-0.5,0.8-1.1,0.8H41.3c-0.6,0-1.1-0.4-1.1-0.8V58.9C40.2,58.4,40.7,58.1,41.3,58.1z"
186
+ fill={GHOST} />
187
+ <ellipse cx="110.8" cy="66.7" rx="3.5" ry="3.5" fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
188
+ <path d="M47.6,84.9l12.7-14.4c0.9-0.9,2.3-1,3.2-0.1l7.2,7.3c0.9,0.9,2.2,0.9,3.1,0l6.4-6.4c0.7-0.7,1.9-0.9,2.8-0.2l19.3,13.4c1.8,1.2,0.9,4.1-1.2,4.1h-52C47.4,88.6,46.4,86.3,47.6,84.9z"
189
+ fill="#FFFFFF" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
190
+ <path d="M35.2,51.6h96.6c1.1,0,2,0.7,2,1.6v45c0,0.9-0.9,1.6-2,1.6H35.2c-1.1-0.1-2-0.8-2-1.6v-45C33.2,52.3,34.1,51.6,35.2,51.6z"
191
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
192
+
193
+ {/* Scroll arrow on the right */}
194
+ <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
195
+ <line x1="150.1" y1="17.6" x2="150.1" y2="88.3" />
196
+ <polygon points="150.1,96.8 145.3,84.8 150.1,87.7 155,84.8" />
197
+ </g>
198
+ </svg>
199
+ );
200
+ }
201
+
202
+ // ─────────────────────────────────────────────────────────────────────
203
+ // Create Custom Section — frame + circle + plus
204
+ // ─────────────────────────────────────────────────────────────────────
205
+ export function CreateCustomSectionCardIcon() {
206
+ return (
207
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
208
+ <defs>
209
+ <BgDefs prefix="sccSec" />
210
+ <ShadowFilter id="shadSccSec" />
211
+ <VertBevel id="bevelSccSec" endColor={BEVEL_END} />
212
+ </defs>
213
+ <Bg prefix="sccSec" />
214
+
215
+ <g filter="url(#shadSccSec)">
216
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
217
+ fill="url(#bevelSccSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
218
+ </g>
219
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
220
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
221
+
222
+ <circle cx="82.8" cy="59.2" r="16.9" fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" />
223
+ <line x1="82.8" y1="50.2" x2="82.8" y2="67.7" fill="none" stroke={ACCENT} strokeWidth="3" strokeLinecap="round" strokeMiterlimit="10" />
224
+ <line x1="74" y1="58.9" x2="91.5" y2="58.9" fill="none" stroke={ACCENT} strokeWidth="3" strokeLinecap="round" strokeMiterlimit="10" />
225
+ </svg>
226
+ );
227
+ }
228
+
229
+ // ─────────────────────────────────────────────────────────────────────
230
+ // Saved Custom Section — frame + save/download icon
231
+ // ─────────────────────────────────────────────────────────────────────
232
+ export function SavedSectionCardIcon() {
233
+ return (
234
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
235
+ <defs>
236
+ <BgDefs prefix="ssSec" />
237
+ <ShadowFilter id="shadSsSec" />
238
+ <VertBevel id="bevelSsSec" endColor={BEVEL_END} />
239
+ </defs>
240
+ <Bg prefix="ssSec" />
241
+
242
+ <g filter="url(#shadSsSec)">
243
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
244
+ fill="url(#bevelSsSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
245
+ </g>
246
+ <path d="M26.8,19h112.7c1.3,0,2.3,1.2,2.3,2.7v75c0,1.5-1.1,2.7-2.3,2.7H26.8c-1.3-0.1-2.3-1.3-2.3-2.7V21.6C24.5,20.2,25.5,19,26.8,19z"
247
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
248
+
249
+ {/* Save/download icon */}
250
+ <path fill={ACCENT}
251
+ d="M69.4,39.5c-0.7,0-1.2,0.5-1.2,1.2v34.2c0,0.7,0.5,1.2,1.2,1.2h28.5c0.7,0,1.2-0.5,1.2-1.2V49.7c0-0.3-0.1-0.6-0.4-0.8l-9.1-9.1h0c-0.2-0.2-0.5-0.3-0.8-0.3L69.4,39.5z M70.6,41.9h17.8l8.3,8.4v23.5H70.6V41.9z M83.7,47.6c-0.7,0-1.2,0.5-1.2,1.2v11.5l-2-2h0C80.3,58.1,80,58,79.6,58c-0.3,0-0.6,0.1-0.9,0.4c-0.5,0.5-0.5,1.2,0,1.7l4,4c0.2,0.2,0.4,0.3,0.8,0.3c0.3,0,0.6-0.1,0.8-0.3l4-4c0.5-0.5,0.5-1.2,0-1.7c-0.5-0.5-1.2-0.5-1.7,0l-2,2V48.8C84.9,48.2,84.3,47.6,83.7,47.6L83.7,47.6z M78.1,65.5c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2h11.2c0.7,0,1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2H78.1z" />
252
+ </svg>
253
+ );
254
+ }
255
+
256
+ // ─────────────────────────────────────────────────────────────────────
257
+ // Project Carousel — 3 horizontal cards with navigation arrows
258
+ // ─────────────────────────────────────────────────────────────────────
259
+ export function ProjectCarouselCardIcon() {
260
+ return (
261
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
262
+ <defs>
263
+ <BgDefs prefix="pcarSec" />
264
+ <ShadowFilter id="shadPcarSec" />
265
+ <VertBevel id="cardBevelPcarSec" endColor={BEVEL_END} />
266
+ </defs>
267
+ <Bg prefix="pcarSec" />
268
+
269
+ {/* 3 cards with shadow — center one is taller (featured) */}
270
+ <g filter="url(#shadPcarSec)">
271
+ {/* Card 1 (left) */}
272
+ <path d="M25.7,30.1h29c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3h-29c-0.3,0-0.6-0.6-0.6-1.3V31.4C25.1,30.7,25.3,30.1,25.7,30.1z"
273
+ fill="url(#cardBevelPcarSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
274
+ {/* Card 2 (center, featured) */}
275
+ <path d="M62,24.7h39.5c0.5,0,0.8,0.8,0.8,1.8v50c0,1-0.4,1.8-0.8,1.8H62c-0.5-0.1-0.8-0.9-0.8-1.8v-50C61.2,25.5,61.6,24.7,62,24.7z"
276
+ fill="url(#cardBevelPcarSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
277
+ {/* Card 3 (right) */}
278
+ <path d="M108.7,30.1h29c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3h-29c-0.3,0-0.6-0.6-0.6-1.3V31.4C108.1,30.7,108.3,30.1,108.7,30.1z"
279
+ fill="url(#cardBevelPcarSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
280
+ </g>
281
+
282
+ {/* Ghost content areas (image placeholders inside each card) */}
283
+ <g fill={GHOST}>
284
+ <path d="M28.1,33.2h24.1c0.2,0,0.3,0.2,0.3,0.5v20.2c0,0.3-0.1,0.5-0.3,0.5H28.1c-0.2,0-0.3-0.2-0.3-0.5V33.7C27.8,33.4,27.9,33.2,28.1,33.2z" />
285
+ <path d="M65.4,28.9h32.8c0.2,0,0.4,0.3,0.4,0.7V57c0,0.4-0.2,0.7-0.4,0.7H65.4c-0.2,0-0.4-0.3-0.4-0.7V29.5C65,29.1,65.1,28.9,65.4,28.9z" />
286
+ <path d="M111.1,33.2h24.1c0.2,0,0.3,0.2,0.3,0.5v20.2c0,0.3-0.1,0.5-0.3,0.5h-24.1c-0.2,0-0.3-0.2-0.3-0.5V33.7C110.8,33.4,111,33.2,111.1,33.2z" />
287
+ </g>
288
+
289
+ {/* Dashed violet outlines on all 3 cards */}
290
+ <g fill="none" stroke={ACCENT} strokeWidth="2" strokeDasharray="3,3">
291
+ <path d="M25.7,30.1H55c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3H25.7c-0.3,0-0.6-0.6-0.6-1.3V31.4C25.1,30.7,25.3,30.1,25.7,30.1z" />
292
+ <path d="M62,24.7h39.9c0.5,0,0.8,0.8,0.8,1.8v50c0,1-0.4,1.8-0.8,1.8H62c-0.5-0.1-0.8-0.9-0.8-1.8v-50C61.2,25.5,61.6,24.7,62,24.7z" />
293
+ <path d="M108.7,30.1H138c0.3,0,0.6,0.6,0.6,1.3v36.7c0,0.7-0.3,1.3-0.6,1.3h-29.3c-0.3,0-0.6-0.6-0.6-1.3V31.4C108.1,30.7,108.3,30.1,108.7,30.1z" />
294
+ </g>
295
+
296
+ {/* Navigation arrows at the bottom — hint at horizontal swipe */}
297
+ <g fill={ACCENT} stroke={ACCENT} strokeMiterlimit="10">
298
+ {/* Right arrow (pointing right) */}
299
+ <line x1="103" y1="88.8" x2="136" y2="88.8" />
300
+ <polygon points="139.9,88.8 134.4,91 135.7,88.8 134.4,86.5" />
301
+ {/* Left arrow (pointing left) */}
302
+ <line x1="63.6" y1="88.8" x2="30.6" y2="88.8" />
303
+ <polygon points="26.6,88.8 32.2,86.5 30.8,88.8 32.2,91" />
304
+ </g>
305
+ </svg>
306
+ );
307
+ }
308
+
309
+ // ─────────────────────────────────────────────────────────────────────
310
+ // Marquee featured "Aa" card centered, two partial cards fading off
311
+ // the left/right edges to suggest horizontal scroll, plus bidirectional
312
+ // arrows. Preserves the coordinates from the user-provided mockup
313
+ // (`docs/mockups/icons-v2/section-marquee.svg`) and adds the shadow the
314
+ // mockup was missing via the shared `ShadowFilter`.
315
+ // ─────────────────────────────────────────────────────────────────────
316
+ export function MarqueeCardIcon() {
317
+ return (
318
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 120" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
319
+ <defs>
320
+ <BgDefs prefix="mqSec" />
321
+ <ShadowFilter id="shadMqSec" />
322
+ <VertBevel id="bevelMqSec" endColor={BEVEL_END} />
323
+
324
+ {/* Left partial card — transparent at the off-screen edge,
325
+ opaque where it meets the featured card. */}
326
+ <linearGradient id="mqSecLFill" x1="-40.3" x2="34" y1="0" y2="0" gradientUnits="userSpaceOnUse">
327
+ <stop offset="0" stopColor="#FFFFFF" stopOpacity="0" />
328
+ <stop offset="1" stopColor={BEVEL_END} />
329
+ </linearGradient>
330
+ <linearGradient id="mqSecLStroke" x1="-42.1" x2="35.9" y1="0" y2="0" gradientUnits="userSpaceOnUse">
331
+ <stop offset="0.514" stopColor={NEUTRAL_STROKE} stopOpacity="0" />
332
+ <stop offset="1" stopColor={NEUTRAL_STROKE} />
333
+ </linearGradient>
334
+ <linearGradient id="mqSecLGhost" x1="-35.8" x2="29.7" y1="0" y2="0" gradientUnits="userSpaceOnUse">
335
+ <stop offset="0.7172" stopColor={GHOST} stopOpacity="0" />
336
+ <stop offset="1" stopColor={GHOST} />
337
+ </linearGradient>
338
+ <linearGradient id="mqSecLDash" x1="-42.66" x2="37.14" y1="0" y2="0" gradientUnits="userSpaceOnUse">
339
+ <stop offset="0.7328" stopColor={ACCENT} stopOpacity="0" />
340
+ <stop offset="1" stopColor={ACCENT} />
341
+ </linearGradient>
342
+
343
+ {/* Right partial card — mirrored: opaque where it meets the
344
+ featured card, transparent at the off-screen edge. */}
345
+ <linearGradient id="mqSecRFill" x1="208.6" x2="134.3" y1="0" y2="0" gradientUnits="userSpaceOnUse">
346
+ <stop offset="0" stopColor="#FFFFFF" stopOpacity="0" />
347
+ <stop offset="1" stopColor={BEVEL_END} />
348
+ </linearGradient>
349
+ <linearGradient id="mqSecRStroke" x1="210.4" x2="132.4" y1="0" y2="0" gradientUnits="userSpaceOnUse">
350
+ <stop offset="0.514" stopColor={NEUTRAL_STROKE} stopOpacity="0" />
351
+ <stop offset="1" stopColor={NEUTRAL_STROKE} />
352
+ </linearGradient>
353
+ <linearGradient id="mqSecRGhost" x1="204.1" x2="138.6" y1="0" y2="0" gradientUnits="userSpaceOnUse">
354
+ <stop offset="0.7172" stopColor={GHOST} stopOpacity="0" />
355
+ <stop offset="1" stopColor={GHOST} />
356
+ </linearGradient>
357
+ <linearGradient id="mqSecRDash" x1="211" x2="131.2" y1="0" y2="0" gradientUnits="userSpaceOnUse">
358
+ <stop offset="0.7328" stopColor={ACCENT} stopOpacity="0" />
359
+ <stop offset="1" stopColor={ACCENT} />
360
+ </linearGradient>
361
+ </defs>
362
+ <Bg prefix="mqSec" />
363
+
364
+ {/* Left partial card */}
365
+ <path d="M-40.3,27.4h74.3c0.8,0,1.5,0.7,1.5,1.6v45c0,0.9-0.8,1.6-1.5,1.6h-74.3c-0.8-0.1-1.5-0.8-1.5-1.6V29C-41.8,28.1-41.1,27.4-40.3,27.4z"
366
+ fill="url(#mqSecLFill)" stroke="url(#mqSecLStroke)" strokeWidth="0.7" />
367
+ <path d="M-35,33.9h63.8c0.5,0,0.8,0.4,0.8,0.8v33.5c0,0.5-0.4,0.8-0.8,0.8H-35c-0.5,0-0.8-0.4-0.8-0.8V34.7C-35.8,34.2-35.4,33.9-35,33.9z"
368
+ fill="url(#mqSecLGhost)" />
369
+ <path d="M-40.1,27.4h74.7c0.9,0,1.5,0.7,1.5,1.6v45c0,0.9-0.7,1.6-1.5,1.6h-74.7c-0.9-0.1-1.5-0.8-1.5-1.6V29C-41.7,28.1-41,27.4-40.1,27.4z"
370
+ fill="none" stroke="url(#mqSecLDash)" strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
371
+
372
+ {/* Right partial card */}
373
+ <path d="M206.7,75.6h-74.3c-0.8,0-1.5-0.7-1.5-1.6V29c0-0.9,0.8-1.6,1.5-1.6h74.3c0.8,0.1,1.5,0.8,1.5,1.6v45C208.2,74.9,207.5,75.6,206.7,75.6z"
374
+ fill="url(#mqSecRFill)" stroke="url(#mqSecRStroke)" strokeWidth="0.7" />
375
+ <path d="M201.4,69.1h-63.8c-0.5,0-0.8-0.4-0.8-0.8V34.8c0-0.5,0.4-0.8,0.8-0.8h63.8c0.5,0,0.8,0.4,0.8,0.8v33.5C202.2,68.8,201.9,69.1,201.4,69.1z"
376
+ fill="url(#mqSecRGhost)" />
377
+ <path d="M206.6,75.6h-74.7c-0.9,0-1.5-0.7-1.5-1.6V29c0-0.9,0.7-1.6,1.5-1.6h74.7c0.9,0.1,1.5,0.8,1.5,1.6v45C208.1,74.9,207.4,75.6,206.6,75.6z"
378
+ fill="none" stroke="url(#mqSecRDash)" strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
379
+
380
+ {/* Featured center card (shadowed) */}
381
+ <g filter="url(#shadMqSec)">
382
+ <path d="M46.3,26.5h74.3c0.8,0,1.5,0.7,1.5,1.6v45c0,0.9-0.8,1.6-1.5,1.6H46.3c-0.8-0.1-1.5-0.8-1.5-1.6v-45C44.8,27.2,45.5,26.5,46.3,26.5z"
383
+ fill="url(#bevelMqSec)" stroke={NEUTRAL_STROKE} strokeWidth="0.7" />
384
+ </g>
385
+ <path d="M51.6,33h63.8c0.5,0,0.8,0.4,0.8,0.8v33.5c0,0.5-0.4,0.8-0.8,0.8H51.6c-0.5,0-0.8-0.4-0.8-0.8V33.8C50.8,33.3,51.2,33,51.6,33z"
386
+ fill={GHOST} />
387
+
388
+ {/* "Aa" glyphs */}
389
+ <path fillRule="evenodd" clipRule="evenodd" fill={ACCENT}
390
+ d="M84,62.5h-6.1l-1-4.4h-6.2l-1,4.4h-6l6.9-26h6.6L84,62.5z M75.7,53.5c-0.9-3.9-1.6-7.6-2-11h-0.1c-0.5,3.6-1.1,7.3-2,11H75.7z" />
391
+ <path fill={ACCENT}
392
+ d="M97.8,62.5l-0.2-2h-0.1c-0.9,1.2-2.6,2.4-4.8,2.4c-3.2,0-4.8-2.3-4.8-4.5c0-3.8,3.4-5.9,9.5-5.9v-0.3c0-1.3-0.4-3.7-3.6-3.7c-1.5,0-3,0.4-4.1,1.2L89,47.8c1.3-0.9,3.2-1.4,5.2-1.4c4.8,0,6,3.3,6,6.5v5.9c0,1.4,0.1,2.7,0.3,3.8L97.8,62.5L97.8,62.5z M97.4,54.5c-3.1-0.1-6.7,0.5-6.7,3.6c0,1.9,1.2,2.8,2.7,2.8c2,0,3.4-1.3,3.8-2.7c0.1-0.3,0.2-0.6,0.2-0.9V54.5z" />
393
+
394
+ {/* Featured card dashed violet border */}
395
+ <path d="M46.5,26.5h74.7c0.9,0,1.5,0.7,1.5,1.6v45c0,0.9-0.7,1.6-1.5,1.6H46.5c-0.9-0.1-1.5-0.8-1.5-1.6v-45C44.9,27.2,45.6,26.5,46.5,26.5z"
396
+ fill="none" stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10" strokeDasharray="3,3" />
397
+
398
+ {/* Bidirectional horizontal-scroll arrows */}
399
+ <g fill={ACCENT} stroke={ACCENT} strokeWidth="2" strokeMiterlimit="10">
400
+ <line x1="93.2" y1="87.4" x2="139.9" y2="87.4" />
401
+ <polygon points="145.5,87.4 137.6,90.6 139.5,87.4 137.6,84.2" />
402
+ <line x1="77.1" y1="87.5" x2="30.5" y2="87.5" />
403
+ <polygon points="24.9,87.5 32.8,84.4 30.9,87.5 32.8,90.8" />
404
+ </g>
405
+ </svg>
406
+ );
407
+ }
408
+
409
+ // ─────────────────────────────────────────────────────────────────────
410
+ // Lookup map for the Add Section modal
411
+ // ─────────────────────────────────────────────────────────────────────
412
+ export const SECTION_CARD_ICONS: Record<string, React.FC> = {
413
+ "empty-v2": EmptySectionV2CardIcon,
414
+ coverSection: CoverSectionCardIcon,
415
+ projectGridBlock: ProjectGridCardIcon,
416
+ projectCarouselBlock: ProjectCarouselCardIcon,
417
+ marqueeBlock: MarqueeCardIcon,
418
+ parallaxGroup: ParallaxGroupCardIcon,
419
+ createCustom: CreateCustomSectionCardIcon,
420
+ savedCustom: SavedSectionCardIcon,
421
+ };